1
0
mirror of https://github.com/catchorg/Catch2.git synced 2025-01-16 07:08:01 +00:00

Compare commits

...

3 Commits

Author SHA1 Message Date
Martin Hořeňovský
f2b9508081
Remove last vestiges of shared ptr use with IConfig 2020-05-31 15:25:14 +02:00
Martin Hořeňovský
1d1ccf8f3c
Replace all uses of std::unique_ptr with Catch::Detail::unique_ptr
Doing some benchmarking with ClangBuildAnalyzer suggests that
compiling Catch2's `SelfTest` spends 10% of the time instantiating
`std::unique_ptr` for some interface types required for registering
and running tests.

The lesser compilation overhead of `Catch::Detail::unique_ptr` should
significantly reduce that time.

The compiled implementation was also changed to use the custom impl,
to avoid having to convert between using `std::unique_ptr` and
`Catch::Detail::unique_ptr`. This will likely also improve the compile
times of the implementation, but that is less important than improving
compilation times of the user's TUs with tests.
2020-05-31 15:20:24 +02:00
Martin Hořeňovský
41bbaa6d57
Implement a simplified variant of std::unique_ptr<T>
This simplified variant supports only a subset of the functionality
in `std::unique_ptr<T>`. `Catch::Detail::unique_ptr<T>` only supports
single element pointer (no array support) with default deleter.

By removing the support for custom deleters, we also avoid requiring
significant machinery to support EBO, speeding up instantiations of
`unique_ptr<T>` significantly. Catch2 also currently does not need
to support `unique_ptr<T[]>`, so that is not supported either.
2020-05-31 15:08:47 +02:00
54 changed files with 1031 additions and 140 deletions

View File

@ -43,7 +43,9 @@ int const& RandomIntGenerator::get() const {
// is a value-wrapper around std::unique_ptr<IGenerator<int>>.
Catch::Generators::GeneratorWrapper<int> random(int low, int high) {
return Catch::Generators::GeneratorWrapper<int>(
std::make_unique<RandomIntGenerator>(low, high)
new RandomIntGenerator(low, high)
// Another possibility:
// Catch::Detail::make_unique<RandomIntGenerator>(low, high)
);
}
@ -58,7 +60,7 @@ TEST_CASE("Generating random ints", "[example][generator]") {
REQUIRE(i <= 100);
}
SECTION("Creating the random generator directly") {
auto i = GENERATE(take(100, GeneratorWrapper<int>(std::unique_ptr<IGenerator<int>>(new RandomIntGenerator(-100, 100)))));
auto i = GENERATE(take(100, GeneratorWrapper<int>(Catch::Detail::make_unique<RandomIntGenerator>(-100, 100))));
REQUIRE(i >= -100);
REQUIRE(i <= 100);
}

View File

@ -40,7 +40,7 @@ std::string const& LineGenerator::get() const {
// is a value-wrapper around std::unique_ptr<IGenerator<std::string>>.
Catch::Generators::GeneratorWrapper<std::string> lines(std::string /* ignored for example */) {
return Catch::Generators::GeneratorWrapper<std::string>(
std::make_unique<LineGenerator>()
new LineGenerator()
);
}

View File

@ -125,6 +125,7 @@ set(INTERNAL_HEADERS
${SOURCES_DIR}/catch_totals.hpp
${SOURCES_DIR}/catch_translate_exception.hpp
${SOURCES_DIR}/internal/catch_uncaught_exceptions.hpp
${SOURCES_DIR}/internal/catch_unique_ptr.hpp
${SOURCES_DIR}/catch_version.hpp
${SOURCES_DIR}/catch_version_macros.hpp
${SOURCES_DIR}/internal/catch_wildcard_pattern.hpp

View File

@ -14,11 +14,11 @@
#include <catch2/benchmark/catch_chronometer.hpp>
#include <catch2/benchmark/detail/catch_complete_invoke.hpp>
#include <catch2/internal/catch_meta.hpp>
#include <catch2/internal/catch_unique_ptr.hpp>
#include <cassert>
#include <type_traits>
#include <utility>
#include <memory>
namespace Catch {
namespace Benchmark {
@ -100,7 +100,7 @@ namespace Catch {
void operator()(Chronometer meter) const { f->call(meter); }
private:
std::unique_ptr<callable> f;
Catch::Detail::unique_ptr<callable> f;
};
} // namespace Detail
} // namespace Benchmark

View File

@ -85,6 +85,7 @@
#include <catch2/internal/catch_text.hpp>
#include <catch2/internal/catch_to_string.hpp>
#include <catch2/internal/catch_uncaught_exceptions.hpp>
#include <catch2/internal/catch_unique_ptr.hpp>
#include <catch2/internal/catch_wildcard_pattern.hpp>
#include <catch2/internal/catch_windows_h_proxy.hpp>
#include <catch2/internal/catch_xmlwriter.hpp>

View File

@ -10,8 +10,8 @@
#include <catch2/catch_test_spec.hpp>
#include <catch2/interfaces/catch_interfaces_config.hpp>
#include <catch2/internal/catch_unique_ptr.hpp>
#include <memory>
#include <vector>
#include <string>
@ -116,7 +116,7 @@ namespace Catch {
IStream const* openStream();
ConfigData m_data;
std::unique_ptr<IStream const> m_stream;
Detail::unique_ptr<IStream const> m_stream;
TestSpec m_testSpec;
bool m_hasTestFilters = false;
};

View File

@ -49,7 +49,7 @@ namespace Catch {
void registerListener( IReporterFactoryPtr factory ) override {
m_reporterRegistry.registerListener( std::move(factory) );
}
void registerTest( std::unique_ptr<TestCaseInfo>&& testInfo, std::unique_ptr<ITestInvoker>&& invoker ) override {
void registerTest( Detail::unique_ptr<TestCaseInfo>&& testInfo, Detail::unique_ptr<ITestInvoker>&& invoker ) override {
m_testCaseRegistry.registerTest( std::move(testInfo), std::move(invoker) );
}
void registerTranslator( const IExceptionTranslator* translator ) override {

View File

@ -10,6 +10,7 @@
#define TWOBLUECUBES_CATCH_REPORTER_REGISTRARS_HPP_INCLUDED
#include <catch2/interfaces/catch_interfaces_registry_hub.hpp>
#include <catch2/internal/catch_unique_ptr.hpp>
namespace Catch {
@ -17,7 +18,7 @@ namespace Catch {
class ReporterFactory : public IReporterFactory {
IStreamingReporterPtr create( ReporterConfig const& config ) const override {
return std::make_unique<T>( config );
return Detail::make_unique<T>( config );
}
std::string getDescription() const override {
@ -30,7 +31,7 @@ namespace Catch {
class ReporterRegistrar {
public:
explicit ReporterRegistrar( std::string const& name ) {
getMutableRegistryHub().registerReporter( name, std::make_unique<ReporterFactory<T>>() );
getMutableRegistryHub().registerReporter( name, Detail::make_unique<ReporterFactory<T>>() );
}
};
@ -40,7 +41,7 @@ namespace Catch {
class ListenerFactory : public IReporterFactory {
IStreamingReporterPtr create( ReporterConfig const& config ) const override {
return std::make_unique<T>(config);
return Detail::make_unique<T>(config);
}
std::string getDescription() const override {
return std::string();
@ -50,7 +51,7 @@ namespace Catch {
public:
ListenerRegistrar() {
getMutableRegistryHub().registerListener( std::make_unique<ListenerFactory>() );
getMutableRegistryHub().registerListener( Detail::make_unique<ListenerFactory>() );
}
};
}

View File

@ -44,12 +44,12 @@ namespace Catch {
return createReporter(config->getReporterName(), config);
}
// On older platforms, returning std::unique_ptr<ListeningReporter>
// when the return type is std::unique_ptr<IStreamingReporter>
// On older platforms, returning unique_ptr<ListeningReporter>
// when the return type is unique_ptr<IStreamingReporter>
// doesn't compile without a std::move call. However, this causes
// a warning on newer platforms. Thus, we have to work around
// it a bit and downcast the pointer manually.
auto ret = std::unique_ptr<IStreamingReporter>(new ListeningReporter);
auto ret = Detail::unique_ptr<IStreamingReporter>(new ListeningReporter);
auto& multi = static_cast<ListeningReporter&>(*ret);
auto const& listeners = Catch::getRegistryHub().getReporterRegistry().getListeners();
for (auto const& listener : listeners) {
@ -252,7 +252,7 @@ namespace Catch {
}
Config& Session::config() {
if( !m_config )
m_config = std::make_unique<Config>( m_configData );
m_config = Detail::make_unique<Config>( m_configData );
return *m_config;
}

View File

@ -11,8 +11,7 @@
#include <catch2/internal/catch_commandline.hpp>
#include <catch2/catch_config.hpp>
#include <catch2/internal/catch_text.hpp>
#include <memory>
#include <catch2/internal/catch_unique_ptr.hpp>
namespace Catch {
@ -53,7 +52,7 @@ namespace Catch {
clara::Parser m_cli;
ConfigData m_configData;
std::unique_ptr<Config> m_config;
Detail::unique_ptr<Config> m_config;
bool m_startupExceptions = false;
};

View File

@ -105,11 +105,11 @@ namespace Catch {
}
}
std::unique_ptr<TestCaseInfo>
Detail::unique_ptr<TestCaseInfo>
makeTestCaseInfo(std::string const& _className,
NameAndTags const& nameAndTags,
SourceLineInfo const& _lineInfo ) {
return std::make_unique<TestCaseInfo>(_className, nameAndTags, _lineInfo);
return Detail::unique_ptr<TestCaseInfo>(new TestCaseInfo(_className, nameAndTags, _lineInfo));
}
TestCaseInfo::TestCaseInfo(std::string const& _className,

View File

@ -11,10 +11,11 @@
#include <catch2/internal/catch_common.hpp>
#include <catch2/internal/catch_stringref.hpp>
#include <catch2/internal/catch_test_registry.hpp>
#include <catch2/internal/catch_unique_ptr.hpp>
#include <string>
#include <vector>
#include <memory>
#ifdef __clang__
#pragma clang diagnostic push
@ -90,7 +91,7 @@ namespace Catch {
bool operator < ( TestCaseHandle const& rhs ) const;
};
std::unique_ptr<TestCaseInfo> makeTestCaseInfo( std::string const& className,
Detail::unique_ptr<TestCaseInfo> makeTestCaseInfo( std::string const& className,
NameAndTags const& nameAndTags,
SourceLineInfo const& lineInfo );
}

View File

@ -13,7 +13,6 @@
#include <algorithm>
#include <string>
#include <vector>
#include <memory>
namespace Catch {

View File

@ -13,11 +13,11 @@
#pragma clang diagnostic ignored "-Wpadded"
#endif
#include <catch2/internal/catch_unique_ptr.hpp>
#include <catch2/internal/catch_wildcard_pattern.hpp>
#include <string>
#include <vector>
#include <memory>
namespace Catch {
@ -54,8 +54,8 @@ namespace Catch {
};
struct Filter {
std::vector<std::unique_ptr<Pattern>> m_required;
std::vector<std::unique_ptr<Pattern>> m_forbidden;
std::vector<Detail::unique_ptr<Pattern>> m_required;
std::vector<Detail::unique_ptr<Pattern>> m_forbidden;
bool matches( TestCaseInfo const& testCase ) const;
std::string name() const;

View File

@ -10,7 +10,6 @@
#include <catch2/interfaces/catch_interfaces_generatortracker.hpp>
#include <catch2/internal/catch_common.hpp>
#include <memory>
#include <vector>
#include <tuple>
#include <utility>
@ -43,11 +42,35 @@ namespace Detail {
using type = T;
};
template <typename T>
using GeneratorPtr = Catch::Detail::unique_ptr<IGenerator<T>>;
template <typename T>
class GeneratorWrapper final {
GeneratorPtr<T> m_generator;
public:
//! Takes ownership of the passed pointer.
GeneratorWrapper(IGenerator<T>* generator):
m_generator(generator) {}
GeneratorWrapper(GeneratorPtr<T> generator):
m_generator(std::move(generator)) {}
T const& get() const {
return m_generator->get();
}
bool next() {
return m_generator->next();
}
};
template<typename T>
class SingleValueGenerator final : public IGenerator<T> {
T m_value;
public:
SingleValueGenerator(T&& value) : m_value(std::move(value)) {}
SingleValueGenerator(T&& value):
m_value(std::forward<T>(value))
{}
T const& get() const override {
return m_value;
@ -76,28 +99,13 @@ namespace Detail {
}
};
template <typename T>
class GeneratorWrapper final {
std::unique_ptr<IGenerator<T>> m_generator;
public:
GeneratorWrapper(std::unique_ptr<IGenerator<T>> generator):
m_generator(std::move(generator))
{}
T const& get() const {
return m_generator->get();
}
bool next() {
return m_generator->next();
}
};
template <typename T>
GeneratorWrapper<T> value(T&& value) {
return GeneratorWrapper<T>(std::make_unique<SingleValueGenerator<T>>(std::forward<T>(value)));
return GeneratorWrapper<T>(Catch::Detail::make_unique<SingleValueGenerator<T>>(std::forward<T>(value)));
}
template <typename T>
GeneratorWrapper<T> values(std::initializer_list<T> values) {
return GeneratorWrapper<T>(std::make_unique<FixedValuesGenerator<T>>(values));
return GeneratorWrapper<T>(Catch::Detail::make_unique<FixedValuesGenerator<T>>(values));
}
template<typename T>
@ -182,7 +190,7 @@ namespace Detail {
IGeneratorTracker& tracker = acquireGeneratorTracker( lineInfo );
if (!tracker.hasGenerator()) {
tracker.setGenerator(std::make_unique<Generators<UnderlyingType>>(generatorExpression()));
tracker.setGenerator(Catch::Detail::make_unique<Generators<UnderlyingType>>(generatorExpression()));
}
auto const& generator = static_cast<IGenerator<UnderlyingType> const&>( *tracker.getGenerator() );

View File

@ -46,7 +46,7 @@ namespace Generators {
template <typename T>
GeneratorWrapper<T> take(size_t target, GeneratorWrapper<T>&& generator) {
return GeneratorWrapper<T>(std::make_unique<TakeGenerator<T>>(target, std::move(generator)));
return GeneratorWrapper<T>(Catch::Detail::make_unique<TakeGenerator<T>>(target, std::move(generator)));
}
@ -87,7 +87,7 @@ namespace Generators {
template <typename T, typename Predicate>
GeneratorWrapper<T> filter(Predicate&& pred, GeneratorWrapper<T>&& generator) {
return GeneratorWrapper<T>(std::unique_ptr<IGenerator<T>>(std::make_unique<FilterGenerator<T, Predicate>>(std::forward<Predicate>(pred), std::move(generator))));
return GeneratorWrapper<T>(Catch::Detail::make_unique<FilterGenerator<T, Predicate>>(std::forward<Predicate>(pred), std::move(generator)));
}
template <typename T>
@ -143,7 +143,7 @@ namespace Generators {
template <typename T>
GeneratorWrapper<T> repeat(size_t repeats, GeneratorWrapper<T>&& generator) {
return GeneratorWrapper<T>(std::make_unique<RepeatGenerator<T>>(repeats, std::move(generator)));
return GeneratorWrapper<T>(Catch::Detail::make_unique<RepeatGenerator<T>>(repeats, std::move(generator)));
}
template <typename T, typename U, typename Func>
@ -176,14 +176,14 @@ namespace Generators {
template <typename Func, typename U, typename T = FunctionReturnType<Func, U>>
GeneratorWrapper<T> map(Func&& function, GeneratorWrapper<U>&& generator) {
return GeneratorWrapper<T>(
std::make_unique<MapGenerator<T, U, Func>>(std::forward<Func>(function), std::move(generator))
Catch::Detail::make_unique<MapGenerator<T, U, Func>>(std::forward<Func>(function), std::move(generator))
);
}
template <typename T, typename U, typename Func>
GeneratorWrapper<T> map(Func&& function, GeneratorWrapper<U>&& generator) {
return GeneratorWrapper<T>(
std::make_unique<MapGenerator<T, U, Func>>(std::forward<Func>(function), std::move(generator))
Catch::Detail::make_unique<MapGenerator<T, U, Func>>(std::forward<Func>(function), std::move(generator))
);
}
@ -226,7 +226,7 @@ namespace Generators {
template <typename T>
GeneratorWrapper<std::vector<T>> chunk(size_t size, GeneratorWrapper<T>&& generator) {
return GeneratorWrapper<std::vector<T>>(
std::make_unique<ChunkGenerator<T>>(size, std::move(generator))
Catch::Detail::make_unique<ChunkGenerator<T>>(size, std::move(generator))
);
}

View File

@ -67,7 +67,7 @@ std::enable_if_t<std::is_integral<T>::value && !std::is_same<T, bool>::value,
GeneratorWrapper<T>>
random(T a, T b) {
return GeneratorWrapper<T>(
std::make_unique<RandomIntegerGenerator<T>>(a, b)
Catch::Detail::make_unique<RandomIntegerGenerator<T>>(a, b)
);
}
@ -76,7 +76,7 @@ std::enable_if_t<std::is_floating_point<T>::value,
GeneratorWrapper<T>>
random(T a, T b) {
return GeneratorWrapper<T>(
std::make_unique<RandomFloatingGenerator<T>>(a, b)
Catch::Detail::make_unique<RandomFloatingGenerator<T>>(a, b)
);
}

View File

@ -52,13 +52,13 @@ public:
template <typename T>
GeneratorWrapper<T> range(T const& start, T const& end, T const& step) {
static_assert(std::is_arithmetic<T>::value && !std::is_same<T, bool>::value, "Type must be numeric");
return GeneratorWrapper<T>(std::make_unique<RangeGenerator<T>>(start, end, step));
return GeneratorWrapper<T>(Catch::Detail::make_unique<RangeGenerator<T>>(start, end, step));
}
template <typename T>
GeneratorWrapper<T> range(T const& start, T const& end) {
static_assert(std::is_integral<T>::value && !std::is_same<T, bool>::value, "Type must be an integer");
return GeneratorWrapper<T>(std::make_unique<RangeGenerator<T>>(start, end));
return GeneratorWrapper<T>(Catch::Detail::make_unique<RangeGenerator<T>>(start, end));
}
@ -92,13 +92,13 @@ template <typename InputIterator,
typename InputSentinel,
typename ResultType = typename std::iterator_traits<InputIterator>::value_type>
GeneratorWrapper<ResultType> from_range(InputIterator from, InputSentinel to) {
return GeneratorWrapper<ResultType>(std::make_unique<IteratorGenerator<ResultType>>(from, to));
return GeneratorWrapper<ResultType>(Catch::Detail::make_unique<IteratorGenerator<ResultType>>(from, to));
}
template <typename Container,
typename ResultType = typename Container::value_type>
GeneratorWrapper<ResultType> from_range(Container const& cnt) {
return GeneratorWrapper<ResultType>(std::make_unique<IteratorGenerator<ResultType>>(cnt.begin(), cnt.end()));
return GeneratorWrapper<ResultType>(Catch::Detail::make_unique<IteratorGenerator<ResultType>>(cnt.begin(), cnt.end()));
}

View File

@ -14,7 +14,6 @@
#include <iosfwd>
#include <string>
#include <vector>
#include <memory>
namespace Catch {
@ -83,8 +82,6 @@ namespace Catch {
virtual unsigned int benchmarkResamples() const = 0;
virtual std::chrono::milliseconds benchmarkWarmupTime() const = 0;
};
using IConfigPtr = std::shared_ptr<IConfig const>;
}
#endif // TWOBLUECUBES_CATCH_INTERFACES_CONFIG_H_INCLUDED

View File

@ -10,6 +10,7 @@
#include <catch2/interfaces/catch_interfaces_registry_hub.hpp>
#include <catch2/internal/catch_compiler_capabilities.hpp>
#include <catch2/internal/catch_unique_ptr.hpp>
#include <string>
#include <vector>
@ -18,7 +19,7 @@ namespace Catch {
using exceptionTranslateFunction = std::string(*)();
struct IExceptionTranslator;
using ExceptionTranslators = std::vector<std::unique_ptr<IExceptionTranslator const>>;
using ExceptionTranslators = std::vector<Detail::unique_ptr<IExceptionTranslator const>>;
struct IExceptionTranslator {
virtual ~IExceptionTranslator();

View File

@ -8,7 +8,7 @@
#ifndef TWOBLUECUBES_CATCH_INTERFACES_GENERATORTRACKER_INCLUDED
#define TWOBLUECUBES_CATCH_INTERFACES_GENERATORTRACKER_INCLUDED
#include <memory>
#include <catch2/internal/catch_unique_ptr.hpp>
namespace Catch {
@ -29,7 +29,7 @@ namespace Catch {
// can be retrieved).
virtual bool next() = 0;
};
using GeneratorBasePtr = std::unique_ptr<GeneratorUntypedBase>;
using GeneratorBasePtr = Catch::Detail::unique_ptr<GeneratorUntypedBase>;
} // namespace Generators

View File

@ -9,9 +9,9 @@
#define TWOBLUECUBES_CATCH_INTERFACES_REGISTRY_HUB_H_INCLUDED
#include <catch2/internal/catch_common.hpp>
#include <catch2/internal/catch_unique_ptr.hpp>
#include <string>
#include <memory>
namespace Catch {
@ -28,7 +28,7 @@ namespace Catch {
class StartupExceptionRegistry;
using IReporterFactoryPtr = std::unique_ptr<IReporterFactory>;
using IReporterFactoryPtr = Detail::unique_ptr<IReporterFactory>;
struct IRegistryHub {
virtual ~IRegistryHub();
@ -46,7 +46,7 @@ namespace Catch {
virtual ~IMutableRegistryHub();
virtual void registerReporter( std::string const& name, IReporterFactoryPtr factory ) = 0;
virtual void registerListener( IReporterFactoryPtr factory ) = 0;
virtual void registerTest(std::unique_ptr<TestCaseInfo>&& testInfo, std::unique_ptr<ITestInvoker>&& invoker) = 0;
virtual void registerTest(Detail::unique_ptr<TestCaseInfo>&& testInfo, Detail::unique_ptr<ITestInvoker>&& invoker) = 0;
virtual void registerTranslator( const IExceptionTranslator* translator ) = 0;
virtual void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) = 0;
virtual void registerStartupException() noexcept = 0;

View File

@ -17,6 +17,7 @@
#include <catch2/internal/catch_message_info.hpp>
#include <catch2/internal/catch_option.hpp>
#include <catch2/internal/catch_stringref.hpp>
#include <catch2/internal/catch_unique_ptr.hpp>
#include <catch2/benchmark/catch_estimate.hpp>
#include <catch2/benchmark/catch_outlier_classification.hpp>
@ -25,7 +26,6 @@
#include <string>
#include <iosfwd>
#include <map>
#include <memory>
#include <algorithm>
namespace Catch {
@ -222,14 +222,14 @@ namespace Catch {
virtual void listTags(std::vector<TagInfo> const& tags, Config const& config);
};
using IStreamingReporterPtr = std::unique_ptr<IStreamingReporter>;
using IStreamingReporterPtr = Detail::unique_ptr<IStreamingReporter>;
struct IReporterFactory {
virtual ~IReporterFactory();
virtual IStreamingReporterPtr create( ReporterConfig const& config ) const = 0;
virtual std::string getDescription() const = 0;
};
using IReporterFactoryPtr = std::unique_ptr<IReporterFactory>;
using IReporterFactoryPtr = Detail::unique_ptr<IReporterFactory>;
struct IReporterRegistry {
using FactoryMap = std::map<std::string, IReporterFactoryPtr>;

View File

@ -9,7 +9,6 @@
#define TWOBLUECUBES_CATCH_INTERFACES_TESTCASE_H_INCLUDED
#include <vector>
#include <memory>
namespace Catch {
@ -26,7 +25,8 @@ namespace Catch {
struct ITestCaseRegistry {
virtual ~ITestCaseRegistry();
virtual std::vector<std::unique_ptr<TestCaseInfo>> const& getAllInfos() const = 0;
// TODO: this exists only for adding filenames to test cases -- let's expose this in a saner way later
virtual std::vector<TestCaseInfo* > const& getAllInfos() const = 0;
virtual std::vector<TestCaseHandle> const& getAllTests() const = 0;
virtual std::vector<TestCaseHandle> const& getAllTestsSorted( IConfig const& config ) const = 0;
};

View File

@ -8,8 +8,6 @@
#ifndef TWOBLUECUBES_CATCH_CONTEXT_H_INCLUDED
#define TWOBLUECUBES_CATCH_CONTEXT_H_INCLUDED
#include <memory>
namespace Catch {
struct IResultCapture;
@ -17,8 +15,6 @@ namespace Catch {
struct IConfig;
struct IMutableContext;
using IConfigPtr = std::shared_ptr<IConfig const>;
struct IContext
{
virtual ~IContext();

View File

@ -51,8 +51,8 @@ namespace Catch {
return "{** unexpected enum value **}"_sr;
}
std::unique_ptr<EnumInfo> makeEnumInfo( StringRef enumName, StringRef allValueNames, std::vector<int> const& values ) {
auto enumInfo = std::make_unique<EnumInfo>();
Catch::Detail::unique_ptr<EnumInfo> makeEnumInfo( StringRef enumName, StringRef allValueNames, std::vector<int> const& values ) {
auto enumInfo = Catch::Detail::make_unique<EnumInfo>();
enumInfo->m_name = enumName;
enumInfo->m_values.reserve( values.size() );

View File

@ -9,19 +9,19 @@
#define TWOBLUECUBES_CATCH_ENUMVALUESREGISTRY_H_INCLUDED
#include <catch2/interfaces/catch_interfaces_enum_values_registry.hpp>
#include <catch2/internal/catch_unique_ptr.hpp>
#include <vector>
#include <memory>
namespace Catch {
namespace Detail {
std::unique_ptr<EnumInfo> makeEnumInfo( StringRef enumName, StringRef allValueNames, std::vector<int> const& values );
Catch::Detail::unique_ptr<EnumInfo> makeEnumInfo( StringRef enumName, StringRef allValueNames, std::vector<int> const& values );
class EnumValuesRegistry : public IMutableEnumValuesRegistry {
std::vector<std::unique_ptr<EnumInfo>> m_enumInfos;
std::vector<Catch::Detail::unique_ptr<EnumInfo>> m_enumInfos;
EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::vector<int> const& values) override;
};

View File

@ -17,7 +17,7 @@ namespace Catch {
}
void ExceptionTranslatorRegistry::registerTranslator( const IExceptionTranslator* translator ) {
m_translators.push_back( std::unique_ptr<const IExceptionTranslator>( translator ) );
m_translators.push_back( Detail::unique_ptr<const IExceptionTranslator>( translator ) );
}
#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)

View File

@ -11,7 +11,6 @@
#include <catch2/interfaces/catch_interfaces_exception.hpp>
#include <vector>
#include <string>
#include <memory>
namespace Catch {
@ -23,7 +22,7 @@ namespace Catch {
std::string tryTranslators() const;
private:
std::vector<std::unique_ptr<IExceptionTranslator const>> m_translators;
ExceptionTranslators m_translators;
};
}

View File

@ -21,14 +21,14 @@ namespace Catch {
ReporterRegistry::ReporterRegistry() {
// Because it is impossible to move out of initializer list,
// we have to add the elements manually
m_factories["automake"] = std::make_unique<ReporterFactory<AutomakeReporter>>();
m_factories["compact"] = std::make_unique<ReporterFactory<CompactReporter>>();
m_factories["console"] = std::make_unique<ReporterFactory<ConsoleReporter>>();
m_factories["junit"] = std::make_unique<ReporterFactory<JunitReporter>>();
m_factories["sonarqube"] = std::make_unique<ReporterFactory<SonarQubeReporter>>();
m_factories["tap"] = std::make_unique<ReporterFactory<TAPReporter>>();
m_factories["teamcity"] = std::make_unique<ReporterFactory<TeamCityReporter>>();
m_factories["xml"] = std::make_unique<ReporterFactory<XmlReporter>>();
m_factories["automake"] = Detail::make_unique<ReporterFactory<AutomakeReporter>>();
m_factories["compact"] = Detail::make_unique<ReporterFactory<CompactReporter>>();
m_factories["console"] = Detail::make_unique<ReporterFactory<ConsoleReporter>>();
m_factories["junit"] = Detail::make_unique<ReporterFactory<JunitReporter>>();
m_factories["sonarqube"] = Detail::make_unique<ReporterFactory<SonarQubeReporter>>();
m_factories["tap"] = Detail::make_unique<ReporterFactory<TAPReporter>>();
m_factories["teamcity"] = Detail::make_unique<ReporterFactory<TeamCityReporter>>();
m_factories["xml"] = Detail::make_unique<ReporterFactory<XmlReporter>>();
}
ReporterRegistry::~ReporterRegistry() = default;

View File

@ -13,19 +13,20 @@
#include <catch2/internal/catch_debug_console.hpp>
#include <catch2/internal/catch_stringref.hpp>
#include <catch2/internal/catch_singletons.hpp>
#include <catch2/internal/catch_unique_ptr.hpp>
#include <cstdio>
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <memory>
namespace Catch {
Catch::IStream::~IStream() = default;
namespace Detail { namespace {
namespace Detail {
namespace {
template<typename WriterF, std::size_t bufferSize=256>
class StreamBufImpl : public std::streambuf {
char data[bufferSize];
@ -104,11 +105,11 @@ namespace Catch {
///////////////////////////////////////////////////////////////////////////
class DebugOutStream : public IStream {
std::unique_ptr<StreamBufImpl<OutputDebugWriter>> m_streamBuf;
Detail::unique_ptr<StreamBufImpl<OutputDebugWriter>> m_streamBuf;
mutable std::ostream m_os;
public:
DebugOutStream()
: m_streamBuf( std::make_unique<StreamBufImpl<OutputDebugWriter>>() ),
: m_streamBuf( Detail::make_unique<StreamBufImpl<OutputDebugWriter>>() ),
m_os( m_streamBuf.get() )
{}
@ -118,7 +119,8 @@ namespace Catch {
std::ostream& stream() const override { return m_os; }
};
}} // namespace anon::detail
} // unnamed namespace
} // namespace Detail
///////////////////////////////////////////////////////////////////////////
@ -138,13 +140,13 @@ namespace Catch {
// This class encapsulates the idea of a pool of ostringstreams that can be reused.
struct StringStreams {
std::vector<std::unique_ptr<std::ostringstream>> m_streams;
std::vector<Detail::unique_ptr<std::ostringstream>> m_streams;
std::vector<std::size_t> m_unused;
std::ostringstream m_referenceStream; // Used for copy state/ flags from
auto add() -> std::size_t {
if( m_unused.empty() ) {
m_streams.push_back( std::unique_ptr<std::ostringstream>( new std::ostringstream ) );
m_streams.push_back( Detail::unique_ptr<std::ostringstream>( new std::ostringstream ) );
return m_streams.size()-1;
}
else {

View File

@ -10,8 +10,6 @@
#include <catch2/internal/catch_preprocessor.hpp>
#include <catch2/internal/catch_meta.hpp>
#include <memory>
// GCC 5 and older do not properly handle disabling unused-variable warning
// with a _Pragma. This means that we have to leak the suppression to the
// user code as well :-(

View File

@ -116,14 +116,15 @@ namespace {
return getRegistryHub().getTestCaseRegistry().getAllTestsSorted( config );
}
void TestRegistry::registerTest(std::unique_ptr<TestCaseInfo> testInfo, std::unique_ptr<ITestInvoker> testInvoker) {
void TestRegistry::registerTest(Detail::unique_ptr<TestCaseInfo> testInfo, Detail::unique_ptr<ITestInvoker> testInvoker) {
m_handles.emplace_back(testInfo.get(), testInvoker.get());
m_infos.push_back(std::move(testInfo));
m_viewed_test_infos.push_back(testInfo.get());
m_owned_test_infos.push_back(std::move(testInfo));
m_invokers.push_back(std::move(testInvoker));
}
std::vector<std::unique_ptr<TestCaseInfo>> const& TestRegistry::getAllInfos() const {
return m_infos;
std::vector<TestCaseInfo*> const& TestRegistry::getAllInfos() const {
return m_viewed_test_infos;
}
std::vector<TestCaseHandle> const& TestRegistry::getAllTests() const {

View File

@ -35,15 +35,19 @@ namespace Catch {
public:
~TestRegistry() override = default;
virtual void registerTest( std::unique_ptr<TestCaseInfo> testInfo, std::unique_ptr<ITestInvoker> testInvoker );
virtual void registerTest( Detail::unique_ptr<TestCaseInfo> testInfo, Detail::unique_ptr<ITestInvoker> testInvoker );
std::vector<std::unique_ptr<TestCaseInfo>> const& getAllInfos() const override;
std::vector<TestCaseInfo*> const& getAllInfos() const override;
std::vector<TestCaseHandle> const& getAllTests() const override;
std::vector<TestCaseHandle> const& getAllTestsSorted( IConfig const& config ) const override;
private:
std::vector<std::unique_ptr<TestCaseInfo>> m_infos;
std::vector<std::unique_ptr<ITestInvoker>> m_invokers;
std::vector<Detail::unique_ptr<TestCaseInfo>> m_owned_test_infos;
// Keeps a materialized vector for `getAllInfos`.
// We should get rid of that eventually (see interface note)
std::vector<TestCaseInfo*> m_viewed_test_infos;
std::vector<Detail::unique_ptr<ITestInvoker>> m_invokers;
std::vector<TestCaseHandle> m_handles;
mutable RunTests::InWhatOrder m_currentSortOrder = RunTests::InDeclarationOrder;
mutable std::vector<TestCaseHandle> m_sortedFunctions;

View File

@ -13,11 +13,11 @@
namespace Catch {
std::unique_ptr<ITestInvoker> makeTestInvoker( void(*testAsFunction)() ) {
return std::make_unique<TestInvokerAsFunction>( testAsFunction );
Detail::unique_ptr<ITestInvoker> makeTestInvoker( void(*testAsFunction)() ) {
return Detail::unique_ptr<ITestInvoker>( new TestInvokerAsFunction( testAsFunction ));
}
AutoReg::AutoReg( std::unique_ptr<ITestInvoker> invoker, SourceLineInfo const& lineInfo, StringRef const& classOrMethod, NameAndTags const& nameAndTags ) noexcept {
AutoReg::AutoReg( Detail::unique_ptr<ITestInvoker> invoker, SourceLineInfo const& lineInfo, StringRef const& classOrMethod, NameAndTags const& nameAndTags ) noexcept {
CATCH_TRY {
getMutableRegistryHub()
.registerTest(
@ -25,7 +25,8 @@ namespace Catch {
extractClassName( classOrMethod ),
nameAndTags,
lineInfo),
std::move(invoker));
std::move(invoker)
);
} CATCH_CATCH_ALL {
// Do not throw when constructing global objects, instead register the exception to be processed later
getMutableRegistryHub().registerStartupException();

View File

@ -12,8 +12,7 @@
#include <catch2/interfaces/catch_interfaces_testcase.hpp>
#include <catch2/internal/catch_compiler_capabilities.hpp>
#include <catch2/internal/catch_stringref.hpp>
#include <memory>
#include <catch2/internal/catch_unique_ptr.hpp>
// GCC 5 and older do not properly handle disabling unused-variable warning
// with a _Pragma. This means that we have to leak the suppression to the
@ -38,11 +37,11 @@ public:
}
};
std::unique_ptr<ITestInvoker> makeTestInvoker( void(*testAsFunction)() );
Detail::unique_ptr<ITestInvoker> makeTestInvoker( void(*testAsFunction)() );
template<typename C>
std::unique_ptr<ITestInvoker> makeTestInvoker( void (C::*testAsMethod)() ) {
return std::make_unique<TestInvokerAsMethod<C>>( testAsMethod );
Detail::unique_ptr<ITestInvoker> makeTestInvoker( void (C::*testAsMethod)() ) {
return Detail::unique_ptr<ITestInvoker>( new TestInvokerAsMethod<C>(testAsMethod) );
}
struct NameAndTags {
@ -54,7 +53,7 @@ struct NameAndTags {
};
struct AutoReg : NonCopyable {
AutoReg( std::unique_ptr<ITestInvoker> invoker, SourceLineInfo const& lineInfo, StringRef const& classOrMethod, NameAndTags const& nameAndTags ) noexcept;
AutoReg( Detail::unique_ptr<ITestInvoker> invoker, SourceLineInfo const& lineInfo, StringRef const& classOrMethod, NameAndTags const& nameAndTags ) noexcept;
};
} // end namespace Catch

View File

@ -199,9 +199,9 @@ namespace Catch {
if (!token.empty()) {
if (m_exclusion) {
m_currentFilter.m_forbidden.emplace_back(std::make_unique<TestSpec::NamePattern>(token, m_substring));
m_currentFilter.m_forbidden.emplace_back(Detail::make_unique<TestSpec::NamePattern>(token, m_substring));
} else {
m_currentFilter.m_required.emplace_back(std::make_unique<TestSpec::NamePattern>(token, m_substring));
m_currentFilter.m_required.emplace_back(Detail::make_unique<TestSpec::NamePattern>(token, m_substring));
}
}
m_substring.clear();
@ -218,17 +218,17 @@ namespace Catch {
if (token.size() > 1 && token[0] == '.') {
token.erase(token.begin());
if (m_exclusion) {
m_currentFilter.m_forbidden.emplace_back(std::make_unique<TestSpec::TagPattern>(".", m_substring));
m_currentFilter.m_forbidden.emplace_back(std::make_unique<TestSpec::TagPattern>(token, m_substring));
m_currentFilter.m_forbidden.emplace_back(Detail::make_unique<TestSpec::TagPattern>(".", m_substring));
m_currentFilter.m_forbidden.emplace_back(Detail::make_unique<TestSpec::TagPattern>(token, m_substring));
} else {
m_currentFilter.m_required.emplace_back(std::make_unique<TestSpec::TagPattern>(".", m_substring));
m_currentFilter.m_required.emplace_back(std::make_unique<TestSpec::TagPattern>(token, m_substring));
m_currentFilter.m_required.emplace_back(Detail::make_unique<TestSpec::TagPattern>(".", m_substring));
m_currentFilter.m_required.emplace_back(Detail::make_unique<TestSpec::TagPattern>(token, m_substring));
}
}
if (m_exclusion) {
m_currentFilter.m_forbidden.emplace_back(std::make_unique<TestSpec::TagPattern>(token, m_substring));
m_currentFilter.m_forbidden.emplace_back(Detail::make_unique<TestSpec::TagPattern>(token, m_substring));
} else {
m_currentFilter.m_required.emplace_back(std::make_unique<TestSpec::TagPattern>(token, m_substring));
m_currentFilter.m_required.emplace_back(Detail::make_unique<TestSpec::TagPattern>(token, m_substring));
}
}
m_substring.clear();

View File

@ -0,0 +1,110 @@
#ifndef CATCH_UNIQUE_PTR_HPP_INCLUDED
#define CATCH_UNIQUE_PTR_HPP_INCLUDED
#include <cassert>
#include <type_traits>
namespace Catch {
namespace Detail {
// reimplementation of unique_ptr for improved compilation times
// Does not support custom deleters (and thus does not require EBO)
// Does not support arrays
template <typename T>
class unique_ptr {
T* m_ptr;
public:
constexpr unique_ptr(std::nullptr_t = nullptr):
m_ptr{}
{}
explicit constexpr unique_ptr(T* ptr):
m_ptr(ptr)
{}
template <typename U, typename = std::enable_if_t<std::is_base_of<T, U>::value>>
unique_ptr(unique_ptr<U>&& from):
m_ptr(from.release())
{}
template <typename U, typename = std::enable_if_t<std::is_base_of<T, U>::value>>
unique_ptr& operator=(unique_ptr<U>&& from) {
reset(from.release());
return *this;
}
unique_ptr(unique_ptr const&) = delete;
unique_ptr& operator=(unique_ptr const&) = delete;
unique_ptr(unique_ptr&& rhs) noexcept:
m_ptr(rhs.m_ptr) {
rhs.m_ptr = nullptr;
}
unique_ptr& operator=(unique_ptr&& rhs) noexcept {
reset(rhs.release());
return *this;
}
~unique_ptr() {
delete m_ptr;
}
T& operator*() {
assert(m_ptr);
return *m_ptr;
}
T const& operator*() const {
assert(m_ptr);
return *m_ptr;
}
T* operator->() const noexcept {
assert(m_ptr);
return m_ptr;
}
T* get() { return m_ptr; }
T const* get() const { return m_ptr; }
void reset(T* ptr = nullptr) {
delete m_ptr;
m_ptr = ptr;
}
T* release() {
auto temp = m_ptr;
m_ptr = nullptr;
return temp;
}
explicit operator bool() const {
return m_ptr;
}
friend void swap(unique_ptr& lhs, unique_ptr& rhs) {
auto temp = lhs.m_ptr;
lhs.m_ptr = rhs.m_ptr;
rhs.m_ptr = temp;
}
};
// Purposefully doesn't exist
// We could also rely on compiler warning + werror for calling plain delete
// on a T[], but this seems better.
// Maybe add definition and a static assert?
template <typename T>
class unique_ptr<T[]>;
template <typename T, typename... Args>
unique_ptr<T> make_unique(Args&&... args) {
// static_cast<Args&&> does the same thing as std::forward in
// this case, but does not require including big header (<utility>)
// and compiles faster thanks to not requiring template instantiation
// and overload resolution
return unique_ptr<T>(new T(static_cast<Args&&>(args)...));
}
} // end namespace Detail
} // end namespace Catch
#endif // CATCH_UNIQUE_PTR_HPP_INCLUDED

View File

@ -17,7 +17,6 @@
#include <cstdio>
#include <ostream>
#include <cassert>
#include <memory>
namespace Catch {
void prepareExpandedExpression(AssertionResult& result) {

View File

@ -9,6 +9,7 @@
#define TWOBLUECUBES_CATCH_REPORTER_CONSOLE_H_INCLUDED
#include <catch2/reporters/catch_reporter_bases.hpp>
#include <catch2/internal/catch_unique_ptr.hpp>
#if defined(_MSC_VER)
#pragma warning(push)
@ -24,7 +25,7 @@ namespace Catch {
class TablePrinter;
struct ConsoleReporter : StreamingReporterBase {
std::unique_ptr<TablePrinter> m_tablePrinter;
Detail::unique_ptr<TablePrinter> m_tablePrinter;
ConsoleReporter(ReporterConfig const& config);
~ConsoleReporter() override;

View File

@ -27,6 +27,7 @@ set(TEST_SOURCES
${SELF_TEST_DIR}/IntrospectiveTests/StringManip.tests.cpp
${SELF_TEST_DIR}/IntrospectiveTests/Xml.tests.cpp
${SELF_TEST_DIR}/IntrospectiveTests/ToString.tests.cpp
${SELF_TEST_DIR}/IntrospectiveTests/UniquePtr.tests.cpp
${SELF_TEST_DIR}/UsageTests/Approx.tests.cpp
${SELF_TEST_DIR}/UsageTests/BDD.tests.cpp
${SELF_TEST_DIR}/UsageTests/Benchmark.tests.cpp

View File

@ -222,6 +222,7 @@ Message from section two
:test-result: PASS Tracker
:test-result: PASS Trim strings
:test-result: FAIL Unexpected exceptions can be translated
:test-result: PASS Upcasting special member functions
:test-result: PASS Usage of the SizeIs range matcher
:test-result: PASS Use a custom approx
:test-result: PASS Variadic macros
@ -268,6 +269,7 @@ loose text artifact
:test-result: PASS long long
:test-result: FAIL looped SECTION tests
:test-result: FAIL looped tests
:test-result: PASS make_unique reimplementation
:test-result: PASS mean
:test-result: PASS measure
:test-result: FAIL mix info, unscoped info and warning
@ -331,6 +333,7 @@ loose text artifact
:test-result: PASS tuple<string,string>
:test-result: PASS tuple<tuple<int>,tuple<>,float>
:test-result: PASS uniform samples
:test-result: PASS unique_ptr reimplementation: basic functionality
:test-result: PASS vec<vec<string,alloc>> -> toString
:test-result: PASS vector<bool> -> toString
:test-result: PASS vector<int,allocator> -> toString

View File

@ -1587,6 +1587,8 @@ StringManip.tests.cpp:<line number>: passed: trim(StringRef(whitespace_at_both_e
==
There is no extra whitespace here
Exception.tests.cpp:<line number>: failed: unexpected exception with message: '3.14'
UniquePtr.tests.cpp:<line number>: passed: bptr->i == 3 for: 3 == 3
UniquePtr.tests.cpp:<line number>: passed: bptr->i == 3 for: 3 == 3
MatchersRanges.tests.cpp:<line number>: passed: empty_vec, SizeIs(0) for: { } has size == 0
MatchersRanges.tests.cpp:<line number>: passed: empty_vec, !SizeIs(2) for: { } not has size == 2
MatchersRanges.tests.cpp:<line number>: passed: empty_vec, SizeIs(Lt(2)) for: { } size matches is less than 2
@ -1794,6 +1796,9 @@ Misc.tests.cpp:<line number>: failed: ( fib[i] % 2 ) == 0 for: 1 == 0 with 1 mes
Misc.tests.cpp:<line number>: passed: ( fib[i] % 2 ) == 0 for: 0 == 0 with 1 message: 'Testing if fib[5] (8) is even'
Misc.tests.cpp:<line number>: failed: ( fib[i] % 2 ) == 0 for: 1 == 0 with 1 message: 'Testing if fib[6] (13) is even'
Misc.tests.cpp:<line number>: failed: ( fib[i] % 2 ) == 0 for: 1 == 0 with 1 message: 'Testing if fib[7] (21) is even'
UniquePtr.tests.cpp:<line number>: passed: !(lval.has_moved) for: !false
UniquePtr.tests.cpp:<line number>: passed: rval.has_moved for: true
UniquePtr.tests.cpp:<line number>: passed: *ptr == std::tuple<int, double, int>{1, 2., 3} for: {?} == {?}
InternalBenchmark.tests.cpp:<line number>: passed: m == 19. for: 19.0 == 19.0
InternalBenchmark.tests.cpp:<line number>: passed: x == 17 for: 17 == 17
InternalBenchmark.tests.cpp:<line number>: passed: x == 23 for: 23 == 23
@ -1990,6 +1995,29 @@ InternalBenchmark.tests.cpp:<line number>: passed: e.point == 23 for: 23.0 == 23
InternalBenchmark.tests.cpp:<line number>: passed: e.upper_bound == 23 for: 23.0 == 23
InternalBenchmark.tests.cpp:<line number>: passed: e.lower_bound == 23 for: 23.0 == 23
InternalBenchmark.tests.cpp:<line number>: passed: e.confidence_interval == 0.95 for: 0.95 == 0.95
UniquePtr.tests.cpp:<line number>: passed: !(ptr) for: !{?}
UniquePtr.tests.cpp:<line number>: passed: ptr.get() == 0 for: 0 == 0
UniquePtr.tests.cpp:<line number>: passed: ptr for: {?}
UniquePtr.tests.cpp:<line number>: passed: *ptr == 0 for: 0 == 0
UniquePtr.tests.cpp:<line number>: passed: ptr.get() == naked_ptr for: 0x<hex digits> == 0x<hex digits>
UniquePtr.tests.cpp:<line number>: passed: !(ptr) for: !{?}
UniquePtr.tests.cpp:<line number>: passed: ptr.get() == 0 for: 0 == 0
UniquePtr.tests.cpp:<line number>: passed: ptr for: {?}
UniquePtr.tests.cpp:<line number>: passed: *ptr == 0 for: 0 == 0
UniquePtr.tests.cpp:<line number>: passed: ptr.get() == naked_ptr for: 0x<hex digits> == 0x<hex digits>
UniquePtr.tests.cpp:<line number>: passed: ptr for: {?}
UniquePtr.tests.cpp:<line number>: passed: ptr.get() != 0 for: 0x<hex digits> != 0
UniquePtr.tests.cpp:<line number>: passed: *ptr == 2 for: 2 == 2
UniquePtr.tests.cpp:<line number>: passed: !(ptr) for: !{?}
UniquePtr.tests.cpp:<line number>: passed: ptr.get() == 0 for: 0 == 0
UniquePtr.tests.cpp:<line number>: passed: !(ptr1) for: !{?}
UniquePtr.tests.cpp:<line number>: passed: ptr2 for: {?}
UniquePtr.tests.cpp:<line number>: passed: *ptr2 == 1 for: 1 == 1
UniquePtr.tests.cpp:<line number>: passed: !(ptr2) for: !{?}
UniquePtr.tests.cpp:<line number>: passed: ptr1 for: {?}
UniquePtr.tests.cpp:<line number>: passed: *ptr1 == 2 for: 2 == 2
UniquePtr.tests.cpp:<line number>: passed: *ptr1 == 2 for: 2 == 2
UniquePtr.tests.cpp:<line number>: passed: *ptr2 == 1 for: 1 == 1
ToStringVector.tests.cpp:<line number>: passed: ::Catch::Detail::stringify(v) == "{ }" for: "{ }" == "{ }"
ToStringVector.tests.cpp:<line number>: passed: ::Catch::Detail::stringify(v) == "{ { \"hello\" }, { \"world\" } }" for: "{ { "hello" }, { "world" } }"
==

View File

@ -1380,6 +1380,6 @@ due to unexpected exception with message:
Why would you throw a std::string?
===============================================================================
test cases: 334 | 260 passed | 70 failed | 4 failed as expected
assertions: 1896 | 1744 passed | 131 failed | 21 failed as expected
test cases: 337 | 263 passed | 70 failed | 4 failed as expected
assertions: 1924 | 1772 passed | 131 failed | 21 failed as expected

View File

@ -11547,6 +11547,30 @@ Exception.tests.cpp:<line number>: FAILED:
due to unexpected exception with message:
3.14
-------------------------------------------------------------------------------
Upcasting special member functions
Move constructor
-------------------------------------------------------------------------------
UniquePtr.tests.cpp:<line number>
...............................................................................
UniquePtr.tests.cpp:<line number>: PASSED:
REQUIRE( bptr->i == 3 )
with expansion:
3 == 3
-------------------------------------------------------------------------------
Upcasting special member functions
move assignment
-------------------------------------------------------------------------------
UniquePtr.tests.cpp:<line number>
...............................................................................
UniquePtr.tests.cpp:<line number>: PASSED:
REQUIRE( bptr->i == 3 )
with expansion:
3 == 3
-------------------------------------------------------------------------------
Usage of the SizeIs range matcher
Some with stdlib containers
@ -13096,6 +13120,42 @@ with expansion:
with message:
Testing if fib[7] (21) is even
-------------------------------------------------------------------------------
make_unique reimplementation
From lvalue copies
-------------------------------------------------------------------------------
UniquePtr.tests.cpp:<line number>
...............................................................................
UniquePtr.tests.cpp:<line number>: PASSED:
REQUIRE_FALSE( lval.has_moved )
with expansion:
!false
-------------------------------------------------------------------------------
make_unique reimplementation
From rvalue moves
-------------------------------------------------------------------------------
UniquePtr.tests.cpp:<line number>
...............................................................................
UniquePtr.tests.cpp:<line number>: PASSED:
REQUIRE( rval.has_moved )
with expansion:
true
-------------------------------------------------------------------------------
make_unique reimplementation
Variadic constructor
-------------------------------------------------------------------------------
UniquePtr.tests.cpp:<line number>
...............................................................................
UniquePtr.tests.cpp:<line number>: PASSED:
REQUIRE( *ptr == std::tuple<int, double, int>{1, 2., 3} )
with expansion:
{?} == {?}
-------------------------------------------------------------------------------
mean
-------------------------------------------------------------------------------
@ -14485,6 +14545,186 @@ InternalBenchmark.tests.cpp:<line number>: PASSED:
with expansion:
0.95 == 0.95
-------------------------------------------------------------------------------
unique_ptr reimplementation: basic functionality
Default constructed unique_ptr is empty
-------------------------------------------------------------------------------
UniquePtr.tests.cpp:<line number>
...............................................................................
UniquePtr.tests.cpp:<line number>: PASSED:
REQUIRE_FALSE( ptr )
with expansion:
!{?}
UniquePtr.tests.cpp:<line number>: PASSED:
REQUIRE( ptr.get() == 0 )
with expansion:
0 == 0
-------------------------------------------------------------------------------
unique_ptr reimplementation: basic functionality
Take ownership of allocation
-------------------------------------------------------------------------------
UniquePtr.tests.cpp:<line number>
...............................................................................
UniquePtr.tests.cpp:<line number>: PASSED:
REQUIRE( ptr )
with expansion:
{?}
UniquePtr.tests.cpp:<line number>: PASSED:
REQUIRE( *ptr == 0 )
with expansion:
0 == 0
UniquePtr.tests.cpp:<line number>: PASSED:
REQUIRE( ptr.get() == naked_ptr )
with expansion:
0x<hex digits> == 0x<hex digits>
-------------------------------------------------------------------------------
unique_ptr reimplementation: basic functionality
Take ownership of allocation
Plain reset deallocates
-------------------------------------------------------------------------------
UniquePtr.tests.cpp:<line number>
...............................................................................
UniquePtr.tests.cpp:<line number>: PASSED:
REQUIRE_FALSE( ptr )
with expansion:
!{?}
UniquePtr.tests.cpp:<line number>: PASSED:
REQUIRE( ptr.get() == 0 )
with expansion:
0 == 0
-------------------------------------------------------------------------------
unique_ptr reimplementation: basic functionality
Take ownership of allocation
-------------------------------------------------------------------------------
UniquePtr.tests.cpp:<line number>
...............................................................................
UniquePtr.tests.cpp:<line number>: PASSED:
REQUIRE( ptr )
with expansion:
{?}
UniquePtr.tests.cpp:<line number>: PASSED:
REQUIRE( *ptr == 0 )
with expansion:
0 == 0
UniquePtr.tests.cpp:<line number>: PASSED:
REQUIRE( ptr.get() == naked_ptr )
with expansion:
0x<hex digits> == 0x<hex digits>
-------------------------------------------------------------------------------
unique_ptr reimplementation: basic functionality
Take ownership of allocation
Reset replaces ownership
-------------------------------------------------------------------------------
UniquePtr.tests.cpp:<line number>
...............................................................................
UniquePtr.tests.cpp:<line number>: PASSED:
REQUIRE( ptr )
with expansion:
{?}
UniquePtr.tests.cpp:<line number>: PASSED:
REQUIRE( ptr.get() != 0 )
with expansion:
0x<hex digits> != 0
UniquePtr.tests.cpp:<line number>: PASSED:
REQUIRE( *ptr == 2 )
with expansion:
2 == 2
-------------------------------------------------------------------------------
unique_ptr reimplementation: basic functionality
Release releases ownership
-------------------------------------------------------------------------------
UniquePtr.tests.cpp:<line number>
...............................................................................
UniquePtr.tests.cpp:<line number>: PASSED:
CHECK_FALSE( ptr )
with expansion:
!{?}
UniquePtr.tests.cpp:<line number>: PASSED:
CHECK( ptr.get() == 0 )
with expansion:
0 == 0
-------------------------------------------------------------------------------
unique_ptr reimplementation: basic functionality
Move constructor
-------------------------------------------------------------------------------
UniquePtr.tests.cpp:<line number>
...............................................................................
UniquePtr.tests.cpp:<line number>: PASSED:
REQUIRE_FALSE( ptr1 )
with expansion:
!{?}
UniquePtr.tests.cpp:<line number>: PASSED:
REQUIRE( ptr2 )
with expansion:
{?}
UniquePtr.tests.cpp:<line number>: PASSED:
REQUIRE( *ptr2 == 1 )
with expansion:
1 == 1
-------------------------------------------------------------------------------
unique_ptr reimplementation: basic functionality
Move assignment
-------------------------------------------------------------------------------
UniquePtr.tests.cpp:<line number>
...............................................................................
UniquePtr.tests.cpp:<line number>: PASSED:
REQUIRE_FALSE( ptr2 )
with expansion:
!{?}
UniquePtr.tests.cpp:<line number>: PASSED:
REQUIRE( ptr1 )
with expansion:
{?}
UniquePtr.tests.cpp:<line number>: PASSED:
REQUIRE( *ptr1 == 2 )
with expansion:
2 == 2
-------------------------------------------------------------------------------
unique_ptr reimplementation: basic functionality
free swap
-------------------------------------------------------------------------------
UniquePtr.tests.cpp:<line number>
...............................................................................
UniquePtr.tests.cpp:<line number>: PASSED:
REQUIRE( *ptr1 == 2 )
with expansion:
2 == 2
UniquePtr.tests.cpp:<line number>: PASSED:
REQUIRE( *ptr2 == 1 )
with expansion:
1 == 1
-------------------------------------------------------------------------------
vec<vec<string,alloc>> -> toString
-------------------------------------------------------------------------------
@ -14792,6 +15032,6 @@ Misc.tests.cpp:<line number>
Misc.tests.cpp:<line number>: PASSED:
===============================================================================
test cases: 334 | 244 passed | 86 failed | 4 failed as expected
assertions: 1913 | 1744 passed | 148 failed | 21 failed as expected
test cases: 337 | 247 passed | 86 failed | 4 failed as expected
assertions: 1941 | 1772 passed | 148 failed | 21 failed as expected

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<testsuitesloose text artifact
>
<testsuite name="<exe-name>" errors="17" failures="132" tests="1914" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
<testsuite name="<exe-name>" errors="17" failures="132" tests="1942" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
<properties>
<property name="filters" value="~[!nonportable]~[!benchmark]~[approvals] *"/>
<property name="random-seed" value="1"/>
@ -1256,6 +1256,8 @@ FAILED:
Exception.tests.cpp:<line number>
</error>
</testcase>
<testcase classname="<exe-name>.global" name="Upcasting special member functions/Move constructor" time="{duration}"/>
<testcase classname="<exe-name>.global" name="Upcasting special member functions/move assignment" time="{duration}"/>
<testcase classname="<exe-name>.global" name="Usage of the SizeIs range matcher/Some with stdlib containers" time="{duration}"/>
<testcase classname="<exe-name>.global" name="Usage of the SizeIs range matcher/Type requires ADL found size free function" time="{duration}"/>
<testcase classname="<exe-name>.global" name="Usage of the SizeIs range matcher/Type has size member" time="{duration}"/>
@ -1577,6 +1579,9 @@ Testing if fib[7] (21) is even
Misc.tests.cpp:<line number>
</failure>
</testcase>
<testcase classname="<exe-name>.global" name="make_unique reimplementation/From lvalue copies" time="{duration}"/>
<testcase classname="<exe-name>.global" name="make_unique reimplementation/From rvalue moves" time="{duration}"/>
<testcase classname="<exe-name>.global" name="make_unique reimplementation/Variadic constructor" time="{duration}"/>
<testcase classname="<exe-name>.global" name="mean" time="{duration}"/>
<testcase classname="<exe-name>.global" name="measure" time="{duration}"/>
<testcase classname="<exe-name>.global" name="mix info, unscoped info and warning" time="{duration}"/>
@ -1733,6 +1738,14 @@ Exception.tests.cpp:<line number>
<testcase classname="<exe-name>.global" name="tuple&lt;string,string>" time="{duration}"/>
<testcase classname="<exe-name>.global" name="tuple&lt;tuple&lt;int>,tuple&lt;>,float>" time="{duration}"/>
<testcase classname="<exe-name>.global" name="uniform samples" time="{duration}"/>
<testcase classname="<exe-name>.global" name="unique_ptr reimplementation: basic functionality/Default constructed unique_ptr is empty" time="{duration}"/>
<testcase classname="<exe-name>.global" name="unique_ptr reimplementation: basic functionality/Take ownership of allocation" time="{duration}"/>
<testcase classname="<exe-name>.global" name="unique_ptr reimplementation: basic functionality/Take ownership of allocation/Plain reset deallocates" time="{duration}"/>
<testcase classname="<exe-name>.global" name="unique_ptr reimplementation: basic functionality/Take ownership of allocation/Reset replaces ownership" time="{duration}"/>
<testcase classname="<exe-name>.global" name="unique_ptr reimplementation: basic functionality/Release releases ownership" time="{duration}"/>
<testcase classname="<exe-name>.global" name="unique_ptr reimplementation: basic functionality/Move constructor" time="{duration}"/>
<testcase classname="<exe-name>.global" name="unique_ptr reimplementation: basic functionality/Move assignment" time="{duration}"/>
<testcase classname="<exe-name>.global" name="unique_ptr reimplementation: basic functionality/free swap" time="{duration}"/>
<testcase classname="<exe-name>.global" name="vec&lt;vec&lt;string,alloc>> -> toString" time="{duration}"/>
<testcase classname="<exe-name>.global" name="vector&lt;bool> -> toString" time="{duration}"/>
<testcase classname="<exe-name>.global" name="vector&lt;int,allocator> -> toString" time="{duration}"/>

View File

@ -180,6 +180,21 @@
<testCase name="parseEnums/One enum value" duration="{duration}"/>
<testCase name="parseEnums/Multiple enum values" duration="{duration}"/>
</file>
<file path="tests/<exe-name>/IntrospectiveTests/UniquePtr.tests.cpp">
<testCase name="Upcasting special member functions/Move constructor" duration="{duration}"/>
<testCase name="Upcasting special member functions/move assignment" duration="{duration}"/>
<testCase name="make_unique reimplementation/From lvalue copies" duration="{duration}"/>
<testCase name="make_unique reimplementation/From rvalue moves" duration="{duration}"/>
<testCase name="make_unique reimplementation/Variadic constructor" duration="{duration}"/>
<testCase name="unique_ptr reimplementation: basic functionality/Default constructed unique_ptr is empty" duration="{duration}"/>
<testCase name="unique_ptr reimplementation: basic functionality/Take ownership of allocation" duration="{duration}"/>
<testCase name="unique_ptr reimplementation: basic functionality/Take ownership of allocation/Plain reset deallocates" duration="{duration}"/>
<testCase name="unique_ptr reimplementation: basic functionality/Take ownership of allocation/Reset replaces ownership" duration="{duration}"/>
<testCase name="unique_ptr reimplementation: basic functionality/Release releases ownership" duration="{duration}"/>
<testCase name="unique_ptr reimplementation: basic functionality/Move constructor" duration="{duration}"/>
<testCase name="unique_ptr reimplementation: basic functionality/Move assignment" duration="{duration}"/>
<testCase name="unique_ptr reimplementation: basic functionality/free swap" duration="{duration}"/>
</file>
<file path="tests/<exe-name>/IntrospectiveTests/Xml.tests.cpp">
<testCase name="XmlEncode/normal string" duration="{duration}"/>
<testCase name="XmlEncode/empty string" duration="{duration}"/>

View File

@ -3021,6 +3021,10 @@ ok {test-number} - trim(StringRef(trailing_whitespace)) == StringRef(no_whitespa
ok {test-number} - trim(StringRef(whitespace_at_both_ends)) == StringRef(no_whitespace) for: There is no extra whitespace here == There is no extra whitespace here
# Unexpected exceptions can be translated
not ok {test-number} - unexpected exception with message: '3.14'
# Upcasting special member functions
ok {test-number} - bptr->i == 3 for: 3 == 3
# Upcasting special member functions
ok {test-number} - bptr->i == 3 for: 3 == 3
# Usage of the SizeIs range matcher
ok {test-number} - empty_vec, SizeIs(0) for: { } has size == 0
# Usage of the SizeIs range matcher
@ -3418,6 +3422,12 @@ ok {test-number} - ( fib[i] % 2 ) == 0 for: 0 == 0 with 1 message: 'Testing if f
not ok {test-number} - ( fib[i] % 2 ) == 0 for: 1 == 0 with 1 message: 'Testing if fib[6] (13) is even'
# looped tests
not ok {test-number} - ( fib[i] % 2 ) == 0 for: 1 == 0 with 1 message: 'Testing if fib[7] (21) is even'
# make_unique reimplementation
ok {test-number} - !(lval.has_moved) for: !false
# make_unique reimplementation
ok {test-number} - rval.has_moved for: true
# make_unique reimplementation
ok {test-number} - *ptr == std::tuple<int, double, int>{1, 2., 3} for: {?} == {?}
# mean
ok {test-number} - m == 19. for: 19.0 == 19.0
# measure
@ -3742,6 +3752,52 @@ ok {test-number} - e.upper_bound == 23 for: 23.0 == 23
ok {test-number} - e.lower_bound == 23 for: 23.0 == 23
# uniform samples
ok {test-number} - e.confidence_interval == 0.95 for: 0.95 == 0.95
# unique_ptr reimplementation: basic functionality
ok {test-number} - !(ptr) for: !{?}
# unique_ptr reimplementation: basic functionality
ok {test-number} - ptr.get() == 0 for: 0 == 0
# unique_ptr reimplementation: basic functionality
ok {test-number} - ptr for: {?}
# unique_ptr reimplementation: basic functionality
ok {test-number} - *ptr == 0 for: 0 == 0
# unique_ptr reimplementation: basic functionality
ok {test-number} - ptr.get() == naked_ptr for: 0x<hex digits> == 0x<hex digits>
# unique_ptr reimplementation: basic functionality
ok {test-number} - !(ptr) for: !{?}
# unique_ptr reimplementation: basic functionality
ok {test-number} - ptr.get() == 0 for: 0 == 0
# unique_ptr reimplementation: basic functionality
ok {test-number} - ptr for: {?}
# unique_ptr reimplementation: basic functionality
ok {test-number} - *ptr == 0 for: 0 == 0
# unique_ptr reimplementation: basic functionality
ok {test-number} - ptr.get() == naked_ptr for: 0x<hex digits> == 0x<hex digits>
# unique_ptr reimplementation: basic functionality
ok {test-number} - ptr for: {?}
# unique_ptr reimplementation: basic functionality
ok {test-number} - ptr.get() != 0 for: 0x<hex digits> != 0
# unique_ptr reimplementation: basic functionality
ok {test-number} - *ptr == 2 for: 2 == 2
# unique_ptr reimplementation: basic functionality
ok {test-number} - !(ptr) for: !{?}
# unique_ptr reimplementation: basic functionality
ok {test-number} - ptr.get() == 0 for: 0 == 0
# unique_ptr reimplementation: basic functionality
ok {test-number} - !(ptr1) for: !{?}
# unique_ptr reimplementation: basic functionality
ok {test-number} - ptr2 for: {?}
# unique_ptr reimplementation: basic functionality
ok {test-number} - *ptr2 == 1 for: 1 == 1
# unique_ptr reimplementation: basic functionality
ok {test-number} - !(ptr2) for: !{?}
# unique_ptr reimplementation: basic functionality
ok {test-number} - ptr1 for: {?}
# unique_ptr reimplementation: basic functionality
ok {test-number} - *ptr1 == 2 for: 2 == 2
# unique_ptr reimplementation: basic functionality
ok {test-number} - *ptr1 == 2 for: 2 == 2
# unique_ptr reimplementation: basic functionality
ok {test-number} - *ptr2 == 1 for: 1 == 1
# vec<vec<string,alloc>> -> toString
ok {test-number} - ::Catch::Detail::stringify(v) == "{ }" for: "{ }" == "{ }"
# vec<vec<string,alloc>> -> toString
@ -3818,5 +3874,5 @@ ok {test-number} - q3 == 23. for: 23.0 == 23.0
ok {test-number} -
# xmlentitycheck
ok {test-number} -
1..1905
1..1933

View File

@ -547,6 +547,8 @@ Exception.tests.cpp:<line number>|nunexpected exception with message:|n "For so
##teamcity[testStarted name='Unexpected exceptions can be translated']
Exception.tests.cpp:<line number>|nunexpected exception with message:|n "3.14"']
##teamcity[testFinished name='Unexpected exceptions can be translated' duration="{duration}"]
##teamcity[testStarted name='Upcasting special member functions']
##teamcity[testFinished name='Upcasting special member functions' duration="{duration}"]
##teamcity[testStarted name='Usage of the SizeIs range matcher']
##teamcity[testFinished name='Usage of the SizeIs range matcher' duration="{duration}"]
##teamcity[testStarted name='Use a custom approx']
@ -671,6 +673,8 @@ Misc.tests.cpp:<line number>|nexpression failed with message:|n "Testing if fib
Misc.tests.cpp:<line number>|nexpression failed with message:|n "Testing if fib|[6|] (13) is even"|n CHECK( ( fib|[i|] % 2 ) == 0 )|nwith expansion:|n 1 == 0|n']
Misc.tests.cpp:<line number>|nexpression failed with message:|n "Testing if fib|[7|] (21) is even"|n CHECK( ( fib|[i|] % 2 ) == 0 )|nwith expansion:|n 1 == 0|n']
##teamcity[testFinished name='looped tests' duration="{duration}"]
##teamcity[testStarted name='make_unique reimplementation']
##teamcity[testFinished name='make_unique reimplementation' duration="{duration}"]
##teamcity[testStarted name='mean']
##teamcity[testFinished name='mean' duration="{duration}"]
##teamcity[testStarted name='measure']
@ -807,6 +811,8 @@ Exception.tests.cpp:<line number>|nunexpected exception with message:|n "Why wo
##teamcity[testFinished name='tuple<tuple<int>,tuple<>,float>' duration="{duration}"]
##teamcity[testStarted name='uniform samples']
##teamcity[testFinished name='uniform samples' duration="{duration}"]
##teamcity[testStarted name='unique_ptr reimplementation: basic functionality']
##teamcity[testFinished name='unique_ptr reimplementation: basic functionality' duration="{duration}"]
##teamcity[testStarted name='vec<vec<string,alloc>> -> toString']
##teamcity[testFinished name='vec<vec<string,alloc>> -> toString' duration="{duration}"]
##teamcity[testStarted name='vector<bool> -> toString']

View File

@ -13944,6 +13944,31 @@ There is no extra whitespace here
</Exception>
<OverallResult success="false"/>
</TestCase>
<TestCase name="Upcasting special member functions" tags="[internals][unique-ptr]" filename="tests/<exe-name>/IntrospectiveTests/UniquePtr.tests.cpp" >
<Section name="Move constructor" filename="tests/<exe-name>/IntrospectiveTests/UniquePtr.tests.cpp" >
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/IntrospectiveTests/UniquePtr.tests.cpp" >
<Original>
bptr->i == 3
</Original>
<Expanded>
3 == 3
</Expanded>
</Expression>
<OverallResults successes="1" failures="0" expectedFailures="0"/>
</Section>
<Section name="move assignment" filename="tests/<exe-name>/IntrospectiveTests/UniquePtr.tests.cpp" >
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/IntrospectiveTests/UniquePtr.tests.cpp" >
<Original>
bptr->i == 3
</Original>
<Expanded>
3 == 3
</Expanded>
</Expression>
<OverallResults successes="1" failures="0" expectedFailures="0"/>
</Section>
<OverallResult success="true"/>
</TestCase>
<TestCase name="Usage of the SizeIs range matcher" tags="[matchers][size][templated]" filename="tests/<exe-name>/UsageTests/MatchersRanges.tests.cpp" >
<Section name="Some with stdlib containers" filename="tests/<exe-name>/UsageTests/MatchersRanges.tests.cpp" >
<Expression success="true" type="REQUIRE_THAT" filename="tests/<exe-name>/UsageTests/MatchersRanges.tests.cpp" >
@ -15773,6 +15798,42 @@ loose text artifact
</Expression>
<OverallResult success="false"/>
</TestCase>
<TestCase name="make_unique reimplementation" tags="[internals][unique-ptr]" filename="tests/<exe-name>/IntrospectiveTests/UniquePtr.tests.cpp" >
<Section name="From lvalue copies" filename="tests/<exe-name>/IntrospectiveTests/UniquePtr.tests.cpp" >
<Expression success="true" type="REQUIRE_FALSE" filename="tests/<exe-name>/IntrospectiveTests/UniquePtr.tests.cpp" >
<Original>
!(lval.has_moved)
</Original>
<Expanded>
!false
</Expanded>
</Expression>
<OverallResults successes="1" failures="0" expectedFailures="0"/>
</Section>
<Section name="From rvalue moves" filename="tests/<exe-name>/IntrospectiveTests/UniquePtr.tests.cpp" >
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/IntrospectiveTests/UniquePtr.tests.cpp" >
<Original>
rval.has_moved
</Original>
<Expanded>
true
</Expanded>
</Expression>
<OverallResults successes="1" failures="0" expectedFailures="0"/>
</Section>
<Section name="Variadic constructor" filename="tests/<exe-name>/IntrospectiveTests/UniquePtr.tests.cpp" >
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/IntrospectiveTests/UniquePtr.tests.cpp" >
<Original>
*ptr == std::tuple&lt;int, double, int>{1, 2., 3}
</Original>
<Expanded>
{?} == {?}
</Expanded>
</Expression>
<OverallResults successes="1" failures="0" expectedFailures="0"/>
</Section>
<OverallResult success="true"/>
</TestCase>
<TestCase name="mean" tags="[benchmark]" filename="tests/<exe-name>/IntrospectiveTests/InternalBenchmark.tests.cpp" >
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/IntrospectiveTests/InternalBenchmark.tests.cpp" >
<Original>
@ -17416,6 +17477,220 @@ loose text artifact
</Expression>
<OverallResult success="true"/>
</TestCase>
<TestCase name="unique_ptr reimplementation: basic functionality" tags="[internals][unique-ptr]" filename="tests/<exe-name>/IntrospectiveTests/UniquePtr.tests.cpp" >
<Section name="Default constructed unique_ptr is empty" filename="tests/<exe-name>/IntrospectiveTests/UniquePtr.tests.cpp" >
<Expression success="true" type="REQUIRE_FALSE" filename="tests/<exe-name>/IntrospectiveTests/UniquePtr.tests.cpp" >
<Original>
!(ptr)
</Original>
<Expanded>
!{?}
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/IntrospectiveTests/UniquePtr.tests.cpp" >
<Original>
ptr.get() == 0
</Original>
<Expanded>
0 == 0
</Expanded>
</Expression>
<OverallResults successes="2" failures="0" expectedFailures="0"/>
</Section>
<Section name="Take ownership of allocation" filename="tests/<exe-name>/IntrospectiveTests/UniquePtr.tests.cpp" >
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/IntrospectiveTests/UniquePtr.tests.cpp" >
<Original>
ptr
</Original>
<Expanded>
{?}
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/IntrospectiveTests/UniquePtr.tests.cpp" >
<Original>
*ptr == 0
</Original>
<Expanded>
0 == 0
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/IntrospectiveTests/UniquePtr.tests.cpp" >
<Original>
ptr.get() == naked_ptr
</Original>
<Expanded>
0x<hex digits> == 0x<hex digits>
</Expanded>
</Expression>
<Section name="Plain reset deallocates" filename="tests/<exe-name>/IntrospectiveTests/UniquePtr.tests.cpp" >
<Expression success="true" type="REQUIRE_FALSE" filename="tests/<exe-name>/IntrospectiveTests/UniquePtr.tests.cpp" >
<Original>
!(ptr)
</Original>
<Expanded>
!{?}
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/IntrospectiveTests/UniquePtr.tests.cpp" >
<Original>
ptr.get() == 0
</Original>
<Expanded>
0 == 0
</Expanded>
</Expression>
<OverallResults successes="2" failures="0" expectedFailures="0"/>
</Section>
<OverallResults successes="5" failures="0" expectedFailures="0"/>
</Section>
<Section name="Take ownership of allocation" filename="tests/<exe-name>/IntrospectiveTests/UniquePtr.tests.cpp" >
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/IntrospectiveTests/UniquePtr.tests.cpp" >
<Original>
ptr
</Original>
<Expanded>
{?}
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/IntrospectiveTests/UniquePtr.tests.cpp" >
<Original>
*ptr == 0
</Original>
<Expanded>
0 == 0
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/IntrospectiveTests/UniquePtr.tests.cpp" >
<Original>
ptr.get() == naked_ptr
</Original>
<Expanded>
0x<hex digits> == 0x<hex digits>
</Expanded>
</Expression>
<Section name="Reset replaces ownership" filename="tests/<exe-name>/IntrospectiveTests/UniquePtr.tests.cpp" >
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/IntrospectiveTests/UniquePtr.tests.cpp" >
<Original>
ptr
</Original>
<Expanded>
{?}
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/IntrospectiveTests/UniquePtr.tests.cpp" >
<Original>
ptr.get() != 0
</Original>
<Expanded>
0x<hex digits> != 0
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/IntrospectiveTests/UniquePtr.tests.cpp" >
<Original>
*ptr == 2
</Original>
<Expanded>
2 == 2
</Expanded>
</Expression>
<OverallResults successes="3" failures="0" expectedFailures="0"/>
</Section>
<OverallResults successes="6" failures="0" expectedFailures="0"/>
</Section>
<Section name="Release releases ownership" filename="tests/<exe-name>/IntrospectiveTests/UniquePtr.tests.cpp" >
<Expression success="true" type="CHECK_FALSE" filename="tests/<exe-name>/IntrospectiveTests/UniquePtr.tests.cpp" >
<Original>
!(ptr)
</Original>
<Expanded>
!{?}
</Expanded>
</Expression>
<Expression success="true" type="CHECK" filename="tests/<exe-name>/IntrospectiveTests/UniquePtr.tests.cpp" >
<Original>
ptr.get() == 0
</Original>
<Expanded>
0 == 0
</Expanded>
</Expression>
<OverallResults successes="2" failures="0" expectedFailures="0"/>
</Section>
<Section name="Move constructor" filename="tests/<exe-name>/IntrospectiveTests/UniquePtr.tests.cpp" >
<Expression success="true" type="REQUIRE_FALSE" filename="tests/<exe-name>/IntrospectiveTests/UniquePtr.tests.cpp" >
<Original>
!(ptr1)
</Original>
<Expanded>
!{?}
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/IntrospectiveTests/UniquePtr.tests.cpp" >
<Original>
ptr2
</Original>
<Expanded>
{?}
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/IntrospectiveTests/UniquePtr.tests.cpp" >
<Original>
*ptr2 == 1
</Original>
<Expanded>
1 == 1
</Expanded>
</Expression>
<OverallResults successes="3" failures="0" expectedFailures="0"/>
</Section>
<Section name="Move assignment" filename="tests/<exe-name>/IntrospectiveTests/UniquePtr.tests.cpp" >
<Expression success="true" type="REQUIRE_FALSE" filename="tests/<exe-name>/IntrospectiveTests/UniquePtr.tests.cpp" >
<Original>
!(ptr2)
</Original>
<Expanded>
!{?}
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/IntrospectiveTests/UniquePtr.tests.cpp" >
<Original>
ptr1
</Original>
<Expanded>
{?}
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/IntrospectiveTests/UniquePtr.tests.cpp" >
<Original>
*ptr1 == 2
</Original>
<Expanded>
2 == 2
</Expanded>
</Expression>
<OverallResults successes="3" failures="0" expectedFailures="0"/>
</Section>
<Section name="free swap" filename="tests/<exe-name>/IntrospectiveTests/UniquePtr.tests.cpp" >
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/IntrospectiveTests/UniquePtr.tests.cpp" >
<Original>
*ptr1 == 2
</Original>
<Expanded>
2 == 2
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/IntrospectiveTests/UniquePtr.tests.cpp" >
<Original>
*ptr2 == 1
</Original>
<Expanded>
1 == 1
</Expanded>
</Expression>
<OverallResults successes="2" failures="0" expectedFailures="0"/>
</Section>
<OverallResult success="true"/>
</TestCase>
<TestCase name="vec&lt;vec&lt;string,alloc>> -> toString" tags="[toString][vector,allocator]" filename="tests/<exe-name>/UsageTests/ToStringVector.tests.cpp" >
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/UsageTests/ToStringVector.tests.cpp" >
<Original>
@ -17756,7 +18031,7 @@ loose text artifact
</Section>
<OverallResult success="true"/>
</TestCase>
<OverallResults successes="1744" failures="149" expectedFailures="21"/>
<OverallResults successes="1772" failures="149" expectedFailures="21"/>
</Group>
<OverallResults successes="1744" failures="148" expectedFailures="21"/>
<OverallResults successes="1772" failures="148" expectedFailures="21"/>
</Catch>

View File

@ -313,7 +313,7 @@ TEST_CASE("GENERATE capture macros", "[generators][internals][approvals]") {
non_copyable nc; nc.value = value;
// neither `GENERATE_COPY` nor plain `GENERATE` would compile here
auto value2 = GENERATE_REF(Catch::Generators::GeneratorWrapper<int>(std::unique_ptr<Catch::Generators::IGenerator<int>>(new TestGen(nc))));
auto value2 = GENERATE_REF(Catch::Generators::GeneratorWrapper<int>(Catch::Detail::make_unique<TestGen>(nc)));
REQUIRE(value == value2);
}

View File

@ -34,7 +34,7 @@ TEST_CASE( "parseEnums", "[Strings][enums]" ) {
TEST_CASE( "Directly creating an EnumInfo" ) {
using namespace Catch::Detail;
std::unique_ptr<EnumInfo> enumInfo = makeEnumInfo( "EnumName", "EnumName::Value1, EnumName::Value2", {0, 1} );
auto enumInfo = makeEnumInfo( "EnumName", "EnumName::Value1, EnumName::Value2", {0, 1} );
CHECK( enumInfo->lookup(0) == "Value1" );
CHECK( enumInfo->lookup(1) == "Value2" );

View File

@ -0,0 +1,133 @@
#include <catch2/catch_test_macros.hpp>
#include <catch2/internal/catch_unique_ptr.hpp>
#include <tuple>
namespace {
struct unique_ptr_test_helper {
bool dummy = false;
};
} // end unnamed namespace
TEST_CASE("unique_ptr reimplementation: basic functionality", "[internals][unique-ptr]") {
using Catch::Detail::unique_ptr;
SECTION("Default constructed unique_ptr is empty") {
unique_ptr<int> ptr;
REQUIRE_FALSE(ptr);
REQUIRE(ptr.get() == nullptr);
}
SECTION("Take ownership of allocation") {
auto naked_ptr = new int{ 0 };
unique_ptr<int> ptr(naked_ptr);
REQUIRE(ptr);
REQUIRE(*ptr == 0);
REQUIRE(ptr.get() == naked_ptr);
SECTION("Plain reset deallocates") {
ptr.reset(); // this makes naked_ptr dangling!
REQUIRE_FALSE(ptr);
REQUIRE(ptr.get() == nullptr);
}
SECTION("Reset replaces ownership") {
ptr.reset(new int{ 2 });
REQUIRE(ptr);
REQUIRE(ptr.get() != nullptr);
REQUIRE(*ptr == 2);
}
}
SECTION("Release releases ownership") {
auto naked_ptr = new int{ 1 };
unique_ptr<int> ptr(naked_ptr);
ptr.release();
CHECK_FALSE(ptr);
CHECK(ptr.get() == nullptr);
delete naked_ptr;
}
SECTION("Move constructor") {
unique_ptr<int> ptr1(new int{ 1 });
auto ptr2(std::move(ptr1));
REQUIRE_FALSE(ptr1);
REQUIRE(ptr2);
REQUIRE(*ptr2 == 1);
}
SECTION("Move assignment") {
unique_ptr<int> ptr1(new int{ 1 }), ptr2(new int{ 2 });
ptr1 = std::move(ptr2);
REQUIRE_FALSE(ptr2);
REQUIRE(ptr1);
REQUIRE(*ptr1 == 2);
}
SECTION("free swap") {
unique_ptr<int> ptr1(new int{ 1 }), ptr2(new int{ 2 });
swap(ptr1, ptr2);
REQUIRE(*ptr1 == 2);
REQUIRE(*ptr2 == 1);
}
}
namespace {
struct base {
int i;
base(int i) :i(i) {}
};
struct derived : base { using base::base; };
struct unrelated {};
} // end unnamed namespace
static_assert( std::is_constructible<Catch::Detail::unique_ptr<base>,
Catch::Detail::unique_ptr<derived>>::value, "Upcasting is supported");
static_assert(!std::is_constructible<Catch::Detail::unique_ptr<derived>,
Catch::Detail::unique_ptr<base>>::value, "Downcasting is not supported");
static_assert(!std::is_constructible<Catch::Detail::unique_ptr<base>,
Catch::Detail::unique_ptr<unrelated>>::value, "Cannot just convert one ptr type to another");
TEST_CASE("Upcasting special member functions", "[internals][unique-ptr]") {
using Catch::Detail::unique_ptr;
unique_ptr<derived> dptr(new derived{3});
SECTION("Move constructor") {
unique_ptr<base> bptr(std::move(dptr));
REQUIRE(bptr->i == 3);
}
SECTION("move assignment") {
unique_ptr<base> bptr(new base{ 1 });
bptr = std::move(dptr);
REQUIRE(bptr->i == 3);
}
}
namespace {
struct move_detector {
bool has_moved = false;
move_detector() = default;
move_detector(move_detector const& rhs) = default;
move_detector& operator=(move_detector const& rhs) = default;
move_detector(move_detector&& rhs) {
rhs.has_moved = true;
}
move_detector& operator=(move_detector&& rhs) {
rhs.has_moved = true;
return *this;
}
};
} // end unnamed namespace
TEST_CASE("make_unique reimplementation", "[internals][unique-ptr]") {
using Catch::Detail::make_unique;
SECTION("From lvalue copies") {
move_detector lval;
auto ptr = make_unique<move_detector>(lval);
REQUIRE_FALSE(lval.has_moved);
}
SECTION("From rvalue moves") {
move_detector rval;
auto ptr = make_unique<move_detector>(std::move(rval));
REQUIRE(rval.has_moved);
}
SECTION("Variadic constructor") {
auto ptr = make_unique<std::tuple<int, double, int>>(1, 2., 3);
REQUIRE(*ptr == std::tuple<int, double, int>{1, 2., 3});
}
}

View File

@ -16,6 +16,7 @@
#include <cerrno>
#include <limits>
#include <array>
#include <tuple>
namespace { namespace MiscTests {