From edfb4d9c5308495170d84d7cd9ffd53c47ba2d38 Mon Sep 17 00:00:00 2001 From: Andrzej Rybczak Date: Tue, 2 Sep 2014 18:28:06 +0200 Subject: [PATCH] option parser: adjust functors so no object copies are made --- src/settings.cpp | 10 +++++ src/utility/option_parser.h | 77 ++++++++++++++++++++++++++----------- 2 files changed, 64 insertions(+), 23 deletions(-) diff --git a/src/settings.cpp b/src/settings.cpp index 1dbd77f4..fcf634b2 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -23,6 +23,7 @@ #include #include "configuration.h" +#include "helpers.h" #include "settings.h" #include "utility/conversion.h" #include "utility/option_parser.h" @@ -167,6 +168,15 @@ std::string adjust_and_validate_format(std::string &&format) return format; } +// parser worker for buffer +template +option_parser::worker buffer(NC::Buffer &arg, ValueT &&value, TransformT &&map) +{ + return option_parser::worker(assign(arg, [&arg, map](std::string &&s) { + return map(stringToBuffer(s)); + }), defaults_to(arg, map(std::forward(value)))); +} + } bool Configuration::read(const std::string &config_path) diff --git a/src/utility/option_parser.h b/src/utility/option_parser.h index 6804d461..4bc9f35e 100644 --- a/src/utility/option_parser.h +++ b/src/utility/option_parser.h @@ -26,8 +26,6 @@ #include #include -#include "helpers.h" -#include "strbuffer.h" #include "utility/functional.h" struct option_parser @@ -35,6 +33,50 @@ struct option_parser typedef std::function parser_t; typedef std::function default_t; + template + struct assign_value_once + { + typedef DestT dest_type; + typedef typename std::decay::type source_type; + + template + assign_value_once(DestT &dest, ArgT &&value) + : m_assigned(false), m_dest(dest), m_source(std::forward(value)) { } + + void operator()() + { + assert(m_assigned == false); + m_dest = std::move(m_source); + m_assigned = true; + } + + private: + bool m_assigned; + dest_type &m_dest; + source_type m_source; + }; + + template + struct parse_and_transform + { + template + parse_and_transform(DestT &dest, ArgT &&map) + : m_dest(dest), m_map(std::forward(map)) { } + + void operator()(std::string &&v) + { + try { + m_dest = m_map(boost::lexical_cast(v)); + } catch (boost::bad_lexical_cast &) { + throw std::runtime_error("invalid value: " + v); + } + } + + private: + DestT &m_dest; + TransformT m_map; + }; + struct worker { worker() { } @@ -83,30 +125,27 @@ private: }; template -option_parser::parser_t assign(ArgT &arg, TransformT map = id_()) +option_parser::parser_t assign(ArgT &arg, TransformT &&map = id_()) { - return [&arg, map](std::string &&v) { - try { - arg = map(boost::lexical_cast(v)); - } catch (boost::bad_lexical_cast &) { - throw std::runtime_error("invalid value: " + v); - } - }; + return option_parser::parse_and_transform( + arg, std::forward(map) + ); } template option_parser::default_t defaults_to(ArgT &arg, ValueT &&value) { - return [&arg, value] { - arg = std::move(value); - }; + return option_parser::assign_value_once( + arg, std::forward(value) + ); } template -option_parser::worker assign_default(ArgT &arg, ValueT &&value, TransformT map) +option_parser::worker assign_default(ArgT &arg, ValueT &&value, TransformT &&map) { return option_parser::worker( - assign(arg, map), defaults_to(arg, map(std::forward(value))) + assign(arg, std::forward(map)), + defaults_to(arg, map(std::forward(value))) ); } @@ -118,14 +157,6 @@ option_parser::worker assign_default(ArgT &arg, ValueT &&value) // workers for specific types -template -option_parser::worker buffer(NC::Buffer &arg, ValueT &&value, TransformT map) -{ - return option_parser::worker(assign(arg, [&arg, map](std::string &&s) { - return map(stringToBuffer(s)); - }), defaults_to(arg, map(std::forward(value)))); -} - option_parser::worker yes_no(bool &arg, bool value); #endif // NCMPCPP_UTILITY_OPTION_PARSER_H