File indexing completed on 2025-01-18 09:54:05
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef CATCH_OPTIONAL_HPP_INCLUDED
0009 #define CATCH_OPTIONAL_HPP_INCLUDED
0010
0011 #include <catch2/internal/catch_move_and_forward.hpp>
0012
0013 #include <cassert>
0014
0015 namespace Catch {
0016
0017
0018 template<typename T>
0019 class Optional {
0020 public:
0021 Optional(): nullableValue( nullptr ) {}
0022 ~Optional() { reset(); }
0023
0024 Optional( T const& _value ):
0025 nullableValue( new ( storage ) T( _value ) ) {}
0026 Optional( T&& _value ):
0027 nullableValue( new ( storage ) T( CATCH_MOVE( _value ) ) ) {}
0028
0029 Optional& operator=( T const& _value ) {
0030 reset();
0031 nullableValue = new ( storage ) T( _value );
0032 return *this;
0033 }
0034 Optional& operator=( T&& _value ) {
0035 reset();
0036 nullableValue = new ( storage ) T( CATCH_MOVE( _value ) );
0037 return *this;
0038 }
0039
0040 Optional( Optional const& _other ):
0041 nullableValue( _other ? new ( storage ) T( *_other ) : nullptr ) {}
0042 Optional( Optional&& _other ):
0043 nullableValue( _other ? new ( storage ) T( CATCH_MOVE( *_other ) )
0044 : nullptr ) {}
0045
0046 Optional& operator=( Optional const& _other ) {
0047 if ( &_other != this ) {
0048 reset();
0049 if ( _other ) { nullableValue = new ( storage ) T( *_other ); }
0050 }
0051 return *this;
0052 }
0053 Optional& operator=( Optional&& _other ) {
0054 if ( &_other != this ) {
0055 reset();
0056 if ( _other ) {
0057 nullableValue = new ( storage ) T( CATCH_MOVE( *_other ) );
0058 }
0059 }
0060 return *this;
0061 }
0062
0063 void reset() {
0064 if ( nullableValue ) { nullableValue->~T(); }
0065 nullableValue = nullptr;
0066 }
0067
0068 T& operator*() {
0069 assert(nullableValue);
0070 return *nullableValue;
0071 }
0072 T const& operator*() const {
0073 assert(nullableValue);
0074 return *nullableValue;
0075 }
0076 T* operator->() {
0077 assert(nullableValue);
0078 return nullableValue;
0079 }
0080 const T* operator->() const {
0081 assert(nullableValue);
0082 return nullableValue;
0083 }
0084
0085 T valueOr( T const& defaultValue ) const {
0086 return nullableValue ? *nullableValue : defaultValue;
0087 }
0088
0089 bool some() const { return nullableValue != nullptr; }
0090 bool none() const { return nullableValue == nullptr; }
0091
0092 bool operator !() const { return nullableValue == nullptr; }
0093 explicit operator bool() const {
0094 return some();
0095 }
0096
0097 friend bool operator==(Optional const& a, Optional const& b) {
0098 if (a.none() && b.none()) {
0099 return true;
0100 } else if (a.some() && b.some()) {
0101 return *a == *b;
0102 } else {
0103 return false;
0104 }
0105 }
0106 friend bool operator!=(Optional const& a, Optional const& b) {
0107 return !( a == b );
0108 }
0109
0110 private:
0111 T* nullableValue;
0112 alignas(alignof(T)) char storage[sizeof(T)];
0113 };
0114
0115 }
0116
0117 #endif