From f58f206b7f4f6bf7eb67a3001083e97835dc0acc Mon Sep 17 00:00:00 2001 From: qicosmos Date: Wed, 27 Nov 2024 14:27:03 +0800 Subject: [PATCH] support span --- iguana/detail/traits.hpp | 16 ++++++++++++++++ iguana/json_reader.hpp | 14 +++++++++++++- iguana/util.hpp | 8 +++++++- test/unit_test.cpp | 17 +++++++++++++++++ 4 files changed, 53 insertions(+), 2 deletions(-) diff --git a/iguana/detail/traits.hpp b/iguana/detail/traits.hpp index a51941f8..062e1fb6 100644 --- a/iguana/detail/traits.hpp +++ b/iguana/detail/traits.hpp @@ -14,6 +14,12 @@ #include #include +#if __cplusplus > 201703L +#if __has_include() +#include +#endif +#endif + #include "iguana/define.h" namespace iguana { @@ -40,6 +46,16 @@ struct is_stdstring : is_template_instant_of {}; template struct is_tuple : is_template_instant_of {}; +#if __cplusplus > 201703L +#if __has_include() +template +struct is_span : std::false_type {}; + +template +struct is_span> : std::true_type {}; +#endif +#endif + template struct is_sequence_container : std::integral_constant< diff --git a/iguana/json_reader.hpp b/iguana/json_reader.hpp index 1485f2bb..768610dc 100644 --- a/iguana/json_reader.hpp +++ b/iguana/json_reader.hpp @@ -265,10 +265,22 @@ IGUANA_INLINE void from_json_impl(U &value, It &&it, It &&end) { } } +template +constexpr size_t get_array_size(const T &t) { +#if __cplusplus > 201703L +#if __has_include() + if constexpr (is_span::value) + return t.size(); + else +#endif +#endif + return sizeof(T) / sizeof(decltype(std::declval()[0])); +} + template , int> = 0> IGUANA_INLINE void from_json_impl(U &value, It &&it, It &&end) { using T = std::remove_reference_t; - constexpr auto n = sizeof(T) / sizeof(decltype(std::declval()[0])); + size_t n = get_array_size(value); skip_ws(it, end); if constexpr (std::is_same_v constexpr inline bool array_v = is_array>::value; template -constexpr inline bool fixed_array_v = c_array_v || array_v; +constexpr inline bool fixed_array_v = c_array_v || +#if __cplusplus > 201703L +#if __has_include() + is_span::value || +#endif +#endif + array_v; template constexpr inline bool string_view_v = diff --git a/test/unit_test.cpp b/test/unit_test.cpp index 92d265b4..c0bd2a1e 100644 --- a/test/unit_test.cpp +++ b/test/unit_test.cpp @@ -95,6 +95,23 @@ TEST_CASE("test parse item array_t") { CHECK(test[0] == 1); CHECK(test[1] == -222); } +#if __cplusplus > 201703L +#if __has_include() + { + std::vector v{1, 2}; + std::span span(v); + std::string str; + iguana::to_json(span, str); + + std::vector v1; + v1.resize(2); + std::span span1(v1); + + iguana::from_json(span1, str); + CHECK(v == v1); + } +#endif +#endif { std::string str{"[1, -222,"}; std::array test;