Use std::optional

This commit is contained in:
Chris Thrasher
2025-09-21 16:55:09 -06:00
parent 9c089788ab
commit 44f9adebc1
26 changed files with 74 additions and 264 deletions

View File

@@ -84,7 +84,7 @@ namespace Catch {
std::vector<FDuration> samples2;
samples2.reserve(samples.size());
for (auto s : samples) {
samples2.emplace_back( s );
samples2.push_back( FDuration( s ) );
}
return {

View File

@@ -101,7 +101,6 @@ set(IMPL_HEADERS
${SOURCES_DIR}/internal/catch_meta.hpp
${SOURCES_DIR}/internal/catch_move_and_forward.hpp
${SOURCES_DIR}/internal/catch_noncopyable.hpp
${SOURCES_DIR}/internal/catch_optional.hpp
${SOURCES_DIR}/internal/catch_output_redirect.hpp
${SOURCES_DIR}/internal/catch_parse_numbers.hpp
${SOURCES_DIR}/internal/catch_platform.hpp

View File

@@ -82,7 +82,6 @@
#include <catch2/internal/catch_meta.hpp>
#include <catch2/internal/catch_move_and_forward.hpp>
#include <catch2/internal/catch_noncopyable.hpp>
#include <catch2/internal/catch_optional.hpp>
#include <catch2/internal/catch_output_redirect.hpp>
#include <catch2/internal/catch_parse_numbers.hpp>
#include <catch2/internal/catch_platform.hpp>

View File

@@ -17,6 +17,7 @@
#include <catch2/internal/catch_getenv.hpp>
#include <fstream>
#include <optional>
namespace Catch {
@@ -34,7 +35,7 @@ namespace Catch {
std::string shardFilePath;
};
static Optional<bazelShardingOptions> readBazelShardingOptions() {
static std::optional<bazelShardingOptions> readBazelShardingOptions() {
const auto bazelShardIndex = Detail::getEnv( "TEST_SHARD_INDEX" );
const auto bazelShardTotal = Detail::getEnv( "TEST_TOTAL_SHARDS" );
const auto bazelShardInfoFile = Detail::getEnv( "TEST_SHARD_STATUS_FILE" );
@@ -142,7 +143,7 @@ namespace Catch {
// We do the default-output check separately, while always
// using the default output below to make the code simpler
// and avoid superfluous copies.
if ( reporterSpec.outputFile().none() ) {
if ( !reporterSpec.outputFile() ) {
CATCH_ENFORCE( !defaultOutputUsed,
"Internal error: cannot use default output for "
"multiple reporters" );
@@ -153,7 +154,7 @@ namespace Catch {
reporterSpec.name(),
reporterSpec.outputFile() ? *reporterSpec.outputFile()
: data.defaultOutputFilename,
reporterSpec.colourMode().valueOr( data.defaultColourMode ),
reporterSpec.colourMode().value_or( data.defaultColourMode ),
reporterSpec.customOptions() } );
}
}

View File

@@ -11,7 +11,6 @@
#include <catch2/catch_test_spec.hpp>
#include <catch2/interfaces/catch_interfaces_config.hpp>
#include <catch2/internal/catch_unique_ptr.hpp>
#include <catch2/internal/catch_optional.hpp>
#include <catch2/internal/catch_stringref.hpp>
#include <catch2/internal/catch_random_seed_generation.hpp>
#include <catch2/internal/catch_reporter_spec_parser.hpp>

View File

@@ -88,7 +88,7 @@ namespace Catch {
return ParserResult::ok( ParseResultType::Matched );
};
auto const setDefaultColourMode = [&]( std::string const& colourMode ) {
Optional<ColourMode> maybeMode = Catch::Detail::stringToColourMode(toLower( colourMode ));
std::optional<ColourMode> maybeMode = Catch::Detail::stringToColourMode(toLower( colourMode ));
if ( !maybeMode ) {
return ParserResult::runtimeError(
"colour mode must be one of: default, ansi, win32, "
@@ -135,7 +135,7 @@ namespace Catch {
return ParserResult::runtimeError( "Received empty reporter spec." );
}
Optional<ReporterSpec> parsed =
std::optional<ReporterSpec> parsed =
parseReporterSpec( userReporterSpec );
if ( !parsed ) {
return ParserResult::runtimeError(
@@ -156,7 +156,7 @@ namespace Catch {
}
const bool hadOutputFile = reporterSpec.outputFile().some();
const bool hadOutputFile = reporterSpec.outputFile().has_value();
config.reporterSpecifications.push_back( CATCH_MOVE( *parsed ) );
// It would be enough to check this only once at the very end, but
// there is not a place where we could call this check, so do it
@@ -165,7 +165,7 @@ namespace Catch {
if (!hadOutputFile) {
int n_reporters_without_file = 0;
for (auto const& spec : config.reporterSpecifications) {
if (spec.outputFile().none()) {
if (!spec.outputFile()) {
n_reporters_without_file++;
}
}

View File

@@ -1,117 +0,0 @@
// 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

View File

@@ -12,10 +12,11 @@
#include <limits>
#include <stdexcept>
#include <optional>
namespace Catch {
Optional<unsigned int> parseUInt(std::string const& input, int base) {
std::optional<unsigned int> parseUInt(std::string const& input, int base) {
auto trimmed = trim( input );
// std::stoull is annoying and accepts numbers starting with '-',
// it just negates them into unsigned int

View File

@@ -8,8 +8,7 @@
#ifndef CATCH_PARSE_NUMBERS_HPP_INCLUDED
#define CATCH_PARSE_NUMBERS_HPP_INCLUDED
#include <catch2/internal/catch_optional.hpp>
#include <optional>
#include <string>
namespace Catch {
@@ -20,7 +19,7 @@ namespace Catch {
* Effectively a wrapper around std::stoul but with better error checking
* e.g. "-1" is rejected, instead of being parsed as UINT_MAX.
*/
Optional<unsigned int> parseUInt(std::string const& input, int base = 10);
std::optional<unsigned int> parseUInt(std::string const& input, int base = 10);
}
#endif // CATCH_PARSE_NUMBERS_HPP_INCLUDED

View File

@@ -80,7 +80,7 @@ namespace Catch {
return parts;
}
Optional<ColourMode> stringToColourMode( StringRef colourMode ) {
std::optional<ColourMode> stringToColourMode( StringRef colourMode ) {
if ( colourMode == "default" ) {
return ColourMode::PlatformDefault;
} else if ( colourMode == "ansi" ) {
@@ -103,14 +103,14 @@ namespace Catch {
lhs.m_customOptions == rhs.m_customOptions;
}
Optional<ReporterSpec> parseReporterSpec( StringRef reporterSpec ) {
std::optional<ReporterSpec> parseReporterSpec( StringRef reporterSpec ) {
auto parts = Detail::splitReporterSpec( reporterSpec );
assert( parts.size() > 0 && "Split should never return empty vector" );
std::map<std::string, std::string> kvPairs;
Optional<std::string> outputFileName;
Optional<ColourMode> colourMode;
std::optional<std::string> outputFileName;
std::optional<ColourMode> colourMode;
// First part is always reporter name, so we skip it
for ( size_t i = 1; i < parts.size(); ++i ) {
@@ -162,8 +162,8 @@ namespace Catch {
ReporterSpec::ReporterSpec(
std::string name,
Optional<std::string> outputFileName,
Optional<ColourMode> colourMode,
std::optional<std::string> outputFileName,
std::optional<ColourMode> colourMode,
std::map<std::string, std::string> customOptions ):
m_name( CATCH_MOVE( name ) ),
m_outputFileName( CATCH_MOVE( outputFileName ) ),

View File

@@ -9,12 +9,12 @@
#define CATCH_REPORTER_SPEC_PARSER_HPP_INCLUDED
#include <catch2/interfaces/catch_interfaces_config.hpp>
#include <catch2/internal/catch_optional.hpp>
#include <catch2/internal/catch_stringref.hpp>
#include <map>
#include <string>
#include <vector>
#include <optional>
namespace Catch {
@@ -24,7 +24,7 @@ namespace Catch {
//! Splits the reporter spec into reporter name and kv-pair options
std::vector<std::string> splitReporterSpec( StringRef reporterSpec );
Optional<ColourMode> stringToColourMode( StringRef colourMode );
std::optional<ColourMode> stringToColourMode( StringRef colourMode );
}
/**
@@ -37,8 +37,8 @@ namespace Catch {
*/
class ReporterSpec {
std::string m_name;
Optional<std::string> m_outputFileName;
Optional<ColourMode> m_colourMode;
std::optional<std::string> m_outputFileName;
std::optional<ColourMode> m_colourMode;
std::map<std::string, std::string> m_customOptions;
friend bool operator==( ReporterSpec const& lhs,
@@ -51,17 +51,17 @@ namespace Catch {
public:
ReporterSpec(
std::string name,
Optional<std::string> outputFileName,
Optional<ColourMode> colourMode,
std::optional<std::string> outputFileName,
std::optional<ColourMode> colourMode,
std::map<std::string, std::string> customOptions );
std::string const& name() const { return m_name; }
Optional<std::string> const& outputFile() const {
std::optional<std::string> const& outputFile() const {
return m_outputFileName;
}
Optional<ColourMode> const& colourMode() const { return m_colourMode; }
std::optional<ColourMode> const& colourMode() const { return m_colourMode; }
std::map<std::string, std::string> const& customOptions() const {
return m_customOptions;
@@ -78,7 +78,7 @@ namespace Catch {
* * empty key/value in an custom kv pair
* * ...
*/
Optional<ReporterSpec> parseReporterSpec( StringRef reporterSpec );
std::optional<ReporterSpec> parseReporterSpec( StringRef reporterSpec );
}

View File

@@ -355,7 +355,7 @@ namespace Catch {
// Reset working state. assertion info will be reset after
// populateReaction is run if it is needed
m_lastResult = CATCH_MOVE( result );
m_lastResult.emplace(CATCH_MOVE( result ));
}
void RunContext::notifyAssertionStarted( AssertionInfo const& info ) {

View File

@@ -18,10 +18,10 @@
#include <catch2/internal/catch_test_case_tracker.hpp>
#include <catch2/catch_assertion_info.hpp>
#include <catch2/catch_assertion_result.hpp>
#include <catch2/internal/catch_optional.hpp>
#include <catch2/internal/catch_move_and_forward.hpp>
#include <catch2/internal/catch_thread_support.hpp>
#include <optional>
#include <string>
namespace Catch {
@@ -144,7 +144,7 @@ namespace Catch {
TestRunInfo m_runInfo;
TestCaseHandle const* m_activeTestCase = nullptr;
ITracker* m_testCaseTracker = nullptr;
Optional<AssertionResult> m_lastResult;
std::optional<AssertionResult> m_lastResult;
IConfig const* m_config;
Totals m_totals;
Detail::AtomicCounts m_atomicAssertionCount;

View File

@@ -108,7 +108,6 @@ internal_headers = [
'internal/catch_meta.hpp',
'internal/catch_move_and_forward.hpp',
'internal/catch_noncopyable.hpp',
'internal/catch_optional.hpp',
'internal/catch_output_redirect.hpp',
'internal/catch_parse_numbers.hpp',
'internal/catch_platform.hpp',

View File

@@ -42,19 +42,19 @@ namespace Catch {
m_benchmark( benchmark ) {}
bool AssertionOrBenchmarkResult::isAssertion() const {
return m_assertion.some();
return m_assertion.has_value();
}
bool AssertionOrBenchmarkResult::isBenchmark() const {
return m_benchmark.some();
return m_benchmark.has_value();
}
AssertionStats const& AssertionOrBenchmarkResult::asAssertion() const {
assert(m_assertion.some());
assert(m_assertion.has_value());
return *m_assertion;
}
BenchmarkStats<> const& AssertionOrBenchmarkResult::asBenchmark() const {
assert(m_benchmark.some());
assert(m_benchmark.has_value());
return *m_benchmark;
}

View File

@@ -11,8 +11,8 @@
#include <catch2/reporters/catch_reporter_common_base.hpp>
#include <catch2/internal/catch_move_and_forward.hpp>
#include <catch2/internal/catch_unique_ptr.hpp>
#include <catch2/internal/catch_optional.hpp>
#include <optional>
#include <string>
#include <vector>
@@ -25,8 +25,8 @@ namespace Catch {
// This should really be a variant, but this is much faster
// to write and the data layout here is already terrible
// enough that we do not have to care about the object size.
Optional<AssertionStats> m_assertion;
Optional<BenchmarkStats<>> m_benchmark;
std::optional<AssertionStats> m_assertion;
std::optional<BenchmarkStats<>> m_benchmark;
public:
AssertionOrBenchmarkResult(AssertionStats const& assertion);
AssertionOrBenchmarkResult(BenchmarkStats<> const& benchmark);

View File

@@ -1364,10 +1364,10 @@ Matchers.tests.cpp:<line number>: passed: ( EvilMatcher(), EvilMatcher() ), Evil
Matchers.tests.cpp:<line number>: passed: &EvilMatcher(), EvilAddressOfOperatorUsed
Matchers.tests.cpp:<line number>: passed: EvilMatcher() || ( EvilMatcher() && !EvilMatcher() )
Matchers.tests.cpp:<line number>: passed: ( EvilMatcher() && EvilMatcher() ) || !EvilMatcher()
Parse.tests.cpp:<line number>: passed: parseUInt( "0" ) == Optional<unsigned int>{ 0 } for: {?} == {?}
Parse.tests.cpp:<line number>: passed: parseUInt( "100" ) == Optional<unsigned int>{ 100 } for: {?} == {?}
Parse.tests.cpp:<line number>: passed: parseUInt( "4294967295" ) == Optional<unsigned int>{ 4294967295 } for: {?} == {?}
Parse.tests.cpp:<line number>: passed: parseUInt( "0x<hex digits>", 16 ) == Optional<unsigned int>{ 255 } for: {?} == {?}
Parse.tests.cpp:<line number>: passed: parseUInt( "0" ) == std::optional<unsigned int>{ 0 } for: {?} == {?}
Parse.tests.cpp:<line number>: passed: parseUInt( "100" ) == std::optional<unsigned int>{ 100 } for: {?} == {?}
Parse.tests.cpp:<line number>: passed: parseUInt( "4294967295" ) == std::optional<unsigned int>{ 4294967295 } for: {?} == {?}
Parse.tests.cpp:<line number>: passed: parseUInt( "0x<hex digits>", 16 ) == std::optional<unsigned int>{ 255 } for: {?} == {?}
Parse.tests.cpp:<line number>: passed: !(parseUInt( "" )) for: !{?}
Parse.tests.cpp:<line number>: passed: !(parseUInt( "!!KJHF*#" )) for: !{?}
Parse.tests.cpp:<line number>: passed: !(parseUInt( "-1" )) for: !{?}

View File

@@ -1362,10 +1362,10 @@ Matchers.tests.cpp:<line number>: passed: ( EvilMatcher(), EvilMatcher() ), Evil
Matchers.tests.cpp:<line number>: passed: &EvilMatcher(), EvilAddressOfOperatorUsed
Matchers.tests.cpp:<line number>: passed: EvilMatcher() || ( EvilMatcher() && !EvilMatcher() )
Matchers.tests.cpp:<line number>: passed: ( EvilMatcher() && EvilMatcher() ) || !EvilMatcher()
Parse.tests.cpp:<line number>: passed: parseUInt( "0" ) == Optional<unsigned int>{ 0 } for: {?} == {?}
Parse.tests.cpp:<line number>: passed: parseUInt( "100" ) == Optional<unsigned int>{ 100 } for: {?} == {?}
Parse.tests.cpp:<line number>: passed: parseUInt( "4294967295" ) == Optional<unsigned int>{ 4294967295 } for: {?} == {?}
Parse.tests.cpp:<line number>: passed: parseUInt( "0x<hex digits>", 16 ) == Optional<unsigned int>{ 255 } for: {?} == {?}
Parse.tests.cpp:<line number>: passed: parseUInt( "0" ) == std::optional<unsigned int>{ 0 } for: {?} == {?}
Parse.tests.cpp:<line number>: passed: parseUInt( "100" ) == std::optional<unsigned int>{ 100 } for: {?} == {?}
Parse.tests.cpp:<line number>: passed: parseUInt( "4294967295" ) == std::optional<unsigned int>{ 4294967295 } for: {?} == {?}
Parse.tests.cpp:<line number>: passed: parseUInt( "0x<hex digits>", 16 ) == std::optional<unsigned int>{ 255 } for: {?} == {?}
Parse.tests.cpp:<line number>: passed: !(parseUInt( "" )) for: !{?}
Parse.tests.cpp:<line number>: passed: !(parseUInt( "!!KJHF*#" )) for: !{?}
Parse.tests.cpp:<line number>: passed: !(parseUInt( "-1" )) for: !{?}

View File

@@ -8848,22 +8848,22 @@ Parse.tests.cpp:<line number>
...............................................................................
Parse.tests.cpp:<line number>: PASSED:
REQUIRE( parseUInt( "0" ) == Optional<unsigned int>{ 0 } )
REQUIRE( parseUInt( "0" ) == std::optional<unsigned int>{ 0 } )
with expansion:
{?} == {?}
Parse.tests.cpp:<line number>: PASSED:
REQUIRE( parseUInt( "100" ) == Optional<unsigned int>{ 100 } )
REQUIRE( parseUInt( "100" ) == std::optional<unsigned int>{ 100 } )
with expansion:
{?} == {?}
Parse.tests.cpp:<line number>: PASSED:
REQUIRE( parseUInt( "4294967295" ) == Optional<unsigned int>{ 4294967295 } )
REQUIRE( parseUInt( "4294967295" ) == std::optional<unsigned int>{ 4294967295 } )
with expansion:
{?} == {?}
Parse.tests.cpp:<line number>: PASSED:
REQUIRE( parseUInt( "0x<hex digits>", 16 ) == Optional<unsigned int>{ 255 } )
REQUIRE( parseUInt( "0x<hex digits>", 16 ) == std::optional<unsigned int>{ 255 } )
with expansion:
{?} == {?}

View File

@@ -8846,22 +8846,22 @@ Parse.tests.cpp:<line number>
...............................................................................
Parse.tests.cpp:<line number>: PASSED:
REQUIRE( parseUInt( "0" ) == Optional<unsigned int>{ 0 } )
REQUIRE( parseUInt( "0" ) == std::optional<unsigned int>{ 0 } )
with expansion:
{?} == {?}
Parse.tests.cpp:<line number>: PASSED:
REQUIRE( parseUInt( "100" ) == Optional<unsigned int>{ 100 } )
REQUIRE( parseUInt( "100" ) == std::optional<unsigned int>{ 100 } )
with expansion:
{?} == {?}
Parse.tests.cpp:<line number>: PASSED:
REQUIRE( parseUInt( "4294967295" ) == Optional<unsigned int>{ 4294967295 } )
REQUIRE( parseUInt( "4294967295" ) == std::optional<unsigned int>{ 4294967295 } )
with expansion:
{?} == {?}
Parse.tests.cpp:<line number>: PASSED:
REQUIRE( parseUInt( "0x<hex digits>", 16 ) == Optional<unsigned int>{ 255 } )
REQUIRE( parseUInt( "0x<hex digits>", 16 ) == std::optional<unsigned int>{ 255 } )
with expansion:
{?} == {?}

View File

@@ -2207,13 +2207,13 @@ ok {test-number} - EvilMatcher() || ( EvilMatcher() && !EvilMatcher() )
# Overloaded comma or address-of operators are not used
ok {test-number} - ( EvilMatcher() && EvilMatcher() ) || !EvilMatcher()
# Parse uints
ok {test-number} - parseUInt( "0" ) == Optional<unsigned int>{ 0 } for: {?} == {?}
ok {test-number} - parseUInt( "0" ) == std::optional<unsigned int>{ 0 } for: {?} == {?}
# Parse uints
ok {test-number} - parseUInt( "100" ) == Optional<unsigned int>{ 100 } for: {?} == {?}
ok {test-number} - parseUInt( "100" ) == std::optional<unsigned int>{ 100 } for: {?} == {?}
# Parse uints
ok {test-number} - parseUInt( "4294967295" ) == Optional<unsigned int>{ 4294967295 } for: {?} == {?}
ok {test-number} - parseUInt( "4294967295" ) == std::optional<unsigned int>{ 4294967295 } for: {?} == {?}
# Parse uints
ok {test-number} - parseUInt( "0x<hex digits>", 16 ) == Optional<unsigned int>{ 255 } for: {?} == {?}
ok {test-number} - parseUInt( "0x<hex digits>", 16 ) == std::optional<unsigned int>{ 255 } for: {?} == {?}
# Parse uints
ok {test-number} - !(parseUInt( "" )) for: !{?}
# Parse uints

View File

@@ -2205,13 +2205,13 @@ ok {test-number} - EvilMatcher() || ( EvilMatcher() && !EvilMatcher() )
# Overloaded comma or address-of operators are not used
ok {test-number} - ( EvilMatcher() && EvilMatcher() ) || !EvilMatcher()
# Parse uints
ok {test-number} - parseUInt( "0" ) == Optional<unsigned int>{ 0 } for: {?} == {?}
ok {test-number} - parseUInt( "0" ) == std::optional<unsigned int>{ 0 } for: {?} == {?}
# Parse uints
ok {test-number} - parseUInt( "100" ) == Optional<unsigned int>{ 100 } for: {?} == {?}
ok {test-number} - parseUInt( "100" ) == std::optional<unsigned int>{ 100 } for: {?} == {?}
# Parse uints
ok {test-number} - parseUInt( "4294967295" ) == Optional<unsigned int>{ 4294967295 } for: {?} == {?}
ok {test-number} - parseUInt( "4294967295" ) == std::optional<unsigned int>{ 4294967295 } for: {?} == {?}
# Parse uints
ok {test-number} - parseUInt( "0x<hex digits>", 16 ) == Optional<unsigned int>{ 255 } for: {?} == {?}
ok {test-number} - parseUInt( "0x<hex digits>", 16 ) == std::optional<unsigned int>{ 255 } for: {?} == {?}
# Parse uints
ok {test-number} - !(parseUInt( "" )) for: !{?}
# Parse uints

View File

@@ -10530,7 +10530,7 @@ Approx( 1.21999999999999997 )
<Section name="proper inputs" filename="tests/<exe-name>/IntrospectiveTests/Parse.tests.cpp" >
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/IntrospectiveTests/Parse.tests.cpp" >
<Original>
parseUInt( "0" ) == Optional&lt;unsigned int>{ 0 }
parseUInt( "0" ) == std::optional&lt;unsigned int>{ 0 }
</Original>
<Expanded>
{?} == {?}
@@ -10538,7 +10538,7 @@ Approx( 1.21999999999999997 )
</Expression>
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/IntrospectiveTests/Parse.tests.cpp" >
<Original>
parseUInt( "100" ) == Optional&lt;unsigned int>{ 100 }
parseUInt( "100" ) == std::optional&lt;unsigned int>{ 100 }
</Original>
<Expanded>
{?} == {?}
@@ -10546,7 +10546,7 @@ Approx( 1.21999999999999997 )
</Expression>
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/IntrospectiveTests/Parse.tests.cpp" >
<Original>
parseUInt( "4294967295" ) == Optional&lt;unsigned int>{ 4294967295 }
parseUInt( "4294967295" ) == std::optional&lt;unsigned int>{ 4294967295 }
</Original>
<Expanded>
{?} == {?}
@@ -10554,7 +10554,7 @@ Approx( 1.21999999999999997 )
</Expression>
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/IntrospectiveTests/Parse.tests.cpp" >
<Original>
parseUInt( "0x<hex digits>", 16 ) == Optional&lt;unsigned int>{ 255 }
parseUInt( "0x<hex digits>", 16 ) == std::optional&lt;unsigned int>{ 255 }
</Original>
<Expanded>
{?} == {?}

View File

@@ -10530,7 +10530,7 @@ Approx( 1.21999999999999997 )
<Section name="proper inputs" filename="tests/<exe-name>/IntrospectiveTests/Parse.tests.cpp" >
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/IntrospectiveTests/Parse.tests.cpp" >
<Original>
parseUInt( "0" ) == Optional&lt;unsigned int>{ 0 }
parseUInt( "0" ) == std::optional&lt;unsigned int>{ 0 }
</Original>
<Expanded>
{?} == {?}
@@ -10538,7 +10538,7 @@ Approx( 1.21999999999999997 )
</Expression>
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/IntrospectiveTests/Parse.tests.cpp" >
<Original>
parseUInt( "100" ) == Optional&lt;unsigned int>{ 100 }
parseUInt( "100" ) == std::optional&lt;unsigned int>{ 100 }
</Original>
<Expanded>
{?} == {?}
@@ -10546,7 +10546,7 @@ Approx( 1.21999999999999997 )
</Expression>
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/IntrospectiveTests/Parse.tests.cpp" >
<Original>
parseUInt( "4294967295" ) == Optional&lt;unsigned int>{ 4294967295 }
parseUInt( "4294967295" ) == std::optional&lt;unsigned int>{ 4294967295 }
</Original>
<Expanded>
{?} == {?}
@@ -10554,7 +10554,7 @@ Approx( 1.21999999999999997 )
</Expression>
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/IntrospectiveTests/Parse.tests.cpp" >
<Original>
parseUInt( "0x<hex digits>", 16 ) == Optional&lt;unsigned int>{ 255 }
parseUInt( "0x<hex digits>", 16 ) == std::optional&lt;unsigned int>{ 255 }
</Original>
<Expanded>
{?} == {?}

View File

@@ -9,7 +9,6 @@
#include <catch2/catch_test_macros.hpp>
#include <catch2/internal/catch_enforce.hpp>
#include <catch2/internal/catch_case_insensitive_comparisons.hpp>
#include <catch2/internal/catch_optional.hpp>
#include <helpers/type_with_lit_0_comparisons.hpp>
@@ -62,74 +61,6 @@ TEST_CASE( "CaseInsensitiveEqualsTo is case insensitive",
}
}
TEST_CASE("Optional comparison ops", "[optional][approvals]") {
using Catch::Optional;
Optional<int> a, b;
SECTION( "Empty optionals are equal" ) {
REQUIRE( a == b );
REQUIRE_FALSE( a != b );
}
SECTION( "Empty and non-empty optionals are never equal" ) {
a = 1;
REQUIRE_FALSE( a == b );
REQUIRE( a != b );
}
SECTION(
"non-empty optionals are equal if the contained elements are equal") {
a = 1;
b = 2;
REQUIRE( a != b );
REQUIRE_FALSE( a == b );
a = 2;
REQUIRE( a == b );
REQUIRE_FALSE( a != b );
}
}
namespace {
struct MoveChecker {
bool has_moved = false;
MoveChecker() = default;
MoveChecker( MoveChecker const& rhs ) = default;
MoveChecker& operator=( MoveChecker const& rhs ) = default;
MoveChecker( MoveChecker&& rhs ) noexcept { rhs.has_moved = true; }
MoveChecker& operator=( MoveChecker&& rhs ) noexcept {
rhs.has_moved = true;
return *this;
}
};
}
TEST_CASE( "Optional supports move ops", "[optional][approvals]" ) {
using Catch::Optional;
MoveChecker a;
Optional<MoveChecker> opt_A( a );
REQUIRE_FALSE( a.has_moved );
REQUIRE_FALSE( opt_A->has_moved );
SECTION( "Move construction from element" ) {
Optional<MoveChecker> opt_B( CATCH_MOVE( a ) );
REQUIRE( a.has_moved );
}
SECTION( "Move assignment from element" ) {
opt_A = CATCH_MOVE( a );
REQUIRE( a.has_moved );
}
SECTION( "Move construction from optional" ) {
Optional<MoveChecker> opt_B( CATCH_MOVE( opt_A ) );
REQUIRE( opt_A->has_moved ); // NOLINT(clang-analyzer-cplusplus.Move)
}
SECTION( "Move assignment from optional" ) {
Optional<MoveChecker> opt_B( opt_A );
REQUIRE_FALSE( opt_A->has_moved );
opt_B = CATCH_MOVE( opt_A );
REQUIRE( opt_A->has_moved ); // NOLINT(clang-analyzer-cplusplus.Move)
}
}
TEST_CASE( "Decomposer checks that the argument is 0 when handling "
"only-0-comparable types",
"[decomposition][approvals]" ) {

View File

@@ -12,14 +12,13 @@
TEST_CASE("Parse uints", "[parse-numbers]") {
using Catch::parseUInt;
using Catch::Optional;
SECTION("proper inputs") {
REQUIRE( parseUInt( "0" ) == Optional<unsigned int>{ 0 } );
REQUIRE( parseUInt( "100" ) == Optional<unsigned int>{ 100 } );
REQUIRE( parseUInt( "0" ) == std::optional<unsigned int>{ 0 } );
REQUIRE( parseUInt( "100" ) == std::optional<unsigned int>{ 100 } );
REQUIRE( parseUInt( "4294967295" ) ==
Optional<unsigned int>{ 4294967295 } );
REQUIRE( parseUInt( "0xFF", 16 ) == Optional<unsigned int>{ 255 } );
std::optional<unsigned int>{ 4294967295 } );
REQUIRE( parseUInt( "0xFF", 16 ) == std::optional<unsigned int>{ 255 } );
}
SECTION( "Bad inputs" ) {
// empty