// // opaque_typedef.hpp // opaque-type // // Created by Sam Jaffe on 8/16/16. // #pragma once #define OPAQUE_TYPE_OPERATOR(name, op) \ template struct name; \ \ template \ struct name { \ friend R operator op(O1 const & lhs, O2 const & rhs) { \ return R(lhs.value() op rhs.value()); \ } \ }; \ \ template \ struct name { \ friend R & operator op##=(R & lhs, O2 const & rhs) { \ return lhs = R(lhs.value() op rhs.value()); \ } \ \ friend R operator op(R const & lhs, O2 const & rhs) { \ return R(lhs.value() op rhs.value()); \ } \ }; OPAQUE_TYPE_OPERATOR(addition, +) OPAQUE_TYPE_OPERATOR(subtraction, -) OPAQUE_TYPE_OPERATOR(multiplication, *) OPAQUE_TYPE_OPERATOR(division, /) #undef OPAQUE_TYPE_OPERATOR template class opaque_typedef { public: opaque_typedef() : _value() {} explicit opaque_typedef(T val) : _value(val) {} explicit operator T() const { return _value; } T value() const { return _value; } private: T _value; };