option parser: adjust functors so no object copies are made

This commit is contained in:
Andrzej Rybczak
2014-09-02 18:28:06 +02:00
parent 4cf170d44b
commit edfb4d9c53
2 changed files with 64 additions and 23 deletions

View File

@@ -23,6 +23,7 @@
#include <stdexcept>
#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 <typename ValueT, typename TransformT>
option_parser::worker buffer(NC::Buffer &arg, ValueT &&value, TransformT &&map)
{
return option_parser::worker(assign<std::string>(arg, [&arg, map](std::string &&s) {
return map(stringToBuffer(s));
}), defaults_to(arg, map(std::forward<ValueT>(value))));
}
}
bool Configuration::read(const std::string &config_path)

View File

@@ -26,8 +26,6 @@
#include <stdexcept>
#include <unordered_map>
#include "helpers.h"
#include "strbuffer.h"
#include "utility/functional.h"
struct option_parser
@@ -35,6 +33,50 @@ struct option_parser
typedef std::function<void(std::string &&)> parser_t;
typedef std::function<void()> default_t;
template <typename DestT, typename SourceT>
struct assign_value_once
{
typedef DestT dest_type;
typedef typename std::decay<SourceT>::type source_type;
template <typename ArgT>
assign_value_once(DestT &dest, ArgT &&value)
: m_assigned(false), m_dest(dest), m_source(std::forward<ArgT>(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 <typename IntermediateT, typename DestT, typename TransformT>
struct parse_and_transform
{
template <typename ArgT>
parse_and_transform(DestT &dest, ArgT &&map)
: m_dest(dest), m_map(std::forward<ArgT>(map)) { }
void operator()(std::string &&v)
{
try {
m_dest = m_map(boost::lexical_cast<IntermediateT>(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 <typename IntermediateT, typename ArgT, typename TransformT>
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<IntermediateT>(v));
} catch (boost::bad_lexical_cast &) {
throw std::runtime_error("invalid value: " + v);
}
};
return option_parser::parse_and_transform<IntermediateT, ArgT, TransformT>(
arg, std::forward<TransformT>(map)
);
}
template <typename ArgT, typename ValueT>
option_parser::default_t defaults_to(ArgT &arg, ValueT &&value)
{
return [&arg, value] {
arg = std::move(value);
};
return option_parser::assign_value_once<ArgT, ValueT>(
arg, std::forward<ValueT>(value)
);
}
template <typename IntermediateT, typename ArgT, typename ValueT, typename TransformT>
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<IntermediateT>(arg, map), defaults_to(arg, map(std::forward<ValueT>(value)))
assign<IntermediateT>(arg, std::forward<TransformT>(map)),
defaults_to(arg, map(std::forward<ValueT>(value)))
);
}
@@ -118,14 +157,6 @@ option_parser::worker assign_default(ArgT &arg, ValueT &&value)
// workers for specific types
template <typename ValueT, typename TransformT>
option_parser::worker buffer(NC::Buffer &arg, ValueT &&value, TransformT map)
{
return option_parser::worker(assign<std::string>(arg, [&arg, map](std::string &&s) {
return map(stringToBuffer(s));
}), defaults_to(arg, map(std::forward<ValueT>(value))));
}
option_parser::worker yes_no(bool &arg, bool value);
#endif // NCMPCPP_UTILITY_OPTION_PARSER_H