/ externals / catch / src / catch2 / internal / catch_enum_values_registry.cpp
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