stl_map.h (map(const map&)): Make default.
authorFrançois Dumont <fdumont@gcc.gnu.org>
Wed, 7 Dec 2016 21:12:49 +0000 (21:12 +0000)
committerFrançois Dumont <fdumont@gcc.gnu.org>
Wed, 7 Dec 2016 21:12:49 +0000 (21:12 +0000)
2016-12-07  François Dumont  <fdumont@gcc.gnu.org>

* include/bits/stl_map.h (map(const map&)): Make default.
(map(map&&)): Likewise.
(~map()): Likewise.
(operator=(const map&)): Likewise.
* include/bits/stl_multimap.h (multimap(const multimap&)): Make default.
(multimap(multimap&&)): Likewise.
(~multimap()): Likewise.
(operator=(const multimap&)): Likewise.
* include/bits/stl_set.h (set(const set&)): Make default.
(set(set&&)): Likewise.
(~set()): Likewise.
(operator=(const set&)): Likewise.
* include/bits/stl_multiset.h (multiset(const multiset&)): Make default.
(multiset(multiset&&)): Likewise.
(~multiset()): Likewise.
(operator=(const multiset&)): Likewise.
* include/bits/stl_tree.h (_Rb_tree_key_compare<>): New.
(_Rb_tree_header): New.
(_Rb_tree_impl): Inherit from latters.
(_Rb_tree_impl()): Make default.
(_Rb_tree_impl(const _Rb_tree_impl&)): New.
(_Rb_tree<>(const _Rb_tree&): Use latter.
(_Rb_tree_impl(_Rb_tree_impl&&)): New, default.
(_Rb_tree_impl(const _Key_compare&, const _Node_allocator&)): Delete.
(_Rb_tree_impl::_M_reset): Move...
(_Rb_tree_header::_M_reset): ...here.
(_Rb_tree_impl::_M_initialize): Delete.
(_Rb_tree(_Rb_tree&&)): Make default.
(_Rb_tree_header::_M_move_data(_Rb_tree_header&)): New.
(_Rb_tree<>::_M_move_data(_Rb_tree&, true_type)): Use latter.
(_Rb_tree<>(_Rb_tree&&)): Make default.

From-SVN: r243379

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/stl_map.h
libstdc++-v3/include/bits/stl_multimap.h
libstdc++-v3/include/bits/stl_multiset.h
libstdc++-v3/include/bits/stl_set.h
libstdc++-v3/include/bits/stl_tree.h

index 28c5d9d78714f834cfa5ce3f2039a9f5a45ba947..3feef857c009875c0c389ae9e4e9c65390aed88d 100644 (file)
@@ -1,3 +1,37 @@
+2016-12-07  François Dumont  <fdumont@gcc.gnu.org>
+
+       * include/bits/stl_map.h (map(const map&)): Make default.
+       (map(map&&)): Likewise.
+       (~map()): Likewise.
+       (operator=(const map&)): Likewise.
+       * include/bits/stl_multimap.h (multimap(const multimap&)): Make default.
+       (multimap(multimap&&)): Likewise.
+       (~multimap()): Likewise.
+       (operator=(const multimap&)): Likewise.
+       * include/bits/stl_set.h (set(const set&)): Make default.
+       (set(set&&)): Likewise.
+       (~set()): Likewise.
+       (operator=(const set&)): Likewise.
+       * include/bits/stl_multiset.h (multiset(const multiset&)): Make default.
+       (multiset(multiset&&)): Likewise.
+       (~multiset()): Likewise.
+       (operator=(const multiset&)): Likewise.
+       * include/bits/stl_tree.h (_Rb_tree_key_compare<>): New.
+       (_Rb_tree_header): New.
+       (_Rb_tree_impl): Inherit from latters.
+       (_Rb_tree_impl()): Make default.
+       (_Rb_tree_impl(const _Rb_tree_impl&)): New.
+       (_Rb_tree<>(const _Rb_tree&): Use latter.
+       (_Rb_tree_impl(_Rb_tree_impl&&)): New, default.
+       (_Rb_tree_impl(const _Key_compare&, const _Node_allocator&)): Delete.
+       (_Rb_tree_impl::_M_reset): Move...
+       (_Rb_tree_header::_M_reset): ...here.
+       (_Rb_tree_impl::_M_initialize): Delete.
+       (_Rb_tree(_Rb_tree&&)): Make default.
+       (_Rb_tree_header::_M_move_data(_Rb_tree_header&)): New.
+       (_Rb_tree<>::_M_move_data(_Rb_tree&, true_type)): Use latter.
+       (_Rb_tree<>(_Rb_tree&&)): Make default.
+
 2016-12-07  Jonathan Wakely  <jwakely@redhat.com>
 
        * include/experimental/bits/fs_path.h (path::_S_convert): Replace
index dea7d5bc376095f29a6b20fb517b7a753d05ff6e..bbd0a97f24359cf0c0370c54140c28d1151f91c8 100644 (file)
@@ -185,25 +185,22 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 
       /**
        *  @brief  %Map copy constructor.
-       *  @param  __x  A %map of identical element and allocator types.
        *
-       *  The newly-created %map uses a copy of the allocator object used
-       *  by @a __x (unless the allocator traits dictate a different object).
+       *  Whether the allocator is copied depends on the allocator traits.
        */
+#if __cplusplus < 201103L
       map(const map& __x)
       : _M_t(__x._M_t) { }
+#else
+      map(const map&) = default;
 
-#if __cplusplus >= 201103L
       /**
        *  @brief  %Map move constructor.
-       *  @param  __x  A %map of identical element and allocator types.
        *
-       *  The newly-created %map contains the exact contents of @a __x.
-       *  The contents of @a __x are a valid, but unspecified %map.
+       *  The newly-created %map contains the exact contents of the moved
+       *  instance. The moved instance is a valid, but unspecified, %map.
        */
-      map(map&& __x)
-      noexcept(is_nothrow_copy_constructible<_Compare>::value)
-      : _M_t(std::move(__x._M_t)) { }
+      map(map&&) = default;
 
       /**
        *  @brief  Builds a %map from an initializer_list.
@@ -284,31 +281,31 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
        : _M_t(__comp, _Pair_alloc_type(__a))
         { _M_t._M_insert_unique(__first, __last); }
 
-      // FIXME There is no dtor declared, but we should have something
-      // generated by Doxygen.  I don't know what tags to add to this
-      // paragraph to make that happen:
+#if __cplusplus >= 201103L
       /**
        *  The dtor only erases the elements, and note that if the elements
        *  themselves are pointers, the pointed-to memory is not touched in any
        *  way.  Managing the pointer is the user's responsibility.
        */
+      ~map() = default;
+#endif
 
       /**
        *  @brief  %Map assignment operator.
-       *  @param  __x  A %map of identical element and allocator types.
-       *
-       *  All the elements of @a __x are copied.
        *
        *  Whether the allocator is copied depends on the allocator traits.
        */
+#if __cplusplus < 201103L
       map&
       operator=(const map& __x)
       {
        _M_t = __x._M_t;
        return *this;
       }
+#else
+      map&
+      operator=(const map&) = default;
 
-#if __cplusplus >= 201103L
       /// Move assignment operator.
       map&
       operator=(map&&) = default;
index 7e86b76e9878c8d9b4dfcd26daf1cb2f0724c18d..a5f775b468f053e58fada8a4704d0057302f45db 100644 (file)
@@ -182,25 +182,23 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 
       /**
        *  @brief  %Multimap copy constructor.
-       *  @param  __x  A %multimap of identical element and allocator types.
        *
-       *  The newly-created %multimap uses a copy of the allocator object used
-       *  by @a __x (unless the allocator traits dictate a different object).
+       *  Whether the allocator is copied depends on the allocator traits.
        */
+#if __cplusplus < 201103L
       multimap(const multimap& __x)
       : _M_t(__x._M_t) { }
+#else
+      multimap(const multimap&) = default;
 
-#if __cplusplus >= 201103L
       /**
        *  @brief  %Multimap move constructor.
-       *  @param   __x  A %multimap of identical element and allocator types.
        *
-       *  The newly-created %multimap contains the exact contents of @a __x.
-       *  The contents of @a __x are a valid, but unspecified %multimap.
+       *  The newly-created %multimap contains the exact contents of the
+       *  moved instance. The moved instance is a valid, but unspecified
+       *  %multimap.
        */
-      multimap(multimap&& __x)
-      noexcept(is_nothrow_copy_constructible<_Compare>::value)
-      : _M_t(std::move(__x._M_t)) { }
+      multimap(multimap&&) = default;
 
       /**
        *  @brief  Builds a %multimap from an initializer_list.
@@ -278,31 +276,31 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
        : _M_t(__comp, _Pair_alloc_type(__a))
         { _M_t._M_insert_equal(__first, __last); }
 
-      // FIXME There is no dtor declared, but we should have something generated
-      // by Doxygen.  I don't know what tags to add to this paragraph to make
-      // that happen:
+#if __cplusplus >= 201103L
       /**
        *  The dtor only erases the elements, and note that if the elements
        *  themselves are pointers, the pointed-to memory is not touched in any
-       *  way.  Managing the pointer is the user's responsibility.
+       *  way. Managing the pointer is the user's responsibility.
        */
+      ~multimap() = default;
+#endif
 
       /**
        *  @brief  %Multimap assignment operator.
-       *  @param  __x  A %multimap of identical element and allocator types.
-       *
-       *  All the elements of @a __x are copied.
        *
        *  Whether the allocator is copied depends on the allocator traits.
        */
+#if __cplusplus < 201103L
       multimap&
       operator=(const multimap& __x)
       {
        _M_t = __x._M_t;
        return *this;
       }
+#else
+      multimap&
+      operator=(const multimap&) = default;
 
-#if __cplusplus >= 201103L
       /// Move assignment operator.
       multimap&
       operator=(multimap&&) = default;
index 7fe2fbd4f0259799d173b725ea6b97493e5d5aa5..8a83b177ac9e48b74b8b714cb13e37aed531d6e5 100644 (file)
@@ -194,25 +194,23 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 
       /**
        *  @brief  %Multiset copy constructor.
-       *  @param  __x  A %multiset of identical element and allocator types.
        *
-       *  The newly-created %multiset uses a copy of the allocator object used
-       *  by @a __x (unless the allocator traits dictate a different object).
+       *  Whether the allocator is copied depends on the allocator traits.
        */
+#if __cplusplus < 201103L
       multiset(const multiset& __x)
       : _M_t(__x._M_t) { }
+#else
+      multiset(const multiset&) = default;
 
-#if __cplusplus >= 201103L
      /**
        *  @brief  %Multiset move constructor.
-       *  @param  __x  A %multiset of identical element and allocator types.
        *
-       *  The newly-created %multiset contains the exact contents of @a __x.
-       *  The contents of @a __x are a valid, but unspecified %multiset.
+       *  The newly-created %multiset contains the exact contents of the
+       *  moved instance. The moved instance is a valid, but unspecified
+       *  %multiset.
        */
-      multiset(multiset&& __x)
-      noexcept(is_nothrow_copy_constructible<_Compare>::value)
-      : _M_t(std::move(__x._M_t)) { }
+      multiset(multiset&&) = default;
 
       /**
        *  @brief  Builds a %multiset from an initializer_list.
@@ -256,24 +254,31 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
                 const allocator_type& __a)
        : _M_t(_Compare(), _Key_alloc_type(__a))
         { _M_t._M_insert_equal(__first, __last); }
+
+      /**
+       *  The dtor only erases the elements, and note that if the elements
+       *  themselves are pointers, the pointed-to memory is not touched in any
+       *  way. Managing the pointer is the user's responsibility.
+       */
+      ~multiset() = default;
 #endif
 
       /**
        *  @brief  %Multiset assignment operator.
-       *  @param  __x  A %multiset of identical element and allocator types.
-       *
-       *  All the elements of @a __x are copied.
        *
        *  Whether the allocator is copied depends on the allocator traits.
        */
+#if __cplusplus < 201103L
       multiset&
       operator=(const multiset& __x)
       {
        _M_t = __x._M_t;
        return *this;
       }
+#else
+      multiset&
+      operator=(const multiset&) = default;
 
-#if __cplusplus >= 201103L
       /// Move assignment operator.
       multiset&
       operator=(multiset&&) = default;
index 5ed9672de5891354deff2c6184298baeda0bf7ea..db1e031dc3621d860189e0de140a210632b2dd38 100644 (file)
@@ -199,25 +199,22 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 
       /**
        *  @brief  %Set copy constructor.
-       *  @param  __x  A %set of identical element and allocator types.
        *
-       *  The newly-created %set uses a copy of the allocator object used
-       *  by @a __x (unless the allocator traits dictate a different object).
+       *  Whether the allocator is copied depends on the allocator traits.
        */
+#if __cplusplus < 201103L
       set(const set& __x)
       : _M_t(__x._M_t) { }
+#else
+      set(const set&) = default;
 
-#if __cplusplus >= 201103L
      /**
        *  @brief %Set move constructor
-       *  @param __x  A %set of identical element and allocator types.
        *
-       *  The newly-created %set contains the exact contents of @a x.
-       *  The contents of @a x are a valid, but unspecified %set.
+       *  The newly-created %set contains the exact contents of the moved
+       *  instance. The moved instance is a valid, but unspecified, %set.
        */
-      set(set&& __x)
-      noexcept(is_nothrow_copy_constructible<_Compare>::value)
-      : _M_t(std::move(__x._M_t)) { }
+      set(set&&) = default;
 
       /**
        *  @brief  Builds a %set from an initializer_list.
@@ -261,24 +258,31 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
            const allocator_type& __a)
        : _M_t(_Compare(), _Key_alloc_type(__a))
         { _M_t._M_insert_unique(__first, __last); }
+
+      /**
+       *  The dtor only erases the elements, and note that if the elements
+       *  themselves are pointers, the pointed-to memory is not touched in any
+       *  way. Managing the pointer is the user's responsibility.
+       */
+      ~set() = default;
 #endif
 
       /**
        *  @brief  %Set assignment operator.
-       *  @param  __x  A %set of identical element and allocator types.
-       *
-       *  All the elements of @a __x are copied.
        *
        *  Whether the allocator is copied depends on the allocator traits.
        */
+#if __cplusplus < 201103L
       set&
       operator=(const set& __x)
       {
        _M_t = __x._M_t;
        return *this;
       }
+#else
+      set&
+      operator=(const set&) = default;
 
-#if __cplusplus >= 201103L
       /// Move assignment operator.
       set&
       operator=(set&&) = default;
index 2c67ad96dd12bd813265373602cf565c05956479..f5bb5f78946452720d9b4b69f35026052aeaaf81 100644 (file)
@@ -137,6 +137,80 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     }
   };
 
+  // Helper type offering value initialization guarantee on the compare functor.
+  template<typename _Key_compare>
+    struct _Rb_tree_key_compare
+    {
+      _Key_compare             _M_key_compare;
+
+      _Rb_tree_key_compare()
+      _GLIBCXX_NOEXCEPT_IF(
+       is_nothrow_default_constructible<_Key_compare>::value)
+      : _M_key_compare()
+      { }
+
+      _Rb_tree_key_compare(const _Key_compare& __comp)
+      : _M_key_compare(__comp)
+      { }
+
+#if __cplusplus >= 201103L
+      // Copy constructor added for consistency with C++98 mode.
+      _Rb_tree_key_compare(const _Rb_tree_key_compare&) = default;
+
+      _Rb_tree_key_compare(_Rb_tree_key_compare&& __x)
+       noexcept(is_nothrow_copy_constructible<_Key_compare>::value)
+      : _M_key_compare(__x._M_key_compare)
+      { }
+#endif
+    };
+
+  // Helper type to manage default initialization of node count and header.
+  struct _Rb_tree_header
+  {
+    _Rb_tree_node_base _M_header;
+    size_t             _M_node_count; // Keeps track of size of tree.
+
+    _Rb_tree_header() _GLIBCXX_NOEXCEPT
+    {
+      _M_header._M_color = _S_red;
+      _M_reset();
+    }
+
+#if __cplusplus >= 201103L
+    _Rb_tree_header(_Rb_tree_header&& __x) noexcept
+    {
+      if (__x._M_header._M_parent != nullptr)
+       _M_move_data(__x);
+      else
+       {
+         _M_header._M_color = _S_red;
+         _M_reset();
+       }
+    }
+#endif
+
+    void
+    _M_move_data(_Rb_tree_header& __from)
+    {
+      _M_header._M_parent = __from._M_header._M_parent;
+      _M_header._M_left = __from._M_header._M_left;
+      _M_header._M_right = __from._M_header._M_right;
+      _M_header._M_parent->_M_parent = &_M_header;
+      _M_node_count = __from._M_node_count;
+
+      __from._M_reset();
+    }
+
+    void
+    _M_reset()
+    {
+      _M_header._M_parent = 0;
+      _M_header._M_left = &_M_header;
+      _M_header._M_right = &_M_header;
+      _M_node_count = 0;
+    }
+  };
+
   template<typename _Val>
     struct _Rb_tree_node : public _Rb_tree_node_base
     {
@@ -599,50 +673,31 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       // Unused _Is_pod_comparator is kept as it is part of mangled name.
       template<typename _Key_compare,
               bool /* _Is_pod_comparator */ = __is_pod(_Key_compare)>
-        struct _Rb_tree_impl : public _Node_allocator
+        struct _Rb_tree_impl
+       : public _Node_allocator
+       , public _Rb_tree_key_compare<_Key_compare>
+       , public _Rb_tree_header
         {
-         _Key_compare          _M_key_compare;
-         _Rb_tree_node_base    _M_header;
-         size_type             _M_node_count; // Keeps track of size of tree.
+         typedef _Rb_tree_key_compare<_Key_compare> _Base_key_compare;
 
+#if __cplusplus < 201103L
          _Rb_tree_impl()
-         _GLIBCXX_NOEXCEPT_IF(
-           is_nothrow_default_constructible<_Node_allocator>::value
-           && is_nothrow_default_constructible<_Key_compare>::value)
-         : _Node_allocator(), _M_key_compare(), _M_header(),
-           _M_node_count(0)
-         { _M_initialize(); }
-
-         _Rb_tree_impl(const _Key_compare& __comp, const _Node_allocator& __a)
-         : _Node_allocator(__a), _M_key_compare(__comp), _M_header(),
-           _M_node_count(0)
-         { _M_initialize(); }
+         { }
+#else
+         _Rb_tree_impl() = default;
+#endif
+
+         _Rb_tree_impl(const _Rb_tree_impl& __x)
+         : _Node_allocator(_Alloc_traits::_S_select_on_copy(__x))
+         , _Base_key_compare(__x._M_key_compare)
+         { }
 
 #if __cplusplus >= 201103L
+         _Rb_tree_impl(_Rb_tree_impl&&) = default;
          _Rb_tree_impl(const _Key_compare& __comp, _Node_allocator&& __a)
-         : _Node_allocator(std::move(__a)), _M_key_compare(__comp),
-           _M_header(), _M_node_count(0)
-         { _M_initialize(); }
+         : _Node_allocator(std::move(__a)), _Base_key_compare(__comp)
+         { }
 #endif
-
-         void
-         _M_reset()
-         {
-           this->_M_header._M_parent = 0;
-           this->_M_header._M_left = &this->_M_header;
-           this->_M_header._M_right = &this->_M_header;
-           this->_M_node_count = 0;
-         }
-
-       private:
-         void
-         _M_initialize()
-         {
-           this->_M_header._M_color = _S_red;
-           this->_M_header._M_parent = 0;
-           this->_M_header._M_left = &this->_M_header;
-           this->_M_header._M_right = &this->_M_header;
-         }
        };
 
       _Rb_tree_impl<_Compare> _M_impl;
@@ -845,8 +900,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       : _M_impl(__comp, _Node_allocator(__a)) { }
 
       _Rb_tree(const _Rb_tree& __x)
-      : _M_impl(__x._M_impl._M_key_compare,
-               _Alloc_traits::_S_select_on_copy(__x._M_get_Node_allocator()))
+      : _M_impl(__x._M_impl)
       {
        if (__x._M_root() != 0)
          {
@@ -874,13 +928,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
          }
       }
 
-      _Rb_tree(_Rb_tree&& __x)
-      : _M_impl(__x._M_impl._M_key_compare,
-               std::move(__x._M_get_Node_allocator()))
-      {
-       if (__x._M_root() != 0)
-         _M_move_data(__x, std::true_type());
-      }
+      _Rb_tree(_Rb_tree&&) = default;
 
       _Rb_tree(_Rb_tree&& __x, const allocator_type& __a)
       : _Rb_tree(std::move(__x), _Node_allocator(__a))
@@ -1278,7 +1326,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     private:
       // Move elements from container with equal allocator.
       void
-      _M_move_data(_Rb_tree&, std::true_type);
+      _M_move_data(_Rb_tree& __x, std::true_type)
+      { _M_impl._M_move_data(__x._M_impl); }
 
       // Move elements from container with possibly non-equal allocator,
       // which might result in a copy not a move.
@@ -1529,25 +1578,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        _M_move_data(__x, __eq());
     }
 
-  template<typename _Key, typename _Val, typename _KeyOfValue,
-           typename _Compare, typename _Alloc>
-    void
-    _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
-    _M_move_data(_Rb_tree& __x, std::true_type)
-    {
-      _M_root() = __x._M_root();
-      _M_leftmost() = __x._M_leftmost();
-      _M_rightmost() = __x._M_rightmost();
-      _M_root()->_M_parent = _M_end();
-
-      __x._M_root() = 0;
-      __x._M_leftmost() = __x._M_end();
-      __x._M_rightmost() = __x._M_end();
-
-      this->_M_impl._M_node_count = __x._M_impl._M_node_count;
-      __x._M_impl._M_node_count = 0;
-    }
-
   template<typename _Key, typename _Val, typename _KeyOfValue,
            typename _Compare, typename _Alloc>
     void
@@ -1555,7 +1585,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     _M_move_data(_Rb_tree& __x, std::false_type)
     {
       if (_M_get_Node_allocator() == __x._M_get_Node_allocator())
-         _M_move_data(__x, std::true_type());
+       _M_move_data(__x, std::true_type());
       else
        {
          _Alloc_node __an(*this);
@@ -1966,26 +1996,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       if (_M_root() == 0)
        {
          if (__t._M_root() != 0)
-           {
-             _M_root() = __t._M_root();
-             _M_leftmost() = __t._M_leftmost();
-             _M_rightmost() = __t._M_rightmost();
-             _M_root()->_M_parent = _M_end();
-             _M_impl._M_node_count = __t._M_impl._M_node_count;
-             
-             __t._M_impl._M_reset();
-           }
+           _M_impl._M_move_data(__t._M_impl);
        }
       else if (__t._M_root() == 0)
-       {
-         __t._M_root() = _M_root();
-         __t._M_leftmost() = _M_leftmost();
-         __t._M_rightmost() = _M_rightmost();
-         __t._M_root()->_M_parent = __t._M_end();
-         __t._M_impl._M_node_count = _M_impl._M_node_count;
-         
-         _M_impl._M_reset();
-       }
+       __t._M_impl._M_move_data(_M_impl);
       else
        {
          std::swap(_M_root(),__t._M_root());