diff --git a/include/ss/converter.hpp b/include/ss/converter.hpp index 886ad39..08c2e37 100644 --- a/include/ss/converter.hpp +++ b/include/ss/converter.hpp @@ -81,6 +81,11 @@ struct no_void_validator_tup { using type = no_validator_tup_t>; }; +template +struct no_void_validator_tup> { + using type = no_validator_tup_t>; +}; + template using no_void_validator_tup_t = typename no_void_validator_tup::type; @@ -152,6 +157,10 @@ class converter { return to_object( convert_impl(elems, (arg_tuple*){})); + } else if constexpr (sizeof...(Ts) == 0 && + is_instance_of::value) { + return convert_impl(elems, (T*){}); + } else { return convert_impl(elems); } @@ -337,11 +346,11 @@ class converter { using elem_t = std::tuple_element_t>; constexpr bool not_void = !std::is_void_v; - constexpr bool not_tuple = + constexpr bool one_element = count_not::size == 1; if constexpr (not_void) { - if constexpr (not_tuple) { + if constexpr (one_element) { extract_one(tup, elems[ArgN], ArgN); } else { auto& el = std::get(tup); @@ -359,7 +368,6 @@ class converter { no_void_validator_tup_t extract_tuple(const split_input& elems) { static_assert(!all_of::value, "at least one parameter must be non void"); - no_void_validator_tup_t ret; extract_multiple<0, 0, Ts...>(ret, elems); return ret; diff --git a/include/ss/parser.hpp b/include/ss/parser.hpp index 67cc908..9e65191 100644 --- a/include/ss/parser.hpp +++ b/include/ss/parser.hpp @@ -115,7 +115,7 @@ class parser { return composite_with(std::move(value)); } - auto values() { + std::tuple values() { return values_; } @@ -198,10 +198,13 @@ class parser { // failed template void try_invoke(Arg&& arg, Fun&& fun) { - if constexpr (!std::is_same_v, None>) { + constexpr bool is_none = + std::is_same_v, None>; + if constexpr (!is_none) { using Ret = decltype( try_invoke_impl(arg, std::forward(fun))); - if constexpr (!std::is_same_v) { + constexpr bool returns_void = std::is_same_v; + if constexpr (!returns_void) { if (!try_invoke_impl(arg, std::forward(fun))) { set_error_failed_check(); @@ -219,7 +222,9 @@ class parser { // laid out as a parameter pack template auto try_invoke_impl(Arg&& arg, Fun&& fun) { - if constexpr (!std::is_same_v) { + constexpr bool is_none = + std::is_same_v, None>; + if constexpr (!is_none) { if constexpr (std::is_invocable_v) { return fun(); } else if constexpr (std::is_invocable_v) { diff --git a/include/ss/type_traits.hpp b/include/ss/type_traits.hpp index 1c8fa19..34ab136 100644 --- a/include/ss/type_traits.hpp +++ b/include/ss/type_traits.hpp @@ -312,13 +312,13 @@ struct none_of> { // is instance of //////////////// -template class> +template class Template> struct is_instance_of { constexpr static bool value = false; }; -template class U> -struct is_instance_of, U> { +template class Template> +struct is_instance_of, Template> { constexpr static bool value = true; }; diff --git a/test/test_parser.cpp b/test/test_parser.cpp index d346ad4..4692aec 100644 --- a/test/test_parser.cpp +++ b/test/test_parser.cpp @@ -217,7 +217,7 @@ TEST_CASE("testing the moving of parsed values") { ss::parser p{f.name, ","}; auto x = p.get_next(); CHECK(copy_called == 0); - CHECK(move_called == 3 * move_called_one_col); + CHECK(move_called <= 3 * move_called_one_col); move_called = copy_called = 0; } @@ -225,7 +225,8 @@ TEST_CASE("testing the moving of parsed values") { ss::parser p{f.name, ","}; auto x = p.get_object(); CHECK(copy_called == 0); - CHECK(move_called == 6 * move_called_one_col); + CHECK(move_called <= 6 * move_called_one_col); + std::cout << move_called << std::endl; move_called = copy_called = 0; } @@ -233,7 +234,7 @@ TEST_CASE("testing the moving of parsed values") { ss::parser p{f.name, ","}; auto x = p.get_next(); CHECK(copy_called == 0); - CHECK(move_called == 6 * move_called_one_col); + CHECK(move_called <= 6 * move_called_one_col); move_called = copy_called = 0; } }