diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt --- a/libcxx/include/CMakeLists.txt +++ b/libcxx/include/CMakeLists.txt @@ -34,6 +34,7 @@ __algorithm/is_permutation.h __algorithm/is_sorted.h __algorithm/is_sorted_until.h + __algorithm/iter_swap.h __algorithm/lexicographical_compare.h __algorithm/lower_bound.h __algorithm/make_heap.h @@ -85,6 +86,7 @@ __algorithm/sort_heap.h __algorithm/stable_partition.h __algorithm/stable_sort.h + __algorithm/swap_ranges.h __algorithm/transform.h __algorithm/unique_copy.h __algorithm/unique.h @@ -156,6 +158,11 @@ __tree __tuple __undef_macros + __utility/__decay_copy.h + __utility/declval.h + __utility/forward.h + __utility/move.h + __utility/swap.h __utility/to_underlying.h algorithm any diff --git a/libcxx/include/__algorithm/inplace_merge.h b/libcxx/include/__algorithm/inplace_merge.h --- a/libcxx/include/__algorithm/inplace_merge.h +++ b/libcxx/include/__algorithm/inplace_merge.h @@ -17,6 +17,7 @@ #include <__algorithm/min.h> #include <__algorithm/upper_bound.h> #include <__iterator/iterator_traits.h> +#include <__utility/swap.h> #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git a/libcxx/include/__algorithm/iter_swap.h b/libcxx/include/__algorithm/iter_swap.h new file mode 100644 --- /dev/null +++ b/libcxx/include/__algorithm/iter_swap.h @@ -0,0 +1,37 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_ITER_SWAP_H +#define _LIBCPP___ALGORITHM_ITER_SWAP_H + +#include <__config> +#include <__utility/declval.h> +#include <__utility/swap.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 void iter_swap(_ForwardIterator1 __a, + _ForwardIterator2 __b) + // _NOEXCEPT_(_NOEXCEPT_(swap(*__a, *__b))) + _NOEXCEPT_(_NOEXCEPT_(swap(*declval<_ForwardIterator1>(), *declval<_ForwardIterator2>()))) { + swap(*__a, *__b); +} + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___ALGORITHM_ITER_SWAP_H diff --git a/libcxx/include/__algorithm/move.h b/libcxx/include/__algorithm/move.h --- a/libcxx/include/__algorithm/move.h +++ b/libcxx/include/__algorithm/move.h @@ -11,6 +11,7 @@ #include <__config> #include <__algorithm/unwrap_iter.h> +#include <__utility/move.h> #include #include #include diff --git a/libcxx/include/__algorithm/next_permutation.h b/libcxx/include/__algorithm/next_permutation.h --- a/libcxx/include/__algorithm/next_permutation.h +++ b/libcxx/include/__algorithm/next_permutation.h @@ -14,7 +14,7 @@ #include <__algorithm/comp_ref_type.h> #include <__algorithm/reverse.h> #include <__iterator/iterator_traits.h> -#include // swap +#include <__utility/swap.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/libcxx/include/__algorithm/nth_element.h b/libcxx/include/__algorithm/nth_element.h --- a/libcxx/include/__algorithm/nth_element.h +++ b/libcxx/include/__algorithm/nth_element.h @@ -14,7 +14,7 @@ #include <__algorithm/comp_ref_type.h> #include <__algorithm/sort.h> #include <__iterator/iterator_traits.h> -#include // swap +#include <__utility/swap.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/libcxx/include/__algorithm/partial_sort.h b/libcxx/include/__algorithm/partial_sort.h --- a/libcxx/include/__algorithm/partial_sort.h +++ b/libcxx/include/__algorithm/partial_sort.h @@ -16,7 +16,7 @@ #include <__algorithm/sift_down.h> #include <__algorithm/sort_heap.h> #include <__iterator/iterator_traits.h> -#include // swap +#include <__utility/swap.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/libcxx/include/__algorithm/partition.h b/libcxx/include/__algorithm/partition.h --- a/libcxx/include/__algorithm/partition.h +++ b/libcxx/include/__algorithm/partition.h @@ -11,6 +11,8 @@ #include <__config> #include <__iterator/iterator_traits.h> +#include <__utility/swap.h> +#include // pair #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git a/libcxx/include/__algorithm/pop_heap.h b/libcxx/include/__algorithm/pop_heap.h --- a/libcxx/include/__algorithm/pop_heap.h +++ b/libcxx/include/__algorithm/pop_heap.h @@ -14,7 +14,7 @@ #include <__algorithm/comp_ref_type.h> #include <__algorithm/sift_down.h> #include <__iterator/iterator_traits.h> -#include // swap +#include <__utility/swap.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/libcxx/include/__algorithm/prev_permutation.h b/libcxx/include/__algorithm/prev_permutation.h --- a/libcxx/include/__algorithm/prev_permutation.h +++ b/libcxx/include/__algorithm/prev_permutation.h @@ -14,7 +14,7 @@ #include <__algorithm/comp_ref_type.h> #include <__algorithm/reverse.h> #include <__iterator/iterator_traits.h> -#include // swap +#include <__utility/swap.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/libcxx/include/__algorithm/push_heap.h b/libcxx/include/__algorithm/push_heap.h --- a/libcxx/include/__algorithm/push_heap.h +++ b/libcxx/include/__algorithm/push_heap.h @@ -13,7 +13,7 @@ #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> #include <__iterator/iterator_traits.h> -#include // swap +#include <__utility/move.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/libcxx/include/__algorithm/remove.h b/libcxx/include/__algorithm/remove.h --- a/libcxx/include/__algorithm/remove.h +++ b/libcxx/include/__algorithm/remove.h @@ -11,8 +11,8 @@ #include <__config> #include <__algorithm/find.h> -#include -#include +#include <__algorithm/find_if.h> +#include <__utility/move.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/libcxx/include/__algorithm/reverse.h b/libcxx/include/__algorithm/reverse.h --- a/libcxx/include/__algorithm/reverse.h +++ b/libcxx/include/__algorithm/reverse.h @@ -10,8 +10,8 @@ #define _LIBCPP___ALGORITHM_REVERSE_H #include <__config> +#include <__algorithm/iter_swap.h> #include <__iterator/iterator_traits.h> -#include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/libcxx/include/__algorithm/rotate.h b/libcxx/include/__algorithm/rotate.h --- a/libcxx/include/__algorithm/rotate.h +++ b/libcxx/include/__algorithm/rotate.h @@ -15,7 +15,8 @@ #include <__iterator/iterator_traits.h> #include <__iterator/next.h> #include <__iterator/prev.h> -#include +#include <__utility/swap.h> +#include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/libcxx/include/__algorithm/shift_right.h b/libcxx/include/__algorithm/shift_right.h --- a/libcxx/include/__algorithm/shift_right.h +++ b/libcxx/include/__algorithm/shift_right.h @@ -12,6 +12,7 @@ #include <__config> #include <__algorithm/move.h> #include <__algorithm/move_backward.h> +#include <__algorithm/swap_ranges.h> #include <__iterator/iterator_traits.h> #include // swap diff --git a/libcxx/include/__algorithm/shuffle.h b/libcxx/include/__algorithm/shuffle.h --- a/libcxx/include/__algorithm/shuffle.h +++ b/libcxx/include/__algorithm/shuffle.h @@ -12,9 +12,9 @@ #include <__config> #include <__iterator/iterator_traits.h> #include <__random/uniform_int_distribution.h> +#include <__utility/swap.h> #include #include -#include // swap #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/libcxx/include/__algorithm/sift_down.h b/libcxx/include/__algorithm/sift_down.h --- a/libcxx/include/__algorithm/sift_down.h +++ b/libcxx/include/__algorithm/sift_down.h @@ -11,8 +11,7 @@ #include <__config> #include <__iterator/iterator_traits.h> -#include -#include +#include <__utility/move.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/libcxx/include/__algorithm/sort.h b/libcxx/include/__algorithm/sort.h --- a/libcxx/include/__algorithm/sort.h +++ b/libcxx/include/__algorithm/sort.h @@ -15,6 +15,7 @@ #include <__algorithm/min_element.h> #include <__algorithm/partial_sort.h> #include <__algorithm/unwrap_iter.h> +#include <__utility/swap.h> #include #include // swap diff --git a/libcxx/include/__algorithm/stable_partition.h b/libcxx/include/__algorithm/stable_partition.h --- a/libcxx/include/__algorithm/stable_partition.h +++ b/libcxx/include/__algorithm/stable_partition.h @@ -12,6 +12,7 @@ #include <__config> #include <__algorithm/rotate.h> #include <__iterator/iterator_traits.h> +#include <__utility/swap.h> #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git a/libcxx/include/__algorithm/stable_sort.h b/libcxx/include/__algorithm/stable_sort.h --- a/libcxx/include/__algorithm/stable_sort.h +++ b/libcxx/include/__algorithm/stable_sort.h @@ -15,6 +15,7 @@ #include <__algorithm/inplace_merge.h> #include <__algorithm/sort.h> #include <__iterator/iterator_traits.h> +#include <__utility/swap.h> #include #include // swap diff --git a/libcxx/include/__algorithm/swap_ranges.h b/libcxx/include/__algorithm/swap_ranges.h new file mode 100644 --- /dev/null +++ b/libcxx/include/__algorithm/swap_ranges.h @@ -0,0 +1,52 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_SWAP_RANGES_H +#define _LIBCPP___ALGORITHM_SWAP_RANGES_H + +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +inline _LIBCPP_INLINE_VISIBILITY +#ifndef _LIBCPP_CXX03_LANG + typename enable_if::value && is_move_assignable<_Tp>::value>::type +#else + void +#endif + _LIBCPP_CONSTEXPR_AFTER_CXX17 + swap(_Tp& __x, _Tp& __y) + _NOEXCEPT_(is_nothrow_move_constructible<_Tp>::value&& is_nothrow_move_assignable<_Tp>::value); + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 + typename enable_if<__is_swappable<_Tp>::value>::type swap(_Tp (&__a)[_Np], _Tp (&__b)[_Np]) + _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value); + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator2 +swap_ranges(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2) { + for (; __first1 != __last1; ++__first1, (void)++__first2) + swap(*__first1, *__first2); + return __first2; +} + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___ALGORITHM_SWAP_RANGES_H diff --git a/libcxx/include/__algorithm/unique.h b/libcxx/include/__algorithm/unique.h --- a/libcxx/include/__algorithm/unique.h +++ b/libcxx/include/__algorithm/unique.h @@ -13,7 +13,7 @@ #include <__algorithm/comp.h> #include <__algorithm/adjacent_find.h> #include <__iterator/iterator_traits.h> -#include +#include <__utility/move.h> #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git a/libcxx/include/__iterator/concepts.h b/libcxx/include/__iterator/concepts.h --- a/libcxx/include/__iterator/concepts.h +++ b/libcxx/include/__iterator/concepts.h @@ -16,6 +16,7 @@ #include <__iterator/iterator_traits.h> #include <__iterator/readable_traits.h> #include <__memory/pointer_traits.h> +#include <__utility/forward.h> #include #include diff --git a/libcxx/include/__iterator/iter_move.h b/libcxx/include/__iterator/iter_move.h --- a/libcxx/include/__iterator/iter_move.h +++ b/libcxx/include/__iterator/iter_move.h @@ -12,6 +12,7 @@ #include <__config> #include <__iterator/iterator_traits.h> +#include <__utility/forward.h> #include // __class_or_enum #include #include diff --git a/libcxx/include/__memory/allocator.h b/libcxx/include/__memory/allocator.h --- a/libcxx/include/__memory/allocator.h +++ b/libcxx/include/__memory/allocator.h @@ -12,6 +12,7 @@ #include <__config> #include <__memory/allocator_traits.h> +#include <__utility/forward.h> #include #include #include diff --git a/libcxx/include/__memory/allocator_traits.h b/libcxx/include/__memory/allocator_traits.h --- a/libcxx/include/__memory/allocator_traits.h +++ b/libcxx/include/__memory/allocator_traits.h @@ -13,6 +13,7 @@ #include <__config> #include <__memory/construct_at.h> #include <__memory/pointer_traits.h> +#include <__utility/forward.h> #include #include diff --git a/libcxx/include/__memory/compressed_pair.h b/libcxx/include/__memory/compressed_pair.h --- a/libcxx/include/__memory/compressed_pair.h +++ b/libcxx/include/__memory/compressed_pair.h @@ -11,6 +11,7 @@ #define _LIBCPP___MEMORY_COMPRESSED_PAIR_H #include <__config> +#include <__utility/forward.h> #include // needed in c++03 for some constructors #include #include diff --git a/libcxx/include/__memory/construct_at.h b/libcxx/include/__memory/construct_at.h --- a/libcxx/include/__memory/construct_at.h +++ b/libcxx/include/__memory/construct_at.h @@ -12,6 +12,7 @@ #include <__config> #include <__debug> +#include <__utility/forward.h> #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git a/libcxx/include/__memory/shared_ptr.h b/libcxx/include/__memory/shared_ptr.h --- a/libcxx/include/__memory/shared_ptr.h +++ b/libcxx/include/__memory/shared_ptr.h @@ -20,6 +20,7 @@ #include <__memory/compressed_pair.h> #include <__memory/pointer_traits.h> #include <__memory/unique_ptr.h> +#include <__utility/forward.h> #include #include // abort #include diff --git a/libcxx/include/__memory/unique_ptr.h b/libcxx/include/__memory/unique_ptr.h --- a/libcxx/include/__memory/unique_ptr.h +++ b/libcxx/include/__memory/unique_ptr.h @@ -14,6 +14,7 @@ #include <__functional_base> // std::less #include <__memory/allocator_traits.h> // __pointer #include <__memory/compressed_pair.h> +#include <__utility/forward.h> #include #include #include diff --git a/libcxx/include/__ranges/access.h b/libcxx/include/__ranges/access.h --- a/libcxx/include/__ranges/access.h +++ b/libcxx/include/__ranges/access.h @@ -13,6 +13,8 @@ #include <__iterator/concepts.h> #include <__iterator/readable_traits.h> #include <__ranges/enable_borrowed_range.h> +#include <__utility/__decay_copy.h> +#include <__utility/forward.h> #include #include diff --git a/libcxx/include/__ranges/data.h b/libcxx/include/__ranges/data.h --- a/libcxx/include/__ranges/data.h +++ b/libcxx/include/__ranges/data.h @@ -14,6 +14,7 @@ #include <__iterator/iterator_traits.h> #include <__memory/pointer_traits.h> #include <__ranges/access.h> +#include <__utility/forward.h> #include #include diff --git a/libcxx/include/__ranges/empty.h b/libcxx/include/__ranges/empty.h --- a/libcxx/include/__ranges/empty.h +++ b/libcxx/include/__ranges/empty.h @@ -13,6 +13,7 @@ #include <__iterator/concepts.h> #include <__ranges/access.h> #include <__ranges/size.h> +#include <__utility/forward.h> #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git a/libcxx/include/__ranges/size.h b/libcxx/include/__ranges/size.h --- a/libcxx/include/__ranges/size.h +++ b/libcxx/include/__ranges/size.h @@ -13,6 +13,8 @@ #include <__iterator/concepts.h> #include <__iterator/iterator_traits.h> #include <__ranges/access.h> +#include <__utility/__decay_copy.h> +#include <__utility/forward.h> #include #include diff --git a/libcxx/include/__split_buffer b/libcxx/include/__split_buffer --- a/libcxx/include/__split_buffer +++ b/libcxx/include/__split_buffer @@ -3,6 +3,7 @@ #define _LIBCPP_SPLIT_BUFFER #include <__config> +#include <__utility/forward.h> #include #include diff --git a/libcxx/include/__tree b/libcxx/include/__tree --- a/libcxx/include/__tree +++ b/libcxx/include/__tree @@ -11,6 +11,7 @@ #define _LIBCPP___TREE #include <__config> +#include <__utility/forward.h> #include #include #include diff --git a/libcxx/include/__utility/__decay_copy.h b/libcxx/include/__utility/__decay_copy.h new file mode 100644 --- /dev/null +++ b/libcxx/include/__utility/__decay_copy.h @@ -0,0 +1,39 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_DECAY_COPY_H +#define _LIBCPP___TYPE_TRAITS_DECAY_COPY_H + +#include <__config> +#include <__utility/forward.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +inline _LIBCPP_INLINE_VISIBILITY typename decay<_Tp>::type __decay_copy(_Tp&& __t) +#if _LIBCPP_STD_VER > 17 + noexcept(is_nothrow_convertible_v<_Tp, remove_reference_t<_Tp> >) +#endif +{ + return _VSTD::forward<_Tp>(__t); +} + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___TYPE_TRAITS_DECAY_COPY_H diff --git a/libcxx/include/__utility/declval.h b/libcxx/include/__utility/declval.h new file mode 100644 --- /dev/null +++ b/libcxx/include/__utility/declval.h @@ -0,0 +1,39 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___UTILITY_DECLVAL_H +#define _LIBCPP___UTILITY_DECLVAL_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +// Suppress deprecation notice for volatile-qualified return type resulting +// from volatile-qualified types _Tp. +_LIBCPP_SUPPRESS_DEPRECATED_PUSH +template +_Tp&& __declval(int); +template +_Tp __declval(long); +_LIBCPP_SUPPRESS_DEPRECATED_POP + +template +decltype(__declval<_Tp>(0)) declval() _NOEXCEPT; + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___UTILITY_DECLVAL_H diff --git a/libcxx/include/__utility/forward.h b/libcxx/include/__utility/forward.h new file mode 100644 --- /dev/null +++ b/libcxx/include/__utility/forward.h @@ -0,0 +1,42 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___UTILITY_FORWARD_H +#define _LIBCPP___UTILITY_FORWARD_H + +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR _Tp&& +forward(typename remove_reference<_Tp>::type& __t) _NOEXCEPT { + return static_cast<_Tp&&>(__t); +} + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR _Tp&& +forward(typename remove_reference<_Tp>::type&& __t) _NOEXCEPT { + static_assert(!is_lvalue_reference<_Tp>::value, "cannot forward an rvalue as an lvalue"); + return static_cast<_Tp&&>(__t); +} + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___UTILITY_FORWARD_H diff --git a/libcxx/include/__utility/move.h b/libcxx/include/__utility/move.h new file mode 100644 --- /dev/null +++ b/libcxx/include/__utility/move.h @@ -0,0 +1,52 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___UTILITY_MOVE_H +#define _LIBCPP___UTILITY_MOVE_H + +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR typename remove_reference<_Tp>::type&& +move(_Tp&& __t) _NOEXCEPT { + typedef _LIBCPP_NODEBUG_TYPE typename remove_reference<_Tp>::type _Up; + return static_cast<_Up&&>(__t); +} + +#ifndef _LIBCPP_CXX03_LANG +template +using __move_if_noexcept_result_t = + typename conditional::value && is_copy_constructible<_Tp>::value, const _Tp&, + _Tp&&>::type; +#else // _LIBCPP_CXX03_LANG +template +using __move_if_noexcept_result_t = const _Tp&; +#endif + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 __move_if_noexcept_result_t<_Tp> +move_if_noexcept(_Tp& __x) _NOEXCEPT { + return _VSTD::move(__x); +} + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___UTILITY_MOVE_H diff --git a/libcxx/include/__utility/swap.h b/libcxx/include/__utility/swap.h new file mode 100644 --- /dev/null +++ b/libcxx/include/__utility/swap.h @@ -0,0 +1,57 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___UTILITY_SWAP_H +#define _LIBCPP___UTILITY_SWAP_H + +#include <__config> +#include <__utility/declval.h> +#include <__utility/move.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator2 +swap_ranges(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2); + +#ifndef _LIBCPP_CXX03_LANG +template +using __swap_result_t = typename enable_if::value && is_move_assignable<_Tp>::value>::type; +#else +template +using __swap_result_t = void; +#endif + +template +inline _LIBCPP_INLINE_VISIBILITY __swap_result_t<_Tp> _LIBCPP_CONSTEXPR_AFTER_CXX17 swap(_Tp& __x, _Tp& __y) + _NOEXCEPT_(is_nothrow_move_constructible<_Tp>::value&& is_nothrow_move_assignable<_Tp>::value) { + _Tp __t(_VSTD::move(__x)); + __x = _VSTD::move(__y); + __y = _VSTD::move(__t); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 typename enable_if<__is_swappable<_Tp>::value>::type +swap(_Tp (&__a)[_Np], _Tp (&__b)[_Np]) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value) { + _VSTD::swap_ranges(__a, __a + _Np, __b); +} + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___UTILITY_SWAP_H diff --git a/libcxx/include/algorithm b/libcxx/include/algorithm --- a/libcxx/include/algorithm +++ b/libcxx/include/algorithm @@ -695,6 +695,7 @@ #include <__algorithm/is_permutation.h> #include <__algorithm/is_sorted.h> #include <__algorithm/is_sorted_until.h> +#include <__algorithm/iter_swap.h> #include <__algorithm/lexicographical_compare.h> #include <__algorithm/lower_bound.h> #include <__algorithm/make_heap.h> @@ -746,6 +747,7 @@ #include <__algorithm/sort_heap.h> #include <__algorithm/stable_partition.h> #include <__algorithm/stable_sort.h> +#include <__algorithm/swap_ranges.h> #include <__algorithm/transform.h> #include <__algorithm/unique_copy.h> #include <__algorithm/unique.h> diff --git a/libcxx/include/any b/libcxx/include/any --- a/libcxx/include/any +++ b/libcxx/include/any @@ -82,6 +82,7 @@ #include <__availability> #include <__config> +#include <__utility/forward.h> #include #include #include diff --git a/libcxx/include/deque b/libcxx/include/deque --- a/libcxx/include/deque +++ b/libcxx/include/deque @@ -163,6 +163,7 @@ #include <__config> #include <__debug> #include <__split_buffer> +#include <__utility/forward.h> #include #include #include diff --git a/libcxx/include/exception b/libcxx/include/exception --- a/libcxx/include/exception +++ b/libcxx/include/exception @@ -266,7 +266,7 @@ _LIBCPP_NORETURN static inline _LIBCPP_INLINE_VISIBILITY void __do_throw(_Tp&& __t) { - throw __nested<_Up>(_VSTD::forward<_Tp>(__t)); + throw __nested<_Up>(static_cast<_Tp&&>(__t)); } }; @@ -279,7 +279,7 @@ __do_throw (_Tp& __t) #endif // _LIBCPP_CXX03_LANG { - throw _VSTD::forward<_Tp>(__t); + throw static_cast<_Tp&&>(__t); } }; #endif @@ -296,7 +296,7 @@ is_class<_Up>::value && !is_base_of::value && !__libcpp_is_final<_Up>::value>:: - __do_throw(_VSTD::forward<_Tp>(__t)); + __do_throw(static_cast<_Tp&&>(__t)); #else ((void)__t); // FIXME: Make this abort diff --git a/libcxx/include/experimental/iterator b/libcxx/include/experimental/iterator --- a/libcxx/include/experimental/iterator +++ b/libcxx/include/experimental/iterator @@ -56,6 +56,9 @@ #if _LIBCPP_STD_VER > 11 +#include <__memory/addressof.h> +#include <__utility/move.h> +#include <__utility/forward.h> #include _LIBCPP_BEGIN_NAMESPACE_LFTS diff --git a/libcxx/include/filesystem b/libcxx/include/filesystem --- a/libcxx/include/filesystem +++ b/libcxx/include/filesystem @@ -232,6 +232,7 @@ #include <__availability> #include <__config> #include <__debug> +#include <__utility/forward.h> #include #include #include diff --git a/libcxx/include/forward_list b/libcxx/include/forward_list --- a/libcxx/include/forward_list +++ b/libcxx/include/forward_list @@ -180,6 +180,7 @@ */ #include <__config> +#include <__utility/forward.h> #include #include #include diff --git a/libcxx/include/functional b/libcxx/include/functional --- a/libcxx/include/functional +++ b/libcxx/include/functional @@ -491,6 +491,7 @@ #include <__debug> #include <__functional_base> #include <__functional/search.h> +#include <__utility/forward.h> #include #include #include diff --git a/libcxx/include/future b/libcxx/include/future --- a/libcxx/include/future +++ b/libcxx/include/future @@ -364,6 +364,8 @@ #include <__availability> #include <__config> #include <__debug> +#include <__utility/__decay_copy.h> +#include <__utility/forward.h> #include #include #include diff --git a/libcxx/include/istream b/libcxx/include/istream --- a/libcxx/include/istream +++ b/libcxx/include/istream @@ -159,6 +159,7 @@ */ #include <__config> +#include <__utility/forward.h> #include #include diff --git a/libcxx/include/iterator b/libcxx/include/iterator --- a/libcxx/include/iterator +++ b/libcxx/include/iterator @@ -570,6 +570,7 @@ #include <__iterator/readable_traits.h> #include <__memory/addressof.h> #include <__memory/pointer_traits.h> +#include <__utility/forward.h> #include #include // Mandated by the Standard. #include diff --git a/libcxx/include/list b/libcxx/include/list --- a/libcxx/include/list +++ b/libcxx/include/list @@ -182,6 +182,7 @@ #include <__config> #include <__debug> +#include <__utility/forward.h> #include #include #include diff --git a/libcxx/include/map b/libcxx/include/map --- a/libcxx/include/map +++ b/libcxx/include/map @@ -493,6 +493,7 @@ #include <__debug> #include <__node_handle> #include <__tree> +#include <__utility/forward.h> #include #include #include diff --git a/libcxx/include/module.modulemap b/libcxx/include/module.modulemap --- a/libcxx/include/module.modulemap +++ b/libcxx/include/module.modulemap @@ -666,9 +666,12 @@ export * module __utility { - module to_underlying { - header "__utility/to_underlying.h" - } + module __decay_copy { header "__utility/__decay_copy.h" } + module declval { header "__utility/declval.h" } + module forward { header "__utility/forward.h" } + module move { header "__utility/move.h" } + module swap { header "__utility/swap.h" } + module to_underlying { header "__utility/to_underlying.h" } } } module valarray { diff --git a/libcxx/include/mutex b/libcxx/include/mutex --- a/libcxx/include/mutex +++ b/libcxx/include/mutex @@ -189,6 +189,7 @@ #include <__config> #include <__mutex_base> #include <__threading_support> +#include <__utility/forward.h> #include #include #include diff --git a/libcxx/include/queue b/libcxx/include/queue --- a/libcxx/include/queue +++ b/libcxx/include/queue @@ -179,6 +179,7 @@ */ #include <__config> +#include <__utility/forward.h> #include #include #include diff --git a/libcxx/include/scoped_allocator b/libcxx/include/scoped_allocator --- a/libcxx/include/scoped_allocator +++ b/libcxx/include/scoped_allocator @@ -106,6 +106,7 @@ */ #include <__config> +#include <__utility/forward.h> #include #include diff --git a/libcxx/include/set b/libcxx/include/set --- a/libcxx/include/set +++ b/libcxx/include/set @@ -437,6 +437,7 @@ #include <__debug> #include <__node_handle> #include <__tree> +#include <__utility/forward.h> #include #include #include diff --git a/libcxx/include/stack b/libcxx/include/stack --- a/libcxx/include/stack +++ b/libcxx/include/stack @@ -88,6 +88,7 @@ */ #include <__config> +#include <__utility/forward.h> #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git a/libcxx/include/thread b/libcxx/include/thread --- a/libcxx/include/thread +++ b/libcxx/include/thread @@ -87,6 +87,8 @@ #include <__functional_base> #include <__mutex_base> #include <__threading_support> +#include <__utility/__decay_copy.h> +#include <__utility/forward.h> #include #include #include diff --git a/libcxx/include/tuple b/libcxx/include/tuple --- a/libcxx/include/tuple +++ b/libcxx/include/tuple @@ -151,6 +151,8 @@ #include <__config> #include <__functional_base> +#include <__utility/forward.h> +#include <__utility/move.h> #include <__tuple> #include #include diff --git a/libcxx/include/type_traits b/libcxx/include/type_traits --- a/libcxx/include/type_traits +++ b/libcxx/include/type_traits @@ -2818,46 +2818,6 @@ #endif // __has_keyword(__is_destructible) -// move - -template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR -typename remove_reference<_Tp>::type&& -move(_Tp&& __t) _NOEXCEPT -{ - typedef _LIBCPP_NODEBUG_TYPE typename remove_reference<_Tp>::type _Up; - return static_cast<_Up&&>(__t); -} - -template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR -_Tp&& -forward(typename remove_reference<_Tp>::type& __t) _NOEXCEPT -{ - return static_cast<_Tp&&>(__t); -} - -template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR -_Tp&& -forward(typename remove_reference<_Tp>::type&& __t) _NOEXCEPT -{ - static_assert(!is_lvalue_reference<_Tp>::value, - "cannot forward an rvalue as an lvalue"); - return static_cast<_Tp&&>(__t); -} - -template -inline _LIBCPP_INLINE_VISIBILITY -typename decay<_Tp>::type -__decay_copy(_Tp&& __t) -#if _LIBCPP_STD_VER > 17 -noexcept(is_nothrow_convertible_v<_Tp, remove_reference_t<_Tp>>) -#endif -{ - return static_cast<_Tp&&>(__t); -} - template struct __member_pointer_traits_imp { @@ -4185,15 +4145,11 @@ #endif // _LIBCPP_STD_VER > 14 +// __swappable + template struct __is_swappable; template struct __is_nothrow_swappable; -// swap, swap_ranges - -template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -_ForwardIterator2 -swap_ranges(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2); #ifndef _LIBCPP_CXX03_LANG template @@ -4207,47 +4163,14 @@ inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 __swap_result_t<_Tp> swap(_Tp& __x, _Tp& __y) _NOEXCEPT_(is_nothrow_move_constructible<_Tp>::value && - is_nothrow_move_assignable<_Tp>::value) -{ - _Tp __t(_VSTD::move(__x)); - __x = _VSTD::move(__y); - __y = _VSTD::move(__t); -} + is_nothrow_move_assignable<_Tp>::value); template inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 typename enable_if< __is_swappable<_Tp>::value >::type -swap(_Tp (&__a)[_Np], _Tp (&__b)[_Np]) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value) -{ - _VSTD::swap_ranges(__a, __a + _Np, __b); -} - -template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -_ForwardIterator2 -swap_ranges(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2) -{ - for(; __first1 != __last1; ++__first1, (void) ++__first2) - swap(*__first1, *__first2); - return __first2; -} - -// iter_swap - -template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -void -iter_swap(_ForwardIterator1 __a, _ForwardIterator2 __b) - // _NOEXCEPT_(_NOEXCEPT_(swap(*__a, *__b))) - _NOEXCEPT_(_NOEXCEPT_(swap(*declval<_ForwardIterator1>(), - *declval<_ForwardIterator2>()))) -{ - swap(*__a, *__b); -} - -// __swappable +swap(_Tp (&__a)[_Np], _Tp (&__b)[_Np]) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value); namespace __detail { diff --git a/libcxx/include/unordered_map b/libcxx/include/unordered_map --- a/libcxx/include/unordered_map +++ b/libcxx/include/unordered_map @@ -435,6 +435,7 @@ #include <__debug> #include <__hash_table> #include <__node_handle> +#include <__utility/forward.h> #include #include #include // __libcpp_erase_if_container diff --git a/libcxx/include/unordered_set b/libcxx/include/unordered_set --- a/libcxx/include/unordered_set +++ b/libcxx/include/unordered_set @@ -390,6 +390,7 @@ #include <__debug> #include <__hash_table> #include <__node_handle> +#include <__utility/forward.h> #include #include #include // __libcpp_erase_if_container diff --git a/libcxx/include/utility b/libcxx/include/utility --- a/libcxx/include/utility +++ b/libcxx/include/utility @@ -210,6 +210,10 @@ #include <__config> #include <__debug> #include <__tuple> +#include <__utility/declval.h> +#include <__utility/forward.h> +#include <__utility/move.h> +#include <__utility/swap.h> #include <__utility/to_underlying.h> #include #include @@ -266,29 +270,6 @@ } // rel_ops -// swap_ranges is defined in ` - -// swap is defined in - -// move_if_noexcept - -template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 -#ifndef _LIBCPP_CXX03_LANG -typename conditional -< - !is_nothrow_move_constructible<_Tp>::value && is_copy_constructible<_Tp>::value, - const _Tp&, - _Tp&& ->::type -#else // _LIBCPP_CXX03_LANG -const _Tp& -#endif -move_if_noexcept(_Tp& __x) _NOEXCEPT -{ - return _VSTD::move(__x); -} - #if _LIBCPP_STD_VER > 14 template _LIBCPP_NODISCARD_EXT constexpr add_const_t<_Tp>& as_const(_Tp& __t) noexcept { return __t; } diff --git a/libcxx/include/variant b/libcxx/include/variant --- a/libcxx/include/variant +++ b/libcxx/include/variant @@ -201,6 +201,7 @@ #include <__availability> #include <__config> +#include <__utility/forward.h> #include <__tuple> #include #include diff --git a/libcxx/include/vector b/libcxx/include/vector --- a/libcxx/include/vector +++ b/libcxx/include/vector @@ -276,6 +276,7 @@ #include <__debug> #include <__functional_base> #include <__split_buffer> +#include <__utility/forward.h> #include #include #include diff --git a/libcxx/test/std/utilities/utility/forward/forward.fail.cpp b/libcxx/test/std/utilities/utility/forward/forward.fail.cpp --- a/libcxx/test/std/utilities/utility/forward/forward.fail.cpp +++ b/libcxx/test/std/utilities/utility/forward/forward.fail.cpp @@ -23,7 +23,7 @@ { { std::forward(source()); // expected-note {{requested here}} - // expected-error-re@type_traits:* 1 {{static_assert failed{{.*}} "cannot forward an rvalue as an lvalue"}} + // expected-error-re@*:* 1 {{static_assert failed{{.*}} "cannot forward an rvalue as an lvalue"}} } { const A ca = A(); diff --git a/libcxx/test/std/utilities/utility/utility.swap/swap.pass.cpp b/libcxx/test/std/utilities/utility/utility.swap/swap.pass.cpp --- a/libcxx/test/std/utilities/utility/utility.swap/swap.pass.cpp +++ b/libcxx/test/std/utilities/utility/utility.swap/swap.pass.cpp @@ -13,9 +13,10 @@ // void // swap(T& a, T& b); -#include #include #include +#include +#include #include "test_macros.h" diff --git a/libcxx/test/std/utilities/utility/utility.swap/swap_array.pass.cpp b/libcxx/test/std/utilities/utility/utility.swap/swap_array.pass.cpp --- a/libcxx/test/std/utilities/utility/utility.swap/swap_array.pass.cpp +++ b/libcxx/test/std/utilities/utility/utility.swap/swap_array.pass.cpp @@ -13,9 +13,11 @@ // void // swap(T (&a)[N], T (&b)[N]); -#include +#include #include #include +#include +#include #include "test_macros.h" diff --git a/libcxx/test/support/poisoned_hash_helper.h b/libcxx/test/support/poisoned_hash_helper.h --- a/libcxx/test/support/poisoned_hash_helper.h +++ b/libcxx/test/support/poisoned_hash_helper.h @@ -9,8 +9,9 @@ #ifndef SUPPORT_POISONED_HASH_HELPER_H #define SUPPORT_POISONED_HASH_HELPER_H -#include +#include <__utility/move.h> // TODO: replace with when std::hash is moved out of the header #include +#include #include "test_macros.h" #include "test_workarounds.h"