OSDN Git Service

2007-11-05 Chris Jefferson <chris@bubblescope.net>
authorpaolo <paolo@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 5 Nov 2007 19:46:07 +0000 (19:46 +0000)
committerpaolo <paolo@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 5 Nov 2007 19:46:07 +0000 (19:46 +0000)
    Paolo Carlini  <pcarlini@suse.de>

* include/bits/stl_vector.h (vector<>::push_back<>(_Args...),
emplace<>(iterator, _Args...), insert(iterator, _Tp&&),
_M_insert_aux<>(iterator, _Args&&...)): Add.
* include/bits/vector.tcc (insert(iterator, value_type&&),
emplace<>(iterator, _Args...), _M_insert_aux<>(iterator, _Args&&...)):
Define.
(_M_fill_insert(iterator, size_type, const value_type&),
_M_range_insert(iterator, _ForwardIterator, _ForwardIterator,
std::forward_iterator_tag)): Use __uninitialized_move_a,
_GLIBCXX_MOVE_BACKWARD3 when possible.
* include/bits/stl_uninitialized.h (__uninitialized_move_a): Add.
* include/debug/vector (vector<>::push_back<>(_Args...),
emplace<>(iterator, _Args...), insert(iterator, _Tp&&)): Add.
* testsuite/23_containers/vector/modifiers/moveable.cc: Enable.
* testsuite/23_containers/vector/resize/moveable.cc: Likewise.
* testsuite/23_containers/vector/cons/moveable.cc: Likewise.
* testsuite/23_containers/vector/requirements/dr438/assign_neg.cc:
Adjust dg-error line numbers.
* testsuite/23_containers/vector/requirements/dr438/insert_neg.cc:
Likewise.
* testsuite/23_containers/vector/requirements/dr438/
constructor_1_neg.cc: Likewise.
* testsuite/23_containers/vector/requirements/dr438/
constructor_2_neg.cc: Likewise.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@129907 138bc75d-0d04-0410-961f-82ee72b054a4

12 files changed:
libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/stl_uninitialized.h
libstdc++-v3/include/bits/stl_vector.h
libstdc++-v3/include/bits/vector.tcc
libstdc++-v3/include/debug/vector
libstdc++-v3/testsuite/23_containers/vector/cons/moveable.cc
libstdc++-v3/testsuite/23_containers/vector/modifiers/moveable.cc
libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc
libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc
libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc
libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc
libstdc++-v3/testsuite/23_containers/vector/resize/moveable.cc

index 9687899..36c9f4b 100644 (file)
@@ -1,3 +1,31 @@
+2007-11-05  Chris Jefferson  <chris@bubblescope.net>
+           Paolo Carlini  <pcarlini@suse.de>
+
+       * include/bits/stl_vector.h (vector<>::push_back<>(_Args...),
+       emplace<>(iterator, _Args...), insert(iterator, _Tp&&),
+       _M_insert_aux<>(iterator, _Args&&...)): Add.
+       * include/bits/vector.tcc (insert(iterator, value_type&&),
+       emplace<>(iterator, _Args...), _M_insert_aux<>(iterator, _Args&&...)):
+       Define.
+       (_M_fill_insert(iterator, size_type, const value_type&),
+       _M_range_insert(iterator, _ForwardIterator, _ForwardIterator,
+       std::forward_iterator_tag)): Use __uninitialized_move_a,
+       _GLIBCXX_MOVE_BACKWARD3 when possible.
+       * include/bits/stl_uninitialized.h (__uninitialized_move_a): Add.
+       * include/debug/vector (vector<>::push_back<>(_Args...),
+       emplace<>(iterator, _Args...), insert(iterator, _Tp&&)): Add.
+       * testsuite/23_containers/vector/modifiers/moveable.cc: Enable.
+       * testsuite/23_containers/vector/resize/moveable.cc: Likewise.
+       * testsuite/23_containers/vector/cons/moveable.cc: Likewise.
+       * testsuite/23_containers/vector/requirements/dr438/assign_neg.cc:
+       Adjust dg-error line numbers.
+       * testsuite/23_containers/vector/requirements/dr438/insert_neg.cc:
+       Likewise.
+       * testsuite/23_containers/vector/requirements/dr438/
+       constructor_1_neg.cc: Likewise.
+       * testsuite/23_containers/vector/requirements/dr438/
+       constructor_2_neg.cc: Likewise.
+
 2007-11-03  Paolo Carlini  <pcarlini@suse.de>
            Kai-Uwe Bux  <bux@kubux.net>
 
index d3e7a2c..6f7437a 100644 (file)
@@ -261,6 +261,17 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
                           _ForwardIterator __result, allocator<_Tp>&)
     { return std::uninitialized_copy(__first, __last, __result); }
 
+  template<typename _InputIterator, typename _ForwardIterator,
+          typename _Allocator>
+    inline _ForwardIterator
+    __uninitialized_move_a(_InputIterator __first, _InputIterator __last,
+                          _ForwardIterator __result, _Allocator& __alloc)
+    {
+      return std::__uninitialized_copy_a(_GLIBCXX_MAKE_MOVE_ITERATOR(__first),
+                                        _GLIBCXX_MAKE_MOVE_ITERATOR(__last),
+                                        __result, __alloc);
+    }
+
   template<typename _ForwardIterator, typename _Tp, typename _Allocator>
     void
     __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last,
index f48fbdb..bf2cc27 100644 (file)
@@ -683,6 +683,7 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
        *  done in constant time if the %vector has preallocated space
        *  available.
        */
+#ifndef __GXX_EXPERIMENTAL_CXX0X__
       void
       push_back(const value_type& __x)
       {
@@ -694,6 +695,21 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
        else
          _M_insert_aux(end(), __x);
       }
+#else
+      template<typename... _Args>
+        void
+        push_back(_Args&&... __args)
+       {
+         if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage)
+           {
+             this->_M_impl.construct(this->_M_impl._M_finish,
+                                     std::forward<_Args>(__args)...);
+             ++this->_M_impl._M_finish;
+           }
+         else
+           _M_insert_aux(end(), std::forward<_Args>(__args)...);
+       }
+#endif
 
       /**
        *  @brief  Removes last element.
@@ -711,6 +727,24 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
        this->_M_impl.destroy(this->_M_impl._M_finish);
       }
 
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+      /**
+       *  @brief  Inserts an object in %vector before specified iterator.
+       *  @param  position  An iterator into the %vector.
+       *  @param  args  Arguments.
+       *  @return  An iterator that points to the inserted data.
+       *
+       *  This function will insert an object of type T constructed
+       *  with T(std::forward<Args>(args)...) before the specified location.
+       *  Note that this kind of operation could be expensive for a %vector
+       *  and if it is frequently used the user should consider using
+       *  std::list.
+       */
+      template<typename... _Args>
+        iterator
+        emplace(iterator __position, _Args&&... __args);
+#endif
+
       /**
        *  @brief  Inserts given value into %vector before specified iterator.
        *  @param  position  An iterator into the %vector.
@@ -725,6 +759,22 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
       iterator
       insert(iterator __position, const value_type& __x);
 
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+      /**
+       *  @brief  Inserts given rvalue into %vector before specified iterator.
+       *  @param  position  An iterator into the %vector.
+       *  @param  x  Data to be inserted.
+       *  @return  An iterator that points to the inserted data.
+       *
+       *  This function will insert a copy of the given rvalue before
+       *  the specified location.  Note that this kind of operation
+       *  could be expensive for a %vector and if it is frequently
+       *  used the user should consider using std::list.
+       */
+      iterator
+      insert(iterator __position, value_type&& __x);
+#endif
+
       /**
        *  @brief  Inserts a number of copies of given data into the %vector.
        *  @param  position  An iterator into the %vector.
@@ -1014,8 +1064,14 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
       _M_fill_insert(iterator __pos, size_type __n, const value_type& __x);
 
       // Called by insert(p,x)
+#ifndef __GXX_EXPERIMENTAL_CXX0X__
       void
       _M_insert_aux(iterator __position, const value_type& __x);
+#else
+      template<typename... _Args>
+        void
+        _M_insert_aux(iterator __position, _Args&&... __args);
+#endif
 
       // Called by the latter.
       size_type
index e15d80d..b097f44 100644 (file)
@@ -105,6 +105,26 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
       return iterator(this->_M_impl._M_start + __n);
     }
 
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+  template<typename _Tp, typename _Alloc>
+    typename vector<_Tp, _Alloc>::iterator
+    vector<_Tp, _Alloc>::
+    insert(iterator __position, value_type&& __x)
+    {
+      const size_type __n = __position - begin();
+      if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage
+         && __position == end())
+       {
+         this->_M_impl.construct(this->_M_impl._M_finish,
+                                 std::forward<value_type>(__x));
+         ++this->_M_impl._M_finish;
+       }
+      else
+        _M_insert_aux(__position, std::forward<value_type>(__x));
+      return iterator(this->_M_impl._M_start + __n);
+    }
+#endif
+
   template<typename _Tp, typename _Alloc>
     typename vector<_Tp, _Alloc>::iterator
     vector<_Tp, _Alloc>::
@@ -241,21 +261,53 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
          }
       }
 
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+  template<typename _Tp, typename _Alloc>
+    template<typename... _Args>
+      typename vector<_Tp, _Alloc>::iterator
+      vector<_Tp, _Alloc>::
+      emplace(iterator __position, _Args&&... __args)
+      {
+       const size_type __n = __position - begin();
+       if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage
+           && __position == end())
+         {
+           this->_M_impl.construct(this->_M_impl._M_finish,
+                                   std::forward<_Args>(__args)...);
+           ++this->_M_impl._M_finish;
+         }
+       else
+         _M_insert_aux(__position, std::forward<_Args>(__args)...);
+       return iterator(this->_M_impl._M_start + __n);
+      }
+
+  template<typename _Tp, typename _Alloc>
+    template<typename... _Args>
+      void
+      vector<_Tp, _Alloc>::
+      _M_insert_aux(iterator __position, _Args&&... __args)
+      {
+       _Tp __x_copy(std::forward<_Args>(__args)...);
+#else
   template<typename _Tp, typename _Alloc>
     void
     vector<_Tp, _Alloc>::
     _M_insert_aux(iterator __position, const _Tp& __x)
     {
+#endif
       if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage)
        {
          this->_M_impl.construct(this->_M_impl._M_finish,
-                                 *(this->_M_impl._M_finish - 1));
+                                 _GLIBCXX_MOVE(*(this->_M_impl._M_finish
+                                                 - 1)));
          ++this->_M_impl._M_finish;
+#ifndef __GXX_EXPERIMENTAL_CXX0X__
          _Tp __x_copy = __x;
-         std::copy_backward(__position.base(),
-                            this->_M_impl._M_finish - 2,
-                            this->_M_impl._M_finish - 1);
-         *__position = __x_copy;
+#endif
+         _GLIBCXX_MOVE_BACKWARD3(__position.base(),
+                                 this->_M_impl._M_finish - 2,
+                                 this->_M_impl._M_finish - 1);
+         *__position = _GLIBCXX_MOVE(__x_copy);
        }
       else
        {
@@ -266,13 +318,17 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
          try
            {
              __new_finish =
-               std::__uninitialized_copy_a(this->_M_impl._M_start,
+               std::__uninitialized_move_a(this->_M_impl._M_start,
                                            __position.base(), __new_start,
                                            _M_get_Tp_allocator());
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+             this->_M_impl.construct(__new_finish, std::move(__x_copy));
+#else
              this->_M_impl.construct(__new_finish, __x);
+#endif
              ++__new_finish;
              __new_finish =
-               std::__uninitialized_copy_a(__position.base(),
+               std::__uninitialized_move_a(__position.base(),
                                            this->_M_impl._M_finish,
                                            __new_finish,
                                            _M_get_Tp_allocator());
@@ -301,21 +357,26 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
     {
       if (__n != 0)
        {
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+         value_type __x_copy = __x;
+#endif
          if (size_type(this->_M_impl._M_end_of_storage
                        - this->_M_impl._M_finish) >= __n)
            {
+#ifndef __GXX_EXPERIMENTAL_CXX0X__
              value_type __x_copy = __x;
+#endif
              const size_type __elems_after = end() - __position;
              pointer __old_finish(this->_M_impl._M_finish);
              if (__elems_after > __n)
                {
-                 std::__uninitialized_copy_a(this->_M_impl._M_finish - __n,
+                 std::__uninitialized_move_a(this->_M_impl._M_finish - __n,
                                              this->_M_impl._M_finish,
                                              this->_M_impl._M_finish,
                                              _M_get_Tp_allocator());
                  this->_M_impl._M_finish += __n;
-                 std::copy_backward(__position.base(), __old_finish - __n,
-                                    __old_finish);
+                 _GLIBCXX_MOVE_BACKWARD3(__position.base(),
+                                         __old_finish - __n, __old_finish);
                  std::fill(__position.base(), __position.base() + __n,
                            __x_copy);
                }
@@ -326,7 +387,7 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
                                                __x_copy,
                                                _M_get_Tp_allocator());
                  this->_M_impl._M_finish += __n - __elems_after;
-                 std::__uninitialized_copy_a(__position.base(), __old_finish,
+                 std::__uninitialized_move_a(__position.base(), __old_finish,
                                              this->_M_impl._M_finish,
                                              _M_get_Tp_allocator());
                  this->_M_impl._M_finish += __elems_after;
@@ -342,15 +403,19 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
              try
                {
                  __new_finish =
-                   std::__uninitialized_copy_a(this->_M_impl._M_start,
+                   std::__uninitialized_move_a(this->_M_impl._M_start,
                                                __position.base(),
                                                __new_start,
                                                _M_get_Tp_allocator());
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+                 std::__uninitialized_fill_n_a(__new_finish, __n, __x_copy,
+#else
                  std::__uninitialized_fill_n_a(__new_finish, __n, __x,
+#endif
                                                _M_get_Tp_allocator());
                  __new_finish += __n;
                  __new_finish =
-                   std::__uninitialized_copy_a(__position.base(),
+                   std::__uninitialized_move_a(__position.base(),
                                                this->_M_impl._M_finish,
                                                __new_finish,
                                                _M_get_Tp_allocator());
@@ -405,13 +470,13 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
                pointer __old_finish(this->_M_impl._M_finish);
                if (__elems_after > __n)
                  {
-                   std::__uninitialized_copy_a(this->_M_impl._M_finish - __n,
+                   std::__uninitialized_move_a(this->_M_impl._M_finish - __n,
                                                this->_M_impl._M_finish,
                                                this->_M_impl._M_finish,
                                                _M_get_Tp_allocator());
                    this->_M_impl._M_finish += __n;
-                   std::copy_backward(__position.base(), __old_finish - __n,
-                                      __old_finish);
+                   _GLIBCXX_MOVE_BACKWARD3(__position.base(),
+                                           __old_finish - __n, __old_finish);
                    std::copy(__first, __last, __position);
                  }
                else
@@ -422,7 +487,7 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
                                                this->_M_impl._M_finish,
                                                _M_get_Tp_allocator());
                    this->_M_impl._M_finish += __n - __elems_after;
-                   std::__uninitialized_copy_a(__position.base(),
+                   std::__uninitialized_move_a(__position.base(),
                                                __old_finish,
                                                this->_M_impl._M_finish,
                                                _M_get_Tp_allocator());
@@ -439,15 +504,16 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
                try
                  {
                    __new_finish =
-                     std::__uninitialized_copy_a(this->_M_impl._M_start,
+                     std::__uninitialized_move_a(this->_M_impl._M_start,
                                                  __position.base(),
                                                  __new_start,
                                                  _M_get_Tp_allocator());
                    __new_finish =
-                     std::__uninitialized_copy_a(__first, __last, __new_finish,
+                     std::__uninitialized_copy_a(__first, __last,
+                                                 __new_finish,
                                                  _M_get_Tp_allocator());
                    __new_finish =
-                     std::__uninitialized_copy_a(__position.base(),
+                     std::__uninitialized_move_a(__position.base(),
                                                  this->_M_impl._M_finish,
                                                  __new_finish,
                                                  _M_get_Tp_allocator());
index ce44241..977fbbd 100644 (file)
@@ -278,6 +278,7 @@ namespace __debug
       using _Base::data;
 
       // 23.2.4.3 modifiers:
+#ifndef __GXX_EXPERIMENTAL_CXX0X__
       void
       push_back(const _Tp& __x)
       {
@@ -287,6 +288,18 @@ namespace __debug
          this->_M_invalidate_all();
        _M_update_guaranteed_capacity();
       }
+#else
+      template<typename... _Args>
+        void
+        push_back(_Args... __args)
+       {
+         bool __realloc = _M_requires_reallocation(this->size() + 1);
+         _Base::push_back(std::forward<_Args>(__args)...);
+         if (__realloc)
+           this->_M_invalidate_all();
+         _M_update_guaranteed_capacity();
+       }
+#endif
 
       void
       pop_back()
@@ -297,6 +310,25 @@ namespace __debug
        _Base::pop_back();
       }
 
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+      template<typename... _Args>
+        iterator
+        emplace(iterator __position, _Args... __args)
+       {
+         __glibcxx_check_insert(__position);
+         bool __realloc = _M_requires_reallocation(this->size() + 1);
+         difference_type __offset = __position - begin();
+         typename _Base::iterator __res = _Base::emplace(__position.base(),
+                                           std::forward<_Args>(__args)...);
+         if (__realloc)
+           this->_M_invalidate_all();
+         else
+           this->_M_invalidate_if(_After_nth(__offset, _M_base().begin()));
+         _M_update_guaranteed_capacity();
+         return iterator(__res, this);
+       }
+#endif
+
       iterator
       insert(iterator __position, const _Tp& __x)
       {
@@ -312,6 +344,24 @@ namespace __debug
        return iterator(__res, this);
       }
 
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+      iterator
+      insert(iterator __position, _Tp&& __x)
+      {
+       __glibcxx_check_insert(__position);
+       bool __realloc = _M_requires_reallocation(this->size() + 1);
+       difference_type __offset = __position - begin();
+       typename _Base::iterator __res = _Base::insert(__position.base(),
+                                                      std::forward<_Tp>(__x));
+       if (__realloc)
+         this->_M_invalidate_all();
+       else
+         this->_M_invalidate_if(_After_nth(__offset, _M_base().begin()));
+       _M_update_guaranteed_capacity();
+       return iterator(__res, this);
+      }
+#endif
+
       void
       insert(iterator __position, size_type __n, const _Tp& __x)
       {
index 7184a25..688423e 100644 (file)
@@ -1,5 +1,4 @@
 // { dg-do compile } 
-// { dg-require-rvalref "" }
 // { dg-options "-std=gnu++0x" }
 
 // Copyright (C) 2005, 2007 Free Software Foundation, Inc.
index ef4410a..15adafc 100644 (file)
@@ -1,4 +1,3 @@
-// { dg-require-rvalref "" }
 // { dg-options "-std=gnu++0x" }
 
 // Copyright (C) 2005, 2007 Free Software Foundation, Inc.
index c5b20cb..6e7d587 100644 (file)
@@ -19,7 +19,7 @@
 // USA.
 
 // { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 945 }
+// { dg-error "no matching" "" { target *-*-* } 995 }
 // { dg-excess-errors "" }
 
 #include <vector>
index 28e0c4d..532d89a 100644 (file)
@@ -19,7 +19,7 @@
 // USA.
 
 // { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 885 }
+// { dg-error "no matching" "" { target *-*-* } 935 }
 // { dg-excess-errors "" }
 
 #include <vector>
index 717bbc6..640aa79 100644 (file)
@@ -19,7 +19,7 @@
 // USA.
 
 // { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 885 }
+// { dg-error "no matching" "" { target *-*-* } 935 }
 // { dg-excess-errors "" }
 
 #include <vector>
index 62b331a..1971317 100644 (file)
@@ -19,7 +19,7 @@
 // USA.
 
 // { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 986 }
+// { dg-error "no matching" "" { target *-*-* } 1036 }
 // { dg-excess-errors "" }
 
 #include <vector>
index 84136f4..f4dbc19 100644 (file)
@@ -1,4 +1,3 @@
-// { dg-require-rvalref "" }
 // { dg-options "-std=gnu++0x" }
 
 // Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc.