From 0b3c8ca3fef9e3befb8e8d633df6209780180924 Mon Sep 17 00:00:00 2001 From: bergmann Date: Sat, 11 May 2019 19:39:19 +0200 Subject: [PATCH] * some refactoring --- include/cppargs/misc/misc.h | 6 +- include/cppargs/misc/misc.inl | 43 -------- .../options/member/member_predicate_option.h | 3 +- .../member/member_predicate_option.inl | 8 +- include/cppargs/options/option.h | 5 +- include/cppargs/options/option.inl | 104 ++++++++++++++++-- include/cppargs/parser/member_parser.h | 15 ++- include/cppargs/parser/member_parser.inl | 17 ++- include/cppargs/parser/simple_parser.inl | 2 +- test/cppargs/member_parser.cpp | 18 +-- test/cppargs/misc.cpp | 23 ++-- 11 files changed, 150 insertions(+), 94 deletions(-) diff --git a/include/cppargs/misc/misc.h b/include/cppargs/misc/misc.h index 4085a1b..d06a704 100644 --- a/include/cppargs/misc/misc.h +++ b/include/cppargs/misc/misc.h @@ -6,10 +6,6 @@ namespace cppargs { - template - struct argument_props - { - static std::string type(bool optional = false) = delete; - }; + } diff --git a/include/cppargs/misc/misc.inl b/include/cppargs/misc/misc.inl index 8499dda..0326b53 100644 --- a/include/cppargs/misc/misc.inl +++ b/include/cppargs/misc/misc.inl @@ -9,49 +9,6 @@ namespace cppargs { - inline std::string enwrap_type(const std::string& type, bool optional) - { - auto opn = optional ? "(" : "<"; - auto cls = optional ? ")" : ">"; - return std::string(opn) + type + cls; - } - template<> - struct argument_props - { - static std::string type(bool optional = false) - { return enwrap_type("string", false); } - }; - - template - struct argument_props::value>> - { - static std::string type(bool optional = false) - { return enwrap_type(utl::type_helper::name(), false); } - }; - - template - struct argument_props, void> - { - static std::string type(bool optional = false) - { - return - argument_props::type(false) + ' ' + - argument_props::type(true) + ' ' + - enwrap_type("...", true); - } - }; - - template - struct argument_props, void> - { - static std::string type(bool optional = false) - { - return - argument_props::type(false) + ' ' + - argument_props::type(true) + ' ' + - enwrap_type("...", true); - } - }; } diff --git a/include/cppargs/options/member/member_predicate_option.h b/include/cppargs/options/member/member_predicate_option.h index e7ebb17..9349e63 100644 --- a/include/cppargs/options/member/member_predicate_option.h +++ b/include/cppargs/options/member/member_predicate_option.h @@ -5,13 +5,12 @@ namespace cppargs { - template + template struct member_predicate_option : public member_option { public: using instance_type = T_instance; - using value_type = T_value; using predicate_type = T_predicate; using base_type = member_option; diff --git a/include/cppargs/options/member/member_predicate_option.inl b/include/cppargs/options/member/member_predicate_option.inl index 8371ab2..0a7700c 100644 --- a/include/cppargs/options/member/member_predicate_option.inl +++ b/include/cppargs/options/member/member_predicate_option.inl @@ -5,17 +5,17 @@ namespace cppargs { - template + template template - member_predicate_option::member_predicate_option( + member_predicate_option::member_predicate_option( const option_meta& p_meta, T_args&&... args) : base_type (p_meta) , _predicate(std::forward(args)...) { } - template - void member_predicate_option::parse(context& c) const + template + void member_predicate_option::parse(context& c) const { _predicate(this->instance(), c); } } diff --git a/include/cppargs/options/option.h b/include/cppargs/options/option.h index 5efbad3..77e0678 100644 --- a/include/cppargs/options/option.h +++ b/include/cppargs/options/option.h @@ -22,11 +22,12 @@ namespace cppargs inline option_meta& set_long_name (const std::string& value); inline option_meta& set_description (const std::string& value); inline option_meta& set_arguments (const std::string& value); - inline option_meta& set_default_value (const std::string& value); + template + inline option_meta& set_default_value (const T_value& value); inline option_meta& set_mandatory (bool value = true); template - static option_meta prepare_arguments(const option_meta& meta); + static option_meta prepare(const option_meta& meta, T_value&& value); }; /** diff --git a/include/cppargs/options/option.inl b/include/cppargs/options/option.inl index c7234d1..2773ce3 100644 --- a/include/cppargs/options/option.inl +++ b/include/cppargs/options/option.inl @@ -1,5 +1,6 @@ #pragma once +#include #include #include "option.h" @@ -7,6 +8,95 @@ namespace cppargs { + /* argument_props */ + + inline std::string enwrap_type(const std::string& type, bool optional) + { + auto opn = optional ? "(" : "<"; + auto cls = optional ? ")" : ">"; + return std::string(opn) + type + cls; + } + + template + struct argument_props + { + static std::string type(bool optional = false) + { return "unknown"; }; + }; + + template<> + struct argument_props + { + static std::string type(bool optional = false) + { return enwrap_type("string", false); } + }; + + template + struct argument_props::value>> + { + static std::string type(bool optional = false) + { return enwrap_type(utl::type_helper::name(), false); } + }; + + template + struct argument_props, void> + { + static std::string type(bool optional = false) + { + return + argument_props::type(false) + ' ' + + argument_props::type(true) + ' ' + + enwrap_type("...", true); + } + }; + + template + struct argument_props, void> + { + static std::string type(bool optional = false) + { + return + argument_props::type(false) + ' ' + + argument_props::type(true) + ' ' + + enwrap_type("...", true); + } + }; + + /* prepare_impl */ + + template + struct prepare_impl + { + static inline option_meta prepare(const option_meta& meta, T_value&& value) + { + option_meta m = meta; + if (m.arguments.empty()) + m.arguments = argument_props::type(std::is_same::value); + if (m.default_value.empty()) + m.set_default_value(std::forward(value)); + return m; + } + }; + + template + struct prepare_impl< + T_value T_object::*, + utl::mp::enable_if_c< + std::is_default_constructible::value>> + { + static inline option_meta prepare(const option_meta& meta, T_value T_object::*member) + { + option_meta m = meta; + if (m.arguments.empty()) + m.arguments = argument_props::type(std::is_same::value); + if (m.default_value.empty()) + m.set_default_value(T_object().*member); + return m; + } + }; + + /* option_meta */ + option_meta& option_meta::set_short_name(char value) { short_name = value; @@ -31,9 +121,10 @@ namespace cppargs return *this; } - option_meta& option_meta::set_default_value(const std::string& value) + template + option_meta& option_meta::set_default_value(const T_value& value) { - default_value = value; + default_value = utl::to_string(value); return *this; } @@ -44,13 +135,8 @@ namespace cppargs } template - option_meta option_meta::prepare_arguments(const option_meta& meta) - { - option_meta m = meta; - if (m.arguments.empty()) - m.arguments = argument_props::type(); - return m; - } + option_meta option_meta::prepare(const option_meta& meta, T_value&& value) + { return prepare_impl>::prepare(meta, std::forward(value)); } option::option(const option_meta& p_meta) : meta(p_meta) diff --git a/include/cppargs/parser/member_parser.h b/include/cppargs/parser/member_parser.h index d922575..d0681dd 100644 --- a/include/cppargs/parser/member_parser.h +++ b/include/cppargs/parser/member_parser.h @@ -13,6 +13,17 @@ namespace cppargs using parser::parser; public: + /** + * @brief Create new member predicate option. + * + * @param[in] meta Meta data of the new option. + * @param[in] predicate Predicate to execute for this option. + * + * @return Created option. + */ + template + static constexpr decltype(auto) make_option(const option_meta& meta, T_predicate&& predicate); + /** * @brief Create new member option. * @@ -22,7 +33,7 @@ namespace cppargs * @return Created option. */ template - static constexpr decltype(auto) make_member_option(const option_meta& meta, T_value T_object::*member); + static constexpr decltype(auto) make_option(const option_meta& meta, T_value T_object::*member); /** * @brief Create new group. @@ -45,7 +56,7 @@ namespace cppargs * @return Created group. */ template - static constexpr decltype(auto) make_member_group(const group_meta& meta, T_value T_object::*member, T_args&&... args); + static constexpr decltype(auto) make_group(const group_meta& meta, T_value T_object::*member, T_args&&... args); }; /** diff --git a/include/cppargs/parser/member_parser.inl b/include/cppargs/parser/member_parser.inl index c54347f..dcbe7ab 100644 --- a/include/cppargs/parser/member_parser.inl +++ b/include/cppargs/parser/member_parser.inl @@ -11,8 +11,17 @@ namespace cppargs { + template + constexpr decltype(auto) member_parser_base::make_option(const option_meta& meta, T_predicate&& predicate) + { + using instance_type = T_instance; + using predicate_type = T_predicate; + using member_predicate_option_type = member_predicate_option; + return std::make_unique(meta, std::forward(predicate)); + } + template - constexpr decltype(auto) member_parser_base::make_member_option(const option_meta& meta, T_value T_object::*member) + constexpr decltype(auto) member_parser_base::make_option(const option_meta& meta, T_value T_object::*member) { static_assert(std::is_base_of::value, "Member pointer must be in the instance type."); @@ -26,9 +35,9 @@ namespace cppargs }; using predicate_type = decltype(predicate); - using member_predicate_option_type = member_predicate_option; + using member_predicate_option_type = member_predicate_option; return std::make_unique( - option_meta::prepare_arguments(meta), + option_meta::prepare(meta, member), std::move(predicate)); } @@ -47,7 +56,7 @@ namespace cppargs } template - constexpr decltype(auto) member_parser_base::make_member_group(const group_meta& meta, T_value T_object::*member, T_args&&... args) + constexpr decltype(auto) member_parser_base::make_group(const group_meta& meta, T_value T_object::*member, T_args&&... args) { using owner_instance_type = T_instance; using my_instance_type = T_value; diff --git a/include/cppargs/parser/simple_parser.inl b/include/cppargs/parser/simple_parser.inl index ca2bb07..578b0c8 100644 --- a/include/cppargs/parser/simple_parser.inl +++ b/include/cppargs/parser/simple_parser.inl @@ -46,7 +46,7 @@ namespace cppargs using predicate_type = decltype(predicate); using simple_predicate_option_type = simple_predicate_option; return std::make_unique( - option_meta::prepare_arguments(meta), + option_meta::prepare(meta, value), std::move(predicate)); } diff --git a/test/cppargs/member_parser.cpp b/test/cppargs/member_parser.cpp index 999570e..323b99c 100644 --- a/test/cppargs/member_parser.cpp +++ b/test/cppargs/member_parser.cpp @@ -18,9 +18,9 @@ TEST(member_parser, simple_object) simple s; parser p( nullptr, - parser::make_member_option({ 'i', "int" }, &simple::i), - parser::make_member_option({ 's', "string" }, &simple::s), - parser::make_member_option({ 'd', "double" }, &simple::d) + parser::make_option({ 'i', "int" }, &simple::i), + parser::make_option({ 's', "string" }, &simple::s), + parser::make_option({ 'd', "double" }, &simple::d) ); std::vector args({ @@ -55,12 +55,12 @@ TEST(member_parser, grouped_object) grouped g; parser p( nullptr, - parser::make_member_option({ 'i', "int" }, &grouped::i), - parser::make_member_option({ 's', "string" }, &grouped::s), - parser::make_member_option({ 'd', "double" }, &grouped::d), - parser::make_member_group ({ }, &grouped::g1, - parser::make_member_option({ 'l', "list" }, &grouped::group1::list), - parser::make_member_option({ 'v', "vector" }, &grouped::group1::vec)) + parser::make_option({ 'i', "int" }, &grouped::i), + parser::make_option({ 's', "string" }, &grouped::s), + parser::make_option({ 'd', "double" }, &grouped::d), + parser::make_group ({ }, &grouped::g1, + parser::make_option({ 'l', "list" }, &grouped::group1::list), + parser::make_option({ 'v', "vector" }, &grouped::group1::vec)) ); std::vector args({ diff --git a/test/cppargs/misc.cpp b/test/cppargs/misc.cpp index fe338af..7a64584 100644 --- a/test/cppargs/misc.cpp +++ b/test/cppargs/misc.cpp @@ -31,7 +31,7 @@ TEST(misc, print_help) parser p( nullptr, - parser::make_member_option( + parser::make_option( ::cppargs::option_meta() .set_short_name ('c') .set_long_name ("config") @@ -40,47 +40,45 @@ TEST(misc, print_help) .set_mandatory (true), &config::config), - // parser::make_group({ }), - /* database */ - parser::make_member_group( + parser::make_group( ::cppargs::group_meta() .set_name("Database") .set_description("The following parameters are database related."), &config::database, - parser::make_member_option( + parser::make_option( ::cppargs::option_meta() .set_long_name ("database:host") .set_description("Database host to connect to."), &config::database::host), - parser::make_member_option( + parser::make_option( ::cppargs::option_meta() .set_long_name ("database:port") .set_description("Database port to connect to."), &config::database::port), - parser::make_member_option( + parser::make_option( ::cppargs::option_meta() .set_long_name ("database:password") .set_description("Password to use for authenticatiom"), &config::database::password)), /* logging */ - parser::make_member_group( + parser::make_group( ::cppargs::group_meta() .set_name("Logging"), &config::logging, - parser::make_member_option( + parser::make_option( ::cppargs::option_meta() .set_long_name ("logging:file") .set_arguments (::cppargs::enwrap_type("filename", false)) .set_description("File to write log output to."), &config::logging::file), - parser::make_member_option( + parser::make_option( ::cppargs::option_meta() .set_long_name ("logging:level") .set_description("Log Level."), &config::logging::level), - parser::make_member_option( + parser::make_option( ::cppargs::option_meta() .set_long_name ("logging:name") .set_description("Default name of the logger."), @@ -88,6 +86,5 @@ TEST(misc, print_help) std::ostringstream ss; p.print_help(ss); - - std::cout << ss.str(); + EXPECT_FALSE(ss.str().empty()); }