catch_enum_values_registry.cpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  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. #include <map>
  12. #include <cassert>
  13. namespace Catch {
  14. IMutableEnumValuesRegistry::~IMutableEnumValuesRegistry() {}
  15. namespace Detail {
  16. namespace {
  17. // Extracts the actual name part of an enum instance
  18. // In other words, it returns the Blue part of Bikeshed::Colour::Blue
  19. StringRef extractInstanceName(StringRef enumInstance) {
  20. // Find last occurrence of ":"
  21. size_t name_start = enumInstance.size();
  22. while (name_start > 0 && enumInstance[name_start - 1] != ':') {
  23. --name_start;
  24. }
  25. return enumInstance.substr(name_start, enumInstance.size() - name_start);
  26. }
  27. }
  28. std::vector<StringRef> parseEnums( StringRef enums ) {
  29. auto enumValues = splitStringRef( enums, ',' );
  30. std::vector<StringRef> parsed;
  31. parsed.reserve( enumValues.size() );
  32. for( auto const& enumValue : enumValues ) {
  33. parsed.push_back(trim(extractInstanceName(enumValue)));
  34. }
  35. return parsed;
  36. }
  37. EnumInfo::~EnumInfo() {}
  38. StringRef EnumInfo::lookup( int value ) const {
  39. for( auto const& valueToName : m_values ) {
  40. if( valueToName.first == value )
  41. return valueToName.second;
  42. }
  43. return "{** unexpected enum value **}"_sr;
  44. }
  45. std::unique_ptr<EnumInfo> makeEnumInfo( StringRef enumName, StringRef allValueNames, std::vector<int> const& values ) {
  46. std::unique_ptr<EnumInfo> enumInfo( new EnumInfo );
  47. enumInfo->m_name = enumName;
  48. enumInfo->m_values.reserve( values.size() );
  49. const auto valueNames = Catch::Detail::parseEnums( allValueNames );
  50. assert( valueNames.size() == values.size() );
  51. std::size_t i = 0;
  52. for( auto value : values )
  53. enumInfo->m_values.emplace_back(value, valueNames[i++]);
  54. return enumInfo;
  55. }
  56. EnumInfo const& EnumValuesRegistry::registerEnum( StringRef enumName, StringRef allValueNames, std::vector<int> const& values ) {
  57. m_enumInfos.push_back(makeEnumInfo(enumName, allValueNames, values));
  58. return *m_enumInfos.back();
  59. }
  60. } // Detail
  61. } // Catch