#ifndef PKE_MACROS_HPP #define PKE_MACROS_HPP #define Q(x) #x #define QUOTE(x) Q(x) #define CONCAT2(x, y) x##y #define CONCAT(x, y) CONCAT2(x, y) #define CAFE_BABE(T) reinterpret_cast(0xCAFEBABE) #define IS_CONSTRUCTIBLE(T) constexpr(std::is_default_constructible::value && !std::is_integral::value && !std::is_floating_point::value) #define IS_DESTRUCTIBLE(T) constexpr(std::is_destructible::value && !std::is_integral::value && !std::is_floating_point::value) #define TypeSafeInt2_H(TypeName, Type, Max, TypeName_T, TypeName_MAX, TypeName_T_MAX)\ using TypeName_T = Type; \ enum class TypeName : TypeName_T; \ constexpr TypeName_T TypeName_T_MAX = TypeName_T{Max}; \ constexpr TypeName TypeName_MAX = TypeName{TypeName_T_MAX}; \ TypeName operator+(const TypeName &a, const TypeName_T &i); \ TypeName operator-(const TypeName &a, const TypeName_T &i); \ TypeName operator+(const TypeName &a, const TypeName &b); \ TypeName operator-(const TypeName &a, const TypeName &b); \ TypeName operator&(const TypeName &a, const TypeName &b); \ TypeName operator|(const TypeName &a, const TypeName &b); \ TypeName operator^(const TypeName &a, const TypeName &b); \ TypeName &operator++(TypeName &a); \ TypeName &operator--(TypeName &a); \ TypeName operator<<(const TypeName &a, const TypeName &b); \ TypeName operator>>(const TypeName &a, const TypeName &b); #define TypeSafeInt2_B(TypeName, TypeName_T) \ inline TypeName operator+(const TypeName &a, const TypeName_T &i) { \ return TypeName(static_cast(a) + i); \ } \ inline TypeName operator-(const TypeName &a, const TypeName_T &i) { \ return TypeName(static_cast(a) - i); \ } \ inline TypeName operator+(const TypeName &a, const TypeName &b) { \ return TypeName(static_cast(a) + static_cast(b)); \ } \ inline TypeName operator-(const TypeName &a, const TypeName &b) { \ return TypeName(static_cast(a) - static_cast(b)); \ } \ inline TypeName operator&(const TypeName &a, const TypeName &b) { \ return TypeName(static_cast(a) & static_cast(b)); \ } \ inline TypeName operator|(const TypeName &a, const TypeName &b) { \ return TypeName(static_cast(a) | static_cast(b)); \ } \ inline TypeName operator^(const TypeName &a, const TypeName &b) { \ return TypeName(static_cast(a) ^ static_cast(b)); \ } \ inline TypeName &operator++(TypeName &a) { \ a = a + 1; \ return a; \ } \ inline TypeName &operator--(TypeName &a) { \ a = a - 1; \ return a; \ }; \ inline TypeName operator<<(const TypeName &a, const TypeName &b) { \ return TypeName(static_cast(a) << static_cast(b)); \ }; \ inline TypeName operator>>(const TypeName &a, const TypeName &b) { \ return TypeName(static_cast(a) >> static_cast(b)); \ }; #define TypeSafeInt_H(TypeName, Type, Max) \ TypeSafeInt2_H(TypeName, Type, Max, CONCAT(TypeName, _T), CONCAT(TypeName, _MAX), CONCAT(TypeName, _T_MAX)) #define TypeSafeInt_B(TypeName) \ TypeSafeInt2_B(TypeName, CONCAT(TypeName, _T)) #define TypeSafeInt2_H_constexpr(TypeName, Type, Max, TypeName_T, TypeName_MAX, TypeName_T_MAX)\ using TypeName_T = Type; \ enum class TypeName : TypeName_T; \ constexpr TypeName_T TypeName_T_MAX = TypeName_T{Max}; \ constexpr TypeName TypeName_MAX = TypeName{TypeName_T_MAX}; \ constexpr TypeName operator+(const TypeName &a, const TypeName_T &b) { \ return TypeName(static_cast(a) + static_cast(b)); \ } \ constexpr TypeName operator-(const TypeName &a, const TypeName_T &b) { \ return TypeName(static_cast(a) - static_cast(b)); \ } \ constexpr TypeName operator+(const TypeName &a, const TypeName &b) { \ return TypeName(static_cast(a) + static_cast(b)); \ } \ constexpr TypeName operator-(const TypeName &a, const TypeName &b) { \ return TypeName(static_cast(a) - static_cast(b)); \ } \ constexpr TypeName operator&(const TypeName &a, const TypeName &b) { \ return TypeName(static_cast(a) & static_cast(b)); \ } \ constexpr TypeName operator|(const TypeName &a, const TypeName &b) { \ return TypeName(static_cast(a) | static_cast(b)); \ } \ constexpr TypeName operator^(const TypeName &a, const TypeName &b) { \ return TypeName(static_cast(a) ^ static_cast(b)); \ } \ constexpr TypeName &operator++(TypeName &a) { \ a = a + TypeName(1); \ return a; \ } \ constexpr TypeName &operator--(TypeName &a) { \ a = a - TypeName{1}; \ return a; \ }; \ constexpr TypeName operator<<(const TypeName &a, const TypeName &b) { \ return TypeName(static_cast(a) << static_cast(b)); \ }; \ constexpr TypeName operator>>(const TypeName &a, const TypeName &b) { \ return TypeName(static_cast(a) >> static_cast(b)); \ }; #define TypeSafeInt_Const_Expr(TypeName, Type, Max) \ TypeSafeInt2_H_constexpr(TypeName, Type, Max, CONCAT(TypeName, _T), CONCAT(TypeName, _MAX), CONCAT(TypeName, _T_MAX)) #endif /* PKE_MACROS_HPP */