Unify IMutableEnumRegistry and EnumValuesRegistry

This time there was no need for compilation firewall, so we keep
everything inlined.
This commit is contained in:
Martin Hořeňovský 2023-03-14 16:28:30 +01:00
parent ceb7ab6b20
commit 31b291ba26
No known key found for this signature in database
GPG Key ID: DE48307B8B0D381A
9 changed files with 70 additions and 87 deletions

View File

@ -210,7 +210,6 @@ set(INTERFACE_HEADERS
${SOURCES_DIR}/interfaces/catch_interfaces_all.hpp ${SOURCES_DIR}/interfaces/catch_interfaces_all.hpp
${SOURCES_DIR}/interfaces/catch_interfaces_capture.hpp ${SOURCES_DIR}/interfaces/catch_interfaces_capture.hpp
${SOURCES_DIR}/interfaces/catch_interfaces_config.hpp ${SOURCES_DIR}/interfaces/catch_interfaces_config.hpp
${SOURCES_DIR}/interfaces/catch_interfaces_enum_values_registry.hpp
${SOURCES_DIR}/interfaces/catch_interfaces_exception.hpp ${SOURCES_DIR}/interfaces/catch_interfaces_exception.hpp
${SOURCES_DIR}/interfaces/catch_interfaces_generatortracker.hpp ${SOURCES_DIR}/interfaces/catch_interfaces_generatortracker.hpp
${SOURCES_DIR}/interfaces/catch_interfaces_registry_hub.hpp ${SOURCES_DIR}/interfaces/catch_interfaces_registry_hub.hpp

View File

@ -71,7 +71,7 @@ namespace Catch {
CATCH_INTERNAL_ERROR("Attempted to register active exception under CATCH_CONFIG_DISABLE_EXCEPTIONS!"); CATCH_INTERNAL_ERROR("Attempted to register active exception under CATCH_CONFIG_DISABLE_EXCEPTIONS!");
#endif #endif
} }
IMutableEnumValuesRegistry& getMutableEnumValuesRegistry() override { EnumValuesRegistry& getMutableEnumValuesRegistry() override {
return m_enumValuesRegistry; return m_enumValuesRegistry;
} }
@ -81,7 +81,7 @@ namespace Catch {
ExceptionTranslatorRegistry m_exceptionTranslatorRegistry; ExceptionTranslatorRegistry m_exceptionTranslatorRegistry;
TagAliasRegistry m_tagAliasRegistry; TagAliasRegistry m_tagAliasRegistry;
StartupExceptionRegistry m_exceptionRegistry; StartupExceptionRegistry m_exceptionRegistry;
Detail::EnumValuesRegistry m_enumValuesRegistry; EnumValuesRegistry m_enumValuesRegistry;
}; };
} }

View File

@ -16,9 +16,9 @@
#include <catch2/internal/catch_compiler_capabilities.hpp> #include <catch2/internal/catch_compiler_capabilities.hpp>
#include <catch2/internal/catch_config_wchar.hpp> #include <catch2/internal/catch_config_wchar.hpp>
#include <catch2/internal/catch_stringref.hpp>
#include <catch2/internal/catch_reusable_string_stream.hpp> #include <catch2/internal/catch_reusable_string_stream.hpp>
#include <catch2/internal/catch_void_type.hpp> #include <catch2/internal/catch_void_type.hpp>
#include <catch2/interfaces/catch_interfaces_enum_values_registry.hpp>
#ifdef CATCH_CONFIG_CPP17_STRING_VIEW #ifdef CATCH_CONFIG_CPP17_STRING_VIEW
#include <string_view> #include <string_view>

View File

@ -24,7 +24,6 @@
#include <catch2/interfaces/catch_interfaces_capture.hpp> #include <catch2/interfaces/catch_interfaces_capture.hpp>
#include <catch2/interfaces/catch_interfaces_config.hpp> #include <catch2/interfaces/catch_interfaces_config.hpp>
#include <catch2/interfaces/catch_interfaces_enum_values_registry.hpp>
#include <catch2/interfaces/catch_interfaces_exception.hpp> #include <catch2/interfaces/catch_interfaces_exception.hpp>
#include <catch2/interfaces/catch_interfaces_generatortracker.hpp> #include <catch2/interfaces/catch_interfaces_generatortracker.hpp>
#include <catch2/interfaces/catch_interfaces_registry_hub.hpp> #include <catch2/interfaces/catch_interfaces_registry_hub.hpp>

View File

@ -1,47 +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_INTERFACES_ENUM_VALUES_REGISTRY_HPP_INCLUDED
#define CATCH_INTERFACES_ENUM_VALUES_REGISTRY_HPP_INCLUDED
#include <catch2/internal/catch_stringref.hpp>
#include <vector>
namespace Catch {
namespace Detail {
struct EnumInfo {
StringRef m_name;
std::vector<std::pair<int, StringRef>> m_values;
~EnumInfo();
StringRef lookup( int value ) const;
};
} // namespace Detail
class IMutableEnumValuesRegistry {
public:
virtual ~IMutableEnumValuesRegistry(); // = default;
virtual Detail::EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::vector<int> const& values ) = 0;
template<typename E>
Detail::EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::initializer_list<E> values ) {
static_assert(sizeof(int) >= sizeof(E), "Cannot serialize enum to int");
std::vector<int> intValues;
intValues.reserve( values.size() );
for( auto enumValue : values )
intValues.push_back( static_cast<int>( enumValue ) );
return registerEnum( enumName, allEnums, intValues );
}
};
} // Catch
#endif // CATCH_INTERFACES_ENUM_VALUES_REGISTRY_HPP_INCLUDED

View File

@ -23,7 +23,7 @@ namespace Catch {
class IReporterFactory; class IReporterFactory;
class ITagAliasRegistry; class ITagAliasRegistry;
class ITestInvoker; class ITestInvoker;
class IMutableEnumValuesRegistry; class EnumValuesRegistry;
struct SourceLineInfo; struct SourceLineInfo;
class StartupExceptionRegistry; class StartupExceptionRegistry;
@ -53,7 +53,7 @@ namespace Catch {
virtual void registerTranslator( Detail::unique_ptr<IExceptionTranslator>&& translator ) = 0; virtual void registerTranslator( Detail::unique_ptr<IExceptionTranslator>&& translator ) = 0;
virtual void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) = 0; virtual void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) = 0;
virtual void registerStartupException() noexcept = 0; virtual void registerStartupException() noexcept = 0;
virtual IMutableEnumValuesRegistry& getMutableEnumValuesRegistry() = 0; virtual EnumValuesRegistry& getMutableEnumValuesRegistry() = 0;
}; };
IRegistryHub const& getRegistryHub(); IRegistryHub const& getRegistryHub();

View File

@ -12,44 +12,47 @@
namespace Catch { namespace Catch {
IMutableEnumValuesRegistry::~IMutableEnumValuesRegistry() = default;
namespace Detail { namespace Detail {
namespace { namespace {
// Extracts the actual name part of an enum instance // Extracts the actual name part of an enum instance
// In other words, it returns the Blue part of Bikeshed::Colour::Blue // In other words, it returns the Blue part of
StringRef extractInstanceName(StringRef enumInstance) { // Bikeshed::Colour::Blue
static StringRef extractInstanceName( StringRef enumInstance ) {
// Find last occurrence of ":" // Find last occurrence of ":"
size_t name_start = enumInstance.size(); size_t name_start = enumInstance.size();
while (name_start > 0 && enumInstance[name_start - 1] != ':') { while ( name_start > 0 &&
enumInstance[name_start - 1] != ':' ) {
--name_start; --name_start;
} }
return enumInstance.substr(name_start, enumInstance.size() - name_start); return enumInstance.substr( name_start,
enumInstance.size() - name_start );
} }
} } // end unnamed namespace
std::vector<StringRef> parseEnums( StringRef enums ) { std::vector<StringRef> parseEnums( StringRef enums ) {
auto enumValues = splitStringRef( enums, ',' ); auto enumValues = splitStringRef( enums, ',' );
std::vector<StringRef> parsed; std::vector<StringRef> parsed;
parsed.reserve( enumValues.size() ); parsed.reserve( enumValues.size() );
for( auto const& enumValue : enumValues ) { for ( auto const& enumValue : enumValues ) {
parsed.push_back(trim(extractInstanceName(enumValue))); parsed.push_back( trim( extractInstanceName( enumValue ) ) );
} }
return parsed; return parsed;
} }
EnumInfo::~EnumInfo() {} EnumInfo::~EnumInfo() = default;
StringRef EnumInfo::lookup( int value ) const { StringRef EnumInfo::lookup( int value ) const {
for( auto const& valueToName : m_values ) { for ( auto const& valueToName : m_values ) {
if( valueToName.first == value ) if ( valueToName.first == value ) { return valueToName.second; }
return valueToName.second;
} }
return "{** unexpected enum value **}"_sr; return "{** unexpected enum value **}"_sr;
} }
Catch::Detail::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 ) {
auto enumInfo = Catch::Detail::make_unique<EnumInfo>(); auto enumInfo = Catch::Detail::make_unique<EnumInfo>();
enumInfo->m_name = enumName; enumInfo->m_name = enumName;
enumInfo->m_values.reserve( values.size() ); enumInfo->m_values.reserve( values.size() );
@ -57,17 +60,22 @@ namespace Catch {
const auto valueNames = Catch::Detail::parseEnums( allValueNames ); const auto valueNames = Catch::Detail::parseEnums( allValueNames );
assert( valueNames.size() == values.size() ); assert( valueNames.size() == values.size() );
std::size_t i = 0; std::size_t i = 0;
for( auto value : values ) for ( auto value : values ) {
enumInfo->m_values.emplace_back(value, valueNames[i++]); enumInfo->m_values.emplace_back( value, valueNames[i++] );
}
return enumInfo; return enumInfo;
} }
EnumInfo const& EnumValuesRegistry::registerEnum( StringRef enumName, StringRef allValueNames, std::vector<int> const& values ) { } // namespace Detail
m_enumInfos.push_back(makeEnumInfo(enumName, allValueNames, values));
return *m_enumInfos.back();
}
} // Detail Detail::EnumInfo const&
} // Catch EnumValuesRegistry::registerEnum( StringRef enumName,
StringRef allValueNames,
std::vector<int> const& values ) {
m_enumInfos.push_back(
Detail::makeEnumInfo( enumName, allValueNames, values ) );
return *m_enumInfos.back();
}
} // namespace Catch

View File

@ -8,29 +8,54 @@
#ifndef CATCH_ENUM_VALUES_REGISTRY_HPP_INCLUDED #ifndef CATCH_ENUM_VALUES_REGISTRY_HPP_INCLUDED
#define 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 <catch2/internal/catch_stringref.hpp>
#include <catch2/internal/catch_unique_ptr.hpp>
#include <vector> #include <vector>
namespace Catch { namespace Catch {
namespace Detail { namespace Detail {
struct EnumInfo {
StringRef m_name;
std::vector<std::pair<int, StringRef>> m_values;
Catch::Detail::unique_ptr<EnumInfo> makeEnumInfo( StringRef enumName, StringRef allValueNames, std::vector<int> const& values ); ~EnumInfo();
class EnumValuesRegistry : public IMutableEnumValuesRegistry { StringRef lookup( int value ) const;
std::vector<Catch::Detail::unique_ptr<EnumInfo>> m_enumInfos;
EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::vector<int> const& values) override;
}; };
Detail::unique_ptr<EnumInfo>
makeEnumInfo( StringRef enumName,
StringRef allValueNames,
std::vector<int> const& values );
std::vector<StringRef> parseEnums( StringRef enums ); std::vector<StringRef> parseEnums( StringRef enums );
} // Detail } // namespace Detail
} // Catch class EnumValuesRegistry {
std::vector<Catch::Detail::unique_ptr<Detail::EnumInfo>> m_enumInfos;
public:
Detail::EnumInfo const& registerEnum( StringRef enumName,
StringRef allEnums,
std::vector<int> const& values );
template <typename E>
Detail::EnumInfo const&
registerEnum( StringRef enumName,
StringRef allEnums,
std::initializer_list<E> values ) {
static_assert( sizeof( int ) >= sizeof( E ),
"Cannot serialize enum to int" );
std::vector<int> intValues;
intValues.reserve( values.size() );
for ( auto enumValue : values ) {
intValues.push_back( static_cast<int>( enumValue ) );
}
return registerEnum( enumName, allEnums, intValues );
}
};
} // namespace Catch
#endif // CATCH_ENUM_VALUES_REGISTRY_HPP_INCLUDED #endif // CATCH_ENUM_VALUES_REGISTRY_HPP_INCLUDED

View File

@ -58,7 +58,6 @@ internal_headers = [
'interfaces/catch_interfaces_all.hpp', 'interfaces/catch_interfaces_all.hpp',
'interfaces/catch_interfaces_capture.hpp', 'interfaces/catch_interfaces_capture.hpp',
'interfaces/catch_interfaces_config.hpp', 'interfaces/catch_interfaces_config.hpp',
'interfaces/catch_interfaces_enum_values_registry.hpp',
'interfaces/catch_interfaces_exception.hpp', 'interfaces/catch_interfaces_exception.hpp',
'interfaces/catch_interfaces_generatortracker.hpp', 'interfaces/catch_interfaces_generatortracker.hpp',
'interfaces/catch_interfaces_registry_hub.hpp', 'interfaces/catch_interfaces_registry_hub.hpp',