Created
April 26, 2019 14:13
-
-
Save ikskuh/2525138929ae1d137fe4dd37be5bf4ed to your computer and use it in GitHub Desktop.
Tagged, configurable integer type which allows only "self-interaction"
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <type_traits> | |
template< | |
typename Tag, // Discriminator | |
typename UnderlyingType = std::size_t, // What integer are we defining | |
bool EnableOrdering = true, // Allow relational operators | |
bool EnableBitwise = false, // Allow bitwise operators | |
bool EnableArithmetic = false // Allow arithmetic operators | |
> | |
struct tagged_int | |
{ | |
static_assert(std::is_integral_v<UnderlyingType>); | |
UnderlyingType value; | |
constexpr tagged_int() : value(0) { } | |
constexpr tagged_int(UnderlyingType val) : value(val) { } | |
}; | |
#define DEFINE_TAGGED_INT_OPERATOR(_Oper, _Cond, _Msg) \ | |
template<typename T, typename U, bool O, bool B, bool A> \ | |
constexpr auto operator _Oper (tagged_int<T,U,O,B,A> lhs, tagged_int<T,U,O,B,A> rhs) \ | |
{ \ | |
static_assert(_Cond, _Msg); \ | |
return lhs.value _Oper rhs.value; \ | |
} | |
#define DEFINE_TAGGED_INT_SETTER(_Oper, _Cond, _Msg) \ | |
template<typename T, typename U, bool O, bool B, bool A> \ | |
constexpr tagged_int<T,U,O,B,A> & operator _Oper (tagged_int<T,U,O,B,A> & lhs, tagged_int<T,U,O,B,A> rhs) \ | |
{ \ | |
static_assert(_Cond, _Msg); \ | |
lhs.value _Oper rhs.value; \ | |
return lhs; \ | |
} | |
DEFINE_TAGGED_INT_OPERATOR(==, true, "") | |
DEFINE_TAGGED_INT_OPERATOR(!=, true, "") | |
DEFINE_TAGGED_INT_OPERATOR(>, O, "tagged_int has no ordering enabled!") | |
DEFINE_TAGGED_INT_OPERATOR(<, O, "tagged_int has no ordering enabled!") | |
DEFINE_TAGGED_INT_OPERATOR(>=, O, "tagged_int has no ordering enabled!") | |
DEFINE_TAGGED_INT_OPERATOR(<=, O, "tagged_int has no ordering enabled!") | |
DEFINE_TAGGED_INT_OPERATOR(&, B, "tagged_int has no bitwise operations enabled!") | |
DEFINE_TAGGED_INT_OPERATOR(|, B, "tagged_int has no bitwise operations enabled!") | |
DEFINE_TAGGED_INT_OPERATOR(^, B, "tagged_int has no bitwise operations enabled!") | |
DEFINE_TAGGED_INT_SETTER(|=, B, "tagged_int has no bitwise operations enabled!") | |
DEFINE_TAGGED_INT_SETTER(&=, B, "tagged_int has no bitwise operations enabled!") | |
DEFINE_TAGGED_INT_SETTER(^=, B, "tagged_int has no bitwise operations enabled!") | |
DEFINE_TAGGED_INT_OPERATOR(+, A, "tagged_int has no arithmetic operations enabled!") | |
DEFINE_TAGGED_INT_OPERATOR(-, A, "tagged_int has no arithmetic operations enabled!") | |
DEFINE_TAGGED_INT_OPERATOR(*, A, "tagged_int has no arithmetic operations enabled!") | |
DEFINE_TAGGED_INT_OPERATOR(/, A, "tagged_int has no arithmetic operations enabled!") | |
DEFINE_TAGGED_INT_OPERATOR(%, A, "tagged_int has no arithmetic operations enabled!") | |
DEFINE_TAGGED_INT_SETTER(+=, A, "tagged_int has no arithmetic operations enabled!") | |
DEFINE_TAGGED_INT_SETTER(-=, A, "tagged_int has no arithmetic operations enabled!") | |
DEFINE_TAGGED_INT_SETTER(*=, A, "tagged_int has no arithmetic operations enabled!") | |
DEFINE_TAGGED_INT_SETTER(/=, A, "tagged_int has no arithmetic operations enabled!") | |
DEFINE_TAGGED_INT_SETTER(%=, A, "tagged_int has no arithmetic operations enabled!") | |
#undef DEFINE_TAGGED_INT_OPERATOR | |
#undef DEFINE_TAGGED_INT_SETTER |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "tagged_int.h" | |
using myint = tagged_int<struct myint_tag, int, true, true, true>; | |
using myid = tagged_int<struct myid_tag, std::size_t, true, false, false>; | |
constexpr void test_myint() | |
{ | |
myint a, b; | |
a = myint { 10 }; | |
a = b; | |
a == b; | |
a != b; | |
a > b; | |
a < b; | |
a >= b; | |
a <= b; | |
a | b; | |
a & b; | |
a ^ b; | |
a |= b; | |
a &= b; | |
a ^= b; | |
a + b; | |
a - b; | |
a * b; | |
a / b; | |
a % b; | |
a += b; | |
a -= b; | |
a *= b; | |
a /= b; | |
a %= b; | |
} | |
constexpr void test_myid() | |
{ | |
myid a, b; | |
a = myid { 10 }; | |
a = b; | |
a == b; | |
a != b; | |
a > b; | |
a < b; | |
a >= b; | |
a <= b; | |
/* everything from here throws errors | |
a | b; | |
a & b; | |
a ^ b; | |
a + b; | |
a - b; | |
a * b; | |
a / b; | |
a % b; | |
// */ | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment