Skip to content

Commit

Permalink
feat: support std::array
Browse files Browse the repository at this point in the history
fix #46
  • Loading branch information
MistEO committed Mar 15, 2024
1 parent 2463cdb commit 8aa6708
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 1 deletion.
23 changes: 23 additions & 0 deletions include/common/array.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ class basic_array
bool all() const;
template <typename value_t, template <typename...> typename collection_t = std::vector>
collection_t<value_t> as_collection() const;
template <typename value_t, size_t Size>
std::array<value_t, Size> as_collection() const;

// Usage: get(key_1, key_2, ..., default_value);
template <typename... key_then_default_value_t>
Expand Down Expand Up @@ -155,6 +157,12 @@ class basic_array
return as_collection<value_t, collection_t>();
}

template <typename value_t, size_t Size>
explicit operator std::array<value_t, Size>() const
{
return as_collection<value_t, Size>();
}

template <
typename jsonization_t,
std::enable_if_t<_utils::has_from_json_in_member<jsonization_t, string_t>::value, bool> =
Expand Down Expand Up @@ -339,6 +347,21 @@ inline collection_t<value_t> basic_array<string_t>::as_collection() const
return result;
}

template <typename string_t>
template <typename value_t, size_t Size>
inline std::array<value_t, Size> basic_array<string_t>::as_collection() const
{
if (size() != Size) {
throw exception("Wrong array size");
}

std::array<value_t, Size> result;
for (size_t i = 0; i < Size; ++i) {
result.at(i) = _array_data.at(i).template as<value_t>();
}
return result;
}

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 @@ -69,6 +69,16 @@ constexpr bool is_collection = false;
template <typename T>
constexpr bool is_collection<T> = is_container<T> && !is_map<T>;

template <typename T, typename = void>
constexpr bool is_std_array = false;
template <typename T, size_t Size>
constexpr bool is_std_array<std::array<T, Size>> = true;

template <typename T, typename = void>
constexpr size_t std_array_size = 0;
template <typename T, size_t Size>
constexpr size_t std_array_size<std::array<T, Size>> = Size;

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

template <typename value_t, template <typename...> typename collection_t = std::vector>
collection_t<value_t> as_collection() const;
template <typename value_t, size_t Size>
std::array<value_t, Size> as_collection() const;
template <typename value_t, template <typename...> typename map_t = std::map>
map_t<string_t, value_t> as_map() const;

Expand Down Expand Up @@ -276,6 +278,12 @@ class basic_value
return as_collection<value_t, collection_t>();
}

template <typename value_t, size_t Size>
explicit operator std::array<value_t, Size>() const
{
return as_collection<value_t, Size>();
}

template <
typename value_t,
template <typename...> typename map_t = std::map,
Expand Down Expand Up @@ -491,6 +499,10 @@ inline bool basic_value<string_t>::is() const noexcept
else if constexpr (std::is_same_v<basic_array<string_t>, value_t>) {
return is_array();
}
else if constexpr (_utils::is_std_array<value_t>) {
return is_array() && all<typename value_t::value_type>()
&& as_array().size() == _utils::std_array_size<value_t>;
}
else if constexpr (_utils::is_collection<value_t>) {
return is_array() && all<typename value_t::value_type>();
}
Expand Down Expand Up @@ -922,6 +934,13 @@ inline collection_t<value_t> basic_value<string_t>::as_collection() const
return as_array().template as_collection<value_t, collection_t>();
}

template <typename string_t>
template <typename value_t, size_t Size>
inline std::array<value_t, Size> basic_value<string_t>::as_collection() const
{
return as_array().template as_collection<value_t, Size>();
}

template <typename string_t>
template <typename value_t, template <typename...> typename map_t>
inline map_t<string_t, value_t> basic_value<string_t>::as_map() const
Expand Down
25 changes: 24 additions & 1 deletion test/serializing_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -262,8 +262,9 @@ bool jsonizing()
std::string str3;
std::vector<double> vec;
std::unordered_map<std::string, std::list<std::map<std::string, std::deque<int>>>> map;
std::array<int, 5> arr;

MEO_JSONIZATION(str1, str2, str3, vec, map);
MEO_JSONIZATION(str1, str2, str3, vec, map, arr);
};

MyStruct mine;
Expand Down Expand Up @@ -313,5 +314,27 @@ bool jsonizing()
return false;
}

std::array<int, 10> stdarr { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
json::value jarr = stdarr;
std::array<int, 10> new_std_arr;
if (jarr.is<std::array<int, 10>>()) {
new_std_arr = jarr.as_collection<int, 10>();
}
else {
std::cerr << "error std::array" << std::endl;
return false;
}

if (new_std_arr.back() != 10) {
std::cerr << "error std::array value" << std::endl;
return false;
}

if (jarr.is<std::array<int, 5>>()) {
std::cerr << "error std::array size" << std::endl;
return false;

}

return true;
}

0 comments on commit 8aa6708

Please sign in to comment.