1 | #pragma once |
2 | |
3 | #include <type_traits> |
4 | |
5 | namespace taichi { |
6 | |
7 | // This allows us to static_assert(always_false_v<T>) when using if constexpr. |
8 | // See https://stackoverflow.com/a/53945549/12003165 |
9 | template <typename T> |
10 | struct always_false : std::false_type {}; |
11 | |
12 | template <typename T> |
13 | inline constexpr bool always_false_v = always_false<T>::value; |
14 | |
15 | #define ENUM_FLAG_OPERATOR(T, X) \ |
16 | inline T operator X(T lhs, T rhs) { \ |
17 | return (T)(static_cast<std::underlying_type_t<T>>(lhs) \ |
18 | X static_cast<std::underlying_type_t<T>>(rhs)); \ |
19 | } |
20 | #define ENUM_FLAGS(T) \ |
21 | enum class T; \ |
22 | inline T operator~(T t) { \ |
23 | return (T)(~static_cast<std::underlying_type_t<T>>(t)); \ |
24 | } \ |
25 | ENUM_FLAG_OPERATOR(T, |) \ |
26 | ENUM_FLAG_OPERATOR(T, ^) \ |
27 | ENUM_FLAG_OPERATOR(T, &) \ |
28 | enum class T |
29 | |
30 | } // namespace taichi |
31 | |