Last active
February 19, 2020 13:01
-
-
Save Denzo77/d4135a5ea93631e0ee626c71650adc00 to your computer and use it in GitHub Desktop.
An example generic newtype implementation for cpp. See https://github.com/satori16/NewType for another take on this.
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
/** | |
* @brief Newtype pattern impl for cpp. Derives a new type from one that | |
* implements arithmetic operations to allow typesafe arithmetic. | |
* | |
* # Purpose: | |
* It is useful to restrict arithmetic on builtin types to | |
* variables that represent the same quantity, e.g. only allow 'meters' to be | |
* added to 'meters'. This struct provides a template definition for easily | |
* deriving these 'new types'. | |
* | |
* # Usage: | |
* To create a new type 'Meters' that behaves like a double, but can only | |
* be added/subtracted etc to other instances of Meters: | |
* ``` | |
* struct Meters : public NewType<Meters, double> | |
* { | |
* using NewType::NewType; | |
* }; | |
* ``` | |
* - The first parameter passed to NewType is the struct that is inheriting | |
* it, to allow its members to take/return the correct type. | |
* - The second parameter is the base type that it is being derived from. | |
* - Additional overloaded operations could be defined for interacting safely | |
* with another type 'Feet' without having to worry about every accidently | |
* directly adding the raw values together. | |
* | |
* | |
* @params DerivedType: The type that is inheriting this struct. | |
* @params BaseType: The type that we are subtyping. | |
*/ | |
template<typename DerivedType, typename BaseType> | |
struct NewType { | |
BaseType val; | |
constexpr NewType(BaseType val) : val(val) {} | |
void operator=(const NewType &t) { val = t.val; } | |
DerivedType operator+(const DerivedType &t) const { return (this->val + t.val); } | |
DerivedType operator-(const DerivedType &t) const { return (this->val - t.val); } | |
DerivedType operator*(const DerivedType &t) const { return (this->val * t.val); } | |
DerivedType operator/(const DerivedType &t) const { return (this->val / t.val); } | |
bool operator>(const DerivedType &t) const { return (this->val > t.val); } | |
bool operator>=(const DerivedType &t) const { return (this->val >= t.val); } | |
bool operator<(const DerivedType &t) const { return (this->val < t.val); } | |
bool operator<=(const DerivedType &t) const { return (this->val <= t.val); } | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment