Commit ce1e74c5 authored by Ivan Mylyanyk's avatar Ivan Mylyanyk Committed by Facebook Github Bot

allow dynamic to accept vector<bool>::reference

Summary:
`std::vector<bool>` is a bit specific ([1], [2] and [3]), so element access doesn't return bool, but `std::vector<bool>::reference`  instead. Folly did not know how to cast it to bool.
[1]: http://en.cppreference.com/w/cpp/container/vector_bool
[2]: http://en.cppreference.com/w/cpp/container/vector_bool/reference
[3]: https://en.wikipedia.org/w/index.php?title=Sequence_container_(C%2B%2B)&oldid=767869909#Specialization_for_bool

Reviewed By: yfeldblum, ot

Differential Revision: D7986013

fbshipit-source-id: 01c1350b3f6815e9da4ce6305f25e4b9b1ca9d6d
parent 44b2d6f5
...@@ -352,6 +352,9 @@ struct dynamic::NumericTypeHelper<double> { ...@@ -352,6 +352,9 @@ struct dynamic::NumericTypeHelper<double> {
using type = double; using type = double;
}; };
inline dynamic::dynamic(std::vector<bool>::reference b)
: dynamic(static_cast<bool>(b)) {}
template < template <
class T, class T,
class NumericType /* = typename NumericTypeHelper<T>::type */> class NumericType /* = typename NumericTypeHelper<T>::type */>
......
...@@ -172,6 +172,14 @@ struct dynamic : private boost::operators<dynamic> { ...@@ -172,6 +172,14 @@ struct dynamic : private boost::operators<dynamic> {
template <class T, class NumericType = typename NumericTypeHelper<T>::type> template <class T, class NumericType = typename NumericTypeHelper<T>::type>
/* implicit */ dynamic(T t); /* implicit */ dynamic(T t);
/*
* If v is vector<bool>, v[idx] is a proxy object implicitly convertible to
* bool. Calling a function f(dynamic) with f(v[idx]) would require a double
* implicit conversion (reference -> bool -> dynamic) which is not allowed,
* hence we explicitly accept the reference proxy.
*/
/* implicit */ dynamic(std::vector<bool>::reference val);
/* /*
* Create a dynamic that is an array of the values from the supplied * Create a dynamic that is an array of the values from the supplied
* iterator range. * iterator range.
......
...@@ -142,6 +142,22 @@ TEST(Dynamic, ObjectBasics) { ...@@ -142,6 +142,22 @@ TEST(Dynamic, ObjectBasics) {
EXPECT_EQ(mergeObj1, combinedPreferObj1); EXPECT_EQ(mergeObj1, combinedPreferObj1);
} }
TEST(Dynamic, CastFromVectorOfBooleans) {
std::vector<bool> b;
b.push_back(true);
b.push_back(false);
dynamic obj = dynamic::object("a", b[0])("b", b[1]);
EXPECT_EQ(obj.at("a"), true);
EXPECT_EQ(obj.at("b"), false);
}
TEST(Dynamic, CastFromConstVectorOfBooleans) {
const std::vector<bool> b = {true, false};
dynamic obj = dynamic::object("a", b[0])("b", b[1]);
EXPECT_EQ(obj.at("a"), true);
EXPECT_EQ(obj.at("b"), false);
}
TEST(Dynamic, ObjectErase) { TEST(Dynamic, ObjectErase) {
dynamic obj = dynamic::object("key1", "val") dynamic obj = dynamic::object("key1", "val")
("key2", "val2"); ("key2", "val2");
......
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