Browse Source

feat: add type-coercion ctor
feat: make everything constexpr

Sam Jaffe 2 years ago
parent
commit
04f68c57c6
2 changed files with 15 additions and 8 deletions
  1. 13 8
      include/opaque_typedef/opaque_typedef.hpp
  2. 2 0
      include/opaque_typedef/traits.hpp

+ 13 - 8
include/opaque_typedef/opaque_typedef.hpp

@@ -67,7 +67,7 @@ namespace types {
     using underlying_type = underlying_type_t<Base>;
 
   private:
-    Base value_;
+    value_type value_;
 
   public:
     /**
@@ -84,9 +84,14 @@ namespace types {
      * to reason about, and half as error-prone due to limitting the number of
      * mixups
      */
-    explicit opaque_typedef(Base const & value) : value_(value){};
-    explicit opaque_typedef(Base && value)
-        : value_(std::forward<Base>(value)){};
+    constexpr explicit opaque_typedef(value_type const & value)
+        : value_(value) {}
+    constexpr explicit opaque_typedef(value_type && value)
+        : value_(std::forward<value_type>(value)) {}
+
+    template <typename S, REQUIRES(std::is_constructible_v<value_type, S>)>
+    constexpr explicit opaque_typedef(S const & value)
+        : value_(static_cast<value_type>(value)) {}
     /**
      * Implicit conversion between multiple opaque_typedef types can be
      * accomplished by defining this constructor for the two types. The weakness
@@ -102,14 +107,14 @@ namespace types {
      * \endcode
      */
     template <typename B, typename T, template <typename> class... S>
-    opaque_typedef(opaque_typedef<B, T, S...> const & other);
+    constexpr opaque_typedef(opaque_typedef<B, T, S...> const & other);
 
     /**
      * Explicit conversion for use in static_casts, or by invoking get()
      * directly in your code.
      */
-    value_type const & get() const { return value_; }
-    explicit operator value_type const &() const { return value_; }
-    underlying_type operator*() const { return value_; }
+    constexpr value_type const & get() const { return value_; }
+    constexpr explicit operator value_type const &() const { return value_; }
+    constexpr underlying_type operator*() const { return value_; }
   };
 }

+ 2 - 0
include/opaque_typedef/traits.hpp

@@ -8,6 +8,8 @@
 
 #pragma once
 
+#define REQUIRES(...) typename = std::enable_if_t<__VA_ARGS__>
+
 namespace types {
   template <typename Base, typename = void> struct underlying_type {
     using type = Base const &;