diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt --- a/libcxx/include/CMakeLists.txt +++ b/libcxx/include/CMakeLists.txt @@ -28,6 +28,7 @@ __algorithm/is_partitioned.h __algorithm/is_permutation.h __algorithm/is_sorted.h + __algorithm/iter_swap.h __algorithm/lexicographical_compare.h __algorithm/lower_bound.h __algorithm/make_heap.h @@ -67,6 +68,7 @@ __algorithm/sort_heap.h __algorithm/stable_partition.h __algorithm/stable_sort.h + __algorithm/swap_ranges.h __algorithm/transform.h __algorithm/uniform_int_distribution.h __algorithm/unique.h @@ -79,6 +81,7 @@ __bsd_locale_fallbacks.h __config __debug + __decay_copy.h __errc __format/format_error.h __format/format_parse_context.h @@ -133,7 +136,15 @@ __threading_support __tree __tuple + __type_traits/integral_constant.h + __type_traits/is_same.h + __type_traits/references.h __undef_macros + __utility/declval.h + __utility/forward.h + __utility/move_if_noexcept.h + __utility/move.h + __utility/swap.h __utility/to_underlying.h algorithm any 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 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 @@ -12,6 +12,7 @@ #include <__config> #include <__algorithm/comp_ref_type.h> #include <__iterator/iterator_traits.h> +#include <__utility/move.h> #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_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 @@ -12,6 +12,7 @@ #include <__config> #include <__algorithm/find.h> #include <__algorithm/find_if.h> +#include <__utility/move.h> #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_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/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,6 +11,7 @@ #include <__config> #include <__iterator/iterator_traits.h> +#include <__utility/move.h> #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 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 @@ -12,6 +12,7 @@ #include <__config> #include <__algorithm/adjacent_find.h> #include <__iterator/iterator_traits.h> +#include <__utility/move.h> #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git a/libcxx/include/__decay_copy.h b/libcxx/include/__decay_copy.h new file mode 100644 --- /dev/null +++ b/libcxx/include/__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___DECAY_COPY_H +#define _LIBCPP___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___DECAY_COPY_H 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 @@ -10,6 +10,7 @@ #define _LIBCPP___RANGES_ACCESS_H #include <__config> +#include <__decay_copy.h> #include <__iterator/concepts.h> #include <__ranges/enable_borrowed_range.h> #include 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 @@ -10,6 +10,7 @@ #define _LIBCPP___RANGES_SIZE_H #include <__config> +#include <__decay_copy.h> #include <__iterator/concepts.h> #include <__iterator/iterator_traits.h> #include <__ranges/access.h> diff --git a/libcxx/include/__type_traits/integral_constant.h b/libcxx/include/__type_traits/integral_constant.h new file mode 100644 --- /dev/null +++ b/libcxx/include/__type_traits/integral_constant.h @@ -0,0 +1,58 @@ +// -*- 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_INTEGRAL_CONSTANT_H +#define _LIBCPP___TYPE_TRAITS_INTEGRAL_CONSTANT_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 + +template +struct _LIBCPP_TEMPLATE_VIS integral_constant { + static _LIBCPP_CONSTEXPR const _Tp value = __v; + typedef _Tp value_type; + typedef integral_constant type; + _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR operator value_type() const _NOEXCEPT { return value; } +#if _LIBCPP_STD_VER > 11 + _LIBCPP_INLINE_VISIBILITY + constexpr value_type operator()() const _NOEXCEPT { return value; } +#endif +}; + +template +_LIBCPP_CONSTEXPR const _Tp integral_constant<_Tp, __v>::value; + +#if _LIBCPP_STD_VER > 14 +template +using bool_constant = integral_constant; +#define _LIBCPP_BOOL_CONSTANT(__b) bool_constant<(__b)> +#else +#define _LIBCPP_BOOL_CONSTANT(__b) integral_constant +#endif + +typedef _LIBCPP_BOOL_CONSTANT(true) true_type; +typedef _LIBCPP_BOOL_CONSTANT(false) false_type; + +template +using _BoolConstant _LIBCPP_NODEBUG_TYPE = integral_constant; + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___TYPE_TRAITS_INTEGRAL_CONSTANT_H diff --git a/libcxx/include/__type_traits/is_same.h b/libcxx/include/__type_traits/is_same.h new file mode 100644 --- /dev/null +++ b/libcxx/include/__type_traits/is_same.h @@ -0,0 +1,73 @@ +// -*- 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_IS_SAME_H +#define _LIBCPP___TYPE_TRAITS_IS_SAME_H + +#include <__config> +#include <__type_traits/integral_constant.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +// is_same + +#if __has_keyword(__is_same) + +template +struct _LIBCPP_TEMPLATE_VIS is_same : _BoolConstant<__is_same(_Tp, _Up)> {}; + +#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) +template +_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_same_v = __is_same(_Tp, _Up); +#endif + +#else + +template +struct _LIBCPP_TEMPLATE_VIS is_same : public false_type {}; +template +struct _LIBCPP_TEMPLATE_VIS is_same<_Tp, _Tp> : public true_type {}; + +#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) +template +_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_same_v = is_same<_Tp, _Up>::value; +#endif + +#endif // __is_same + +template +using _IsSame = _BoolConstant< +#ifdef __clang__ + __is_same(_Tp, _Up) +#else + is_same<_Tp, _Up>::value +#endif + >; + +template +using _IsNotSame = _BoolConstant< +#ifdef __clang__ + !__is_same(_Tp, _Up) +#else + !is_same<_Tp, _Up>::value +#endif + >; + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___TYPE_TRAITS_IS_SAME_H diff --git a/libcxx/include/__type_traits/references.h b/libcxx/include/__type_traits/references.h new file mode 100644 --- /dev/null +++ b/libcxx/include/__type_traits/references.h @@ -0,0 +1,174 @@ +// -*- 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_REFERENCES_H +#define _LIBCPP___TYPE_TRAITS_REFERENCES_H + +#include <__config> +#include <__type_traits/integral_constant.h> +#include <__type_traits/is_same.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +// is_reference + +#if __has_keyword(__is_lvalue_reference) && __has_keyword(__is_rvalue_reference) && __has_keyword(__is_reference) + +template +struct _LIBCPP_TEMPLATE_VIS is_lvalue_reference : _BoolConstant<__is_lvalue_reference(_Tp)> {}; + +template +struct _LIBCPP_TEMPLATE_VIS is_rvalue_reference : _BoolConstant<__is_rvalue_reference(_Tp)> {}; + +template +struct _LIBCPP_TEMPLATE_VIS is_reference : _BoolConstant<__is_reference(_Tp)> {}; + +#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) +template +_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_reference_v = __is_reference(_Tp); + +template +_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_lvalue_reference_v = __is_lvalue_reference(_Tp); + +template +_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_rvalue_reference_v = __is_rvalue_reference(_Tp); +#endif + +#else // __has_keyword(__is_lvalue_reference) && etc... + +template +struct _LIBCPP_TEMPLATE_VIS is_lvalue_reference : public false_type {}; +template +struct _LIBCPP_TEMPLATE_VIS is_lvalue_reference<_Tp&> : public true_type {}; + +template +struct _LIBCPP_TEMPLATE_VIS is_rvalue_reference : public false_type {}; +template +struct _LIBCPP_TEMPLATE_VIS is_rvalue_reference<_Tp&&> : public true_type {}; + +template +struct _LIBCPP_TEMPLATE_VIS is_reference : public false_type {}; +template +struct _LIBCPP_TEMPLATE_VIS is_reference<_Tp&> : public true_type {}; +template +struct _LIBCPP_TEMPLATE_VIS is_reference<_Tp&&> : public true_type {}; + +#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) +template +_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_reference_v = is_reference<_Tp>::value; + +template +_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_lvalue_reference_v = is_lvalue_reference<_Tp>::value; + +template +_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_rvalue_reference_v = is_rvalue_reference<_Tp>::value; +#endif + +#endif // __has_keyword(__is_lvalue_reference) && etc... + +// remove_reference + +#if __has_keyword(__remove_reference) + +template +struct _LIBCPP_TEMPLATE_VIS remove_reference { + typedef __remove_reference(_Tp) type; +}; + +#else // __has_keyword(__remove_reference) + +template +struct _LIBCPP_TEMPLATE_VIS remove_reference { + typedef _LIBCPP_NODEBUG_TYPE _Tp type; +}; +template +struct _LIBCPP_TEMPLATE_VIS remove_reference<_Tp&> { + typedef _LIBCPP_NODEBUG_TYPE _Tp type; +}; +template +struct _LIBCPP_TEMPLATE_VIS remove_reference<_Tp&&> { + typedef _LIBCPP_NODEBUG_TYPE _Tp type; +}; + +#if _LIBCPP_STD_VER > 11 +template +using remove_reference_t = typename remove_reference<_Tp>::type; +#endif + +#endif // __has_keyword(__remove_reference) + +struct __two { + char __lx[2]; +}; + +// __is_referenceable [defns.referenceable] + +struct __is_referenceable_impl { + template + static _Tp& __test(int); + template + static __two __test(...); +}; + +template +struct __is_referenceable + : integral_constant(0)), __two>::value> {}; + +// add_lvalue_reference + +template ::value> +struct __add_lvalue_reference_impl { + typedef _LIBCPP_NODEBUG_TYPE _Tp type; +}; +template +struct __add_lvalue_reference_impl<_Tp, true> { + typedef _LIBCPP_NODEBUG_TYPE _Tp& type; +}; + +template +struct _LIBCPP_TEMPLATE_VIS add_lvalue_reference { + typedef _LIBCPP_NODEBUG_TYPE typename __add_lvalue_reference_impl<_Tp>::type type; +}; + +#if _LIBCPP_STD_VER > 11 +template +using add_lvalue_reference_t = typename add_lvalue_reference<_Tp>::type; +#endif + +template ::value> +struct __add_rvalue_reference_impl { + typedef _LIBCPP_NODEBUG_TYPE _Tp type; +}; +template +struct __add_rvalue_reference_impl<_Tp, true> { + typedef _LIBCPP_NODEBUG_TYPE _Tp&& type; +}; + +template +struct _LIBCPP_TEMPLATE_VIS add_rvalue_reference { + typedef _LIBCPP_NODEBUG_TYPE typename __add_rvalue_reference_impl<_Tp>::type type; +}; + +#if _LIBCPP_STD_VER > 11 +template +using add_rvalue_reference_t = typename add_rvalue_reference<_Tp>::type; +#endif + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___TYPE_TRAITS_REFERENCES_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 <__type_traits/references.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 +_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,36 @@ +// -*- 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 <__type_traits/references.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 +_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); +} + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___UTILITY_MOVE_H diff --git a/libcxx/include/__utility/move_if_noexcept.h b/libcxx/include/__utility/move_if_noexcept.h new file mode 100644 --- /dev/null +++ b/libcxx/include/__utility/move_if_noexcept.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_MOVE_IF_NOEXCEPT_H +#define _LIBCPP___UTILITY_MOVE_IF_NOEXCEPT_H + +#include <__config> +#include <__utility/move.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 +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +#ifndef _LIBCPP_CXX03_LANG + typename conditional::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); +} + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___UTILITY_MOVE_IF_NOEXCEPT_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,54 @@ +//===----------------------------------------------------------------------===// +// +// 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/move.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 _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator2 +swap_ranges(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2); + +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) { + _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 @@ -689,6 +689,7 @@ #include <__algorithm/is_partitioned.h> #include <__algorithm/is_permutation.h> #include <__algorithm/is_sorted.h> +#include <__algorithm/iter_swap.h> #include <__algorithm/lexicographical_compare.h> #include <__algorithm/lower_bound.h> #include <__algorithm/make_heap.h> @@ -728,6 +729,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/uniform_int_distribution.h> #include <__algorithm/unique.h> diff --git a/libcxx/include/future b/libcxx/include/future --- a/libcxx/include/future +++ b/libcxx/include/future @@ -364,6 +364,7 @@ #include <__availability> #include <__config> #include <__debug> +#include <__decay_copy.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 @@ -619,6 +619,12 @@ module type_traits { header "type_traits" export * + + module __type_traits { + module integral_constant { header "__type_traits/integral_constant.h" } + module is_same { header "__type_traits/is_same.h" } + module references { header "__type_traits/references.h" } + } } module typeindex { header "typeindex" @@ -644,9 +650,12 @@ export * module __utility { - module to_underlying { - header "__utility/to_underlying.h" - } + module declval { header "__utility/declval.h" } + module forward { header "__utility/forward.h" } + module move_if_noexcept { header "__utility/move_if_noexcept.h" } + module move { header "__utility/move.h" } + module swap { header "__utility/swap.h" } + module to_underlying { header "__utility/to_underlying.h" } } } module valarray { @@ -674,6 +683,7 @@ module __bits { header "__bits" export * } module __config { header "__config" export * } module __debug { header "__debug" export * } + module __decay_copy { header "__decay_copy.h" export * } module __errc { header "__errc" export * } module __function_like { header "__function_like.h" export * } module __functional_base { header "__functional_base" export * } diff --git a/libcxx/include/thread b/libcxx/include/thread --- a/libcxx/include/thread +++ b/libcxx/include/thread @@ -84,6 +84,7 @@ #include <__config> #include <__debug> +#include <__decay_copy.h> #include <__functional_base> #include <__mutex_base> #include <__threading_support> diff --git a/libcxx/include/tuple b/libcxx/include/tuple --- a/libcxx/include/tuple +++ b/libcxx/include/tuple @@ -151,6 +151,7 @@ #include <__config> #include <__functional_base> +#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 @@ -417,6 +417,12 @@ */ #include <__config> +#include <__type_traits/integral_constant.h> +#include <__type_traits/is_same.h> +#include <__type_traits/references.h> +#include <__utility/declval.h> +#include <__utility/forward.h> +#include <__utility/move.h> // TODO: remove #include #include @@ -430,37 +436,6 @@ template class _LIBCPP_TEMPLATE_VIS reference_wrapper; template struct _LIBCPP_TEMPLATE_VIS hash; -template -struct _LIBCPP_TEMPLATE_VIS integral_constant -{ - static _LIBCPP_CONSTEXPR const _Tp value = __v; - typedef _Tp value_type; - typedef integral_constant type; - _LIBCPP_INLINE_VISIBILITY - _LIBCPP_CONSTEXPR operator value_type() const _NOEXCEPT {return value;} -#if _LIBCPP_STD_VER > 11 - _LIBCPP_INLINE_VISIBILITY - constexpr value_type operator ()() const _NOEXCEPT {return value;} -#endif -}; - -template -_LIBCPP_CONSTEXPR const _Tp integral_constant<_Tp, __v>::value; - -#if _LIBCPP_STD_VER > 14 -template -using bool_constant = integral_constant; -#define _LIBCPP_BOOL_CONSTANT(__b) bool_constant<(__b)> -#else -#define _LIBCPP_BOOL_CONSTANT(__b) integral_constant -#endif - -typedef _LIBCPP_BOOL_CONSTANT(true) true_type; -typedef _LIBCPP_BOOL_CONSTANT(false) false_type; - -template -using _BoolConstant _LIBCPP_NODEBUG_TYPE = integral_constant; - template struct _MetaBase; template <> struct _MetaBase { @@ -550,50 +525,6 @@ template using enable_if_t = typename enable_if<_Bp, _Tp>::type; #endif -// is_same - -#if __has_keyword(__is_same) - -template -struct _LIBCPP_TEMPLATE_VIS is_same : _BoolConstant<__is_same(_Tp, _Up)> { }; - -#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) -template -_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_same_v = __is_same(_Tp, _Up); -#endif - -#else - -template struct _LIBCPP_TEMPLATE_VIS is_same : public false_type {}; -template struct _LIBCPP_TEMPLATE_VIS is_same<_Tp, _Tp> : public true_type {}; - -#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) -template -_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_same_v - = is_same<_Tp, _Up>::value; -#endif - -#endif // __is_same - -template -using _IsSame = _BoolConstant< -#ifdef __clang__ - __is_same(_Tp, _Up) -#else - is_same<_Tp, _Up>::value -#endif ->; - -template -using _IsNotSame = _BoolConstant< -#ifdef __clang__ - !__is_same(_Tp, _Up) -#else - !is_same<_Tp, _Up>::value -#endif ->; - - template using __test_for_primary_template = _EnableIf< _IsSame<_Tp, typename _Tp::__primary_template>::value @@ -603,8 +534,6 @@ __test_for_primary_template, _Tp >; -struct __two {char __lx[2];}; - // helper class: // is_const @@ -900,60 +829,6 @@ #endif // __has_keyword(__is_pointer) -// is_reference - -#if __has_keyword(__is_lvalue_reference) && \ - __has_keyword(__is_rvalue_reference) && \ - __has_keyword(__is_reference) - -template -struct _LIBCPP_TEMPLATE_VIS is_lvalue_reference : _BoolConstant<__is_lvalue_reference(_Tp)> { }; - -template -struct _LIBCPP_TEMPLATE_VIS is_rvalue_reference : _BoolConstant<__is_rvalue_reference(_Tp)> { }; - -template -struct _LIBCPP_TEMPLATE_VIS is_reference : _BoolConstant<__is_reference(_Tp)> { }; - -#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) -template -_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_reference_v = __is_reference(_Tp); - -template -_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_lvalue_reference_v = __is_lvalue_reference(_Tp); - -template -_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_rvalue_reference_v = __is_rvalue_reference(_Tp); -#endif - -#else // __has_keyword(__is_lvalue_reference) && etc... - -template struct _LIBCPP_TEMPLATE_VIS is_lvalue_reference : public false_type {}; -template struct _LIBCPP_TEMPLATE_VIS is_lvalue_reference<_Tp&> : public true_type {}; - -template struct _LIBCPP_TEMPLATE_VIS is_rvalue_reference : public false_type {}; -template struct _LIBCPP_TEMPLATE_VIS is_rvalue_reference<_Tp&&> : public true_type {}; - -template struct _LIBCPP_TEMPLATE_VIS is_reference : public false_type {}; -template struct _LIBCPP_TEMPLATE_VIS is_reference<_Tp&> : public true_type {}; -template struct _LIBCPP_TEMPLATE_VIS is_reference<_Tp&&> : public true_type {}; - -#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) -template -_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_reference_v - = is_reference<_Tp>::value; - -template -_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_lvalue_reference_v - = is_lvalue_reference<_Tp>::value; - -template -_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_rvalue_reference_v - = is_rvalue_reference<_Tp>::value; -#endif - -#endif // __has_keyword(__is_lvalue_reference) && etc... - // is_union #if __has_feature(is_union) || defined(_LIBCPP_COMPILER_GCC) @@ -1281,18 +1156,6 @@ #endif // __has_keyword(__is_compound) -// __is_referenceable [defns.referenceable] - -struct __is_referenceable_impl { - template static _Tp& __test(int); - template static __two __test(...); -}; - -template -struct __is_referenceable : integral_constant(0)), __two>::value> {}; - - // add_const template struct _LIBCPP_TEMPLATE_VIS add_const { @@ -1322,58 +1185,6 @@ template using add_cv_t = typename add_cv<_Tp>::type; #endif -// remove_reference - -#if __has_keyword(__remove_reference) - -template -struct _LIBCPP_TEMPLATE_VIS remove_reference { typedef __remove_reference(_Tp) type; }; - -#else // __has_keyword(__remove_reference) - -template struct _LIBCPP_TEMPLATE_VIS remove_reference {typedef _LIBCPP_NODEBUG_TYPE _Tp type;}; -template struct _LIBCPP_TEMPLATE_VIS remove_reference<_Tp&> {typedef _LIBCPP_NODEBUG_TYPE _Tp type;}; -template struct _LIBCPP_TEMPLATE_VIS remove_reference<_Tp&&> {typedef _LIBCPP_NODEBUG_TYPE _Tp type;}; - -#if _LIBCPP_STD_VER > 11 -template using remove_reference_t = typename remove_reference<_Tp>::type; -#endif - -#endif // __has_keyword(__remove_reference) - -// add_lvalue_reference - -template ::value> struct __add_lvalue_reference_impl { typedef _LIBCPP_NODEBUG_TYPE _Tp type; }; -template struct __add_lvalue_reference_impl<_Tp, true> { typedef _LIBCPP_NODEBUG_TYPE _Tp& type; }; - -template struct _LIBCPP_TEMPLATE_VIS add_lvalue_reference -{typedef _LIBCPP_NODEBUG_TYPE typename __add_lvalue_reference_impl<_Tp>::type type;}; - -#if _LIBCPP_STD_VER > 11 -template using add_lvalue_reference_t = typename add_lvalue_reference<_Tp>::type; -#endif - -template ::value> struct __add_rvalue_reference_impl { typedef _LIBCPP_NODEBUG_TYPE _Tp type; }; -template struct __add_rvalue_reference_impl<_Tp, true> { typedef _LIBCPP_NODEBUG_TYPE _Tp&& type; }; - -template struct _LIBCPP_TEMPLATE_VIS add_rvalue_reference -{typedef _LIBCPP_NODEBUG_TYPE typename __add_rvalue_reference_impl<_Tp>::type type;}; - -#if _LIBCPP_STD_VER > 11 -template using add_rvalue_reference_t = typename add_rvalue_reference<_Tp>::type; -#endif - -// 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; - // __uncvref template @@ -2818,46 +2629,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 _VSTD::forward<_Tp>(__t); -} - template struct __member_pointer_traits_imp { @@ -4188,13 +3959,7 @@ 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); - +// __swappable template inline _LIBCPP_INLINE_VISIBILITY #ifndef _LIBCPP_CXX03_LANG @@ -4208,47 +3973,14 @@ #endif _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); -} + 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/utility b/libcxx/include/utility --- a/libcxx/include/utility +++ b/libcxx/include/utility @@ -210,6 +210,11 @@ #include <__config> #include <__debug> #include <__tuple> +#include <__utility/declval.h> +#include <__utility/forward.h> +#include <__utility/move_if_noexcept.h> +#include <__utility/move.h> +#include <__utility/swap.h> #include <__utility/to_underlying.h> #include #include @@ -266,29 +271,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/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_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,10 @@ // void // swap(T (&a)[N], T (&b)[N]); -#include +#include #include #include +#include #include "test_macros.h"