1 #ifndef jle_optional__h 2 #define jle_optional__h 4 #include <experimental/optional> 23 enum class _Construct { _Token };
26 explicit constexpr
nullopt_t(_Construct) { }
29 constexpr
nullopt_t nullopt { nullopt_t::_Construct::_Token };
42 template<
typename _Tp>
46 std::experimental::optional<_Tp> iopt;
58 constexpr optional(_Tp&& __t)
61 template<
typename... _Args>
62 constexpr
explicit optional(
in_place_t, _Args&&... __args)
65 template<
typename _Up,
typename... _Args,
66 typename std::enable_if<std::is_constructible<_Tp,
67 std::initializer_list<_Up>&,
71 std::initializer_list<_Up> __il,
73 : iopt{
in_place, __il, __args ...} {}
76 optional(
const optional& __other)
77 : iopt{__other.iopt} {}
79 optional(optional&& __other)
80 noexcept(std::is_nothrow_move_constructible<_Tp>())
81 : iopt{__other.iopt} {}
94 iopt.operator=(std::experimental::nullopt);
99 operator=(
const optional& __other)
107 operator=(optional&& __other)
108 noexcept(std::__and_<std::is_nothrow_move_constructible<_Tp>,
109 std::is_nothrow_move_assignable<_Tp>>())
116 template<
typename _Up>
117 typename std::enable_if<
118 std::is_same<_Tp, typename std::decay<_Up>::type>::value,
123 static_assert(std::__and_<std::is_constructible<_Tp, _Up>,
124 std::is_assignable<_Tp&, _Up>>(),
125 "Cannot assign to value type from argument");
131 template<
typename... _Args>
133 emplace(_Args&&... __args)
135 static_assert(std::is_constructible<_Tp, _Args&&...>(),
136 "Cannot emplace value type from arguments");
138 iopt.emplace(__args ...);
141 template<
typename _Up,
typename... _Args>
142 typename std::enable_if<
143 std::is_constructible<_Tp,
144 std::initializer_list<_Up>&,
147 emplace(std::initializer_list<_Up> __il, _Args&&... __args)
149 iopt.emplace(__il, __args ...);
155 swap(optional& __other)
159 iopt.swap(__other.iopt);
166 if(has_value() ==
false)
167 throw std::runtime_error(
"optional not valid on ->");
169 return iopt.operator->();
175 if(has_value() ==
false)
176 throw std::runtime_error(
"optional not valid on ->");
178 return iopt.operator->();
184 if(has_value() ==
false)
185 throw std::runtime_error(
"optional not valid on *");
187 return iopt.operator*();
193 if(has_value() ==
false)
194 throw std::runtime_error(
"optional not valid on ->");
196 return iopt.operator*();
199 constexpr
explicit operator bool()
const noexcept
204 constexpr
bool has_value()
const noexcept
221 template<
typename _Up>
223 value_or(_Up&& __u)
const&
225 return iopt.value_or(__u);
228 template<
typename _Up>
230 value_or(_Up&& __u) &&
232 return iopt.value_or(__u);
235 template<
typename _Tpa>
236 friend constexpr
bool 239 template<
typename _Tpa>
240 friend constexpr
bool 243 template<
typename _Tpa>
244 friend constexpr
bool 245 operator<(const optional<_Tpa>& __lhs,
const optional<_Tpa>& __rhs);
247 template<
typename _Tpa>
248 friend constexpr
bool 251 template<
typename _Tpa>
252 friend constexpr
bool 253 operator<=(const optional<_Tpa>& __lhs,
const optional<_Tpa>& __rhs);
255 template<
typename _Tpa>
256 friend constexpr
bool 259 template<
typename _Tpa>
260 friend constexpr
bool 263 template<
typename _Tpa>
264 friend constexpr
bool 267 template<
typename _Tpa>
268 friend constexpr
bool 271 template<
typename _Tpa>
272 friend constexpr
bool 275 template<
typename _Tpa>
276 friend constexpr
bool 277 operator<(const optional<_Tpa>& ,
nullopt_t) noexcept;
279 template<
typename _Tpa>
280 friend constexpr
bool 281 operator<(nullopt_t, const optional<_Tpa>& __rhs) noexcept;
283 template<
typename _Tpa>
284 friend constexpr
bool 287 template<
typename _Tpa>
288 friend constexpr
bool 291 template<
typename _Tpa>
292 friend constexpr
bool 293 operator<=(const optional<_Tpa>& __lhs,
nullopt_t) noexcept;
295 template<
typename _Tpa>
296 friend constexpr
bool 297 operator<=(nullopt_t, const optional<_Tpa>& ) noexcept;
299 template<
typename _Tpa>
300 friend constexpr
bool 303 template<
typename _Tpa>
304 friend constexpr
bool 307 template<
typename _Tpa>
308 friend constexpr
bool 311 template<
typename _Tpa>
312 friend constexpr
bool 315 template<
typename _Tpa>
316 friend constexpr
bool 319 template<
typename _Tpa>
320 friend constexpr
bool 323 template<
typename _Tpa>
324 friend constexpr
bool 325 operator<(const optional<_Tpa>& __lhs,
const _Tpa& __rhs);
327 template<
typename _Tpa>
328 friend constexpr
bool 329 operator<(const _Tpa& __lhs, const optional<_Tpa>& __rhs);
331 template<
typename _Tpa>
332 friend constexpr
bool 335 template<
typename _Tpa>
336 friend constexpr
bool 339 template<
typename _Tpa>
340 friend constexpr
bool 341 operator<=(const optional<_Tpa>& __lhs,
const _Tpa& __rhs);
343 template<
typename _Tpa>
344 friend constexpr
bool 345 operator<=(const _Tpa& __lhs, const optional<_Tpa>& __rhs);
347 template<
typename _Tpa>
348 friend constexpr
bool 351 template<
typename _Tpa>
352 friend constexpr
bool 358 template<
typename _Tp>
362 return __lhs.iopt == __rhs.iopt;
365 template<
typename _Tp>
369 return __lhs.iopt != __rhs.iopt;
372 template<
typename _Tp>
374 operator<(const optional<_Tp>& __lhs,
const optional<_Tp>& __rhs)
376 return __lhs.iopt < __rhs.iopt;
379 template<
typename _Tp>
383 return __lhs.iopt > __rhs.iopt;
386 template<
typename _Tp>
388 operator<=(const optional<_Tp>& __lhs,
const optional<_Tp>& __rhs)
390 return __lhs.iopt <= __rhs.iopt;
393 template<
typename _Tp>
397 return __lhs.iopt >= __rhs.iopt;
401 template<
typename _Tp>
405 return __lhs.iopt == nullopt;
408 template<
typename _Tp>
412 return nullopt == __rhs.iopt;
415 template<
typename _Tp>
419 return __lhs.iopt != nullopt;
422 template<
typename _Tp>
426 return nullopt != __rhs.iopt;
429 template<
typename _Tp>
431 operator<(const optional<_Tp>& ,
nullopt_t) noexcept
436 template<
typename _Tp>
438 operator<(nullopt_t, const optional<_Tp>& __rhs) noexcept
440 return nullopt < __rhs.iopt;
443 template<
typename _Tp>
447 return __lhs.iopt > nullopt;
450 template<
typename _Tp>
457 template<
typename _Tp>
459 operator<=(const optional<_Tp>& __lhs,
nullopt_t) noexcept
461 return __lhs.iopt <= nullopt;
464 template<
typename _Tp>
466 operator<=(nullopt_t, const optional<_Tp>& ) noexcept
471 template<
typename _Tp>
478 template<
typename _Tp>
482 {
return !__rhs.iopt; }
486 template<
typename _Tp>
490 return __lhs.iopt == __rhs;
493 template<
typename _Tp>
497 return __lhs == __rhs.iopt;
500 template<
typename _Tp>
504 return __lhs.iopt != __rhs;
507 template<
typename _Tp>
511 return __lhs != __rhs.iopt;
514 template<
typename _Tp>
516 operator<(const optional<_Tp>& __lhs,
const _Tp& __rhs)
518 return __lhs.iopt < __rhs;
521 template<
typename _Tp>
523 operator<(const _Tp& __lhs, const optional<_Tp>& __rhs)
525 return __lhs < __rhs.iopt;
528 template<
typename _Tp>
532 return __lhs.iopt > __rhs;
535 template<
typename _Tp>
539 return __lhs > __rhs.iopt;
542 template<
typename _Tp>
544 operator<=(const optional<_Tp>& __lhs,
const _Tp& __rhs)
546 return __lhs.iopt <= __rhs;
549 template<
typename _Tp>
551 operator<=(const _Tp& __lhs, const optional<_Tp>& __rhs)
553 return __lhs <= __rhs.iopt;
556 template<
typename _Tp>
560 return __lhs.iopt >= __rhs;
563 template<
typename _Tp>
567 return __lhs >= __rhs.iopt;
571 template<
typename _Tp>
574 noexcept(noexcept(__lhs.swap(__rhs)))
575 { std::swap(__lhs.iopt, __rhs.iopt); }
577 template<
typename _Tp>
579 make_optional(_Tp&& __t)
585 template<
typename _Tp>
586 std::ostream& operator<< (std::ostream& os, const jle::optional<_Tp>& opt)
588 if(!opt) os <<
"null";
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