仅是一个原型,留作记录。我感觉可以写出非常逆天的代码。
#include <array>
#include <string>
#include <map>
#include <tuple>
#include <string_view>
template <size_t key_name_length>
struct key_name_t
{
std::array<char16_t, key_name_length> name;
constexpr key_name_t(const char16_t(&name)[key_name_length])
{
for (size_t i = 0; i < key_name_length; i++)
this->name[i] = name[i];
}
constexpr operator std::u16string_view() const
{
return { name.begin(), name.end() - (name.back() == 0) };
}
};
template <key_name_t key_name, typename T>
class key_name_with_type
{
public:
using type = T;
};
template <key_name_t key_name, typename T>
using key_name_with_type_t = key_name_with_type<key_name, T>::type;
template <key_name_t ...key_names>
class value_t : public std::tuple<key_name_with_type_t<key_names, std::u16string>...>
{
private:
using value_tuple_t = std::tuple<key_name_with_type_t<key_names, std::u16string>...>;
static constexpr auto key_name_tuple = std::tuple{ key_names... };
static constexpr size_t size = std::tuple_size_v<value_tuple_t>;
private:
template<class map_t, size_t index>
void _serialize(map_t& map, std::index_sequence<index>) const
{
map[map_t::key_type(std::get<index>(key_name_tuple))] = std::get<index>(*this);
}
template<class map_t, size_t current_index, size_t ...rest_index>
void _serialize(map_t& map, std::index_sequence<current_index, rest_index...>) const
{
_serialize(map, std::index_sequence<current_index>());
_serialize(map, std::index_sequence<rest_index...>());
}
public:
template<class map_t>
void serialize(map_t& map) const
{
constexpr size_t size = std::tuple_size_v<std::tuple<key_name_with_type_t<key_names, std::u16string>...>>;
_serialize(map, std::make_index_sequence<size>());
}
private:
template<class map_t, size_t index>
void _deserialize(const map_t& map, std::index_sequence<index>)
{
std::get<index>(*this) = map.at(map_t::key_type(std::get<index>(key_name_tuple)));
}
template<class map_t, size_t current_index, size_t ...rest_index>
void _deserialize(const map_t& map, std::index_sequence<current_index, rest_index...>)
{
_deserialize(map, std::index_sequence<current_index>());
_deserialize(map, std::index_sequence<rest_index...>());
}
public:
template<class map_t>
void deserialize(const map_t& map)
{
_deserialize(map, std::make_index_sequence<size>());
}
public:
static constexpr size_t npos = std::numeric_limits<size_t>::max();
private:
template<size_t index>
static constexpr size_t _key_index(std::u16string_view key, std::index_sequence<index>)
{
if (key == std::get<index>(key_name_tuple))
return index;
return npos;
}
template<size_t current_index, size_t ...rest_index>
static constexpr size_t _key_index(std::u16string_view key, std::index_sequence<current_index, rest_index...>)
{
size_t result = _key_index(key, std::index_sequence<current_index>());
if (result != npos)
return result;
return _key_index(key, std::index_sequence<rest_index...>());
}
public:
static constexpr size_t key_index(std::u16string_view key)
{
return _key_index(key, std::make_index_sequence<size>());
}
public:
template<key_name_t key>
auto& get()
{
return std::get<key_index(key)>(*this);
}
};
using record_t = value_t<u"Key1", u"Key2", u"Key_3">;
int main()
{
record_t r;
std::map<std::u16string, std::u16string, std::less< >> map;
r.serialize(map);
map.at(u"Key2") = u"123";
r.deserialize(map);
auto test1 = std::get<1>(r);
auto test2 = r.get<u"Key2">();
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)