text: // Copyright (C) 2018-2021 Intel Corporation
  // SPDX-License-Identifier: Apache-2.0
  //
  
  #pragma once
  
  #include <algorithm>
  #include <string>
  #include <utility>
  
  #include "ngraph/check.hpp"
  
  namespace ov {
  /// Uses a pairings defined by EnumTypes::get() to convert between strings
  /// and enum values.
  template <typename EnumType>
  class EnumNames {
  public:
      /// Converts strings to enum values
      static EnumType as_enum(const std::string& name) {
          auto to_lower = [](const std::string& s) {
              std::string rc = s;
              std::transform(rc.begin(), rc.end(), rc.begin(), [](char c) {
                  return static_cast<char>(::tolower(static_cast<int>(c)));
              });
              return rc;
          };
          for (const auto& p : get().m_string_enums) {
              if (to_lower(p.first) == to_lower(name)) {
                  return p.second;
              }
          }
          NGRAPH_CHECK(false, "\"", name, "\"", " is not a member of enum ", get().m_enum_name);
      }
  
      /// Converts enum values to strings
      static const std::string& as_string(EnumType e) {
          for (const auto& p : get().m_string_enums) {
              if (p.second == e) {
                  return p.first;
              }
          }
          NGRAPH_CHECK(false, " invalid member of enum ", get().m_enum_name);
      }
  
  private:
      /// Creates the mapping.
      EnumNames(const std::string& enum_name, const std::vector<std::pair<std::string, EnumType>> string_enums)
          : m_enum_name(enum_name),
            m_string_enums(string_enums) {}
  
      /// Must be defined to returns a singleton for each supported enum class
      static EnumNames<EnumType>& get();
  
      const std::string m_enum_name;
      std::vector<std::pair<std::string, EnumType>> m_string_enums;
  };
  
  /// Returns the enum value matching the string
  template <typename Type, typename Value>
  typename std::enable_if<std::is_convertible<Value, std::string>::value, Type>::type as_enum(const Value& value) {
      return EnumNames<Type>::as_enum(value);
  }
  
  /// Returns the string matching the enum value
  template <typename Value>
  const std::string& as_string(Value value) {
      return EnumNames<Value>::as_string(value);
  }
  }  // namespace ov
  