catch_enum_values_registry.cpp
1 2 // Copyright Catch2 Authors 3 // Distributed under the Boost Software License, Version 1.0. 4 // (See accompanying file LICENSE.txt or copy at 5 // https://www.boost.org/LICENSE_1_0.txt) 6 7 // SPDX-License-Identifier: BSL-1.0 8 #include <catch2/internal/catch_enum_values_registry.hpp> 9 #include <catch2/internal/catch_string_manip.hpp> 10 11 #include <cassert> 12 13 namespace Catch { 14 15 IMutableEnumValuesRegistry::~IMutableEnumValuesRegistry() = default; 16 17 namespace Detail { 18 19 namespace { 20 // Extracts the actual name part of an enum instance 21 // In other words, it returns the Blue part of Bikeshed::Colour::Blue 22 StringRef extractInstanceName(StringRef enumInstance) { 23 // Find last occurrence of ":" 24 size_t name_start = enumInstance.size(); 25 while (name_start > 0 && enumInstance[name_start - 1] != ':') { 26 --name_start; 27 } 28 return enumInstance.substr(name_start, enumInstance.size() - name_start); 29 } 30 } 31 32 std::vector<StringRef> parseEnums( StringRef enums ) { 33 auto enumValues = splitStringRef( enums, ',' ); 34 std::vector<StringRef> parsed; 35 parsed.reserve( enumValues.size() ); 36 for( auto const& enumValue : enumValues ) { 37 parsed.push_back(trim(extractInstanceName(enumValue))); 38 } 39 return parsed; 40 } 41 42 EnumInfo::~EnumInfo() = default; 43 44 StringRef EnumInfo::lookup( int value ) const { 45 for( auto const& valueToName : m_values ) { 46 if( valueToName.first == value ) 47 return valueToName.second; 48 } 49 return "{** unexpected enum value **}"_sr; 50 } 51 52 Catch::Detail::unique_ptr<EnumInfo> makeEnumInfo( StringRef enumName, StringRef allValueNames, std::vector<int> const& values ) { 53 auto enumInfo = Catch::Detail::make_unique<EnumInfo>(); 54 enumInfo->m_name = enumName; 55 enumInfo->m_values.reserve( values.size() ); 56 57 const auto valueNames = Catch::Detail::parseEnums( allValueNames ); 58 assert( valueNames.size() == values.size() ); 59 std::size_t i = 0; 60 for( auto value : values ) 61 enumInfo->m_values.emplace_back(value, valueNames[i++]); 62 63 return enumInfo; 64 } 65 66 EnumInfo const& EnumValuesRegistry::registerEnum( StringRef enumName, StringRef allValueNames, std::vector<int> const& values ) { 67 m_enumInfos.push_back(makeEnumInfo(enumName, allValueNames, values)); 68 return *m_enumInfos.back(); 69 } 70 71 } // Detail 72 } // Catch 73