Skip to content

Instantly share code, notes, and snippets.

@lzqlzzq
Last active November 30, 2023 14:27
Show Gist options
  • Save lzqlzzq/3480833b28e237430da0dc10afce453d to your computer and use it in GitHub Desktop.
Save lzqlzzq/3480833b28e237430da0dc10afce453d to your computer and use it in GitHub Desktop.
A C++ generic numeric type that you can inherit from!
#ifndef _META_NUMERIC_
#define _META_NUMERIC_
#include <iostream>
#include <string>
namespace metanumeric {
#define UNARY_ASGN_OPTS \
UNARY_ASGN_OPT(++) \
UNARY_ASGN_OPT(--)
#define BIN_ARTH_OPTS \
BIN_ARTH_OPT(+) \
BIN_ARTH_OPT(-) \
BIN_ARTH_OPT(*) \
BIN_ARTH_OPT(/) \
BIN_ARTH_OPT(%) \
BIN_ARTH_OPT(&) \
BIN_ARTH_OPT(|) \
BIN_ARTH_OPT(^) \
BIN_ARTH_OPT(<<) \
BIN_ARTH_OPT(>>)
#define BIN_BOOL_OPTS \
BIN_BOOL_OPT(==) \
BIN_BOOL_OPT(!=) \
BIN_BOOL_OPT(>=) \
BIN_BOOL_OPT(<=) \
BIN_BOOL_OPT(<) \
BIN_BOOL_OPT(>)
#define BIN_ASGN_OPTS \
BIN_ASGN_OPT(=) \
BIN_ASGN_OPT(+=) \
BIN_ASGN_OPT(-=) \
BIN_ASGN_OPT(*=) \
BIN_ASGN_OPT(/=) \
BIN_ASGN_OPT(%=) \
BIN_ASGN_OPT(&=) \
BIN_ASGN_OPT(|=) \
BIN_ASGN_OPT(^=) \
BIN_ASGN_OPT(<<=) \
BIN_ASGN_OPT(>>=)
template <typename T>
class MetaNumeric {
public:
T value;
explicit MetaNumeric(T value) : value(value) {};
template <typename U>
explicit operator MetaNumeric<U>() const {
return MetaNumeric<U>(value);
};
explicit operator T() const {
return value;
};
MetaNumeric& operator=(const T& other) {
value = other;
return *this;
};
// Unary Assignment Operator
#define UNARY_ASGN_OPT(opt) \
MetaNumeric<T>& operator opt() { \
opt this->value; \
return *this; \
}; \
\
MetaNumeric<T> operator opt(int) { \
opt this->value; \
return *this; \
};
UNARY_ASGN_OPTS
#undef UNARY_ASGN_OPT
// Binary Assignment Operator
#define BIN_ASGN_OPT(opt) \
void operator opt(T other) { \
this->value opt other; \
}; \
\
void operator opt(const MetaNumeric<T> &other) { \
this->value opt other.value; \
};
BIN_ASGN_OPTS
#undef BIN_ASGN_OPT
// Binary Arithmetic Operator
#define BIN_ARTH_OPT(opt) \
MetaNumeric<T> operator opt(T other) const { \
return MetaNumeric<T>(this->value opt other); \
}; \
\
MetaNumeric<T> operator opt(const MetaNumeric<T> &other) const { \
return MetaNumeric<T>(this->value opt other.value); \
};
BIN_ARTH_OPTS
#undef BIN_ARTH_OPT
// Binary Bool Operator
#define BIN_BOOL_OPT(opt) \
bool operator opt(T other) const { \
return this->value opt other; \
}; \
\
bool operator opt(const MetaNumeric<T> &other) const { \
return this->value opt other.value; \
};
BIN_BOOL_OPTS
#undef BIN_BOOL_OPT
std::string to_string() const {
return std::to_string(value);
};
};
template<typename T>
std::string to_string(const MetaNumeric<T> &num) {
return num.to_string();
};
// iostream
template<typename T>
std::ostream& operator<<(std::ostream& os, const MetaNumeric<T>& obj) {
return os << obj.value;
};
template<typename T>
std::istream& operator>>(std::istream& is, MetaNumeric<T>& obj) {
return is >> obj.value;
};
#undef UNARY_ASGN_OPT
#undef BIN_ARTH_OPTS
#undef BIN_BOOL_OPTS
#undef BIN_ASGN_OPTS
}
#endif
#include <iostream>
#include <string>
#include "MetaNumeric.hpp"
using namespace metanumeric;
int main() {
// Change to whatever type you want!
MetaNumeric<float> num(42);
std::cout << to_string(num) << std::endl;
num += 6;
std::cout << int(num < 45) << std::endl;
std::cout << num << std::endl;
num ++;
std::cout << num << std::endl;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment