| 4407 | // An optional type |
| 4408 | template<typename T> |
| 4409 | class Option { |
| 4410 | public: |
| 4411 | Option() : nullableValue( nullptr ) {} |
| 4412 | Option( T const& _value ) |
| 4413 | : nullableValue( new( storage ) T( _value ) ) |
| 4414 | {} |
| 4415 | Option( Option const& _other ) |
| 4416 | : nullableValue( _other ? new( storage ) T( *_other ) : nullptr ) |
| 4417 | {} |
| 4418 | |
| 4419 | ~Option() { |
| 4420 | reset(); |
| 4421 | } |
| 4422 | |
| 4423 | Option& operator= ( Option const& _other ) { |
| 4424 | if( &_other != this ) { |
| 4425 | reset(); |
| 4426 | if( _other ) |
| 4427 | nullableValue = new( storage ) T( *_other ); |
| 4428 | } |
| 4429 | return *this; |
| 4430 | } |
| 4431 | Option& operator = ( T const& _value ) { |
| 4432 | reset(); |
| 4433 | nullableValue = new( storage ) T( _value ); |
| 4434 | return *this; |
| 4435 | } |
| 4436 | |
| 4437 | void reset() { |
| 4438 | if( nullableValue ) |
| 4439 | nullableValue->~T(); |
| 4440 | nullableValue = nullptr; |
| 4441 | } |
| 4442 | |
| 4443 | T& operator*() { return *nullableValue; } |
| 4444 | T const& operator*() const { return *nullableValue; } |
| 4445 | T* operator->() { return nullableValue; } |
| 4446 | const T* operator->() const { return nullableValue; } |
| 4447 | |
| 4448 | T valueOr( T const& defaultValue ) const { |
| 4449 | return nullableValue ? *nullableValue : defaultValue; |
| 4450 | } |
| 4451 | |
| 4452 | bool some() const { return nullableValue != nullptr; } |
| 4453 | bool none() const { return nullableValue == nullptr; } |
| 4454 | |
| 4455 | bool operator !() const { return nullableValue == nullptr; } |
| 4456 | explicit operator bool() const { |
| 4457 | return some(); |
| 4458 | } |
| 4459 | |
| 4460 | private: |
| 4461 | T *nullableValue; |
| 4462 | alignas(alignof(T)) char storage[sizeof(T)]; |
| 4463 | }; |
| 4464 | |
| 4465 | } // end namespace Catch |
| 4466 | |