This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] 77864 Fix noexcept conditions for map/set default constructors


On 05/10/2016 14:13, Jonathan Wakely wrote:
On 05/10/16 14:10 +0200, Marc Glisse wrote:
On Wed, 5 Oct 2016, Jonathan Wakely wrote:

I added conditional noexcept to maps and sets, but forgot to account
for the comparison function, which could throw when constructed.

IMO you are fighting a losing battle. We should implement noexcept(auto) (possibly with some private __noexcept_auto__ spelling) and just use that in most places where we want a conditional noexcept.

That would be nice, but beyond my ability :-)

So until then we can either remove the exception specs entirely, or
make them correct.


Another approach is to rely on existing compiler ability to compute conditional noexcept when defaulting implementations. This is what I have done in this patch.

The new default constructor on _Rb_tree_node_base is not a problem as it is not used to build _Rb_tree_node.

I'll try to do the same for copy constructor/assignment and move constructor/assignment.

    * include/bits/stl_map.h (map()): Make default.
    * include/bits/stl_multimap.h (multimap()): Likewise.
    * include/bits/stl_multiset.h (multiset()): Likewise.
    * include/bits/stl_set.h (set()): Likewise.
    * include/bits/stl_tree.h (_Rb_tree_node_base()): New.
    (_Rb_tree_impl()): Make default.
    (_Rb_tree_impl::_M_initialize()): Delete.
    (_Rb_tree()): Make default.

Tested under Linux x86_64, ok to commit ?

François

diff --git a/libstdc++-v3/include/bits/stl_map.h b/libstdc++-v3/include/bits/stl_map.h
index e5b2a1b..dea7d5b 100644
--- a/libstdc++-v3/include/bits/stl_map.h
+++ b/libstdc++-v3/include/bits/stl_map.h
@@ -167,11 +167,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       /**
        *  @brief  Default constructor creates no elements.
        */
-      map()
-      _GLIBCXX_NOEXCEPT_IF(
-	  is_nothrow_default_constructible<allocator_type>::value
-	  && is_nothrow_default_constructible<key_compare>::value)
-      : _M_t() { }
+#if __cplusplus < 201103L
+      map() : _M_t() { }
+#else
+      map() = default;
+#endif
 
       /**
        *  @brief  Creates a %map with no elements.
diff --git a/libstdc++-v3/include/bits/stl_multimap.h b/libstdc++-v3/include/bits/stl_multimap.h
index d240427..7e86b76 100644
--- a/libstdc++-v3/include/bits/stl_multimap.h
+++ b/libstdc++-v3/include/bits/stl_multimap.h
@@ -164,11 +164,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       /**
        *  @brief  Default constructor creates no elements.
        */
-      multimap()
-      _GLIBCXX_NOEXCEPT_IF(
-	  is_nothrow_default_constructible<allocator_type>::value
-	  && is_nothrow_default_constructible<key_compare>::value)
-      : _M_t() { }
+#if __cplusplus < 201103L
+      multimap() : _M_t() { }
+#else
+      multimap() = default;
+#endif
 
       /**
        *  @brief  Creates a %multimap with no elements.
diff --git a/libstdc++-v3/include/bits/stl_multiset.h b/libstdc++-v3/include/bits/stl_multiset.h
index cc068a9..7fe2fbd 100644
--- a/libstdc++-v3/include/bits/stl_multiset.h
+++ b/libstdc++-v3/include/bits/stl_multiset.h
@@ -144,11 +144,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       /**
        *  @brief  Default constructor creates no elements.
        */
-      multiset()
-      _GLIBCXX_NOEXCEPT_IF(
-	  is_nothrow_default_constructible<allocator_type>::value
-	  && is_nothrow_default_constructible<key_compare>::value)
-      : _M_t() { }
+#if __cplusplus < 201103L
+      multiset() : _M_t() { }
+#else
+      multiset() = default;
+#endif
 
       /**
        *  @brief  Creates a %multiset with no elements.
diff --git a/libstdc++-v3/include/bits/stl_set.h b/libstdc++-v3/include/bits/stl_set.h
index 3938351..5ed9672 100644
--- a/libstdc++-v3/include/bits/stl_set.h
+++ b/libstdc++-v3/include/bits/stl_set.h
@@ -147,11 +147,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       /**
        *  @brief  Default constructor creates no elements.
        */
-      set()
-      _GLIBCXX_NOEXCEPT_IF(
-	  is_nothrow_default_constructible<allocator_type>::value
-	  && is_nothrow_default_constructible<key_compare>::value)
-      : _M_t() { }
+#if __cplusplus < 201103L
+      set() : _M_t() { }
+#else
+      set() = default;
+#endif
 
       /**
        *  @brief  Creates a %set with no elements.
diff --git a/libstdc++-v3/include/bits/stl_tree.h b/libstdc++-v3/include/bits/stl_tree.h
index ee2dc70..ed575d0 100644
--- a/libstdc++-v3/include/bits/stl_tree.h
+++ b/libstdc++-v3/include/bits/stl_tree.h
@@ -108,6 +108,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     _Base_ptr		_M_left;
     _Base_ptr		_M_right;
 
+    _Rb_tree_node_base() _GLIBCXX_NOEXCEPT
+      : _M_color(_S_red), _M_parent(0), _M_left(this), _M_right(this)
+    { }
+
     static _Base_ptr
     _S_minimum(_Base_ptr __x) _GLIBCXX_NOEXCEPT
     {
@@ -603,23 +607,33 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
         {
 	  _Key_compare		_M_key_compare;
 	  _Rb_tree_node_base 	_M_header;
+#if __cplusplus < 201103L
 	  size_type 		_M_node_count; // Keeps track of size of tree.
+#else
+	  size_type 		_M_node_count = 0; // Keeps track of size of tree.
+#endif
 
+#if __cplusplus < 201103L
 	  _Rb_tree_impl()
 	  : _Node_allocator(), _M_key_compare(), _M_header(),
 	    _M_node_count(0)
-	  { _M_initialize(); }
+	  { }
+#else
+	  _Rb_tree_impl() = default;
+#endif
 
 	  _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(); }
+	  : _Node_allocator(__a), _M_key_compare(__comp), _M_header()
+#if __cplusplus < 201103L
+	  , _M_node_count(0)
+#endif
+	  { }
 
 #if __cplusplus >= 201103L
 	  _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)), _M_key_compare(__comp),
+	      _M_header()
+	  { }
 #endif
 
 	  void
@@ -630,16 +644,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	    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;
@@ -831,7 +835,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
     public:
       // allocation/deallocation
+#if __cplusplus < 201103L
       _Rb_tree() { }
+#else
+      _Rb_tree() = default;
+#endif
 
       _Rb_tree(const _Compare& __comp,
 	       const allocator_type& __a = allocator_type())

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]