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 @@ ...@@ -23,7 +23,7 @@
#include "caf/config_option.hpp" #include "caf/config_option.hpp"
#include "caf/config_value.hpp" #include "caf/config_value.hpp"
#include "caf/detail/parse.hpp" #include "caf/detail/parse.hpp"
#include "caf/detail/type_name.hpp" #include "caf/detail/type_traits.hpp"
#include "caf/error.hpp" #include "caf/error.hpp"
#include "caf/expected.hpp" #include "caf/expected.hpp"
#include "caf/fwd.hpp" #include "caf/fwd.hpp"
...@@ -53,15 +53,15 @@ config_value get_impl(const void* ptr) { ...@@ -53,15 +53,15 @@ config_value get_impl(const void* ptr) {
template <class T> template <class T>
expected<config_value> parse_impl(T* ptr, string_view str) { 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; T tmp;
if (auto err = parse(str, tmp)) if (auto err = parse(str, tmp))
return err; 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); 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) { ...@@ -73,9 +73,10 @@ expected<config_value> parse_impl_delegate(void* ptr, string_view str) {
template <class T> template <class T>
config_option::meta_state* option_meta_state_instance() { 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>, static config_option::meta_state obj{check_impl<T>, store_impl<T>,
get_impl<T>, parse_impl_delegate<T>, get_impl<T>, parse_impl_delegate<T>,
detail::type_name<T>()}; trait::type_name()};
return &obj; return &obj;
} }
......
...@@ -24,9 +24,11 @@ ...@@ -24,9 +24,11 @@
#include "caf/optional.hpp" #include "caf/optional.hpp"
#define DEFAULT_META(type, parse_fun) \ #define DEFAULT_META(type, parse_fun) \
config_option::meta_state type##_meta_state{ \ config_option::meta_state \
default_config_option_check<type>, default_config_option_store<type>, \ type##_meta_state{default_config_option_check<type>, \
get_impl<type>, parse_fun, detail::type_name<type>()}; default_config_option_store<type>, get_impl<type>, \
parse_fun, \
select_config_value_access_t<type>::type_name()};
using std::string; using std::string;
...@@ -75,43 +77,34 @@ config_value bool_get_neg(const void* ptr) { ...@@ -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, meta_state bool_neg_meta{detail::check_impl<bool>, bool_store_neg, bool_get_neg,
nullptr, detail::type_name<bool>()}; nullptr,
select_config_value_access_t<bool>::type_name()};
meta_state us_res_meta{
[](const config_value& x) -> error { error check_timespan(const config_value& x) {
if (holds_alternative<timespan>(x)) if (holds_alternative<timespan>(x))
return none; return none;
return make_error(pec::type_mismatch); 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()) template <uint64_t Denominator>
/ 1000; void store_timespan(void* ptr, const config_value& x) {
}, *static_cast<size_t*>(ptr) = static_cast<size_t>(get<timespan>(x).count())
[](const void* ptr) -> config_value { / Denominator;
auto ival = static_cast<int64_t>(*static_cast<const size_t*>(ptr)); }
timespan val{ival * 1000}; template <uint64_t Denominator>
return config_value{val}; config_value get_timespan(const void* ptr) {
}, auto ival = static_cast<int64_t>(*static_cast<const size_t*>(ptr));
nullptr, timespan val{ival * 1000};
detail::type_name<timespan>() return config_value{val};
}; }
meta_state ms_res_meta{[](const config_value& x) -> error { meta_state us_res_meta{check_timespan, store_timespan<1000>, get_timespan<1000>,
if (holds_alternative<timespan>(x)) nullptr,
return none; select_config_value_access_t<timespan>::type_name()};
return make_error(pec::type_mismatch);
}, meta_state ms_res_meta{check_timespan, store_timespan<1000000>,
[](void* ptr, const config_value& x) { get_timespan<1000000>, nullptr,
*static_cast<size_t*>(ptr) = static_cast<size_t>( select_config_value_access_t<timespan>::type_name()};
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>()};
} // namespace } // 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