Read-only mirrors. Development, issues and pull requests are on GitHub.

summaryrefslogtreecommitdiffhomepage
path: root/src/catch2/internal
diff options
context:
space:
mode:
authorLeitwolf112026-10-23 23:25:41 +0300
committerLeitwolf112026-10-23 23:25:41 +0300
commit93d4e7dbebab867e0a7f59fc25308460a7a76280 (patch)
tree54c568a3063d49e21f039b6d38f40f51be7991f0 /src/catch2/internal
parent83c6fc3ac13abe83fa39f7b5f8559ccaf4412233 (diff)
downloadcatch3-93d4e7dbebab867e0a7f59fc25308460a7a76280.tar.gz
Replace Catch2's runner with the Catch3 runner
Catch3 keeps Catch2's API for writing tests (test cases, sections, assertions, matchers, generators, listeners, benchmarks) and replaces its session, command line and reporters with a runner of its own. The runner starts the test binary again as worker processes that take the next test when they are free. A crash, an exit or a hang ends one test, not the run. On top of that it adds: - retries that tell deterministic, flaky and order-dependent failures apart, and a bisection that names the test leaving state behind; - a history of verdicts and durations, kept under a file lock, that drives automatic quarantine, adaptive time limits, predictive ordering, incremental runs, failure replay and analytics; - selection by change, past failure or prediction, dependency closure, and sharding by a stable hash or by recorded durations; - tags for serial and isolated tests, shared resources, dependencies, time limits and retries; - a failure category, a signature, an analysis and a replay command for every failure; - console, JUnit XML (with flakyFailure and rerunFailure), JSON and Chrome trace reports, and a versioned discovery listing (--list=json); - a temporary directory per test (TMPDIR, TMP, TEMP and TestTemporaryDirectory()); - Bazel's test environment: XML output file, test filter, sharding, seed, premature exit file and undeclared outputs. The command line is parsed by a hand-written, typed parser. Catch::Session remains as a thin facade over the runner for custom main functions. The result model in Progmasoft/Catch3/Results.hpp was rewritten around tests and attempts, and the JUnit writer now writes it. The property engine's example database is updated under a file lock with an atomic rename, so parallel workers can write it at the same time. Removed: Clara, the command-line and reporter-spec parsers, every reporter and CATCH_REGISTER_REPORTER, listing, text flow, console colour and width, the JSON and XML writers, sharding in the test registry, approval tests and their baselines, Conan packaging, and the unused third_party/clara.hpp. Listeners keep working; reporters' list and skip events are gone. The Catch2 library is now compiled as C++20; code that includes only Catch2's headers still needs C++14. Duplicate test cases are still refused at start-up. Version 0.3.0. ExtraTests now turn exceptions off for clang-cl with MSVC-style options, which -fno-exceptions did not do.
Diffstat (limited to 'src/catch2/internal')
-rw-r--r--src/catch2/internal/catch_clara.cpp464
-rw-r--r--src/catch2/internal/catch_clara.hpp749
-rw-r--r--src/catch2/internal/catch_commandline.cpp379
-rw-r--r--src/catch2/internal/catch_commandline.hpp21
-rw-r--r--src/catch2/internal/catch_console_colour.cpp288
-rw-r--r--src/catch2/internal/catch_console_colour.hpp141
-rw-r--r--src/catch2/internal/catch_console_width.hpp19
-rw-r--r--src/catch2/internal/catch_debug_console.cpp45
-rw-r--r--src/catch2/internal/catch_debug_console.hpp17
-rw-r--r--src/catch2/internal/catch_istream.cpp152
-rw-r--r--src/catch2/internal/catch_istream.hpp52
-rw-r--r--src/catch2/internal/catch_jsonwriter.cpp214
-rw-r--r--src/catch2/internal/catch_jsonwriter.hpp129
-rw-r--r--src/catch2/internal/catch_list.cpp120
-rw-r--r--src/catch2/internal/catch_list.hpp43
-rw-r--r--src/catch2/internal/catch_reporter_registry.cpp61
-rw-r--r--src/catch2/internal/catch_reporter_registry.hpp14
-rw-r--r--src/catch2/internal/catch_reporter_spec_parser.cpp196
-rw-r--r--src/catch2/internal/catch_reporter_spec_parser.hpp90
-rw-r--r--src/catch2/internal/catch_reusable_string_stream.hpp1
-rw-r--r--src/catch2/internal/catch_run_context.cpp8
-rw-r--r--src/catch2/internal/catch_run_context.hpp4
-rw-r--r--src/catch2/internal/catch_sharding.hpp44
-rw-r--r--src/catch2/internal/catch_test_case_registry_impl.cpp4
-rw-r--r--src/catch2/internal/catch_textflow.cpp430
-rw-r--r--src/catch2/internal/catch_textflow.hpp309
-rw-r--r--src/catch2/internal/catch_xmlwriter.cpp344
-rw-r--r--src/catch2/internal/catch_xmlwriter.hpp164
28 files changed, 16 insertions, 4486 deletions
diff --git a/src/catch2/internal/catch_clara.cpp b/src/catch2/internal/catch_clara.cpp
deleted file mode 100644
index f9dd9138..00000000
--- a/src/catch2/internal/catch_clara.cpp
+++ /dev/null
@@ -1,464 +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
-
-#include <catch2/internal/catch_clara.hpp>
-#include <catch2/internal/catch_console_width.hpp>
-#include <catch2/internal/catch_platform.hpp>
-#include <catch2/internal/catch_string_manip.hpp>
-#include <catch2/internal/catch_textflow.hpp>
-#include <catch2/internal/catch_reusable_string_stream.hpp>
-
-#include <algorithm>
-#include <ostream>
-
-namespace {
- bool isOptPrefix( char c ) {
- return c == '-'
-#ifdef CATCH_PLATFORM_WINDOWS
- || c == '/'
-#endif
- ;
- }
-
- Catch::StringRef normaliseOpt( Catch::StringRef optName ) {
- if ( optName[0] == '-'
-#if defined(CATCH_PLATFORM_WINDOWS)
- || optName[0] == '/'
-#endif
- ) {
- return optName.substr( 1, optName.size() );
- }
-
- return optName;
- }
-
- static size_t find_first_separator(Catch::StringRef sr) {
- auto is_separator = []( char c ) {
- return c == ' ' || c == ':' || c == '=';
- };
- size_t pos = 0;
- while (pos < sr.size()) {
- if (is_separator(sr[pos])) { return pos; }
- ++pos;
- }
-
- return Catch::StringRef::npos;
- }
-
-} // namespace
-
-namespace Catch {
- namespace Clara {
- namespace Detail {
-
- void TokenStream::loadBuffer() {
- m_tokenBuffer.clear();
-
- // Skip any empty strings
- while ( it != itEnd && it->empty() ) {
- ++it;
- }
-
- if ( it != itEnd ) {
- StringRef next = *it;
- if ( isOptPrefix( next[0] ) ) {
- auto delimiterPos = find_first_separator(next);
- if ( delimiterPos != StringRef::npos ) {
- m_tokenBuffer.push_back(
- { TokenType::Option,
- next.substr( 0, delimiterPos ) } );
- m_tokenBuffer.push_back(
- { TokenType::Argument,
- next.substr( delimiterPos + 1, next.size() ) } );
- } else {
- if ( next.size() > 1 && next[1] != '-' && next.size() > 2 ) {
- // Combined short args, e.g. "-ab" for "-a -b"
- for ( size_t i = 1; i < next.size(); ++i ) {
- m_tokenBuffer.push_back(
- { TokenType::Option,
- next.substr( i, 1 ) } );
- }
- } else {
- m_tokenBuffer.push_back(
- { TokenType::Option, next } );
- }
- }
- } else {
- m_tokenBuffer.push_back(
- { TokenType::Argument, next } );
- }
- }
- }
-
- TokenStream::TokenStream( Args const& args ):
- TokenStream( args.m_args.begin(), args.m_args.end() ) {}
-
- TokenStream::TokenStream( Iterator it_, Iterator itEnd_ ):
- it( it_ ), itEnd( itEnd_ ) {
- loadBuffer();
- }
-
- TokenStream& TokenStream::operator++() {
- if ( m_tokenBuffer.size() >= 2 ) {
- m_tokenBuffer.erase( m_tokenBuffer.begin() );
- } else {
- if ( it != itEnd )
- ++it;
- loadBuffer();
- }
- return *this;
- }
-
- ParserResult convertInto( std::string const& source,
- std::string& target ) {
- target = source;
- return ParserResult::ok( ParseResultType::Matched );
- }
-
- ParserResult convertInto( std::string const& source,
- bool& target ) {
- std::string srcLC = toLower( source );
-
- if ( srcLC == "y" || srcLC == "1" || srcLC == "true" ||
- srcLC == "yes" || srcLC == "on" ) {
- target = true;
- } else if ( srcLC == "n" || srcLC == "0" || srcLC == "false" ||
- srcLC == "no" || srcLC == "off" ) {
- target = false;
- } else {
- return ParserResult::runtimeError(
- "Expected a boolean value but did not recognise: '" +
- source + '\'' );
- }
- return ParserResult::ok( ParseResultType::Matched );
- }
-
- size_t ParserBase::cardinality() const { return 1; }
-
- InternalParseResult ParserBase::parse( Args const& args ) const {
- return parse( static_cast<std::string>(args.exeName()), TokenStream( args ) );
- }
-
- ParseState::ParseState( ParseResultType type,
- TokenStream remainingTokens ):
- m_type( type ), m_remainingTokens( CATCH_MOVE(remainingTokens) ) {}
-
- ParserResult BoundFlagRef::setFlag( bool flag ) {
- m_ref = flag;
- return ParserResult::ok( ParseResultType::Matched );
- }
-
- ResultBase::~ResultBase() = default;
-
- bool BoundRef::isContainer() const { return false; }
-
- bool BoundRef::isFlag() const { return false; }
-
- bool BoundFlagRefBase::isFlag() const { return true; }
-
-} // namespace Detail
-
- Detail::InternalParseResult Arg::parse(std::string const&,
- Detail::TokenStream tokens) const {
- auto validationResult = validate();
- if (!validationResult)
- return Detail::InternalParseResult(validationResult);
-
- auto token = *tokens;
- if (token.type != Detail::TokenType::Argument)
- return Detail::InternalParseResult::ok(Detail::ParseState(
- ParseResultType::NoMatch, CATCH_MOVE(tokens)));
-
- assert(!m_ref->isFlag());
- auto valueRef =
- static_cast<Detail::BoundValueRefBase*>(m_ref.get());
-
- auto result = valueRef->setValue(static_cast<std::string>(token.token));
- if ( !result )
- return Detail::InternalParseResult( result );
- else
- return Detail::InternalParseResult::ok(
- Detail::ParseState( ParseResultType::Matched,
- CATCH_MOVE( ++tokens ) ) );
- }
-
- Opt::Opt(bool& ref) :
- ParserRefImpl(std::make_shared<Detail::BoundFlagRef>(ref)) {}
-
- Detail::HelpColumns Opt::getHelpColumns() const {
- ReusableStringStream oss;
- bool first = true;
- for (auto const& opt : m_optNames) {
- if (first)
- first = false;
- else
- oss << ", ";
- oss << opt;
- }
- if (!m_hint.empty())
- oss << " <" << m_hint << '>';
- return { oss.str(), m_description };
- }
-
- bool Opt::isMatch(StringRef optToken) const {
- auto normalisedToken = normaliseOpt(optToken);
- for (auto const& name : m_optNames) {
- if (normaliseOpt(name) == normalisedToken)
- return true;
- }
- return false;
- }
-
- Detail::InternalParseResult Opt::parse(std::string const&,
- Detail::TokenStream tokens) const {
- auto validationResult = validate();
- if (!validationResult)
- return Detail::InternalParseResult(validationResult);
-
- if (tokens &&
- tokens->type == Detail::TokenType::Option) {
- auto const& token = *tokens;
- if (isMatch(token.token)) {
- if (m_ref->isFlag()) {
- auto flagRef =
- static_cast<Detail::BoundFlagRefBase*>(
- m_ref.get());
- auto result = flagRef->setFlag(true);
- if (!result)
- return Detail::InternalParseResult(result);
- if (result.value() ==
- ParseResultType::ShortCircuitAll)
- return Detail::InternalParseResult::ok(Detail::ParseState(
- result.value(), CATCH_MOVE(tokens)));
- } else {
- auto valueRef =
- static_cast<Detail::BoundValueRefBase*>(
- m_ref.get());
- ++tokens;
- if (!tokens)
- return Detail::InternalParseResult::runtimeError(
- "Expected argument following " +
- token.token);
- auto const& argToken = *tokens;
- if (argToken.type != Detail::TokenType::Argument)
- return Detail::InternalParseResult::runtimeError(
- "Expected argument following " +
- token.token);
- const auto result = valueRef->setValue(static_cast<std::string>(argToken.token));
- if (!result)
- return Detail::InternalParseResult(result);
- if (result.value() ==
- ParseResultType::ShortCircuitAll)
- return Detail::InternalParseResult::ok(Detail::ParseState(
- result.value(), CATCH_MOVE(tokens)));
- }
- return Detail::InternalParseResult::ok(Detail::ParseState(
- ParseResultType::Matched, CATCH_MOVE(++tokens)));
- }
- }
- return Detail::InternalParseResult::ok(
- Detail::ParseState(ParseResultType::NoMatch, CATCH_MOVE(tokens)));
- }
-
- Detail::Result Opt::validate() const {
- if (m_optNames.empty())
- return Detail::Result::logicError("No options supplied to Opt");
- for (auto const& name : m_optNames) {
- if (name.empty())
- return Detail::Result::logicError(
- "Option name cannot be empty");
-#ifdef CATCH_PLATFORM_WINDOWS
- if (name[0] != '-' && name[0] != '/')
- return Detail::Result::logicError(
- "Option name must begin with '-' or '/'");
-#else
- if (name[0] != '-')
- return Detail::Result::logicError(
- "Option name must begin with '-'");
-#endif
- }
- return ParserRefImpl::validate();
- }
-
- ExeName::ExeName() :
- m_name(std::make_shared<std::string>("<executable>")) {}
-
- ExeName::ExeName(std::string& ref) : ExeName() {
- m_ref = std::make_shared<Detail::BoundValueRef<std::string>>(ref);
- }
-
- Detail::InternalParseResult
- ExeName::parse(std::string const&,
- Detail::TokenStream tokens) const {
- return Detail::InternalParseResult::ok(
- Detail::ParseState(ParseResultType::NoMatch, CATCH_MOVE(tokens)));
- }
-
- ParserResult ExeName::set(std::string const& newName) {
- auto lastSlash = newName.find_last_of("\\/");
- auto filename = (lastSlash == std::string::npos)
- ? newName
- : newName.substr(lastSlash + 1);
-
- *m_name = filename;
- if (m_ref)
- return m_ref->setValue(filename);
- else
- return ParserResult::ok(ParseResultType::Matched);
- }
-
-
-
-
- Parser& Parser::operator|=( Parser const& other ) {
- m_options.insert( m_options.end(),
- other.m_options.begin(),
- other.m_options.end() );
- m_args.insert(
- m_args.end(), other.m_args.begin(), other.m_args.end() );
- return *this;
- }
-
- std::vector<Detail::HelpColumns> Parser::getHelpColumns() const {
- std::vector<Detail::HelpColumns> cols;
- cols.reserve( m_options.size() );
- for ( auto const& o : m_options ) {
- cols.push_back(o.getHelpColumns());
- }
- return cols;
- }
-
- void Parser::writeToStream( std::ostream& os ) const {
- if ( !m_exeName.name().empty() ) {
- os << "usage:\n"
- << " " << m_exeName.name() << ' ';
- bool required = true, first = true;
- for ( auto const& arg : m_args ) {
- if ( first )
- first = false;
- else
- os << ' ';
- if ( arg.isOptional() && required ) {
- os << '[';
- required = false;
- }
- os << '<' << arg.hint() << '>';
- if ( arg.cardinality() == 0 )
- os << " ... ";
- }
- if ( !required )
- os << ']';
- if ( !m_options.empty() )
- os << " options";
- os << "\n\nwhere options are:\n";
- }
-
- auto rows = getHelpColumns();
- size_t consoleWidth = CATCH_CONFIG_CONSOLE_WIDTH;
- size_t optWidth = 0;
- for ( auto const& cols : rows )
- optWidth = ( std::max )( optWidth, cols.left.size() + 2 );
-
- optWidth = ( std::min )( optWidth, consoleWidth / 2 );
-
- for ( auto& cols : rows ) {
- auto row = TextFlow::Column( CATCH_MOVE(cols.left) )
- .width( optWidth )
- .indent( 2 ) +
- TextFlow::Spacer( 4 ) +
- TextFlow::Column( static_cast<std::string>(cols.descriptions) )
- .width( consoleWidth - 7 - optWidth );
- os << row << '\n';
- }
- }
-
- Detail::Result Parser::validate() const {
- for ( auto const& opt : m_options ) {
- auto result = opt.validate();
- if ( !result )
- return result;
- }
- for ( auto const& arg : m_args ) {
- auto result = arg.validate();
- if ( !result )
- return result;
- }
- return Detail::Result::ok();
- }
-
- Detail::InternalParseResult
- Parser::parse( std::string const& exeName,
- Detail::TokenStream tokens ) const {
-
- struct ParserInfo {
- ParserBase const* parser = nullptr;
- size_t count = 0;
- };
- std::vector<ParserInfo> parseInfos;
- parseInfos.reserve( m_options.size() + m_args.size() );
- for ( auto const& opt : m_options ) {
- parseInfos.push_back( { &opt, 0 } );
- }
- for ( auto const& arg : m_args ) {
- parseInfos.push_back( { &arg, 0 } );
- }
-
- m_exeName.set( exeName );
-
- auto result = Detail::InternalParseResult::ok(
- Detail::ParseState( ParseResultType::NoMatch, CATCH_MOVE(tokens) ) );
- while ( result.value().remainingTokens() ) {
- bool tokenParsed = false;
-
- for ( auto& parseInfo : parseInfos ) {
- if ( parseInfo.parser->cardinality() == 0 ||
- parseInfo.count < parseInfo.parser->cardinality() ) {
- result = parseInfo.parser->parse(
- exeName, CATCH_MOVE(result).value().remainingTokens() );
- if ( !result )
- return result;
- if ( result.value().type() !=
- ParseResultType::NoMatch ) {
- tokenParsed = true;
- ++parseInfo.count;
- break;
- }
- }
- }
-
- if ( result.value().type() == ParseResultType::ShortCircuitAll )
- return result;
- if ( !tokenParsed )
- return Detail::InternalParseResult::runtimeError(
- "Unrecognised token: " +
- result.value().remainingTokens()->token );
- }
- // !TBD Check missing required options
- return result;
- }
-
- Args::Args(int argc, char const* const* argv) :
- m_exeName(argv[0]), m_args(argv + 1, argv + argc) {}
-
- Args::Args(std::initializer_list<StringRef> args) :
- m_exeName(*args.begin()),
- m_args(args.begin() + 1, args.end()) {}
-
-
- Help::Help( bool& showHelpFlag ):
- Opt( [&]( bool flag ) {
- showHelpFlag = flag;
- return ParserResult::ok( ParseResultType::ShortCircuitAll );
- } ) {
- static_cast<Opt&> ( *this )(
- "display usage information" )["-?"]["-h"]["--help"]
- .optional();
- }
-
- } // namespace Clara
-} // namespace Catch
diff --git a/src/catch2/internal/catch_clara.hpp b/src/catch2/internal/catch_clara.hpp
deleted file mode 100644
index ef297947..00000000
--- a/src/catch2/internal/catch_clara.hpp
+++ /dev/null
@@ -1,749 +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_CLARA_HPP_INCLUDED
-#define CATCH_CLARA_HPP_INCLUDED
-
-#if defined( __clang__ )
-# pragma clang diagnostic push
-# pragma clang diagnostic ignored "-Wweak-vtables"
-# pragma clang diagnostic ignored "-Wshadow"
-# pragma clang diagnostic ignored "-Wdeprecated"
-#endif
-
-#if defined( __GNUC__ )
-# pragma GCC diagnostic push
-# pragma GCC diagnostic ignored "-Wsign-conversion"
-#endif
-
-#ifndef CLARA_CONFIG_OPTIONAL_TYPE
-# ifdef __has_include
-# if __has_include( <optional>) && __cplusplus >= 201703L
-# include <optional>
-# define CLARA_CONFIG_OPTIONAL_TYPE std::optional
-# endif
-# endif
-#endif
-
-#include <catch2/internal/catch_stringref.hpp>
-#include <catch2/internal/catch_move_and_forward.hpp>
-#include <catch2/internal/catch_noncopyable.hpp>
-#include <catch2/internal/catch_void_type.hpp>
-
-#include <cassert>
-#include <memory>
-#include <ostream>
-#include <sstream>
-#include <string>
-#include <type_traits>
-#include <vector>
-
-namespace Catch {
- namespace Clara {
-
- class Args;
- class Parser;
-
- // enum of result types from a parse
- enum class ParseResultType {
- Matched,
- NoMatch,
- ShortCircuitAll,
- ShortCircuitSame
- };
-
- struct accept_many_t {};
- constexpr accept_many_t accept_many {};
-
- namespace Detail {
- struct fake_arg {
- template <typename T>
- operator T();
- };
-
- template <typename F, typename = void>
- static constexpr bool is_unary_function_v = false;
-
- template <typename F>
- static constexpr bool is_unary_function_v<
- F,
- Catch::Detail::void_t<decltype( std::declval<F>()(
- fake_arg() ) )>> = true;
-
- // Traits for extracting arg and return type of lambdas (for single
- // argument lambdas)
- template <typename L>
- struct UnaryLambdaTraits
- : UnaryLambdaTraits<decltype( &L::operator() )> {};
-
- template <typename ClassT, typename ReturnT, typename... Args>
- struct UnaryLambdaTraits<ReturnT ( ClassT::* )( Args... ) const> {
- static const bool isValid = false;
- };
-
- template <typename ClassT, typename ReturnT, typename ArgT>
- struct UnaryLambdaTraits<ReturnT ( ClassT::* )( ArgT ) const> {
- static const bool isValid = true;
- using ArgType = std::remove_const_t<std::remove_reference_t<ArgT>>;
- using ReturnType = ReturnT;
- };
-
- class TokenStream;
-
- // Wraps a token coming from a token stream. These may not directly
- // correspond to strings as a single string may encode an option +
- // its argument if the : or = form is used
- enum class TokenType { Option, Argument };
- struct Token {
- TokenType type;
- StringRef token;
- };
-
- // Abstracts iterators into args as a stream of tokens, with option
- // arguments uniformly handled
- class TokenStream {
- using Iterator = std::vector<StringRef>::const_iterator;
- Iterator it;
- Iterator itEnd;
- std::vector<Token> m_tokenBuffer;
- void loadBuffer();
-
- public:
- explicit TokenStream( Args const& args );
- TokenStream( Iterator it, Iterator itEnd );
-
- explicit operator bool() const {
- return !m_tokenBuffer.empty() || it != itEnd;
- }
-
- size_t count() const {
- return m_tokenBuffer.size() + ( itEnd - it );
- }
-
- Token operator*() const {
- assert( !m_tokenBuffer.empty() );
- return m_tokenBuffer.front();
- }
-
- Token const* operator->() const {
- assert( !m_tokenBuffer.empty() );
- return &m_tokenBuffer.front();
- }
-
- TokenStream& operator++();
- };
-
- //! Denotes type of a parsing result
- enum class ResultType {
- Ok, ///< No errors
- LogicError, ///< Error in user-specified arguments for
- ///< construction
- RuntimeError ///< Error in parsing inputs
- };
-
- class ResultBase {
- protected:
- ResultBase( ResultType type ): m_type( type ) {}
- virtual ~ResultBase(); // = default;
-
-
- ResultBase(ResultBase const&) = default;
- ResultBase& operator=(ResultBase const&) = default;
- ResultBase(ResultBase&&) = default;
- ResultBase& operator=(ResultBase&&) = default;
-
- virtual void enforceOk() const = 0;
-
- ResultType m_type;
- };
-
- template <typename T>
- class ResultValueBase : public ResultBase {
- public:
- T const& value() const& {
- enforceOk();
- return m_value;
- }
- T&& value() && {
- enforceOk();
- return CATCH_MOVE( m_value );
- }
-
- protected:
- ResultValueBase( ResultType type ): ResultBase( type ) {}
-
- ResultValueBase( ResultValueBase const& other ):
- ResultBase( other ) {
- if ( m_type == ResultType::Ok )
- new ( &m_value ) T( other.m_value );
- }
- ResultValueBase( ResultValueBase&& other ):
- ResultBase( other ) {
- if ( m_type == ResultType::Ok )
- new ( &m_value ) T( CATCH_MOVE(other.m_value) );
- }
-
-
- ResultValueBase( ResultType, T const& value ):
- ResultBase( ResultType::Ok ) {
- new ( &m_value ) T( value );
- }
- ResultValueBase( ResultType, T&& value ):
-