2018-05-18 François Dumont <fdumont@gcc.gnu.org>
authorFrançois Dumont <fdumont@gcc.gnu.org>
Fri, 18 May 2018 20:49:49 +0000 (20:49 +0000)
committerFrançois Dumont <fdumont@gcc.gnu.org>
Fri, 18 May 2018 20:49:49 +0000 (20:49 +0000)
* include/bits/stl_tree.h
(_Rb_tree_impl(_Rb_tree_impl&&, _Node_allocator&&)): New.
(_Rb_tree(_Rb_tree&&, _Node_allocator&&, true_type)): New, use latter.
(_Rb_tree(_Rb_tree&&, _Node_allocator&&, false_type)): New.
(_Rb_tree(_Rb_tree&&, _Node_allocator&&)): Adapt, use latters.
* include/debug/map.h
(map(map&&, const_allocator_type&)): Add noexcept qualitication.
* include/debug/multimap.h
(multimap(multimap&&, const_allocator_type&)): Likewise.
* include/debug/set.h
(set(set&&, const_allocator_type&)): Likewise.
* include/debug/multiset.h
(multiset(multiset&&, const_allocator_type&)): Likewise.
* testsuite/23_containers/map/cons/noexcept_default_construct.cc:
Add checks.
* testsuite/23_containers/map/cons/noexcept_move_construct.cc:
Add checks.
* testsuite/23_containers/multimap/cons/noexcept_default_construct.cc:
Add checks.
* testsuite/23_containers/multimap/cons/noexcept_move_construct.cc:
Add checks.
* testsuite/23_containers/multiset/cons/noexcept_default_construct.cc:
Add checks.
* testsuite/23_containers/multiset/cons/noexcept_move_construct.cc:
Add checks.
* testsuite/23_containers/set/cons/noexcept_default_construct.cc:
Add checks.
* testsuite/23_containers/set/cons/noexcept_move_construct.cc:
Add checks.

From-SVN: r260382

14 files changed:
libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/stl_tree.h
libstdc++-v3/include/debug/map.h
libstdc++-v3/include/debug/multimap.h
libstdc++-v3/include/debug/multiset.h
libstdc++-v3/include/debug/set.h
libstdc++-v3/testsuite/23_containers/map/cons/noexcept_default_construct.cc
libstdc++-v3/testsuite/23_containers/map/cons/noexcept_move_construct.cc
libstdc++-v3/testsuite/23_containers/multimap/cons/noexcept_default_construct.cc
libstdc++-v3/testsuite/23_containers/multimap/cons/noexcept_move_construct.cc
libstdc++-v3/testsuite/23_containers/multiset/cons/noexcept_default_construct.cc
libstdc++-v3/testsuite/23_containers/multiset/cons/noexcept_move_construct.cc
libstdc++-v3/testsuite/23_containers/set/cons/noexcept_default_construct.cc
libstdc++-v3/testsuite/23_containers/set/cons/noexcept_move_construct.cc

index c4e10f1..092fa75 100644 (file)
@@ -1,3 +1,35 @@
+2018-05-18  François Dumont  <fdumont@gcc.gnu.org>
+
+       * include/bits/stl_tree.h
+       (_Rb_tree_impl(_Rb_tree_impl&&, _Node_allocator&&)): New.
+       (_Rb_tree(_Rb_tree&&, _Node_allocator&&, true_type)): New, use latter.
+       (_Rb_tree(_Rb_tree&&, _Node_allocator&&, false_type)): New.
+       (_Rb_tree(_Rb_tree&&, _Node_allocator&&)): Adapt, use latters.
+       * include/debug/map.h
+       (map(map&&, const_allocator_type&)): Add noexcept qualitication.
+       * include/debug/multimap.h
+       (multimap(multimap&&, const_allocator_type&)): Likewise.
+       * include/debug/set.h
+       (set(set&&, const_allocator_type&)): Likewise.
+       * include/debug/multiset.h
+       (multiset(multiset&&, const_allocator_type&)): Likewise.
+       * testsuite/23_containers/map/cons/noexcept_default_construct.cc:
+       Add checks.
+       * testsuite/23_containers/map/cons/noexcept_move_construct.cc:
+       Add checks.
+       * testsuite/23_containers/multimap/cons/noexcept_default_construct.cc:
+       Add checks.
+       * testsuite/23_containers/multimap/cons/noexcept_move_construct.cc:
+       Add checks.
+       * testsuite/23_containers/multiset/cons/noexcept_default_construct.cc:
+       Add checks.
+       * testsuite/23_containers/multiset/cons/noexcept_move_construct.cc:
+       Add checks.
+       * testsuite/23_containers/set/cons/noexcept_default_construct.cc:
+       Add checks.
+       * testsuite/23_containers/set/cons/noexcept_move_construct.cc:
+       Add checks.
+
 2018-05-18  Jason Merrill  <jason@redhat.com>
 
        * include/bits/stl_deque.h (_Deque_iterator): Constrain constructor
index d0a8448..85f190a 100644 (file)
@@ -471,7 +471,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       struct _Reuse_or_alloc_node
       {
        _Reuse_or_alloc_node(_Rb_tree& __t)
-         : _M_root(__t._M_root()), _M_nodes(__t._M_rightmost()), _M_t(__t)
+       : _M_root(__t._M_root()), _M_nodes(__t._M_rightmost()), _M_t(__t)
        {
          if (_M_root)
            {
@@ -555,7 +555,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       struct _Alloc_node
       {
        _Alloc_node(_Rb_tree& __t)
-         : _M_t(__t) { }
+       : _M_t(__t) { }
 
        template<typename _Arg>
          _Link_type
@@ -715,6 +715,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #else
          _Rb_tree_impl(_Rb_tree_impl&&) = default;
 
+         _Rb_tree_impl(_Rb_tree_impl&& __x, _Node_allocator&& __a)
+         : _Node_allocator(std::move(__a)),
+           _Base_key_compare(std::move(__x)),
+           _Rb_tree_header(std::move(__x))
+         { }
+
          _Rb_tree_impl(const _Key_compare& __comp, _Node_allocator&& __a)
          : _Node_allocator(std::move(__a)), _Base_key_compare(__comp)
          { }
@@ -958,7 +964,27 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       : _Rb_tree(std::move(__x), _Node_allocator(__a))
       { }
 
-      _Rb_tree(_Rb_tree&& __x, _Node_allocator&& __a);
+    private:
+      _Rb_tree(_Rb_tree&& __x, _Node_allocator&& __a, true_type)
+      noexcept(is_nothrow_default_constructible<_Compare>::value)
+      : _M_impl(std::move(__x._M_impl), std::move(__a))
+      { }
+
+      _Rb_tree(_Rb_tree&& __x, _Node_allocator&& __a, false_type)
+      : _M_impl(__x._M_impl._M_key_compare, std::move(__a))
+      {
+       if (__x._M_root() != nullptr)
+         _M_move_data(__x, false_type{});
+      }
+
+    public:
+      _Rb_tree(_Rb_tree&& __x, _Node_allocator&& __a)
+      noexcept( noexcept(
+       _Rb_tree(std::declval<_Rb_tree>(), std::declval<_Node_allocator>(),
+                std::declval<typename _Alloc_traits::is_always_equal>())) )
+      : _Rb_tree(std::move(__x), std::move(__a),
+                typename _Alloc_traits::is_always_equal{})
+      { }
 #endif
 
       ~_Rb_tree() _GLIBCXX_NOEXCEPT
@@ -1358,22 +1384,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     private:
       // Move elements from container with equal allocator.
       void
-      _M_move_data(_Rb_tree& __x, std::true_type)
+      _M_move_data(_Rb_tree& __x, 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.
       void
-      _M_move_data(_Rb_tree&, std::false_type);
+      _M_move_data(_Rb_tree&, false_type);
 
       // Move assignment from container with equal allocator.
       void
-      _M_move_assign(_Rb_tree&, std::true_type);
+      _M_move_assign(_Rb_tree&, true_type);
 
       // Move assignment from container with possibly non-equal allocator,
       // which might result in a copy not a move.
       void
-      _M_move_assign(_Rb_tree&, std::false_type);
+      _M_move_assign(_Rb_tree&, false_type);
 #endif
 
 #if __cplusplus > 201402L
@@ -1601,23 +1627,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #if __cplusplus >= 201103L
   template<typename _Key, typename _Val, typename _KeyOfValue,
           typename _Compare, typename _Alloc>
-    _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
-    _Rb_tree(_Rb_tree&& __x, _Node_allocator&& __a)
-    : _M_impl(__x._M_impl._M_key_compare, std::move(__a))
-    {
-      using __eq = typename _Alloc_traits::is_always_equal;
-      if (__x._M_root() != nullptr)
-       _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::false_type)
+    _M_move_data(_Rb_tree& __x, false_type)
     {
       if (_M_get_Node_allocator() == __x._M_get_Node_allocator())
-       _M_move_data(__x, std::true_type());
+       _M_move_data(__x, true_type());
       else
        {
          _Alloc_node __an(*this);
@@ -1639,7 +1654,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     {
       clear();
       if (__x._M_root() != nullptr)
-       _M_move_data(__x, std::true_type());
+       _M_move_data(__x, true_type());
       std::__alloc_on_move(_M_get_Node_allocator(),
                           __x._M_get_Node_allocator());
     }
index 3f0649a..23966ba 100644 (file)
@@ -105,6 +105,7 @@ namespace __debug
       : _Base(__m, __a) { }
 
       map(map&& __m, const allocator_type& __a)
+      noexcept( noexcept(_Base(std::move(__m._M_base()), __a)) )
       : _Safe(std::move(__m._M_safe()), __a),
        _Base(std::move(__m._M_base()), __a) { }
 
index e709eb7..8054984 100644 (file)
@@ -105,6 +105,7 @@ namespace __debug
       : _Base(__m, __a) { }
 
       multimap(multimap&& __m, const allocator_type& __a)
+      noexcept( noexcept(_Base(std::move(__m._M_base()), __a)) )
       : _Safe(std::move(__m._M_safe()), __a),
        _Base(std::move(__m._M_base()), __a) { }
 
index 461f4f6..6e4c1b0 100644 (file)
@@ -104,6 +104,7 @@ namespace __debug
       : _Base(__m, __a) { }
 
       multiset(multiset&& __m, const allocator_type& __a)
+      noexcept( noexcept(_Base(std::move(__m._M_base()), __a)) )
       : _Safe(std::move(__m._M_safe()), __a),
        _Base(std::move(__m._M_base()), __a) { }
 
index 2ac8f1c..571cc47 100644 (file)
@@ -104,6 +104,7 @@ namespace __debug
       : _Base(__x, __a) { }
 
       set(set&& __x, const allocator_type& __a)
+      noexcept( noexcept(_Base(std::move(__x._M_base()), __a)) )
       : _Safe(std::move(__x._M_safe()), __a),
        _Base(std::move(__x._M_base()), __a) { }
 
index 4b9e119..e5c924d 100644 (file)
@@ -30,3 +30,19 @@ struct cmp
 
 using mtype2 = std::map<int, int, cmp>;
 static_assert( !std::is_nothrow_default_constructible<mtype2>::value, "Error");
+
+template<typename _Tp>
+  struct not_noexcept_cons_alloc : std::allocator<_Tp>
+  {
+    not_noexcept_cons_alloc() /* noexcept */
+    { }
+
+    template<typename _Tp1>
+      struct rebind
+      { typedef not_noexcept_cons_alloc<_Tp1> other; };
+  };
+
+using mtype3 = std::map<int, int, std::less<int>,
+                       not_noexcept_cons_alloc<std::pair<const int, int>>>;
+
+static_assert(!std::is_nothrow_default_constructible<mtype3>::value, "Error");
index 0041408..723a63f 100644 (file)
 
 typedef std::map<int, int> mtype;
 
-static_assert(std::is_nothrow_move_constructible<mtype>::value, "Error");
+static_assert( std::is_nothrow_move_constructible<mtype>::value,
+              "noexcept move constructor" );
+static_assert( std::is_nothrow_constructible<mtype,
+              mtype&&, const typename mtype::allocator_type&>::value,
+              "noexcept move constructor with allocator" );
+
+struct not_noexcept_less
+{
+  not_noexcept_less() = default;
+  not_noexcept_less(const not_noexcept_less&) /* noexcept */
+  { }
+
+  bool
+  operator()(int l, int r) const
+  { return l < r; }
+};
+
+typedef std::map<int, int, not_noexcept_less> emtype;
+
+static_assert( !std::is_nothrow_constructible<emtype, emtype&&,
+              const typename emtype::allocator_type&>::value,
+              "except move constructor with allocator" );
index 9873770..62f5d60 100644 (file)
@@ -30,3 +30,19 @@ struct cmp
 
 using mtype2 = std::multimap<int, int, cmp>;
 static_assert( !std::is_nothrow_default_constructible<mtype2>::value, "Error");
+
+template<typename _Tp>
+  struct not_noexcept_cons_alloc : std::allocator<_Tp>
+  {
+    not_noexcept_cons_alloc() /* noexcept */
+    { }
+
+    template<typename _Tp1>
+      struct rebind
+      { typedef not_noexcept_cons_alloc<_Tp1> other; };
+  };
+
+using mtype3 = std::multimap<int, int, std::less<int>,
+                       not_noexcept_cons_alloc<std::pair<const int, int>>>;
+
+static_assert(!std::is_nothrow_default_constructible<mtype3>::value, "Error");
index 0319a61..1612b0d 100644 (file)
 
 typedef std::multimap<int, int> mmtype;
 
-static_assert(std::is_nothrow_move_constructible<mmtype>::value, "Error");
+static_assert( std::is_nothrow_move_constructible<mmtype>::value,
+              "noexcept move constructor" );
+static_assert( std::is_nothrow_constructible<mmtype,
+              mmtype&&, const typename mmtype::allocator_type&>::value,
+              "noexcept move constructor with allocator" );
+
+struct not_noexcept_less
+{
+  not_noexcept_less() = default;
+  not_noexcept_less(const not_noexcept_less&) /* noexcept */
+  { }
+
+  bool
+  operator()(int l, int r) const
+  { return l < r; }
+};
+
+typedef std::multimap<int, int, not_noexcept_less> emmtype;
+
+static_assert( !std::is_nothrow_constructible<emmtype, emmtype&&,
+              const typename emmtype::allocator_type&>::value,
+              "except move constructor with allocator" );
index 963e3d1..8e49168 100644 (file)
@@ -30,3 +30,19 @@ struct cmp
 
 using stype2 = std::multiset<int, cmp>;
 static_assert( !std::is_nothrow_default_constructible<stype2>::value, "Error");
+
+template<typename _Tp>
+  struct not_noexcept_cons_alloc : std::allocator<_Tp>
+  {
+    not_noexcept_cons_alloc() /* noexcept */
+    { }
+
+    template<typename _Tp1>
+      struct rebind
+      { typedef not_noexcept_cons_alloc<_Tp1> other; };
+  };
+
+using stype3 = std::multiset<int, std::less<int>,
+                            not_noexcept_cons_alloc<int>>;
+
+static_assert(!std::is_nothrow_default_constructible<stype3>::value, "Error");
index b1c6dd5..4ef5127 100644 (file)
 
 typedef std::multiset<int> mstype;
 
-static_assert(std::is_nothrow_move_constructible<mstype>::value, "Error");
+static_assert( std::is_nothrow_move_constructible<mstype>::value,
+              "noexcept move constructor" );
+static_assert( std::is_nothrow_constructible<mstype,
+              mstype&&, const typename mstype::allocator_type&>::value,
+              "noexcept move constructor with allocator" );
+
+struct not_noexcept_less
+{
+  not_noexcept_less() = default;
+  not_noexcept_less(const not_noexcept_less&) /* noexcept */
+  { }
+
+  bool
+  operator()(int l, int r) const
+  { return l < r; }
+};
+
+typedef std::multiset<int, not_noexcept_less> emstype;
+
+static_assert( !std::is_nothrow_constructible<emstype, emstype&&,
+              const typename emstype::allocator_type&>::value,
+              "except move constructor with allocator" );
index 882a12c..d3dc98d 100644 (file)
@@ -30,3 +30,19 @@ struct cmp
 
 using stype2 = std::set<int, cmp>;
 static_assert( !std::is_nothrow_default_constructible<stype2>::value, "Error");
+
+template<typename _Tp>
+  struct not_noexcept_cons_alloc : std::allocator<_Tp>
+  {
+    not_noexcept_cons_alloc() /* noexcept */
+    { }
+
+    template<typename _Tp1>
+      struct rebind
+      { typedef not_noexcept_cons_alloc<_Tp1> other; };
+  };
+
+using stype3 = std::set<int, std::less<int>,
+                       not_noexcept_cons_alloc<int>>;
+
+static_assert(!std::is_nothrow_default_constructible<stype3>::value, "Error");
index a7de0ef..942400e 100644 (file)
 
 typedef std::set<int> stype;
 
-static_assert(std::is_nothrow_move_constructible<stype>::value, "Error");
+static_assert( std::is_nothrow_move_constructible<stype>::value,
+              "noexcept move constructor" );
+static_assert( std::is_nothrow_constructible<stype,
+              stype&&, const typename stype::allocator_type&>::value,
+              "noexcept move constructor with allocator" );
+
+struct not_noexcept_less
+{
+  not_noexcept_less() = default;
+  not_noexcept_less(const not_noexcept_less&) /* noexcept */
+  { }
+
+  bool
+  operator()(int l, int r) const
+  { return l < r; }
+};
+
+typedef std::set<int, not_noexcept_less> estype;
+
+static_assert( !std::is_nothrow_constructible<estype, estype&&,
+              const typename estype::allocator_type&>::value,
+              "except move constructor with allocator" );