Skip to content

Commit

Permalink
feat: array as tuple
Browse files Browse the repository at this point in the history
  • Loading branch information
MistEO committed Sep 29, 2024
1 parent 676cb37 commit 66e09f5
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 0 deletions.
51 changes: 51 additions & 0 deletions include/common/array.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,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 @@ -217,6 +221,11 @@ 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;

string_t format(size_t indent, size_t indent_times) const;

private:
Expand Down Expand Up @@ -379,6 +388,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
10 changes: 10 additions & 0 deletions include/common/utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,16 @@ constexpr bool is_collection = false;
template <typename T>
constexpr bool is_collection<T> = is_container<T> && !is_map<T> && !is_fixed_array<T>;

template <typename T, template <typename...> typename Ref, typename = void>
constexpr bool is_specialization = false;
template <template <typename...> typename T, template <typename...> typename Ref, typename... Args>
constexpr bool is_specialization<T<Args...>, Ref> = std::is_same_v<T<Args...>, Ref<Args...>>;

template <typename T, typename = void>
constexpr bool is_tuple = false;
template <typename T>
constexpr bool is_tuple<T> = is_specialization<T, std::tuple> || is_specialization<T, std::pair>;

template <typename T>
class has_to_json_in_member
{
Expand Down
16 changes: 16 additions & 0 deletions include/common/value.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,14 @@ class basic_value
{
}

template <
typename tuple_t,
std::enable_if_t<_utils::is_specialization<tuple_t, std::tuple>, bool> = true>
basic_value(tuple_t&& tup)
: basic_value(basic_array<string_t>(std::forward<tuple_t>(tup)))
{
}

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 +357,14 @@ class basic_value
return static_cast<enum_t>(static_cast<std::underlying_type_t<enum_t>>(*this));
}

/*template <
typename tuple_t,
std::enable_if_t<_utils::is_specialization<tuple_t, std::tuple>, bool> = true>
explicit operator tuple_t() const
{
return as_array().as_tup
}*/

private:
friend class basic_array<string_t>;
friend class basic_object<string_t>;
Expand Down
6 changes: 6 additions & 0 deletions test/serializing_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,12 @@ 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>();

return true;
}

Expand Down

0 comments on commit 66e09f5

Please sign in to comment.