diff --git a/include/common/array.hpp b/include/common/array.hpp index 3ec8b7c..af6e2fb 100644 --- a/include/common/array.hpp +++ b/include/common/array.hpp @@ -74,6 +74,17 @@ class basic_array { } + template + basic_array(const std::tuple& tup) + { + foreach_tuple(tup, std::make_index_sequence>>()); + } + template + basic_array(std::pair pair) + : _array_data({ std::move(pair.first), std::move(pair.second) }) + { + } + ~basic_array() noexcept = default; bool empty() const noexcept { return _array_data.empty(); } @@ -104,6 +115,10 @@ class basic_array size_t Size, template typename fixed_array_t = std::array> fixed_array_t as_fixed_array() const; + template + std::tuple as_tuple() const; + template + std::pair as_pair() const; // Usage: get(key_1, key_2, ..., default_value); template @@ -180,6 +195,18 @@ class basic_array return as_fixed_array(); } + template + explicit operator std::tuple() const + { + return as_tuple(); + } + + template + explicit operator std::pair() const + { + return as_pair(); + } + template < typename jsonization_t, std::enable_if_t<_utils::has_from_json_in_member::value, bool> = @@ -217,6 +244,17 @@ class basic_array template auto get_helper(const value_t& default_value, size_t pos) const; + template + tuple_t as_tuple_templ() const; + template + void set_tuple(tuple_t& tup) const; + + template + void foreach_tuple(const Tuple& t, std::index_sequence) + { + (_array_data.emplace_back(std::get(t)), ...); + } + string_t format(size_t indent, size_t indent_times) const; private: @@ -379,6 +417,48 @@ inline fixed_array_t basic_array::as_fixed_array() cons return result; } +template +template +inline void basic_array::set_tuple(tuple_t& tup) const +{ + using elem_t = std::tuple_element_t; + + if constexpr (index > 0) { + set_tuple(tup); + } + + std::get(tup) = static_cast(at(index)); +} + +template +template +inline tuple_t basic_array::as_tuple_templ() const +{ + constexpr size_t tuple_size = std::tuple_size_v; + + if (size() != tuple_size) { + throw exception("Wrong array size"); + } + + tuple_t result; + set_tuple(result); + return result; +} + +template +template +inline std::tuple basic_array::as_tuple() const +{ + return as_tuple_templ>(); +} + +template +template +inline std::pair basic_array::as_pair() const +{ + return as_tuple_templ>(); +} + template template inline auto basic_array::get(key_then_default_value_t&&... keys_then_default_value) const diff --git a/include/common/value.hpp b/include/common/value.hpp index c78b7ae..439c5a7 100644 --- a/include/common/value.hpp +++ b/include/common/value.hpp @@ -122,6 +122,18 @@ class basic_value { } + template + basic_value(std::tuple&& tup) + : basic_value(basic_array(std::forward>(tup))) + { + } + + template + basic_value(std::pair&& pair) + : basic_value(basic_array(std::pair(pair))) + { + } + template < typename value_t, std::enable_if_t>, bool> = true> @@ -349,6 +361,18 @@ class basic_value return static_cast(static_cast>(*this)); } + template + explicit operator std::tuple() const + { + return as_array().template as_tuple(); + } + + template + explicit operator std::pair() const + { + return as_array().template as_pair(); + } + private: friend class basic_array; friend class basic_object; diff --git a/test/serializing_test.cpp b/test/serializing_test.cpp index 0a12b4f..72492d4 100644 --- a/test/serializing_test.cpp +++ b/test/serializing_test.cpp @@ -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(); + auto p = tuple_arr.as_pair(); + auto t2 = std::tuple(tuple_arr); + auto p2 = std::pair(tuple_arr); + json::value tuple_val = tuple_arr; + auto t3 = std::tuple(tuple_val); + auto p3 = std::tuple(tuple_val); + + auto new_tuple_arr = (json::array)t; + auto new_tuple_val = (json::value)t; + new_tuple_val.as>(); + new_tuple_val.as>(); + + auto new_pair_arr = (json::array)p; + auto new_pair_val = (json::value)p; + return true; }