Implement the first part of N4258: 'Cleaning up noexcept in the Library'. This patch deals with swapping containers, and implements a more strict noexcept specification (a conforming extension) than the standard mandates.
git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@242056 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/__hash_table b/include/__hash_table
index d089bce..f3a2030 100644
--- a/include/__hash_table
+++ b/include/__hash_table
@@ -985,12 +985,14 @@
void swap(__hash_table& __u)
_NOEXCEPT_(
- (!allocator_traits<__pointer_allocator>::propagate_on_container_swap::value ||
- __is_nothrow_swappable<__pointer_allocator>::value) &&
- (!__node_traits::propagate_on_container_swap::value ||
- __is_nothrow_swappable<__node_allocator>::value) &&
- __is_nothrow_swappable<hasher>::value &&
- __is_nothrow_swappable<key_equal>::value);
+ __is_nothrow_swappable<hasher>::value && __is_nothrow_swappable<key_equal>::value
+#if _LIBCPP_STD_VER <= 11
+ && (!allocator_traits<__pointer_allocator>::propagate_on_container_swap::value
+ || __is_nothrow_swappable<__pointer_allocator>::value)
+ && (!__node_traits::propagate_on_container_swap::value
+ || __is_nothrow_swappable<__node_allocator>::value)
+#endif
+ );
_LIBCPP_INLINE_VISIBILITY
size_type max_bucket_count() const _NOEXCEPT
@@ -1118,38 +1120,6 @@
_LIBCPP_INLINE_VISIBILITY
void __move_assign_alloc(__hash_table&, false_type) _NOEXCEPT {}
- template <class _Ap>
- _LIBCPP_INLINE_VISIBILITY
- static
- void
- __swap_alloc(_Ap& __x, _Ap& __y)
- _NOEXCEPT_(
- !allocator_traits<_Ap>::propagate_on_container_swap::value ||
- __is_nothrow_swappable<_Ap>::value)
- {
- __swap_alloc(__x, __y,
- integral_constant<bool,
- allocator_traits<_Ap>::propagate_on_container_swap::value
- >());
- }
-
- template <class _Ap>
- _LIBCPP_INLINE_VISIBILITY
- static
- void
- __swap_alloc(_Ap& __x, _Ap& __y, true_type)
- _NOEXCEPT_(__is_nothrow_swappable<_Ap>::value)
- {
- using _VSTD::swap;
- swap(__x, __y);
- }
-
- template <class _Ap>
- _LIBCPP_INLINE_VISIBILITY
- static
- void
- __swap_alloc(_Ap&, _Ap&, false_type) _NOEXCEPT {}
-
void __deallocate(__node_pointer __np) _NOEXCEPT;
__node_pointer __detach() _NOEXCEPT;
@@ -2382,12 +2352,14 @@
void
__hash_table<_Tp, _Hash, _Equal, _Alloc>::swap(__hash_table& __u)
_NOEXCEPT_(
- (!allocator_traits<__pointer_allocator>::propagate_on_container_swap::value ||
- __is_nothrow_swappable<__pointer_allocator>::value) &&
- (!__node_traits::propagate_on_container_swap::value ||
- __is_nothrow_swappable<__node_allocator>::value) &&
- __is_nothrow_swappable<hasher>::value &&
- __is_nothrow_swappable<key_equal>::value)
+ __is_nothrow_swappable<hasher>::value && __is_nothrow_swappable<key_equal>::value
+#if _LIBCPP_STD_VER <= 11
+ && (!allocator_traits<__pointer_allocator>::propagate_on_container_swap::value
+ || __is_nothrow_swappable<__pointer_allocator>::value)
+ && (!__node_traits::propagate_on_container_swap::value
+ || __is_nothrow_swappable<__node_allocator>::value)
+#endif
+ )
{
{
__node_pointer_pointer __npp = __bucket_list_.release();
@@ -2395,9 +2367,9 @@
__u.__bucket_list_.reset(__npp);
}
_VSTD::swap(__bucket_list_.get_deleter().size(), __u.__bucket_list_.get_deleter().size());
- __swap_alloc(__bucket_list_.get_deleter().__alloc(),
+ __swap_allocator(__bucket_list_.get_deleter().__alloc(),
__u.__bucket_list_.get_deleter().__alloc());
- __swap_alloc(__node_alloc(), __u.__node_alloc());
+ __swap_allocator(__node_alloc(), __u.__node_alloc());
_VSTD::swap(__p1_.first().__next_, __u.__p1_.first().__next_);
__p2_.swap(__u.__p2_);
__p3_.swap(__u.__p3_);
diff --git a/include/__split_buffer b/include/__split_buffer
index 1d529cb..727b1b6 100644
--- a/include/__split_buffer
+++ b/include/__split_buffer
@@ -156,25 +156,6 @@
_LIBCPP_INLINE_VISIBILITY
void __move_assign_alloc(__split_buffer&, false_type) _NOEXCEPT
{}
-
- _LIBCPP_INLINE_VISIBILITY
- static void __swap_alloc(__alloc_rr& __x, __alloc_rr& __y)
- _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value||
- __is_nothrow_swappable<__alloc_rr>::value)
- {__swap_alloc(__x, __y, integral_constant<bool,
- __alloc_traits::propagate_on_container_swap::value>());}
-
- _LIBCPP_INLINE_VISIBILITY
- static void __swap_alloc(__alloc_rr& __x, __alloc_rr& __y, true_type)
- _NOEXCEPT_(__is_nothrow_swappable<__alloc_rr>::value)
- {
- using _VSTD::swap;
- swap(__x, __y);
- }
-
- _LIBCPP_INLINE_VISIBILITY
- static void __swap_alloc(__alloc_rr&, __alloc_rr&, false_type) _NOEXCEPT
- {}
};
template <class _Tp, class _Allocator>
@@ -431,7 +412,7 @@
_VSTD::swap(__begin_, __x.__begin_);
_VSTD::swap(__end_, __x.__end_);
_VSTD::swap(__end_cap(), __x.__end_cap());
- __swap_alloc(__alloc(), __x.__alloc());
+ __swap_allocator(__alloc(), __x.__alloc());
}
template <class _Tp, class _Allocator>
diff --git a/include/__tree b/include/__tree
index 588f438..574e74b 100644
--- a/include/__tree
+++ b/include/__tree
@@ -926,9 +926,12 @@
void swap(__tree& __t)
_NOEXCEPT_(
- __is_nothrow_swappable<value_compare>::value &&
- (!__node_traits::propagate_on_container_swap::value ||
- __is_nothrow_swappable<__node_allocator>::value));
+ __is_nothrow_swappable<value_compare>::value
+#if _LIBCPP_STD_VER <= 11
+ && (!__node_traits::propagate_on_container_swap::value ||
+ __is_nothrow_swappable<__node_allocator>::value)
+#endif
+ );
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
#ifndef _LIBCPP_HAS_NO_VARIADICS
@@ -1096,25 +1099,6 @@
_LIBCPP_INLINE_VISIBILITY
void __move_assign_alloc(__tree& __t, false_type) _NOEXCEPT {}
- _LIBCPP_INLINE_VISIBILITY
- static void __swap_alloc(__node_allocator& __x, __node_allocator& __y)
- _NOEXCEPT_(
- !__node_traits::propagate_on_container_swap::value ||
- __is_nothrow_swappable<__node_allocator>::value)
- {__swap_alloc(__x, __y, integral_constant<bool,
- __node_traits::propagate_on_container_swap::value>());}
- _LIBCPP_INLINE_VISIBILITY
- static void __swap_alloc(__node_allocator& __x, __node_allocator& __y, true_type)
- _NOEXCEPT_(__is_nothrow_swappable<__node_allocator>::value)
- {
- using _VSTD::swap;
- swap(__x, __y);
- }
- _LIBCPP_INLINE_VISIBILITY
- static void __swap_alloc(__node_allocator& __x, __node_allocator& __y, false_type)
- _NOEXCEPT
- {}
-
__node_pointer __detach();
static __node_pointer __detach(__node_pointer);
@@ -1452,15 +1436,18 @@
template <class _Tp, class _Compare, class _Allocator>
void
__tree<_Tp, _Compare, _Allocator>::swap(__tree& __t)
- _NOEXCEPT_(
- __is_nothrow_swappable<value_compare>::value &&
- (!__node_traits::propagate_on_container_swap::value ||
- __is_nothrow_swappable<__node_allocator>::value))
+ _NOEXCEPT_(
+ __is_nothrow_swappable<value_compare>::value
+#if _LIBCPP_STD_VER <= 11
+ && (!__node_traits::propagate_on_container_swap::value ||
+ __is_nothrow_swappable<__node_allocator>::value)
+#endif
+ )
{
using _VSTD::swap;
swap(__begin_node_, __t.__begin_node_);
swap(__pair1_.first(), __t.__pair1_.first());
- __swap_alloc(__node_alloc(), __t.__node_alloc());
+ __swap_allocator(__node_alloc(), __t.__node_alloc());
__pair3_.swap(__t.__pair3_);
if (size() == 0)
__begin_node() = __end_node();
diff --git a/include/deque b/include/deque
index a372560..5e152e4 100644
--- a/include/deque
+++ b/include/deque
@@ -124,8 +124,7 @@
iterator erase(const_iterator p);
iterator erase(const_iterator f, const_iterator l);
void swap(deque& c)
- noexcept(!allocator_type::propagate_on_container_swap::value ||
- __is_nothrow_swappable<allocator_type>::value);
+ noexcept(allocator_traits<allocator_type>::is_always_equal::value); // C++17
void clear() noexcept;
};
@@ -954,8 +953,12 @@
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
void swap(__deque_base& __c)
- _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
- __is_nothrow_swappable<allocator_type>::value);
+#if _LIBCPP_STD_VER >= 14
+ _NOEXCEPT;
+#else
+ _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
+ __is_nothrow_swappable<allocator_type>::value);
+#endif
protected:
void clear() _NOEXCEPT;
@@ -991,26 +994,6 @@
_LIBCPP_INLINE_VISIBILITY
void __move_assign_alloc(__deque_base&, false_type) _NOEXCEPT
{}
-
- _LIBCPP_INLINE_VISIBILITY
- static void __swap_alloc(allocator_type& __x, allocator_type& __y)
- _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
- __is_nothrow_swappable<allocator_type>::value)
- {__swap_alloc(__x, __y, integral_constant<bool,
- __alloc_traits::propagate_on_container_swap::value>());}
-
- _LIBCPP_INLINE_VISIBILITY
- static void __swap_alloc(allocator_type& __x, allocator_type& __y, true_type)
- _NOEXCEPT_(__is_nothrow_swappable<allocator_type>::value)
- {
- using _VSTD::swap;
- swap(__x, __y);
- }
-
- _LIBCPP_INLINE_VISIBILITY
- static void __swap_alloc(allocator_type&, allocator_type&, false_type)
- _NOEXCEPT
- {}
};
template <class _Tp, class _Allocator>
@@ -1134,13 +1117,17 @@
template <class _Tp, class _Allocator>
void
__deque_base<_Tp, _Allocator>::swap(__deque_base& __c)
- _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value||
- __is_nothrow_swappable<allocator_type>::value)
+#if _LIBCPP_STD_VER >= 14
+ _NOEXCEPT
+#else
+ _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
+ __is_nothrow_swappable<allocator_type>::value)
+#endif
{
__map_.swap(__c.__map_);
_VSTD::swap(__start_, __c.__start_);
_VSTD::swap(size(), __c.size());
- __swap_alloc(__alloc(), __c.__alloc());
+ __swap_allocator(__alloc(), __c.__alloc());
}
template <class _Tp, class _Allocator>
@@ -1342,8 +1329,12 @@
iterator erase(const_iterator __f, const_iterator __l);
void swap(deque& __c)
+#if _LIBCPP_STD_VER >= 14
+ _NOEXCEPT;
+#else
_NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
__is_nothrow_swappable<allocator_type>::value);
+#endif
void clear() _NOEXCEPT;
_LIBCPP_INLINE_VISIBILITY
@@ -2277,13 +2268,13 @@
__buf(max<size_type>(2 * __base::__map_.capacity(), 1),
0, __base::__map_.__alloc());
- typedef __allocator_destructor<_Allocator> _Dp;
- unique_ptr<pointer, _Dp> __hold(
- __alloc_traits::allocate(__a, __base::__block_size),
- _Dp(__a, __base::__block_size));
- __buf.push_back(__hold.get());
- __hold.release();
-
+ typedef __allocator_destructor<_Allocator> _Dp;
+ unique_ptr<pointer, _Dp> __hold(
+ __alloc_traits::allocate(__a, __base::__block_size),
+ _Dp(__a, __base::__block_size));
+ __buf.push_back(__hold.get());
+ __hold.release();
+
for (typename __base::__map_pointer __i = __base::__map_.begin();
__i != __base::__map_.end(); ++__i)
__buf.push_back(*__i);
@@ -2420,12 +2411,12 @@
__base::__map_.size(),
__base::__map_.__alloc());
- typedef __allocator_destructor<_Allocator> _Dp;
- unique_ptr<pointer, _Dp> __hold(
- __alloc_traits::allocate(__a, __base::__block_size),
- _Dp(__a, __base::__block_size));
- __buf.push_back(__hold.get());
- __hold.release();
+ typedef __allocator_destructor<_Allocator> _Dp;
+ unique_ptr<pointer, _Dp> __hold(
+ __alloc_traits::allocate(__a, __base::__block_size),
+ _Dp(__a, __base::__block_size));
+ __buf.push_back(__hold.get());
+ __hold.release();
for (typename __base::__map_pointer __i = __base::__map_.end();
__i != __base::__map_.begin();)
@@ -2793,8 +2784,12 @@
inline _LIBCPP_INLINE_VISIBILITY
void
deque<_Tp, _Allocator>::swap(deque& __c)
- _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
- __is_nothrow_swappable<allocator_type>::value)
+#if _LIBCPP_STD_VER >= 14
+ _NOEXCEPT
+#else
+ _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
+ __is_nothrow_swappable<allocator_type>::value)
+#endif
{
__base::swap(__c);
}
diff --git a/include/forward_list b/include/forward_list
index fbb850c..8a87fc5 100644
--- a/include/forward_list
+++ b/include/forward_list
@@ -107,8 +107,7 @@
iterator erase_after(const_iterator first, const_iterator last);
void swap(forward_list& x)
- noexcept(!allocator_type::propagate_on_container_swap::value ||
- __is_nothrow_swappable<allocator_type>::value);
+ noexcept(allocator_traits<allocator_type>::is_always_equal::value); // C++17
void resize(size_type n);
void resize(size_type n, const value_type& v);
@@ -431,8 +430,12 @@
public:
void swap(__forward_list_base& __x)
- _NOEXCEPT_(!__node_traits::propagate_on_container_swap::value ||
- __is_nothrow_swappable<__node_allocator>::value);
+#if _LIBCPP_STD_VER >= 14
+ _NOEXCEPT;
+#else
+ _NOEXCEPT_(!__node_traits::propagate_on_container_move_assignment::value ||
+ __is_nothrow_swappable<__node_allocator>::value);
+#endif
protected:
void clear() _NOEXCEPT;
@@ -454,26 +457,6 @@
void __move_assign_alloc(__forward_list_base& __x, true_type)
_NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value)
{__alloc() = _VSTD::move(__x.__alloc());}
-
- _LIBCPP_INLINE_VISIBILITY
- static void __swap_alloc(__node_allocator& __x, __node_allocator& __y)
- _NOEXCEPT_(!__node_traits::propagate_on_container_swap::value ||
- __is_nothrow_swappable<__node_allocator>::value)
- {__swap_alloc(__x, __y, integral_constant<bool,
- __node_traits::propagate_on_container_swap::value>());}
- _LIBCPP_INLINE_VISIBILITY
- static void __swap_alloc(__node_allocator& __x, __node_allocator& __y,
- false_type)
- _NOEXCEPT
- {}
- _LIBCPP_INLINE_VISIBILITY
- static void __swap_alloc(__node_allocator& __x, __node_allocator& __y,
- true_type)
- _NOEXCEPT_(__is_nothrow_swappable<__node_allocator>::value)
- {
- using _VSTD::swap;
- swap(__x, __y);
- }
};
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
@@ -512,10 +495,15 @@
inline _LIBCPP_INLINE_VISIBILITY
void
__forward_list_base<_Tp, _Alloc>::swap(__forward_list_base& __x)
- _NOEXCEPT_(!__node_traits::propagate_on_container_swap::value ||
- __is_nothrow_swappable<__node_allocator>::value)
+#if _LIBCPP_STD_VER >= 14
+ _NOEXCEPT
+#else
+ _NOEXCEPT_(!__node_traits::propagate_on_container_move_assignment::value ||
+ __is_nothrow_swappable<__node_allocator>::value)
+#endif
{
- __swap_alloc(__alloc(), __x.__alloc());
+ __swap_allocator(__alloc(), __x.__alloc(),
+ integral_constant<bool, __node_traits::propagate_on_container_swap::value>());
using _VSTD::swap;
swap(__before_begin()->__next_, __x.__before_begin()->__next_);
}
@@ -703,8 +691,12 @@
_LIBCPP_INLINE_VISIBILITY
void swap(forward_list& __x)
+#if _LIBCPP_STD_VER >= 14
+ _NOEXCEPT
+#else
_NOEXCEPT_(!__node_traits::propagate_on_container_swap::value ||
__is_nothrow_swappable<__node_allocator>::value)
+#endif
{base::swap(__x);}
void resize(size_type __n);
diff --git a/include/list b/include/list
index d39f076..14201a8 100644
--- a/include/list
+++ b/include/list
@@ -118,8 +118,7 @@
void resize(size_type sz, const value_type& c);
void swap(list&)
- noexcept(!allocator_type::propagate_on_container_swap::value ||
- __is_nothrow_swappable<allocator_type>::value);
+ noexcept(allocator_traits<allocator_type>::is_always_equal::value); // C++17
void clear() noexcept;
void splice(const_iterator position, list& x);
@@ -593,8 +592,12 @@
}
void swap(__list_imp& __c)
- _NOEXCEPT_(!__node_alloc_traits::propagate_on_container_swap::value ||
- __is_nothrow_swappable<__node_allocator>::value);
+#if _LIBCPP_STD_VER >= 14
+ _NOEXCEPT;
+#else
+ _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
+ __is_nothrow_swappable<allocator_type>::value);
+#endif
_LIBCPP_INLINE_VISIBILITY
void __copy_assign_alloc(const __list_imp& __c)
@@ -611,24 +614,6 @@
private:
_LIBCPP_INLINE_VISIBILITY
- static void __swap_alloc(__node_allocator& __x, __node_allocator& __y)
- _NOEXCEPT_(!__node_alloc_traits::propagate_on_container_swap::value ||
- __is_nothrow_swappable<__node_allocator>::value)
- {__swap_alloc(__x, __y, integral_constant<bool,
- __node_alloc_traits::propagate_on_container_swap::value>());}
- _LIBCPP_INLINE_VISIBILITY
- static void __swap_alloc(__node_allocator& __x, __node_allocator& __y, true_type)
- _NOEXCEPT_(__is_nothrow_swappable<__node_allocator>::value)
- {
- using _VSTD::swap;
- swap(__x, __y);
- }
- _LIBCPP_INLINE_VISIBILITY
- static void __swap_alloc(__node_allocator& __x, __node_allocator& __y, false_type)
- _NOEXCEPT
- {}
-
- _LIBCPP_INLINE_VISIBILITY
void __copy_assign_alloc(const __list_imp& __c, true_type)
{
if (__node_alloc() != __c.__node_alloc())
@@ -728,15 +713,19 @@
template <class _Tp, class _Alloc>
void
__list_imp<_Tp, _Alloc>::swap(__list_imp& __c)
- _NOEXCEPT_(!__node_alloc_traits::propagate_on_container_swap::value ||
- __is_nothrow_swappable<__node_allocator>::value)
+#if _LIBCPP_STD_VER >= 14
+ _NOEXCEPT
+#else
+ _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
+ __is_nothrow_swappable<allocator_type>::value)
+#endif
{
_LIBCPP_ASSERT(__alloc_traits::propagate_on_container_swap::value ||
this->__node_alloc() == __c.__node_alloc(),
"list::swap: Either propagate_on_container_swap must be true"
" or the allocators must compare equal");
using _VSTD::swap;
- __swap_alloc(__node_alloc(), __c.__node_alloc());
+ __swap_allocator(__node_alloc(), __c.__node_alloc());
swap(__sz(), __c.__sz());
swap(__end_, __c.__end_);
if (__sz() == 0)
@@ -972,8 +961,12 @@
_LIBCPP_INLINE_VISIBILITY
void swap(list& __c)
+#if _LIBCPP_STD_VER >= 14
+ _NOEXCEPT
+#else
_NOEXCEPT_(!__node_alloc_traits::propagate_on_container_swap::value ||
__is_nothrow_swappable<__node_allocator>::value)
+#endif
{base::swap(__c);}
_LIBCPP_INLINE_VISIBILITY
void clear() _NOEXCEPT {base::clear();}
diff --git a/include/map b/include/map
index 0f689b7..eb6b8ed 100644
--- a/include/map
+++ b/include/map
@@ -159,10 +159,8 @@
void clear() noexcept;
void swap(map& m)
- noexcept(
- __is_nothrow_swappable<key_compare>::value &&
- (!allocator_type::propagate_on_container_swap::value ||
- __is_nothrow_swappable<allocator_type>::value));
+ noexcept(allocator_traits<allocator_type>::is_always_equal::value &&
+ __is_nothrow_swappable<key_compare>::value); // C++17
// observers:
allocator_type get_allocator() const noexcept;
@@ -354,10 +352,8 @@
void clear() noexcept;
void swap(multimap& m)
- noexcept(
- __is_nothrow_swappable<key_compare>::value &&
- (!allocator_type::propagate_on_container_swap::value ||
- __is_nothrow_swappable<allocator_type>::value));
+ noexcept(allocator_traits<allocator_type>::is_always_equal::value &&
+ __is_nothrow_swappable<key_compare>::value); // C++17
// observers:
allocator_type get_allocator() const noexcept;
@@ -479,6 +475,12 @@
_LIBCPP_INLINE_VISIBILITY
bool operator()(const _Key& __x, const _CP& __y) const
{return static_cast<const _Compare&>(*this)(__x, __y.__cc.first);}
+ void swap(__map_value_compare&__y)
+ _NOEXCEPT_(__is_nothrow_swappable<_Compare>::value)
+ {
+ using _VSTD::swap;
+ swap(static_cast<const _Compare&>(*this), static_cast<const _Compare&>(__y));
+ }
#if _LIBCPP_STD_VER > 11
template <typename _K2>
@@ -521,7 +523,13 @@
_LIBCPP_INLINE_VISIBILITY
bool operator()(const _Key& __x, const _CP& __y) const
{return comp(__x, __y.__cc.first);}
-
+ void swap(__map_value_compare&__y)
+ _NOEXCEPT_(__is_nothrow_swappable<_Compare>::value)
+ {
+ using _VSTD::swap;
+ swap(comp, __y.comp);
+ }
+
#if _LIBCPP_STD_VER > 11
template <typename _K2>
_LIBCPP_INLINE_VISIBILITY
@@ -537,6 +545,16 @@
#endif
};
+template <class _Key, class _CP, class _Compare, bool __b>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+swap(__map_value_compare<_Key, _CP, _Compare, __b>& __x,
+ __map_value_compare<_Key, _CP, _Compare, __b>& __y)
+ _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
+{
+ __x.swap(__y);
+}
+
template <class _Allocator>
class __map_node_destructor
{
diff --git a/include/memory b/include/memory
index 4f59d80..9c1eef7 100644
--- a/include/memory
+++ b/include/memory
@@ -5543,6 +5543,38 @@
_LIBCPP_FUNC_VIS void* align(size_t __align, size_t __sz, void*& __ptr, size_t& __space);
+// --- Helper for container swap --
+template <typename _Alloc>
+_LIBCPP_INLINE_VISIBILITY
+void __swap_allocator(_Alloc & __a1, _Alloc & __a2)
+#if _LIBCPP_STD_VER >= 14
+ _NOEXCEPT
+#else
+ _NOEXCEPT_(__is_nothrow_swappable<_Alloc>::value)
+#endif
+{
+ __swap_allocator(__a1, __a2,
+ integral_constant<bool, _VSTD::allocator_traits<_Alloc>::propagate_on_container_swap::value>());
+}
+
+template <typename _Alloc>
+_LIBCPP_INLINE_VISIBILITY
+void __swap_allocator(_Alloc & __a1, _Alloc & __a2, true_type)
+#if _LIBCPP_STD_VER >= 14
+ _NOEXCEPT
+#else
+ _NOEXCEPT_(__is_nothrow_swappable<_Alloc>::value)
+#endif
+{
+ using _VSTD::swap;
+ swap(__a1, __a2);
+}
+
+template <typename _Alloc>
+_LIBCPP_INLINE_VISIBILITY
+void __swap_allocator(_Alloc &, _Alloc &, false_type) _NOEXCEPT {}
+
+
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_MEMORY
diff --git a/include/string b/include/string
index ac7b30a..6be2195 100644
--- a/include/string
+++ b/include/string
@@ -220,8 +220,8 @@
basic_string substr(size_type pos = 0, size_type n = npos) const;
void swap(basic_string& str)
- noexcept(!allocator_type::propagate_on_container_swap::value ||
- __is_nothrow_swappable<allocator_type>::value)
+ noexcept(allocator_traits<allocator_type>::propagate_on_container_swap::value ||
+ allocator_traits<allocator_type>::is_always_equal::value); // C++17
const value_type* c_str() const noexcept;
const value_type* data() const noexcept;
@@ -1604,8 +1604,12 @@
_LIBCPP_INLINE_VISIBILITY
void swap(basic_string& __str)
- _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
- __is_nothrow_swappable<allocator_type>::value);
+#if _LIBCPP_STD_VER >= 14
+ _NOEXCEPT;
+#else
+ _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
+ __is_nothrow_swappable<allocator_type>::value);
+#endif
_LIBCPP_INLINE_VISIBILITY
const value_type* c_str() const _NOEXCEPT {return data();}
@@ -1868,24 +1872,6 @@
_NOEXCEPT
{}
- _LIBCPP_INLINE_VISIBILITY
- static void __swap_alloc(allocator_type& __x, allocator_type& __y)
- _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
- __is_nothrow_swappable<allocator_type>::value)
- {__swap_alloc(__x, __y, integral_constant<bool,
- __alloc_traits::propagate_on_container_swap::value>());}
-
- _LIBCPP_INLINE_VISIBILITY
- static void __swap_alloc(allocator_type& __x, allocator_type& __y, true_type)
- _NOEXCEPT_(__is_nothrow_swappable<allocator_type>::value)
- {
- using _VSTD::swap;
- swap(__x, __y);
- }
- _LIBCPP_INLINE_VISIBILITY
- static void __swap_alloc(allocator_type&, allocator_type&, false_type) _NOEXCEPT
- {}
-
_LIBCPP_INLINE_VISIBILITY void __invalidate_all_iterators();
_LIBCPP_INLINE_VISIBILITY void __invalidate_iterators_past(size_type);
@@ -3366,8 +3352,12 @@
inline _LIBCPP_INLINE_VISIBILITY
void
basic_string<_CharT, _Traits, _Allocator>::swap(basic_string& __str)
- _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
- __is_nothrow_swappable<allocator_type>::value)
+#if _LIBCPP_STD_VER >= 14
+ _NOEXCEPT
+#else
+ _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
+ __is_nothrow_swappable<allocator_type>::value)
+#endif
{
#if _LIBCPP_DEBUG_LEVEL >= 2
if (!__is_long())
@@ -3377,7 +3367,7 @@
__get_db()->swap(this, &__str);
#endif
_VSTD::swap(__r_.first(), __str.__r_.first());
- __swap_alloc(__alloc(), __str.__alloc());
+ __swap_allocator(__alloc(), __str.__alloc());
}
// find
diff --git a/include/unordered_map b/include/unordered_map
index fe20bdb..cf70ab6 100644
--- a/include/unordered_map
+++ b/include/unordered_map
@@ -401,6 +401,12 @@
_LIBCPP_INLINE_VISIBILITY
size_t operator()(const _Key& __x) const
{return static_cast<const _Hash&>(*this)(__x);}
+ void swap(__unordered_map_hasher&__y)
+ _NOEXCEPT_(__is_nothrow_swappable<_Hash>::value)
+ {
+ using _VSTD::swap;
+ swap(static_cast<const _Hash&>(*this), static_cast<const _Hash&>(__y));
+ }
};
template <class _Key, class _Cp, class _Hash>
@@ -425,8 +431,24 @@
_LIBCPP_INLINE_VISIBILITY
size_t operator()(const _Key& __x) const
{return __hash_(__x);}
+ void swap(__unordered_map_hasher&__y)
+ _NOEXCEPT_(__is_nothrow_swappable<_Hash>::value)
+ {
+ using _VSTD::swap;
+ swap(__hash_, __y.__hash_);
+ }
};
+template <class _Key, class _Cp, class _Hash, bool __b>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+swap(__unordered_map_hasher<_Key, _Cp, _Hash, __b>& __x,
+ __unordered_map_hasher<_Key, _Cp, _Hash, __b>& __y)
+ _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
+{
+ __x.swap(__y);
+}
+
template <class _Key, class _Cp, class _Pred,
bool = is_empty<_Pred>::value && !__libcpp_is_final<_Pred>::value
>
@@ -453,6 +475,12 @@
_LIBCPP_INLINE_VISIBILITY
bool operator()(const _Key& __x, const _Cp& __y) const
{return static_cast<const _Pred&>(*this)(__x, __y.__cc.first);}
+ void swap(__unordered_map_equal&__y)
+ _NOEXCEPT_(__is_nothrow_swappable<_Pred>::value)
+ {
+ using _VSTD::swap;
+ swap(static_cast<const _Pred&>(*this), static_cast<const _Pred&>(__y));
+ }
};
template <class _Key, class _Cp, class _Pred>
@@ -480,8 +508,24 @@
_LIBCPP_INLINE_VISIBILITY
bool operator()(const _Key& __x, const _Cp& __y) const
{return __pred_(__x, __y.__cc.first);}
+ void swap(__unordered_map_equal&__y)
+ _NOEXCEPT_(__is_nothrow_swappable<_Pred>::value)
+ {
+ using _VSTD::swap;
+ swap(__pred_, __y.__pred_);
+ }
};
+template <class _Key, class _Cp, class _Pred, bool __b>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+swap(__unordered_map_equal<_Key, _Cp, _Pred, __b>& __x,
+ __unordered_map_equal<_Key, _Cp, _Pred, __b>& __y)
+ _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
+{
+ __x.swap(__y);
+}
+
template <class _Alloc>
class __hash_map_node_destructor
{
diff --git a/include/unordered_set b/include/unordered_set
index 26ef6fd..f6ccdc3 100644
--- a/include/unordered_set
+++ b/include/unordered_set
@@ -120,11 +120,9 @@
void clear() noexcept;
void swap(unordered_set&)
- noexcept(
- (!allocator_type::propagate_on_container_swap::value ||
- __is_nothrow_swappable<allocator_type>::value) &&
- __is_nothrow_swappable<hasher>::value &&
- __is_nothrow_swappable<key_equal>::value);
+ noexcept(allocator_traits<Allocator>::is_always_equal::value &&
+ noexcept(swap(declval<hasher&>(), declval<hasher&>())) &&
+ noexcept(swap(declval<key_equal&>(), declval<key_equal&>()))); // C++17
hasher hash_function() const;
key_equal key_eq() const;
@@ -270,11 +268,9 @@
void clear() noexcept;
void swap(unordered_multiset&)
- noexcept(
- (!allocator_type::propagate_on_container_swap::value ||
- __is_nothrow_swappable<allocator_type>::value) &&
- __is_nothrow_swappable<hasher>::value &&
- __is_nothrow_swappable<key_equal>::value);
+ noexcept(allocator_traits<Allocator>::is_always_equal::value &&
+ noexcept(swap(declval<hasher&>(), declval<hasher&>())) &&
+ noexcept(swap(declval<key_equal&>(), declval<key_equal&>()))); // C++17
hasher hash_function() const;
key_equal key_eq() const;
diff --git a/include/vector b/include/vector
index 3600147..65a087c 100644
--- a/include/vector
+++ b/include/vector
@@ -119,8 +119,8 @@
void resize(size_type sz, const value_type& c);
void swap(vector&)
- noexcept(!allocator_type::propagate_on_container_swap::value ||
- __is_nothrow_swappable<allocator_type>::value);
+ noexcept(allocator_traits<allocator_type>::propagate_on_container_swap::value ||
+ allocator_traits<allocator_type>::is_always_equal::value); // C++17
bool __invariants() const;
};
@@ -237,8 +237,8 @@
void resize(size_type sz, value_type x);
void swap(vector&)
- noexcept(!allocator_type::propagate_on_container_swap::value ||
- __is_nothrow_swappable<allocator_type>::value);
+ noexcept(allocator_traits<allocator_type>::propagate_on_container_swap::value ||
+ allocator_traits<allocator_type>::is_always_equal::value); // C++17
void flip() noexcept;
bool __invariants() const;
@@ -385,14 +385,6 @@
is_nothrow_move_assignable<allocator_type>::value)
{__move_assign_alloc(__c, integral_constant<bool,
__alloc_traits::propagate_on_container_move_assignment::value>());}
-
- _LIBCPP_INLINE_VISIBILITY
- static void __swap_alloc(allocator_type& __x, allocator_type& __y)
- _NOEXCEPT_(
- !__alloc_traits::propagate_on_container_swap::value ||
- __is_nothrow_swappable<allocator_type>::value)
- {__swap_alloc(__x, __y, integral_constant<bool,
- __alloc_traits::propagate_on_container_swap::value>());}
private:
_LIBCPP_INLINE_VISIBILITY
void __copy_assign_alloc(const __vector_base& __c, true_type)
@@ -421,18 +413,6 @@
void __move_assign_alloc(__vector_base&, false_type)
_NOEXCEPT
{}
-
- _LIBCPP_INLINE_VISIBILITY
- static void __swap_alloc(allocator_type& __x, allocator_type& __y, true_type)
- _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
- {
- using _VSTD::swap;
- swap(__x, __y);
- }
- _LIBCPP_INLINE_VISIBILITY
- static void __swap_alloc(allocator_type&, allocator_type&, false_type)
- _NOEXCEPT
- {}
};
template <class _Tp, class _Allocator>
@@ -760,8 +740,12 @@
void resize(size_type __sz, const_reference __x);
void swap(vector&)
- _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
- __is_nothrow_swappable<allocator_type>::value);
+#if _LIBCPP_STD_VER >= 14
+ _NOEXCEPT;
+#else
+ _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
+ __is_nothrow_swappable<allocator_type>::value);
+#endif
bool __invariants() const;
@@ -2016,8 +2000,12 @@
template <class _Tp, class _Allocator>
void
vector<_Tp, _Allocator>::swap(vector& __x)
- _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
- __is_nothrow_swappable<allocator_type>::value)
+#if _LIBCPP_STD_VER >= 14
+ _NOEXCEPT
+#else
+ _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
+ __is_nothrow_swappable<allocator_type>::value)
+#endif
{
_LIBCPP_ASSERT(__alloc_traits::propagate_on_container_swap::value ||
this->__alloc() == __x.__alloc(),
@@ -2026,7 +2014,8 @@
_VSTD::swap(this->__begin_, __x.__begin_);
_VSTD::swap(this->__end_, __x.__end_);
_VSTD::swap(this->__end_cap(), __x.__end_cap());
- __base::__swap_alloc(this->__alloc(), __x.__alloc());
+ __swap_allocator(this->__alloc(), __x.__alloc(),
+ integral_constant<bool,__alloc_traits::propagate_on_container_swap::value>());
#if _LIBCPP_DEBUG_LEVEL >= 2
__get_db()->swap(this, &__x);
#endif // _LIBCPP_DEBUG_LEVEL >= 2
@@ -2354,8 +2343,12 @@
void clear() _NOEXCEPT {__size_ = 0;}
void swap(vector&)
- _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
- __is_nothrow_swappable<allocator_type>::value);
+#if _LIBCPP_STD_VER >= 14
+ _NOEXCEPT;
+#else
+ _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
+ __is_nothrow_swappable<allocator_type>::value);
+#endif
void resize(size_type __sz, value_type __x = false);
void flip() _NOEXCEPT;
@@ -2433,26 +2426,6 @@
_NOEXCEPT
{}
- _LIBCPP_INLINE_VISIBILITY
- static void __swap_alloc(__storage_allocator& __x, __storage_allocator& __y)
- _NOEXCEPT_(
- !__storage_traits::propagate_on_container_swap::value ||
- __is_nothrow_swappable<allocator_type>::value)
- {__swap_alloc(__x, __y, integral_constant<bool,
- __storage_traits::propagate_on_container_swap::value>());}
-
- _LIBCPP_INLINE_VISIBILITY
- static void __swap_alloc(__storage_allocator& __x, __storage_allocator& __y, true_type)
- _NOEXCEPT_(__is_nothrow_swappable<allocator_type>::value)
- {
- using _VSTD::swap;
- swap(__x, __y);
- }
- _LIBCPP_INLINE_VISIBILITY
- static void __swap_alloc(__storage_allocator&, __storage_allocator&, false_type)
- _NOEXCEPT
- {}
-
size_t __hash_code() const _NOEXCEPT;
friend class __bit_reference<vector>;
@@ -3155,13 +3128,18 @@
template <class _Allocator>
void
vector<bool, _Allocator>::swap(vector& __x)
- _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
- __is_nothrow_swappable<allocator_type>::value)
+#if _LIBCPP_STD_VER >= 14
+ _NOEXCEPT
+#else
+ _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
+ __is_nothrow_swappable<allocator_type>::value)
+#endif
{
_VSTD::swap(this->__begin_, __x.__begin_);
_VSTD::swap(this->__size_, __x.__size_);
_VSTD::swap(this->__cap(), __x.__cap());
- __swap_alloc(this->__alloc(), __x.__alloc());
+ __swap_allocator(this->__alloc(), __x.__alloc(),
+ integral_constant<bool, __alloc_traits::propagate_on_container_swap::value>());
}
template <class _Allocator>