in include/ylt/struct_pack/type_calculate.hpp [195:306]
constexpr decltype(auto) get_type_literal() {
if constexpr (is_trivial_view_v<Arg>) {
return get_type_literal<typename Arg::value_type, ParentArgs...>();
}
else if constexpr (user_defined_serialization<Arg>) {
constexpr auto begin = string_literal<char, 1>{
{static_cast<char>(type_id::user_defined_type)}};
constexpr auto end =
string_literal<char, 1>{{static_cast<char>(type_id::type_end_flag)}};
if constexpr (user_defined_type_name<Arg>) {
constexpr auto type_name = sp_set_type_name((Arg *)nullptr);
string_literal<char, type_name.size()> ret{type_name};
return begin + ret + end;
}
else {
constexpr auto type_name = type_string<Arg>();
string_literal<char, type_name.size()> ret{type_name};
return begin + ret + end;
}
}
else {
constexpr std::size_t has_cycle = check_circle<Arg, ParentArgs...>();
if constexpr (has_cycle != 0) {
static_assert(has_cycle >= 2);
return string_literal<char, 1>{
{static_cast<char>(type_id::circle_flag)}} +
get_size_literal<has_cycle - 2>();
}
else {
constexpr auto parent_tag = get_parent_tag<ParentArgs...>();
constexpr auto id = get_type_id<Arg, parent_tag>();
constexpr auto begin = string_literal<char, 1>{{static_cast<char>(id)}};
if constexpr (id == type_id::struct_t) {
using Args = decltype(get_types<Arg>());
constexpr auto end = get_type_end_flag<Arg>();
constexpr auto body = get_type_literal<Args, Arg, ParentArgs...>(
std::make_index_sequence<std::tuple_size_v<Args>>());
if constexpr (is_trivial_serializable<Arg, true>::value) {
static_assert(
align::pack_alignment_v<Arg> <= align::alignment_v<Arg>,
"If you add #pragma_pack to a struct, please specify the "
"struct_pack::pack_alignment_v<T>.");
return begin + body +
get_size_literal<align::pack_alignment_v<Arg>>() +
get_size_literal<align::alignment_v<Arg>>() + end;
}
else {
return begin + body + end;
}
}
else if constexpr (id == type_id::variant_t) {
constexpr auto sz = std::variant_size_v<Arg>;
static_assert(sz > 0, "empty param of std::variant is not allowed!");
static_assert(sz < 256, "too many alternative type in variant!");
constexpr auto body = get_variant_literal<Arg, ParentArgs...>(
std::make_index_sequence<std::variant_size_v<Arg>>());
constexpr auto end = string_literal<char, 1>{
{static_cast<char>(type_id::type_end_flag)}};
return begin + body + end;
}
else if constexpr (id == type_id::array_t) {
constexpr auto sz = get_array_size<Arg>();
static_assert(sz > 0, "The array's size must greater than zero!");
return begin +
get_type_literal<
remove_cvref_t<decltype(std::declval<Arg>()[0])>, Arg,
ParentArgs...>() +
get_size_literal<sz>();
}
else if constexpr (id == type_id::bitset_t) {
constexpr auto sz = get_array_size<Arg>();
static_assert(sz > 0, "The array's size must greater than zero!");
return begin + get_size_literal<sz>();
}
else if constexpr (unique_ptr<Arg>) {
return begin +
get_type_literal<remove_cvref_t<typename Arg::element_type>, Arg,
ParentArgs...>();
}
else if constexpr (id == type_id::container_t ||
id == type_id::optional_t || id == type_id::string_t) {
return begin +
get_type_literal<remove_cvref_t<typename Arg::value_type>, Arg,
ParentArgs...>();
}
else if constexpr (id == type_id::set_container_t) {
return begin + get_type_literal<remove_cvref_t<typename Arg::key_type>,
Arg, ParentArgs...>();
}
else if constexpr (id == type_id::map_container_t) {
return begin +
get_type_literal<remove_cvref_t<typename Arg::key_type>, Arg,
ParentArgs...>() +
get_type_literal<remove_cvref_t<typename Arg::mapped_type>, Arg,
ParentArgs...>();
}
else if constexpr (id == type_id::expected_t) {
return begin +
get_type_literal<remove_cvref_t<typename Arg::value_type>, Arg,
ParentArgs...>() +
get_type_literal<remove_cvref_t<typename Arg::error_type>, Arg,
ParentArgs...>();
}
else if constexpr (id != type_id::compatible_t) {
return begin;
}
else {
return string_literal<char, 0>{};
}
}
}
}