diff --git a/include/clippson/clippson.hpp b/include/clippson/clippson.hpp index 6b1ec49..be4bc22 100644 --- a/include/clippson/clippson.hpp +++ b/include/clippson/clippson.hpp @@ -65,17 +65,14 @@ inline std::string longest(const std::vector& args) { return lstrip(*it); } -template >* = nullptr> inline -std::string doc_default(const T& x, std::string_view doc) { - std::ostringstream oss; - oss << doc << " (=" << x << ")"; - return oss.str(); -} - -template >* = nullptr> inline +template inline std::string doc_default(const T& x, std::string_view doc) { std::ostringstream oss; - join(x, oss << doc << " (=[", ",") << "])"; + if constexpr (is_vector_v) { + join(x, oss << doc << " (=[", ",") << "])"; + } else { + oss << doc << " (=" << x << ")"; + } return oss.str(); } @@ -133,55 +130,47 @@ struct try_split { } }; -template >* = nullptr> -inline try_conversion filter() { - return try_conversion{}; -} - -template >* = nullptr> -inline try_split filter() { - return try_split{}; -} - -template >* = nullptr> inline -std::function set(X* target) { - return [target](const char* s){ - *target = sto(s); - }; +template +inline auto filter() { + if constexpr (is_vector_v) { + return try_split{}; + } else { + return try_conversion{}; + } } -template >* = nullptr> inline +template inline std::function set(X* target) { return [target](const char* s){ - target->clear(); - split(s, target); - }; -} - -template >* = nullptr> inline -std::function append_positional(X* target) { - return [target](const char* s){ - target->operator[]("--").push_back(sto(s)); + if constexpr (is_vector_v) { + target->clear(); + split(s, target); + } else { + *target = sto(s); + } }; } -template >* = nullptr> inline +template inline std::function append_positional(X* target) { return [target](const char* s){ - auto v = nlohmann::json::array(); - split(s, &v); - target->operator[]("--").push_back(std::move(v)); + if constexpr (is_vector_v) { + auto v = nlohmann::json::array(); + split(s, &v); + target->operator[]("--").push_back(std::move(v)); + } else { + target->operator[]("--").push_back(sto(s)); + } }; } -template >* = nullptr> inline -std::function clear(X*) { - return [](){}; -} - -template >* = nullptr> inline +template inline std::function clear(X* target) { - return [target](){target->clear();}; + if constexpr (std::is_arithmetic_v) { + return [](){}; + } else { + return [target](){target->clear();}; + } } } // namespace detail @@ -242,49 +231,64 @@ option(F&& flags, Target* target, Rest*... rest) { return option(std::forward(flags), rest...).call(detail::clear(target)); } -template >* = nullptr, class... Targets> +template inline clipp::group group(F&& flags, const std::string& label, Targets*... targets) { return option(std::forward(flags), targets...) & value(label, targets...); } -template >* = nullptr> -inline clipp::group -option(std::vector&& flags, T* target, std::string_view doc="", const std::string& label="") { - const auto key = detail::longest(flags); - return ( - group(key + "=", label, target), - group(std::move(flags), label, target) - % detail::doc_default(*target, doc) - ); +template +inline auto +option(std::vector&& flags, + T* target, const std::string& doc="", const std::string& label="") { + if constexpr (std::is_same_v) { + return option(std::move(flags)).set(*target).doc(doc); + } else { + const auto key = detail::longest(flags); + return ( + group(key + "=", label, target), + group(std::move(flags), label, target) + % detail::doc_default(*target, doc) + ); + } } -template >* = nullptr> -inline clipp::group -option(nlohmann::json* obj, std::vector&& flags, const T init, std::string_view doc="", const std::string& label="") { +template +inline auto +option(nlohmann::json* obj, std::vector&& flags, + const T init, const std::string& doc="", const std::string& label="") { const auto key = detail::longest(flags); auto& target_js = (*obj)[key] = init; - return ( - group(key + "=", label, &target_js), - group(std::move(flags), label, &target_js) - % detail::doc_default(init, doc) - ); + if constexpr (std::is_same_v) { + return option(std::move(flags)).call(detail::set(&target_js)).doc(doc); + } else { + return ( + group(key + "=", label, &target_js), + group(std::move(flags), label, &target_js) + % detail::doc_default(init, doc) + ); + } } -template && !std::is_same_v>* = nullptr> -inline clipp::group -option(nlohmann::json* obj, std::vector&& flags, T* target, std::string_view doc="", const std::string& label="") { +template >* = nullptr> +inline auto +option(nlohmann::json* obj, std::vector&& flags, + T* target, const std::string& doc="", const std::string& label="") { const auto key = detail::longest(flags); auto& target_js = (*obj)[key] = *target; - return ( - group(key + "=", label, &target_js, target), - group(std::move(flags), label, &target_js, target) - % detail::doc_default(*target, doc) - ); + if constexpr (std::is_same_v) { + return option(std::move(flags)).call(detail::set(&target_js)).set(*target).doc(doc); + } else { + return ( + group(key + "=", label, &target_js, target), + group(std::move(flags), label, &target_js, target) + % detail::doc_default(*target, doc) + ); + } } -template >* = nullptr> +template inline clipp::group option(std::vector&& flags, std::vector choices, T* target, std::string_view doc="") { @@ -297,7 +301,7 @@ option(std::vector&& flags, ); } -template >* = nullptr> +template inline clipp::group option(nlohmann::json* obj, std::vector&& flags, std::vector choices, const T init, std::string_view doc="") { @@ -311,7 +315,7 @@ option(nlohmann::json* obj, std::vector&& flags, ); } -template && !std::is_same_v>* = nullptr> +template >* = nullptr> inline clipp::group option(nlohmann::json* obj, std::vector&& flags, std::vector choices, T* target, std::string_view doc="") { @@ -325,25 +329,6 @@ option(nlohmann::json* obj, std::vector&& flags, ); } -inline clipp::parameter -option(std::vector&& flags, bool* target, const std::string& doc=" ") { - return option(std::move(flags)).set(*target).doc(doc); -} - -inline clipp::parameter -option(nlohmann::json* obj, std::vector&& flags, const bool init=false, const std::string& doc=" ") { - const auto key = detail::longest(flags); - auto& target_js = (*obj)[key] = init; - return option(std::move(flags)).call(detail::set(&target_js)).doc(doc); -} - -inline clipp::parameter -option(nlohmann::json* obj, std::vector&& flags, bool* target, const std::string& doc=" ") { - const auto key = detail::longest(flags); - auto& target_js = (*obj)[key] = *target; - return option(std::move(flags)).call(detail::set(&target_js)).set(*target).doc(doc); -} - inline clipp::doc_formatting doc_format() { return clipp::doc_formatting{} .first_column(0)