jle_cpp_tk  0.0 2015-04-03 sh1:"d699093732dd5f321606d0ff7a6b63b229f1922c"
A small, safe, selft contained, soft-realtime C++ toolkit
optional.hpp
1 #ifndef jle_optional__h
2 #define jle_optional__h
3 
4 #include <experimental/optional>
5 
6 
13 namespace jle
14 {
15 
16  struct nullopt_t
17  {
18  // Do not user-declare default constructor at all for
19  // optional_value = {} syntax to work.
20  // nullopt_t() = delete;
21 
22  // Used for constructing nullopt.
23  enum class _Construct { _Token };
24 
25  // Must be constexpr for nullopt_t to be literal.
26  explicit constexpr nullopt_t(_Construct) { }
27  };
28 
29  constexpr nullopt_t nullopt { nullopt_t::_Construct::_Token };
30 
31 
33  struct in_place_t { };
34 
36  constexpr in_place_t in_place { };
37 
38 
42  template<typename _Tp>
43  class optional
44  {
45  private:
46  std::experimental::optional<_Tp> iopt;
47 
48  public:
49  // constructors ..........
50  constexpr optional() noexcept {}
51 
52  constexpr optional(nullopt_t) noexcept {}
53 
54  // Constructors for engaged optionals.
55  constexpr optional(const _Tp& __t)
56  : iopt{__t} {}
57 
58  constexpr optional(_Tp&& __t)
59  : iopt{__t} {}
60 
61  template<typename... _Args>
62  constexpr explicit optional(in_place_t, _Args&&... __args)
63  : iopt{in_place, __args ...} {}
64 
65  template<typename _Up, typename... _Args,
66  typename std::enable_if<std::is_constructible<_Tp,
67  std::initializer_list<_Up>&,
68  _Args&&...>::value,
69  int>::type...>
70  constexpr explicit optional(in_place_t,
71  std::initializer_list<_Up> __il,
72  _Args&&... __args)
73  : iopt{in_place, __il, __args ...} {}
74 
75  // Copy and move constructors.
76  optional(const optional& __other)
77  : iopt{__other.iopt} {}
78 
79  optional(optional&& __other)
80  noexcept(std::is_nothrow_move_constructible<_Tp>())
81  : iopt{__other.iopt} {}
82  // constructors ..........
83 
84 
85 
86 
87 
88 
89  //using value_type = _Tp;
90 
91  optional&
92  operator=(nullopt_t) noexcept
93  {
94  iopt.operator=(std::experimental::nullopt);
95  return *this;
96  }
97 
98  optional&
99  operator=(const optional& __other)
100  {
101  iopt = __other.iopt;
102  return *this;
103 
104  }
105 
106  optional&
107  operator=(optional&& __other)
108  noexcept(std::__and_<std::is_nothrow_move_constructible<_Tp>,
109  std::is_nothrow_move_assignable<_Tp>>())
110  {
111  iopt = __other.iopt;
112  return *this;
113  }
114 
115 
116  template<typename _Up>
117  typename std::enable_if<
118  std::is_same<_Tp, typename std::decay<_Up>::type>::value,
119  optional&
120  >::type
121  operator=(_Up&& __u)
122  {
123  static_assert(std::__and_<std::is_constructible<_Tp, _Up>,
124  std::is_assignable<_Tp&, _Up>>(),
125  "Cannot assign to value type from argument");
126 
127  iopt.operator=(__u);
128  return *this;
129  }
130 
131  template<typename... _Args>
132  void
133  emplace(_Args&&... __args)
134  {
135  static_assert(std::is_constructible<_Tp, _Args&&...>(),
136  "Cannot emplace value type from arguments");
137 
138  iopt.emplace(__args ...);
139  }
140 
141  template<typename _Up, typename... _Args>
142  typename std::enable_if<
143  std::is_constructible<_Tp,
144  std::initializer_list<_Up>&,
145  _Args&&...>::value
146  >::type
147  emplace(std::initializer_list<_Up> __il, _Args&&... __args)
148  {
149  iopt.emplace(__il, __args ...);
150  }
151 
152 
153 
154  void
155  swap(optional& __other)
156  //noexcept(std::is_nothrow_move_constructible<_Tp>()
157  //&& noexcept(swap(declval<_Tp&>(), declval<_Tp&>())))
158  {
159  iopt.swap(__other.iopt);
160  }
161 
162 
163  constexpr const _Tp*
164  operator->() const
165  {
166  if(has_value() == false)
167  throw std::runtime_error("optional not valid on ->");
168 
169  return iopt.operator->();
170  }
171 
172  _Tp*
173  operator->()
174  {
175  if(has_value() == false)
176  throw std::runtime_error("optional not valid on ->");
177 
178  return iopt.operator->();
179  }
180 
181  constexpr const _Tp&
182  operator*() const
183  {
184  if(has_value() == false)
185  throw std::runtime_error("optional not valid on *");
186 
187  return iopt.operator*();
188  }
189 
190  _Tp&
191  operator*()
192  {
193  if(has_value() == false)
194  throw std::runtime_error("optional not valid on ->");
195 
196  return iopt.operator*();
197  }
198 
199  constexpr explicit operator bool() const noexcept
200  {
201  return bool(iopt);
202  }
203 
204  constexpr bool has_value() const noexcept
205  {
206  return bool(iopt);
207  }
208 
209  constexpr const _Tp&
210  value() const
211  {
212  return iopt.value();
213  }
214 
215  _Tp&
216  value()
217  {
218  return iopt.value();
219  }
220 
221  template<typename _Up>
222  constexpr _Tp
223  value_or(_Up&& __u) const&
224  {
225  return iopt.value_or(__u);
226  }
227 
228  template<typename _Up>
229  _Tp
230  value_or(_Up&& __u) &&
231  {
232  return iopt.value_or(__u);
233  }
234 
235  template<typename _Tpa>
236  friend constexpr bool
237  operator==(const optional<_Tpa>& __lhs, const optional<_Tpa>& __rhs);
238 
239  template<typename _Tpa>
240  friend constexpr bool
241  operator!=(const optional<_Tpa>& __lhs, const optional<_Tpa>& __rhs);
242 
243  template<typename _Tpa>
244  friend constexpr bool
245  operator<(const optional<_Tpa>& __lhs, const optional<_Tpa>& __rhs);
246 
247  template<typename _Tpa>
248  friend constexpr bool
249  operator>(const optional<_Tpa>& __lhs, const optional<_Tpa>& __rhs);
250 
251  template<typename _Tpa>
252  friend constexpr bool
253  operator<=(const optional<_Tpa>& __lhs, const optional<_Tpa>& __rhs);
254 
255  template<typename _Tpa>
256  friend constexpr bool
257  operator>=(const optional<_Tpa>& __lhs, const optional<_Tpa>& __rhs);
258 
259  template<typename _Tpa>
260  friend constexpr bool
261  operator==(const optional<_Tpa>& __lhs, nullopt_t) noexcept;
262 
263  template<typename _Tpa>
264  friend constexpr bool
265  operator==(nullopt_t, const optional<_Tpa>& __rhs) noexcept;
266 
267  template<typename _Tpa>
268  friend constexpr bool
269  operator!=(const optional<_Tpa>& __lhs, nullopt_t) noexcept;
270 
271  template<typename _Tpa>
272  friend constexpr bool
273  operator!=(nullopt_t, const optional<_Tpa>& __rhs) noexcept;
274 
275  template<typename _Tpa>
276  friend constexpr bool
277  operator<(const optional<_Tpa>& /* __lhs */, nullopt_t) noexcept;
278 
279  template<typename _Tpa>
280  friend constexpr bool
281  operator<(nullopt_t, const optional<_Tpa>& __rhs) noexcept;
282 
283  template<typename _Tpa>
284  friend constexpr bool
285  operator>(const optional<_Tpa>& __lhs, nullopt_t) noexcept;
286 
287  template<typename _Tpa>
288  friend constexpr bool
289  operator>(nullopt_t, const optional<_Tpa>& /* __rhs */) noexcept;
290 
291  template<typename _Tpa>
292  friend constexpr bool
293  operator<=(const optional<_Tpa>& __lhs, nullopt_t) noexcept;
294 
295  template<typename _Tpa>
296  friend constexpr bool
297  operator<=(nullopt_t, const optional<_Tpa>& /* __rhs */) noexcept;
298 
299  template<typename _Tpa>
300  friend constexpr bool
301  operator>=(const optional<_Tpa>& /* __lhs */, nullopt_t) noexcept;
302 
303  template<typename _Tpa>
304  friend constexpr bool
305  operator>=(nullopt_t, const optional<_Tpa>& __rhs) noexcept;
306 
307  template<typename _Tpa>
308  friend constexpr bool
309  operator==(const optional<_Tpa>& __lhs, const _Tpa& __rhs);
310 
311  template<typename _Tpa>
312  friend constexpr bool
313  operator==(const _Tpa& __lhs, const optional<_Tpa>& __rhs);
314 
315  template<typename _Tpa>
316  friend constexpr bool
317  operator!=(const optional<_Tpa>& __lhs, _Tpa const& __rhs);
318 
319  template<typename _Tpa>
320  friend constexpr bool
321  operator!=(const _Tpa& __lhs, const optional<_Tpa>& __rhs);
322 
323  template<typename _Tpa>
324  friend constexpr bool
325  operator<(const optional<_Tpa>& __lhs, const _Tpa& __rhs);
326 
327  template<typename _Tpa>
328  friend constexpr bool
329  operator<(const _Tpa& __lhs, const optional<_Tpa>& __rhs);
330 
331  template<typename _Tpa>
332  friend constexpr bool
333  operator>(const optional<_Tpa>& __lhs, const _Tpa& __rhs);
334 
335  template<typename _Tpa>
336  friend constexpr bool
337  operator>(const _Tpa& __lhs, const optional<_Tpa>& __rhs);
338 
339  template<typename _Tpa>
340  friend constexpr bool
341  operator<=(const optional<_Tpa>& __lhs, const _Tpa& __rhs);
342 
343  template<typename _Tpa>
344  friend constexpr bool
345  operator<=(const _Tpa& __lhs, const optional<_Tpa>& __rhs);
346 
347  template<typename _Tpa>
348  friend constexpr bool
349  operator>=(const optional<_Tpa>& __lhs, const _Tpa& __rhs);
350 
351  template<typename _Tpa>
352  friend constexpr bool
353  operator>=(const _Tpa& __lhs, const optional<_Tpa>& __rhs);
354 
355  };
356 
357 
358  template<typename _Tp>
359  constexpr bool
360  operator==(const optional<_Tp>& __lhs, const optional<_Tp>& __rhs)
361  {
362  return __lhs.iopt == __rhs.iopt;
363  }
364 
365  template<typename _Tp>
366  constexpr bool
367  operator!=(const optional<_Tp>& __lhs, const optional<_Tp>& __rhs)
368  {
369  return __lhs.iopt != __rhs.iopt;
370  }
371 
372  template<typename _Tp>
373  constexpr bool
374  operator<(const optional<_Tp>& __lhs, const optional<_Tp>& __rhs)
375  {
376  return __lhs.iopt < __rhs.iopt;
377  }
378 
379  template<typename _Tp>
380  constexpr bool
381  operator>(const optional<_Tp>& __lhs, const optional<_Tp>& __rhs)
382  {
383  return __lhs.iopt > __rhs.iopt;
384  }
385 
386  template<typename _Tp>
387  constexpr bool
388  operator<=(const optional<_Tp>& __lhs, const optional<_Tp>& __rhs)
389  {
390  return __lhs.iopt <= __rhs.iopt;
391  }
392 
393  template<typename _Tp>
394  constexpr bool
395  operator>=(const optional<_Tp>& __lhs, const optional<_Tp>& __rhs)
396  {
397  return __lhs.iopt >= __rhs.iopt;
398  }
399 
400  // [X.Y.9] Comparisons with nullopt.
401  template<typename _Tp>
402  constexpr bool
403  operator==(const optional<_Tp>& __lhs, nullopt_t) noexcept
404  {
405  return __lhs.iopt == nullopt;
406  }
407 
408  template<typename _Tp>
409  constexpr bool
410  operator==(nullopt_t, const optional<_Tp>& __rhs) noexcept
411  {
412  return nullopt == __rhs.iopt;
413  }
414 
415  template<typename _Tp>
416  constexpr bool
417  operator!=(const optional<_Tp>& __lhs, nullopt_t) noexcept
418  {
419  return __lhs.iopt != nullopt;
420  }
421 
422  template<typename _Tp>
423  constexpr bool
424  operator!=(nullopt_t, const optional<_Tp>& __rhs) noexcept
425  {
426  return nullopt != __rhs.iopt;
427  }
428 
429  template<typename _Tp>
430  constexpr bool
431  operator<(const optional<_Tp>& /* __lhs */, nullopt_t) noexcept
432  {
433  return false;
434  }
435 
436  template<typename _Tp>
437  constexpr bool
438  operator<(nullopt_t, const optional<_Tp>& __rhs) noexcept
439  {
440  return nullopt < __rhs.iopt;
441  }
442 
443  template<typename _Tp>
444  constexpr bool
445  operator>(const optional<_Tp>& __lhs, nullopt_t) noexcept
446  {
447  return __lhs.iopt > nullopt;
448  }
449 
450  template<typename _Tp>
451  constexpr bool
452  operator>(nullopt_t, const optional<_Tp>& /* __rhs */) noexcept
453  {
454  return false;
455  }
456 
457  template<typename _Tp>
458  constexpr bool
459  operator<=(const optional<_Tp>& __lhs, nullopt_t) noexcept
460  {
461  return __lhs.iopt <= nullopt;
462  }
463 
464  template<typename _Tp>
465  constexpr bool
466  operator<=(nullopt_t, const optional<_Tp>& /* __rhs */) noexcept
467  {
468  return true;
469  }
470 
471  template<typename _Tp>
472  constexpr bool
473  operator>=(const optional<_Tp>& /* __lhs */, nullopt_t) noexcept
474  {
475  return true;
476  }
477 
478  template<typename _Tp>
479  constexpr bool
480  operator>=(nullopt_t, const optional<_Tp>& __rhs) noexcept
481  {
482  { return !__rhs.iopt; }
483  }
484 
485  // [X.Y.10] Comparisons with value type.
486  template<typename _Tp>
487  constexpr bool
488  operator==(const optional<_Tp>& __lhs, const _Tp& __rhs)
489  {
490  return __lhs.iopt == __rhs;
491  }
492 
493  template<typename _Tp>
494  constexpr bool
495  operator==(const _Tp& __lhs, const optional<_Tp>& __rhs)
496  {
497  return __lhs == __rhs.iopt;
498  }
499 
500  template<typename _Tp>
501  constexpr bool
502  operator!=(const optional<_Tp>& __lhs, _Tp const& __rhs)
503  {
504  return __lhs.iopt != __rhs;
505  }
506 
507  template<typename _Tp>
508  constexpr bool
509  operator!=(const _Tp& __lhs, const optional<_Tp>& __rhs)
510  {
511  return __lhs != __rhs.iopt;
512  }
513 
514  template<typename _Tp>
515  constexpr bool
516  operator<(const optional<_Tp>& __lhs, const _Tp& __rhs)
517  {
518  return __lhs.iopt < __rhs;
519  }
520 
521  template<typename _Tp>
522  constexpr bool
523  operator<(const _Tp& __lhs, const optional<_Tp>& __rhs)
524  {
525  return __lhs < __rhs.iopt;
526  }
527 
528  template<typename _Tp>
529  constexpr bool
530  operator>(const optional<_Tp>& __lhs, const _Tp& __rhs)
531  {
532  return __lhs.iopt > __rhs;
533  }
534 
535  template<typename _Tp>
536  constexpr bool
537  operator>(const _Tp& __lhs, const optional<_Tp>& __rhs)
538  {
539  return __lhs > __rhs.iopt;
540  }
541 
542  template<typename _Tp>
543  constexpr bool
544  operator<=(const optional<_Tp>& __lhs, const _Tp& __rhs)
545  {
546  return __lhs.iopt <= __rhs;
547  }
548 
549  template<typename _Tp>
550  constexpr bool
551  operator<=(const _Tp& __lhs, const optional<_Tp>& __rhs)
552  {
553  return __lhs <= __rhs.iopt;
554  }
555 
556  template<typename _Tp>
557  constexpr bool
558  operator>=(const optional<_Tp>& __lhs, const _Tp& __rhs)
559  {
560  return __lhs.iopt >= __rhs;
561  }
562 
563  template<typename _Tp>
564  constexpr bool
565  operator>=(const _Tp& __lhs, const optional<_Tp>& __rhs)
566  {
567  return __lhs >= __rhs.iopt;
568  }
569 
570 
571  template<typename _Tp>
572  inline void
573  swap(optional<_Tp>& __lhs, optional<_Tp>& __rhs)
574  noexcept(noexcept(__lhs.swap(__rhs)))
575  { std::swap(__lhs.iopt, __rhs.iopt); }
576 
577  template<typename _Tp>
578  constexpr optional<std::decay_t<_Tp>>
579  make_optional(_Tp&& __t)
580  {
581  return optional<std::decay_t<_Tp>> { std::forward<_Tp>(__t) };
582  }
583 
584 
585 template<typename _Tp>
586 std::ostream& operator<< (std::ostream& os, const jle::optional<_Tp>& opt)
587 {
588  if(!opt) os << "null";
589  else os << *opt;
590  return os;
591 }
592 
593 
594 } // namespace jle
595 
596 #endif // jle_optional__h
Tag type for in-place construction.
Definition: optional.hpp:33
Definition: optional.hpp:16
constexpr in_place_t in_place
Tag for in-place construction.
Definition: optional.hpp:36
Class template for optional values.
Definition: optional.hpp:43
generic namespace
Definition: alarm.cpp:12