1#ifndef DUNE_COMMON_STD_OPTIONAL_HH
2#define DUNE_COMMON_STD_OPTIONAL_HH
10#ifdef DUNE_HAVE_CXX_OPTIONAL
21#ifdef DUNE_HAVE_CXX_OPTIONAL
24 using optional = std::optional< T >;
26 using nullopt_t = std::nullopt_t;
27 using in_place_t = std::in_place_t;
31 const std::nullopt_t nullopt = std::nullopt;
32 const std::in_place_t in_place = std::in_place;
35 using bad_optional_access = std::bad_optional_access;
48 const nullopt_t nullopt = {};
62 const in_place_t in_place = {};
72 class bad_optional_access
73 :
public std::logic_error
76 explicit bad_optional_access (
const std::string &what ) :
std::logic_error( what ) {}
77 explicit bad_optional_access (
const char *what ) :
std::logic_error( what ) {}
101 constexpr optional () noexcept : engaged_( false ) {}
103 constexpr optional ( nullopt_t ) noexcept : engaged_(
false ) {}
105 template<
class U = value_type,
106 std::enable_if_t< std::is_constructible< value_type, U&& >::value,
int > = 0,
107 std::enable_if_t< !std::is_convertible< U&&, value_type >::value,
int > = 0 >
108 explicit constexpr optional ( U && value )
109 : engaged_( true ), value_(
std::forward< U >( value ) )
112 template<
class U = value_type,
113 std::enable_if_t< std::is_constructible< value_type, U&& >::value,
int > = 0,
114 std::enable_if_t< not(std::is_same<std::decay_t<U>, optional<value_type>>::value),
int > = 0,
115 std::enable_if_t< not(std::is_same<std::decay_t<U>, in_place_t>::value),
int > = 0
117 constexpr optional ( U && value )
118 : engaged_( true ), value_(
std::forward< U >( value ) )
121 optional (
const value_type &value ) : engaged_( true ), value_( value ) {}
122 optional ( value_type &&value ) : engaged_( true ), value_(
std::move( value ) ) {}
124 template<
class... Args >
125 explicit constexpr optional ( in_place_t, Args &&... args )
126 : engaged_( true ), value_(
std::forward< Args >( args )... )
136 optional (
const optional &other )
noexcept( std::is_nothrow_copy_constructible< T >::value )
137 : engaged_( other.engaged_ )
140 rawEmplace(other.value_);
143 optional ( optional &&other )
noexcept( std::is_nothrow_move_constructible< T >::value )
144 : engaged_( other.engaged_ )
147 rawEmplace(std::move( other.value_ ));
151 std::enable_if_t< std::is_constructible< value_type, const U& >::value,
int > = 0,
152 std::enable_if_t< !std::is_constructible< value_type, optional< U >& >::value,
int > = 0,
153 std::enable_if_t< !std::is_constructible< value_type, const optional< U >& >::value,
int > = 0,
154 std::enable_if_t< !std::is_constructible< value_type, optional< U >&& >::value,
int > = 0,
155 std::enable_if_t< !std::is_constructible< optional< U >&, value_type >::value,
int > = 0,
156 std::enable_if_t< !std::is_constructible< const optional< U >&, value_type >::value,
int > = 0,
157 std::enable_if_t< !std::is_constructible< optional< U >&&, value_type >::value,
int > = 0,
158 std::enable_if_t< !std::is_convertible< const U&, value_type >::value,
int > = 0 >
159 explicit optional (
const optional< U > &other )
160 : engaged_( other.engaged_ )
163 rawEmplace(other.value_);
167 std::enable_if_t< std::is_constructible< value_type, const U& >::value,
int > = 0,
168 std::enable_if_t< !std::is_constructible< value_type, optional< U >& >::value,
int > = 0,
169 std::enable_if_t< !std::is_constructible< value_type, const optional< U >& >::value,
int > = 0,
170 std::enable_if_t< !std::is_constructible< value_type, optional< U >&& >::value,
int > = 0,
171 std::enable_if_t< !std::is_constructible< optional< U >&, value_type >::value,
int > = 0,
172 std::enable_if_t< !std::is_constructible< const optional< U >&, value_type >::value,
int > = 0,
173 std::enable_if_t< !std::is_constructible< optional< U >&&, value_type >::value,
int > = 0,
174 std::enable_if_t< std::is_convertible< const U&, value_type >::value,
int > = 0 >
175 optional (
const optional< U > &other )
176 : engaged_( other.engaged_ )
179 rawEmplace(other.value_);
183 std::enable_if_t< std::is_constructible< value_type, const U& >::value,
int > = 0,
184 std::enable_if_t< !std::is_constructible< value_type, optional< U >& >::value,
int > = 0,
185 std::enable_if_t< !std::is_constructible< value_type, const optional< U >& >::value,
int > = 0,
186 std::enable_if_t< !std::is_constructible< value_type, optional< U >&& >::value,
int > = 0,
187 std::enable_if_t< !std::is_constructible< optional< U >&, value_type >::value,
int > = 0,
188 std::enable_if_t< !std::is_constructible< const optional< U >&, value_type >::value,
int > = 0,
189 std::enable_if_t< !std::is_constructible< optional< U >&&, value_type >::value,
int > = 0,
190 std::enable_if_t< !std::is_convertible< const U&, value_type >::value,
int > = 0 >
191 explicit optional ( optional< U > &&other )
192 : engaged_( other.engaged_ )
195 rawEmplace(std::move(other.value_));
199 std::enable_if_t< std::is_constructible< value_type, const U& >::value,
int > = 0,
200 std::enable_if_t< !std::is_constructible< value_type, optional< U >& >::value,
int > = 0,
201 std::enable_if_t< !std::is_constructible< value_type, const optional< U >& >::value,
int > = 0,
202 std::enable_if_t< !std::is_constructible< value_type, optional< U >&& >::value,
int > = 0,
203 std::enable_if_t< !std::is_constructible< optional< U >&, value_type >::value,
int > = 0,
204 std::enable_if_t< !std::is_constructible< const optional< U >&, value_type >::value,
int > = 0,
205 std::enable_if_t< !std::is_constructible< optional< U >&&, value_type >::value,
int > = 0,
206 std::enable_if_t< std::is_convertible< const U&, value_type >::value,
int > = 0 >
207 optional ( optional< U > &&other )
208 : engaged_( other.engaged_ )
211 rawEmplace(std::move(other.value_));
214 optional &operator= ( nullopt_t )
noexcept
217 value_.~value_type();
222 optional &operator= (
const optional &other )
noexcept( std::is_nothrow_copy_constructible< T >::value && std::is_nothrow_copy_assignable< T >::value )
227 value_ = other.value_;
229 value_.~value_type();
231 else if( other.engaged_ )
232 rawEmplace(other.value_);
233 engaged_ = other.engaged_;
237 optional &operator= ( optional &&other )
noexcept( std::is_nothrow_move_constructible< T >::value && std::is_nothrow_move_assignable< T >::value )
242 value_ = std::move( other.value_ );
244 value_.~value_type();
246 else if( other.engaged_ )
247 rawEmplace(std::move(other.value_));
248 engaged_ = other.engaged_;
252 template<
class U = value_type >
253 typename std::enable_if< std::is_constructible< value_type, U >::value && std::is_assignable< value_type, U >::value, optional & >::type
254 operator= ( U &&value )
257 value_ = std::forward<U>( value );
259 rawEmplace(std::forward<U>(value));
269 value_.~value_type();
278 explicit constexpr operator bool () const noexcept {
return engaged_; }
281 const value_type &operator* () const noexcept { assert( engaged_ );
return value_; }
283 value_type &operator* () noexcept { assert( engaged_ );
return value_; }
286 const value_type *operator->() const noexcept { assert( engaged_ );
return &value_; }
288 value_type *operator->() noexcept { assert( engaged_ );
return &value_; }
290 const value_type &value ()
const
295 throw bad_optional_access(
"Cannot access value of disengaged optional." );
303 throw bad_optional_access(
"Cannot access value of disengaged optional." );
307 value_type value_or ( U &&value )
const
309 return (engaged_ ? value_ :
static_cast< value_type
>( std::forward< U >( value ) ));
319 template<
class... Args >
320 void emplace ( Args &&... args )
325 rawEmplace(std::forward<Args>(args)...);
329 void reset () noexcept
333 value_.~value_type();
338 void swap ( optional &other )
noexcept( std::is_nothrow_move_constructible< T >::value &&
noexcept( std::swap( std::declval< T & >(), std::declval< T & >() ) ) )
340 std::swap( engaged_, other.engaged_ );
344 std::swap( value_, other.value_ );
347 rawEmplace( std::move( other.value_ ) );
348 other.value_.~value_type();
351 else if( other.engaged_ )
353 other.rawEmplace( std::move( value_ ) );
354 value_.~value_type();
365 template<
class... Args>
366 void rawEmplace(Args&&... args)
370 new(
const_cast<std::remove_const_t<value_type>*
>(&value_) ) value_type( std::forward< Args >( args )... );
374 union { value_type value_; };
383 inline static constexpr bool operator== (
const optional< T > &lhs,
const optional< T > &rhs )
385 return (lhs && rhs ? *lhs == *rhs :
static_cast< bool >( lhs ) ==
static_cast< bool >( rhs ));
390 inline static constexpr bool operator< (
const optional< T > &lhs,
const optional< T > &rhs )
392 return (rhs && (lhs ? std::less< T >()( *lhs, *rhs ) :
true));
397 inline static constexpr bool operator== (
const optional< T > &lhs, nullopt_t )
noexcept
403 inline static constexpr bool operator== ( nullopt_t,
const optional< T > &rhs )
noexcept
409 inline static constexpr bool operator< (
const optional< T > &lhs, nullopt_t )
noexcept
415 inline static constexpr bool operator< ( nullopt_t,
const optional< T > &rhs )
noexcept
417 return static_cast< bool >( rhs );
421 inline static constexpr bool operator== (
const optional< T > &lhs,
const T &rhs )
423 return (lhs && (*lhs == rhs));
427 inline static constexpr bool operator== (
const T &lhs,
const optional< T > &rhs )
429 return (rhs && (lhs == *rhs));
433 inline static constexpr bool operator< (
const optional< T > &lhs,
const T &rhs )
435 return (lhs ? std::less< T >()( *lhs, rhs ) :
true);
439 inline static constexpr bool operator< (
const T &lhs,
const optional< T > &rhs )
441 return (rhs ? std::less< T >()( lhs, *rhs ) :
false);
450 inline static constexpr optional< typename std::decay< T >::type > make_optional ( T &&value )
452 return optional< typename std::decay< T >::type >( std::forward< T >( value ) );
462#ifndef DUNE_HAVE_CXX_OPTIONAL
470 inline static void swap ( Dune::Std::optional< T > &lhs, Dune::Std::optional< T > &rhs )
noexcept(
noexcept( lhs.swap( rhs ) ) )
481 struct hash<
Dune::Std::optional< T > >
483 std::size_t operator() (
const Dune::Std::optional< T > &arg )
const
485 return (arg ? std::hash< T >()( arg ) : 0);
Dune namespace.
Definition: alignedallocator.hh:14