From 63e4249e9fc127cac2a793ac085f8650ba1be666 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20DELRIEU?= Date: Sat, 14 Jan 2017 02:33:03 +0100 Subject: [PATCH] use a priority_tag instead of int and longs with sfinae-dispatch --- src/json.hpp | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/src/json.hpp b/src/json.hpp index 4b8f9e5a..f10f178b 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -189,6 +189,11 @@ template std::string type_name(Json const &j) } } +// dispatch utility (taken from ranges-v3) +template struct priority_tag : priority_tag {}; + +template <> struct priority_tag<0> {}; + // This is an experiment. I need this to move constructors out of basic_json. // I'm sure there is a better way, but this might need a big basic_json refactoring template struct external_constructor; @@ -642,9 +647,8 @@ void from_json(Json const&j, std::forward_list& l) l.push_front(it->template get()); } - template -void from_json_array_impl(Json const &j, CompatibleArrayType &arr, long) +void from_json_array_impl(Json const &j, CompatibleArrayType &arr, priority_tag<0>) { using std::begin; using std::end; @@ -659,7 +663,7 @@ void from_json_array_impl(Json const &j, CompatibleArrayType &arr, long) } template -auto from_json_array_impl(Json const &j, CompatibleArrayType &arr, int) +auto from_json_array_impl(Json const &j, CompatibleArrayType &arr, priority_tag<1>) -> decltype( arr.reserve(std::declval()), void()) @@ -693,7 +697,7 @@ void from_json(Json const &j, CompatibleArrayType &arr) if (!j.is_array()) throw std::domain_error("type must be array, but is " + type_name(j)); } - from_json_array_impl(j, arr, 0); + from_json_array_impl(j, arr, priority_tag<1>{}); } @@ -744,7 +748,7 @@ void from_json(Json const &j, ArithmeticType &val) struct to_json_fn { template - auto call(int, Json& j, T&& val) const + auto call(Json& j, T&& val, priority_tag<1>) const noexcept(noexcept(to_json(j, std::forward(val)))) -> decltype(to_json(j, std::forward(val)), void()) @@ -753,7 +757,7 @@ struct to_json_fn } template - void call(long, Json&, T&&) const noexcept + void call(Json&, T&&, priority_tag<0>) const noexcept { static_assert(sizeof(Json) == 0, "to_json method in T's namespace can not be called"); } @@ -761,9 +765,9 @@ struct to_json_fn public: template void operator()(Json &j, T &&val) const - noexcept(noexcept(std::declval().call(0, j, std::forward(val)))) + noexcept(noexcept(std::declval().call(j, std::forward(val), priority_tag<1>{}))) { - return call(0, j, std::forward(val)); + return call(j, std::forward(val), priority_tag<1>{}); } }; @@ -771,7 +775,7 @@ struct from_json_fn { private: template - auto call(int, Json const &j, T &val) const + auto call(Json const &j, T &val, priority_tag<1>) const noexcept(noexcept(from_json(j, val))) -> decltype(from_json(j, val), void()) { @@ -779,7 +783,7 @@ private: } template - void call(long, Json const&, T&) const noexcept + void call(Json const&, T&, priority_tag<0>) const noexcept { static_assert(sizeof(Json) == 0, "from_json method in T's namespace can not be called"); } @@ -787,9 +791,9 @@ private: public: template void operator()(Json const &j, T &val) const - noexcept(noexcept(std::declval().call(0, j, val))) + noexcept(noexcept(std::declval().call(j, val, priority_tag<1>{}))) { - return call(0, j, val); + return call(j, val, priority_tag<1>{}); } };