diff options
| author | Martin Hořeňovský | 2026-04-08 10:26:57 +0200 |
|---|---|---|
| committer | Martin Hořeňovský | 2026-04-08 12:57:09 +0200 |
| commit | 47200ddbee03eaf4a9d3d99d18cb692381d8f5bc (patch) | |
| tree | ec947545e5f35b38ea5592c6fafcd7861081648c /src/catch2/internal | |
| parent | e51dcdcc595371828de2b1d28985e8d8c1895345 (diff) | |
| download | catch3-47200ddbee03eaf4a9d3d99d18cb692381d8f5bc.tar.gz | |
Rework internals of CATCH_REGISTER_ENUM
The old internals reached into the global hub to stash the allocation(s)
for enum value -> string value there, then kept around a potentially
invalid (in case the hub was cleaned up) reference into it, going through
whole bunch of virtual dispatch in the process.
The new internals just store the data in a static variable inside the
`StringMaker` specialization. This avoids potential lifetime issues,
avoids all virtual dispatch and (almost) reduces the include bloat in
the main header path.
The reason for (almost) there is that for full include correctness,
`EnumInfo` needs `<utility>` include for `std::pair`. However, this brings
in things like `std::relops`, because the std headers in C++ are dumb.
As this was not included before, and instead we relied on `std::pair`
existing in an internal stdlib header that we transitively included, the
full include size ends up bigger than before.
Diffstat (limited to 'src/catch2/internal')
| -rw-r--r-- | src/catch2/internal/catch_assertion_handler.cpp | 1 | ||||
| -rw-r--r-- | src/catch2/internal/catch_enum_info.cpp (renamed from src/catch2/internal/catch_enum_values_registry.cpp) | 28 | ||||
| -rw-r--r-- | src/catch2/internal/catch_enum_info.hpp | 48 | ||||
| -rw-r--r-- | src/catch2/internal/catch_enum_values_registry.hpp | 36 | ||||
| -rw-r--r-- | src/catch2/internal/catch_run_context.cpp | 1 |
5 files changed, 60 insertions, 54 deletions
diff --git a/src/catch2/internal/catch_assertion_handler.cpp b/src/catch2/internal/catch_assertion_handler.cpp index a0fcfcb4..5a4806e9 100644 --- a/src/catch2/internal/catch_assertion_handler.cpp +++ b/src/catch2/internal/catch_assertion_handler.cpp @@ -8,6 +8,7 @@ #include <catch2/internal/catch_assertion_handler.hpp> #include <catch2/interfaces/catch_interfaces_capture.hpp> #include <catch2/interfaces/catch_interfaces_config.hpp> +#include <catch2/interfaces/catch_interfaces_registry_hub.hpp> #include <catch2/internal/catch_context.hpp> #include <catch2/internal/catch_debugger.hpp> #include <catch2/internal/catch_test_failure_exception.hpp> diff --git a/src/catch2/internal/catch_enum_values_registry.cpp b/src/catch2/internal/catch_enum_info.cpp index a94b6088..0793abd9 100644 --- a/src/catch2/internal/catch_enum_values_registry.cpp +++ b/src/catch2/internal/catch_enum_info.cpp @@ -5,15 +5,14 @@ // https://www.boost.org/LICENSE_1_0.txt) // SPDX-License-Identifier: BSL-1.0 -#include <catch2/internal/catch_enum_values_registry.hpp> + +#include <catch2/internal/catch_enum_info.hpp> #include <catch2/internal/catch_string_manip.hpp> #include <cassert> namespace Catch { - IMutableEnumValuesRegistry::~IMutableEnumValuesRegistry() = default; - namespace Detail { namespace { @@ -39,9 +38,7 @@ namespace Catch { return parsed; } - EnumInfo::~EnumInfo() = default; - - StringRef EnumInfo::lookup( int value ) const { + StringRef EnumInfo::lookup( int64_t value ) const { for( auto const& valueToName : m_values ) { if( valueToName.first == value ) return valueToName.second; @@ -49,25 +46,20 @@ namespace Catch { return "{** unexpected enum value **}"_sr; } - 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() ); + EnumInfo makeEnumInfo( StringRef enumName, StringRef allValueNames, std::vector<int64_t> const& values ) { + EnumInfo enumInfo; + enumInfo.m_name = enumName; + enumInfo.m_values.reserve( values.size() ); const auto valueNames = Catch::Detail::parseEnums( allValueNames ); assert( valueNames.size() == values.size() ); - std::size_t i = 0; - for( auto value : values ) - enumInfo->m_values.emplace_back(value, valueNames[i++]); + for (size_t i = 0; i < values.size(); ++i) { + enumInfo.m_values.emplace_back( values[i], valueNames[i] ); + } return enumInfo; } - EnumInfo const& EnumValuesRegistry::registerEnum( StringRef enumName, StringRef allValueNames, std::vector<int> const& values ) { - m_enumInfos.push_back(makeEnumInfo(enumName, allValueNames, values)); - return *m_enumInfos.back(); - } - } // Detail } // Catch diff --git a/src/catch2/internal/catch_enum_info.hpp b/src/catch2/internal/catch_enum_info.hpp new file mode 100644 index 00000000..b3036a82 --- /dev/null +++ b/src/catch2/internal/catch_enum_info.hpp @@ -0,0 +1,48 @@ + +// 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_ENUM_INFO_HPP_INCLUDED +#define CATCH_ENUM_INFO_HPP_INCLUDED + +#include <catch2/internal/catch_stringref.hpp> + +#include <cstdint> +#include <utility> +#include <vector> + +namespace Catch { + namespace Detail { + + struct EnumInfo { + StringRef m_name; + std::vector<std::pair<int64_t, StringRef>> m_values; + + StringRef lookup( int64_t value ) const; + }; + + EnumInfo makeEnumInfo( StringRef enumName, + StringRef allValueNames, + std::vector<int64_t> const& values ); + template <typename E> + Detail::EnumInfo makeEnumInfo( StringRef enumName, + StringRef allEnums, + std::initializer_list<E> values ) { + static_assert( sizeof( int64_t ) >= sizeof( E ), + "Cannot serialize enum to int64_t" ); + std::vector<int64_t> intValues; + intValues.reserve( values.size() ); + for ( auto enumValue : values ) + intValues.push_back( static_cast<int64_t>( enumValue ) ); + return makeEnumInfo( enumName, allEnums, intValues ); + } + + std::vector<StringRef> parseEnums( StringRef enums ); + + } // namespace Detail +} // namespace Catch + +#endif // CATCH_ENUM_INFO_HPP_INCLUDED diff --git a/src/catch2/internal/catch_enum_values_registry.hpp b/src/catch2/internal/catch_enum_values_registry.hpp deleted file mode 100644 index 7b5e7a72..00000000 --- a/src/catch2/internal/catch_enum_values_registry.hpp +++ /dev/null @@ -1,36 +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_ENUM_VALUES_REGISTRY_HPP_INCLUDED -#define CATCH_ENUM_VALUES_REGISTRY_HPP_INCLUDED - -#include <catch2/interfaces/catch_interfaces_enum_values_registry.hpp> -#include <catch2/internal/catch_unique_ptr.hpp> -#include <catch2/internal/catch_stringref.hpp> - -#include <vector> - -namespace Catch { - - namespace Detail { - - Catch::Detail::unique_ptr<EnumInfo> makeEnumInfo( StringRef enumName, StringRef allValueNames, std::vector<int> const& values ); - - class EnumValuesRegistry final : public IMutableEnumValuesRegistry { - - std::vector<Catch::Detail::unique_ptr<EnumInfo>> m_enumInfos; - - EnumInfo const& registerEnum( StringRef enumName, StringRef allValueNames, std::vector<int> const& values) override; - }; - - std::vector<StringRef> parseEnums( StringRef enums ); - - } // Detail - -} // Catch - -#endif // CATCH_ENUM_VALUES_REGISTRY_HPP_INCLUDED diff --git a/src/catch2/internal/catch_run_context.cpp b/src/catch2/internal/catch_run_context.cpp index 547ff9d8..e7e22c58 100644 --- a/src/catch2/internal/catch_run_context.cpp +++ b/src/catch2/internal/catch_run_context.cpp @@ -11,6 +11,7 @@ #include <catch2/generators/catch_generators_throw.hpp> #include <catch2/interfaces/catch_interfaces_config.hpp> #include <catch2/interfaces/catch_interfaces_generatortracker.hpp> +#include <catch2/interfaces/catch_interfaces_registry_hub.hpp> #include <catch2/interfaces/catch_interfaces_reporter.hpp> #include <catch2/internal/catch_compiler_capabilities.hpp> #include <catch2/internal/catch_context.hpp> |