[libcxx] r178075 - Tighten up the iterator requirements for the vector member templates. This is especially important for the constructors so that is_constructible<vector<T>, I, I> gives the right answer when T can not be constructed from *I. Test case included for this latter point.

Howard Hinnant hhinnant at apple.com
Tue Mar 26 14:40:54 PDT 2013


Author: hhinnant
Date: Tue Mar 26 16:40:54 2013
New Revision: 178075

URL: http://llvm.org/viewvc/llvm-project?rev=178075&view=rev
Log:
Tighten up the iterator requirements for the vector member templates.  This is especially important for the constructors so that is_constructible<vector<T>, I, I> gives the right answer when T can not be constructed from *I.  Test case included for this latter point.

Modified:
    libcxx/trunk/include/vector
    libcxx/trunk/test/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp

Modified: libcxx/trunk/include/vector
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/vector?rev=178075&r1=178074&r2=178075&view=diff
==============================================================================
--- libcxx/trunk/include/vector (original)
+++ libcxx/trunk/include/vector Tue Mar 26 16:40:54 2013
@@ -526,17 +526,29 @@ public:
     template <class _InputIterator>
         vector(_InputIterator __first, _InputIterator __last,
                typename enable_if<__is_input_iterator  <_InputIterator>::value &&
-                                 !__is_forward_iterator<_InputIterator>::value>::type* = 0);
+                                 !__is_forward_iterator<_InputIterator>::value &&
+                                 is_constructible<
+                                    value_type,
+                                    typename iterator_traits<_InputIterator>::reference>::value>::type* = 0);
     template <class _InputIterator>
         vector(_InputIterator __first, _InputIterator __last, const allocator_type& __a,
                typename enable_if<__is_input_iterator  <_InputIterator>::value &&
-                                 !__is_forward_iterator<_InputIterator>::value>::type* = 0);
+                                 !__is_forward_iterator<_InputIterator>::value &&
+                                 is_constructible<
+                                    value_type,
+                                    typename iterator_traits<_InputIterator>::reference>::value>::type* = 0);
     template <class _ForwardIterator>
         vector(_ForwardIterator __first, _ForwardIterator __last,
-               typename enable_if<__is_forward_iterator<_ForwardIterator>::value>::type* = 0);
+               typename enable_if<__is_forward_iterator<_ForwardIterator>::value &&
+                                 is_constructible<
+                                    value_type,
+                                    typename iterator_traits<_ForwardIterator>::reference>::value>::type* = 0);
     template <class _ForwardIterator>
         vector(_ForwardIterator __first, _ForwardIterator __last, const allocator_type& __a,
-               typename enable_if<__is_forward_iterator<_ForwardIterator>::value>::type* = 0);
+               typename enable_if<__is_forward_iterator<_ForwardIterator>::value &&
+                                 is_constructible<
+                                    value_type,
+                                    typename iterator_traits<_ForwardIterator>::reference>::value>::type* = 0);
 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
     _LIBCPP_INLINE_VISIBILITY
     vector(initializer_list<value_type> __il);
@@ -577,14 +589,20 @@ public:
         typename enable_if
         <
              __is_input_iterator  <_InputIterator>::value &&
-            !__is_forward_iterator<_InputIterator>::value,
+            !__is_forward_iterator<_InputIterator>::value &&
+            is_constructible<
+                 value_type,
+                 typename iterator_traits<_InputIterator>::reference>::value,
             void
         >::type
         assign(_InputIterator __first, _InputIterator __last);
     template <class _ForwardIterator>
         typename enable_if
         <
-            __is_forward_iterator<_ForwardIterator>::value,
+            __is_forward_iterator<_ForwardIterator>::value &&
+            is_constructible<
+                 value_type,
+                 typename iterator_traits<_ForwardIterator>::reference>::value,
             void
         >::type
         assign(_ForwardIterator __first, _ForwardIterator __last);
@@ -700,14 +718,20 @@ public:
         typename enable_if
         <
              __is_input_iterator  <_InputIterator>::value &&
-            !__is_forward_iterator<_InputIterator>::value,
+            !__is_forward_iterator<_InputIterator>::value &&
+            is_constructible<
+                 value_type,
+                 typename iterator_traits<_InputIterator>::reference>::value,
             iterator
         >::type
         insert(const_iterator __position, _InputIterator __first, _InputIterator __last);
     template <class _ForwardIterator>
         typename enable_if
         <
-            __is_forward_iterator<_ForwardIterator>::value,
+            __is_forward_iterator<_ForwardIterator>::value &&
+            is_constructible<
+                 value_type,
+                 typename iterator_traits<_ForwardIterator>::reference>::value,
             iterator
         >::type
         insert(const_iterator __position, _ForwardIterator __first, _ForwardIterator __last);
@@ -1034,7 +1058,10 @@ template <class _Tp, class _Allocator>
 template <class _InputIterator>
 vector<_Tp, _Allocator>::vector(_InputIterator __first, _InputIterator __last,
        typename enable_if<__is_input_iterator  <_InputIterator>::value &&
-                         !__is_forward_iterator<_InputIterator>::value>::type*)
+                         !__is_forward_iterator<_InputIterator>::value &&
+                         is_constructible<
+                            value_type,
+                            typename iterator_traits<_InputIterator>::reference>::value>::type*)
 {
 #if _LIBCPP_DEBUG_LEVEL >= 2
     __get_db()->__insert_c(this);
@@ -1047,7 +1074,10 @@ template <class _Tp, class _Allocator>
 template <class _InputIterator>
 vector<_Tp, _Allocator>::vector(_InputIterator __first, _InputIterator __last, const allocator_type& __a,
        typename enable_if<__is_input_iterator  <_InputIterator>::value &&
-                         !__is_forward_iterator<_InputIterator>::value>::type*)
+                         !__is_forward_iterator<_InputIterator>::value &&
+                         is_constructible<
+                            value_type,
+                            typename iterator_traits<_InputIterator>::reference>::value>::type*)
     : __base(__a)
 {
 #if _LIBCPP_DEBUG_LEVEL >= 2
@@ -1060,7 +1090,10 @@ vector<_Tp, _Allocator>::vector(_InputIt
 template <class _Tp, class _Allocator>
 template <class _ForwardIterator>
 vector<_Tp, _Allocator>::vector(_ForwardIterator __first, _ForwardIterator __last,
-                                typename enable_if<__is_forward_iterator<_ForwardIterator>::value>::type*)
+                                typename enable_if<__is_forward_iterator<_ForwardIterator>::value &&
+                                is_constructible<
+                                   value_type,
+                                   typename iterator_traits<_ForwardIterator>::reference>::value>::type*)
 {
 #if _LIBCPP_DEBUG_LEVEL >= 2
     __get_db()->__insert_c(this);
@@ -1076,7 +1109,10 @@ vector<_Tp, _Allocator>::vector(_Forward
 template <class _Tp, class _Allocator>
 template <class _ForwardIterator>
 vector<_Tp, _Allocator>::vector(_ForwardIterator __first, _ForwardIterator __last, const allocator_type& __a,
-                                typename enable_if<__is_forward_iterator<_ForwardIterator>::value>::type*)
+                                typename enable_if<__is_forward_iterator<_ForwardIterator>::value &&
+                                is_constructible<
+                                   value_type,
+                                   typename iterator_traits<_ForwardIterator>::reference>::value>::type*)
     : __base(__a)
 {
 #if _LIBCPP_DEBUG_LEVEL >= 2
@@ -1258,7 +1294,10 @@ template <class _InputIterator>
 typename enable_if
 <
      __is_input_iterator  <_InputIterator>::value &&
-    !__is_forward_iterator<_InputIterator>::value,
+    !__is_forward_iterator<_InputIterator>::value &&
+    is_constructible<
+       _Tp,
+       typename iterator_traits<_InputIterator>::reference>::value,
     void
 >::type
 vector<_Tp, _Allocator>::assign(_InputIterator __first, _InputIterator __last)
@@ -1272,7 +1311,10 @@ template <class _Tp, class _Allocator>
 template <class _ForwardIterator>
 typename enable_if
 <
-    __is_forward_iterator<_ForwardIterator>::value,
+    __is_forward_iterator<_ForwardIterator>::value &&
+    is_constructible<
+       _Tp,
+       typename iterator_traits<_ForwardIterator>::reference>::value,
     void
 >::type
 vector<_Tp, _Allocator>::assign(_ForwardIterator __first, _ForwardIterator __last)
@@ -1753,7 +1795,10 @@ template <class _InputIterator>
 typename enable_if
 <
      __is_input_iterator  <_InputIterator>::value &&
-    !__is_forward_iterator<_InputIterator>::value,
+    !__is_forward_iterator<_InputIterator>::value &&
+    is_constructible<
+       _Tp,
+       typename iterator_traits<_InputIterator>::reference>::value,
     typename vector<_Tp, _Allocator>::iterator
 >::type
 vector<_Tp, _Allocator>::insert(const_iterator __position, _InputIterator __first, _InputIterator __last)
@@ -1805,7 +1850,10 @@ template <class _Tp, class _Allocator>
 template <class _ForwardIterator>
 typename enable_if
 <
-    __is_forward_iterator<_ForwardIterator>::value,
+    __is_forward_iterator<_ForwardIterator>::value &&
+    is_constructible<
+       _Tp,
+       typename iterator_traits<_ForwardIterator>::reference>::value,
     typename vector<_Tp, _Allocator>::iterator
 >::type
 vector<_Tp, _Allocator>::insert(const_iterator __position, _ForwardIterator __first, _ForwardIterator __last)

Modified: libcxx/trunk/test/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp?rev=178075&r1=178074&r2=178075&view=diff
==============================================================================
--- libcxx/trunk/test/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp (original)
+++ libcxx/trunk/test/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp Tue Mar 26 16:40:54 2013
@@ -28,6 +28,10 @@ test(Iterator first, Iterator last)
         assert(*i == *first);
 }
 
+struct X
+{
+};
+
 int main()
 {
     int a[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 7, 6, 5, 4, 3, 1, 0};
@@ -43,4 +47,7 @@ int main()
     test<std::vector<int, stack_allocator<int, 18> > >(bidirectional_iterator<const int*>(a), bidirectional_iterator<const int*>(an));
     test<std::vector<int, stack_allocator<int, 18> > >(random_access_iterator<const int*>(a), random_access_iterator<const int*>(an));
     test<std::vector<int, stack_allocator<int, 18> > >(a, an);
+
+    X x[2];
+    static_assert(!(std::is_constructible<std::vector<int>, X*, X*>::value), "");
 }





More information about the cfe-commits mailing list