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