Commit da6bf118 authored by Dominik Charousset's avatar Dominik Charousset

Fix handling of vector<bool>

parent d4e9f99b
......@@ -22,6 +22,7 @@
#include <functional>
#include <string>
#include <type_traits>
#include <vector>
#include "caf/detail/append_hex.hpp"
#include "caf/detail/apply_args.hpp"
......@@ -80,26 +81,23 @@ public:
void consume(const char* cstr);
void consume(float x);
void consume(const std::vector<bool>& xs);
void consume(double x);
void consume(long double x);
void consume(int64_t x);
void consume(uint64_t x);
template <class T>
enable_if_t<std::is_floating_point<T>::value> consume(T x) {
result_ += std::to_string(x);
}
template <class T>
enable_if_t<std::is_integral<T>::value && std::is_signed<T>::value>
consume(T x) {
consume(static_cast<int64_t>(x));
consume_int(static_cast<int64_t>(x));
}
template <class T>
enable_if_t<std::is_integral<T>::value && std::is_unsigned<T>::value>
consume(T x) {
consume(static_cast<uint64_t>(x));
consume_int(static_cast<uint64_t>(x));
}
template <class Clock, class Duration>
......@@ -165,6 +163,16 @@ public:
result_ += '}';
}
template <class Iterator>
void consume_range(Iterator first, Iterator last) {
result_ += '[';
while (first != last) {
sep();
consume(*first++);
}
result_ += ']';
}
template <class T>
enable_if_t<is_iterable<T>::value && !is_map_like<T>::value
&& !is_inspectable<stringification_inspector, T>::value
......@@ -172,14 +180,12 @@ public:
&& !is_inspectable<stringification_inspector, T>::value
&& !has_to_string<T>::value>
consume(const T& xs) {
result_ += '[';
// use a hand-written for loop instead of for-each to avoid
// range-loop-analysis warnings when using this function with vector<bool>
for (auto i = xs.begin(); i != xs.end(); ++i) {
sep();
consume(*i);
consume_range(xs.begin(), xs.end());
}
result_ += ']';
template <class T, size_t S>
void consume(const T (&xs)[S]) {
return consume_range(xs, xs + S);
}
template <class T>
......@@ -193,26 +199,6 @@ public:
result_ += ']';
}
template <class T>
void consume(const T* xs, size_t n) {
result_ += '(';
for (size_t i = 0; i < n; ++i) {
sep();
consume(xs[i]);
}
result_ += ')';
}
template <class T, size_t S>
void consume(const std::array<T, S>& xs) {
return consume(xs.data(), S);
}
template <class T, size_t S>
void consume(const T (&xs)[S]) {
return consume(xs, S);
}
template <class T>
enable_if_t<
std::is_pointer<T>::value
......@@ -304,6 +290,10 @@ public:
}
private:
void consume_int(int64_t x);
void consume_int(uint64_t x);
std::string& result_;
};
......
......@@ -173,21 +173,18 @@ void stringification_inspector::consume(const char* cstr) {
result_ += '"';
}
void stringification_inspector::consume(float x) {
result_ += std::to_string(x);
}
void stringification_inspector::consume(double x) {
result_ += std::to_string(x);
}
void stringification_inspector::consume(long double x) {
result_ += std::to_string(x);
void stringification_inspector::consume(const std::vector<bool>& xs) {
result_ += '[';
for (bool x : xs) {
sep();
consume(x);
}
result_ += ']';
}
void stringification_inspector::consume(int64_t x) {
void stringification_inspector::consume_int(int64_t x) {
if (x >= 0)
return consume(static_cast<uint64_t>(x));
return consume_int(static_cast<uint64_t>(x));
result_ += '-';
auto begin = result_.size();
result_ += -(x % 10) + '0';
......@@ -199,7 +196,7 @@ void stringification_inspector::consume(int64_t x) {
std::reverse(result_.begin() + begin, result_.end());
}
void stringification_inspector::consume(uint64_t x) {
void stringification_inspector::consume_int(uint64_t x) {
auto begin = result_.size();
result_ += (x % 10) + '0';
x /= 10;
......
......@@ -32,16 +32,38 @@ void foobar() {
} // namespace <anonymous>
#define CHECK_DEEP_TO_STRING(val, str) CAF_CHECK_EQUAL(deep_to_string(val), str)
CAF_TEST(timespans) {
CAF_CHECK_EQUAL(deep_to_string(timespan{1}), "1ns");
CAF_CHECK_EQUAL(deep_to_string(timespan{1000}), "1us");
CAF_CHECK_EQUAL(deep_to_string(timespan{1000000}), "1ms");
CAF_CHECK_EQUAL(deep_to_string(timespan{1000000000}), "1s");
CAF_CHECK_EQUAL(deep_to_string(timespan{60000000000}), "1min");
CHECK_DEEP_TO_STRING(timespan{1}, "1ns");
CHECK_DEEP_TO_STRING(timespan{1000}, "1us");
CHECK_DEEP_TO_STRING(timespan{1000000}, "1ms");
CHECK_DEEP_TO_STRING(timespan{1000000000}, "1s");
CHECK_DEEP_TO_STRING(timespan{60000000000}, "1min");
}
CAF_TEST(integer lists) {
int carray[] = {1, 2, 3, 4};
using array_type = std::array<int, 4>;
CHECK_DEEP_TO_STRING(std::list<int>({1, 2, 3, 4}), "[1, 2, 3, 4]");
CHECK_DEEP_TO_STRING(std::vector<int>({1, 2, 3, 4}), "[1, 2, 3, 4]");
CHECK_DEEP_TO_STRING(std::set<int>({1, 2, 3, 4}), "[1, 2, 3, 4]");
CHECK_DEEP_TO_STRING(array_type({{1, 2, 3, 4}}), "[1, 2, 3, 4]");
CHECK_DEEP_TO_STRING(carray, "[1, 2, 3, 4]");
}
CAF_TEST(boolean lists) {
bool carray[] = {false, true};
using array_type = std::array<bool, 2>;
CHECK_DEEP_TO_STRING(std::list<bool>({false, true}), "[false, true]");
CHECK_DEEP_TO_STRING(std::vector<bool>({false, true}), "[false, true]");
CHECK_DEEP_TO_STRING(std::set<bool>({false, true}), "[false, true]");
CHECK_DEEP_TO_STRING(array_type({{false, true}}), "[false, true]");
CHECK_DEEP_TO_STRING(carray, "[false, true]");
}
CAF_TEST(pointers) {
auto i = 42;
CAF_CHECK_EQUAL(deep_to_string(&i), "*42");
CAF_CHECK_EQUAL(deep_to_string(foobar), "<fun>");
CHECK_DEEP_TO_STRING(&i, "*42");
CHECK_DEEP_TO_STRING(foobar, "<fun>");
}
......@@ -272,10 +272,10 @@ CAF_TEST(tuples_to_string) {
}
CAF_TEST(arrays_to_string) {
CAF_CHECK_EQUAL(msg_as_string(s1{}), "((10, 20, 30))");
CAF_CHECK_EQUAL(msg_as_string(s1{}), "([10, 20, 30])");
auto msg2 = make_message(s2{});
s2 tmp;
tmp.value[0][1] = 100;
CAF_CHECK_EQUAL(to_string(msg2), "(((1, 10), (2, 20), (3, 30), (4, 40)))");
CAF_CHECK_EQUAL(msg_as_string(s3{}), "((1, 2, 3, 4))");
CAF_CHECK_EQUAL(to_string(msg2), "([[1, 10], [2, 20], [3, 30], [4, 40]])");
CAF_CHECK_EQUAL(msg_as_string(s3{}), "([1, 2, 3, 4])");
}
......@@ -554,7 +554,7 @@ SERIALIZATION_TEST(bool_vector_size_0) {
SERIALIZATION_TEST(bool_vector_size_1) {
std::vector<bool> xs{true};
CAF_CHECK_EQUAL(deep_to_string(xs), "[1]");
CAF_CHECK_EQUAL(deep_to_string(xs), "[true]");
CAF_CHECK_EQUAL(xs, roundtrip(xs));
CAF_CHECK_EQUAL(xs, msg_roundtrip(xs));
}
......@@ -563,11 +563,14 @@ SERIALIZATION_TEST(bool_vector_size_63) {
std::vector<bool> xs;
for (int i = 0; i < 63; ++i)
xs.push_back(i % 3 == 0);
CAF_CHECK_EQUAL(deep_to_string(xs),
"[1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, "
"0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, "
"1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, "
"0, 1, 0, 0]");
CAF_CHECK_EQUAL(
deep_to_string(xs),
"[true, false, false, true, false, false, true, false, false, true, false, "
"false, true, false, false, true, false, false, true, false, false, true, "
"false, false, true, false, false, true, false, false, true, false, false, "
"true, false, false, true, false, false, true, false, false, true, false, "
"false, true, false, false, true, false, false, true, false, false, true, "
"false, false, true, false, false, true, false, false]");
CAF_CHECK_EQUAL(xs, roundtrip(xs));
CAF_CHECK_EQUAL(xs, msg_roundtrip(xs));
}
......@@ -577,10 +580,14 @@ SERIALIZATION_TEST(bool_vector_size_64) {
for (int i = 0; i < 64; ++i)
xs.push_back(i % 5 == 0);
CAF_CHECK_EQUAL(deep_to_string(xs),
"[1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, "
"0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, "
"0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, "
"0, 1, 0, 0, 0]");
"[true, false, false, false, false, true, false, false, "
"false, false, true, false, false, false, false, true, "
"false, false, false, false, true, false, false, false, "
"false, true, false, false, false, false, true, false, "
"false, false, false, true, false, false, false, false, "
"true, false, false, false, false, true, false, false, "
"false, false, true, false, false, false, false, true, "
"false, false, false, false, true, false, false, false]");
CAF_CHECK_EQUAL(xs, roundtrip(xs));
CAF_CHECK_EQUAL(xs, msg_roundtrip(xs));
}
......@@ -589,11 +596,14 @@ SERIALIZATION_TEST(bool_vector_size_65) {
std::vector<bool> xs;
for (int i = 0; i < 65; ++i)
xs.push_back(!(i % 7 == 0));
CAF_CHECK_EQUAL(deep_to_string(xs),
"[0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, "
"1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, "
"1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, "
"1, 1, 1, 1, 0, 1]");
CAF_CHECK_EQUAL(
deep_to_string(xs),
"[false, true, true, true, true, true, true, false, true, true, true, "
"true, true, true, false, true, true, true, true, true, true, false, true, "
"true, true, true, true, true, false, true, true, true, true, true, true, "
"false, true, true, true, true, true, true, false, true, true, true, true, "
"true, true, false, true, true, true, true, true, true, false, true, true, "
"true, true, true, true, false, true]");
CAF_CHECK_EQUAL(xs, roundtrip(xs));
CAF_CHECK_EQUAL(xs, msg_roundtrip(xs));
}
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