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

Merge branch 'topic/config-value'

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