aboutsummaryrefslogtreecommitdiff
path: root/src/unique.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/unique.hpp')
-rw-r--r--src/unique.hpp31
1 files changed, 27 insertions, 4 deletions
diff --git a/src/unique.hpp b/src/unique.hpp
index 27ea71e..c214dbc 100644
--- a/src/unique.hpp
+++ b/src/unique.hpp
@@ -26,11 +26,13 @@ class Unique
26 constexpr Unique& operator=(Unique const&) = default; 26 constexpr Unique& operator=(Unique const&) = default;
27 constexpr Unique& operator=(Unique&&) = default; 27 constexpr Unique& operator=(Unique&&) = default;
28 28
29 // Forbid construction with any other class, especially with types that convert naturally to UnderlyingType. 29 // Forbid construction with any other class, especially with types that convert naturally to T.
30 // For instance, this prevents construction with a float when UnderlyingType is an integer type. 30 // For instance, this prevents construction with a float when T is an integer type.
31 // Conversion will have to be explicit and the developer will be aware of it. 31 // Conversion will have to be explicit and the developer will be aware of it.
32 // However we want to keep the same-type copy constructors (including with an inherited class), hence the enable_if stuff. 32 // However we want to keep the same-type copy constructors (including with an inherited class), hence the enable_if stuff.
33 template <typename AnyOtherClass, std::enable_if_t<!std::is_base_of_v<self, std::decay_t<AnyOtherClass>>, bool> = true> 33 template <typename AnyOtherClass, std::enable_if_t<!std::is_base_of_v<self, std::decay_t<AnyOtherClass>>, bool> = true>
34 Unique(AnyOtherClass const&) = delete;
35 template <typename AnyOtherClass, std::enable_if_t<!std::is_base_of_v<self, std::decay_t<AnyOtherClass>>, bool> = true>
34 Unique(AnyOtherClass&&) = delete; 36 Unique(AnyOtherClass&&) = delete;
35 37
36 // can't implicitly affect from base type 38 // can't implicitly affect from base type
@@ -38,8 +40,8 @@ class Unique
38 constexpr Unique& operator=(T&&) = delete; 40 constexpr Unique& operator=(T&&) = delete;
39 41
40 // cast 42 // cast
41 constexpr operator T() const noexcept { return val; } 43 constexpr operator T const&() const noexcept { return val; }
42 constexpr T value() const noexcept { return val; } 44 constexpr T const& value() const noexcept { return val; }
43 45
44 // pre-increment 46 // pre-increment
45 auto& operator++() noexcept 47 auto& operator++() noexcept
@@ -71,12 +73,33 @@ class Unique<T, TAG, std::enable_if_t<!std::is_scalar_v<T>>>
71: public T 73: public T
72{ 74{
73 public: 75 public:
76 using self = Unique<T, TAG, void>;
74 using type = T; 77 using type = T;
75 using T::T; 78 using T::T;
76 explicit Unique(T const& b_) 79 explicit Unique(T const& b_)
77 : T{ b_ } 80 : T{ b_ }
78 { 81 {
79 } 82 }
83
84 // rule of 5
85 constexpr Unique() = default;
86 constexpr Unique(Unique const&) = default;
87 constexpr Unique(Unique&&) = default;
88 constexpr Unique& operator=(Unique const&) = default;
89 constexpr Unique& operator=(Unique&&) = default;
90
91 // Forbid construction with any other class, especially with types that convert naturally to T.
92 // For instance, this prevents construction with a float when T is an integer type.
93 // Conversion will have to be explicit and the developer will be aware of it.
94 // However we want to keep the same-type copy constructors (including with an inherited class), hence the enable_if stuff.
95 template <typename AnyOtherClass, std::enable_if_t<!std::is_base_of_v<self, std::decay_t<AnyOtherClass>>, bool> = true>
96 Unique(AnyOtherClass const&) = delete;
97 template <typename AnyOtherClass, std::enable_if_t<!std::is_base_of_v<self, std::decay_t<AnyOtherClass>>, bool> = true>
98 Unique(AnyOtherClass&&) = delete;
99
100 // can't implicitly affect from base type
101 Unique& operator=(T const&) = delete;
102 constexpr Unique& operator=(T&&) = delete;
80}; 103};
81 104
82#define DECLARE_UNIQUE_TYPE(_name, _type) using _name = Unique<_type, class Unique_##_name##_Tag> 105#define DECLARE_UNIQUE_TYPE(_name, _type) using _name = Unique<_type, class Unique_##_name##_Tag>