option parser: adjust functors so no object copies are made
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user