Backport
optional.hpp
Go to the documentation of this file.
1 
7 /*
8  The MIT License (MIT)
9 
10  Copyright (c) 2020 Matthew Rodusek All rights reserved.
11 
12  Permission is hereby granted, free of charge, to any person obtaining a copy
13  of this software and associated documentation files (the "Software"), to deal
14  in the Software without restriction, including without limitation the rights
15  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16  copies of the Software, and to permit persons to whom the Software is
17  furnished to do so, subject to the following conditions:
18 
19  The above copyright notice and this permission notice shall be included in
20  all copies or substantial portions of the Software.
21 
22  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28  SOFTWARE.
29 */
30 #ifndef BPSTD_OPTIONAL_HPP
31 #define BPSTD_OPTIONAL_HPP
32 
33 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
34 # pragma once
35 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
36 
37 #include "detail/config.hpp"
38 #include "detail/enable_overload.hpp" // enable_overload_if, disable_overload_if
39 
40 #include "utility.hpp" // in_place_t, forward, move
41 #include "functional.hpp" // invoke_result_t
42 #include "type_traits.hpp"
43 
44 #include <initializer_list> // std::initializer_list
45 #include <type_traits> // enable_if
46 #include <stdexcept> // std::logic_error
47 #include <new> // placement new
48 
49 BPSTD_COMPILER_DIAGNOSTIC_PREAMBLE
50 
51 namespace bpstd {
52 
53  template <typename> class optional;
54 
55  namespace detail {
56 
57  //==========================================================================
58  // trait : is_optional
59  //==========================================================================
60 
61  template <typename T, typename U>
62  using optional_is_convertible = conjunction<
63  std::is_constructible<T, optional<U>&>,
64  std::is_constructible<T, const optional<U>&>,
65  std::is_constructible<T, optional<U>&&>,
66  std::is_constructible<T, const optional<U>&&>,
67  std::is_convertible<optional<U>&, T>,
68  std::is_convertible<const optional<U>&, T>,
69  std::is_convertible<optional<U>&&, T>,
70  std::is_convertible<const optional<U>&&, T>
71  >;
72 
73  template <typename T, typename U>
74  using optional_is_copy_convertible = conjunction<
75  optional_is_convertible<T,U>,
76  std::is_constructible<T, const U&>
77  >;
78 
79  template <typename T, typename U>
80  using optional_is_move_convertible = conjunction<
81  optional_is_convertible<T,U>,
82  std::is_constructible<T, U&&>
83  >;
84 
85  template <typename T, typename U>
86  using optional_is_value_convertible = conjunction<
87  std::is_constructible<T, U&&>,
90  >;
91 
92  template <typename T, typename U>
93  using optional_is_convert_assignable = conjunction<
94  optional_is_convertible<T,U>,
95  std::is_assignable<T&, optional<U>&>,
96  std::is_assignable<T&, const optional<U>&>,
97  std::is_assignable<T&, optional<U>&&>,
98  std::is_assignable<T&, const optional<U>&&>
99  >;
100 
101  template <typename T, typename U>
102  using optional_is_copy_convert_assignable = conjunction<
103  optional_is_convert_assignable<T,U>,
104  std::is_constructible<T, const U&>,
105  std::is_assignable<T&, const U&>
106  >;
107 
108  template <typename T, typename U>
109  using optional_is_move_convert_assignable = conjunction<
110  optional_is_convert_assignable<T,U>,
111  std::is_constructible<T, U&&>,
112  std::is_assignable<T&, U&&>
113  >;
114 
115  template <typename T, typename U>
116  using optional_is_value_assignable = conjunction<
118  std::is_constructible<T,U>,
119  std::is_assignable<T,U>,
120  disjunction<
123  >
124  >;
125 
126  } // namespace detail
127 
128  //=========================================================================
129  // class : bad_optional_access
130  //=========================================================================
131 
136  class bad_optional_access : public std::logic_error
137  {
138  public:
139  bad_optional_access() : std::logic_error("bad_optional_access"){}
140  };
141 
142  //=========================================================================
143  // struct : nullopt_t
144  //=========================================================================
145 
147  struct nullopt_t
148  {
149  nullopt_t() = delete;
150  constexpr explicit nullopt_t(int) noexcept{}
151  };
152 
153  //-------------------------------------------------------------------------
154 
156  constexpr nullopt_t nullopt = nullopt_t{0};
157 
158  //=========================================================================
159  // class : optional
160  //=========================================================================
161 
162  namespace detail {
163 
164  template <typename T, bool IsTrivial> class optional_base;
165 
166  template <typename T>
167  class optional_base<T,true>
168  {
169  //---------------------------------------------------------------------
170  // Constructors / Assignment
171  //---------------------------------------------------------------------
172  public:
173  // cppcheck-suppress noExplicitConstructor
174  constexpr optional_base(nullopt_t) noexcept;
175 
176  template <typename...Args>
177  constexpr optional_base(in_place_t, Args&&...args)
178  noexcept(std::is_nothrow_constructible<T,Args...>::value);
179 
180  optional_base(optional_base&& other) = default;
181  optional_base(const optional_base& other) = default;
182 
183  //---------------------------------------------------------------------
184 
185  optional_base& operator=(optional_base&& other) = default;
186  optional_base& operator=(const optional_base& other) = default;
187 
188  //---------------------------------------------------------------------
189  // Protected Modifiers
190  //---------------------------------------------------------------------
191  protected:
192 
193  BPSTD_CPP14_CONSTEXPR T* val() noexcept;
194  constexpr const T* val() const noexcept;
195 
196  constexpr bool contains_value() const noexcept;
197 
198  //---------------------------------------------------------------------
199  // Protected Observers
200  //---------------------------------------------------------------------
201  protected:
202 
203  template <typename...Args>
204  void construct(Args&&...args);
205 
206  void destruct();
207 
208  //---------------------------------------------------------------------
209  // Private Member Types
210  //---------------------------------------------------------------------
211  private:
212 
213  struct empty{};
214  union storage_type {
215  empty nothing;
216  T something;
217 
218  template <typename...Args>
219  constexpr storage_type(in_place_t, Args&&...args)
220  : something(bpstd::forward<Args>(args)...){}
221  constexpr storage_type() : nothing(){}
222  };
223 
224  //---------------------------------------------------------------------
225  // Private Members
226  //---------------------------------------------------------------------
227  private:
228 
229  storage_type m_storage;
230  bool m_engaged;
231  };
232 
233  template <typename T>
234  class optional_base<T,false>
235  {
236  //---------------------------------------------------------------------
237  // Protected Constructors / Destructor / Assignment
238  //---------------------------------------------------------------------
239  protected:
240 
241  // cppcheck-suppress noExplicitConstructor
242  optional_base(nullopt_t) noexcept;
243 
244  template <typename...Args>
245  optional_base(in_place_t, Args&&...args)
246  noexcept(std::is_nothrow_constructible<T,Args...>::value);
247 
248  optional_base(optional_base&& other) = default;
249  optional_base(const optional_base& other) = default;
250 
251  //---------------------------------------------------------------------
252 
253  ~optional_base() noexcept(std::is_nothrow_destructible<T>::value);
254 
255  //---------------------------------------------------------------------
256 
257  optional_base& operator=(optional_base&& other) = default;
258  optional_base& operator=(const optional_base& other) = default;
259 
260  //---------------------------------------------------------------------
261  // Protected Observers
262  //---------------------------------------------------------------------
263  protected:
264 
265  T* val() noexcept;
266  const T* val() const noexcept;
267  bool contains_value() const noexcept;
268 
269  //---------------------------------------------------------------------
270  // Protected Modifiers
271  //---------------------------------------------------------------------
272  protected:
273 
274  template <typename...Args>
275  void construct(Args&&...args);
276  void destruct();
277 
278  //---------------------------------------------------------------------
279  // Private Member Types
280  //---------------------------------------------------------------------
281  private:
282 
283  struct empty{};
284  union storage_type {
285  empty nothing;
286  T something;
287 
288  template <typename...Args>
289  storage_type(in_place_t, Args&&...args)
290  : something(bpstd::forward<Args>(args)...){}
291  storage_type() : nothing(){}
292  ~storage_type(){}
293  };
294 
295  //---------------------------------------------------------------------
296  // Private Members
297  //---------------------------------------------------------------------
298  private:
299 
300  storage_type m_storage;
301  bool m_engaged;
302  };
303  } // namespace detail
304 
339  template <typename T>
340  class optional
341  : detail::optional_base<T,std::is_trivially_destructible<T>::value>
342  {
343  static_assert(
344  !std::is_void<T>::value,
345  "optional<void> is ill-formed"
346  );
347  static_assert(
348  !std::is_reference<T>::value,
349  "optional<T> is ill-formed"
350  );
351  static_assert(
352  !std::is_abstract<T>::value,
353  "optional of an abstract-type is ill-formed"
354  );
355 
356  using base_type = detail::optional_base<T,std::is_trivially_destructible<T>::value>;
357 
358  //-----------------------------------------------------------------------
359  // Public Member Types
360  //-----------------------------------------------------------------------
361  public:
362 
363  using value_type = T;
364 
365  //-----------------------------------------------------------------------
366  // Constructor / Destructor / Assignment
367  //-----------------------------------------------------------------------
368  public:
369 
372  constexpr optional() noexcept;
373  // cppcheck-suppress noExplicitConstructor
374  constexpr optional(nullopt_t) noexcept;
376 
389  // cppcheck-suppress noExplicitConstructor
390  optional(detail::enable_overload_if_t<std::is_copy_constructible<T>::value,const optional&> other);
391  optional(detail::disable_overload_if_t<std::is_copy_constructible<T>::value,const optional&> other) = delete;
392 
407  // cppcheck-suppress noExplicitConstructor
408  optional(detail::enable_overload_if_t<std::is_move_constructible<T>::value,optional&&> other);
409  optional(detail::disable_overload_if_t<std::is_move_constructible<T>::value,optional&&> other) = delete;
410 
439  template <typename U,
440  enable_if_t<detail::optional_is_copy_convertible<T,U>::value && std::is_convertible<const U&, T>::value>* =nullptr>
441  // cppcheck-suppress noExplicitConstructor
442  optional(const optional<U>& other);
443  template <typename U,
444  enable_if_t<detail::optional_is_copy_convertible<T,U>::value && !std::is_convertible<const U&, T>::value>* =nullptr>
445  explicit optional(const optional<U>& other);
447 
476  template <typename U,
477  enable_if_t<detail::optional_is_move_convertible<T,U>::value && std::is_convertible<U&&, T>::value>* =nullptr>
478  // cppcheck-suppress noExplicitConstructor
479  optional(optional<U>&& other);
480  template <typename U,
481  enable_if_t<detail::optional_is_move_convertible<T,U>::value && !std::is_convertible<U&&, T>::value>* =nullptr>
482  explicit optional(optional<U>&& other);
484 
492  template <typename...Args,
493  typename=enable_if_t<std::is_constructible<T,Args...>::value>>
494  constexpr explicit optional(in_place_t, Args&&... args);
495 
504  template <typename U, typename...Args,
505  typename=enable_if_t<std::is_constructible<T, std::initializer_list<U>&, Args...>::value>>
506  constexpr explicit optional(in_place_t,
507  std::initializer_list<U> ilist,
508  Args&&...args);
509 
529  template <typename U=T,
530  enable_if_t<detail::optional_is_value_convertible<T,U>::value && std::is_convertible<U&&, T>::value>* =nullptr>
531  // cppcheck-suppress noExplicitConstructor
532  constexpr optional(U&& value);
533  template <typename U=T,
534  enable_if_t<detail::optional_is_value_convertible<T,U>::value && !std::is_convertible<U&&, T>::value>* =nullptr>
535  constexpr explicit optional(U&& value);
537 
538  //-----------------------------------------------------------------------
539 
544  optional& operator=(nullopt_t);
545 
549  optional& operator=(detail::enable_overload_if_t<std::is_copy_constructible<T>::value && std::is_copy_assignable<T>::value,const optional&> other);
550  optional& operator=(detail::disable_overload_if_t<std::is_copy_constructible<T>::value && std::is_copy_assignable<T>::value,const optional&> other) = delete;
551 
561  optional& operator=(detail::enable_overload_if_t<std::is_move_constructible<T>::value && std::is_move_assignable<T>::value,optional&&> other);
562  optional& operator=(detail::disable_overload_if_t<std::is_move_constructible<T>::value && std::is_move_assignable<T>::value,optional&&> other) = delete;
563 
580  template <typename U=T,
581  typename=enable_if_t<detail::optional_is_value_assignable<T,U>::value>>
582  optional& operator=(U&& value);
583 
619  template <typename U>
620  optional& operator=(enable_if_t<detail::optional_is_copy_convert_assignable<T,U>::value,const optional<U>&> other);
621 
658  template <typename U>
659  optional& operator=(enable_if_t<detail::optional_is_move_convert_assignable<T,U>::value,optional<U>&&> other);
660 
661  //-----------------------------------------------------------------------
662  // Observers
663  //-----------------------------------------------------------------------
664 
671  BPSTD_CPP14_CONSTEXPR value_type* operator->() noexcept;
672  constexpr const value_type* operator->() const noexcept;
674 
681  BPSTD_CPP14_CONSTEXPR value_type& operator*() & noexcept;
682  BPSTD_CPP14_CONSTEXPR value_type&& operator*() && noexcept;
683  constexpr const value_type& operator*() const& noexcept;
684  constexpr const value_type&& operator*() const&& noexcept;
686 
691  constexpr explicit operator bool() const noexcept;
692 
697  constexpr bool has_value() const noexcept;
698 
699  //-----------------------------------------------------------------------
700 
707  BPSTD_CPP14_CONSTEXPR value_type& value() &;
708  BPSTD_CPP14_CONSTEXPR value_type&& value() &&;
710 
717  BPSTD_CPP14_CONSTEXPR const value_type& value() const &;
718  BPSTD_CPP14_CONSTEXPR const value_type&& value() const &&;
720 
721  //-----------------------------------------------------------------------
722 
729  template <typename U>
730  constexpr value_type value_or(U&& default_value) const &;
731  template <typename U>
732  BPSTD_CPP14_CONSTEXPR value_type value_or(U&& default_value) &&;
734 
735  //-----------------------------------------------------------------------
736  // Modifiers
737  //-----------------------------------------------------------------------
738 
742  void swap(optional& other);
743 
749  void reset() noexcept(std::is_nothrow_destructible<T>::value);
750 
757  template <typename...Args>
758  void emplace(Args&&...args);
759 
767  template <typename U,typename...Args >
768  void emplace(std::initializer_list<U> ilist, Args&&...args);
769  };
770 
771  //=========================================================================
772  // non-member functions : class : optional
773  //=========================================================================
774 
775  //-------------------------------------------------------------------------
776  // Comparison
777  //-------------------------------------------------------------------------
778 
779  template <typename T>
780  BPSTD_CPP14_CONSTEXPR bool operator==(const optional<T>& lhs, const optional<T>& rhs);
781  template <typename T>
782  BPSTD_CPP14_CONSTEXPR bool operator!=(const optional<T>& lhs, const optional<T>& rhs);
783  template <typename T>
784  BPSTD_CPP14_CONSTEXPR bool operator<(const optional<T>& lhs, const optional<T>& rhs);
785  template <typename T>
786  BPSTD_CPP14_CONSTEXPR bool operator>(const optional<T>& lhs, const optional<T>& rhs);
787  template <typename T>
788  BPSTD_CPP14_CONSTEXPR bool operator<=(const optional<T>& lhs, const optional<T>& rhs);
789  template <typename T>
790  BPSTD_CPP14_CONSTEXPR bool operator>=(const optional<T>& lhs, const optional<T>& rhs);
791 
792  //-------------------------------------------------------------------------
793 
794  template <typename T>
795  constexpr bool operator==(const optional<T>& opt, nullopt_t) noexcept;
796  template <typename T>
797  constexpr bool operator==(nullopt_t, const optional<T>& opt) noexcept;
798  template <typename T>
799  constexpr bool operator!=(const optional<T>& opt, nullopt_t) noexcept;
800  template <typename T>
801  constexpr bool operator!=(nullopt_t, const optional<T>& opt) noexcept;
802  template <typename T>
803  constexpr bool operator<(const optional<T>& opt, nullopt_t) noexcept;
804  template <typename T>
805  constexpr bool operator<(nullopt_t, const optional<T>& opt) noexcept;
806  template <typename T>
807  constexpr bool operator>(const optional<T>& opt, nullopt_t) noexcept;
808  template <typename T>
809  constexpr bool operator>(nullopt_t, const optional<T>& opt) noexcept;
810  template <typename T>
811  constexpr bool operator<=(const optional<T>& opt, nullopt_t) noexcept;
812  template <typename T>
813  constexpr bool operator<=(nullopt_t, const optional<T>& opt) noexcept;
814  template <typename T>
815  constexpr bool operator>=(const optional<T>& opt, nullopt_t) noexcept;
816  template <typename T>
817  constexpr bool operator>=(nullopt_t, const optional<T>& opt) noexcept;
818 
819  //-------------------------------------------------------------------------
820 
821  template <typename T>
822  constexpr bool operator==(const optional<T>& opt, const T& value);
823  template <typename T>
824  constexpr bool operator==(const T& value, const optional<T>& opt);
825  template <typename T>
826  constexpr bool operator!=(const optional<T>& opt, const T& value);
827  template <typename T>
828  constexpr bool operator!=(const T& value, const optional<T>& opt);
829  template <typename T>
830  constexpr bool operator<(const optional<T>& opt, const T& value);
831  template <typename T>
832  constexpr bool operator<(const T& value, const optional<T>& opt);
833  template <typename T>
834  constexpr bool operator>(const optional<T>& opt, const T& value);
835  template <typename T>
836  constexpr bool operator>(const T& value, const optional<T>& opt);
837  template <typename T>
838  constexpr bool operator<=(const optional<T>& opt, const T& value);
839  template <typename T>
840  constexpr bool operator<=(const T& value, const optional<T>& opt);
841  template <typename T>
842  constexpr bool operator>=(const optional<T>& opt, const T& value);
843  template <typename T>
844  constexpr bool operator>=(const T& value, const optional<T>& opt);
845 
846  //-------------------------------------------------------------------------
847  // Utilities
848  //-------------------------------------------------------------------------
849 
853  template <typename T>
854  constexpr optional<decay_t<T>> make_optional(T&& value);
855 
860  template <typename T, typename... Args >
861  constexpr optional<T> make_optional(Args&&... args);
862 
869  template <typename T, typename U, typename... Args >
870  constexpr optional<T> make_optional(std::initializer_list<U> il, Args&&... args);
871 
872  //-------------------------------------------------------------------------
873 
878  template <typename T>
879  void swap(optional<T>& lhs, optional<T>& rhs);
880 
881 } // namespace bpstd
882 
883 //=============================================================================
884 // class : detail::optional_base<T,true>
885 //=============================================================================
886 
887 //-----------------------------------------------------------------------------
888 // Constructors
889 //-----------------------------------------------------------------------------
890 
891 template <typename T>
892 inline BPSTD_INLINE_VISIBILITY constexpr
893 bpstd::detail::optional_base<T,true>
894  ::optional_base(nullopt_t)
895  noexcept
896  : m_storage{},
897  m_engaged{false}
898 {
899 }
900 
901 template <typename T>
902 template <typename...Args>
903 inline BPSTD_INLINE_VISIBILITY constexpr
904 bpstd::detail::optional_base<T,true>::optional_base(in_place_t, Args&&...args)
905  noexcept(std::is_nothrow_constructible<T,Args...>::value)
906  : m_storage(in_place, bpstd::forward<Args>(args)...),
907  m_engaged{true}
908 {
909 
910 }
911 
912 //-----------------------------------------------------------------------------
913 // Protected Observers
914 //-----------------------------------------------------------------------------
915 
916 template <typename T>
917 inline BPSTD_INLINE_VISIBILITY BPSTD_CPP14_CONSTEXPR
918 T* bpstd::detail::optional_base<T,true>::val()
919  noexcept
920 {
921  return &m_storage.something;
922 }
923 
924 template <typename T>
925 inline BPSTD_INLINE_VISIBILITY constexpr
926 const T* bpstd::detail::optional_base<T,true>::val()
927  const noexcept
928 {
929  return &m_storage.something;
930 }
931 
932 template <typename T>
933 inline BPSTD_INLINE_VISIBILITY constexpr
934 bool bpstd::detail::optional_base<T,true>::contains_value()
935  const noexcept
936 {
937  return m_engaged;
938 }
939 
940 //-----------------------------------------------------------------------------
941 // Protected Modifiers
942 //-----------------------------------------------------------------------------
943 
944 template <typename T>
945 template <typename...Args>
946 inline BPSTD_INLINE_VISIBILITY
947 void bpstd::detail::optional_base<T,true>::construct(Args&&...args)
948 {
949  m_storage.something = T(bpstd::forward<Args>(args)...);
950  m_engaged = true;
951 }
952 
953 template <typename T>
954 inline BPSTD_INLINE_VISIBILITY
955 void bpstd::detail::optional_base<T,true>::destruct()
956 {
957  m_engaged = false;
958 }
959 
960 //=============================================================================
961 // class : detail::optional_base<T,false>
962 //=============================================================================
963 
964 //-----------------------------------------------------------------------------
965 // Constructors / Destructor
966 //-----------------------------------------------------------------------------
967 
968 template <typename T>
969 inline BPSTD_INLINE_VISIBILITY
970 bpstd::detail::optional_base<T,false>
971  ::optional_base(nullopt_t)
972  noexcept
973  : m_storage{},
974  m_engaged{false}
975 {
976 }
977 
978 template <typename T>
979 template <typename...Args>
980 inline BPSTD_INLINE_VISIBILITY
981 bpstd::detail::optional_base<T,false>
982  ::optional_base(in_place_t, Args&&...args)
983  noexcept(std::is_nothrow_constructible<T,Args...>::value)
984  : m_storage(in_place, bpstd::forward<Args>(args)...),
985  m_engaged{true}
986 {
987 
988 }
989 
990 //-----------------------------------------------------------------------------
991 
992 template <typename T>
993 inline BPSTD_INLINE_VISIBILITY
994 bpstd::detail::optional_base<T,false>::~optional_base()
995  noexcept(std::is_nothrow_destructible<T>::value)
996 {
997  if (m_engaged) {
998  m_storage.something.~T();
999  }
1000 }
1001 
1002 //-----------------------------------------------------------------------------
1003 // Protected Observers
1004 //-----------------------------------------------------------------------------
1005 
1006 template <typename T>
1007 inline BPSTD_INLINE_VISIBILITY
1008 T* bpstd::detail::optional_base<T,false>::val()
1009  noexcept
1010 {
1011  return &m_storage.something;
1012 }
1013 
1014 template <typename T>
1015 inline BPSTD_INLINE_VISIBILITY
1016 const T* bpstd::detail::optional_base<T,false>::val()
1017  const noexcept
1018 {
1019  return &m_storage.something;
1020 }
1021 
1022 template <typename T>
1023 inline BPSTD_INLINE_VISIBILITY
1024 bool bpstd::detail::optional_base<T,false>::contains_value()
1025  const noexcept
1026 {
1027  return m_engaged;
1028 }
1029 
1030 //-----------------------------------------------------------------------------
1031 // Protected Modifiers
1032 //-----------------------------------------------------------------------------
1033 
1034 template <typename T>
1035 template <typename...Args>
1036 inline BPSTD_INLINE_VISIBILITY
1037 void bpstd::detail::optional_base<T,false>::construct(Args&&...args)
1038 {
1039  new (&m_storage.something) T(bpstd::forward<Args>(args)...);
1040  m_engaged = true;
1041 }
1042 
1043 template <typename T>
1044 inline BPSTD_INLINE_VISIBILITY
1045 void bpstd::detail::optional_base<T,false>::destruct()
1046 {
1047  if (m_engaged) {
1048  m_storage.something.~T();
1049  m_engaged = false;
1050  }
1051 }
1052 
1053 //=============================================================================
1054 // class : optional
1055 //=============================================================================
1056 
1057 //-----------------------------------------------------------------------------
1058 // Constructor / Assignment
1059 //-----------------------------------------------------------------------------
1060 
1061 template <typename T>
1062 inline BPSTD_INLINE_VISIBILITY constexpr
1064  noexcept
1065  : base_type{ nullopt }
1066 {
1067 
1068 }
1069 
1070 template <typename T>
1071 inline BPSTD_INLINE_VISIBILITY constexpr
1073  noexcept
1074  : optional{}
1075 {
1076 
1077 }
1078 
1079 //-----------------------------------------------------------------------------
1080 
1081 template <typename T>
1082 inline BPSTD_INLINE_VISIBILITY
1084  ::optional(detail::enable_overload_if_t<std::is_copy_constructible<T>::value,const optional&> other)
1085  : optional{}
1086 {
1087  if (other.has_value())
1088  {
1089  base_type::construct(*other);
1090  }
1091 }
1092 
1093 template <typename T>
1094 inline BPSTD_INLINE_VISIBILITY
1096  ::optional(detail::enable_overload_if_t<std::is_move_constructible<T>::value,optional&&> other)
1097  : optional{}
1098 {
1099  if (other.has_value())
1100  {
1101  base_type::construct(bpstd::move(*other));
1102  }
1103 }
1104 
1105 //-----------------------------------------------------------------------------
1106 
1107 template <typename T>
1108 template <typename U,
1109  bpstd::enable_if_t<bpstd::detail::optional_is_copy_convertible<T,U>::value && std::is_convertible<const U&, T>::value>*>
1110 inline BPSTD_INLINE_VISIBILITY
1111 bpstd::optional<T>::optional(const optional<U>& other)
1112  : optional{}
1113 {
1114  if (other.has_value())
1115  {
1116  base_type::construct(*other);
1117  }
1118 }
1119 
1120 template <typename T>
1121 template <typename U,
1122  bpstd::enable_if_t<bpstd::detail::optional_is_copy_convertible<T,U>::value && !std::is_convertible<const U&, T>::value>*>
1123 inline BPSTD_INLINE_VISIBILITY
1124 bpstd::optional<T>::optional(const optional<U>& other)
1125  : optional{}
1126 {
1127  if (other.has_value())
1128  {
1129  base_type::construct(*other);
1130  }
1131 }
1132 
1133 //-----------------------------------------------------------------------------
1134 
1135 template <typename T>
1136 template <typename U,
1137  bpstd::enable_if_t<bpstd::detail::optional_is_move_convertible<T,U>::value && std::is_convertible<U&&, T>::value>*>
1138 inline BPSTD_INLINE_VISIBILITY
1139 bpstd::optional<T>::optional(optional<U>&& other)
1140  : optional{}
1141 {
1142  if (other.has_value())
1143  {
1144  base_type::construct(bpstd::move(*other));
1145  }
1146 }
1147 template <typename T>
1148 template <typename U,
1149  bpstd::enable_if_t<bpstd::detail::optional_is_move_convertible<T,U>::value && !std::is_convertible<U&&, T>::value>*>
1150 inline BPSTD_INLINE_VISIBILITY
1151 bpstd::optional<T>::optional(optional<U>&& other)
1152  : optional{}
1153 {
1154  if (other.has_value())
1155  {
1156  base_type::construct(bpstd::move(*other));
1157  }
1158 }
1159 
1160 template <typename T>
1161 template <typename...Args, typename>
1162 inline BPSTD_INLINE_VISIBILITY constexpr
1163 bpstd::optional<T>::optional(in_place_t, Args&&...args)
1164  : base_type{ in_place, bpstd::forward<Args>(args)... }
1165 {
1166 
1167 }
1168 
1169 template <typename T>
1170 template <typename U, typename...Args, typename>
1171 inline BPSTD_INLINE_VISIBILITY constexpr
1173  ::optional( in_place_t,
1174  std::initializer_list<U> ilist,
1175  Args&&...args )
1176  : base_type{ in_place, ilist, bpstd::forward<Args>(args)... }
1177 {
1178 
1179 }
1180 
1181 template <typename T>
1182 template <typename U,
1183  bpstd::enable_if_t<bpstd::detail::optional_is_value_convertible<T,U>::value && std::is_convertible<U&&, T>::value>*>
1184 inline BPSTD_INLINE_VISIBILITY constexpr
1186  : base_type{ in_place, bpstd::forward<U>(value) }
1187 {
1188 
1189 }
1190 
1191 template <typename T>
1192 template <typename U,
1193  bpstd::enable_if_t<bpstd::detail::optional_is_value_convertible<T,U>::value && !std::is_convertible<U&&, T>::value>*>
1194 inline BPSTD_INLINE_VISIBILITY constexpr
1196  : base_type{ in_place, bpstd::forward<U>(value) }
1197 {
1198 
1199 }
1200 
1201 //-----------------------------------------------------------------------------
1202 
1203 template <typename T>
1204 inline BPSTD_INLINE_VISIBILITY
1206 {
1207  base_type::destruct();
1208  return (*this);
1209 }
1210 
1211 template <typename T>
1212 inline BPSTD_INLINE_VISIBILITY
1214  bpstd::optional<T>::operator=(detail::enable_overload_if_t<std::is_copy_constructible<T>::value && std::is_copy_assignable<T>::value,const optional&> other)
1215 {
1216  if (has_value() && other.has_value()) {
1217  (*base_type::val()) = (*other);
1218  } else if (has_value()) {
1219  base_type::destruct();
1220  } else if (other.has_value()) {
1221  base_type::construct(*other);
1222  }
1223 
1224  return (*this);
1225 }
1226 
1227 template <typename T>
1228 inline BPSTD_INLINE_VISIBILITY
1230  bpstd::optional<T>::operator=(detail::enable_overload_if_t<std::is_move_constructible<T>::value && std::is_move_assignable<T>::value,optional&&> other)
1231 {
1232  if (has_value() && other.has_value()) {
1233  (*base_type::val()) = bpstd::move(*other);
1234  } else if (has_value()) {
1235  base_type::destruct();
1236  } else if (other.has_value()) {
1237  base_type::construct(bpstd::move( *other ));
1238  }
1239 
1240  return (*this);
1241 }
1242 
1243 template <typename T>
1244 template <typename U, typename>
1245 inline BPSTD_INLINE_VISIBILITY
1247 {
1248  if (has_value()) {
1249  (*base_type::val()) = bpstd::forward<U>(value);
1250  } else {
1251  base_type::construct(bpstd::forward<U>(value));
1252  }
1253  return (*this);
1254 }
1255 
1256 //-----------------------------------------------------------------------------
1257 // Observers
1258 //-----------------------------------------------------------------------------
1259 
1260 template <typename T>
1261 inline BPSTD_INLINE_VISIBILITY constexpr
1263  const noexcept
1264 {
1265  return base_type::contains_value();
1266 }
1267 
1268 template <typename T>
1269 inline BPSTD_INLINE_VISIBILITY constexpr
1271  const noexcept
1272 {
1273  return base_type::contains_value();
1274 }
1275 
1276 //-----------------------------------------------------------------------------
1277 
1278 template <typename T>
1279 inline BPSTD_INLINE_VISIBILITY BPSTD_CPP14_CONSTEXPR
1282  noexcept
1283 {
1284  return base_type::val();
1285 }
1286 
1287 template <typename T>
1288 inline BPSTD_INLINE_VISIBILITY constexpr
1289 const typename bpstd::optional<T>::value_type*
1291  const noexcept
1292 {
1293  return base_type::val();
1294 }
1295 
1296 //-----------------------------------------------------------------------------
1297 
1298 template <typename T>
1299 inline BPSTD_INLINE_VISIBILITY BPSTD_CPP14_CONSTEXPR
1302  & noexcept
1303 {
1304  return *base_type::val();
1305 }
1306 
1307 template <typename T>
1308 inline BPSTD_INLINE_VISIBILITY BPSTD_CPP14_CONSTEXPR
1311  && noexcept
1312 {
1313  return bpstd::move(*base_type::val());
1314 }
1315 
1316 //-----------------------------------------------------------------------------
1317 
1318 template <typename T>
1319 inline BPSTD_INLINE_VISIBILITY constexpr
1320 const typename bpstd::optional<T>::value_type&
1322  const & noexcept
1323 {
1324  return *base_type::val();
1325 }
1326 
1327 template <typename T>
1328 inline BPSTD_INLINE_VISIBILITY constexpr
1329 const typename bpstd::optional<T>::value_type&&
1331  const && noexcept
1332 {
1333  return bpstd::move(*base_type::val());
1334 }
1335 
1336 //-----------------------------------------------------------------------------
1337 
1338 template <typename T>
1339 inline BPSTD_INLINE_VISIBILITY BPSTD_CPP14_CONSTEXPR
1342  &
1343 {
1344  if (static_cast<bool>(*this)) {
1345  return *base_type::val();
1346  }
1347  throw bad_optional_access{};
1348 }
1349 
1350 template <typename T>
1351 inline BPSTD_INLINE_VISIBILITY BPSTD_CPP14_CONSTEXPR
1354  &&
1355 {
1356  if (static_cast<bool>(*this)) {
1357  return bpstd::move(*base_type::val());
1358  }
1359  throw bad_optional_access{};
1360 }
1361 
1362 //-----------------------------------------------------------------------------
1363 
1364 template <typename T>
1365 inline BPSTD_INLINE_VISIBILITY BPSTD_CPP14_CONSTEXPR
1366 const typename bpstd::optional<T>::value_type&
1368  const &
1369 {
1370  if (static_cast<bool>(*this)) {
1371  return *base_type::val();
1372  }
1373  throw bad_optional_access{};
1374 }
1375 
1376 template <typename T>
1377 inline BPSTD_INLINE_VISIBILITY BPSTD_CPP14_CONSTEXPR
1378 const typename bpstd::optional<T>::value_type&&
1380  const &&
1381 {
1382  if (static_cast<bool>(*this)) {
1383  return bpstd::move(*base_type::val());
1384  }
1385  throw bad_optional_access{};
1386 }
1387 
1388 //-----------------------------------------------------------------------------
1389 
1390 template <typename T>
1391 template <typename U>
1392 inline BPSTD_INLINE_VISIBILITY constexpr
1394  bpstd::optional<T>::value_or(U&& default_value)
1395  const &
1396 {
1397  return bool(*this) ? (*base_type::val()) : bpstd::forward<U>(default_value);
1398 }
1399 
1400 template <typename T>
1401 template <typename U>
1402 inline BPSTD_INLINE_VISIBILITY BPSTD_CPP14_CONSTEXPR
1404  bpstd::optional<T>::value_or(U&& default_value)
1405  &&
1406 {
1407  return bool(*this) ? (*base_type::val()) : bpstd::forward<U>(default_value);
1408 }
1409 
1410 //-----------------------------------------------------------------------------
1411 // Modifiers
1412 //-----------------------------------------------------------------------------
1413 
1414 template <typename T>
1415 inline BPSTD_INLINE_VISIBILITY
1417 {
1418  using std::swap;
1419 
1420  if (has_value() && other.has_value()){
1421  swap(*base_type::val(), *other);
1422  } else if (has_value()) {
1423  other = bpstd::move(*this);
1424  reset(); // leave this unengaged
1425  } else if (other.has_value()) {
1426  *this = bpstd::move(other);
1427  other.reset(); // leave 'other' unengaged
1428  }
1429 }
1430 
1431 template <typename T>
1432 inline BPSTD_INLINE_VISIBILITY
1434  noexcept(std::is_nothrow_destructible<T>::value)
1435 {
1436  base_type::destruct();
1437 }
1438 
1439 //-----------------------------------------------------------------------------
1440 
1441 template <typename T>
1442 template <typename...Args>
1443 inline BPSTD_INLINE_VISIBILITY
1444 void bpstd::optional<T>::emplace(Args&&...args)
1445 {
1446  base_type::destruct();
1447  base_type::construct(bpstd::forward<Args>(args)...);
1448 }
1449 
1450 template <typename T>
1451 template <typename U, typename...Args>
1452 inline BPSTD_INLINE_VISIBILITY
1453 void bpstd::optional<T>::emplace(std::initializer_list<U> ilist,
1454  Args&&...args)
1455 {
1456  base_type::destruct();
1457  base_type::construct(ilist, bpstd::forward<Args>(args)...);
1458 }
1459 
1460 //=============================================================================
1461 // Equality Operators
1462 //=============================================================================
1463 
1464 //-----------------------------------------------------------------------------
1465 // Comparison
1466 //-----------------------------------------------------------------------------
1467 
1468 template <typename T>
1469 inline BPSTD_INLINE_VISIBILITY BPSTD_CPP14_CONSTEXPR
1470 bool
1471  bpstd::operator==(const optional<T>& lhs, const optional<T>& rhs)
1472 {
1473  if (static_cast<bool>(lhs) != static_cast<bool>(rhs)) {
1474  return false;
1475  }
1476  if (!static_cast<bool>(lhs)) {
1477  return true;
1478  }
1479  return *lhs == *rhs;
1480 }
1481 
1482 template <typename T>
1483 inline BPSTD_INLINE_VISIBILITY BPSTD_CPP14_CONSTEXPR
1484 bool
1485  bpstd::operator!=(const optional<T>& lhs, const optional<T>& rhs)
1486 {
1487  if (static_cast<bool>(lhs) != static_cast<bool>(rhs)) {
1488  return true;
1489  }
1490  if (!static_cast<bool>(lhs)) {
1491  return false;
1492  }
1493  return *lhs != *rhs;
1494 }
1495 
1496 template <typename T>
1497 inline BPSTD_INLINE_VISIBILITY BPSTD_CPP14_CONSTEXPR
1498 bool
1499  bpstd::operator<(const optional<T>& lhs, const optional<T>& rhs)
1500 {
1501  if (!static_cast<bool>(rhs)) {
1502  return false;
1503  }
1504  if (!static_cast<bool>(lhs)) {
1505  return true;
1506  }
1507  return *lhs < *rhs;
1508 }
1509 
1510 template <typename T>
1511 inline BPSTD_INLINE_VISIBILITY BPSTD_CPP14_CONSTEXPR
1512 bool
1513  bpstd::operator>(const optional<T>& lhs, const optional<T>& rhs)
1514 {
1515  if (!static_cast<bool>(lhs)) {
1516  return false;
1517  }
1518  if (!static_cast<bool>(rhs)) {
1519  return true;
1520  }
1521  return *lhs > *rhs;
1522 }
1523 
1524 template <typename T>
1525 inline BPSTD_INLINE_VISIBILITY BPSTD_CPP14_CONSTEXPR
1526 bool
1527  bpstd::operator<=(const optional<T>& lhs, const optional<T>& rhs)
1528 {
1529  if (!static_cast<bool>(lhs)) {
1530  return true;
1531  }
1532  if (!static_cast<bool>(rhs)) {
1533  return false;
1534  }
1535  return *lhs <= *rhs;
1536 }
1537 
1538 template <typename T>
1539 inline BPSTD_INLINE_VISIBILITY BPSTD_CPP14_CONSTEXPR
1540 bool
1541  bpstd::operator>=(const optional<T>& lhs, const optional<T>& rhs)
1542 {
1543  if (!static_cast<bool>(rhs)) {
1544  return true;
1545  }
1546  if (!static_cast<bool>(lhs)) {
1547  return false;
1548  }
1549  return *lhs >= *rhs;
1550 }
1551 
1552 //-----------------------------------------------------------------------------
1553 
1554 template <typename T>
1555 inline BPSTD_INLINE_VISIBILITY constexpr
1556 bool bpstd::operator==(const optional<T>& opt, nullopt_t)
1557  noexcept
1558 {
1559  return !opt;
1560 }
1561 
1562 template <typename T>
1563 inline BPSTD_INLINE_VISIBILITY constexpr
1564 bool bpstd::operator==(nullopt_t, const optional<T>& opt)
1565  noexcept
1566 {
1567  return !opt;
1568 }
1569 
1570 template <typename T>
1571 inline BPSTD_INLINE_VISIBILITY constexpr
1572 bool bpstd::operator!=(const optional<T>& opt, nullopt_t)
1573  noexcept
1574 {
1575  return static_cast<bool>(opt);
1576 }
1577 
1578 template <typename T>
1579 inline BPSTD_INLINE_VISIBILITY constexpr
1580 bool bpstd::operator!=(nullopt_t, const optional<T>& opt)
1581  noexcept
1582 {
1583  return static_cast<bool>(opt);
1584 }
1585 
1586 template <typename T>
1587 inline BPSTD_INLINE_VISIBILITY constexpr
1588 bool bpstd::operator<(const optional<T>&, nullopt_t)
1589  noexcept
1590 {
1591  return false;
1592 }
1593 
1594 template <typename T>
1595 inline BPSTD_INLINE_VISIBILITY constexpr
1596 bool bpstd::operator<(nullopt_t, const optional<T>& opt)
1597  noexcept
1598 {
1599  return static_cast<bool>(opt);
1600 }
1601 
1602 template <typename T>
1603 inline BPSTD_INLINE_VISIBILITY constexpr
1604 bool bpstd::operator>(const optional<T>& opt, nullopt_t)
1605  noexcept
1606 {
1607  return static_cast<bool>(opt);
1608 }
1609 
1610 template <typename T>
1611 inline BPSTD_INLINE_VISIBILITY constexpr
1612 bool bpstd::operator>(nullopt_t, const optional<T>&)
1613  noexcept
1614 {
1615  return false;
1616 }
1617 
1618 template <typename T>
1619 inline BPSTD_INLINE_VISIBILITY constexpr
1620 bool bpstd::operator<=(const optional<T>& opt, nullopt_t)
1621  noexcept
1622 {
1623  return !opt;
1624 }
1625 
1626 template <typename T>
1627 inline BPSTD_INLINE_VISIBILITY constexpr
1628 bool bpstd::operator<=(nullopt_t, const optional<T>&)
1629  noexcept
1630 {
1631  return true;
1632 }
1633 
1634 template <typename T>
1635 inline BPSTD_INLINE_VISIBILITY constexpr
1636 bool bpstd::operator>=(const optional<T>&, nullopt_t)
1637  noexcept
1638 {
1639  return true;
1640 }
1641 
1642 template <typename T>
1643 inline BPSTD_INLINE_VISIBILITY constexpr
1644 bool bpstd::operator>=(nullopt_t, const optional<T>& opt)
1645  noexcept
1646 {
1647  return !opt;
1648 }
1649 
1650 //-----------------------------------------------------------------------------
1651 
1652 template <typename T>
1653 inline BPSTD_INLINE_VISIBILITY constexpr
1654 bool bpstd::operator==(const optional<T>& opt, const T& value)
1655 {
1656  return static_cast<bool>(opt) ? *opt == value : false;
1657 }
1658 
1659 template <typename T>
1660 inline BPSTD_INLINE_VISIBILITY constexpr
1661 bool bpstd::operator==(const T& value, const optional<T>& opt)
1662 {
1663  return static_cast<bool>(opt) ? value == *opt : false;
1664 }
1665 
1666 template <typename T>
1667 inline BPSTD_INLINE_VISIBILITY constexpr
1668 bool bpstd::operator!=(const optional<T>& opt, const T& value)
1669 {
1670  return static_cast<bool>(opt) ? *opt != value : true;
1671 }
1672 
1673 template <typename T>
1674 inline BPSTD_INLINE_VISIBILITY constexpr
1675 bool bpstd::operator!=(const T& value, const optional<T>& opt)
1676 {
1677  return static_cast<bool>(opt) ? value != *opt : true;
1678 }
1679 
1680 template <typename T>
1681 inline BPSTD_INLINE_VISIBILITY constexpr
1682 bool bpstd::operator<(const optional<T>& opt, const T& value)
1683 {
1684  return static_cast<bool>(opt) ? *opt < value : true;
1685 }
1686 
1687 template <typename T>
1688 inline BPSTD_INLINE_VISIBILITY constexpr
1689 bool bpstd::operator<(const T& value, const optional<T>& opt)
1690 {
1691  return static_cast<bool>(opt) ? value < *opt : false;
1692 }
1693 
1694 template <typename T>
1695 inline BPSTD_INLINE_VISIBILITY constexpr
1696 bool bpstd::operator>(const optional<T>& opt, const T& value)
1697 {
1698  return static_cast<bool>(opt) ? *opt > value : false;
1699 }
1700 
1701 template <typename T>
1702 inline BPSTD_INLINE_VISIBILITY constexpr
1703 bool bpstd::operator>(const T& value, const optional<T>& opt)
1704 {
1705  return static_cast<bool>(opt) ? value > *opt : true;
1706 }
1707 
1708 template <typename T>
1709 inline BPSTD_INLINE_VISIBILITY constexpr
1710 bool bpstd::operator<=(const optional<T>& opt, const T& value)
1711 {
1712  return static_cast<bool>(opt) ? *opt <= value : true;
1713 }
1714 
1715 template <typename T>
1716 inline BPSTD_INLINE_VISIBILITY constexpr
1717 bool bpstd::operator<=(const T& value, const optional<T>& opt)
1718 {
1719  return static_cast<bool>(opt) ? value <= *opt : false;
1720 }
1721 
1722 template <typename T>
1723 inline BPSTD_INLINE_VISIBILITY constexpr
1724 bool bpstd::operator>=(const optional<T>& opt, const T& value)
1725 {
1726  return static_cast<bool>(opt) ? *opt >= value : false;
1727 }
1728 
1729 template <typename T>
1730 inline BPSTD_INLINE_VISIBILITY constexpr
1731 bool bpstd::operator>=(const T& value, const optional<T>& opt)
1732 {
1733  return static_cast<bool>(opt) ? value >= *opt : true;
1734 }
1735 
1736 //-----------------------------------------------------------------------------
1737 // Non-member functions
1738 //-----------------------------------------------------------------------------
1739 
1740 template <typename T>
1741 inline BPSTD_INLINE_VISIBILITY constexpr
1743 {
1744  return optional<decay_t<T>>(bpstd::forward<T>(value));
1745 }
1746 
1747 template <typename T, typename... Args >
1748 inline BPSTD_INLINE_VISIBILITY constexpr
1750 {
1751  return optional<T>(in_place, bpstd::forward<Args>(args)...);
1752 }
1753 
1754 template <typename T, typename U, typename... Args >
1755 inline BPSTD_INLINE_VISIBILITY constexpr
1756 bpstd::optional<T> bpstd::make_optional(std::initializer_list<U> il, Args&&... args)
1757 {
1758  return optional<T>(
1759  in_place,
1760  std::forward<std::initializer_list<U>>(il),
1761  std::forward<Args>(args)...
1762  );
1763 }
1764 
1765 template <typename T>
1766 inline BPSTD_INLINE_VISIBILITY
1767 void bpstd::swap(optional<T>& lhs, optional<T>& rhs)
1768 {
1769  lhs.swap(rhs);
1770 }
1771 
1772 BPSTD_COMPILER_DIAGNOSTIC_POSTAMBLE
1773 
1774 #endif /* BPSTD_OPTIONAL_HPP */
bpstd::in_place_t
This function is a special disambiguation tag for variadic functions, used in any and optional.
Definition: utility.hpp:56
bpstd::optional::optional
constexpr optional() noexcept
Constructs an optional that does not contain a value.
Definition: optional.hpp:1063
type_traits.hpp
This header provides definitions from the C++ header <type_traits>
bpstd::optional::swap
void swap(optional &other)
Swaps the contents with those of other.
Definition: optional.hpp:1411
bpstd::conjunction
Type trait to determine the bool_constant from a logical AND operation of other bool_constants.
Definition: type_traits.hpp:110
bpstd::optional::has_value
constexpr bool has_value() const noexcept
Checks whether *this contains a value.
Definition: optional.hpp:1270
bpstd::optional::value
BPSTD_CPP14_CONSTEXPR value_type & value() &
Returns the contained value.
Definition: optional.hpp:1339
bpstd::optional::operator=
optional & operator=(nullopt_t)
Assigns this optional to be a null optional.
Definition: optional.hpp:1205
bpstd::optional::operator->
BPSTD_CPP14_CONSTEXPR value_type * operator->() noexcept
Accesses the contained value.
Definition: optional.hpp:1281
bpstd::bad_optional_access
An exception thrown when an optional is attempted to be accessed while not containing a value.
Definition: optional.hpp:136
bpstd::empty
constexpr auto empty(const C &c) -> decltype(c.empty())
Queries whether c is empty.
functional.hpp
This header provides definitions from the C++ header <functional>
bpstd::swap
void swap(any &lhs, any &rhs) noexcept
Swaps the contents of lhs and rhs.
Definition: any.hpp:833
bpstd::negation
Utility metafunction for negating a bool_constant.
Definition: type_traits.hpp:153
bpstd::optional::operator*
BPSTD_CPP14_CONSTEXPR value_type & operator*() &noexcept
Accesses the contained value.
Definition: optional.hpp:1301
bpstd::nullopt_t
This type represents null optional value.
Definition: optional.hpp:147
bpstd::optional::value_type
T value_type
The underlying type of this Optional.
Definition: optional.hpp:363
bpstd::optional
The class template optional manages an optional contained value, i.e. a value that may or may not be ...
Definition: optional.hpp:53
bpstd::swap
void swap(variant< Types... > &lhs, variant< Types... > &rhs) noexcept(noexcept(lhs.swap(rhs)))
Swaps the contents of lhs with rhs.
bpstd::optional::emplace
void emplace(Args &&...args)
Constructs the contained value in-place.
bpstd::nullopt
constexpr nullopt_t nullopt
Instance of a nullopt type.
Definition: optional.hpp:156
bpstd::optional::value_or
constexpr value_type value_or(U &&default_value) const &
Returns the contained value if *this has a value, otherwise returns default_value.
bpstd::make_optional
constexpr optional< T > make_optional(std::initializer_list< U > il, Args &&... args)
Creates an optional object of type T from the given il args.
utility.hpp
This header provides definitions from the C++ header <utility>
bpstd::disjunction
Type trait to determine the bool_constant from a logical OR operations of other bool_constant.
Definition: type_traits.hpp:131
bpstd::optional::reset
void reset() noexcept(std::is_nothrow_destructible< T >::value)
If *this contains a value, destroy that value as if by value().T::~T().
Definition: optional.hpp:1428