Add default dispatch handling for generic case of 'const rjp::value&'. Will cause compilation error if return type is not void
This commit is contained in:
parent
4bf41e8b42
commit
06cfc1d0b6
@ -4,9 +4,17 @@
|
|||||||
#include "rjp_internal.hpp"
|
#include "rjp_internal.hpp"
|
||||||
#include <type_traits> //is_same, true_type, false_type
|
#include <type_traits> //is_same, true_type, false_type
|
||||||
#include <utility> //forward
|
#include <utility> //forward
|
||||||
|
#include <exception>
|
||||||
|
|
||||||
namespace rjp{
|
namespace rjp{
|
||||||
|
|
||||||
|
class missing_dispatch_handler : public std::exception
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
const char* what(void)const noexcept override{
|
||||||
|
return "Argument not handled in rjp::dispatch";
|
||||||
|
}
|
||||||
|
};
|
||||||
namespace detail{
|
namespace detail{
|
||||||
template<RJP_data_type T>
|
template<RJP_data_type T>
|
||||||
struct to_value_type;
|
struct to_value_type;
|
||||||
@ -81,6 +89,23 @@ namespace rjp{
|
|||||||
struct has_next_data_type{
|
struct has_next_data_type{
|
||||||
static constexpr bool value = has_next_data_type_helper<T>::value;
|
static constexpr bool value = has_next_data_type_helper<T>::value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<class T, class Param>
|
||||||
|
struct has_operator_for{
|
||||||
|
template<class U, class = decltype(std::declval<U>()(std::declval<Param>()))>
|
||||||
|
static std::true_type check(U*);
|
||||||
|
static std::false_type check(...);
|
||||||
|
|
||||||
|
static constexpr bool value = std::is_same<std::true_type,decltype(check((void*)0))>::value;
|
||||||
|
};
|
||||||
|
template<class Param, class T, class... Ts>
|
||||||
|
struct has_operator_for_any{
|
||||||
|
static constexpr bool value = has_operator_for<T, Param>::value || has_operator_for_any<Param,Ts...>::value;
|
||||||
|
};
|
||||||
|
template<class Param, class T>
|
||||||
|
struct has_operator_for_any<Param,T>{
|
||||||
|
static constexpr bool value = has_operator_for<T,Param>::value;
|
||||||
|
};
|
||||||
template<class Func, class Val, RJP_data_type T>
|
template<class Func, class Val, RJP_data_type T>
|
||||||
decltype(auto) dispatch_helper(Func&& fun, Val&& v){
|
decltype(auto) dispatch_helper(Func&& fun, Val&& v){
|
||||||
if(v.type() == T){
|
if(v.type() == T){
|
||||||
@ -89,6 +114,7 @@ namespace rjp{
|
|||||||
if constexpr(detail::has_next_data_type<T>::value){
|
if constexpr(detail::has_next_data_type<T>::value){
|
||||||
return dispatch_helper<Func,Val,detail::next_data_type<T>::value>(std::forward<Func>(fun), std::forward<Val>(v));
|
return dispatch_helper<Func,Val,detail::next_data_type<T>::value>(std::forward<Func>(fun), std::forward<Val>(v));
|
||||||
}
|
}
|
||||||
|
throw missing_dispatch_handler{}; //deals with -Wreturn-type warnings
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
template<class Func, class Val>
|
template<class Func, class Val>
|
||||||
@ -99,6 +125,9 @@ namespace rjp{
|
|||||||
struct dispatcher : public Ts...
|
struct dispatcher : public Ts...
|
||||||
{
|
{
|
||||||
using Ts::operator()...;
|
using Ts::operator()...;
|
||||||
|
|
||||||
|
template<typename std::enable_if<!detail::has_operator_for_any<const value&,Ts...>::value,void>::type* = nullptr>
|
||||||
|
decltype(auto) operator()(const value&)const{}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class... Ts>
|
template<class... Ts>
|
||||||
|
|||||||
@ -29,20 +29,22 @@ rjp::array initialize_array(int num){
|
|||||||
|
|
||||||
int main(){
|
int main(){
|
||||||
srand(time(0));
|
srand(time(0));
|
||||||
|
int retval = 0;
|
||||||
|
|
||||||
rjp::array root = initialize_array(NUM_ELEMENTS);
|
rjp::array root = initialize_array(NUM_ELEMENTS);
|
||||||
|
|
||||||
for(auto&& val : root){
|
for(auto&& val : root){
|
||||||
RJP_data_type d;
|
RJP_data_type d;
|
||||||
rjp::dispatch(rjp::dispatcher{
|
rjp::dispatch(rjp::dispatcher{
|
||||||
[&d](const rjp::value&){assert(false);},
|
|
||||||
[&d](const rjp::integer&){d = rjp_json_integer;},
|
[&d](const rjp::integer&){d = rjp_json_integer;},
|
||||||
[&d](const rjp::boolean&){d = rjp_json_boolean;},
|
[&d](const rjp::boolean&){d = rjp_json_boolean;},
|
||||||
[&d](const rjp::array&){d = rjp_json_array;},
|
[&d](const rjp::array&){d = rjp_json_array;},
|
||||||
[&d](const rjp::object&){d = rjp_json_object;},
|
[&d](const rjp::object&){d = rjp_json_object;},
|
||||||
}, val);
|
}, val);
|
||||||
if(d != val.type()){
|
if(d != val.type()){
|
||||||
|
++retval;
|
||||||
printf("Dispatch error\n");
|
printf("Dispatch error\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user