option parser: adjust functors so no object copies are made

master
Andrzej Rybczak 12 years ago
parent 4cf170d44b
commit edfb4d9c53
  1. 10
      src/settings.cpp
  2. 77
      src/utility/option_parser.h

@ -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

Loading…
Cancel
Save