Index: base/template_util.h |
diff --git a/base/template_util.h b/base/template_util.h |
index 0cf1477cf9a57b2e7326f5de40dae60f73bb4aa8..fb48b5a95459eee4f865dcd65d5c19ef53541eac 100644 |
--- a/base/template_util.h |
+++ b/base/template_util.h |
@@ -7,6 +7,7 @@ |
#include <stddef.h> |
#include <iosfwd> |
+#include <iterator> |
#include <type_traits> |
#include <utility> |
@@ -40,6 +41,19 @@ template <class T> struct is_non_const_reference : std::false_type {}; |
template <class T> struct is_non_const_reference<T&> : std::true_type {}; |
template <class T> struct is_non_const_reference<const T&> : std::false_type {}; |
+template <typename...> |
+struct make_void { |
+ using type = void; |
+}; |
+ |
+// A clone of C++17 std::void_t. |
+// Unlike the original version, we need |make_void| as a helper struct to avoid |
+// a C++14 defect. |
+// ref: http://en.cppreference.com/w/cpp/types/void_t |
+// ref: http://open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#1558 |
+template <typename... Ts> |
+using void_t = typename make_void<Ts...>::type; |
+ |
namespace internal { |
template <typename...> |
@@ -64,6 +78,17 @@ struct SupportsOstreamOperator<T, |
<< std::declval<T>()))> |
: std::true_type {}; |
+// Used to detech whether the given type is an iterator. This is normally used |
+// with std::enable_if to provide disambiguation for functions that take |
+// templatzed iterators as input. |
+template <typename T, typename = void> |
+struct is_iterator : std::false_type {}; |
+ |
+template <typename T> |
+struct is_iterator<T, |
+ void_t<typename std::iterator_traits<T>::iterator_category>> |
+ : std::true_type {}; |
+ |
} // namespace internal |
// is_trivially_copyable is especially hard to get right. |