Skip to content

Instantly share code, notes, and snippets.

@Denzo77
Last active February 19, 2020 13:01
Show Gist options
  • Save Denzo77/d4135a5ea93631e0ee626c71650adc00 to your computer and use it in GitHub Desktop.
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.
/**
* @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