siplasplas
optional.hpp
1 #ifndef SIPLASPLAS_VARIANT_OPTIONAL_HPP
2 #define SIPLASPLAS_VARIANT_OPTIONAL_HPP
3 
4 #include "variant.hpp"
5 
6 namespace cpp
7 {
8 
9 template<typename T>
10 class Optional
11 {
12 public:
13  Optional() = default;
14 
15  template<typename Arg, typename... Args>
16  Optional(Arg&& arg, Args&&... args) :
17  _variant{T{std::forward<Arg>(arg), std::forward<Args>(args)...}}
18  {}
19 
20  template<typename U>
21  Optional(const Optional<U>& other) :
22  Optional{other.empty() ? Optional() : other.get()}
23  {}
24 
25  template<typename U>
26  Optional(Optional<U>&& other) :
27  Optional{other.empty() ? Optional() : std::move(std::move(other).get())}
28  {}
29 
30  template<typename U>
31  Optional& operator=(U&& value)
32  {
33  _variant = T{std::forward<U>(value)};
34  return *this;
35  }
36 
37  template<typename U>
38  Optional& operator=(const Optional<U>& other)
39  {
40  if(other.empty())
41  {
42  clear();
43  }
44  else
45  {
46  _variant = other.get();
47  }
48 
49  return *this;
50  }
51 
52  template<typename U>
53  Optional& operator=(Optional<U>&& other)
54  {
55  if(other.empty())
56  {
57  clear();
58  }
59  else
60  {
61  _variant = std::move(std::move(other).get());
62  }
63 
64  return *this;
65  }
66 
67  const T& get() const
68  {
69  return _variant.template get<T>();
70  }
71 
72  T& get()
73  {
74  return _variant.template get<T>();
75  }
76 
77  const T* operator->() const
78  {
79  return &get();
80  }
81 
82  T* operator->()
83  {
84  return &get();
85  }
86 
87  void clear()
88  {
89  _variant.clear();
90  }
91 
92  bool empty() const
93  {
94  return _variant.empty();
95  }
96 
97  explicit operator bool() const
98  {
99  return !empty();
100  }
101 
102 private:
103  cpp::Variant<T> _variant;
104 };
105 
106 class Nothing
107 {
108 public:
109  template<typename T>
110  operator Optional<T>()
111  {
112  return Optional<T>();
113  }
114 };
115 
116 template<typename T>
117 Optional<std::decay_t<T>> just(T&& value)
118 {
119  return {value};
120 }
121 
122 inline Nothing nothing()
123 {
124  return {};
125 }
126 
127 }
128 
129 #endif // SIPLASPLAS_VARIANT_OPTIONAL_HPP
Definition: messaging.hpp:8
Definition: optional.hpp:106
Definition: optional.hpp:10