Enhancing strict types with generic mixins
I was playing around with strict types today, and realized you could enhance strict types very easily and pull operators you want. I don't know if this is already a popular pattern or not, but when I got to it felt really cool!
// Standard generic "strict type" wrapper
template <typename T, typename Derived>
struct Strict {
constexpr explicit Strict(T value)
: mValue { value }
{}
static Derived Make(T value) {
return Derived{Strict<T, Derived>{value}};
}
T mValue;
};
template <typename T>
struct Spaceship {
constexpr auto operator<=>(const Spaceship& other) const noexcept {
return static_cast<const T&>(*this).mValue <=> static_cast<const T&>(other).mValue;
}
};
template <typename T>
struct StreamOut {
friend std::ostream& operator<< (std::ostream& stream, const StreamOut<T>& streamOut) {
stream << static_cast<const T&>(streamOut).mValue;
return stream;
}
};
template <typename T>
struct Mult {
constexpr auto operator*(const Mult& other) const noexcept {
return T::Make(static_cast<const T&>(*this).mValue * static_cast<const T&>(other).mValue);
}
};
// We can inherit and add traits we need!! :)
struct MyType: Strict<int, MyType>, Spaceship<MyType>, Mult<MyType>, StreamOut<MyType>
{};
int main() {
auto x = MyType::Make(4);
auto y = MyType::Make(9);
std::cout << std::boolalpha << (x <= y) << std::endl;
std::cout << x * y << std::endl;
}
[https://godbolt.org/z/rT84qox36](https://godbolt.org/z/rT84qox36)
https://redd.it/1p7fwv0
@r_cpp
Post #24358
17