#include "matador/utils/identifier.hpp" #include #include #include namespace matador::utils { namespace { inline const std::type_index& null_type_index() { static const std::type_index value{typeid(null_type_t)}; return value; } inline const std::type_index& i8_type_index() { static const std::type_index value{typeid(int8_t)}; return value; } inline const std::type_index& i16_type_index() { static const std::type_index value{typeid(int16_t)}; return value; } inline const std::type_index& i32_type_index() { static const std::type_index value{typeid(int32_t)}; return value; } inline const std::type_index& i64_type_index() { static const std::type_index value{typeid(int64_t)}; return value; } inline const std::type_index& u8_type_index() { static const std::type_index value{typeid(uint8_t)}; return value; } inline const std::type_index& u16_type_index() { static const std::type_index value{typeid(uint16_t)}; return value; } inline const std::type_index& u32_type_index() { static const std::type_index value{typeid(uint32_t)}; return value; } inline const std::type_index& u64_type_index() { static const std::type_index value{typeid(uint64_t)}; return value; } inline const std::type_index& string_type_index() { static const std::type_index value{typeid(std::string)}; return value; } } // namespace size_t detail::hash(const std::string &value) { return std::hash()(std::string_view(value)); } identifier::identifier() : value_(std::monostate{}) { } size_t identifier::type_rank(const value_type &value) { return value.index(); } std::type_index identifier::type_index_from_value(const value_type &value) { return std::visit([](const auto &v) -> std::type_index { using T = std::decay_t; if constexpr (std::is_same_v) { return null_type_index(); } else { return std::type_index(typeid(T)); } }, value); } const std::type_index &identifier::type_index() const { switch (value_.index()) { case 0: return null_type_index(); case 1: return i8_type_index(); case 2: return i16_type_index(); case 3: return i32_type_index(); case 4: return i64_type_index(); case 5: return u8_type_index(); case 6: return u16_type_index(); case 7: return u32_type_index(); case 8: return u64_type_index(); case 9: return string_type_index(); default: return null_type_index(); } } basic_type identifier::type_from_value(const value_type &value) { return std::visit([](const auto &v) -> basic_type { using T = std::decay_t; if constexpr (std::is_same_v) { return basic_type::Null; } else { return data_type_traits::type(1); } }, value); } identifier::identifier(std::nullptr_t) : value_(std::monostate{}) { } identifier::identifier(const char *value) : value_(value ? std::string(value) : std::string{}) { } identifier & identifier::operator=(const char *value) { value_ = value ? std::string(value) : std::string{}; return *this; } bool identifier::operator==(const identifier &x) const { return value_ == x.value_; } bool identifier::operator!=(const identifier &x) const { return !operator==(x); } identifier &identifier::operator=(std::nullptr_t) { value_ = std::monostate{}; return *this; } identifier &identifier::operator=(const std::string &value) { value_ = value; return *this; } identifier &identifier::operator=(const identifier &other) { if (this != &other) { value_ = other.value_; } return *this; } bool identifier::operator<(const identifier &x) const { if (value_.index() != x.value_.index()) { return value_.index() < x.value_.index(); } return std::visit([](const auto &lhs, const auto &rhs) -> bool { using L = std::decay_t; using R = std::decay_t; if constexpr (std::is_same_v) { return lhs < rhs; } else { return false; } }, value_, x.value_); } bool identifier::operator<=(const identifier &x) const { return operator==(x) || operator<(x); } bool identifier::operator>(const identifier &x) const { return !operator<=(x); } bool identifier::operator>=(const identifier &x) const { return !operator<(x); } std::string identifier::str() const { return std::visit([](const auto &v) -> std::string { using T = std::decay_t; if constexpr (std::is_same_v) { return identifier_type_traits::to_string(); } else if constexpr (std::is_same_v) { return identifier_type_traits::to_string(v); } else { return identifier_type_traits::to_string(v); } }, value_); } basic_type identifier::type() const { return type_from_value(value_); } bool identifier::is_integer() const { return std::holds_alternative(value_) || std::holds_alternative(value_) || std::holds_alternative(value_) || std::holds_alternative(value_) || std::holds_alternative(value_) || std::holds_alternative(value_) || std::holds_alternative(value_) || std::holds_alternative(value_); } bool identifier::is_varchar() const { return std::holds_alternative(value_); } bool identifier::is_null() const { return std::holds_alternative(value_); } bool identifier::is_valid() const { return std::visit([](const auto &v) -> bool { using T = std::decay_t; if constexpr (std::is_same_v) { return identifier_type_traits::is_valid(); } else { return identifier_type_traits::is_valid(v); } }, value_); } void identifier::clear() { value_ = std::monostate{}; } void identifier::serialize(identifier_serializer &s) const { std::visit([&s](const auto &v) { using T = std::decay_t; if constexpr (std::is_same_v) { null_type_t n{}; s.serialize(n, {}); } else { auto tmp = v; s.serialize(tmp, {}); } }, value_); } size_t identifier::hash() const { return std::visit([](const auto &v) -> size_t { using T = std::decay_t; if constexpr (std::is_same_v) { return std::hash{}(0); } else { return detail::hash(v); } }, value_); } std::ostream &operator<<(std::ostream &out, const identifier &id) { out << id.str(); return out; } size_t id_pk_hash::operator()(const identifier &id) const { return id.hash(); } } // namespace matador::utils