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 >;
36 const nullopt_t nullopt = {};
50 const in_place_t in_place = {};
60 class bad_optional_access
61 :
public std::logic_error
64 explicit bad_optional_access (
const std::string &what ) :
std::logic_error( what ) {}
65 explicit bad_optional_access (
const char *what ) :
std::logic_error( what ) {}
89 constexpr optional () noexcept : engaged_( false ) {}
91 constexpr optional ( nullopt_t ) noexcept : engaged_(
false ) {}
93 template<
class U = value_type,
94 std::enable_if_t< std::is_constructible< value_type, U&& >::value,
int > = 0,
95 std::enable_if_t< !std::is_convertible< U&&, value_type >::value,
int > = 0 >
96 explicit constexpr optional ( U && value )
97 : engaged_( true ), value_(
std::forward< U >( value ) )
100 template<
class U = value_type,
101 std::enable_if_t< std::is_constructible< value_type, U&& >::value,
int > = 0,
102 std::enable_if_t< std::is_convertible< U&&, value_type >::value,
int > = 0 >
103 constexpr optional ( U && value )
104 : engaged_( true ), value_(
std::forward< U >( value ) )
107 optional (
const value_type &value ) : engaged_( true ), value_( value ) {}
108 optional ( value_type &&value ) : engaged_( true ), value_(
std::move( value ) ) {}
110 template<
class... Args >
111 explicit constexpr optional ( in_place_t, Args &&... args )
112 : engaged_( true ), value_(
std::forward< Args >( args )... )
122 optional (
const optional &other )
noexcept( std::is_nothrow_copy_constructible< T >::value )
123 : engaged_( other.engaged_ )
126 new( &value_ ) value_type( other.value_ );
129 optional ( optional &&other )
noexcept( std::is_nothrow_move_constructible< T >::value )
130 : engaged_( other.engaged_ )
133 new( &value_ ) value_type( std::move( other.value_ ) );
137 std::enable_if_t< std::is_constructible< value_type, const U& >::value,
int > = 0,
138 std::enable_if_t< !std::is_constructible< value_type, optional< U >& >::value,
int > = 0,
139 std::enable_if_t< !std::is_constructible< value_type, const optional< U >& >::value,
int > = 0,
140 std::enable_if_t< !std::is_constructible< value_type, optional< U >&& >::value,
int > = 0,
141 std::enable_if_t< !std::is_constructible< optional< U >&, value_type >::value,
int > = 0,
142 std::enable_if_t< !std::is_constructible< const optional< U >&, value_type >::value,
int > = 0,
143 std::enable_if_t< !std::is_constructible< optional< U >&&, value_type >::value,
int > = 0,
144 std::enable_if_t< !std::is_convertible< const U&, value_type >::value,
int > = 0 >
145 explicit optional (
const optional< U > &other )
146 : engaged_( other.engaged_ )
149 new( &value_ ) value_type( other.value_ );
153 std::enable_if_t< std::is_constructible< value_type, const 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< value_type, const optional< U >& >::value,
int > = 0,
156 std::enable_if_t< !std::is_constructible< value_type, optional< U >&& >::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_constructible< const optional< U >&, value_type >::value,
int > = 0,
159 std::enable_if_t< !std::is_constructible< optional< U >&&, value_type >::value,
int > = 0,
160 std::enable_if_t< std::is_convertible< const U&, value_type >::value,
int > = 0 >
161 optional (
const optional< U > &other )
162 : engaged_( other.engaged_ )
165 new( &value_ ) value_type( other.value_ );
169 std::enable_if_t< std::is_constructible< value_type, const 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< value_type, const optional< U >& >::value,
int > = 0,
172 std::enable_if_t< !std::is_constructible< value_type, optional< U >&& >::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_constructible< const optional< U >&, value_type >::value,
int > = 0,
175 std::enable_if_t< !std::is_constructible< optional< U >&&, value_type >::value,
int > = 0,
176 std::enable_if_t< !std::is_convertible< const U&, value_type >::value,
int > = 0 >
177 explicit optional ( optional< U > &&other )
178 : engaged_( other.engaged_ )
181 new( &value_ ) value_type( std::move( other.value_ ) );
185 std::enable_if_t< std::is_constructible< value_type, const 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< value_type, const optional< U >& >::value,
int > = 0,
188 std::enable_if_t< !std::is_constructible< value_type, optional< U >&& >::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_constructible< const optional< U >&, value_type >::value,
int > = 0,
191 std::enable_if_t< !std::is_constructible< optional< U >&&, value_type >::value,
int > = 0,
192 std::enable_if_t< std::is_convertible< const U&, value_type >::value,
int > = 0 >
193 optional ( optional< U > &&other )
194 : engaged_( other.engaged_ )
197 new( &value_ ) value_type( std::move( other.value_ ) );
200 optional &operator= ( nullopt_t )
noexcept
203 value_.~value_type();
208 optional &operator= (
const optional &other )
noexcept( std::is_nothrow_copy_constructible< T >::value && std::is_nothrow_copy_assignable< T >::value )
213 value_ = other.value_;
215 value_.~value_type();
217 else if( other.engaged_ )
218 new( &value_ ) value_type( other.value_ );
219 engaged_ = other.engaged_;
223 optional &operator= ( optional &&other )
noexcept( std::is_nothrow_move_constructible< T >::value && std::is_nothrow_move_assignable< T >::value )
228 value_ = std::move( other.value_ );
230 value_.~value_type();
232 else if( other.engaged_ )
233 new( &value_ ) value_type( std::move( other.value_ ) );
234 engaged_ = other.engaged_;
238 template<
class U = value_type >
239 typename std::enable_if< std::is_constructible< value_type, U >::value && std::is_assignable< value_type, U >::value, optional & >::type
240 operator= ( U &&value )
243 value_ = std::move( value );
245 new( &value_ ) value_type( std::forward< U >( value ) );
255 value_.~value_type();
264 explicit constexpr operator bool () const noexcept {
return engaged_; }
267 const value_type &operator* () const noexcept { assert( engaged_ );
return value_; }
269 value_type &operator* () noexcept { assert( engaged_ );
return value_; }
272 const value_type *operator->() const noexcept { assert( engaged_ );
return &value_; }
274 value_type *operator->() noexcept { assert( engaged_ );
return &value_; }
276 const value_type &value ()
const
281 throw bad_optional_access(
"Cannot access value of disengaged optional." );
289 throw bad_optional_access(
"Cannot access value of disengaged optional." );
293 value_type value_or ( U &&value )
const
295 return (engaged_ ? value_ :
static_cast< value_type
>( std::forward< U >( value ) ));
305 template<
class... Args >
306 void emplace ( Args &&... args )
311 new( &value_ ) value_type( std::forward< Args >( args )... );
315 void reset () noexcept
319 value_.~value_type();
324 void swap ( optional &other )
noexcept( std::is_nothrow_move_constructible< T >::value &&
noexcept( std::swap( std::declval< T & >(), std::declval< T & >() ) ) )
326 std::swap( engaged_, other.engaged_ );
330 std::swap( value_, other.value_ );
333 new( &value_ ) value_type( std::move( other.value_ ) );
334 other.value_.~value_type();
337 else if( other.engaged_ )
339 new( &other.value_ ) value_type( std::move( value_ ) );
340 value_.~value_type();
348 union { value_type value_; };
357 inline static constexpr bool operator== (
const optional< T > &lhs,
const optional< T > &rhs )
359 return (lhs && rhs ? *lhs == *rhs :
static_cast< bool >( lhs ) ==
static_cast< bool >( rhs ));
364 inline static constexpr bool operator< (
const optional< T > &lhs,
const optional< T > &rhs )
366 return (rhs && (lhs ? std::less< T >()( *lhs, *rhs ) :
true));
371 inline static constexpr bool operator== (
const optional< T > &lhs, nullopt_t )
noexcept
377 inline static constexpr bool operator== ( nullopt_t,
const optional< T > &rhs )
noexcept
383 inline static constexpr bool operator< (
const optional< T > &lhs, nullopt_t )
noexcept
389 inline static constexpr bool operator< ( nullopt_t,
const optional< T > &rhs )
noexcept
391 return static_cast< bool >( rhs );
395 inline static constexpr bool operator== (
const optional< T > &lhs,
const T &rhs )
397 return (lhs && (*lhs == rhs));
401 inline static constexpr bool operator== (
const T &lhs,
const optional< T > &rhs )
403 return (rhs && (lhs == *rhs));
407 inline static constexpr bool operator< (
const optional< T > &lhs,
const T &rhs )
409 return (lhs ? std::less< T >()( *lhs, rhs ) :
true);
413 inline static constexpr bool operator< (
const T &lhs,
const optional< T > &rhs )
415 return (rhs ? std::less< T >()( lhs, *rhs ) :
false);
424 inline static constexpr optional< typename std::decay< T >::type > make_optional ( T &&value )
426 return optional< typename std::decay< T >::type >( std::forward< T >( value ) );
436#ifndef DUNE_HAVE_CXX_OPTIONAL
444 inline static void swap ( Dune::Std::optional< T > &lhs, Dune::Std::optional< T > &rhs )
noexcept(
noexcept( lhs.swap( rhs ) ) )
455 struct hash<
Dune::Std::optional< T > >
457 std::size_t operator() (
const Dune::Std::optional< T > &arg )
const
459 return (arg ? std::hash< T >()( arg ) : 0);
Dune namespace.
Definition: alignedallocator.hh:10