Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: tuple serialization #60

Merged
merged 5 commits into from
Dec 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 80 additions & 0 deletions include/common/array.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,17 @@ class basic_array
{
}

template <typename... elem_ts>
basic_array(const std::tuple<elem_ts...>& tup)
{
foreach_tuple(tup, std::make_index_sequence<std::tuple_size_v<std::tuple<elem_ts...>>>());
}
template <typename first_t, typename second_t>
basic_array(std::pair<first_t, second_t> pair)
: _array_data({ std::move(pair.first), std::move(pair.second) })
{
}

~basic_array() noexcept = default;

bool empty() const noexcept { return _array_data.empty(); }
Expand Down Expand Up @@ -104,6 +115,10 @@ class basic_array
size_t Size,
template <typename, size_t> typename fixed_array_t = std::array>
fixed_array_t<value_t, Size> as_fixed_array() const;
template <typename... elem_ts>
std::tuple<elem_ts...> as_tuple() const;
template <typename first_t, typename second_t>
std::pair<first_t, second_t> as_pair() const;

// Usage: get(key_1, key_2, ..., default_value);
template <typename... key_then_default_value_t>
Expand Down Expand Up @@ -180,6 +195,18 @@ class basic_array
return as_fixed_array<value_t, Size, fixed_array_t>();
}

template <typename... elem_ts>
explicit operator std::tuple<elem_ts...>() const
{
return as_tuple<elem_ts...>();
}

template <typename elem1_t, typename elem2_t>
explicit operator std::pair<elem1_t, elem2_t>() const
{
return as_pair<elem1_t, elem2_t>();
}

template <
typename jsonization_t,
std::enable_if_t<_utils::has_from_json_in_member<jsonization_t, string_t>::value, bool> =
Expand Down Expand Up @@ -217,6 +244,17 @@ class basic_array
template <typename value_t>
auto get_helper(const value_t& default_value, size_t pos) const;

template <typename tuple_t>
tuple_t as_tuple_templ() const;
template <size_t index, typename tuple_t>
void set_tuple(tuple_t& tup) const;

template <typename Tuple, std::size_t... Is>
void foreach_tuple(const Tuple& t, std::index_sequence<Is...>)
{
(_array_data.emplace_back(std::get<Is>(t)), ...);
}

string_t format(size_t indent, size_t indent_times) const;

private:
Expand Down Expand Up @@ -379,6 +417,48 @@ inline fixed_array_t<value_t, Size> basic_array<string_t>::as_fixed_array() cons
return result;
}

template <typename string_t>
template <size_t index, typename tuple_t>
inline void basic_array<string_t>::set_tuple(tuple_t& tup) const
{
using elem_t = std::tuple_element_t<index, tuple_t>;

if constexpr (index > 0) {
set_tuple<index - 1>(tup);
}

std::get<index>(tup) = static_cast<elem_t>(at(index));
}

template <typename string_t>
template <typename tuple_t>
inline tuple_t basic_array<string_t>::as_tuple_templ() const
{
constexpr size_t tuple_size = std::tuple_size_v<tuple_t>;

if (size() != tuple_size) {
throw exception("Wrong array size");
}

tuple_t result;
set_tuple<tuple_size - 1>(result);
return result;
}

template <typename string_t>
template <typename... elem_ts>
inline std::tuple<elem_ts...> basic_array<string_t>::as_tuple() const
{
return as_tuple_templ<std::tuple<elem_ts...>>();
}

template <typename string_t>
template <typename first_t, typename second_t>
inline std::pair<first_t, second_t> basic_array<string_t>::as_pair() const
{
return as_tuple_templ<std::pair<first_t, second_t>>();
}

template <typename string_t>
template <typename... key_then_default_value_t>
inline auto basic_array<string_t>::get(key_then_default_value_t&&... keys_then_default_value) const
Expand Down
24 changes: 24 additions & 0 deletions include/common/value.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,18 @@ class basic_value
{
}

template <typename... elem_ts>
basic_value(std::tuple<elem_ts...>&& tup)
: basic_value(basic_array<string_t>(std::forward<std::tuple<elem_ts...>>(tup)))
{
}

template <typename elem1_t, typename elem2_t>
basic_value(std::pair<elem1_t, elem2_t>&& pair)
: basic_value(basic_array<string_t>(std::pair<elem1_t, elem2_t>(pair)))
{
}

template <
typename value_t,
std::enable_if_t<!std::is_convertible_v<value_t, basic_value<string_t>>, bool> = true>
Expand Down Expand Up @@ -349,6 +361,18 @@ class basic_value
return static_cast<enum_t>(static_cast<std::underlying_type_t<enum_t>>(*this));
}

template <typename... elem_ts>
explicit operator std::tuple<elem_ts...>() const
{
return as_array().template as_tuple<elem_ts...>();
}

template <typename elem1_t, typename elem2_t>
explicit operator std::pair<elem1_t, elem2_t>() const
{
return as_array().template as_pair<elem1_t, elem2_t>();
}

private:
friend class basic_array<string_t>;
friend class basic_object<string_t>;
Expand Down
19 changes: 19 additions & 0 deletions test/serializing_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,25 @@ bool jsonizing()
return false;
}

json::array tuple_arr;
tuple_arr.emplace_back(1);
tuple_arr.emplace_back("aaabbbccc");
auto t = tuple_arr.as_tuple<int, std::string>();
auto p = tuple_arr.as_pair<int, std::string>();
auto t2 = std::tuple<int, std::string>(tuple_arr);
auto p2 = std::pair<int, std::string>(tuple_arr);
json::value tuple_val = tuple_arr;
auto t3 = std::tuple<int, std::string>(tuple_val);
auto p3 = std::tuple<int, std::string>(tuple_val);

auto new_tuple_arr = (json::array)t;
auto new_tuple_val = (json::value)t;
new_tuple_val.as<std::tuple<int, std::string>>();
new_tuple_val.as<std::pair<int, std::string>>();

auto new_pair_arr = (json::array)p;
auto new_pair_val = (json::value)p;

return true;
}

Expand Down
Loading