From: Nicholas Ormrod Date: Tue, 6 Nov 2012 17:22:57 +0000 (-0800) Subject: Augment DynamicConverter's is_container check X-Git-Tag: v0.22.0~1154 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=c9f168a1db1138aeb73bfc87b34e75e03f414c91;p=folly.git Augment DynamicConverter's is_container check Summary: DynamicConverter uses some simple heuristics to determine if a class is a container. One of those tests was to check that the constructor 'template [container-name](Iterator first, Iterator last)' was present. That test was performed by checking if the class could be constructed by two parameters of some dummy class. However, it is possible to restrict the template parameter such that it only accepts iterators, and not any arbitrary dummy class. This would be useful, for example, to solve overload ambiguity with constructors like 'vector(const T& val, size_type n)', where T and size_type are the same (see N3337 23.2.3 item 14). It also (I believe) produces more meaningful compiler errors when a non-iterator is supplied, since it errors at the function callsite instead of inside the constructor itself. The new FBVector implementation uses such a feature, and so checking for [container-name](dummy, dummy) will fail. Hence the dummy class has been upgraded to reverse_iterator, a valid iterator class which almost certainly does not have a specialized contructor in any class (and hence will not cause any visible change in class_is_container's value). Test Plan: Run DynamicConverterTest; it has tests for the correctness of class_is_container. Reviewed By: delong.j@fb.com FB internal diff: D620607 --- diff --git a/folly/DynamicConverter.h b/folly/DynamicConverter.h index 2f0a1205..b36a56cd 100644 --- a/folly/DynamicConverter.h +++ b/folly/DynamicConverter.h @@ -37,6 +37,7 @@ namespace folly { #include +#include #include #include #include "folly/Likely.h" @@ -59,10 +60,10 @@ template struct map_container_has_correct_types typename T::value_type> {}; template struct class_is_container { - struct dummy {}; + typedef std::reverse_iterator some_iterator; enum { value = has_value_type::value && has_iterator::value && - std::is_constructible::value }; + std::is_constructible::value }; }; template struct container_is_map