Просмотр исходного кода

feat: add wrapped type support

Sam Jaffe 2 лет назад
Родитель
Сommit
699a8b6776
2 измененных файлов с 17 добавлено и 3 удалено
  1. 6 0
      include/serializer/jsonizer.tpp
  2. 11 3
      include/serializer/traits.h

+ 6 - 0
include/serializer/jsonizer.tpp

@@ -81,6 +81,9 @@ template <typename T> Json::Value Jsonizer::to_json(T const & value) const {
       rval.append(to_json(elem));
     }
     return rval;
+  } else if constexpr (detail::is_wrapper_v<T>) {
+    using V = std::decay_t<typename T::value_type>;
+    return to_json(static_cast<V const &>(value));
   } else {
     return to_json_impl(value);
   }
@@ -145,6 +148,9 @@ void Jsonizer::from_json(T & value, Json::Value const & json) const {
     for (auto const & elem : json) {
       value.insert(value.end(), from_json<V>(elem));
     }
+  } else if constexpr (detail::is_wrapper_v<T>) {
+    using V = std::decay_t<typename T::value_type>;
+    value = from_json<V>(json);
   } else if constexpr (std::is_floating_point_v<T>) {
     value = static_cast<T>(json.asDouble());
   } else if constexpr (std::is_same_v<bool, T>) {

+ 11 - 3
include/serializer/traits.h

@@ -19,9 +19,14 @@ struct is_tuple<std::array<T, N>> : std::true_type {};
 template <typename... Ts>
 struct is_tuple<std::tuple<Ts...>> : std::true_type {};
 
+template <typename, typename = void> struct is_wrapper : std::false_type {};
+template <typename T>
+struct is_wrapper<T, std::void_t<typename T::value_type>> : std::true_type {};
+
 template <typename, typename = void> struct is_container : std::false_type {};
 template <typename T>
-struct is_container<T, std::void_t<typename T::value_type>> : std::true_type {};
+struct is_container<T, std::void_t<decltype(std::begin(std::declval<T>()))>>
+    : is_wrapper<T> {};
 
 template <typename, typename = void>
 struct is_associative_container : std::false_type {};
@@ -38,14 +43,17 @@ struct has_serial_type<T, std::void_t<typename T::serial_type>>
 template <typename, typename = void>
 struct is_dereferencable : std::false_type {};
 template <typename T>
-struct is_dereferencable<T, std::enable_if_t<!std::is_void_v<decltype(*T())>>> : std::true_type {};
+struct is_dereferencable<T, std::enable_if_t<!std::is_void_v<decltype(*T())>>>
+    : std::true_type {};
 
 template <typename T> constexpr bool is_tuple_v = is_tuple<T>{};
+template <typename T> constexpr bool is_wrapper_v = is_wrapper<T>{};
 template <typename T> constexpr bool is_container_v = is_container<T>{};
 template <typename T>
 constexpr bool is_associative_container_v =
     is_container_v<T> && is_associative_container<T>{};
 
 template <typename T> constexpr bool has_serial_type_v = has_serial_type<T>{};
-template <typename T> constexpr bool is_dereferencable_v = is_dereferencable<T>{};
+template <typename T>
+constexpr bool is_dereferencable_v = is_dereferencable<T>{};
 }