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 @@ -133,7 +135,23 @@ __threading_support __tree __tuple + __type_traits/__decay_copy.h + __type_traits/__is_swappable.h + __type_traits/__nat.h + __type_traits/cv.h + __type_traits/enable_if.h + __type_traits/integral_constant.h + __type_traits/is_assignable.h + __type_traits/is_constructible.h + __type_traits/is_same.h + __type_traits/is_void.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/__ranges/access.h b/libcxx/include/__ranges/access.h --- a/libcxx/include/__ranges/access.h +++ b/libcxx/include/__ranges/access.h @@ -12,6 +12,7 @@ #include <__config> #include <__iterator/concepts.h> #include <__ranges/enable_borrowed_range.h> +#include <__type_traits/__decay_copy.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,7 @@ #include <__iterator/concepts.h> #include <__iterator/iterator_traits.h> #include <__ranges/access.h> +#include <__type_traits/__decay_copy.h> #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git a/libcxx/include/__type_traits/__decay_copy.h b/libcxx/include/__type_traits/__decay_copy.h new file mode 100644 --- /dev/null +++ b/libcxx/include/__type_traits/__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/__type_traits/__is_swappable.h b/libcxx/include/__type_traits/__is_swappable.h new file mode 100644 --- /dev/null +++ b/libcxx/include/__type_traits/__is_swappable.h @@ -0,0 +1,101 @@ +// -*- 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_SWAPPABLE_H +#define _LIBCPP___TYPE_TRAITS___IS_SWAPPABLE_H + +#include <__config> +#include <__utility/declval.h> +#include <__type_traits/__nat.h> +#include <__type_traits/enable_if.h> +#include <__type_traits/is_assignable.h> +#include <__type_traits/is_constructible.h> +#include <__type_traits/is_same.h> +#include <__type_traits/is_void.h> +#include <__type_traits/integral_constant.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 + +#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 +struct __is_swappable; + +template +struct __is_nothrow_swappable; + +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 __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); + +namespace __detail { +// ALL generic swap overloads MUST already have a declaration available at this point. + +template ::value && !is_void<_Up>::value> +struct __swappable_with { + template + static decltype(swap(declval<_LHS>(), declval<_RHS>())) __test_swap(int); + template + static __nat __test_swap(long); + + // Extra parens are needed for the C++03 definition of decltype. + typedef decltype((__test_swap<_Tp, _Up>(0))) __swap1; + typedef decltype((__test_swap<_Up, _Tp>(0))) __swap2; + + static const bool value = _IsNotSame<__swap1, __nat>::value && _IsNotSame<__swap2, __nat>::value; +}; + +template +struct __swappable_with<_Tp, _Up, false> : false_type {}; + +template ::value> +struct __nothrow_swappable_with { + static const bool value = +#ifndef _LIBCPP_HAS_NO_NOEXCEPT + noexcept(swap(declval<_Tp>(), declval<_Up>())) && noexcept(swap(declval<_Up>(), declval<_Tp>())); +#else + false; +#endif +}; + +template +struct __nothrow_swappable_with<_Tp, _Up, false> : false_type {}; + +} // namespace __detail + +template +struct __is_swappable : public integral_constant::value> {}; + +template +struct __is_nothrow_swappable : public integral_constant::value> {}; + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___TYPE_TRAITS___IS_SWAPPABLE_H diff --git a/libcxx/include/__type_traits/__nat.h b/libcxx/include/__type_traits/__nat.h new file mode 100644 --- /dev/null +++ b/libcxx/include/__type_traits/__nat.h @@ -0,0 +1,37 @@ +// -*- 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___NAT_H +#define _LIBCPP___TYPE_TRAITS___NAT_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 + +struct __nat { +#ifndef _LIBCPP_CXX03_LANG + __nat() = delete; + __nat(const __nat&) = delete; + __nat& operator=(const __nat&) = delete; + ~__nat() = delete; +#endif +}; + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___TYPE_TRAITS___NAT_H diff --git a/libcxx/include/__type_traits/cv.h b/libcxx/include/__type_traits/cv.h new file mode 100644 --- /dev/null +++ b/libcxx/include/__type_traits/cv.h @@ -0,0 +1,238 @@ +// -*- 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_CV_H +#define _LIBCPP___TYPE_TRAITS_CV_H + +#include <__config> +#include <__type_traits/is_same.h> +#include <__type_traits/integral_constant.h> +#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 + +// is_const + +#if __has_keyword(__is_const) + +template +struct _LIBCPP_TEMPLATE_VIS is_const : _BoolConstant<__is_const(_Tp)> {}; + +#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) +template +_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_const_v = __is_const(_Tp); +#endif + +#else + +template +struct _LIBCPP_TEMPLATE_VIS is_const : public false_type {}; +template +struct _LIBCPP_TEMPLATE_VIS is_const<_Tp const> : public true_type {}; + +#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) +template +_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_const_v = is_const<_Tp>::value; +#endif + +#endif // __has_keyword(__is_const) + +// is_volatile + +#if __has_keyword(__is_volatile) + +template +struct _LIBCPP_TEMPLATE_VIS is_volatile : _BoolConstant<__is_volatile(_Tp)> {}; + +#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) +template +_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_volatile_v = __is_volatile(_Tp); +#endif + +#else + +template +struct _LIBCPP_TEMPLATE_VIS is_volatile : public false_type {}; +template +struct _LIBCPP_TEMPLATE_VIS is_volatile<_Tp volatile> : public true_type {}; + +#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) +template +_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_volatile_v = is_volatile<_Tp>::value; +#endif + +#endif // __has_keyword(__is_volatile) + +// remove_const + +#if __has_keyword(__remove_const) + +template +struct _LIBCPP_TEMPLATE_VIS remove_const { + typedef __remove_const(_Tp) type; +}; + +#if _LIBCPP_STD_VER > 11 +template +using remove_const_t = __remove_const(_Tp); +#endif + +#else + +template +struct _LIBCPP_TEMPLATE_VIS remove_const { + typedef _Tp type; +}; +template +struct _LIBCPP_TEMPLATE_VIS remove_const { + typedef _Tp type; +}; +#if _LIBCPP_STD_VER > 11 +template +using remove_const_t = typename remove_const<_Tp>::type; +#endif + +#endif // __has_keyword(__remove_const) + +// remove_volatile + +#if __has_keyword(__remove_volatile) + +template +struct _LIBCPP_TEMPLATE_VIS remove_volatile { + typedef __remove_volatile(_Tp) type; +}; + +#if _LIBCPP_STD_VER > 11 +template +using remove_volatile_t = __remove_volatile(_Tp); +#endif + +#else + +template +struct _LIBCPP_TEMPLATE_VIS remove_volatile { + typedef _Tp type; +}; +template +struct _LIBCPP_TEMPLATE_VIS remove_volatile { + typedef _Tp type; +}; +#if _LIBCPP_STD_VER > 11 +template +using remove_volatile_t = typename remove_volatile<_Tp>::type; +#endif + +#endif // __has_keyword(__remove_volatile) + +// remove_cv + +#if __has_keyword(__remove_cv) + +template +struct _LIBCPP_TEMPLATE_VIS remove_cv { + typedef __remove_cv(_Tp) type; +}; + +#if _LIBCPP_STD_VER > 11 +template +using remove_cv_t = __remove_cv(_Tp); +#endif + +#else + +template +struct _LIBCPP_TEMPLATE_VIS remove_cv { + typedef typename remove_volatile::type>::type type; +}; +#if _LIBCPP_STD_VER > 11 +template +using remove_cv_t = typename remove_cv<_Tp>::type; +#endif + +#endif // __has_keyword(__remove_cv) + +// add_const + +template +struct _LIBCPP_TEMPLATE_VIS add_const { + typedef _LIBCPP_NODEBUG_TYPE const _Tp type; +}; + +#if _LIBCPP_STD_VER > 11 +template +using add_const_t = typename add_const<_Tp>::type; +#endif + +// add_volatile + +template +struct _LIBCPP_TEMPLATE_VIS add_volatile { + typedef _LIBCPP_NODEBUG_TYPE volatile _Tp type; +}; + +#if _LIBCPP_STD_VER > 11 +template +using add_volatile_t = typename add_volatile<_Tp>::type; +#endif + +// add_cv +template +struct _LIBCPP_TEMPLATE_VIS add_cv { + typedef _LIBCPP_NODEBUG_TYPE const volatile _Tp type; +}; + +#if _LIBCPP_STD_VER > 11 +template +using add_cv_t = typename add_cv<_Tp>::type; +#endif + +// __uncvref + +template +struct __uncvref { + typedef _LIBCPP_NODEBUG_TYPE typename remove_cv::type>::type type; +}; + +template +struct __unconstref { + typedef _LIBCPP_NODEBUG_TYPE typename remove_const::type>::type type; +}; + +#ifndef _LIBCPP_CXX03_LANG +template +using __uncvref_t _LIBCPP_NODEBUG_TYPE = typename __uncvref<_Tp>::type; +#endif + +// __is_same_uncvref + +template +struct __is_same_uncvref : _IsSame::type, typename __uncvref<_Up>::type> {}; + +#if _LIBCPP_STD_VER > 17 +// remove_cvref - same as __uncvref +template +struct remove_cvref : public __uncvref<_Tp> {}; + +template +using remove_cvref_t = typename remove_cvref<_Tp>::type; +#endif + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___TYPE_TRAITS_CV_H diff --git a/libcxx/include/__type_traits/enable_if.h b/libcxx/include/__type_traits/enable_if.h new file mode 100644 --- /dev/null +++ b/libcxx/include/__type_traits/enable_if.h @@ -0,0 +1,41 @@ +// -*- 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_ENABLE_IF_H +#define _LIBCPP___TYPE_TRAITS_ENABLE_IF_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 enable_if {}; + +template +struct _LIBCPP_TEMPLATE_VIS enable_if { + typedef _Tp type; +}; + +#if _LIBCPP_STD_VER > 11 +template +using enable_if_t = typename enable_if<_Bp, _Tp>::type; +#endif + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___TYPE_TRAITS_ENABLE_IF_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_assignable.h b/libcxx/include/__type_traits/is_assignable.h new file mode 100644 --- /dev/null +++ b/libcxx/include/__type_traits/is_assignable.h @@ -0,0 +1,203 @@ +// -*- 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_ASSIGNABLE_H +#define _LIBCPP___TYPE_TRAITS_IS_ASSIGNABLE_H + +#include <__config> +#include <__type_traits/cv.h> +#include <__type_traits/integral_constant.h> +#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 + +// is_assignable + +template +struct __select_2nd { + typedef _LIBCPP_NODEBUG_TYPE _Tp type; +}; + +#if __has_keyword(__is_assignable) + +template +struct _LIBCPP_TEMPLATE_VIS is_assignable : _BoolConstant<__is_assignable(_Tp, _Up)> {}; + +#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) +template +_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_assignable_v = __is_assignable(_Tp, _Arg); +#endif + +#else // __has_keyword(__is_assignable) + +template +typename __select_2nd() = declval<_Arg>())), true_type>::type __is_assignable_test(int); + +template +false_type __is_assignable_test(...); + +template ::value || is_void<_Arg>::value> +struct __is_assignable_imp : public decltype((_VSTD::__is_assignable_test<_Tp, _Arg>(0))) {}; + +template +struct __is_assignable_imp<_Tp, _Arg, true> : public false_type {}; + +template +struct is_assignable : public __is_assignable_imp<_Tp, _Arg> {}; + +#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) +template +_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_assignable_v = is_assignable<_Tp, _Arg>::value; +#endif + +#endif // __has_keyword(__is_assignable) + +// is_copy_assignable + +template +struct _LIBCPP_TEMPLATE_VIS is_copy_assignable + : public is_assignable::type, + typename add_lvalue_reference::type>::type> {}; + +#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) +template +_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_copy_assignable_v = is_copy_assignable<_Tp>::value; +#endif + +template +struct _LIBCPP_TEMPLATE_VIS is_move_assignable + : public is_assignable::type, typename add_rvalue_reference<_Tp>::type> {}; + +#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) +template +_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_move_assignable_v = is_move_assignable<_Tp>::value; +#endif + +// is_trivially_assignable + +#if __has_feature(is_trivially_assignable) || _GNUC_VER >= 501 + +template +struct is_trivially_assignable : integral_constant {}; + +#else // !__has_feature(is_trivially_assignable) + +template +struct is_trivially_assignable : public false_type {}; + +template +struct is_trivially_assignable<_Tp&, _Tp> : integral_constant::value> {}; + +template +struct is_trivially_assignable<_Tp&, _Tp&> : integral_constant::value> {}; + +template +struct is_trivially_assignable<_Tp&, const _Tp&> : integral_constant::value> {}; + +template +struct is_trivially_assignable<_Tp&, _Tp&&> : integral_constant::value> {}; + +#endif // !__has_feature(is_trivially_assignable) + +#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) +template +_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_trivially_assignable_v = is_trivially_assignable<_Tp, _Arg>::value; +#endif + +// is_trivially_copy_assignable + +template +struct _LIBCPP_TEMPLATE_VIS is_trivially_copy_assignable + : public is_trivially_assignable::type, + typename add_lvalue_reference::type>::type> {}; + +#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) +template +_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_trivially_copy_assignable_v = is_trivially_copy_assignable<_Tp>::value; +#endif + +// is_trivially_move_assignable + +template +struct _LIBCPP_TEMPLATE_VIS is_trivially_move_assignable + : public is_trivially_assignable::type, + typename add_rvalue_reference<_Tp>::type> {}; + +#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) +template +_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_trivially_move_assignable_v = is_trivially_move_assignable<_Tp>::value; +#endif + +// is_nothrow_assignable + +#if __has_keyword(__is_nothrow_assignable) + +template +struct _LIBCPP_TEMPLATE_VIS is_nothrow_assignable : public integral_constant { +}; + +#else + +template +struct __libcpp_is_nothrow_assignable; + +template +struct __libcpp_is_nothrow_assignable : public false_type {}; + +template +struct __libcpp_is_nothrow_assignable + : public integral_constant() = declval<_Arg>())> {}; + +template +struct _LIBCPP_TEMPLATE_VIS is_nothrow_assignable + : public __libcpp_is_nothrow_assignable::value, _Tp, _Arg> {}; + +#endif // _LIBCPP_HAS_NO_NOEXCEPT + +#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) +template +_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_nothrow_assignable_v = is_nothrow_assignable<_Tp, _Arg>::value; +#endif + +// is_nothrow_copy_assignable + +template +struct _LIBCPP_TEMPLATE_VIS is_nothrow_copy_assignable + : public is_nothrow_assignable::type, + typename add_lvalue_reference::type>::type> {}; + +#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) +template +_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_nothrow_copy_assignable_v = is_nothrow_copy_assignable<_Tp>::value; +#endif + +// is_nothrow_move_assignable + +template +struct _LIBCPP_TEMPLATE_VIS is_nothrow_move_assignable + : public is_nothrow_assignable::type, typename add_rvalue_reference<_Tp>::type> { +}; + +#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) +template +_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_nothrow_move_assignable_v = is_nothrow_move_assignable<_Tp>::value; +#endif + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___TYPE_TRAITS_IS_ASSIGNABLE_H diff --git a/libcxx/include/__type_traits/is_constructible.h b/libcxx/include/__type_traits/is_constructible.h new file mode 100644 --- /dev/null +++ b/libcxx/include/__type_traits/is_constructible.h @@ -0,0 +1,347 @@ +// -*- 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_CONSTRUCTIBLE_H +#define _LIBCPP___TYPE_TRAITS_IS_CONSTRUCTIBLE_H + +#include <__config> +#include <__type_traits/cv.h> +#include <__type_traits/integral_constant.h> +#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 struct is_constructible; + +#if defined(_LIBCPP_COMPILER_GCC) && _GNUC_VER_NEW >= 10000 +#define _LIBCPP_GCC_SUPPORTS_IS_CONSTRUCTIBLE +#endif + +#if !defined(_LIBCPP_CXX03_LANG) && !__has_feature(is_constructible) && !defined(_LIBCPP_GCC_SUPPORTS_IS_CONSTRUCTIBLE) + +template +struct __libcpp_is_constructible; + +template +struct __is_invalid_base_to_derived_cast { + static_assert(is_reference<_To>::value, "Wrong specialization"); + using _RawFrom = __uncvref_t<_From>; + using _RawTo = __uncvref_t<_To>; + static const bool value = _And<_IsNotSame<_RawFrom, _RawTo>, is_base_of<_RawFrom, _RawTo>, + _Not<__libcpp_is_constructible<_RawTo, _From> > >::value; +}; + +template +struct __is_invalid_lvalue_to_rvalue_cast : false_type { + static_assert(is_reference<_To>::value, "Wrong specialization"); +}; + +template +struct __is_invalid_lvalue_to_rvalue_cast<_ToRef&&, _FromRef&> { + using _RawFrom = __uncvref_t<_FromRef>; + using _RawTo = __uncvref_t<_ToRef>; + static const bool value = + _And<_Not >, _Or<_IsSame<_RawFrom, _RawTo>, is_base_of<_RawTo, _RawFrom> > >::value; +}; + +struct __is_constructible_helper { + template + static void __eat(_To); + + // This overload is needed to work around a Clang bug that disallows + // static_cast(e) for non-reference-compatible types. + // Example: static_cast(declval()); + // NOTE: The static_cast implementation below is required to support + // classes with explicit conversion operators. + template (declval<_From>()))> + static true_type __test_cast(int); + + template (declval<_From>()))> + static integral_constant::value && + !__is_invalid_lvalue_to_rvalue_cast<_To, _From>::value> + __test_cast(long); + + template + static false_type __test_cast(...); + + template ()...))> + static true_type __test_nary(int); + template + static false_type __test_nary(...); + + template ()))> + static is_destructible<_Tp> __test_unary(int); + template + static false_type __test_unary(...); +}; + +template ::value> +struct __is_default_constructible : decltype(__is_constructible_helper::__test_nary<_Tp>(0)) {}; + +template +struct __is_default_constructible<_Tp, true> : false_type {}; + +template +struct __is_default_constructible<_Tp[], false> : false_type {}; + +template +struct __is_default_constructible<_Tp[_Nx], false> + : __is_default_constructible::type> {}; + +template +struct __libcpp_is_constructible { + static_assert(sizeof...(_Args) > 1, "Wrong specialization"); + typedef decltype(__is_constructible_helper::__test_nary<_Tp, _Args...>(0)) type; +}; + +template +struct __libcpp_is_constructible<_Tp> : __is_default_constructible<_Tp> {}; + +template +struct __libcpp_is_constructible<_Tp, _A0> : public decltype(__is_constructible_helper::__test_unary<_Tp, _A0>(0)) {}; + +template +struct __libcpp_is_constructible<_Tp&, _A0> : public decltype(__is_constructible_helper::__test_cast<_Tp&, _A0>(0)) {}; + +template +struct __libcpp_is_constructible<_Tp&&, _A0> : public decltype(__is_constructible_helper::__test_cast<_Tp&&, _A0>(0)) { +}; + +#endif + +#if __has_feature(is_constructible) || defined(_LIBCPP_GCC_SUPPORTS_IS_CONSTRUCTIBLE) +template +struct _LIBCPP_TEMPLATE_VIS is_constructible : public integral_constant {}; +#else +template +struct _LIBCPP_TEMPLATE_VIS is_constructible : public __libcpp_is_constructible<_Tp, _Args...>::type {}; +#endif + +#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) +template +_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_constructible_v = is_constructible<_Tp, _Args...>::value; +#endif + +// is_default_constructible + +template +struct _LIBCPP_TEMPLATE_VIS is_default_constructible : public is_constructible<_Tp> {}; + +#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) +template +_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_default_constructible_v = is_default_constructible<_Tp>::value; +#endif + +#ifndef _LIBCPP_CXX03_LANG +// First of all, we can't implement this check in C++03 mode because the {} +// default initialization syntax isn't valid. +// Second, we implement the trait in a funny manner with two defaulted template +// arguments to workaround Clang's PR43454. +template +void __test_implicit_default_constructible(_Tp); + +template ::type> +struct __is_implicitly_default_constructible : false_type {}; + +template +struct __is_implicitly_default_constructible<_Tp, decltype(__test_implicit_default_constructible<_Tp const&>({})), + true_type> : true_type {}; + +template +struct __is_implicitly_default_constructible<_Tp, decltype(__test_implicit_default_constructible<_Tp const&>({})), + false_type> : false_type {}; +#endif // !C++03 + +// is_copy_constructible + +template +struct _LIBCPP_TEMPLATE_VIS is_copy_constructible + : public is_constructible<_Tp, typename add_lvalue_reference::type>::type> {}; + +#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) +template +_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_copy_constructible_v = is_copy_constructible<_Tp>::value; +#endif + +// is_move_constructible + +template +struct _LIBCPP_TEMPLATE_VIS is_move_constructible + : public is_constructible<_Tp, typename add_rvalue_reference<_Tp>::type> {}; + +#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) +template +_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_move_constructible_v = is_move_constructible<_Tp>::value; +#endif + +// is_trivially_constructible + +#if __has_feature(is_trivially_constructible) || _GNUC_VER >= 501 + +template +struct _LIBCPP_TEMPLATE_VIS is_trivially_constructible + : integral_constant {}; + +#else // !__has_feature(is_trivially_constructible) + +template +struct _LIBCPP_TEMPLATE_VIS is_trivially_constructible : false_type {}; + +template +struct _LIBCPP_TEMPLATE_VIS is_trivially_constructible<_Tp> +#if __has_feature(has_trivial_constructor) || defined(_LIBCPP_COMPILER_GCC) + : integral_constant +#else + : integral_constant::value> +#endif +{ +}; + +template +struct _LIBCPP_TEMPLATE_VIS is_trivially_constructible<_Tp, _Tp&&> : integral_constant::value> {}; + +template +struct _LIBCPP_TEMPLATE_VIS is_trivially_constructible<_Tp, const _Tp&> + : integral_constant::value> {}; + +template +struct _LIBCPP_TEMPLATE_VIS is_trivially_constructible<_Tp, _Tp&> : integral_constant::value> {}; + +#endif // !__has_feature(is_trivially_constructible) + +#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) +template +_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_trivially_constructible_v = + is_trivially_constructible<_Tp, _Args...>::value; +#endif + +// is_trivially_default_constructible + +template +struct _LIBCPP_TEMPLATE_VIS is_trivially_default_constructible : public is_trivially_constructible<_Tp> {}; + +#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) +template +_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_trivially_default_constructible_v = + is_trivially_default_constructible<_Tp>::value; +#endif + +// is_trivially_copy_constructible + +template +struct _LIBCPP_TEMPLATE_VIS is_trivially_copy_constructible + : public is_trivially_constructible<_Tp, typename add_lvalue_reference::type> {}; + +#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) +template +_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_trivially_copy_constructible_v = + is_trivially_copy_constructible<_Tp>::value; +#endif + +// is_trivially_move_constructible + +template +struct _LIBCPP_TEMPLATE_VIS is_trivially_move_constructible + : public is_trivially_constructible<_Tp, typename add_rvalue_reference<_Tp>::type> {}; + +#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) +template +_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_trivially_move_constructible_v = + is_trivially_move_constructible<_Tp>::value; +#endif + +// is_nothrow_constructible + +#if __has_keyword(__is_nothrow_constructible) + +template +struct _LIBCPP_TEMPLATE_VIS is_nothrow_constructible + : public integral_constant {}; + +#else + +template +struct __libcpp_is_nothrow_constructible; + +template +struct __libcpp_is_nothrow_constructible + : public integral_constant()...))> {}; + +template +void __implicit_conversion_to(_Tp) noexcept {} + +template +struct __libcpp_is_nothrow_constructible + : public integral_constant(declval<_Arg>()))> {}; + +template +struct __libcpp_is_nothrow_constructible : public false_type { +}; + +template +struct _LIBCPP_TEMPLATE_VIS is_nothrow_constructible + : __libcpp_is_nothrow_constructible::value, is_reference<_Tp>::value, _Tp, + _Args...> {}; + +template +struct _LIBCPP_TEMPLATE_VIS is_nothrow_constructible<_Tp[_Ns]> + : __libcpp_is_nothrow_constructible::value, is_reference<_Tp>::value, _Tp> {}; + +#endif // _LIBCPP_HAS_NO_NOEXCEPT + +#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) +template +_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_nothrow_constructible_v = is_nothrow_constructible<_Tp, _Args...>::value; +#endif + +// is_nothrow_default_constructible + +template +struct _LIBCPP_TEMPLATE_VIS is_nothrow_default_constructible : public is_nothrow_constructible<_Tp> {}; + +#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) +template +_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_nothrow_default_constructible_v = + is_nothrow_default_constructible<_Tp>::value; +#endif + +// is_nothrow_copy_constructible + +template +struct _LIBCPP_TEMPLATE_VIS is_nothrow_copy_constructible + : public is_nothrow_constructible<_Tp, typename add_lvalue_reference::type>::type> {}; + +#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) +template +_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_nothrow_copy_constructible_v = is_nothrow_copy_constructible<_Tp>::value; +#endif + +// is_nothrow_move_constructible + +template +struct _LIBCPP_TEMPLATE_VIS is_nothrow_move_constructible + : public is_nothrow_constructible<_Tp, typename add_rvalue_reference<_Tp>::type> {}; + +#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) +template +_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_nothrow_move_constructible_v = is_nothrow_move_constructible<_Tp>::value; +#endif + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___TYPE_TRAITS_IS_CONSTRUCTIBLE_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/is_void.h b/libcxx/include/__type_traits/is_void.h new file mode 100644 --- /dev/null +++ b/libcxx/include/__type_traits/is_void.h @@ -0,0 +1,53 @@ +// -*- 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_VOID_H +#define _LIBCPP___TYPE_TRAITS_IS_VOID_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_void + +#if __has_keyword(__is_void) + +template +struct _LIBCPP_TEMPLATE_VIS is_void : _BoolConstant<__is_void(_Tp)> {}; + +#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) +template +_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_void_v = __is_void(_Tp); +#endif + +#else + +template +struct _LIBCPP_TEMPLATE_VIS is_void : public is_same::type, void> {}; + +#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) +template +_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_void_v = is_void<_Tp>::value; +#endif + +#endif // __has_keyword(__is_void) + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___TYPE_TRAITS_IS_VOID_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,63 @@ +//===----------------------------------------------------------------------===// +// +// 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 <__type_traits/__is_swappable.h> +#include <__type_traits/enable_if.h> +#include <__type_traits/integral_constant.h> +#include <__type_traits/is_constructible.h> +#include <__type_traits/is_assignable.h> +#include <__type_traits/is_same.h> +#include <__type_traits/is_void.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); + +#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 @@ -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 <__type_traits/__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,20 @@ module type_traits { header "type_traits" export * + + module __type_traits { + module __decay_copy { header "__type_traits/__decay_copy.h" } + module __is_swappable { header "__type_traits/__is_swappable.h" } + module __nat { header "__type_traits/__nat.h" } + module cv { header "__type_traits/cv.h" } + module enable_if { header "__type_traits/enable_if.h" } + module integral_constant { header "__type_traits/integral_constant.h" } + module is_assignable { header "__type_traits/is_assignable.h" } + module is_constructible { header "__type_traits/is_constructible.h" } + module is_same { header "__type_traits/is_same.h" } + module is_void { header "__type_traits/is_void.h" } + module references { header "__type_traits/references.h" } + } } module typeindex { header "typeindex" @@ -644,9 +658,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 { diff --git a/libcxx/include/thread b/libcxx/include/thread --- a/libcxx/include/thread +++ b/libcxx/include/thread @@ -87,6 +87,7 @@ #include <__functional_base> #include <__mutex_base> #include <__threading_support> +#include <__type_traits/__decay_copy.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,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,19 @@ */ #include <__config> +#include <__type_traits/__nat.h> +#include <__type_traits/cv.h> +#include <__type_traits/enable_if.h> +#include <__type_traits/integral_constant.h> +#include <__type_traits/is_assignable.h> +#include <__type_traits/is_constructible.h> +#include <__type_traits/is_same.h> +#include <__type_traits/is_void.h> +#include <__type_traits/references.h> +#include <__utility/declval.h> +#include <__utility/forward.h> +#include <__utility/move.h> // TODO: remove unused header +#include <__utility/swap.h> // TODO: remove unused header #include #include @@ -430,37 +443,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 { @@ -543,57 +525,6 @@ template using conditional_t = typename conditional<_Bp, _If, _Then>::type; #endif -template struct _LIBCPP_TEMPLATE_VIS enable_if {}; -template struct _LIBCPP_TEMPLATE_VIS enable_if {typedef _Tp type;}; - -#if _LIBCPP_STD_VER > 11 -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,148 +534,6 @@ __test_for_primary_template, _Tp >; -struct __two {char __lx[2];}; - -// helper class: - -// is_const - -#if __has_keyword(__is_const) - -template -struct _LIBCPP_TEMPLATE_VIS is_const : _BoolConstant<__is_const(_Tp)> { }; - -#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) -template -_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_const_v = __is_const(_Tp); -#endif - -#else - -template struct _LIBCPP_TEMPLATE_VIS is_const : public false_type {}; -template struct _LIBCPP_TEMPLATE_VIS is_const<_Tp const> : public true_type {}; - -#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) -template -_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_const_v - = is_const<_Tp>::value; -#endif - -#endif // __has_keyword(__is_const) - -// is_volatile - -#if __has_keyword(__is_volatile) - -template -struct _LIBCPP_TEMPLATE_VIS is_volatile : _BoolConstant<__is_volatile(_Tp)> { }; - -#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) -template -_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_volatile_v = __is_volatile(_Tp); -#endif - -#else - -template struct _LIBCPP_TEMPLATE_VIS is_volatile : public false_type {}; -template struct _LIBCPP_TEMPLATE_VIS is_volatile<_Tp volatile> : public true_type {}; - -#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) -template -_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_volatile_v - = is_volatile<_Tp>::value; -#endif - -#endif // __has_keyword(__is_volatile) - -// remove_const - -#if __has_keyword(__remove_const) - -template -struct _LIBCPP_TEMPLATE_VIS remove_const {typedef __remove_const(_Tp) type;}; - -#if _LIBCPP_STD_VER > 11 -template using remove_const_t = __remove_const(_Tp); -#endif - -#else - -template struct _LIBCPP_TEMPLATE_VIS remove_const {typedef _Tp type;}; -template struct _LIBCPP_TEMPLATE_VIS remove_const {typedef _Tp type;}; -#if _LIBCPP_STD_VER > 11 -template using remove_const_t = typename remove_const<_Tp>::type; -#endif - -#endif // __has_keyword(__remove_const) - -// remove_volatile - -#if __has_keyword(__remove_volatile) - -template -struct _LIBCPP_TEMPLATE_VIS remove_volatile {typedef __remove_volatile(_Tp) type;}; - -#if _LIBCPP_STD_VER > 11 -template using remove_volatile_t = __remove_volatile(_Tp); -#endif - -#else - -template struct _LIBCPP_TEMPLATE_VIS remove_volatile {typedef _Tp type;}; -template struct _LIBCPP_TEMPLATE_VIS remove_volatile {typedef _Tp type;}; -#if _LIBCPP_STD_VER > 11 -template using remove_volatile_t = typename remove_volatile<_Tp>::type; -#endif - -#endif // __has_keyword(__remove_volatile) - -// remove_cv - -#if __has_keyword(__remove_cv) - -template -struct _LIBCPP_TEMPLATE_VIS remove_cv {typedef __remove_cv(_Tp) type;}; - -#if _LIBCPP_STD_VER > 11 -template using remove_cv_t = __remove_cv(_Tp); -#endif - -#else - -template struct _LIBCPP_TEMPLATE_VIS remove_cv -{typedef typename remove_volatile::type>::type type;}; -#if _LIBCPP_STD_VER > 11 -template using remove_cv_t = typename remove_cv<_Tp>::type; -#endif - -#endif // __has_keyword(__remove_cv) - -// is_void - -#if __has_keyword(__is_void) - -template -struct _LIBCPP_TEMPLATE_VIS is_void : _BoolConstant<__is_void(_Tp)> { }; - -#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) -template -_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_void_v = __is_void(_Tp); -#endif - -#else - -template struct _LIBCPP_TEMPLATE_VIS is_void - : public is_same::type, void> {}; - -#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) -template -_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_void_v - = is_void<_Tp>::value; -#endif - -#endif // __has_keyword(__is_void) - // __is_nullptr_t template struct __is_nullptr_t_impl : public false_type {}; @@ -900,60 +689,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,131 +1016,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 { - typedef _LIBCPP_NODEBUG_TYPE const _Tp type; -}; - -#if _LIBCPP_STD_VER > 11 -template using add_const_t = typename add_const<_Tp>::type; -#endif - -// add_volatile - -template struct _LIBCPP_TEMPLATE_VIS add_volatile { - typedef _LIBCPP_NODEBUG_TYPE volatile _Tp type; -}; - -#if _LIBCPP_STD_VER > 11 -template using add_volatile_t = typename add_volatile<_Tp>::type; -#endif - -// add_cv -template struct _LIBCPP_TEMPLATE_VIS add_cv { - typedef _LIBCPP_NODEBUG_TYPE const volatile _Tp type; -}; - -#if _LIBCPP_STD_VER > 11 -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 -struct __uncvref { - typedef _LIBCPP_NODEBUG_TYPE typename remove_cv::type>::type type; -}; - -template -struct __unconstref { - typedef _LIBCPP_NODEBUG_TYPE typename remove_const::type>::type type; -}; - -#ifndef _LIBCPP_CXX03_LANG -template -using __uncvref_t _LIBCPP_NODEBUG_TYPE = typename __uncvref<_Tp>::type; -#endif - -// __is_same_uncvref - -template -struct __is_same_uncvref : _IsSame::type, - typename __uncvref<_Up>::type> {}; - -#if _LIBCPP_STD_VER > 17 -// remove_cvref - same as __uncvref -template -struct remove_cvref : public __uncvref<_Tp> {}; - -template using remove_cvref_t = typename remove_cvref<_Tp>::type; -#endif - - struct __any { __any(...); @@ -1948,16 +1558,6 @@ typedef _Tp _Tail; }; -struct __nat -{ -#ifndef _LIBCPP_CXX03_LANG - __nat() = delete; - __nat(const __nat&) = delete; - __nat& operator=(const __nat&) = delete; - ~__nat() = delete; -#endif -}; - template struct __align_type { @@ -2670,106 +2270,36 @@ #endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS) -// is_assignable - -template struct __select_2nd { typedef _LIBCPP_NODEBUG_TYPE _Tp type; }; +// is_destructible -#if __has_keyword(__is_assignable) +#if __has_keyword(__is_destructible) -template -struct _LIBCPP_TEMPLATE_VIS is_assignable : _BoolConstant<__is_assignable(_Tp, _Up)> { }; +template +struct _LIBCPP_TEMPLATE_VIS is_destructible : _BoolConstant<__is_destructible(_Tp)> { }; #if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) -template -_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_assignable_v = __is_assignable(_Tp, _Arg); +template +_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_destructible_v = __is_destructible(_Tp); #endif -#else // __has_keyword(__is_assignable) - -template -typename __select_2nd() = declval<_Arg>())), true_type>::type -__is_assignable_test(int); +#else // __has_keyword(__is_destructible) -template -false_type __is_assignable_test(...); +// if it's a reference, return true +// if it's a function, return false +// if it's void, return false +// if it's an array of unknown bound, return false +// Otherwise, return "declval<_Up&>().~_Up()" is well-formed +// where _Up is remove_all_extents<_Tp>::type +template +struct __is_destructible_apply { typedef int type; }; -template ::value || is_void<_Arg>::value> -struct __is_assignable_imp - : public decltype((_VSTD::__is_assignable_test<_Tp, _Arg>(0))) {}; - -template -struct __is_assignable_imp<_Tp, _Arg, true> - : public false_type -{ -}; - -template -struct is_assignable - : public __is_assignable_imp<_Tp, _Arg> {}; - -#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) -template -_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_assignable_v - = is_assignable<_Tp, _Arg>::value; -#endif - -#endif // __has_keyword(__is_assignable) - -// is_copy_assignable - -template struct _LIBCPP_TEMPLATE_VIS is_copy_assignable - : public is_assignable::type, - typename add_lvalue_reference::type>::type> {}; - -#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) -template -_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_copy_assignable_v - = is_copy_assignable<_Tp>::value; -#endif - -// is_move_assignable - -template struct _LIBCPP_TEMPLATE_VIS is_move_assignable - : public is_assignable::type, - typename add_rvalue_reference<_Tp>::type> {}; - -#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) -template -_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_move_assignable_v - = is_move_assignable<_Tp>::value; -#endif - -// is_destructible - -#if __has_keyword(__is_destructible) - -template -struct _LIBCPP_TEMPLATE_VIS is_destructible : _BoolConstant<__is_destructible(_Tp)> { }; - -#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) -template -_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_destructible_v = __is_destructible(_Tp); -#endif - -#else // __has_keyword(__is_destructible) - -// if it's a reference, return true -// if it's a function, return false -// if it's void, return false -// if it's an array of unknown bound, return false -// Otherwise, return "declval<_Up&>().~_Up()" is well-formed -// where _Up is remove_all_extents<_Tp>::type - -template -struct __is_destructible_apply { typedef int type; }; - -template -struct __is_destructor_wellformed { - template - static char __test ( - typename __is_destructible_apply().~_Tp1())>::type - ); +template +struct __is_destructor_wellformed { + template + static char __test ( + typename __is_destructible_apply().~_Tp1())>::type + ); template static __two __test (...); @@ -2818,46 +2348,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 { @@ -3087,363 +2577,6 @@ typedef _ClassType type; }; -// template struct is_constructible; - -#if defined(_LIBCPP_COMPILER_GCC) && _GNUC_VER_NEW >= 10000 -# define _LIBCPP_GCC_SUPPORTS_IS_CONSTRUCTIBLE -#endif - -#if !defined(_LIBCPP_CXX03_LANG) && !__has_feature(is_constructible) && !defined(_LIBCPP_GCC_SUPPORTS_IS_CONSTRUCTIBLE) - -template -struct __libcpp_is_constructible; - -template -struct __is_invalid_base_to_derived_cast { - static_assert(is_reference<_To>::value, "Wrong specialization"); - using _RawFrom = __uncvref_t<_From>; - using _RawTo = __uncvref_t<_To>; - static const bool value = _And< - _IsNotSame<_RawFrom, _RawTo>, - is_base_of<_RawFrom, _RawTo>, - _Not<__libcpp_is_constructible<_RawTo, _From>> - >::value; -}; - -template -struct __is_invalid_lvalue_to_rvalue_cast : false_type { - static_assert(is_reference<_To>::value, "Wrong specialization"); -}; - -template -struct __is_invalid_lvalue_to_rvalue_cast<_ToRef&&, _FromRef&> { - using _RawFrom = __uncvref_t<_FromRef>; - using _RawTo = __uncvref_t<_ToRef>; - static const bool value = _And< - _Not>, - _Or< - _IsSame<_RawFrom, _RawTo>, - is_base_of<_RawTo, _RawFrom>> - >::value; -}; - -struct __is_constructible_helper -{ - template - static void __eat(_To); - - // This overload is needed to work around a Clang bug that disallows - // static_cast(e) for non-reference-compatible types. - // Example: static_cast(declval()); - // NOTE: The static_cast implementation below is required to support - // classes with explicit conversion operators. - template (declval<_From>()))> - static true_type __test_cast(int); - - template (declval<_From>()))> - static integral_constant::value && - !__is_invalid_lvalue_to_rvalue_cast<_To, _From>::value - > __test_cast(long); - - template - static false_type __test_cast(...); - - template ()...))> - static true_type __test_nary(int); - template - static false_type __test_nary(...); - - template ()))> - static is_destructible<_Tp> __test_unary(int); - template - static false_type __test_unary(...); -}; - -template ::value> -struct __is_default_constructible - : decltype(__is_constructible_helper::__test_nary<_Tp>(0)) -{}; - -template -struct __is_default_constructible<_Tp, true> : false_type {}; - -template -struct __is_default_constructible<_Tp[], false> : false_type {}; - -template -struct __is_default_constructible<_Tp[_Nx], false> - : __is_default_constructible::type> {}; - -template -struct __libcpp_is_constructible -{ - static_assert(sizeof...(_Args) > 1, "Wrong specialization"); - typedef decltype(__is_constructible_helper::__test_nary<_Tp, _Args...>(0)) - type; -}; - -template -struct __libcpp_is_constructible<_Tp> : __is_default_constructible<_Tp> {}; - -template -struct __libcpp_is_constructible<_Tp, _A0> - : public decltype(__is_constructible_helper::__test_unary<_Tp, _A0>(0)) -{}; - -template -struct __libcpp_is_constructible<_Tp&, _A0> - : public decltype(__is_constructible_helper:: - __test_cast<_Tp&, _A0>(0)) -{}; - -template -struct __libcpp_is_constructible<_Tp&&, _A0> - : public decltype(__is_constructible_helper:: - __test_cast<_Tp&&, _A0>(0)) -{}; - -#endif - -#if __has_feature(is_constructible) || defined(_LIBCPP_GCC_SUPPORTS_IS_CONSTRUCTIBLE) -template -struct _LIBCPP_TEMPLATE_VIS is_constructible - : public integral_constant - {}; -#else -template -struct _LIBCPP_TEMPLATE_VIS is_constructible - : public __libcpp_is_constructible<_Tp, _Args...>::type {}; -#endif - -#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) -template -_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_constructible_v - = is_constructible<_Tp, _Args...>::value; -#endif - -// is_default_constructible - -template -struct _LIBCPP_TEMPLATE_VIS is_default_constructible - : public is_constructible<_Tp> - {}; - -#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) -template -_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_default_constructible_v - = is_default_constructible<_Tp>::value; -#endif - -#ifndef _LIBCPP_CXX03_LANG -// First of all, we can't implement this check in C++03 mode because the {} -// default initialization syntax isn't valid. -// Second, we implement the trait in a funny manner with two defaulted template -// arguments to workaround Clang's PR43454. -template -void __test_implicit_default_constructible(_Tp); - -template ::type> -struct __is_implicitly_default_constructible - : false_type -{ }; - -template -struct __is_implicitly_default_constructible<_Tp, decltype(__test_implicit_default_constructible<_Tp const&>({})), true_type> - : true_type -{ }; - -template -struct __is_implicitly_default_constructible<_Tp, decltype(__test_implicit_default_constructible<_Tp const&>({})), false_type> - : false_type -{ }; -#endif // !C++03 - -// is_copy_constructible - -template -struct _LIBCPP_TEMPLATE_VIS is_copy_constructible - : public is_constructible<_Tp, - typename add_lvalue_reference::type>::type> {}; - -#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) -template -_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_copy_constructible_v - = is_copy_constructible<_Tp>::value; -#endif - -// is_move_constructible - -template -struct _LIBCPP_TEMPLATE_VIS is_move_constructible - : public is_constructible<_Tp, typename add_rvalue_reference<_Tp>::type> - {}; - -#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) -template -_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_move_constructible_v - = is_move_constructible<_Tp>::value; -#endif - -// is_trivially_constructible - -#if __has_feature(is_trivially_constructible) || _GNUC_VER >= 501 - -template -struct _LIBCPP_TEMPLATE_VIS is_trivially_constructible - : integral_constant -{ -}; - -#else // !__has_feature(is_trivially_constructible) - -template -struct _LIBCPP_TEMPLATE_VIS is_trivially_constructible - : false_type -{ -}; - -template -struct _LIBCPP_TEMPLATE_VIS is_trivially_constructible<_Tp> -#if __has_feature(has_trivial_constructor) || defined(_LIBCPP_COMPILER_GCC) - : integral_constant -#else - : integral_constant::value> -#endif -{ -}; - -template -struct _LIBCPP_TEMPLATE_VIS is_trivially_constructible<_Tp, _Tp&&> - : integral_constant::value> -{ -}; - -template -struct _LIBCPP_TEMPLATE_VIS is_trivially_constructible<_Tp, const _Tp&> - : integral_constant::value> -{ -}; - -template -struct _LIBCPP_TEMPLATE_VIS is_trivially_constructible<_Tp, _Tp&> - : integral_constant::value> -{ -}; - -#endif // !__has_feature(is_trivially_constructible) - - -#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) -template -_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_trivially_constructible_v - = is_trivially_constructible<_Tp, _Args...>::value; -#endif - -// is_trivially_default_constructible - -template struct _LIBCPP_TEMPLATE_VIS is_trivially_default_constructible - : public is_trivially_constructible<_Tp> - {}; - -#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) -template -_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_trivially_default_constructible_v - = is_trivially_default_constructible<_Tp>::value; -#endif - -// is_trivially_copy_constructible - -template struct _LIBCPP_TEMPLATE_VIS is_trivially_copy_constructible - : public is_trivially_constructible<_Tp, typename add_lvalue_reference::type> - {}; - -#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) -template -_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_trivially_copy_constructible_v - = is_trivially_copy_constructible<_Tp>::value; -#endif - -// is_trivially_move_constructible - -template struct _LIBCPP_TEMPLATE_VIS is_trivially_move_constructible - : public is_trivially_constructible<_Tp, typename add_rvalue_reference<_Tp>::type> - {}; - -#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) -template -_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_trivially_move_constructible_v - = is_trivially_move_constructible<_Tp>::value; -#endif - -// is_trivially_assignable - -#if __has_feature(is_trivially_assignable) || _GNUC_VER >= 501 - -template -struct is_trivially_assignable - : integral_constant -{ -}; - -#else // !__has_feature(is_trivially_assignable) - -template -struct is_trivially_assignable - : public false_type {}; - -template -struct is_trivially_assignable<_Tp&, _Tp> - : integral_constant::value> {}; - -template -struct is_trivially_assignable<_Tp&, _Tp&> - : integral_constant::value> {}; - -template -struct is_trivially_assignable<_Tp&, const _Tp&> - : integral_constant::value> {}; - -template -struct is_trivially_assignable<_Tp&, _Tp&&> - : integral_constant::value> {}; - -#endif // !__has_feature(is_trivially_assignable) - -#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) -template -_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_trivially_assignable_v - = is_trivially_assignable<_Tp, _Arg>::value; -#endif - -// is_trivially_copy_assignable - -template struct _LIBCPP_TEMPLATE_VIS is_trivially_copy_assignable - : public is_trivially_assignable::type, - typename add_lvalue_reference::type>::type> {}; - -#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) -template -_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_trivially_copy_assignable_v - = is_trivially_copy_assignable<_Tp>::value; -#endif - -// is_trivially_move_assignable - -template struct _LIBCPP_TEMPLATE_VIS is_trivially_move_assignable - : public is_trivially_assignable::type, - typename add_rvalue_reference<_Tp>::type> - {}; - -#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) -template -_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_trivially_move_assignable_v - = is_trivially_move_assignable<_Tp>::value; -#endif - // is_trivially_destructible #if __has_keyword(__is_trivially_destructible) @@ -3476,159 +2609,6 @@ = is_trivially_destructible<_Tp>::value; #endif -// is_nothrow_constructible - -#if __has_keyword(__is_nothrow_constructible) - -template -struct _LIBCPP_TEMPLATE_VIS is_nothrow_constructible - : public integral_constant {}; - -#else - -template struct __libcpp_is_nothrow_constructible; - -template -struct __libcpp_is_nothrow_constructible - : public integral_constant()...))> -{ -}; - -template -void __implicit_conversion_to(_Tp) noexcept { } - -template -struct __libcpp_is_nothrow_constructible - : public integral_constant(declval<_Arg>()))> -{ -}; - -template -struct __libcpp_is_nothrow_constructible - : public false_type -{ -}; - -template -struct _LIBCPP_TEMPLATE_VIS is_nothrow_constructible - : __libcpp_is_nothrow_constructible::value, is_reference<_Tp>::value, _Tp, _Args...> -{ -}; - -template -struct _LIBCPP_TEMPLATE_VIS is_nothrow_constructible<_Tp[_Ns]> - : __libcpp_is_nothrow_constructible::value, is_reference<_Tp>::value, _Tp> -{ -}; - -#endif // _LIBCPP_HAS_NO_NOEXCEPT - - -#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) -template -_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_nothrow_constructible_v - = is_nothrow_constructible<_Tp, _Args...>::value; -#endif - -// is_nothrow_default_constructible - -template struct _LIBCPP_TEMPLATE_VIS is_nothrow_default_constructible - : public is_nothrow_constructible<_Tp> - {}; - -#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) -template -_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_nothrow_default_constructible_v - = is_nothrow_default_constructible<_Tp>::value; -#endif - -// is_nothrow_copy_constructible - -template struct _LIBCPP_TEMPLATE_VIS is_nothrow_copy_constructible - : public is_nothrow_constructible<_Tp, - typename add_lvalue_reference::type>::type> {}; - -#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) -template -_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_nothrow_copy_constructible_v - = is_nothrow_copy_constructible<_Tp>::value; -#endif - -// is_nothrow_move_constructible - -template struct _LIBCPP_TEMPLATE_VIS is_nothrow_move_constructible - : public is_nothrow_constructible<_Tp, typename add_rvalue_reference<_Tp>::type> - {}; - -#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) -template -_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_nothrow_move_constructible_v - = is_nothrow_move_constructible<_Tp>::value; -#endif - -// is_nothrow_assignable - -#if __has_keyword(__is_nothrow_assignable) - -template -struct _LIBCPP_TEMPLATE_VIS is_nothrow_assignable - : public integral_constant {}; - -#else - -template struct __libcpp_is_nothrow_assignable; - -template -struct __libcpp_is_nothrow_assignable - : public false_type -{ -}; - -template -struct __libcpp_is_nothrow_assignable - : public integral_constant() = declval<_Arg>()) > -{ -}; - -template -struct _LIBCPP_TEMPLATE_VIS is_nothrow_assignable - : public __libcpp_is_nothrow_assignable::value, _Tp, _Arg> -{ -}; - -#endif // _LIBCPP_HAS_NO_NOEXCEPT - -#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) -template -_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_nothrow_assignable_v - = is_nothrow_assignable<_Tp, _Arg>::value; -#endif - -// is_nothrow_copy_assignable - -template struct _LIBCPP_TEMPLATE_VIS is_nothrow_copy_assignable - : public is_nothrow_assignable::type, - typename add_lvalue_reference::type>::type> {}; - -#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) -template -_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_nothrow_copy_assignable_v - = is_nothrow_copy_assignable<_Tp>::value; -#endif - -// is_nothrow_move_assignable - -template struct _LIBCPP_TEMPLATE_VIS is_nothrow_move_assignable - : public is_nothrow_assignable::type, - typename add_rvalue_reference<_Tp>::type> - {}; - -#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) -template -_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_nothrow_move_assignable_v - = is_nothrow_move_assignable<_Tp>::value; -#endif - // is_nothrow_destructible #if !defined(_LIBCPP_CXX03_LANG) @@ -4188,121 +3168,8 @@ 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); - -template -inline _LIBCPP_INLINE_VISIBILITY -#ifndef _LIBCPP_CXX03_LANG -typename enable_if -< - is_move_constructible<_Tp>::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); -} - -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 -namespace __detail -{ -// ALL generic swap overloads MUST already have a declaration available at this point. - -template ::value && !is_void<_Up>::value> -struct __swappable_with -{ - template - static decltype(swap(declval<_LHS>(), declval<_RHS>())) - __test_swap(int); - template - static __nat __test_swap(long); - - // Extra parens are needed for the C++03 definition of decltype. - typedef decltype((__test_swap<_Tp, _Up>(0))) __swap1; - typedef decltype((__test_swap<_Up, _Tp>(0))) __swap2; - - static const bool value = _IsNotSame<__swap1, __nat>::value - && _IsNotSame<__swap2, __nat>::value; -}; - -template -struct __swappable_with<_Tp, _Up, false> : false_type {}; - -template ::value> -struct __nothrow_swappable_with { - static const bool value = -#ifndef _LIBCPP_HAS_NO_NOEXCEPT - noexcept(swap(declval<_Tp>(), declval<_Up>())) - && noexcept(swap(declval<_Up>(), declval<_Tp>())); -#else - false; -#endif -}; - -template -struct __nothrow_swappable_with<_Tp, _Up, false> : false_type {}; - -} // __detail - -template -struct __is_swappable - : public integral_constant::value> -{ -}; - -template -struct __is_nothrow_swappable - : public integral_constant::value> -{ -}; - #if _LIBCPP_STD_VER > 14 template 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.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"