1#pragma once
2
3#include <type_traits>
4
5namespace 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
9template <typename T>
10struct always_false : std::false_type {};
11
12template <typename T>
13inline 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