FE 0.6.0
A header-only C++ library for writing frontends
Loading...
Searching...
No Matches
enum.h
Go to the documentation of this file.
1#pragma once
2
3#include <compare>
4
5#include <type_traits>
6
7namespace fe {
8
9/// @name is_enum
10///@{
11template<typename T> struct is_bit_enum : std::false_type {};
12template<class T> inline constexpr bool is_bit_enum_v = is_bit_enum<T>::value;
13template<class E>
14concept BitEnum = std::is_enum_v<E> && is_bit_enum_v<E>;
15///@}
16
17/// @name Bit operations for enum classs
18/// Provides all kind of bit and comparison operators for an `enum class` @p E.
19/// Note that the bit operators return @p E's underlying type and not the original `enum` @p E.
20/// This is because the result may not be a valid `enum` value.
21/// For the same reason, it doesn't make sense to declare operators such as `&=`.
22/// Use like this:
23/// ```
24/// using fe::operator&;
25/// using fe::operator|;
26/// using fe::operator^;
27/// using fe::operator<=>;
28/// using fe::operator==;
29/// using fe::operator!=;
30///
31/// enum class MyEnum : unsigned {
32/// A = 1 << 0,
33/// B = 1 << 1,
34/// C = 1 << 2,
35/// };
36///
37/// template<> struct fe::is_bit_enum<MyEnum> : std::true_type { };
38/// ```
39///@{
40// clang-format off
41template <BitEnum E> constexpr auto operator&(E x, E y) { return std::underlying_type_t<E>(x) & std::underlying_type_t<E>(y); }
42template <BitEnum E> constexpr auto operator&(std::underlying_type_t<E> x, E y) { return x & std::underlying_type_t<E>(y); }
43template <BitEnum E> constexpr auto operator&( E x, std::underlying_type_t<E> y) { return std::underlying_type_t<E>(x) & y ; }
44template <BitEnum E> constexpr auto operator|( E x, E y) { return std::underlying_type_t<E>(x) | std::underlying_type_t<E>(y); }
45template <BitEnum E> constexpr auto operator|(std::underlying_type_t<E> x, E y) { return x | std::underlying_type_t<E>(y); }
46template <BitEnum E> constexpr auto operator|( E x, std::underlying_type_t<E> y) { return std::underlying_type_t<E>(x) | y ; }
47template <BitEnum E> constexpr auto operator^( E x, E y) { return std::underlying_type_t<E>(x) ^ std::underlying_type_t<E>(y); }
48template <BitEnum E> constexpr auto operator^(std::underlying_type_t<E> x, E y) { return x ^ std::underlying_type_t<E>(y); }
49template <BitEnum E> constexpr auto operator^( E x, std::underlying_type_t<E> y) { return std::underlying_type_t<E>(x) ^ y ; }
50template <BitEnum E> constexpr std::strong_ordering operator<=>(std::underlying_type_t<E> x, E y) { return x <=> std::underlying_type_t<E>(y); }
51template <BitEnum E> constexpr std::strong_ordering operator<=>(E x, std::underlying_type_t<E> y) { return std::underlying_type_t<E>(x) <=> y; }
52template <BitEnum E> constexpr bool operator==(std::underlying_type_t<E> x, E y) { return x == std::underlying_type_t<E>(y); }
53template <BitEnum E> constexpr bool operator!=(std::underlying_type_t<E> x, E y) { return x != std::underlying_type_t<E>(y); }
54template <BitEnum E> constexpr bool operator==(E x, std::underlying_type_t<E> y) { return std::underlying_type_t<E>(x) == y; }
55template <BitEnum E> constexpr bool operator!=(E x, std::underlying_type_t<E> y) { return std::underlying_type_t<E>(x) != y; }
56// clang-format on
57
58///@}
59
60} // namespace fe
Definition arena.h:9
constexpr bool operator==(std::underlying_type_t< E > x, E y)
Definition enum.h:52
constexpr std::strong_ordering operator<=>(std::underlying_type_t< E > x, E y)
Definition enum.h:50
constexpr auto operator^(E x, E y)
Definition enum.h:47
constexpr auto operator|(E x, E y)
Definition enum.h:44
constexpr bool operator!=(std::underlying_type_t< E > x, E y)
Definition enum.h:53
constexpr bool is_bit_enum_v
Definition enum.h:12
constexpr auto operator&(E x, E y)
Definition enum.h:41