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