浏览代码

feat: implement Boolean, underlying_type

Sam Jaffe 2 年之前
父节点
当前提交
9494d786be
共有 3 个文件被更改,包括 35 次插入2 次删除
  1. 4 0
      include/opaque_typedef/arithmetic.hpp
  2. 8 2
      include/opaque_typedef/opaque_typedef.hpp
  3. 23 0
      include/opaque_typedef/traits.hpp

+ 4 - 0
include/opaque_typedef/arithmetic.hpp

@@ -1,6 +1,10 @@
 #pragma once
 
 namespace types {
+  template <typename Self> struct Boolean {
+    operator bool() const { return static_cast<Self const &>(*this).get(); }
+  };
+
   template <typename Self> struct Incrementable {
     friend Self operator++(Self & self, int) {
       Self copy = self;

+ 8 - 2
include/opaque_typedef/opaque_typedef.hpp

@@ -14,6 +14,7 @@
 
 #include "arithmetic.hpp"
 #include "comparable.hpp"
+#include "traits.hpp"
 
 namespace types {
   /**
@@ -61,6 +62,10 @@ namespace types {
   template <typename Base, typename Tag, template <typename> class... Skills>
   class opaque_typedef
       : public Skills<opaque_typedef<Base, Tag, Skills...>>... {
+  public:
+    using value_type = Base;
+    using underlying_type = underlying_type_t<Base>;
+
   private:
     Base value_;
 
@@ -103,7 +108,8 @@ namespace types {
      * Explicit conversion for use in static_casts, or by invoking get()
      * directly in your code.
      */
-    Base const & get() const { return value_; }
-    explicit operator Base const &() const { return value_; }
+    value_type const & get() const { return value_; }
+    explicit operator value_type const &() const { return value_; }
+    underlying_type operator*() const { return value_; }
   };
 }

+ 23 - 0
include/opaque_typedef/traits.hpp

@@ -0,0 +1,23 @@
+//
+//  traits.hpp
+//  opaque_typedef
+//
+//  Created by Sam Jaffe on 12/1/23.
+//  Copyright © 2023 Sam Jaffe. All rights reserved.
+//
+
+#pragma once
+
+namespace types {
+  template <typename Base, typename = void> struct underlying_type {
+    using type = Base const &;
+  };
+
+  template <typename Base>
+  struct underlying_type<Base, std::void_t<typename Base::underlying_type>> {
+    using type = typename Base::underlying_type;
+  };
+
+  template <typename Base>
+  using underlying_type_t = typename underlying_type<Base>::type;
+}