option parser: adjust functors so no object copies are made
This commit is contained in:
@@ -23,6 +23,7 @@
|
|||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
|
#include "helpers.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "utility/conversion.h"
|
#include "utility/conversion.h"
|
||||||
#include "utility/option_parser.h"
|
#include "utility/option_parser.h"
|
||||||
@@ -167,6 +168,15 @@ std::string adjust_and_validate_format(std::string &&format)
|
|||||||
return 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)
|
bool Configuration::read(const std::string &config_path)
|
||||||
|
|||||||
@@ -26,8 +26,6 @@
|
|||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
#include "helpers.h"
|
|
||||||
#include "strbuffer.h"
|
|
||||||
#include "utility/functional.h"
|
#include "utility/functional.h"
|
||||||
|
|
||||||
struct option_parser
|
struct option_parser
|
||||||
@@ -35,6 +33,50 @@ struct option_parser
|
|||||||
typedef std::function<void(std::string &&)> parser_t;
|
typedef std::function<void(std::string &&)> parser_t;
|
||||||
typedef std::function<void()> default_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
|
struct worker
|
||||||
{
|
{
|
||||||
worker() { }
|
worker() { }
|
||||||
@@ -83,30 +125,27 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <typename IntermediateT, typename ArgT, typename TransformT>
|
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) {
|
return option_parser::parse_and_transform<IntermediateT, ArgT, TransformT>(
|
||||||
try {
|
arg, std::forward<TransformT>(map)
|
||||||
arg = map(boost::lexical_cast<IntermediateT>(v));
|
);
|
||||||
} catch (boost::bad_lexical_cast &) {
|
|
||||||
throw std::runtime_error("invalid value: " + v);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ArgT, typename ValueT>
|
template <typename ArgT, typename ValueT>
|
||||||
option_parser::default_t defaults_to(ArgT &arg, ValueT &&value)
|
option_parser::default_t defaults_to(ArgT &arg, ValueT &&value)
|
||||||
{
|
{
|
||||||
return [&arg, value] {
|
return option_parser::assign_value_once<ArgT, ValueT>(
|
||||||
arg = std::move(value);
|
arg, std::forward<ValueT>(value)
|
||||||
};
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename IntermediateT, typename ArgT, typename ValueT, typename TransformT>
|
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(
|
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
|
// 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);
|
option_parser::worker yes_no(bool &arg, bool value);
|
||||||
|
|
||||||
#endif // NCMPCPP_UTILITY_OPTION_PARSER_H
|
#endif // NCMPCPP_UTILITY_OPTION_PARSER_H
|
||||||
|
|||||||
Reference in New Issue
Block a user