Files
scylladb/concrete_types.hh
Rafael Ávila de Espíndola 7f0a434cfa types: Move abstract_type visit to a header
Signed-off-by: Rafael Ávila de Espíndola <espindola@scylladb.com>
2019-08-14 16:25:43 -07:00

242 lines
9.4 KiB
C++

/*
* Copyright (C) 2019 ScyllaDB
*/
/*
* This file is part of Scylla.
*
* Scylla is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Scylla is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Scylla. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <seastar/net/inet_address.hh>
#include "types.hh"
#include "types/list.hh"
#include "types/map.hh"
#include "types/set.hh"
#include "types/tuple.hh"
#include "types/user.hh"
#include "utils/big_decimal.hh"
struct empty_type_impl final : public abstract_type {
empty_type_impl();
};
struct counter_type_impl final : public abstract_type {
counter_type_impl();
};
template <typename T>
struct simple_type_impl : public concrete_type<T> {
simple_type_impl(abstract_type::kind k, sstring name, std::optional<uint32_t> value_length_if_fixed);
};
template<typename T>
struct integer_type_impl : public simple_type_impl<T> {
integer_type_impl(abstract_type::kind k, sstring name, std::optional<uint32_t> value_length_if_fixed);
};
struct byte_type_impl final : public integer_type_impl<int8_t> {
byte_type_impl();
};
struct short_type_impl final : public integer_type_impl<int16_t> {
short_type_impl();
};
struct int32_type_impl final : public integer_type_impl<int32_t> {
int32_type_impl();
};
struct long_type_impl final : public integer_type_impl<int64_t> {
long_type_impl();
};
struct boolean_type_impl final : public simple_type_impl<bool> {
boolean_type_impl();
};
template <typename T>
struct floating_type_impl : public simple_type_impl<T> {
floating_type_impl(abstract_type::kind k, sstring name, std::optional<uint32_t> value_length_if_fixed);
};
struct double_type_impl final : public floating_type_impl<double> {
double_type_impl();
};
struct float_type_impl final : public floating_type_impl<float> {
float_type_impl();
};
struct decimal_type_impl final : public concrete_type<big_decimal> {
decimal_type_impl();
};
struct duration_type_impl final : public concrete_type<cql_duration> {
duration_type_impl();
};
struct timestamp_type_impl final : public simple_type_impl<db_clock::time_point> {
timestamp_type_impl();
};
struct simple_date_type_impl final : public simple_type_impl<uint32_t> {
simple_date_type_impl();
};
struct time_type_impl final : public simple_type_impl<int64_t> {
time_type_impl();
};
struct string_type_impl : public concrete_type<sstring> {
string_type_impl(kind k, sstring name);
};
struct ascii_type_impl final : public string_type_impl {
ascii_type_impl();
};
struct utf8_type_impl final : public string_type_impl {
utf8_type_impl();
};
struct bytes_type_impl final : public concrete_type<bytes> {
bytes_type_impl();
};
// This is the old version of timestamp_type_impl, but has been replaced as it
// wasn't comparing pre-epoch timestamps correctly. This is kept for backward
// compatibility but shouldn't be used in new code.
struct date_type_impl final : public concrete_type<db_clock::time_point> {
date_type_impl();
};
struct timeuuid_type_impl final : public concrete_type<utils::UUID> {
timeuuid_type_impl();
};
struct varint_type_impl final : public concrete_type<boost::multiprecision::cpp_int> {
varint_type_impl();
};
struct inet_addr_type_impl final : public concrete_type<seastar::net::inet_address> {
inet_addr_type_impl();
};
struct uuid_type_impl final : public concrete_type<utils::UUID> {
uuid_type_impl();
};
template <typename Func> using visit_ret_type = std::invoke_result_t<Func, const ascii_type_impl&>;
GCC6_CONCEPT(
template <typename Func> concept bool CanHandleAllTypes = requires(Func f) {
{ f(*static_cast<const ascii_type_impl*>(nullptr)) } -> visit_ret_type<Func>;
{ f(*static_cast<const boolean_type_impl*>(nullptr)) } -> visit_ret_type<Func>;
{ f(*static_cast<const byte_type_impl*>(nullptr)) } -> visit_ret_type<Func>;
{ f(*static_cast<const bytes_type_impl*>(nullptr)) } -> visit_ret_type<Func>;
{ f(*static_cast<const counter_type_impl*>(nullptr)) } -> visit_ret_type<Func>;
{ f(*static_cast<const date_type_impl*>(nullptr)) } -> visit_ret_type<Func>;
{ f(*static_cast<const decimal_type_impl*>(nullptr)) } -> visit_ret_type<Func>;
{ f(*static_cast<const double_type_impl*>(nullptr)) } -> visit_ret_type<Func>;
{ f(*static_cast<const duration_type_impl*>(nullptr)) } -> visit_ret_type<Func>;
{ f(*static_cast<const empty_type_impl*>(nullptr)) } -> visit_ret_type<Func>;
{ f(*static_cast<const float_type_impl*>(nullptr)) } -> visit_ret_type<Func>;
{ f(*static_cast<const inet_addr_type_impl*>(nullptr)) } -> visit_ret_type<Func>;
{ f(*static_cast<const int32_type_impl*>(nullptr)) } -> visit_ret_type<Func>;
{ f(*static_cast<const list_type_impl*>(nullptr)) } -> visit_ret_type<Func>;
{ f(*static_cast<const long_type_impl*>(nullptr)) } -> visit_ret_type<Func>;
{ f(*static_cast<const map_type_impl*>(nullptr)) } -> visit_ret_type<Func>;
{ f(*static_cast<const reversed_type_impl*>(nullptr)) } -> visit_ret_type<Func>;
{ f(*static_cast<const set_type_impl*>(nullptr)) } -> visit_ret_type<Func>;
{ f(*static_cast<const short_type_impl*>(nullptr)) } -> visit_ret_type<Func>;
{ f(*static_cast<const simple_date_type_impl*>(nullptr)) } -> visit_ret_type<Func>;
{ f(*static_cast<const time_type_impl*>(nullptr)) } -> visit_ret_type<Func>;
{ f(*static_cast<const timestamp_type_impl*>(nullptr)) } -> visit_ret_type<Func>;
{ f(*static_cast<const timeuuid_type_impl*>(nullptr)) } -> visit_ret_type<Func>;
{ f(*static_cast<const tuple_type_impl*>(nullptr)) } -> visit_ret_type<Func>;
{ f(*static_cast<const user_type_impl*>(nullptr)) } -> visit_ret_type<Func>;
{ f(*static_cast<const utf8_type_impl*>(nullptr)) } -> visit_ret_type<Func>;
{ f(*static_cast<const uuid_type_impl*>(nullptr)) } -> visit_ret_type<Func>;
{ f(*static_cast<const varint_type_impl*>(nullptr)) } -> visit_ret_type<Func>;
};
)
template<typename Func>
GCC6_CONCEPT(requires CanHandleAllTypes<Func>)
static inline visit_ret_type<Func> visit(const abstract_type& t, Func&& f) {
switch (t.get_kind()) {
case abstract_type::kind::ascii:
return f(*static_cast<const ascii_type_impl*>(&t));
case abstract_type::kind::boolean:
return f(*static_cast<const boolean_type_impl*>(&t));
case abstract_type::kind::byte:
return f(*static_cast<const byte_type_impl*>(&t));
case abstract_type::kind::bytes:
return f(*static_cast<const bytes_type_impl*>(&t));
case abstract_type::kind::counter:
return f(*static_cast<const counter_type_impl*>(&t));
case abstract_type::kind::date:
return f(*static_cast<const date_type_impl*>(&t));
case abstract_type::kind::decimal:
return f(*static_cast<const decimal_type_impl*>(&t));
case abstract_type::kind::double_kind:
return f(*static_cast<const double_type_impl*>(&t));
case abstract_type::kind::duration:
return f(*static_cast<const duration_type_impl*>(&t));
case abstract_type::kind::empty:
return f(*static_cast<const empty_type_impl*>(&t));
case abstract_type::kind::float_kind:
return f(*static_cast<const float_type_impl*>(&t));
case abstract_type::kind::inet:
return f(*static_cast<const inet_addr_type_impl*>(&t));
case abstract_type::kind::int32:
return f(*static_cast<const int32_type_impl*>(&t));
case abstract_type::kind::list:
return f(*static_cast<const list_type_impl*>(&t));
case abstract_type::kind::long_kind:
return f(*static_cast<const long_type_impl*>(&t));
case abstract_type::kind::map:
return f(*static_cast<const map_type_impl*>(&t));
case abstract_type::kind::reversed:
return f(*static_cast<const reversed_type_impl*>(&t));
case abstract_type::kind::set:
return f(*static_cast<const set_type_impl*>(&t));
case abstract_type::kind::short_kind:
return f(*static_cast<const short_type_impl*>(&t));
case abstract_type::kind::simple_date:
return f(*static_cast<const simple_date_type_impl*>(&t));
case abstract_type::kind::time:
return f(*static_cast<const time_type_impl*>(&t));
case abstract_type::kind::timestamp:
return f(*static_cast<const timestamp_type_impl*>(&t));
case abstract_type::kind::timeuuid:
return f(*static_cast<const timeuuid_type_impl*>(&t));
case abstract_type::kind::tuple:
return f(*static_cast<const tuple_type_impl*>(&t));
case abstract_type::kind::user:
return f(*static_cast<const user_type_impl*>(&t));
case abstract_type::kind::utf8:
return f(*static_cast<const utf8_type_impl*>(&t));
case abstract_type::kind::uuid:
return f(*static_cast<const uuid_type_impl*>(&t));
case abstract_type::kind::varint:
return f(*static_cast<const varint_type_impl*>(&t));
}
__builtin_unreachable();
}