| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475 |
- //
- // opaque_typedef.hpp
- // opaque-type
- //
- // Inspired by https://foonathan.github.io/blog/2016/10/19/strong-typedefs.html and others
- //
- // Created by Sam Jaffe on 8/16/16.
- //
- #pragma once
- #include <type_traits>
- namespace types { namespace detail {
- template <typename FromOpaque>
- struct is_a {
- FromOpaque const & self() const {
- return *(FromOpaque const *)(void const *)(this);
- }
- };
- }}
- namespace types {
- template <typename Base, typename Tag, template <typename> class... Skills>
- class opaque_typedef : public Skills<opaque_typedef<Base, Tag, Skills...>>... {
- public:
- using super = opaque_typedef;
-
- private:
- Base value_;
-
- public:
- opaque_typedef() = default;
- explicit opaque_typedef(Base const & value) : value_(value) {};
- explicit opaque_typedef(Base && value) : value_(std::forward<Base>(value)) {};
-
- Base const & get() const { return value_; }
- explicit operator Base const &() const { return value_; }
- };
-
- template <typename Opaque>
- struct EqualityComparable {
- friend bool operator==(Opaque const & lhs, Opaque const & rhs) {
- return lhs.get() == rhs.get();
- }
- friend bool operator!=(Opaque const & lhs, Opaque const & rhs) {
- return !(lhs == rhs);
- }
- };
-
- template <typename Opaque>
- struct Comparable : EqualityComparable<Opaque> {
- friend bool operator<(Opaque const & lhs, Opaque const & rhs) {
- return lhs.get() < rhs.get();
- }
- friend bool operator>(Opaque const & lhs, Opaque const & rhs) {
- return rhs.get() < lhs.get();
- }
- friend bool operator<=(Opaque const & lhs, Opaque const & rhs) {
- return !(rhs.get() < lhs.get());
- }
- friend bool operator>=(Opaque const & lhs, Opaque const & rhs) {
- return !(lhs.get() < rhs.get());
- }
- };
-
- template <typename ToOpaque>
- struct Convertable {
- template <typename FromOpaque>
- class type : detail::is_a<FromOpaque> {
- public:
- operator ToOpaque() const;
- };
- };
- }
|