Skip to content

Instantly share code, notes, and snippets.

@SasLuca
Last active December 27, 2020 16:20
Show Gist options
  • Save SasLuca/149c0a9c9aba11ba93cb28d9989c0bec to your computer and use it in GitHub Desktop.
Save SasLuca/149c0a9c9aba11ba93cb28d9989c0bec to your computer and use it in GitHub Desktop.
This macro will overload all math operators for enum classes.
#pragma once
#include "type_traits"
#define rf_generate_enum_class_math_operations(rf__enum_type__) \
/* + += - -= * *= / /= % %= */ \
inline rf__enum_type__ operator+(rf__enum_type__ lhs, rf__enum_type__ rhs) \
{ \
using rf__underlying_enum_type = std::underlying_type_t<rf__enum_type__>; \
rf__enum_type__ rf__enum_math_op_result = static_cast<rf__enum_type__>(static_cast<rf__underlying_enum_type>(lhs) + static_cast<rf__underlying_enum_type>(rhs)); \
return rf__enum_math_op_result; \
} \
inline rf__enum_type__& operator+=(rf__enum_type__& lhs, rf__enum_type__ rhs) \
{\
lhs = lhs + rhs; \
return lhs; \
}\
\
inline rf__enum_type__ operator-(rf__enum_type__ lhs, rf__enum_type__ rhs) \
{\
using rf__underlying_enum_type = std::underlying_type_t<rf__enum_type__>; \
rf__enum_type__ rf__enum_math_op_result = static_cast<rf__enum_type__>(static_cast<rf__underlying_enum_type>(lhs) - static_cast<rf__underlying_enum_type>(rhs));\
return rf__enum_math_op_result;\
}\
inline rf__enum_type__& operator-=(rf__enum_type__& lhs, rf__enum_type__ rhs)\
{\
lhs = lhs - rhs;\
return lhs;\
}\
\
inline rf__enum_type__ operator*(rf__enum_type__ lhs, rf__enum_type__ rhs)\
{\
using rf__underlying_enum_type = std::underlying_type_t<rf__enum_type__>;\
rf__enum_type__ rf__enum_math_op_result = static_cast<rf__enum_type__>(static_cast<rf__underlying_enum_type>(lhs) * static_cast<rf__underlying_enum_type>(rhs));\
return rf__enum_math_op_result;\
}\
inline rf__enum_type__& operator*=(rf__enum_type__& lhs, rf__enum_type__ rhs)\
{\
lhs = lhs * rhs;\
return lhs;\
}\
\
inline rf__enum_type__ operator/(rf__enum_type__ lhs, rf__enum_type__ rhs)\
{\
using rf__underlying_enum_type = std::underlying_type_t<rf__enum_type__>;\
rf__enum_type__ rf__enum_math_op_result = static_cast<rf__enum_type__>(static_cast<rf__underlying_enum_type>(lhs) / static_cast<rf__underlying_enum_type>(rhs));\
return rf__enum_math_op_result;\
}\
inline rf__enum_type__& operator/=(rf__enum_type__& lhs, rf__enum_type__ rhs)\
{\
lhs = lhs / rhs;\
return lhs;\
}\
\
inline rf__enum_type__ operator%(rf__enum_type__ lhs, rf__enum_type__ rhs)\
{\
using rf__underlying_enum_type = std::underlying_type_t<rf__enum_type__>;\
rf__enum_type__ rf__enum_math_op_result = static_cast<rf__enum_type__>(static_cast<rf__underlying_enum_type>(lhs) % static_cast<rf__underlying_enum_type>(rhs));\
return rf__enum_math_op_result;\
}\
inline rf__enum_type__& operator%=(rf__enum_type__& lhs, rf__enum_type__ rhs)\
{\
lhs = lhs % rhs;\
return lhs;\
}\
\
/* == != > < >= <=*/\
inline bool operator==(rf__enum_type__ lhs, rf__enum_type__ rhs)\
{\
using rf__underlying_enum_type = std::underlying_type_t<rf__enum_type__>;\
bool rf__enum_math_op_result = static_cast<rf__underlying_enum_type>(lhs) == static_cast<rf__underlying_enum_type>(rhs);\
return rf__enum_math_op_result;\
}\
\
inline bool operator!=(rf__enum_type__ lhs, rf__enum_type__ rhs)\
{\
using rf__underlying_enum_type = std::underlying_type_t<rf__enum_type__>;\
bool rf__enum_math_op_result = static_cast<rf__underlying_enum_type>(lhs) != static_cast<rf__underlying_enum_type>(rhs);\
return rf__enum_math_op_result;\
}\
\
inline bool operator>(rf__enum_type__ lhs, rf__enum_type__ rhs)\
{\
using rf__underlying_enum_type = std::underlying_type_t<rf__enum_type__>;\
bool rf__enum_math_op_result = static_cast<rf__underlying_enum_type>(lhs) > static_cast<rf__underlying_enum_type>(rhs);\
return rf__enum_math_op_result;\
}\
\
inline bool operator<(rf__enum_type__ lhs, rf__enum_type__ rhs)\
{\
using rf__underlying_enum_type = std::underlying_type_t<rf__enum_type__>;\
bool rf__enum_math_op_result = static_cast<rf__underlying_enum_type>(lhs) < static_cast<rf__underlying_enum_type>(rhs);\
return rf__enum_math_op_result;\
}\
\
inline bool operator>=(rf__enum_type__ lhs, rf__enum_type__ rhs)\
{\
using rf__underlying_enum_type = std::underlying_type_t<rf__enum_type__>;\
bool rf__enum_math_op_result = static_cast<rf__underlying_enum_type>(lhs) >= static_cast<rf__underlying_enum_type>(rhs);\
return rf__enum_math_op_result;\
}\
\
inline bool operator<=(rf__enum_type__ lhs, rf__enum_type__ rhs)\
{\
using rf__underlying_enum_type = std::underlying_type_t<rf__enum_type__>;\
bool rf__enum_math_op_result = static_cast<rf__underlying_enum_type>(lhs) <= static_cast<rf__underlying_enum_type>(rhs);\
return rf__enum_math_op_result;\
}\
\
/* ! && || */\
\
inline bool operator!(rf__enum_type__ it)\
{\
using rf__underlying_enum_type = std::underlying_type_t<rf__enum_type__>;\
bool rf__enum_math_op_result = !static_cast<rf__underlying_enum_type>(it);\
return rf__enum_math_op_result;\
}\
\
inline bool operator&&(rf__enum_type__ lhs, rf__enum_type__ rhs)\
{\
using rf__underlying_enum_type = std::underlying_type_t<rf__enum_type__>;\
bool rf__enum_math_op_result = static_cast<rf__underlying_enum_type>(lhs) && static_cast<rf__underlying_enum_type>(rhs);\
return rf__enum_math_op_result;\
}\
\
inline bool operator||(rf__enum_type__ lhs, rf__enum_type__ rhs)\
{\
using rf__underlying_enum_type = std::underlying_type_t<rf__enum_type__>;\
bool rf__enum_math_op_result = static_cast<rf__underlying_enum_type>(lhs) || static_cast<rf__underlying_enum_type>(rhs);\
return rf__enum_math_op_result;\
}\
\
/* & &= | |= ^ ^= ~ << >>*/\
inline rf__enum_type__ operator&(rf__enum_type__ lhs, rf__enum_type__ rhs)\
{\
using rf__underlying_enum_type = std::underlying_type_t<rf__enum_type__>;\
rf__enum_type__ rf__enum_math_op_result = static_cast<rf__enum_type__>(static_cast<rf__underlying_enum_type>(lhs) & static_cast<rf__underlying_enum_type>(rhs));\
return rf__enum_math_op_result;\
}\
inline rf__enum_type__& operator&=(rf__enum_type__& lhs, rf__enum_type__ rhs)\
{\
lhs = lhs & rhs;\
return lhs;\
}\
\
inline rf__enum_type__ operator|(rf__enum_type__ lhs, rf__enum_type__ rhs)\
{\
using rf__underlying_enum_type = std::underlying_type_t<rf__enum_type__>;\
rf__enum_type__ rf__enum_math_op_result = static_cast<rf__enum_type__>(static_cast<rf__underlying_enum_type>(lhs) | static_cast<rf__underlying_enum_type>(rhs));\
return rf__enum_math_op_result;\
}\
inline rf__enum_type__& operator|=(rf__enum_type__& lhs, rf__enum_type__ rhs)\
{\
lhs = lhs | rhs;\
return lhs;\
}\
\
inline rf__enum_type__ operator^(rf__enum_type__ lhs, rf__enum_type__ rhs)\
{\
using rf__underlying_enum_type = std::underlying_type_t<rf__enum_type__>;\
rf__enum_type__ rf__enum_math_op_result = static_cast<rf__enum_type__>(static_cast<rf__underlying_enum_type>(lhs) ^ static_cast<rf__underlying_enum_type>(rhs));\
return rf__enum_math_op_result;\
}\
inline rf__enum_type__& operator^=(rf__enum_type__& lhs, rf__enum_type__ rhs)\
{\
lhs = lhs ^ rhs;\
return lhs;\
}\
\
inline rf__enum_type__ operator~(rf__enum_type__ it)\
{\
using rf__underlying_enum_type = std::underlying_type_t<rf__enum_type__>;\
rf__enum_type__ rf__enum_math_op_result = static_cast<rf__enum_type__>(~static_cast<rf__underlying_enum_type>(it));\
return rf__enum_math_op_result;\
}\
\
inline rf__enum_type__ operator<<(rf__enum_type__ lhs, rf__enum_type__ rhs)\
{\
using rf__underlying_enum_type = std::underlying_type_t<rf__enum_type__>;\
rf__enum_type__ rf__enum_math_op_result = static_cast<rf__enum_type__>(static_cast<rf__underlying_enum_type>(lhs) << static_cast<rf__underlying_enum_type>(rhs));\
return rf__enum_math_op_result;\
}\
inline rf__enum_type__& operator<<=(rf__enum_type__& lhs, rf__enum_type__ rhs)\
{\
lhs = lhs << rhs;\
return lhs;\
}\
\
inline rf__enum_type__ operator>>(rf__enum_type__ lhs, rf__enum_type__ rhs)\
{\
using rf__underlying_enum_type = std::underlying_type_t<rf__enum_type__>;\
rf__enum_type__ rf__enum_math_op_result = static_cast<rf__enum_type__>(static_cast<rf__underlying_enum_type>(lhs) >> static_cast<rf__underlying_enum_type>(rhs));\
return rf__enum_math_op_result;\
}\
inline rf__enum_type__& operator>>=(rf__enum_type__& lhs, rf__enum_type__ rhs)\
{\
lhs = lhs >> rhs;\
return lhs;\
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment