[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.

Daniel Dunbar daniel at zuster.org
Tue Mar 26 21:11:38 PDT 2013


Hi Howard,

This change breaks building LLVM with libc++, as follows:
--
$ /Users/ddunbar/bin/xclang++ ...
/Users/ddunbar/llvm/lib/Transforms/Utils/CodeExtractor.cpp ... -I
~/public/libcxx/include
/Users/ddunbar/llvm/lib/Transforms/Utils/CodeExtractor.cpp:752:28: error:
      no matching constructor for initialization of 'std::vector<BasicBlock
*>'
  std::vector<BasicBlock*> Succs(succ_begin(codeReplacer),
                           ^     ~~~~~~~~~~~~~~~~~~~~~~~~~
/Users/ddunbar/public/libcxx/include/vector:523:5: note: candidate
constructor not viable:
      no known conversion from 'succ_iterator' (aka
'SuccIterator<llvm::TerminatorInst *,
      llvm::BasicBlock>') to 'size_type' (aka 'unsigned long') for 1st
argument
    vector(size_type __n, const_reference __x);
    ^
/Users/ddunbar/public/libcxx/include/vector:566:5: note: candidate
constructor not viable:
      no known conversion from 'succ_iterator' (aka
'SuccIterator<llvm::TerminatorInst *,
      llvm::BasicBlock>') to 'const std::__1::vector<llvm::BasicBlock *,
      std::__1::allocator<llvm::BasicBlock *> >' for 1st argument
    vector(const vector& __x, const allocator_type& __a);
    ^
/Users/ddunbar/public/libcxx/include/vector:527:35: note: candidate
template ignored:
      disabled by 'enable_if' [with _InputIterator =
      llvm::SuccIterator<llvm::TerminatorInst *, llvm::BasicBlock>]
               typename enable_if<__is_input_iterator
 <_InputIterator>::value &&
                                  ^
/Users/ddunbar/public/libcxx/include/vector:541:35: note: candidate
template ignored:
      disabled by 'enable_if' [with _ForwardIterator =
      llvm::SuccIterator<llvm::TerminatorInst *, llvm::BasicBlock>]
               typename
enable_if<__is_forward_iterator<_ForwardIterator>::value &&
                                  ^
/Users/ddunbar/public/libcxx/include/vector:533:9: note: candidate
constructor template
      not viable: requires at least 3 arguments, but 2 were provided
        vector(_InputIterator __first, _InputIterator __last, const
allocator_type& __a,
        ^
/Users/ddunbar/public/libcxx/include/vector:546:9: note: candidate
constructor template
      not viable: requires at least 3 arguments, but 2 were provided
        vector(_ForwardIterator __first, _ForwardIterator __last, const
allocator_...
        ^
/Users/ddunbar/public/libcxx/include/vector:508:5: note: candidate
constructor not viable:
      requires 0 arguments, but 2 were provided
    vector()
    ^
/Users/ddunbar/public/libcxx/include/vector:515:40: note: candidate
constructor not
      viable: requires single argument '__a', but 2 arguments were provided
    _LIBCPP_INLINE_VISIBILITY explicit vector(const allocator_type& __a)
                                       ^
/Users/ddunbar/public/libcxx/include/vector:522:14: note: candidate
constructor not
      viable: requires single argument '__n', but 2 arguments were provided
    explicit vector(size_type __n);
             ^
/Users/ddunbar/public/libcxx/include/vector:524:5: note: candidate
constructor not viable:
      requires 3 arguments, but 2 were provided
    vector(size_type __n, const_reference __x, const allocator_type& __a);
    ^
/Users/ddunbar/public/libcxx/include/vector:565:5: note: candidate
constructor not viable:
      requires single argument '__x', but 2 arguments were provided
    vector(const vector& __x);
    ^
1 error generated.
--

I reverted it in r178116 for the time being, can you take a look?

 - Daniel



On Tue, Mar 26, 2013 at 2:40 PM, Howard Hinnant <hhinnant at apple.com> wrote:

> 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), "");
>  }
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130326/4de0da41/attachment.html>


More information about the cfe-commits mailing list