Commit 5a4a1b7f authored by Dominik Charousset's avatar Dominik Charousset

Enable vectors in config setups

parent 35af5369
......@@ -22,6 +22,7 @@
#include <memory>
#include <string>
#include <vector>
#include <cstdint>
#include <cstring>
#include <functional>
......@@ -33,6 +34,8 @@
#include "caf/deep_to_string.hpp"
#include "caf/static_visitor.hpp"
#include "caf/detail/type_traits.hpp"
namespace caf {
/// Helper class to generate config readers for different input types.
......@@ -117,7 +120,8 @@ private:
char short_name_;
};
template <class T>
template <class T, bool IsInsertable = detail::can_insert_elements<T>()
&& !std::is_same<T, std::string>::value>
class config_option_impl : public config_option {
public:
config_option_impl(T& ref, const char* ctg, const char* nm, const char* xp)
......@@ -166,6 +170,62 @@ private:
T& ref_;
};
template <class T>
class config_option_impl<T, true> : public config_option {
public:
using value_type = typename T::value_type;
config_option_impl(T& ref, const char* ctg, const char* nm, const char* xp)
: config_option(ctg, nm, xp),
ref_(ref) {
// nop
}
std::string to_string() const override {
return deep_to_string(ref_);
}
message::cli_arg to_cli_arg(bool use_caf_prefix) override {
std::string argname;
if (use_caf_prefix)
argname = "caf#";
if (strcmp(category(), "global") != 0) {
argname += category();
argname += ".";
}
argname += name();
if (short_name() != '\0') {
argname += ',';
argname += short_name();
}
return {std::move(argname), explanation(), ref_};
}
config_reader_sink to_sink() override {
return [=](size_t ln, config_value& x) {
// the INI parser accepts all integers as int64_t
using cfg_type =
typename std::conditional<
std::is_integral<value_type>::value
&& !std::is_same<bool, value_type>::value,
int64_t,
value_type
>::type;
value_type tmp;
if (get<cfg_type>(&x) && assign_config_value(tmp, get<cfg_type>(x))) {
ref_.insert(ref_.end(), std::move(tmp));
return;
}
type_name_visitor tnv;
report_type_error(ln, x, tnv(tmp));
};
}
private:
T& ref_;
};
template <class T>
std::unique_ptr<config_option>
make_config_option(T& storage, const char* category,
......
......@@ -588,6 +588,25 @@ struct strip_reference_wrapper<std::reference_wrapper<T>> {
using type = T;
};
template <class T>
constexpr bool can_insert_elements_impl(
T*,
decltype(std::declval<T&>()
.insert(std::declval<T&>().end(),
std::declval<typename T::value_type>()))* = nullptr) {
return true;
}
template <class T>
constexpr bool can_insert_elements_impl(void*) {
return false;
}
template <class T>
constexpr bool can_insert_elements() {
return can_insert_elements_impl<T>(static_cast<T*>(nullptr));
}
} // namespace detail
} // namespace caf
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment