Commit f36bc529 authored by Dominik Charousset's avatar Dominik Charousset

Use config_value_access to obtain type names

parent 2ee64506
This diff is collapsed.
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright 2011-2018 Dominik Charousset *
* *
* Distributed under the terms and conditions of the BSD 3-Clause License or *
* (at your option) under the terms and conditions of the Boost Software *
* License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. *
* *
* If you did not receive a copy of the license files, see *
* http://opensource.org/licenses/BSD-3-Clause and *
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#pragma once
#include <string>
#include <type_traits>
#include <vector>
#include "caf/dictionary.hpp"
#include "caf/fwd.hpp"
#include "caf/timestamp.hpp"
namespace caf {
namespace detail {
template <size_t Bytes>
struct type_name_builder_int_size;
template <>
struct type_name_builder_int_size<1> {
void operator()(std::string& result) const {
result += "8";
}
};
template <>
struct type_name_builder_int_size<2> {
void operator()(std::string& result) const {
result += "16";
}
};
template <>
struct type_name_builder_int_size<4> {
void operator()(std::string& result) const {
result += "32";
}
};
template <>
struct type_name_builder_int_size<8> {
void operator()(std::string& result) const {
result += "64";
}
};
template <class T, bool IsInteger = std::is_integral<T>::value>
struct type_name_builder;
template <>
struct type_name_builder<bool, true> {
void operator()(std::string& result) const {
result += "boolean";
}
};
#define CAF_TYPE_NAME_BUILDER_NOINT(class_name, pretty_name) \
template <> \
struct type_name_builder<class_name, false> { \
void operator()(std::string& result) const { \
result += pretty_name; \
} \
}
CAF_TYPE_NAME_BUILDER_NOINT(float, "32-bit real");
CAF_TYPE_NAME_BUILDER_NOINT(double, "64-bit real");
CAF_TYPE_NAME_BUILDER_NOINT(timespan, "timespan");
CAF_TYPE_NAME_BUILDER_NOINT(std::string, "string");
CAF_TYPE_NAME_BUILDER_NOINT(atom_value, "atom");
CAF_TYPE_NAME_BUILDER_NOINT(uri, "uri");
#undef CAF_TYPE_NAME_BUILDER
template <class T>
struct type_name_builder<T, true> {
void operator()(std::string& result) const {
// TODO: replace with if constexpr when switching to C++17
if (!std::is_signed<T>::value)
result += 'u';
result += "int";
type_name_builder_int_size<sizeof(T)> g;
g(result);
}
};
template <class T>
struct type_name_builder<std::vector<T>, false> {
void operator()(std::string& result) const {
result += "list of ";
type_name_builder<T> g;
g(result);
}
};
template <class T>
struct type_name_builder<dictionary<T>, false> {
void operator()(std::string& result) const {
result += "dictionary of ";
type_name_builder<T> g;
g(result);
}
};
template <class T>
std::string type_name() {
std::string result;
type_name_builder<T> f;
f(result);
return result;
}
} // namespace detail
} // namespace caf
......@@ -23,7 +23,7 @@
#include "caf/config_option.hpp"
#include "caf/config_value.hpp"
#include "caf/detail/parse.hpp"
#include "caf/detail/type_name.hpp"
#include "caf/detail/type_traits.hpp"
#include "caf/error.hpp"
#include "caf/expected.hpp"
#include "caf/fwd.hpp"
......@@ -53,15 +53,15 @@ config_value get_impl(const void* ptr) {
template <class T>
expected<config_value> parse_impl(T* ptr, string_view str) {
if (ptr != nullptr) {
if (auto err = parse(str, *ptr))
return err;
return config_value{*ptr};
}
T tmp;
if (auto err = parse(str, tmp))
return err;
return config_value{std::move(tmp)};
config_value result{std::move(tmp)};
if (!holds_alternative<T>(result))
return pec::type_mismatch;
if (ptr != nullptr)
*ptr = get<T>(result);
return std::move(result);
}
expected<config_value> parse_impl(std::string* ptr, string_view str);
......@@ -73,9 +73,10 @@ expected<config_value> parse_impl_delegate(void* ptr, string_view str) {
template <class T>
config_option::meta_state* option_meta_state_instance() {
using trait = select_config_value_access_t<T>;
static config_option::meta_state obj{check_impl<T>, store_impl<T>,
get_impl<T>, parse_impl_delegate<T>,
detail::type_name<T>()};
trait::type_name()};
return &obj;
}
......
......@@ -24,9 +24,11 @@
#include "caf/optional.hpp"
#define DEFAULT_META(type, parse_fun) \
config_option::meta_state type##_meta_state{ \
default_config_option_check<type>, default_config_option_store<type>, \
get_impl<type>, parse_fun, detail::type_name<type>()};
config_option::meta_state \
type##_meta_state{default_config_option_check<type>, \
default_config_option_store<type>, get_impl<type>, \
parse_fun, \
select_config_value_access_t<type>::type_name()};
using std::string;
......@@ -75,43 +77,34 @@ config_value bool_get_neg(const void* ptr) {
}
meta_state bool_neg_meta{detail::check_impl<bool>, bool_store_neg, bool_get_neg,
nullptr, detail::type_name<bool>()};
meta_state us_res_meta{
[](const config_value& x) -> error {
if (holds_alternative<timespan>(x))
return none;
return make_error(pec::type_mismatch);
},
[](void* ptr, const config_value& x) {
*static_cast<size_t*>(ptr) = static_cast<size_t>(get<timespan>(x).count())
/ 1000;
},
[](const void* ptr) -> config_value {
auto ival = static_cast<int64_t>(*static_cast<const size_t*>(ptr));
timespan val{ival * 1000};
return config_value{val};
},
nullptr,
detail::type_name<timespan>()
};
meta_state ms_res_meta{[](const config_value& x) -> error {
if (holds_alternative<timespan>(x))
return none;
return make_error(pec::type_mismatch);
},
[](void* ptr, const config_value& x) {
*static_cast<size_t*>(ptr) = static_cast<size_t>(
get<timespan>(x).count() / 1000000);
},
[](const void* ptr) -> config_value {
auto ival = static_cast<int64_t>(
*static_cast<const size_t*>(ptr));
timespan val{ival * 1000000};
return config_value{val};
},
nullptr, detail::type_name<timespan>()};
nullptr,
select_config_value_access_t<bool>::type_name()};
error check_timespan(const config_value& x) {
if (holds_alternative<timespan>(x))
return none;
return make_error(pec::type_mismatch);
}
template <uint64_t Denominator>
void store_timespan(void* ptr, const config_value& x) {
*static_cast<size_t*>(ptr) = static_cast<size_t>(get<timespan>(x).count())
/ Denominator;
}
template <uint64_t Denominator>
config_value get_timespan(const void* ptr) {
auto ival = static_cast<int64_t>(*static_cast<const size_t*>(ptr));
timespan val{ival * 1000};
return config_value{val};
}
meta_state us_res_meta{check_timespan, store_timespan<1000>, get_timespan<1000>,
nullptr,
select_config_value_access_t<timespan>::type_name()};
meta_state ms_res_meta{check_timespan, store_timespan<1000000>,
get_timespan<1000000>, nullptr,
select_config_value_access_t<timespan>::type_name()};
} // namespace
......
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