ClickHouse/src/DataTypes/EnumValues.h

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

97 lines
2.5 KiB
C++
Raw Normal View History

2021-03-09 14:10:28 +00:00
#pragma once
#include <unordered_map>
2021-05-06 13:07:36 +00:00
#include <Common/HashTable/HashMap.h>
#include <Common/NamePrompter.h>
2021-03-09 14:10:28 +00:00
namespace DB
{
2023-12-19 16:43:30 +00:00
namespace ErrorCodesEnumValues
2021-03-09 14:10:28 +00:00
{
extern const int BAD_ARGUMENTS;
}
template <typename T>
2023-09-10 03:48:12 +00:00
class EnumValues : public IHints<>
2021-03-09 14:10:28 +00:00
{
public:
using Value = std::pair<std::string, T>;
using Values = std::vector<Value>;
using NameToValueMap = HashMap<StringRef, T, StringRefHash>;
using ValueToNameMap = std::unordered_map<T, StringRef>;
private:
Values values;
NameToValueMap name_to_value_map;
ValueToNameMap value_to_name_map;
void fillMaps();
public:
explicit EnumValues(const Values & values_);
2021-03-09 14:10:28 +00:00
const Values & getValues() const { return values; }
auto findByValue(const T & value) const
{
const auto it = value_to_name_map.find(value);
if (it == std::end(value_to_name_map))
throw Exception(ErrorCodes::BAD_ARGUMENTS, "Unexpected value {} in enum", toString(value));
2021-03-09 14:10:28 +00:00
return it;
}
2023-12-19 16:43:30 +00:00
bool hasValue(const T & value) const
{
return value_to_name_map.contains(value);
}
/// throws exception if value is not valid
2021-03-09 14:10:28 +00:00
const StringRef & getNameForValue(const T & value) const
{
return findByValue(value)->second;
}
/// returns false if value is not valid
bool getNameForValue(const T & value, StringRef & result) const
{
const auto it = value_to_name_map.find(value);
if (it == std::end(value_to_name_map))
return false;
result = it->second;
return true;
}
2021-03-09 14:10:28 +00:00
T getValue(StringRef field_name, bool try_treat_as_id = false) const;
2023-12-19 16:43:30 +00:00
bool tryGetValue(T & x, StringRef field_name, bool try_treat_as_id = false) const;
2021-03-09 14:10:28 +00:00
template <typename TValues>
bool containsAll(const TValues & rhs_values) const
{
auto check = [&](const auto & value)
{
auto it = name_to_value_map.find(value.first);
/// If we don't have this name, than we have to be sure,
/// that this value exists in enum
if (it == name_to_value_map.end())
return value_to_name_map.count(value.second) > 0;
/// If we have this name, than it should have the same value
return it->value.second == value.second;
};
return std::all_of(rhs_values.begin(), rhs_values.end(), check);
}
2021-05-06 13:07:36 +00:00
Names getAllRegisteredNames() const override;
std::unordered_set<String> getSetOfAllNames(bool to_lower) const;
std::unordered_set<T> getSetOfAllValues() const;
2021-03-09 14:10:28 +00:00
};
}