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())