Commit 53ab97d2 authored by Dominik Charousset's avatar Dominik Charousset

Merge branch 'topic/config-value'

parents 5d4f8645 23979bf3
......@@ -20,6 +20,7 @@
#include <chrono>
#include <cstdint>
#include <iosfwd>
#include <iterator>
#include <map>
#include <string>
......@@ -452,6 +453,9 @@ inline bool operator!=(const config_value& x, const config_value& y) {
/// @relates config_value
std::string to_string(const config_value& x);
/// @relates config_value
std::ostream& operator<<(std::ostream& out, const config_value& x);
template <class... Ts>
config_value make_config_value_list(Ts&&... xs) {
std::vector<config_value> lst{config_value{std::forward<Ts>(xs)}...};
......
......@@ -24,24 +24,22 @@
#include <vector>
#include "caf/atom.hpp"
#include "caf/detail/append_hex.hpp"
#include "caf/detail/apply_args.hpp"
#include "caf/detail/int_list.hpp"
#include "caf/detail/type_traits.hpp"
#include "caf/error.hpp"
#include "caf/meta/annotation.hpp"
#include "caf/meta/hex_formatted.hpp"
#include "caf/meta/omittable.hpp"
#include "caf/meta/omittable_if_empty.hpp"
#include "caf/meta/omittable_if_none.hpp"
#include "caf/meta/type_name.hpp"
#include "caf/none.hpp"
#include "caf/string_view.hpp"
#include "caf/timespan.hpp"
#include "caf/timestamp.hpp"
#include "caf/meta/type_name.hpp"
#include "caf/meta/omittable.hpp"
#include "caf/meta/annotation.hpp"
#include "caf/meta/hex_formatted.hpp"
#include "caf/meta/omittable_if_none.hpp"
#include "caf/meta/omittable_if_empty.hpp"
#include "caf/detail/append_hex.hpp"
#include "caf/detail/apply_args.hpp"
#include "caf/detail/int_list.hpp"
#include "caf/detail/type_traits.hpp"
namespace caf {
namespace detail {
......@@ -154,7 +152,23 @@ public:
}
template <class T>
enable_if_t<is_iterable<T>::value
enable_if_t<is_map_like<T>::value
&& !is_inspectable<stringification_inspector, T>::value
&& !std::is_convertible<T, string_view>::value
&& !has_to_string<T>::value>
consume(T& xs) {
result_ += '{';
for (const auto& kvp : xs) {
sep();
consume(deconst(kvp.first));
result_ += " = ";
consume(deconst(kvp.second));
}
result_ += '}';
}
template <class T>
enable_if_t<is_list_like<T>::value
&& !is_inspectable<stringification_inspector, T>::value
&& !std::is_convertible<T, string_view>::value
&& !has_to_string<T>::value>
......
......@@ -53,11 +53,12 @@
class has_##name##_alias { \
private: \
template <class C> \
static std::true_type sfinae(C* ptr, typename C::name* arg = nullptr); \
static std::true_type sfinae(typename C::name*); \
\
static std::false_type sfinae(void* ptr); \
template <class> \
static std::false_type sfinae(...); \
\
using sfinae_type = decltype(sfinae(static_cast<T*>(nullptr))); \
using sfinae_type = decltype(sfinae<T>(nullptr)); \
\
public: \
static constexpr bool value = sfinae_type::value; \
......@@ -768,7 +769,7 @@ CAF_HAS_ALIAS_TRAIT(mapped_type);
// -- constexpr functions for use in enable_if & friends -----------------------
/// Checks whether T behaves like a `std::map` or a `std::unordered_map`.
/// Checks whether T behaves like `std::map`.
template <class T>
struct is_map_like {
static constexpr bool value = is_iterable<T>::value
......@@ -776,12 +777,11 @@ struct is_map_like {
&& has_mapped_type_alias<T>::value;
};
/// Checks whether T behaves like a `std::vector` or a `std::list`.
/// Checks whether T behaves like `std::vector`, `std::list`, or `std::set`.
template <class T>
struct is_list_like {
static constexpr bool value = is_iterable<T>::value
&& has_value_type_alias<T>::value
&& !has_key_type_alias<T>::value
&& !has_mapped_type_alias<T>::value;
};
......
......@@ -19,6 +19,8 @@
#include "caf/config_value.hpp"
#include <ostream>
#include "caf/detail/ini_consumer.hpp"
#include "caf/detail/parser/read_ini.hpp"
#include "caf/detail/type_traits.hpp"
......@@ -136,5 +138,8 @@ std::string to_string(const config_value& x) {
return deep_to_string(x.get_data());
}
} // namespace caf
std::ostream& operator<<(std::ostream& out, const config_value& x) {
return out << to_string(x);
}
} // namespace caf
......@@ -28,6 +28,7 @@ void stringification_inspector::sep() {
switch (result_.back()) {
case '(':
case '[':
case '{':
case ' ': // only at back if we've printed ", " before
break;
default:
......
......@@ -261,7 +261,7 @@ CAF_TEST(strings_to_string) {
CAF_TEST(maps_to_string) {
map<int, int> m1{{1, 10}, {2, 20}, {3, 30}};
auto msg1 = make_message(move(m1));
CAF_CHECK_EQUAL(to_string(msg1), "([(1, 10), (2, 20), (3, 30)])");
CAF_CHECK_EQUAL(to_string(msg1), "({1 = 10, 2 = 20, 3 = 30})");
}
CAF_TEST(tuples_to_string) {
......
......@@ -233,7 +233,7 @@ CAF_TEST(unary visit) {
x = string{"hello world"};
CAF_CHECK_EQUAL(visit(stringify, x), "hello world");
x = map_type{{1, 1}, {2, 2}};
CAF_CHECK_EQUAL(visit(stringify, x), "[(1, 1), (2, 2)]");
CAF_CHECK_EQUAL(visit(stringify, x), "{1 = 1, 2 = 2}");
}
CAF_TEST(binary visit) {
......@@ -253,5 +253,5 @@ CAF_TEST(ternary visit) {
x = 42;
y = string{"foo"};
z = map_type{{1, 1}, {2, 2}};
CAF_CHECK_EQUAL(visit(stringify, x, y, z), "42, foo, [(1, 1), (2, 2)]");
CAF_CHECK_EQUAL(visit(stringify, x, y, z), "42, foo, {1 = 1, 2 = 2}");
}
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