This avoids copies in couple places through Catch2, e.g. reporter spec handling, and moving around `AssertionResult` in `RunContext`.
118 lines
3.4 KiB
C++
118 lines
3.4 KiB
C++
|
|
// Copyright Catch2 Authors
|
|
// Distributed under the Boost Software License, Version 1.0.
|
|
// (See accompanying file LICENSE.txt or copy at
|
|
// https://www.boost.org/LICENSE_1_0.txt)
|
|
|
|
// SPDX-License-Identifier: BSL-1.0
|
|
#ifndef CATCH_OPTIONAL_HPP_INCLUDED
|
|
#define CATCH_OPTIONAL_HPP_INCLUDED
|
|
|
|
#include <catch2/internal/catch_move_and_forward.hpp>
|
|
|
|
#include <cassert>
|
|
|
|
namespace Catch {
|
|
|
|
// An optional type
|
|
template<typename T>
|
|
class Optional {
|
|
public:
|
|
Optional(): nullableValue( nullptr ) {}
|
|
~Optional() { reset(); }
|
|
|
|
Optional( T const& _value ):
|
|
nullableValue( new ( storage ) T( _value ) ) {}
|
|
Optional( T&& _value ):
|
|
nullableValue( new ( storage ) T( CATCH_MOVE( _value ) ) ) {}
|
|
|
|
Optional& operator=( T const& _value ) {
|
|
reset();
|
|
nullableValue = new ( storage ) T( _value );
|
|
return *this;
|
|
}
|
|
Optional& operator=( T&& _value ) {
|
|
reset();
|
|
nullableValue = new ( storage ) T( CATCH_MOVE( _value ) );
|
|
return *this;
|
|
}
|
|
|
|
Optional( Optional const& _other ):
|
|
nullableValue( _other ? new ( storage ) T( *_other ) : nullptr ) {}
|
|
Optional( Optional&& _other ):
|
|
nullableValue( _other ? new ( storage ) T( CATCH_MOVE( *_other ) )
|
|
: nullptr ) {}
|
|
|
|
Optional& operator=( Optional const& _other ) {
|
|
if ( &_other != this ) {
|
|
reset();
|
|
if ( _other ) { nullableValue = new ( storage ) T( *_other ); }
|
|
}
|
|
return *this;
|
|
}
|
|
Optional& operator=( Optional&& _other ) {
|
|
if ( &_other != this ) {
|
|
reset();
|
|
if ( _other ) {
|
|
nullableValue = new ( storage ) T( CATCH_MOVE( *_other ) );
|
|
}
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
void reset() {
|
|
if ( nullableValue ) { nullableValue->~T(); }
|
|
nullableValue = nullptr;
|
|
}
|
|
|
|
T& operator*() {
|
|
assert(nullableValue);
|
|
return *nullableValue;
|
|
}
|
|
T const& operator*() const {
|
|
assert(nullableValue);
|
|
return *nullableValue;
|
|
}
|
|
T* operator->() {
|
|
assert(nullableValue);
|
|
return nullableValue;
|
|
}
|
|
const T* operator->() const {
|
|
assert(nullableValue);
|
|
return nullableValue;
|
|
}
|
|
|
|
T valueOr( T const& defaultValue ) const {
|
|
return nullableValue ? *nullableValue : defaultValue;
|
|
}
|
|
|
|
bool some() const { return nullableValue != nullptr; }
|
|
bool none() const { return nullableValue == nullptr; }
|
|
|
|
bool operator !() const { return nullableValue == nullptr; }
|
|
explicit operator bool() const {
|
|
return some();
|
|
}
|
|
|
|
friend bool operator==(Optional const& a, Optional const& b) {
|
|
if (a.none() && b.none()) {
|
|
return true;
|
|
} else if (a.some() && b.some()) {
|
|
return *a == *b;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
friend bool operator!=(Optional const& a, Optional const& b) {
|
|
return !( a == b );
|
|
}
|
|
|
|
private:
|
|
T* nullableValue;
|
|
alignas(alignof(T)) char storage[sizeof(T)];
|
|
};
|
|
|
|
} // end namespace Catch
|
|
|
|
#endif // CATCH_OPTIONAL_HPP_INCLUDED
|