authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-08-16 23:30:18-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-08-16 23:32:13-07:00
log92b69215e63a3303a5e904ab332e2eec236e0ed2
tree82dc7298eba67fb6881e0a9014d251073c6a76ae
parent1b8f0d8b56a578dbd699021dd14ea80d743b7cf8

update libcxx, libcxxabi, libunwind, and tsan to llvm 13 rc1


585 files changed, 39534 insertions(+), 26229 deletions(-)

lib/libcxx/include/__algorithm/adjacent_find.h created+51
......@@ -0,0 +1,51 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___ALGORITHM_ADJACENT_FIND_H
11#define _LIBCPP___ALGORITHM_ADJACENT_FIND_H
12
13#include <__config>
14#include <__algorithm/comp.h>
15#include <__iterator/iterator_traits.h>
16
17#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
18#pragma GCC system_header
19#endif
20
21_LIBCPP_PUSH_MACROS
22#include <__undef_macros>
23
24_LIBCPP_BEGIN_NAMESPACE_STD
25
26template <class _ForwardIterator, class _BinaryPredicate>
27_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator
28adjacent_find(_ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred) {
29 if (__first != __last) {
30 _ForwardIterator __i = __first;
31 while (++__i != __last) {
32 if (__pred(*__first, *__i))
33 return __first;
34 __first = __i;
35 }
36 }
37 return __last;
38}
39
40template <class _ForwardIterator>
41_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator
42adjacent_find(_ForwardIterator __first, _ForwardIterator __last) {
43 typedef typename iterator_traits<_ForwardIterator>::value_type __v;
44 return _VSTD::adjacent_find(__first, __last, __equal_to<__v>());
45}
46
47_LIBCPP_END_NAMESPACE_STD
48
49_LIBCPP_POP_MACROS
50
51#endif // _LIBCPP___ALGORITHM_ADJACENT_FIND_H
lib/libcxx/include/__algorithm/all_of.h created+37
......@@ -0,0 +1,37 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___ALGORITHM_ALL_OF_H
11#define _LIBCPP___ALGORITHM_ALL_OF_H
12
13#include <__config>
14
15#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
16#pragma GCC system_header
17#endif
18
19_LIBCPP_PUSH_MACROS
20#include <__undef_macros>
21
22_LIBCPP_BEGIN_NAMESPACE_STD
23
24template <class _InputIterator, class _Predicate>
25_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool
26all_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) {
27 for (; __first != __last; ++__first)
28 if (!__pred(*__first))
29 return false;
30 return true;
31}
32
33_LIBCPP_END_NAMESPACE_STD
34
35_LIBCPP_POP_MACROS
36
37#endif // _LIBCPP___ALGORITHM_ALL_OF_H
lib/libcxx/include/__algorithm/any_of.h created+37
......@@ -0,0 +1,37 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___ALGORITHM_ANY_OF_H
11#define _LIBCPP___ALGORITHM_ANY_OF_H
12
13#include <__config>
14
15#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
16#pragma GCC system_header
17#endif
18
19_LIBCPP_PUSH_MACROS
20#include <__undef_macros>
21
22_LIBCPP_BEGIN_NAMESPACE_STD
23
24template <class _InputIterator, class _Predicate>
25_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool
26any_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) {
27 for (; __first != __last; ++__first)
28 if (__pred(*__first))
29 return true;
30 return false;
31}
32
33_LIBCPP_END_NAMESPACE_STD
34
35_LIBCPP_POP_MACROS
36
37#endif // _LIBCPP___ALGORITHM_ANY_OF_H
lib/libcxx/include/__algorithm/binary_search.h created+61
......@@ -0,0 +1,61 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_BINARY_SEARCH_H
10#define _LIBCPP___ALGORITHM_BINARY_SEARCH_H
11
12#include <__config>
13#include <__algorithm/comp.h>
14#include <__algorithm/lower_bound.h>
15#include <__algorithm/comp_ref_type.h>
16#include <__iterator/iterator_traits.h>
17
18#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
19#pragma GCC system_header
20#endif
21
22_LIBCPP_PUSH_MACROS
23#include <__undef_macros>
24
25_LIBCPP_BEGIN_NAMESPACE_STD
26
27template <class _Compare, class _ForwardIterator, class _Tp>
28inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
29bool
30__binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp)
31{
32 __first = _VSTD::__lower_bound<_Compare>(__first, __last, __value_, __comp);
33 return __first != __last && !__comp(__value_, *__first);
34}
35
36template <class _ForwardIterator, class _Tp, class _Compare>
37_LIBCPP_NODISCARD_EXT inline
38_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
39bool
40binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp)
41{
42 typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
43 return _VSTD::__binary_search<_Comp_ref>(__first, __last, __value_, __comp);
44}
45
46template <class _ForwardIterator, class _Tp>
47_LIBCPP_NODISCARD_EXT inline
48_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
49bool
50binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_)
51{
52 return _VSTD::binary_search(__first, __last, __value_,
53 __less<typename iterator_traits<_ForwardIterator>::value_type, _Tp>());
54}
55
56
57_LIBCPP_END_NAMESPACE_STD
58
59_LIBCPP_POP_MACROS
60
61#endif // _LIBCPP___ALGORITHM_BINARY_SEARCH_H
lib/libcxx/include/__algorithm/clamp.h created+52
......@@ -0,0 +1,52 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_CLAMP_H
10#define _LIBCPP___ALGORITHM_CLAMP_H
11
12#include <__config>
13#include <__debug>
14#include <__algorithm/comp.h>
15
16#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
17#pragma GCC system_header
18#endif
19
20_LIBCPP_PUSH_MACROS
21#include <__undef_macros>
22
23_LIBCPP_BEGIN_NAMESPACE_STD
24
25#if _LIBCPP_STD_VER > 14
26// clamp
27template<class _Tp, class _Compare>
28_LIBCPP_NODISCARD_EXT inline
29_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
30const _Tp&
31clamp(const _Tp& __v, const _Tp& __lo, const _Tp& __hi, _Compare __comp)
32{
33 _LIBCPP_ASSERT(!__comp(__hi, __lo), "Bad bounds passed to std::clamp");
34 return __comp(__v, __lo) ? __lo : __comp(__hi, __v) ? __hi : __v;
35
36}
37
38template<class _Tp>
39_LIBCPP_NODISCARD_EXT inline
40_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
41const _Tp&
42clamp(const _Tp& __v, const _Tp& __lo, const _Tp& __hi)
43{
44 return _VSTD::clamp(__v, __lo, __hi, __less<_Tp>());
45}
46#endif
47
48_LIBCPP_END_NAMESPACE_STD
49
50_LIBCPP_POP_MACROS
51
52#endif // _LIBCPP___ALGORITHM_CLAMP_H
lib/libcxx/include/__algorithm/comp.h created+97
......@@ -0,0 +1,97 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_COMP_H
10#define _LIBCPP___ALGORITHM_COMP_H
11
12#include <__config>
13
14#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
15#pragma GCC system_header
16#endif
17
18_LIBCPP_PUSH_MACROS
19#include <__undef_macros>
20
21_LIBCPP_BEGIN_NAMESPACE_STD
22
23// I'd like to replace these with _VSTD::equal_to<void>, but can't because:
24// * That only works with C++14 and later, and
25// * We haven't included <functional> here.
26template <class _T1, class _T2 = _T1>
27struct __equal_to
28{
29 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 bool operator()(const _T1& __x, const _T1& __y) const {return __x == __y;}
30 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 bool operator()(const _T1& __x, const _T2& __y) const {return __x == __y;}
31 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 bool operator()(const _T2& __x, const _T1& __y) const {return __x == __y;}
32 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 bool operator()(const _T2& __x, const _T2& __y) const {return __x == __y;}
33};
34
35template <class _T1>
36struct __equal_to<_T1, _T1>
37{
38 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
39 bool operator()(const _T1& __x, const _T1& __y) const {return __x == __y;}
40};
41
42template <class _T1>
43struct __equal_to<const _T1, _T1>
44{
45 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
46 bool operator()(const _T1& __x, const _T1& __y) const {return __x == __y;}
47};
48
49template <class _T1>
50struct __equal_to<_T1, const _T1>
51{
52 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
53 bool operator()(const _T1& __x, const _T1& __y) const {return __x == __y;}
54};
55
56template <class _T1, class _T2 = _T1>
57struct __less
58{
59 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
60 bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;}
61
62 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
63 bool operator()(const _T1& __x, const _T2& __y) const {return __x < __y;}
64
65 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
66 bool operator()(const _T2& __x, const _T1& __y) const {return __x < __y;}
67
68 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
69 bool operator()(const _T2& __x, const _T2& __y) const {return __x < __y;}
70};
71
72template <class _T1>
73struct __less<_T1, _T1>
74{
75 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
76 bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;}
77};
78
79template <class _T1>
80struct __less<const _T1, _T1>
81{
82 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
83 bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;}
84};
85
86template <class _T1>
87struct __less<_T1, const _T1>
88{
89 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
90 bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;}
91};
92
93_LIBCPP_END_NAMESPACE_STD
94
95_LIBCPP_POP_MACROS
96
97#endif // _LIBCPP___ALGORITHM_COMP_H
lib/libcxx/include/__algorithm/comp_ref_type.h created+87
......@@ -0,0 +1,87 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_COMP_REF_TYPE_H
10#define _LIBCPP___ALGORITHM_COMP_REF_TYPE_H
11
12#include <__config>
13#include <type_traits>
14
15#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
16#pragma GCC system_header
17#endif
18
19_LIBCPP_PUSH_MACROS
20#include <__undef_macros>
21
22_LIBCPP_BEGIN_NAMESPACE_STD
23
24#ifdef _LIBCPP_DEBUG
25
26template <class _Compare>
27struct __debug_less
28{
29 _Compare &__comp_;
30 _LIBCPP_CONSTEXPR_AFTER_CXX17
31 __debug_less(_Compare& __c) : __comp_(__c) {}
32
33 template <class _Tp, class _Up>
34 _LIBCPP_CONSTEXPR_AFTER_CXX17
35 bool operator()(const _Tp& __x, const _Up& __y)
36 {
37 bool __r = __comp_(__x, __y);
38 if (__r)
39 __do_compare_assert(0, __y, __x);
40 return __r;
41 }
42
43 template <class _Tp, class _Up>
44 _LIBCPP_CONSTEXPR_AFTER_CXX17
45 bool operator()(_Tp& __x, _Up& __y)
46 {
47 bool __r = __comp_(__x, __y);
48 if (__r)
49 __do_compare_assert(0, __y, __x);
50 return __r;
51 }
52
53 template <class _LHS, class _RHS>
54 _LIBCPP_CONSTEXPR_AFTER_CXX17
55 inline _LIBCPP_INLINE_VISIBILITY
56 decltype((void)declval<_Compare&>()(
57 declval<_LHS &>(), declval<_RHS &>()))
58 __do_compare_assert(int, _LHS & __l, _RHS & __r) {
59 _LIBCPP_ASSERT(!__comp_(__l, __r),
60 "Comparator does not induce a strict weak ordering");
61 }
62
63 template <class _LHS, class _RHS>
64 _LIBCPP_CONSTEXPR_AFTER_CXX17
65 inline _LIBCPP_INLINE_VISIBILITY
66 void __do_compare_assert(long, _LHS &, _RHS &) {}
67};
68
69#endif // _LIBCPP_DEBUG
70
71template <class _Comp>
72struct __comp_ref_type {
73 // Pass the comparator by lvalue reference. Or in debug mode, using a
74 // debugging wrapper that stores a reference.
75#ifndef _LIBCPP_DEBUG
76 typedef typename add_lvalue_reference<_Comp>::type type;
77#else
78 typedef __debug_less<_Comp> type;
79#endif
80};
81
82
83_LIBCPP_END_NAMESPACE_STD
84
85_LIBCPP_POP_MACROS
86
87#endif // _LIBCPP___ALGORITHM_COMP_REF_TYPE_H
lib/libcxx/include/__algorithm/copy.h created+82
......@@ -0,0 +1,82 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_COPY_H
10#define _LIBCPP___ALGORITHM_COPY_H
11
12#include <__config>
13#include <__algorithm/unwrap_iter.h>
14#include <__iterator/iterator_traits.h>
15#include <cstring>
16#include <type_traits>
17
18#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
19#pragma GCC system_header
20#endif
21
22_LIBCPP_PUSH_MACROS
23#include <__undef_macros>
24
25_LIBCPP_BEGIN_NAMESPACE_STD
26
27// copy
28
29template <class _InputIterator, class _OutputIterator>
30inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
31_OutputIterator
32__copy_constexpr(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
33{
34 for (; __first != __last; ++__first, (void) ++__result)
35 *__result = *__first;
36 return __result;
37}
38
39template <class _InputIterator, class _OutputIterator>
40inline _LIBCPP_INLINE_VISIBILITY
41_OutputIterator
42__copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
43{
44 return _VSTD::__copy_constexpr(__first, __last, __result);
45}
46
47template <class _Tp, class _Up>
48inline _LIBCPP_INLINE_VISIBILITY
49typename enable_if
50<
51 is_same<typename remove_const<_Tp>::type, _Up>::value &&
52 is_trivially_copy_assignable<_Up>::value,
53 _Up*
54>::type
55__copy(_Tp* __first, _Tp* __last, _Up* __result)
56{
57 const size_t __n = static_cast<size_t>(__last - __first);
58 if (__n > 0)
59 _VSTD::memmove(__result, __first, __n * sizeof(_Up));
60 return __result + __n;
61}
62
63template <class _InputIterator, class _OutputIterator>
64inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
65_OutputIterator
66copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
67{
68 if (__libcpp_is_constant_evaluated()) {
69 return _VSTD::__copy_constexpr(__first, __last, __result);
70 } else {
71 return _VSTD::__rewrap_iter(__result,
72 _VSTD::__copy(_VSTD::__unwrap_iter(__first),
73 _VSTD::__unwrap_iter(__last),
74 _VSTD::__unwrap_iter(__result)));
75 }
76}
77
78_LIBCPP_END_NAMESPACE_STD
79
80_LIBCPP_POP_MACROS
81
82#endif // _LIBCPP___ALGORITHM_COPY_H
lib/libcxx/include/__algorithm/copy_backward.h created+84
......@@ -0,0 +1,84 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_COPY_BACKWARD_H
10#define _LIBCPP___ALGORITHM_COPY_BACKWARD_H
11
12#include <__config>
13#include <__algorithm/unwrap_iter.h>
14#include <__iterator/iterator_traits.h>
15#include <cstring>
16#include <type_traits>
17
18#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
19#pragma GCC system_header
20#endif
21
22_LIBCPP_PUSH_MACROS
23#include <__undef_macros>
24
25_LIBCPP_BEGIN_NAMESPACE_STD
26
27template <class _BidirectionalIterator, class _OutputIterator>
28inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
29_OutputIterator
30__copy_backward_constexpr(_BidirectionalIterator __first, _BidirectionalIterator __last, _OutputIterator __result)
31{
32 while (__first != __last)
33 *--__result = *--__last;
34 return __result;
35}
36
37template <class _BidirectionalIterator, class _OutputIterator>
38inline _LIBCPP_INLINE_VISIBILITY
39_OutputIterator
40__copy_backward(_BidirectionalIterator __first, _BidirectionalIterator __last, _OutputIterator __result)
41{
42 return _VSTD::__copy_backward_constexpr(__first, __last, __result);
43}
44
45template <class _Tp, class _Up>
46inline _LIBCPP_INLINE_VISIBILITY
47typename enable_if
48<
49 is_same<typename remove_const<_Tp>::type, _Up>::value &&
50 is_trivially_copy_assignable<_Up>::value,
51 _Up*
52>::type
53__copy_backward(_Tp* __first, _Tp* __last, _Up* __result)
54{
55 const size_t __n = static_cast<size_t>(__last - __first);
56 if (__n > 0)
57 {
58 __result -= __n;
59 _VSTD::memmove(__result, __first, __n * sizeof(_Up));
60 }
61 return __result;
62}
63
64template <class _BidirectionalIterator1, class _BidirectionalIterator2>
65inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
66_BidirectionalIterator2
67copy_backward(_BidirectionalIterator1 __first, _BidirectionalIterator1 __last,
68 _BidirectionalIterator2 __result)
69{
70 if (__libcpp_is_constant_evaluated()) {
71 return _VSTD::__copy_backward_constexpr(__first, __last, __result);
72 } else {
73 return _VSTD::__rewrap_iter(__result,
74 _VSTD::__copy_backward(_VSTD::__unwrap_iter(__first),
75 _VSTD::__unwrap_iter(__last),
76 _VSTD::__unwrap_iter(__result)));
77 }
78}
79
80_LIBCPP_END_NAMESPACE_STD
81
82_LIBCPP_POP_MACROS
83
84#endif // _LIBCPP___ALGORITHM_COPY_BACKWARD_H
lib/libcxx/include/__algorithm/copy_if.h created+48
......@@ -0,0 +1,48 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_COPY_IF_H
10#define _LIBCPP___ALGORITHM_COPY_IF_H
11
12#include <__config>
13#include <__algorithm/unwrap_iter.h>
14#include <__iterator/iterator_traits.h>
15#include <cstring>
16#include <type_traits>
17
18#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
19#pragma GCC system_header
20#endif
21
22_LIBCPP_PUSH_MACROS
23#include <__undef_macros>
24
25_LIBCPP_BEGIN_NAMESPACE_STD
26
27template<class _InputIterator, class _OutputIterator, class _Predicate>
28inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
29_OutputIterator
30copy_if(_InputIterator __first, _InputIterator __last,
31 _OutputIterator __result, _Predicate __pred)
32{
33 for (; __first != __last; ++__first)
34 {
35 if (__pred(*__first))
36 {
37 *__result = *__first;
38 ++__result;
39 }
40 }
41 return __result;
42}
43
44_LIBCPP_END_NAMESPACE_STD
45
46_LIBCPP_POP_MACROS
47
48#endif // _LIBCPP___ALGORITHM_COPY_IF_H
lib/libcxx/include/__algorithm/copy_n.h created+72
......@@ -0,0 +1,72 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_COPY_N_H
10#define _LIBCPP___ALGORITHM_COPY_N_H
11
12#include <__config>
13#include <__algorithm/copy.h>
14#include <__algorithm/unwrap_iter.h>
15#include <__iterator/iterator_traits.h>
16#include <cstring>
17#include <type_traits>
18
19#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
20#pragma GCC system_header
21#endif
22
23_LIBCPP_PUSH_MACROS
24#include <__undef_macros>
25
26_LIBCPP_BEGIN_NAMESPACE_STD
27
28template<class _InputIterator, class _Size, class _OutputIterator>
29inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
30typename enable_if
31<
32 __is_cpp17_input_iterator<_InputIterator>::value &&
33 !__is_cpp17_random_access_iterator<_InputIterator>::value,
34 _OutputIterator
35>::type
36copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result)
37{
38 typedef decltype(_VSTD::__convert_to_integral(__orig_n)) _IntegralSize;
39 _IntegralSize __n = __orig_n;
40 if (__n > 0)
41 {
42 *__result = *__first;
43 ++__result;
44 for (--__n; __n > 0; --__n)
45 {
46 ++__first;
47 *__result = *__first;
48 ++__result;
49 }
50 }
51 return __result;
52}
53
54template<class _InputIterator, class _Size, class _OutputIterator>
55inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
56typename enable_if
57<
58 __is_cpp17_random_access_iterator<_InputIterator>::value,
59 _OutputIterator
60>::type
61copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result)
62{
63 typedef decltype(_VSTD::__convert_to_integral(__orig_n)) _IntegralSize;
64 _IntegralSize __n = __orig_n;
65 return _VSTD::copy(__first, __first + __n, __result);
66}
67
68_LIBCPP_END_NAMESPACE_STD
69
70_LIBCPP_POP_MACROS
71
72#endif // _LIBCPP___ALGORITHM_COPY_N_H
lib/libcxx/include/__algorithm/count.h created+40
......@@ -0,0 +1,40 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___ALGORITHM_COUNT_H
11#define _LIBCPP___ALGORITHM_COUNT_H
12
13#include <__config>
14#include <__iterator/iterator_traits.h>
15
16#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
17#pragma GCC system_header
18#endif
19
20_LIBCPP_PUSH_MACROS
21#include <__undef_macros>
22
23_LIBCPP_BEGIN_NAMESPACE_STD
24
25template <class _InputIterator, class _Tp>
26_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
27 typename iterator_traits<_InputIterator>::difference_type
28 count(_InputIterator __first, _InputIterator __last, const _Tp& __value_) {
29 typename iterator_traits<_InputIterator>::difference_type __r(0);
30 for (; __first != __last; ++__first)
31 if (*__first == __value_)
32 ++__r;
33 return __r;
34}
35
36_LIBCPP_END_NAMESPACE_STD
37
38_LIBCPP_POP_MACROS
39
40#endif // _LIBCPP___ALGORITHM_COUNT_H
lib/libcxx/include/__algorithm/count_if.h created+40
......@@ -0,0 +1,40 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___ALGORITHM_COUNT_IF_H
11#define _LIBCPP___ALGORITHM_COUNT_IF_H
12
13#include <__config>
14#include <__iterator/iterator_traits.h>
15
16#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
17#pragma GCC system_header
18#endif
19
20_LIBCPP_PUSH_MACROS
21#include <__undef_macros>
22
23_LIBCPP_BEGIN_NAMESPACE_STD
24
25template <class _InputIterator, class _Predicate>
26_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
27 typename iterator_traits<_InputIterator>::difference_type
28 count_if(_InputIterator __first, _InputIterator __last, _Predicate __pred) {
29 typename iterator_traits<_InputIterator>::difference_type __r(0);
30 for (; __first != __last; ++__first)
31 if (__pred(*__first))
32 ++__r;
33 return __r;
34}
35
36_LIBCPP_END_NAMESPACE_STD
37
38_LIBCPP_POP_MACROS
39
40#endif // _LIBCPP___ALGORITHM_COUNT_IF_H
lib/libcxx/include/__algorithm/equal.h created+90
......@@ -0,0 +1,90 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___ALGORITHM_EQUAL_H
11#define _LIBCPP___ALGORITHM_EQUAL_H
12
13#include <__config>
14#include <__algorithm/comp.h>
15#include <__iterator/iterator_traits.h>
16#include <iterator> // FIXME: replace with <__iterator/distance.h> when it lands
17
18#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
19#pragma GCC system_header
20#endif
21
22_LIBCPP_PUSH_MACROS
23#include <__undef_macros>
24
25_LIBCPP_BEGIN_NAMESPACE_STD
26
27template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate>
28_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool
29equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _BinaryPredicate __pred) {
30 for (; __first1 != __last1; ++__first1, (void)++__first2)
31 if (!__pred(*__first1, *__first2))
32 return false;
33 return true;
34}
35
36template <class _InputIterator1, class _InputIterator2>
37_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool
38equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2) {
39 typedef typename iterator_traits<_InputIterator1>::value_type __v1;
40 typedef typename iterator_traits<_InputIterator2>::value_type __v2;
41 return _VSTD::equal(__first1, __last1, __first2, __equal_to<__v1, __v2>());
42}
43
44#if _LIBCPP_STD_VER > 11
45template <class _BinaryPredicate, class _InputIterator1, class _InputIterator2>
46inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool
47__equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2,
48 _BinaryPredicate __pred, input_iterator_tag, input_iterator_tag) {
49 for (; __first1 != __last1 && __first2 != __last2; ++__first1, (void)++__first2)
50 if (!__pred(*__first1, *__first2))
51 return false;
52 return __first1 == __last1 && __first2 == __last2;
53}
54
55template <class _BinaryPredicate, class _RandomAccessIterator1, class _RandomAccessIterator2>
56inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool
57__equal(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2,
58 _RandomAccessIterator2 __last2, _BinaryPredicate __pred, random_access_iterator_tag,
59 random_access_iterator_tag) {
60 if (_VSTD::distance(__first1, __last1) != _VSTD::distance(__first2, __last2))
61 return false;
62 return _VSTD::equal<_RandomAccessIterator1, _RandomAccessIterator2,
63 typename add_lvalue_reference<_BinaryPredicate>::type>(__first1, __last1, __first2, __pred);
64}
65
66template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate>
67_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool
68equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2,
69 _BinaryPredicate __pred) {
70 return _VSTD::__equal<typename add_lvalue_reference<_BinaryPredicate>::type>(
71 __first1, __last1, __first2, __last2, __pred, typename iterator_traits<_InputIterator1>::iterator_category(),
72 typename iterator_traits<_InputIterator2>::iterator_category());
73}
74
75template <class _InputIterator1, class _InputIterator2>
76_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool
77equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) {
78 typedef typename iterator_traits<_InputIterator1>::value_type __v1;
79 typedef typename iterator_traits<_InputIterator2>::value_type __v2;
80 return _VSTD::__equal(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>(),
81 typename iterator_traits<_InputIterator1>::iterator_category(),
82 typename iterator_traits<_InputIterator2>::iterator_category());
83}
84#endif
85
86_LIBCPP_END_NAMESPACE_STD
87
88_LIBCPP_POP_MACROS
89
90#endif // _LIBCPP___ALGORITHM_EQUAL_H
lib/libcxx/include/__algorithm/equal_range.h created+87
......@@ -0,0 +1,87 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_EQUAL_RANGE_H
10#define _LIBCPP___ALGORITHM_EQUAL_RANGE_H
11
12#include <__config>
13#include <__algorithm/comp.h>
14#include <__algorithm/comp_ref_type.h>
15#include <__algorithm/half_positive.h>
16#include <__algorithm/lower_bound.h>
17#include <__algorithm/upper_bound.h>
18#include <iterator>
19
20#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
21#pragma GCC system_header
22#endif
23
24_LIBCPP_PUSH_MACROS
25#include <__undef_macros>
26
27_LIBCPP_BEGIN_NAMESPACE_STD
28
29template <class _Compare, class _ForwardIterator, class _Tp>
30_LIBCPP_CONSTEXPR_AFTER_CXX17 pair<_ForwardIterator, _ForwardIterator>
31__equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp)
32{
33 typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type;
34 difference_type __len = _VSTD::distance(__first, __last);
35 while (__len != 0)
36 {
37 difference_type __l2 = _VSTD::__half_positive(__len);
38 _ForwardIterator __m = __first;
39 _VSTD::advance(__m, __l2);
40 if (__comp(*__m, __value_))
41 {
42 __first = ++__m;
43 __len -= __l2 + 1;
44 }
45 else if (__comp(__value_, *__m))
46 {
47 __last = __m;
48 __len = __l2;
49 }
50 else
51 {
52 _ForwardIterator __mp1 = __m;
53 return pair<_ForwardIterator, _ForwardIterator>
54 (
55 _VSTD::__lower_bound<_Compare>(__first, __m, __value_, __comp),
56 _VSTD::__upper_bound<_Compare>(++__mp1, __last, __value_, __comp)
57 );
58 }
59 }
60 return pair<_ForwardIterator, _ForwardIterator>(__first, __first);
61}
62
63template <class _ForwardIterator, class _Tp, class _Compare>
64_LIBCPP_NODISCARD_EXT inline
65_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
66pair<_ForwardIterator, _ForwardIterator>
67equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp)
68{
69 typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
70 return _VSTD::__equal_range<_Comp_ref>(__first, __last, __value_, __comp);
71}
72
73template <class _ForwardIterator, class _Tp>
74_LIBCPP_NODISCARD_EXT inline
75_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
76pair<_ForwardIterator, _ForwardIterator>
77equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_)
78{
79 return _VSTD::equal_range(__first, __last, __value_,
80 __less<typename iterator_traits<_ForwardIterator>::value_type, _Tp>());
81}
82
83_LIBCPP_END_NAMESPACE_STD
84
85_LIBCPP_POP_MACROS
86
87#endif // _LIBCPP___ALGORITHM_EQUAL_RANGE_H
lib/libcxx/include/__algorithm/fill.h created+55
......@@ -0,0 +1,55 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_FILL_H
10#define _LIBCPP___ALGORITHM_FILL_H
11
12#include <__config>
13#include <__algorithm/fill_n.h>
14#include <__iterator/iterator_traits.h>
15#include <type_traits>
16
17#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
18#pragma GCC system_header
19#endif
20
21_LIBCPP_PUSH_MACROS
22#include <__undef_macros>
23
24_LIBCPP_BEGIN_NAMESPACE_STD
25
26template <class _ForwardIterator, class _Tp>
27inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
28void
29__fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, forward_iterator_tag)
30{
31 for (; __first != __last; ++__first)
32 *__first = __value_;
33}
34
35template <class _RandomAccessIterator, class _Tp>
36inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
37void
38__fill(_RandomAccessIterator __first, _RandomAccessIterator __last, const _Tp& __value_, random_access_iterator_tag)
39{
40 _VSTD::fill_n(__first, __last - __first, __value_);
41}
42
43template <class _ForwardIterator, class _Tp>
44inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
45void
46fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_)
47{
48 _VSTD::__fill(__first, __last, __value_, typename iterator_traits<_ForwardIterator>::iterator_category());
49}
50
51_LIBCPP_END_NAMESPACE_STD
52
53_LIBCPP_POP_MACROS
54
55#endif // _LIBCPP___ALGORITHM_FILL_H
lib/libcxx/include/__algorithm/fill_n.h created+47
......@@ -0,0 +1,47 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_FILL_N_H
10#define _LIBCPP___ALGORITHM_FILL_N_H
11
12#include <__config>
13#include <__iterator/iterator_traits.h>
14#include <type_traits>
15
16#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
17#pragma GCC system_header
18#endif
19
20_LIBCPP_PUSH_MACROS
21#include <__undef_macros>
22
23_LIBCPP_BEGIN_NAMESPACE_STD
24
25template <class _OutputIterator, class _Size, class _Tp>
26inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
27_OutputIterator
28__fill_n(_OutputIterator __first, _Size __n, const _Tp& __value_)
29{
30 for (; __n > 0; ++__first, (void) --__n)
31 *__first = __value_;
32 return __first;
33}
34
35template <class _OutputIterator, class _Size, class _Tp>
36inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
37_OutputIterator
38fill_n(_OutputIterator __first, _Size __n, const _Tp& __value_)
39{
40 return _VSTD::__fill_n(__first, _VSTD::__convert_to_integral(__n), __value_);
41}
42
43_LIBCPP_END_NAMESPACE_STD
44
45_LIBCPP_POP_MACROS
46
47#endif // _LIBCPP___ALGORITHM_FILL_N_H
lib/libcxx/include/__algorithm/find.h created+37
......@@ -0,0 +1,37 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___ALGORITHM_FIND_H
11#define _LIBCPP___ALGORITHM_FIND_H
12
13#include <__config>
14
15#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
16#pragma GCC system_header
17#endif
18
19_LIBCPP_PUSH_MACROS
20#include <__undef_macros>
21
22_LIBCPP_BEGIN_NAMESPACE_STD
23
24template <class _InputIterator, class _Tp>
25_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _InputIterator
26find(_InputIterator __first, _InputIterator __last, const _Tp& __value_) {
27 for (; __first != __last; ++__first)
28 if (*__first == __value_)
29 break;
30 return __first;
31}
32
33_LIBCPP_END_NAMESPACE_STD
34
35_LIBCPP_POP_MACROS
36
37#endif // _LIBCPP___ALGORITHM_FIND_H
lib/libcxx/include/__algorithm/find_end.h created+154
......@@ -0,0 +1,154 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___ALGORITHM_FIND_END_OF_H
11#define _LIBCPP___ALGORITHM_FIND_END_OF_H
12
13#include <__config>
14#include <__algorithm/comp.h>
15#include <__iterator/iterator_traits.h>
16#include <type_traits>
17
18#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
19#pragma GCC system_header
20#endif
21
22_LIBCPP_PUSH_MACROS
23#include <__undef_macros>
24
25_LIBCPP_BEGIN_NAMESPACE_STD
26
27template <class _BinaryPredicate, class _ForwardIterator1, class _ForwardIterator2>
28_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator1 __find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
29 _ForwardIterator2 __first2, _ForwardIterator2 __last2,
30 _BinaryPredicate __pred, forward_iterator_tag,
31 forward_iterator_tag) {
32 // modeled after search algorithm
33 _ForwardIterator1 __r = __last1; // __last1 is the "default" answer
34 if (__first2 == __last2)
35 return __r;
36 while (true) {
37 while (true) {
38 if (__first1 == __last1) // if source exhausted return last correct answer
39 return __r; // (or __last1 if never found)
40 if (__pred(*__first1, *__first2))
41 break;
42 ++__first1;
43 }
44 // *__first1 matches *__first2, now match elements after here
45 _ForwardIterator1 __m1 = __first1;
46 _ForwardIterator2 __m2 = __first2;
47 while (true) {
48 if (++__m2 == __last2) { // Pattern exhaused, record answer and search for another one
49 __r = __first1;
50 ++__first1;
51 break;
52 }
53 if (++__m1 == __last1) // Source exhausted, return last answer
54 return __r;
55 if (!__pred(*__m1, *__m2)) // mismatch, restart with a new __first
56 {
57 ++__first1;
58 break;
59 } // else there is a match, check next elements
60 }
61 }
62}
63
64template <class _BinaryPredicate, class _BidirectionalIterator1, class _BidirectionalIterator2>
65_LIBCPP_CONSTEXPR_AFTER_CXX17 _BidirectionalIterator1 __find_end(
66 _BidirectionalIterator1 __first1, _BidirectionalIterator1 __last1, _BidirectionalIterator2 __first2,
67 _BidirectionalIterator2 __last2, _BinaryPredicate __pred, bidirectional_iterator_tag, bidirectional_iterator_tag) {
68 // modeled after search algorithm (in reverse)
69 if (__first2 == __last2)
70 return __last1; // Everything matches an empty sequence
71 _BidirectionalIterator1 __l1 = __last1;
72 _BidirectionalIterator2 __l2 = __last2;
73 --__l2;
74 while (true) {
75 // Find last element in sequence 1 that matchs *(__last2-1), with a mininum of loop checks
76 while (true) {
77 if (__first1 == __l1) // return __last1 if no element matches *__first2
78 return __last1;
79 if (__pred(*--__l1, *__l2))
80 break;
81 }
82 // *__l1 matches *__l2, now match elements before here
83 _BidirectionalIterator1 __m1 = __l1;
84 _BidirectionalIterator2 __m2 = __l2;
85 while (true) {
86 if (__m2 == __first2) // If pattern exhausted, __m1 is the answer (works for 1 element pattern)
87 return __m1;
88 if (__m1 == __first1) // Otherwise if source exhaused, pattern not found
89 return __last1;
90 if (!__pred(*--__m1, *--__m2)) // if there is a mismatch, restart with a new __l1
91 {
92 break;
93 } // else there is a match, check next elements
94 }
95 }
96}
97
98template <class _BinaryPredicate, class _RandomAccessIterator1, class _RandomAccessIterator2>
99_LIBCPP_CONSTEXPR_AFTER_CXX11 _RandomAccessIterator1 __find_end(
100 _RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2,
101 _RandomAccessIterator2 __last2, _BinaryPredicate __pred, random_access_iterator_tag, random_access_iterator_tag) {
102 // Take advantage of knowing source and pattern lengths. Stop short when source is smaller than pattern
103 typename iterator_traits<_RandomAccessIterator2>::difference_type __len2 = __last2 - __first2;
104 if (__len2 == 0)
105 return __last1;
106 typename iterator_traits<_RandomAccessIterator1>::difference_type __len1 = __last1 - __first1;
107 if (__len1 < __len2)
108 return __last1;
109 const _RandomAccessIterator1 __s = __first1 + (__len2 - 1); // End of pattern match can't go before here
110 _RandomAccessIterator1 __l1 = __last1;
111 _RandomAccessIterator2 __l2 = __last2;
112 --__l2;
113 while (true) {
114 while (true) {
115 if (__s == __l1)
116 return __last1;
117 if (__pred(*--__l1, *__l2))
118 break;
119 }
120 _RandomAccessIterator1 __m1 = __l1;
121 _RandomAccessIterator2 __m2 = __l2;
122 while (true) {
123 if (__m2 == __first2)
124 return __m1;
125 // no need to check range on __m1 because __s guarantees we have enough source
126 if (!__pred(*--__m1, *--__m2)) {
127 break;
128 }
129 }
130 }
131}
132
133template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
134_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator1
135find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2,
136 _BinaryPredicate __pred) {
137 return _VSTD::__find_end<typename add_lvalue_reference<_BinaryPredicate>::type>(
138 __first1, __last1, __first2, __last2, __pred, typename iterator_traits<_ForwardIterator1>::iterator_category(),
139 typename iterator_traits<_ForwardIterator2>::iterator_category());
140}
141
142template <class _ForwardIterator1, class _ForwardIterator2>
143_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator1
144find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2) {
145 typedef typename iterator_traits<_ForwardIterator1>::value_type __v1;
146 typedef typename iterator_traits<_ForwardIterator2>::value_type __v2;
147 return _VSTD::find_end(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>());
148}
149
150_LIBCPP_END_NAMESPACE_STD
151
152_LIBCPP_POP_MACROS
153
154#endif // _LIBCPP___ALGORITHM_FIND_END_OF_H
lib/libcxx/include/__algorithm/find_first_of.h created+57
......@@ -0,0 +1,57 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___ALGORITHM_FIND_FIRST_OF_H
11#define _LIBCPP___ALGORITHM_FIND_FIRST_OF_H
12
13#include <__config>
14#include <__algorithm/comp.h>
15#include <__iterator/iterator_traits.h>
16
17#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
18#pragma GCC system_header
19#endif
20
21_LIBCPP_PUSH_MACROS
22#include <__undef_macros>
23
24_LIBCPP_BEGIN_NAMESPACE_STD
25
26template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
27_LIBCPP_CONSTEXPR_AFTER_CXX11 _ForwardIterator1 __find_first_of_ce(_ForwardIterator1 __first1,
28 _ForwardIterator1 __last1,
29 _ForwardIterator2 __first2,
30 _ForwardIterator2 __last2, _BinaryPredicate __pred) {
31 for (; __first1 != __last1; ++__first1)
32 for (_ForwardIterator2 __j = __first2; __j != __last2; ++__j)
33 if (__pred(*__first1, *__j))
34 return __first1;
35 return __last1;
36}
37
38template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
39_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator1
40find_first_of(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
41 _ForwardIterator2 __last2, _BinaryPredicate __pred) {
42 return _VSTD::__find_first_of_ce(__first1, __last1, __first2, __last2, __pred);
43}
44
45template <class _ForwardIterator1, class _ForwardIterator2>
46_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator1 find_first_of(
47 _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2) {
48 typedef typename iterator_traits<_ForwardIterator1>::value_type __v1;
49 typedef typename iterator_traits<_ForwardIterator2>::value_type __v2;
50 return _VSTD::__find_first_of_ce(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>());
51}
52
53_LIBCPP_END_NAMESPACE_STD
54
55_LIBCPP_POP_MACROS
56
57#endif // _LIBCPP___ALGORITHM_FIND_FIRST_OF_H
lib/libcxx/include/__algorithm/find_if.h created+37
......@@ -0,0 +1,37 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___ALGORITHM_FIND_IF_H
11#define _LIBCPP___ALGORITHM_FIND_IF_H
12
13#include <__config>
14
15#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
16#pragma GCC system_header
17#endif
18
19_LIBCPP_PUSH_MACROS
20#include <__undef_macros>
21
22_LIBCPP_BEGIN_NAMESPACE_STD
23
24template <class _InputIterator, class _Predicate>
25_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _InputIterator
26find_if(_InputIterator __first, _InputIterator __last, _Predicate __pred) {
27 for (; __first != __last; ++__first)
28 if (__pred(*__first))
29 break;
30 return __first;
31}
32
33_LIBCPP_END_NAMESPACE_STD
34
35_LIBCPP_POP_MACROS
36
37#endif // _LIBCPP___ALGORITHM_FIND_IF_H
lib/libcxx/include/__algorithm/find_if_not.h created+37
......@@ -0,0 +1,37 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___ALGORITHM_FIND_IF_NOT_H
11#define _LIBCPP___ALGORITHM_FIND_IF_NOT_H
12
13#include <__config>
14
15#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
16#pragma GCC system_header
17#endif
18
19_LIBCPP_PUSH_MACROS
20#include <__undef_macros>
21
22_LIBCPP_BEGIN_NAMESPACE_STD
23
24template <class _InputIterator, class _Predicate>
25_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _InputIterator
26find_if_not(_InputIterator __first, _InputIterator __last, _Predicate __pred) {
27 for (; __first != __last; ++__first)
28 if (!__pred(*__first))
29 break;
30 return __first;
31}
32
33_LIBCPP_END_NAMESPACE_STD
34
35_LIBCPP_POP_MACROS
36
37#endif // _LIBCPP___ALGORITHM_FIND_IF_NOT_H
lib/libcxx/include/__algorithm/for_each.h created+37
......@@ -0,0 +1,37 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___ALGORITHM_FOR_EACH_H
11#define _LIBCPP___ALGORITHM_FOR_EACH_H
12
13#include <__config>
14
15#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
16#pragma GCC system_header
17#endif
18
19_LIBCPP_PUSH_MACROS
20#include <__undef_macros>
21
22_LIBCPP_BEGIN_NAMESPACE_STD
23
24template <class _InputIterator, class _Function>
25inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _Function for_each(_InputIterator __first,
26 _InputIterator __last,
27 _Function __f) {
28 for (; __first != __last; ++__first)
29 __f(*__first);
30 return __f;
31}
32
33_LIBCPP_END_NAMESPACE_STD
34
35_LIBCPP_POP_MACROS
36
37#endif // _LIBCPP___ALGORITHM_FOR_EACH_H
lib/libcxx/include/__algorithm/for_each_n.h created+47
......@@ -0,0 +1,47 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___ALGORITHM_FOR_EACH_N_H
11#define _LIBCPP___ALGORITHM_FOR_EACH_N_H
12
13#include <__config>
14#include <type_traits>
15
16#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
17#pragma GCC system_header
18#endif
19
20_LIBCPP_PUSH_MACROS
21#include <__undef_macros>
22
23_LIBCPP_BEGIN_NAMESPACE_STD
24
25#if _LIBCPP_STD_VER > 14
26
27template <class _InputIterator, class _Size, class _Function>
28inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _InputIterator for_each_n(_InputIterator __first,
29 _Size __orig_n,
30 _Function __f) {
31 typedef decltype(_VSTD::__convert_to_integral(__orig_n)) _IntegralSize;
32 _IntegralSize __n = __orig_n;
33 while (__n > 0) {
34 __f(*__first);
35 ++__first;
36 --__n;
37 }
38 return __first;
39}
40
41#endif
42
43_LIBCPP_END_NAMESPACE_STD
44
45_LIBCPP_POP_MACROS
46
47#endif // _LIBCPP___ALGORITHM_FOR_EACH_N_H
lib/libcxx/include/__algorithm/generate.h created+36
......@@ -0,0 +1,36 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_GENERATE_H
10#define _LIBCPP___ALGORITHM_GENERATE_H
11
12#include <__config>
13
14#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
15#pragma GCC system_header
16#endif
17
18_LIBCPP_PUSH_MACROS
19#include <__undef_macros>
20
21_LIBCPP_BEGIN_NAMESPACE_STD
22
23template <class _ForwardIterator, class _Generator>
24inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
25void
26generate(_ForwardIterator __first, _ForwardIterator __last, _Generator __gen)
27{
28 for (; __first != __last; ++__first)
29 *__first = __gen();
30}
31
32_LIBCPP_END_NAMESPACE_STD
33
34_LIBCPP_POP_MACROS
35
36#endif // _LIBCPP___ALGORITHM_GENERATE_H
lib/libcxx/include/__algorithm/generate_n.h created+40
......@@ -0,0 +1,40 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_GENERATE_N_H
10#define _LIBCPP___ALGORITHM_GENERATE_N_H
11
12#include <__config>
13#include <type_traits>
14
15#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
16#pragma GCC system_header
17#endif
18
19_LIBCPP_PUSH_MACROS
20#include <__undef_macros>
21
22_LIBCPP_BEGIN_NAMESPACE_STD
23
24template <class _OutputIterator, class _Size, class _Generator>
25inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
26_OutputIterator
27generate_n(_OutputIterator __first, _Size __orig_n, _Generator __gen)
28{
29 typedef decltype(_VSTD::__convert_to_integral(__orig_n)) _IntegralSize;
30 _IntegralSize __n = __orig_n;
31 for (; __n > 0; ++__first, (void) --__n)
32 *__first = __gen();
33 return __first;
34}
35
36_LIBCPP_END_NAMESPACE_STD
37
38_LIBCPP_POP_MACROS
39
40#endif // _LIBCPP___ALGORITHM_GENERATE_N_H
lib/libcxx/include/__algorithm/half_positive.h created+54
......@@ -0,0 +1,54 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_HALF_POSITIVE_H
10#define _LIBCPP___ALGORITHM_HALF_POSITIVE_H
11
12#include <__config>
13#include <type_traits>
14
15#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
16#pragma GCC system_header
17#endif
18
19_LIBCPP_PUSH_MACROS
20#include <__undef_macros>
21
22_LIBCPP_BEGIN_NAMESPACE_STD
23
24// Perform division by two quickly for positive integers (llvm.org/PR39129)
25
26template <typename _Integral>
27_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
28typename enable_if
29<
30 is_integral<_Integral>::value,
31 _Integral
32>::type
33__half_positive(_Integral __value)
34{
35 return static_cast<_Integral>(static_cast<typename make_unsigned<_Integral>::type>(__value) / 2);
36}
37
38template <typename _Tp>
39_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
40typename enable_if
41<
42 !is_integral<_Tp>::value,
43 _Tp
44>::type
45__half_positive(_Tp __value)
46{
47 return __value / 2;
48}
49
50_LIBCPP_END_NAMESPACE_STD
51
52_LIBCPP_POP_MACROS
53
54#endif // _LIBCPP___ALGORITHM_HALF_POSITIVE_H
lib/libcxx/include/__algorithm/includes.h created+67
......@@ -0,0 +1,67 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_INCLUDES_H
10#define _LIBCPP___ALGORITHM_INCLUDES_H
11
12#include <__config>
13#include <__algorithm/comp.h>
14#include <__algorithm/comp_ref_type.h>
15#include <__iterator/iterator_traits.h>
16
17#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
18#pragma GCC system_header
19#endif
20
21_LIBCPP_PUSH_MACROS
22#include <__undef_macros>
23
24_LIBCPP_BEGIN_NAMESPACE_STD
25
26template <class _Compare, class _InputIterator1, class _InputIterator2>
27_LIBCPP_CONSTEXPR_AFTER_CXX17 bool
28__includes(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2,
29 _Compare __comp)
30{
31 for (; __first2 != __last2; ++__first1)
32 {
33 if (__first1 == __last1 || __comp(*__first2, *__first1))
34 return false;
35 if (!__comp(*__first1, *__first2))
36 ++__first2;
37 }
38 return true;
39}
40
41template <class _InputIterator1, class _InputIterator2, class _Compare>
42_LIBCPP_NODISCARD_EXT inline
43_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
44bool
45includes(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2,
46 _Compare __comp)
47{
48 typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
49 return _VSTD::__includes<_Comp_ref>(__first1, __last1, __first2, __last2, __comp);
50}
51
52template <class _InputIterator1, class _InputIterator2>
53_LIBCPP_NODISCARD_EXT inline
54_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
55bool
56includes(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2)
57{
58 return _VSTD::includes(__first1, __last1, __first2, __last2,
59 __less<typename iterator_traits<_InputIterator1>::value_type,
60 typename iterator_traits<_InputIterator2>::value_type>());
61}
62
63_LIBCPP_END_NAMESPACE_STD
64
65_LIBCPP_POP_MACROS
66
67#endif // _LIBCPP___ALGORITHM_INCLUDES_H
lib/libcxx/include/__algorithm/inplace_merge.h created+231
......@@ -0,0 +1,231 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_INPLACE_MERGE_H
10#define _LIBCPP___ALGORITHM_INPLACE_MERGE_H
11
12#include <__config>
13#include <__algorithm/comp_ref_type.h>
14#include <__algorithm/comp.h>
15#include <__algorithm/lower_bound.h>
16#include <__algorithm/min.h>
17#include <__algorithm/move.h>
18#include <__algorithm/rotate.h>
19#include <__algorithm/upper_bound.h>
20#include <__iterator/iterator_traits.h>
21#include <__utility/swap.h>
22#include <memory>
23
24#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
25#pragma GCC system_header
26#endif
27
28_LIBCPP_PUSH_MACROS
29#include <__undef_macros>
30
31_LIBCPP_BEGIN_NAMESPACE_STD
32
33template <class _Predicate>
34class __invert // invert the sense of a comparison
35{
36private:
37 _Predicate __p_;
38public:
39 _LIBCPP_INLINE_VISIBILITY __invert() {}
40
41 _LIBCPP_INLINE_VISIBILITY
42 explicit __invert(_Predicate __p) : __p_(__p) {}
43
44 template <class _T1>
45 _LIBCPP_INLINE_VISIBILITY
46 bool operator()(const _T1& __x) {return !__p_(__x);}
47
48 template <class _T1, class _T2>
49 _LIBCPP_INLINE_VISIBILITY
50 bool operator()(const _T1& __x, const _T2& __y) {return __p_(__y, __x);}
51};
52
53template <class _Compare, class _InputIterator1, class _InputIterator2,
54 class _OutputIterator>
55void __half_inplace_merge(_InputIterator1 __first1, _InputIterator1 __last1,
56 _InputIterator2 __first2, _InputIterator2 __last2,
57 _OutputIterator __result, _Compare __comp)
58{
59 for (; __first1 != __last1; ++__result)
60 {
61 if (__first2 == __last2)
62 {
63 _VSTD::move(__first1, __last1, __result);
64 return;
65 }
66
67 if (__comp(*__first2, *__first1))
68 {
69 *__result = _VSTD::move(*__first2);
70 ++__first2;
71 }
72 else
73 {
74 *__result = _VSTD::move(*__first1);
75 ++__first1;
76 }
77 }
78 // __first2 through __last2 are already in the right spot.
79}
80
81template <class _Compare, class _BidirectionalIterator>
82void
83__buffered_inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last,
84 _Compare __comp, typename iterator_traits<_BidirectionalIterator>::difference_type __len1,
85 typename iterator_traits<_BidirectionalIterator>::difference_type __len2,
86 typename iterator_traits<_BidirectionalIterator>::value_type* __buff)
87{
88 typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;
89 __destruct_n __d(0);
90 unique_ptr<value_type, __destruct_n&> __h2(__buff, __d);
91 if (__len1 <= __len2)
92 {
93 value_type* __p = __buff;
94 for (_BidirectionalIterator __i = __first; __i != __middle; __d.template __incr<value_type>(), (void) ++__i, (void) ++__p)
95 ::new ((void*)__p) value_type(_VSTD::move(*__i));
96 _VSTD::__half_inplace_merge<_Compare>(__buff, __p, __middle, __last, __first, __comp);
97 }
98 else
99 {
100 value_type* __p = __buff;
101 for (_BidirectionalIterator __i = __middle; __i != __last; __d.template __incr<value_type>(), (void) ++__i, (void) ++__p)
102 ::new ((void*)__p) value_type(_VSTD::move(*__i));
103 typedef reverse_iterator<_BidirectionalIterator> _RBi;
104 typedef reverse_iterator<value_type*> _Rv;
105 typedef __invert<_Compare> _Inverted;
106 _VSTD::__half_inplace_merge<_Inverted>(_Rv(__p), _Rv(__buff),
107 _RBi(__middle), _RBi(__first),
108 _RBi(__last), _Inverted(__comp));
109 }
110}
111
112template <class _Compare, class _BidirectionalIterator>
113void
114__inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last,
115 _Compare __comp, typename iterator_traits<_BidirectionalIterator>::difference_type __len1,
116 typename iterator_traits<_BidirectionalIterator>::difference_type __len2,
117 typename iterator_traits<_BidirectionalIterator>::value_type* __buff, ptrdiff_t __buff_size)
118{
119 typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type;
120 while (true)
121 {
122 // if __middle == __last, we're done
123 if (__len2 == 0)
124 return;
125 if (__len1 <= __buff_size || __len2 <= __buff_size)
126 return _VSTD::__buffered_inplace_merge<_Compare>
127 (__first, __middle, __last, __comp, __len1, __len2, __buff);
128 // shrink [__first, __middle) as much as possible (with no moves), returning if it shrinks to 0
129 for (; true; ++__first, (void) --__len1)
130 {
131 if (__len1 == 0)
132 return;
133 if (__comp(*__middle, *__first))
134 break;
135 }
136 // __first < __middle < __last
137 // *__first > *__middle
138 // partition [__first, __m1) [__m1, __middle) [__middle, __m2) [__m2, __last) such that
139 // all elements in:
140 // [__first, __m1) <= [__middle, __m2)
141 // [__middle, __m2) < [__m1, __middle)
142 // [__m1, __middle) <= [__m2, __last)
143 // and __m1 or __m2 is in the middle of its range
144 _BidirectionalIterator __m1; // "median" of [__first, __middle)
145 _BidirectionalIterator __m2; // "median" of [__middle, __last)
146 difference_type __len11; // distance(__first, __m1)
147 difference_type __len21; // distance(__middle, __m2)
148 // binary search smaller range
149 if (__len1 < __len2)
150 { // __len >= 1, __len2 >= 2
151 __len21 = __len2 / 2;
152 __m2 = __middle;
153 _VSTD::advance(__m2, __len21);
154 __m1 = _VSTD::__upper_bound<_Compare>(__first, __middle, *__m2, __comp);
155 __len11 = _VSTD::distance(__first, __m1);
156 }
157 else
158 {
159 if (__len1 == 1)
160 { // __len1 >= __len2 && __len2 > 0, therefore __len2 == 1
161 // It is known *__first > *__middle
162 swap(*__first, *__middle);
163 return;
164 }
165 // __len1 >= 2, __len2 >= 1
166 __len11 = __len1 / 2;
167 __m1 = __first;
168 _VSTD::advance(__m1, __len11);
169 __m2 = _VSTD::__lower_bound<_Compare>(__middle, __last, *__m1, __comp);
170 __len21 = _VSTD::distance(__middle, __m2);
171 }
172 difference_type __len12 = __len1 - __len11; // distance(__m1, __middle)
173 difference_type __len22 = __len2 - __len21; // distance(__m2, __last)
174 // [__first, __m1) [__m1, __middle) [__middle, __m2) [__m2, __last)
175 // swap middle two partitions
176 __middle = _VSTD::rotate(__m1, __middle, __m2);
177 // __len12 and __len21 now have swapped meanings
178 // merge smaller range with recursive call and larger with tail recursion elimination
179 if (__len11 + __len21 < __len12 + __len22)
180 {
181 _VSTD::__inplace_merge<_Compare>(__first, __m1, __middle, __comp, __len11, __len21, __buff, __buff_size);
182// _VSTD::__inplace_merge<_Compare>(__middle, __m2, __last, __comp, __len12, __len22, __buff, __buff_size);
183 __first = __middle;
184 __middle = __m2;
185 __len1 = __len12;
186 __len2 = __len22;
187 }
188 else
189 {
190 _VSTD::__inplace_merge<_Compare>(__middle, __m2, __last, __comp, __len12, __len22, __buff, __buff_size);
191// _VSTD::__inplace_merge<_Compare>(__first, __m1, __middle, __comp, __len11, __len21, __buff, __buff_size);
192 __last = __middle;
193 __middle = __m1;
194 __len1 = __len11;
195 __len2 = __len21;
196 }
197 }
198}
199
200template <class _BidirectionalIterator, class _Compare>
201inline _LIBCPP_INLINE_VISIBILITY
202void
203inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last,
204 _Compare __comp)
205{
206 typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;
207 typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type;
208 difference_type __len1 = _VSTD::distance(__first, __middle);
209 difference_type __len2 = _VSTD::distance(__middle, __last);
210 difference_type __buf_size = _VSTD::min(__len1, __len2);
211 pair<value_type*, ptrdiff_t> __buf = _VSTD::get_temporary_buffer<value_type>(__buf_size);
212 unique_ptr<value_type, __return_temporary_buffer> __h(__buf.first);
213 typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
214 return _VSTD::__inplace_merge<_Comp_ref>(__first, __middle, __last, __comp, __len1, __len2,
215 __buf.first, __buf.second);
216}
217
218template <class _BidirectionalIterator>
219inline _LIBCPP_INLINE_VISIBILITY
220void
221inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last)
222{
223 _VSTD::inplace_merge(__first, __middle, __last,
224 __less<typename iterator_traits<_BidirectionalIterator>::value_type>());
225}
226
227_LIBCPP_END_NAMESPACE_STD
228
229_LIBCPP_POP_MACROS
230
231#endif // _LIBCPP___ALGORITHM_INPLACE_MERGE_H
lib/libcxx/include/__algorithm/is_heap.h created+48
......@@ -0,0 +1,48 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_IS_HEAP_H
10#define _LIBCPP___ALGORITHM_IS_HEAP_H
11
12#include <__config>
13#include <__algorithm/comp.h>
14#include <__algorithm/is_heap_until.h>
15#include <__iterator/iterator_traits.h>
16
17#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
18#pragma GCC system_header
19#endif
20
21_LIBCPP_PUSH_MACROS
22#include <__undef_macros>
23
24_LIBCPP_BEGIN_NAMESPACE_STD
25
26template <class _RandomAccessIterator, class _Compare>
27_LIBCPP_NODISCARD_EXT inline
28_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
29bool
30is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
31{
32 return _VSTD::is_heap_until(__first, __last, __comp) == __last;
33}
34
35template<class _RandomAccessIterator>
36_LIBCPP_NODISCARD_EXT inline
37_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
38bool
39is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
40{
41 return _VSTD::is_heap(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
42}
43
44_LIBCPP_END_NAMESPACE_STD
45
46_LIBCPP_POP_MACROS
47
48#endif // _LIBCPP___ALGORITHM_IS_HEAP_H
lib/libcxx/include/__algorithm/is_heap_until.h created+65
......@@ -0,0 +1,65 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_IS_HEAP_UNTIL_H
10#define _LIBCPP___ALGORITHM_IS_HEAP_UNTIL_H
11
12#include <__config>
13#include <__algorithm/comp.h>
14#include <__iterator/iterator_traits.h>
15
16#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
17#pragma GCC system_header
18#endif
19
20_LIBCPP_PUSH_MACROS
21#include <__undef_macros>
22
23_LIBCPP_BEGIN_NAMESPACE_STD
24
25template <class _RandomAccessIterator, class _Compare>
26_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_AFTER_CXX17 _RandomAccessIterator
27is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
28{
29 typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
30 difference_type __len = __last - __first;
31 difference_type __p = 0;
32 difference_type __c = 1;
33 _RandomAccessIterator __pp = __first;
34 while (__c < __len)
35 {
36 _RandomAccessIterator __cp = __first + __c;
37 if (__comp(*__pp, *__cp))
38 return __cp;
39 ++__c;
40 ++__cp;
41 if (__c == __len)
42 return __last;
43 if (__comp(*__pp, *__cp))
44 return __cp;
45 ++__p;
46 ++__pp;
47 __c = 2 * __p + 1;
48 }
49 return __last;
50}
51
52template<class _RandomAccessIterator>
53_LIBCPP_NODISCARD_EXT inline
54_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
55_RandomAccessIterator
56is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last)
57{
58 return _VSTD::is_heap_until(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
59}
60
61_LIBCPP_END_NAMESPACE_STD
62
63_LIBCPP_POP_MACROS
64
65#endif // _LIBCPP___ALGORITHM_IS_HEAP_UNTIL_H
lib/libcxx/include/__algorithm/is_partitioned.h created+43
......@@ -0,0 +1,43 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_IS_PARTITIONED_H
10#define _LIBCPP___ALGORITHM_IS_PARTITIONED_H
11
12#include <__config>
13
14#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
15#pragma GCC system_header
16#endif
17
18_LIBCPP_PUSH_MACROS
19#include <__undef_macros>
20
21_LIBCPP_BEGIN_NAMESPACE_STD
22
23template <class _InputIterator, class _Predicate>
24_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_AFTER_CXX17 bool
25is_partitioned(_InputIterator __first, _InputIterator __last, _Predicate __pred)
26{
27 for (; __first != __last; ++__first)
28 if (!__pred(*__first))
29 break;
30 if ( __first == __last )
31 return true;
32 ++__first;
33 for (; __first != __last; ++__first)
34 if (__pred(*__first))
35 return false;
36 return true;
37}
38
39_LIBCPP_END_NAMESPACE_STD
40
41_LIBCPP_POP_MACROS
42
43#endif // _LIBCPP___ALGORITHM_IS_PARTITIONED_H
lib/libcxx/include/__algorithm/is_permutation.h created+168
......@@ -0,0 +1,168 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___ALGORITHM_IS_PERMUTATION_H
11#define _LIBCPP___ALGORITHM_IS_PERMUTATION_H
12
13#include <__algorithm/comp.h>
14#include <__config>
15#include <__iterator/iterator_traits.h>
16#include <__iterator/next.h>
17#include <iterator> // FIXME: replace with <__iterator/distance.h> when it lands
18
19#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
20#pragma GCC system_header
21#endif
22
23_LIBCPP_PUSH_MACROS
24#include <__undef_macros>
25
26_LIBCPP_BEGIN_NAMESPACE_STD
27
28template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
29_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_AFTER_CXX17 bool
30is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
31 _BinaryPredicate __pred) {
32 // shorten sequences as much as possible by lopping of any equal prefix
33 for (; __first1 != __last1; ++__first1, (void)++__first2)
34 if (!__pred(*__first1, *__first2))
35 break;
36 if (__first1 == __last1)
37 return true;
38
39 // __first1 != __last1 && *__first1 != *__first2
40 typedef typename iterator_traits<_ForwardIterator1>::difference_type _D1;
41 _D1 __l1 = _VSTD::distance(__first1, __last1);
42 if (__l1 == _D1(1))
43 return false;
44 _ForwardIterator2 __last2 = _VSTD::next(__first2, __l1);
45 // For each element in [f1, l1) see if there are the same number of
46 // equal elements in [f2, l2)
47 for (_ForwardIterator1 __i = __first1; __i != __last1; ++__i) {
48 // Have we already counted the number of *__i in [f1, l1)?
49 _ForwardIterator1 __match = __first1;
50 for (; __match != __i; ++__match)
51 if (__pred(*__match, *__i))
52 break;
53 if (__match == __i) {
54 // Count number of *__i in [f2, l2)
55 _D1 __c2 = 0;
56 for (_ForwardIterator2 __j = __first2; __j != __last2; ++__j)
57 if (__pred(*__i, *__j))
58 ++__c2;
59 if (__c2 == 0)
60 return false;
61 // Count number of *__i in [__i, l1) (we can start with 1)
62 _D1 __c1 = 1;
63 for (_ForwardIterator1 __j = _VSTD::next(__i); __j != __last1; ++__j)
64 if (__pred(*__i, *__j))
65 ++__c1;
66 if (__c1 != __c2)
67 return false;
68 }
69 }
70 return true;
71}
72
73template <class _ForwardIterator1, class _ForwardIterator2>
74_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool
75is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2) {
76 typedef typename iterator_traits<_ForwardIterator1>::value_type __v1;
77 typedef typename iterator_traits<_ForwardIterator2>::value_type __v2;
78 return _VSTD::is_permutation(__first1, __last1, __first2, __equal_to<__v1, __v2>());
79}
80
81#if _LIBCPP_STD_VER > 11
82template <class _BinaryPredicate, class _ForwardIterator1, class _ForwardIterator2>
83_LIBCPP_CONSTEXPR_AFTER_CXX17 bool
84__is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
85 _ForwardIterator2 __last2, _BinaryPredicate __pred, forward_iterator_tag, forward_iterator_tag) {
86 // shorten sequences as much as possible by lopping of any equal prefix
87 for (; __first1 != __last1 && __first2 != __last2; ++__first1, (void)++__first2)
88 if (!__pred(*__first1, *__first2))
89 break;
90 if (__first1 == __last1)
91 return __first2 == __last2;
92 else if (__first2 == __last2)
93 return false;
94
95 typedef typename iterator_traits<_ForwardIterator1>::difference_type _D1;
96 _D1 __l1 = _VSTD::distance(__first1, __last1);
97
98 typedef typename iterator_traits<_ForwardIterator2>::difference_type _D2;
99 _D2 __l2 = _VSTD::distance(__first2, __last2);
100 if (__l1 != __l2)
101 return false;
102
103 // For each element in [f1, l1) see if there are the same number of
104 // equal elements in [f2, l2)
105 for (_ForwardIterator1 __i = __first1; __i != __last1; ++__i) {
106 // Have we already counted the number of *__i in [f1, l1)?
107 _ForwardIterator1 __match = __first1;
108 for (; __match != __i; ++__match)
109 if (__pred(*__match, *__i))
110 break;
111 if (__match == __i) {
112 // Count number of *__i in [f2, l2)
113 _D1 __c2 = 0;
114 for (_ForwardIterator2 __j = __first2; __j != __last2; ++__j)
115 if (__pred(*__i, *__j))
116 ++__c2;
117 if (__c2 == 0)
118 return false;
119 // Count number of *__i in [__i, l1) (we can start with 1)
120 _D1 __c1 = 1;
121 for (_ForwardIterator1 __j = _VSTD::next(__i); __j != __last1; ++__j)
122 if (__pred(*__i, *__j))
123 ++__c1;
124 if (__c1 != __c2)
125 return false;
126 }
127 }
128 return true;
129}
130
131template <class _BinaryPredicate, class _RandomAccessIterator1, class _RandomAccessIterator2>
132_LIBCPP_CONSTEXPR_AFTER_CXX17 bool __is_permutation(_RandomAccessIterator1 __first1, _RandomAccessIterator2 __last1,
133 _RandomAccessIterator1 __first2, _RandomAccessIterator2 __last2,
134 _BinaryPredicate __pred, random_access_iterator_tag,
135 random_access_iterator_tag) {
136 if (_VSTD::distance(__first1, __last1) != _VSTD::distance(__first2, __last2))
137 return false;
138 return _VSTD::is_permutation<_RandomAccessIterator1, _RandomAccessIterator2,
139 typename add_lvalue_reference<_BinaryPredicate>::type>(__first1, __last1, __first2,
140 __pred);
141}
142
143template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
144_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool
145is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
146 _ForwardIterator2 __last2, _BinaryPredicate __pred) {
147 return _VSTD::__is_permutation<typename add_lvalue_reference<_BinaryPredicate>::type>(
148 __first1, __last1, __first2, __last2, __pred, typename iterator_traits<_ForwardIterator1>::iterator_category(),
149 typename iterator_traits<_ForwardIterator2>::iterator_category());
150}
151
152template <class _ForwardIterator1, class _ForwardIterator2>
153_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool
154is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
155 _ForwardIterator2 __last2) {
156 typedef typename iterator_traits<_ForwardIterator1>::value_type __v1;
157 typedef typename iterator_traits<_ForwardIterator2>::value_type __v2;
158 return _VSTD::__is_permutation(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>(),
159 typename iterator_traits<_ForwardIterator1>::iterator_category(),
160 typename iterator_traits<_ForwardIterator2>::iterator_category());
161}
162#endif
163
164_LIBCPP_END_NAMESPACE_STD
165
166_LIBCPP_POP_MACROS
167
168#endif // _LIBCPP___ALGORITHM_IS_PERMUTATION_H
lib/libcxx/include/__algorithm/is_sorted.h created+48
......@@ -0,0 +1,48 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_IS_SORTED_H
10#define _LIBCPP___ALGORITHM_IS_SORTED_H
11
12#include <__algorithm/comp.h>
13#include <__algorithm/is_sorted_until.h>
14#include <__config>
15#include <__iterator/iterator_traits.h>
16
17#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
18#pragma GCC system_header
19#endif
20
21_LIBCPP_PUSH_MACROS
22#include <__undef_macros>
23
24_LIBCPP_BEGIN_NAMESPACE_STD
25
26template <class _ForwardIterator, class _Compare>
27_LIBCPP_NODISCARD_EXT inline
28_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
29bool
30is_sorted(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
31{
32 return _VSTD::is_sorted_until(__first, __last, __comp) == __last;
33}
34
35template<class _ForwardIterator>
36_LIBCPP_NODISCARD_EXT inline
37_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
38bool
39is_sorted(_ForwardIterator __first, _ForwardIterator __last)
40{
41 return _VSTD::is_sorted(__first, __last, __less<typename iterator_traits<_ForwardIterator>::value_type>());
42}
43
44_LIBCPP_END_NAMESPACE_STD
45
46_LIBCPP_POP_MACROS
47
48#endif // _LIBCPP___ALGORITHM_IS_SORTED_H
lib/libcxx/include/__algorithm/is_sorted_until.h created+55
......@@ -0,0 +1,55 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_IS_SORTED_UNTIL_H
10#define _LIBCPP___ALGORITHM_IS_SORTED_UNTIL_H
11
12#include <__config>
13#include <__algorithm/comp.h>
14#include <__iterator/iterator_traits.h>
15
16#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
17#pragma GCC system_header
18#endif
19
20_LIBCPP_PUSH_MACROS
21#include <__undef_macros>
22
23_LIBCPP_BEGIN_NAMESPACE_STD
24
25template <class _ForwardIterator, class _Compare>
26_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator
27is_sorted_until(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
28{
29 if (__first != __last)
30 {
31 _ForwardIterator __i = __first;
32 while (++__i != __last)
33 {
34 if (__comp(*__i, *__first))
35 return __i;
36 __first = __i;
37 }
38 }
39 return __last;
40}
41
42template<class _ForwardIterator>
43_LIBCPP_NODISCARD_EXT inline
44_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
45_ForwardIterator
46is_sorted_until(_ForwardIterator __first, _ForwardIterator __last)
47{
48 return _VSTD::is_sorted_until(__first, __last, __less<typename iterator_traits<_ForwardIterator>::value_type>());
49}
50
51_LIBCPP_END_NAMESPACE_STD
52
53_LIBCPP_POP_MACROS
54
55#endif // _LIBCPP___ALGORITHM_IS_SORTED_UNTIL_H
lib/libcxx/include/__algorithm/iter_swap.h created+37
......@@ -0,0 +1,37 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_ITER_SWAP_H
10#define _LIBCPP___ALGORITHM_ITER_SWAP_H
11
12#include <__config>
13#include <__utility/declval.h>
14#include <__utility/swap.h>
15
16#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
17#pragma GCC system_header
18#endif
19
20_LIBCPP_PUSH_MACROS
21#include <__undef_macros>
22
23_LIBCPP_BEGIN_NAMESPACE_STD
24
25template <class _ForwardIterator1, class _ForwardIterator2>
26inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 void iter_swap(_ForwardIterator1 __a,
27 _ForwardIterator2 __b)
28 // _NOEXCEPT_(_NOEXCEPT_(swap(*__a, *__b)))
29 _NOEXCEPT_(_NOEXCEPT_(swap(*declval<_ForwardIterator1>(), *declval<_ForwardIterator2>()))) {
30 swap(*__a, *__b);
31}
32
33_LIBCPP_END_NAMESPACE_STD
34
35_LIBCPP_POP_MACROS
36
37#endif // _LIBCPP___ALGORITHM_ITER_SWAP_H
lib/libcxx/include/__algorithm/lexicographical_compare.h created+68
......@@ -0,0 +1,68 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_LEXICOGRAPHICAL_COMPARE_H
10#define _LIBCPP___ALGORITHM_LEXICOGRAPHICAL_COMPARE_H
11
12#include <__config>
13#include <__algorithm/comp.h>
14#include <__algorithm/comp_ref_type.h>
15#include <__iterator/iterator_traits.h>
16
17#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
18#pragma GCC system_header
19#endif
20
21_LIBCPP_PUSH_MACROS
22#include <__undef_macros>
23
24_LIBCPP_BEGIN_NAMESPACE_STD
25
26template <class _Compare, class _InputIterator1, class _InputIterator2>
27_LIBCPP_CONSTEXPR_AFTER_CXX17 bool
28__lexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1,
29 _InputIterator2 __first2, _InputIterator2 __last2, _Compare __comp)
30{
31 for (; __first2 != __last2; ++__first1, (void) ++__first2)
32 {
33 if (__first1 == __last1 || __comp(*__first1, *__first2))
34 return true;
35 if (__comp(*__first2, *__first1))
36 return false;
37 }
38 return false;
39}
40
41template <class _InputIterator1, class _InputIterator2, class _Compare>
42_LIBCPP_NODISCARD_EXT inline
43_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
44bool
45lexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1,
46 _InputIterator2 __first2, _InputIterator2 __last2, _Compare __comp)
47{
48 typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
49 return _VSTD::__lexicographical_compare<_Comp_ref>(__first1, __last1, __first2, __last2, __comp);
50}
51
52template <class _InputIterator1, class _InputIterator2>
53_LIBCPP_NODISCARD_EXT inline
54_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
55bool
56lexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1,
57 _InputIterator2 __first2, _InputIterator2 __last2)
58{
59 return _VSTD::lexicographical_compare(__first1, __last1, __first2, __last2,
60 __less<typename iterator_traits<_InputIterator1>::value_type,
61 typename iterator_traits<_InputIterator2>::value_type>());
62}
63
64_LIBCPP_END_NAMESPACE_STD
65
66_LIBCPP_POP_MACROS
67
68#endif // _LIBCPP___ALGORITHM_LEXICOGRAPHICAL_COMPARE_H
lib/libcxx/include/__algorithm/lower_bound.h created+72
......@@ -0,0 +1,72 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_LOWER_BOUND_H
10#define _LIBCPP___ALGORITHM_LOWER_BOUND_H
11
12#include <__config>
13#include <__algorithm/comp.h>
14#include <__algorithm/half_positive.h>
15#include <iterator>
16
17#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
18#pragma GCC system_header
19#endif
20
21_LIBCPP_PUSH_MACROS
22#include <__undef_macros>
23
24_LIBCPP_BEGIN_NAMESPACE_STD
25
26template <class _Compare, class _ForwardIterator, class _Tp>
27_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator
28__lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp)
29{
30 typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type;
31 difference_type __len = _VSTD::distance(__first, __last);
32 while (__len != 0)
33 {
34 difference_type __l2 = _VSTD::__half_positive(__len);
35 _ForwardIterator __m = __first;
36 _VSTD::advance(__m, __l2);
37 if (__comp(*__m, __value_))
38 {
39 __first = ++__m;
40 __len -= __l2 + 1;
41 }
42 else
43 __len = __l2;
44 }
45 return __first;
46}
47
48template <class _ForwardIterator, class _Tp, class _Compare>
49_LIBCPP_NODISCARD_EXT inline
50_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
51_ForwardIterator
52lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp)
53{
54 typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
55 return _VSTD::__lower_bound<_Comp_ref>(__first, __last, __value_, __comp);
56}
57
58template <class _ForwardIterator, class _Tp>
59_LIBCPP_NODISCARD_EXT inline
60_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
61_ForwardIterator
62lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_)
63{
64 return _VSTD::lower_bound(__first, __last, __value_,
65 __less<typename iterator_traits<_ForwardIterator>::value_type, _Tp>());
66}
67
68_LIBCPP_END_NAMESPACE_STD
69
70_LIBCPP_POP_MACROS
71
72#endif // _LIBCPP___ALGORITHM_LOWER_BOUND_H
lib/libcxx/include/__algorithm/make_heap.h created+64
......@@ -0,0 +1,64 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_MAKE_HEAP_H
10#define _LIBCPP___ALGORITHM_MAKE_HEAP_H
11
12#include <__config>
13#include <__algorithm/comp.h>
14#include <__algorithm/comp_ref_type.h>
15#include <__algorithm/sift_down.h>
16#include <__iterator/iterator_traits.h>
17
18#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
19#pragma GCC system_header
20#endif
21
22_LIBCPP_PUSH_MACROS
23#include <__undef_macros>
24
25_LIBCPP_BEGIN_NAMESPACE_STD
26
27template <class _Compare, class _RandomAccessIterator>
28_LIBCPP_CONSTEXPR_AFTER_CXX11 void
29__make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
30{
31 typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
32 difference_type __n = __last - __first;
33 if (__n > 1)
34 {
35 // start from the first parent, there is no need to consider children
36 for (difference_type __start = (__n - 2) / 2; __start >= 0; --__start)
37 {
38 _VSTD::__sift_down<_Compare>(__first, __last, __comp, __n, __first + __start);
39 }
40 }
41}
42
43template <class _RandomAccessIterator, class _Compare>
44inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
45void
46make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
47{
48 typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
49 _VSTD::__make_heap<_Comp_ref>(__first, __last, __comp);
50}
51
52template <class _RandomAccessIterator>
53inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
54void
55make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
56{
57 _VSTD::make_heap(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
58}
59
60_LIBCPP_END_NAMESPACE_STD
61
62_LIBCPP_POP_MACROS
63
64#endif // _LIBCPP___ALGORITHM_MAKE_HEAP_H
lib/libcxx/include/__algorithm/max.h created+70
......@@ -0,0 +1,70 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_MAX_H
10#define _LIBCPP___ALGORITHM_MAX_H
11
12#include <__config>
13#include <__algorithm/comp.h>
14#include <__algorithm/max_element.h>
15#include <initializer_list>
16
17#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
18#pragma GCC system_header
19#endif
20
21_LIBCPP_PUSH_MACROS
22#include <__undef_macros>
23
24_LIBCPP_BEGIN_NAMESPACE_STD
25
26template <class _Tp, class _Compare>
27_LIBCPP_NODISCARD_EXT inline
28_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
29const _Tp&
30max(const _Tp& __a, const _Tp& __b, _Compare __comp)
31{
32 return __comp(__a, __b) ? __b : __a;
33}
34
35template <class _Tp>
36_LIBCPP_NODISCARD_EXT inline
37_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
38const _Tp&
39max(const _Tp& __a, const _Tp& __b)
40{
41 return _VSTD::max(__a, __b, __less<_Tp>());
42}
43
44#ifndef _LIBCPP_CXX03_LANG
45
46template<class _Tp, class _Compare>
47_LIBCPP_NODISCARD_EXT inline
48_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
49_Tp
50max(initializer_list<_Tp> __t, _Compare __comp)
51{
52 return *_VSTD::max_element(__t.begin(), __t.end(), __comp);
53}
54
55template<class _Tp>
56_LIBCPP_NODISCARD_EXT inline
57_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
58_Tp
59max(initializer_list<_Tp> __t)
60{
61 return *_VSTD::max_element(__t.begin(), __t.end(), __less<_Tp>());
62}
63
64#endif // _LIBCPP_CXX03_LANG
65
66_LIBCPP_END_NAMESPACE_STD
67
68_LIBCPP_POP_MACROS
69
70#endif // _LIBCPP___ALGORITHM_MAX_H
lib/libcxx/include/__algorithm/max_element.h created+58
......@@ -0,0 +1,58 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_MAX_ELEMENT_H
10#define _LIBCPP___ALGORITHM_MAX_ELEMENT_H
11
12#include <__config>
13#include <__algorithm/comp.h>
14#include <__iterator/iterator_traits.h>
15
16#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
17#pragma GCC system_header
18#endif
19
20_LIBCPP_PUSH_MACROS
21#include <__undef_macros>
22
23_LIBCPP_BEGIN_NAMESPACE_STD
24
25template <class _ForwardIterator, class _Compare>
26_LIBCPP_NODISCARD_EXT inline
27_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
28_ForwardIterator
29max_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
30{
31 static_assert(__is_cpp17_forward_iterator<_ForwardIterator>::value,
32 "std::max_element requires a ForwardIterator");
33 if (__first != __last)
34 {
35 _ForwardIterator __i = __first;
36 while (++__i != __last)
37 if (__comp(*__first, *__i))
38 __first = __i;
39 }
40 return __first;
41}
42
43
44template <class _ForwardIterator>
45_LIBCPP_NODISCARD_EXT inline
46_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
47_ForwardIterator
48max_element(_ForwardIterator __first, _ForwardIterator __last)
49{
50 return _VSTD::max_element(__first, __last,
51 __less<typename iterator_traits<_ForwardIterator>::value_type>());
52}
53
54_LIBCPP_END_NAMESPACE_STD
55
56_LIBCPP_POP_MACROS
57
58#endif // _LIBCPP___ALGORITHM_MAX_ELEMENT_H
lib/libcxx/include/__algorithm/merge.h created+76
......@@ -0,0 +1,76 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_MERGE_H
10#define _LIBCPP___ALGORITHM_MERGE_H
11
12#include <__config>
13#include <__algorithm/comp.h>
14#include <__algorithm/comp_ref_type.h>
15#include <__algorithm/copy.h>
16#include <__iterator/iterator_traits.h>
17
18#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
19#pragma GCC system_header
20#endif
21
22_LIBCPP_PUSH_MACROS
23#include <__undef_macros>
24
25_LIBCPP_BEGIN_NAMESPACE_STD
26
27template <class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator>
28_LIBCPP_CONSTEXPR_AFTER_CXX17
29_OutputIterator
30__merge(_InputIterator1 __first1, _InputIterator1 __last1,
31 _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)
32{
33 for (; __first1 != __last1; ++__result)
34 {
35 if (__first2 == __last2)
36 return _VSTD::copy(__first1, __last1, __result);
37 if (__comp(*__first2, *__first1))
38 {
39 *__result = *__first2;
40 ++__first2;
41 }
42 else
43 {
44 *__result = *__first1;
45 ++__first1;
46 }
47 }
48 return _VSTD::copy(__first2, __last2, __result);
49}
50
51template <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _Compare>
52inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
53_OutputIterator
54merge(_InputIterator1 __first1, _InputIterator1 __last1,
55 _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)
56{
57 typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
58 return _VSTD::__merge<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp);
59}
60
61template <class _InputIterator1, class _InputIterator2, class _OutputIterator>
62inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
63_OutputIterator
64merge(_InputIterator1 __first1, _InputIterator1 __last1,
65 _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result)
66{
67 typedef typename iterator_traits<_InputIterator1>::value_type __v1;
68 typedef typename iterator_traits<_InputIterator2>::value_type __v2;
69 return _VSTD::merge(__first1, __last1, __first2, __last2, __result, __less<__v1, __v2>());
70}
71
72_LIBCPP_END_NAMESPACE_STD
73
74_LIBCPP_POP_MACROS
75
76#endif // _LIBCPP___ALGORITHM_MERGE_H
lib/libcxx/include/__algorithm/min.h created+70
......@@ -0,0 +1,70 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_MIN_H
10#define _LIBCPP___ALGORITHM_MIN_H
11
12#include <__config>
13#include <__algorithm/comp.h>
14#include <__algorithm/min_element.h>
15#include <initializer_list>
16
17#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
18#pragma GCC system_header
19#endif
20
21_LIBCPP_PUSH_MACROS
22#include <__undef_macros>
23
24_LIBCPP_BEGIN_NAMESPACE_STD
25
26template <class _Tp, class _Compare>
27_LIBCPP_NODISCARD_EXT inline
28_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
29const _Tp&
30min(const _Tp& __a, const _Tp& __b, _Compare __comp)
31{
32 return __comp(__b, __a) ? __b : __a;
33}
34
35template <class _Tp>
36_LIBCPP_NODISCARD_EXT inline
37_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
38const _Tp&
39min(const _Tp& __a, const _Tp& __b)
40{
41 return _VSTD::min(__a, __b, __less<_Tp>());
42}
43
44#ifndef _LIBCPP_CXX03_LANG
45
46template<class _Tp, class _Compare>
47_LIBCPP_NODISCARD_EXT inline
48_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
49_Tp
50min(initializer_list<_Tp> __t, _Compare __comp)
51{
52 return *_VSTD::min_element(__t.begin(), __t.end(), __comp);
53}
54
55template<class _Tp>
56_LIBCPP_NODISCARD_EXT inline
57_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
58_Tp
59min(initializer_list<_Tp> __t)
60{
61 return *_VSTD::min_element(__t.begin(), __t.end(), __less<_Tp>());
62}
63
64#endif // _LIBCPP_CXX03_LANG
65
66_LIBCPP_END_NAMESPACE_STD
67
68_LIBCPP_POP_MACROS
69
70#endif // _LIBCPP___ALGORITHM_MIN_H
lib/libcxx/include/__algorithm/min_element.h created+57
......@@ -0,0 +1,57 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_MIN_ELEMENT_H
10#define _LIBCPP___ALGORITHM_MIN_ELEMENT_H
11
12#include <__config>
13#include <__algorithm/comp.h>
14#include <__iterator/iterator_traits.h>
15
16#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
17#pragma GCC system_header
18#endif
19
20_LIBCPP_PUSH_MACROS
21#include <__undef_macros>
22
23_LIBCPP_BEGIN_NAMESPACE_STD
24
25template <class _ForwardIterator, class _Compare>
26_LIBCPP_NODISCARD_EXT inline
27_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
28_ForwardIterator
29min_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
30{
31 static_assert(__is_cpp17_forward_iterator<_ForwardIterator>::value,
32 "std::min_element requires a ForwardIterator");
33 if (__first != __last)
34 {
35 _ForwardIterator __i = __first;
36 while (++__i != __last)
37 if (__comp(*__i, *__first))
38 __first = __i;
39 }
40 return __first;
41}
42
43template <class _ForwardIterator>
44_LIBCPP_NODISCARD_EXT inline
45_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
46_ForwardIterator
47min_element(_ForwardIterator __first, _ForwardIterator __last)
48{
49 return _VSTD::min_element(__first, __last,
50 __less<typename iterator_traits<_ForwardIterator>::value_type>());
51}
52
53_LIBCPP_END_NAMESPACE_STD
54
55_LIBCPP_POP_MACROS
56
57#endif // _LIBCPP___ALGORITHM_MIN_ELEMENT_H
lib/libcxx/include/__algorithm/minmax.h created+101
......@@ -0,0 +1,101 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_MINMAX_H
10#define _LIBCPP___ALGORITHM_MINMAX_H
11
12#include <__config>
13#include <__algorithm/comp.h>
14#include <initializer_list>
15#include <utility>
16
17
18#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
19#pragma GCC system_header
20#endif
21
22_LIBCPP_PUSH_MACROS
23#include <__undef_macros>
24
25_LIBCPP_BEGIN_NAMESPACE_STD
26
27template<class _Tp, class _Compare>
28_LIBCPP_NODISCARD_EXT inline
29_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
30pair<const _Tp&, const _Tp&>
31minmax(const _Tp& __a, const _Tp& __b, _Compare __comp)
32{
33 return __comp(__b, __a) ? pair<const _Tp&, const _Tp&>(__b, __a) :
34 pair<const _Tp&, const _Tp&>(__a, __b);
35}
36
37template<class _Tp>
38_LIBCPP_NODISCARD_EXT inline
39_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
40pair<const _Tp&, const _Tp&>
41minmax(const _Tp& __a, const _Tp& __b)
42{
43 return _VSTD::minmax(__a, __b, __less<_Tp>());
44}
45
46#ifndef _LIBCPP_CXX03_LANG
47
48template<class _Tp, class _Compare>
49_LIBCPP_NODISCARD_EXT inline
50_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
51pair<_Tp, _Tp>
52minmax(initializer_list<_Tp> __t, _Compare __comp)
53{
54 typedef typename initializer_list<_Tp>::const_iterator _Iter;
55 _Iter __first = __t.begin();
56 _Iter __last = __t.end();
57 pair<_Tp, _Tp> __result(*__first, *__first);
58
59 ++__first;
60 if (__t.size() % 2 == 0)
61 {
62 if (__comp(*__first, __result.first))
63 __result.first = *__first;
64 else
65 __result.second = *__first;
66 ++__first;
67 }
68
69 while (__first != __last)
70 {
71 _Tp __prev = *__first++;
72 if (__comp(*__first, __prev)) {
73 if ( __comp(*__first, __result.first)) __result.first = *__first;
74 if (!__comp(__prev, __result.second)) __result.second = __prev;
75 }
76 else {
77 if ( __comp(__prev, __result.first)) __result.first = __prev;
78 if (!__comp(*__first, __result.second)) __result.second = *__first;
79 }
80
81 __first++;
82 }
83 return __result;
84}
85
86template<class _Tp>
87_LIBCPP_NODISCARD_EXT inline
88_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
89pair<_Tp, _Tp>
90minmax(initializer_list<_Tp> __t)
91{
92 return _VSTD::minmax(__t, __less<_Tp>());
93}
94
95#endif // _LIBCPP_CXX03_LANG
96
97_LIBCPP_END_NAMESPACE_STD
98
99_LIBCPP_POP_MACROS
100
101#endif // _LIBCPP___ALGORITHM_MINMAX_H
lib/libcxx/include/__algorithm/minmax_element.h created+90
......@@ -0,0 +1,90 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_MINMAX_ELEMENT_H
10#define _LIBCPP___ALGORITHM_MINMAX_ELEMENT_H
11
12#include <__config>
13#include <__algorithm/comp.h>
14#include <__iterator/iterator_traits.h>
15#include <utility>
16
17#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
18#pragma GCC system_header
19#endif
20
21_LIBCPP_PUSH_MACROS
22#include <__undef_macros>
23
24_LIBCPP_BEGIN_NAMESPACE_STD
25
26template <class _ForwardIterator, class _Compare>
27_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_AFTER_CXX11
28pair<_ForwardIterator, _ForwardIterator>
29minmax_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
30{
31 static_assert(__is_cpp17_forward_iterator<_ForwardIterator>::value,
32 "std::minmax_element requires a ForwardIterator");
33 pair<_ForwardIterator, _ForwardIterator> __result(__first, __first);
34 if (__first != __last)
35 {
36 if (++__first != __last)
37 {
38 if (__comp(*__first, *__result.first))
39 __result.first = __first;
40 else
41 __result.second = __first;
42 while (++__first != __last)
43 {
44 _ForwardIterator __i = __first;
45 if (++__first == __last)
46 {
47 if (__comp(*__i, *__result.first))
48 __result.first = __i;
49 else if (!__comp(*__i, *__result.second))
50 __result.second = __i;
51 break;
52 }
53 else
54 {
55 if (__comp(*__first, *__i))
56 {
57 if (__comp(*__first, *__result.first))
58 __result.first = __first;
59 if (!__comp(*__i, *__result.second))
60 __result.second = __i;
61 }
62 else
63 {
64 if (__comp(*__i, *__result.first))
65 __result.first = __i;
66 if (!__comp(*__first, *__result.second))
67 __result.second = __first;
68 }
69 }
70 }
71 }
72 }
73 return __result;
74}
75
76template <class _ForwardIterator>
77_LIBCPP_NODISCARD_EXT inline
78_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
79pair<_ForwardIterator, _ForwardIterator>
80minmax_element(_ForwardIterator __first, _ForwardIterator __last)
81{
82 return _VSTD::minmax_element(__first, __last,
83 __less<typename iterator_traits<_ForwardIterator>::value_type>());
84}
85
86_LIBCPP_END_NAMESPACE_STD
87
88_LIBCPP_POP_MACROS
89
90#endif // _LIBCPP___ALGORITHM_MINMAX_ELEMENT_H
lib/libcxx/include/__algorithm/mismatch.h created+72
......@@ -0,0 +1,72 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___ALGORITHM_MISMATCH_H
11#define _LIBCPP___ALGORITHM_MISMATCH_H
12
13#include <__config>
14#include <__algorithm/comp.h>
15#include <__iterator/iterator_traits.h>
16#include <utility>
17
18#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
19#pragma GCC system_header
20#endif
21
22_LIBCPP_PUSH_MACROS
23#include <__undef_macros>
24
25_LIBCPP_BEGIN_NAMESPACE_STD
26
27template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate>
28_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY
29 _LIBCPP_CONSTEXPR_AFTER_CXX17 pair<_InputIterator1, _InputIterator2>
30 mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _BinaryPredicate __pred) {
31 for (; __first1 != __last1; ++__first1, (void)++__first2)
32 if (!__pred(*__first1, *__first2))
33 break;
34 return pair<_InputIterator1, _InputIterator2>(__first1, __first2);
35}
36
37template <class _InputIterator1, class _InputIterator2>
38_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY
39 _LIBCPP_CONSTEXPR_AFTER_CXX17 pair<_InputIterator1, _InputIterator2>
40 mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2) {
41 typedef typename iterator_traits<_InputIterator1>::value_type __v1;
42 typedef typename iterator_traits<_InputIterator2>::value_type __v2;
43 return _VSTD::mismatch(__first1, __last1, __first2, __equal_to<__v1, __v2>());
44}
45
46#if _LIBCPP_STD_VER > 11
47template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate>
48_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY
49 _LIBCPP_CONSTEXPR_AFTER_CXX17 pair<_InputIterator1, _InputIterator2>
50 mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2,
51 _BinaryPredicate __pred) {
52 for (; __first1 != __last1 && __first2 != __last2; ++__first1, (void)++__first2)
53 if (!__pred(*__first1, *__first2))
54 break;
55 return pair<_InputIterator1, _InputIterator2>(__first1, __first2);
56}
57
58template <class _InputIterator1, class _InputIterator2>
59_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY
60 _LIBCPP_CONSTEXPR_AFTER_CXX17 pair<_InputIterator1, _InputIterator2>
61 mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) {
62 typedef typename iterator_traits<_InputIterator1>::value_type __v1;
63 typedef typename iterator_traits<_InputIterator2>::value_type __v2;
64 return _VSTD::mismatch(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>());
65}
66#endif
67
68_LIBCPP_END_NAMESPACE_STD
69
70_LIBCPP_POP_MACROS
71
72#endif // _LIBCPP___ALGORITHM_MISMATCH_H
lib/libcxx/include/__algorithm/move.h created+83
......@@ -0,0 +1,83 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_MOVE_H
10#define _LIBCPP___ALGORITHM_MOVE_H
11
12#include <__config>
13#include <__algorithm/unwrap_iter.h>
14#include <__utility/move.h>
15#include <cstring>
16#include <utility>
17#include <type_traits>
18
19#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
20#pragma GCC system_header
21#endif
22
23_LIBCPP_PUSH_MACROS
24#include <__undef_macros>
25
26_LIBCPP_BEGIN_NAMESPACE_STD
27
28// move
29
30template <class _InputIterator, class _OutputIterator>
31inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
32_OutputIterator
33__move_constexpr(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
34{
35 for (; __first != __last; ++__first, (void) ++__result)
36 *__result = _VSTD::move(*__first);
37 return __result;
38}
39
40template <class _InputIterator, class _OutputIterator>
41inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
42_OutputIterator
43__move(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
44{
45 return _VSTD::__move_constexpr(__first, __last, __result);
46}
47
48template <class _Tp, class _Up>
49inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
50typename enable_if
51<
52 is_same<typename remove_const<_Tp>::type, _Up>::value &&
53 is_trivially_move_assignable<_Up>::value,
54 _Up*
55>::type
56__move(_Tp* __first, _Tp* __last, _Up* __result)
57{
58 const size_t __n = static_cast<size_t>(__last - __first);
59 if (__n > 0)
60 _VSTD::memmove(__result, __first, __n * sizeof(_Up));
61 return __result + __n;
62}
63
64template <class _InputIterator, class _OutputIterator>
65inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
66_OutputIterator
67move(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
68{
69 if (__libcpp_is_constant_evaluated()) {
70 return _VSTD::__move_constexpr(__first, __last, __result);
71 } else {
72 return _VSTD::__rewrap_iter(__result,
73 _VSTD::__move(_VSTD::__unwrap_iter(__first),
74 _VSTD::__unwrap_iter(__last),
75 _VSTD::__unwrap_iter(__result)));
76 }
77}
78
79_LIBCPP_END_NAMESPACE_STD
80
81_LIBCPP_POP_MACROS
82
83#endif // _LIBCPP___ALGORITHM_MOVE_H
lib/libcxx/include/__algorithm/move_backward.h created+84
......@@ -0,0 +1,84 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_MOVE_BACKWARD_H
10#define _LIBCPP___ALGORITHM_MOVE_BACKWARD_H
11
12#include <__config>
13#include <__algorithm/unwrap_iter.h>
14#include <cstring>
15#include <utility>
16#include <type_traits>
17
18#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
19#pragma GCC system_header
20#endif
21
22_LIBCPP_PUSH_MACROS
23#include <__undef_macros>
24
25_LIBCPP_BEGIN_NAMESPACE_STD
26
27template <class _InputIterator, class _OutputIterator>
28inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
29_OutputIterator
30__move_backward_constexpr(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
31{
32 while (__first != __last)
33 *--__result = _VSTD::move(*--__last);
34 return __result;
35}
36
37template <class _InputIterator, class _OutputIterator>
38inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
39_OutputIterator
40__move_backward(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
41{
42 return _VSTD::__move_backward_constexpr(__first, __last, __result);
43}
44
45template <class _Tp, class _Up>
46inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
47typename enable_if
48<
49 is_same<typename remove_const<_Tp>::type, _Up>::value &&
50 is_trivially_move_assignable<_Up>::value,
51 _Up*
52>::type
53__move_backward(_Tp* __first, _Tp* __last, _Up* __result)
54{
55 const size_t __n = static_cast<size_t>(__last - __first);
56 if (__n > 0)
57 {
58 __result -= __n;
59 _VSTD::memmove(__result, __first, __n * sizeof(_Up));
60 }
61 return __result;
62}
63
64template <class _BidirectionalIterator1, class _BidirectionalIterator2>
65inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
66_BidirectionalIterator2
67move_backward(_BidirectionalIterator1 __first, _BidirectionalIterator1 __last,
68 _BidirectionalIterator2 __result)
69{
70 if (__libcpp_is_constant_evaluated()) {
71 return _VSTD::__move_backward_constexpr(__first, __last, __result);
72 } else {
73 return _VSTD::__rewrap_iter(__result,
74 _VSTD::__move_backward(_VSTD::__unwrap_iter(__first),
75 _VSTD::__unwrap_iter(__last),
76 _VSTD::__unwrap_iter(__result)));
77 }
78}
79
80_LIBCPP_END_NAMESPACE_STD
81
82_LIBCPP_POP_MACROS
83
84#endif // _LIBCPP___ALGORITHM_MOVE_BACKWARD_H
lib/libcxx/include/__algorithm/next_permutation.h created+77
......@@ -0,0 +1,77 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_NEXT_PERMUTATION_H
10#define _LIBCPP___ALGORITHM_NEXT_PERMUTATION_H
11
12#include <__config>
13#include <__algorithm/comp.h>
14#include <__algorithm/comp_ref_type.h>
15#include <__algorithm/reverse.h>
16#include <__iterator/iterator_traits.h>
17#include <__utility/swap.h>
18
19#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
20#pragma GCC system_header
21#endif
22
23_LIBCPP_PUSH_MACROS
24#include <__undef_macros>
25
26_LIBCPP_BEGIN_NAMESPACE_STD
27
28template <class _Compare, class _BidirectionalIterator>
29_LIBCPP_CONSTEXPR_AFTER_CXX17 bool
30__next_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp)
31{
32 _BidirectionalIterator __i = __last;
33 if (__first == __last || __first == --__i)
34 return false;
35 while (true)
36 {
37 _BidirectionalIterator __ip1 = __i;
38 if (__comp(*--__i, *__ip1))
39 {
40 _BidirectionalIterator __j = __last;
41 while (!__comp(*__i, *--__j))
42 ;
43 swap(*__i, *__j);
44 _VSTD::reverse(__ip1, __last);
45 return true;
46 }
47 if (__i == __first)
48 {
49 _VSTD::reverse(__first, __last);
50 return false;
51 }
52 }
53}
54
55template <class _BidirectionalIterator, class _Compare>
56inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
57bool
58next_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp)
59{
60 typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
61 return _VSTD::__next_permutation<_Comp_ref>(__first, __last, __comp);
62}
63
64template <class _BidirectionalIterator>
65inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
66bool
67next_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last)
68{
69 return _VSTD::next_permutation(__first, __last,
70 __less<typename iterator_traits<_BidirectionalIterator>::value_type>());
71}
72
73_LIBCPP_END_NAMESPACE_STD
74
75_LIBCPP_POP_MACROS
76
77#endif // _LIBCPP___ALGORITHM_NEXT_PERMUTATION_H
lib/libcxx/include/__algorithm/none_of.h created+37
......@@ -0,0 +1,37 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___ALGORITHM_NONE_OF_H
11#define _LIBCPP___ALGORITHM_NONE_OF_H
12
13#include <__config>
14
15#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
16#pragma GCC system_header
17#endif
18
19_LIBCPP_PUSH_MACROS
20#include <__undef_macros>
21
22_LIBCPP_BEGIN_NAMESPACE_STD
23
24template <class _InputIterator, class _Predicate>
25_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool
26none_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) {
27 for (; __first != __last; ++__first)
28 if (__pred(*__first))
29 return false;
30 return true;
31}
32
33_LIBCPP_END_NAMESPACE_STD
34
35_LIBCPP_POP_MACROS
36
37#endif // _LIBCPP___ALGORITHM_NONE_OF_H
lib/libcxx/include/__algorithm/nth_element.h created+244
......@@ -0,0 +1,244 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_NTH_ELEMENT_H
10#define _LIBCPP___ALGORITHM_NTH_ELEMENT_H
11
12#include <__config>
13#include <__algorithm/comp.h>
14#include <__algorithm/comp_ref_type.h>
15#include <__algorithm/sort.h>
16#include <__iterator/iterator_traits.h>
17#include <__utility/swap.h>
18
19#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
20#pragma GCC system_header
21#endif
22
23_LIBCPP_PUSH_MACROS
24#include <__undef_macros>
25
26_LIBCPP_BEGIN_NAMESPACE_STD
27
28template<class _Compare, class _RandomAccessIterator>
29_LIBCPP_CONSTEXPR_AFTER_CXX11 bool
30__nth_element_find_guard(_RandomAccessIterator& __i, _RandomAccessIterator& __j,
31 _RandomAccessIterator __m, _Compare __comp)
32{
33 // manually guard downward moving __j against __i
34 while (true) {
35 if (__i == --__j) {
36 return false;
37 }
38 if (__comp(*__j, *__m)) {
39 return true; // found guard for downward moving __j, now use unguarded partition
40 }
41 }
42}
43
44template <class _Compare, class _RandomAccessIterator>
45_LIBCPP_CONSTEXPR_AFTER_CXX11 void
46__nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last, _Compare __comp)
47{
48 // _Compare is known to be a reference type
49 typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
50 const difference_type __limit = 7;
51 while (true)
52 {
53 if (__nth == __last)
54 return;
55 difference_type __len = __last - __first;
56 switch (__len)
57 {
58 case 0:
59 case 1:
60 return;
61 case 2:
62 if (__comp(*--__last, *__first))
63 swap(*__first, *__last);
64 return;
65 case 3:
66 {
67 _RandomAccessIterator __m = __first;
68 _VSTD::__sort3<_Compare>(__first, ++__m, --__last, __comp);
69 return;
70 }
71 }
72 if (__len <= __limit)
73 {
74 _VSTD::__selection_sort<_Compare>(__first, __last, __comp);
75 return;
76 }
77 // __len > __limit >= 3
78 _RandomAccessIterator __m = __first + __len/2;
79 _RandomAccessIterator __lm1 = __last;
80 unsigned __n_swaps = _VSTD::__sort3<_Compare>(__first, __m, --__lm1, __comp);
81 // *__m is median
82 // partition [__first, __m) < *__m and *__m <= [__m, __last)
83 // (this inhibits tossing elements equivalent to __m around unnecessarily)
84 _RandomAccessIterator __i = __first;
85 _RandomAccessIterator __j = __lm1;
86 // j points beyond range to be tested, *__lm1 is known to be <= *__m
87 // The search going up is known to be guarded but the search coming down isn't.
88 // Prime the downward search with a guard.
89 if (!__comp(*__i, *__m)) // if *__first == *__m
90 {
91 // *__first == *__m, *__first doesn't go in first part
92 if (_VSTD::__nth_element_find_guard<_Compare>(__i, __j, __m, __comp)) {
93 swap(*__i, *__j);
94 ++__n_swaps;
95 } else {
96 // *__first == *__m, *__m <= all other elements
97 // Partition instead into [__first, __i) == *__first and *__first < [__i, __last)
98 ++__i; // __first + 1
99 __j = __last;
100 if (!__comp(*__first, *--__j)) { // we need a guard if *__first == *(__last-1)
101 while (true) {
102 if (__i == __j) {
103 return; // [__first, __last) all equivalent elements
104 } else if (__comp(*__first, *__i)) {
105 swap(*__i, *__j);
106 ++__n_swaps;
107 ++__i;
108 break;
109 }
110 ++__i;
111 }
112 }
113 // [__first, __i) == *__first and *__first < [__j, __last) and __j == __last - 1
114 if (__i == __j) {
115 return;
116 }
117 while (true) {
118 while (!__comp(*__first, *__i))
119 ++__i;
120 while (__comp(*__first, *--__j))
121 ;
122 if (__i >= __j)
123 break;
124 swap(*__i, *__j);
125 ++__n_swaps;
126 ++__i;
127 }
128 // [__first, __i) == *__first and *__first < [__i, __last)
129 // The first part is sorted,
130 if (__nth < __i) {
131 return;
132 }
133 // __nth_element the second part
134 // _VSTD::__nth_element<_Compare>(__i, __nth, __last, __comp);
135 __first = __i;
136 continue;
137 }
138 }
139 ++__i;
140 // j points beyond range to be tested, *__lm1 is known to be <= *__m
141 // if not yet partitioned...
142 if (__i < __j)
143 {
144 // known that *(__i - 1) < *__m
145 while (true)
146 {
147 // __m still guards upward moving __i
148 while (__comp(*__i, *__m))
149 ++__i;
150 // It is now known that a guard exists for downward moving __j
151 while (!__comp(*--__j, *__m))
152 ;
153 if (__i >= __j)
154 break;
155 swap(*__i, *__j);
156 ++__n_swaps;
157 // It is known that __m != __j
158 // If __m just moved, follow it
159 if (__m == __i)
160 __m = __j;
161 ++__i;
162 }
163 }
164 // [__first, __i) < *__m and *__m <= [__i, __last)
165 if (__i != __m && __comp(*__m, *__i))
166 {
167 swap(*__i, *__m);
168 ++__n_swaps;
169 }
170 // [__first, __i) < *__i and *__i <= [__i+1, __last)
171 if (__nth == __i)
172 return;
173 if (__n_swaps == 0)
174 {
175 // We were given a perfectly partitioned sequence. Coincidence?
176 if (__nth < __i)
177 {
178 // Check for [__first, __i) already sorted
179 __j = __m = __first;
180 while (true) {
181 if (++__j == __i) {
182 // [__first, __i) sorted
183 return;
184 }
185 if (__comp(*__j, *__m)) {
186 // not yet sorted, so sort
187 break;
188 }
189 __m = __j;
190 }
191 }
192 else
193 {
194 // Check for [__i, __last) already sorted
195 __j = __m = __i;
196 while (true) {
197 if (++__j == __last) {
198 // [__i, __last) sorted
199 return;
200 }
201 if (__comp(*__j, *__m)) {
202 // not yet sorted, so sort
203 break;
204 }
205 __m = __j;
206 }
207 }
208 }
209 // __nth_element on range containing __nth
210 if (__nth < __i)
211 {
212 // _VSTD::__nth_element<_Compare>(__first, __nth, __i, __comp);
213 __last = __i;
214 }
215 else
216 {
217 // _VSTD::__nth_element<_Compare>(__i+1, __nth, __last, __comp);
218 __first = ++__i;
219 }
220 }
221}
222
223template <class _RandomAccessIterator, class _Compare>
224inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
225void
226nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last, _Compare __comp)
227{
228 typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
229 _VSTD::__nth_element<_Comp_ref>(__first, __nth, __last, __comp);
230}
231
232template <class _RandomAccessIterator>
233inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
234void
235nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last)
236{
237 _VSTD::nth_element(__first, __nth, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
238}
239
240_LIBCPP_END_NAMESPACE_STD
241
242_LIBCPP_POP_MACROS
243
244#endif // _LIBCPP___ALGORITHM_NTH_ELEMENT_H
lib/libcxx/include/__algorithm/partial_sort.h created+71
......@@ -0,0 +1,71 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_PARTIAL_SORT_H
10#define _LIBCPP___ALGORITHM_PARTIAL_SORT_H
11
12#include <__config>
13#include <__algorithm/comp.h>
14#include <__algorithm/comp_ref_type.h>
15#include <__algorithm/make_heap.h>
16#include <__algorithm/sift_down.h>
17#include <__algorithm/sort_heap.h>
18#include <__iterator/iterator_traits.h>
19#include <__utility/swap.h>
20
21#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
22#pragma GCC system_header
23#endif
24
25_LIBCPP_PUSH_MACROS
26#include <__undef_macros>
27
28_LIBCPP_BEGIN_NAMESPACE_STD
29
30template <class _Compare, class _RandomAccessIterator>
31_LIBCPP_CONSTEXPR_AFTER_CXX17 void
32__partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last,
33 _Compare __comp)
34{
35 _VSTD::__make_heap<_Compare>(__first, __middle, __comp);
36 typename iterator_traits<_RandomAccessIterator>::difference_type __len = __middle - __first;
37 for (_RandomAccessIterator __i = __middle; __i != __last; ++__i)
38 {
39 if (__comp(*__i, *__first))
40 {
41 swap(*__i, *__first);
42 _VSTD::__sift_down<_Compare>(__first, __middle, __comp, __len, __first);
43 }
44 }
45 _VSTD::__sort_heap<_Compare>(__first, __middle, __comp);
46}
47
48template <class _RandomAccessIterator, class _Compare>
49inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
50void
51partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last,
52 _Compare __comp)
53{
54 typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
55 _VSTD::__partial_sort<_Comp_ref>(__first, __middle, __last, __comp);
56}
57
58template <class _RandomAccessIterator>
59inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
60void
61partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last)
62{
63 _VSTD::partial_sort(__first, __middle, __last,
64 __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
65}
66
67_LIBCPP_END_NAMESPACE_STD
68
69_LIBCPP_POP_MACROS
70
71#endif // _LIBCPP___ALGORITHM_PARTIAL_SORT_H
lib/libcxx/include/__algorithm/partial_sort_copy.h created+77
......@@ -0,0 +1,77 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_PARTIAL_SORT_COPY_H
10#define _LIBCPP___ALGORITHM_PARTIAL_SORT_COPY_H
11
12#include <__config>
13#include <__algorithm/comp.h>
14#include <__algorithm/comp_ref_type.h>
15#include <__algorithm/make_heap.h>
16#include <__algorithm/sift_down.h>
17#include <__algorithm/sort_heap.h>
18#include <__iterator/iterator_traits.h>
19#include <type_traits> // swap
20
21#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
22#pragma GCC system_header
23#endif
24
25_LIBCPP_PUSH_MACROS
26#include <__undef_macros>
27
28_LIBCPP_BEGIN_NAMESPACE_STD
29
30template <class _Compare, class _InputIterator, class _RandomAccessIterator>
31_LIBCPP_CONSTEXPR_AFTER_CXX17 _RandomAccessIterator
32__partial_sort_copy(_InputIterator __first, _InputIterator __last,
33 _RandomAccessIterator __result_first, _RandomAccessIterator __result_last, _Compare __comp)
34{
35 _RandomAccessIterator __r = __result_first;
36 if (__r != __result_last)
37 {
38 for (; __first != __last && __r != __result_last; ++__first, (void) ++__r)
39 *__r = *__first;
40 _VSTD::__make_heap<_Compare>(__result_first, __r, __comp);
41 typename iterator_traits<_RandomAccessIterator>::difference_type __len = __r - __result_first;
42 for (; __first != __last; ++__first)
43 if (__comp(*__first, *__result_first))
44 {
45 *__result_first = *__first;
46 _VSTD::__sift_down<_Compare>(__result_first, __r, __comp, __len, __result_first);
47 }
48 _VSTD::__sort_heap<_Compare>(__result_first, __r, __comp);
49 }
50 return __r;
51}
52
53template <class _InputIterator, class _RandomAccessIterator, class _Compare>
54inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
55_RandomAccessIterator
56partial_sort_copy(_InputIterator __first, _InputIterator __last,
57 _RandomAccessIterator __result_first, _RandomAccessIterator __result_last, _Compare __comp)
58{
59 typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
60 return _VSTD::__partial_sort_copy<_Comp_ref>(__first, __last, __result_first, __result_last, __comp);
61}
62
63template <class _InputIterator, class _RandomAccessIterator>
64inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
65_RandomAccessIterator
66partial_sort_copy(_InputIterator __first, _InputIterator __last,
67 _RandomAccessIterator __result_first, _RandomAccessIterator __result_last)
68{
69 return _VSTD::partial_sort_copy(__first, __last, __result_first, __result_last,
70 __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
71}
72
73_LIBCPP_END_NAMESPACE_STD
74
75_LIBCPP_POP_MACROS
76
77#endif // _LIBCPP___ALGORITHM_PARTIAL_SORT_COPY_H
lib/libcxx/include/__algorithm/partition.h created+88
......@@ -0,0 +1,88 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_PARTITION_H
10#define _LIBCPP___ALGORITHM_PARTITION_H
11
12#include <__config>
13#include <__iterator/iterator_traits.h>
14#include <__utility/swap.h>
15#include <utility> // pair
16#include <type_traits>
17
18#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
19#pragma GCC system_header
20#endif
21
22_LIBCPP_PUSH_MACROS
23#include <__undef_macros>
24
25_LIBCPP_BEGIN_NAMESPACE_STD
26
27template <class _Predicate, class _ForwardIterator>
28_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator
29__partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, forward_iterator_tag)
30{
31 while (true)
32 {
33 if (__first == __last)
34 return __first;
35 if (!__pred(*__first))
36 break;
37 ++__first;
38 }
39 for (_ForwardIterator __p = __first; ++__p != __last;)
40 {
41 if (__pred(*__p))
42 {
43 swap(*__first, *__p);
44 ++__first;
45 }
46 }
47 return __first;
48}
49
50template <class _Predicate, class _BidirectionalIterator>
51_LIBCPP_CONSTEXPR_AFTER_CXX17 _BidirectionalIterator
52__partition(_BidirectionalIterator __first, _BidirectionalIterator __last, _Predicate __pred,
53 bidirectional_iterator_tag)
54{
55 while (true)
56 {
57 while (true)
58 {
59 if (__first == __last)
60 return __first;
61 if (!__pred(*__first))
62 break;
63 ++__first;
64 }
65 do
66 {
67 if (__first == --__last)
68 return __first;
69 } while (!__pred(*__last));
70 swap(*__first, *__last);
71 ++__first;
72 }
73}
74
75template <class _ForwardIterator, class _Predicate>
76inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
77_ForwardIterator
78partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred)
79{
80 return _VSTD::__partition<typename add_lvalue_reference<_Predicate>::type>
81 (__first, __last, __pred, typename iterator_traits<_ForwardIterator>::iterator_category());
82}
83
84_LIBCPP_END_NAMESPACE_STD
85
86_LIBCPP_POP_MACROS
87
88#endif // _LIBCPP___ALGORITHM_PARTITION_H
lib/libcxx/include/__algorithm/partition_copy.h created+52
......@@ -0,0 +1,52 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_PARTITION_COPY_H
10#define _LIBCPP___ALGORITHM_PARTITION_COPY_H
11
12#include <__config>
13#include <__iterator/iterator_traits.h>
14#include <utility> // pair
15
16#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
17#pragma GCC system_header
18#endif
19
20_LIBCPP_PUSH_MACROS
21#include <__undef_macros>
22
23_LIBCPP_BEGIN_NAMESPACE_STD
24
25template <class _InputIterator, class _OutputIterator1,
26 class _OutputIterator2, class _Predicate>
27_LIBCPP_CONSTEXPR_AFTER_CXX17 pair<_OutputIterator1, _OutputIterator2>
28partition_copy(_InputIterator __first, _InputIterator __last,
29 _OutputIterator1 __out_true, _OutputIterator2 __out_false,
30 _Predicate __pred)
31{
32 for (; __first != __last; ++__first)
33 {
34 if (__pred(*__first))
35 {
36 *__out_true = *__first;
37 ++__out_true;
38 }
39 else
40 {
41 *__out_false = *__first;
42 ++__out_false;
43 }
44 }
45 return pair<_OutputIterator1, _OutputIterator2>(__out_true, __out_false);
46}
47
48_LIBCPP_END_NAMESPACE_STD
49
50_LIBCPP_POP_MACROS
51
52#endif // _LIBCPP___ALGORITHM_PARTITION_COPY_H
lib/libcxx/include/__algorithm/partition_point.h created+51
......@@ -0,0 +1,51 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_PARTITION_POINT_H
10#define _LIBCPP___ALGORITHM_PARTITION_POINT_H
11
12#include <__config>
13#include <__algorithm/half_positive.h>
14#include <iterator>
15
16#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
17#pragma GCC system_header
18#endif
19
20_LIBCPP_PUSH_MACROS
21#include <__undef_macros>
22
23_LIBCPP_BEGIN_NAMESPACE_STD
24
25template<class _ForwardIterator, class _Predicate>
26_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator
27partition_point(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred)
28{
29 typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type;
30 difference_type __len = _VSTD::distance(__first, __last);
31 while (__len != 0)
32 {
33 difference_type __l2 = _VSTD::__half_positive(__len);
34 _ForwardIterator __m = __first;
35 _VSTD::advance(__m, __l2);
36 if (__pred(*__m))
37 {
38 __first = ++__m;
39 __len -= __l2 + 1;
40 }
41 else
42 __len = __l2;
43 }
44 return __first;
45}
46
47_LIBCPP_END_NAMESPACE_STD
48
49_LIBCPP_POP_MACROS
50
51#endif // _LIBCPP___ALGORITHM_PARTITION_POINT_H
lib/libcxx/include/__algorithm/pop_heap.h created+62
......@@ -0,0 +1,62 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_POP_HEAP_H
10#define _LIBCPP___ALGORITHM_POP_HEAP_H
11
12#include <__config>
13#include <__algorithm/comp.h>
14#include <__algorithm/comp_ref_type.h>
15#include <__algorithm/sift_down.h>
16#include <__iterator/iterator_traits.h>
17#include <__utility/swap.h>
18
19#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
20#pragma GCC system_header
21#endif
22
23_LIBCPP_PUSH_MACROS
24#include <__undef_macros>
25
26_LIBCPP_BEGIN_NAMESPACE_STD
27
28template <class _Compare, class _RandomAccessIterator>
29inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
30void
31__pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp,
32 typename iterator_traits<_RandomAccessIterator>::difference_type __len)
33{
34 if (__len > 1)
35 {
36 swap(*__first, *--__last);
37 _VSTD::__sift_down<_Compare>(__first, __last, __comp, __len - 1, __first);
38 }
39}
40
41template <class _RandomAccessIterator, class _Compare>
42inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
43void
44pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
45{
46 typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
47 _VSTD::__pop_heap<_Comp_ref>(__first, __last, __comp, __last - __first);
48}
49
50template <class _RandomAccessIterator>
51inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
52void
53pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
54{
55 _VSTD::pop_heap(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
56}
57
58_LIBCPP_END_NAMESPACE_STD
59
60_LIBCPP_POP_MACROS
61
62#endif // _LIBCPP___ALGORITHM_POP_HEAP_H
lib/libcxx/include/__algorithm/prev_permutation.h created+77
......@@ -0,0 +1,77 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_PREV_PERMUTATION_H
10#define _LIBCPP___ALGORITHM_PREV_PERMUTATION_H
11
12#include <__config>
13#include <__algorithm/comp.h>
14#include <__algorithm/comp_ref_type.h>
15#include <__algorithm/reverse.h>
16#include <__iterator/iterator_traits.h>
17#include <__utility/swap.h>
18
19#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
20#pragma GCC system_header
21#endif
22
23_LIBCPP_PUSH_MACROS
24#include <__undef_macros>
25
26_LIBCPP_BEGIN_NAMESPACE_STD
27
28template <class _Compare, class _BidirectionalIterator>
29_LIBCPP_CONSTEXPR_AFTER_CXX17 bool
30__prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp)
31{
32 _BidirectionalIterator __i = __last;
33 if (__first == __last || __first == --__i)
34 return false;
35 while (true)
36 {
37 _BidirectionalIterator __ip1 = __i;
38 if (__comp(*__ip1, *--__i))
39 {
40 _BidirectionalIterator __j = __last;
41 while (!__comp(*--__j, *__i))
42 ;
43 swap(*__i, *__j);
44 _VSTD::reverse(__ip1, __last);
45 return true;
46 }
47 if (__i == __first)
48 {
49 _VSTD::reverse(__first, __last);
50 return false;
51 }
52 }
53}
54
55template <class _BidirectionalIterator, class _Compare>
56inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
57bool
58prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp)
59{
60 typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
61 return _VSTD::__prev_permutation<_Comp_ref>(__first, __last, __comp);
62}
63
64template <class _BidirectionalIterator>
65inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
66bool
67prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last)
68{
69 return _VSTD::prev_permutation(__first, __last,
70 __less<typename iterator_traits<_BidirectionalIterator>::value_type>());
71}
72
73_LIBCPP_END_NAMESPACE_STD
74
75_LIBCPP_POP_MACROS
76
77#endif // _LIBCPP___ALGORITHM_PREV_PERMUTATION_H
lib/libcxx/include/__algorithm/push_heap.h created+75
......@@ -0,0 +1,75 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_PUSH_HEAP_H
10#define _LIBCPP___ALGORITHM_PUSH_HEAP_H
11
12#include <__config>
13#include <__algorithm/comp.h>
14#include <__algorithm/comp_ref_type.h>
15#include <__iterator/iterator_traits.h>
16#include <__utility/move.h>
17
18#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
19#pragma GCC system_header
20#endif
21
22_LIBCPP_PUSH_MACROS
23#include <__undef_macros>
24
25_LIBCPP_BEGIN_NAMESPACE_STD
26
27template <class _Compare, class _RandomAccessIterator>
28_LIBCPP_CONSTEXPR_AFTER_CXX11 void
29__sift_up(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp,
30 typename iterator_traits<_RandomAccessIterator>::difference_type __len)
31{
32 typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
33 if (__len > 1)
34 {
35 __len = (__len - 2) / 2;
36 _RandomAccessIterator __ptr = __first + __len;
37 if (__comp(*__ptr, *--__last))
38 {
39 value_type __t(_VSTD::move(*__last));
40 do
41 {
42 *__last = _VSTD::move(*__ptr);
43 __last = __ptr;
44 if (__len == 0)
45 break;
46 __len = (__len - 1) / 2;
47 __ptr = __first + __len;
48 } while (__comp(*__ptr, __t));
49 *__last = _VSTD::move(__t);
50 }
51 }
52}
53
54template <class _RandomAccessIterator, class _Compare>
55inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
56void
57push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
58{
59 typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
60 _VSTD::__sift_up<_Comp_ref>(__first, __last, __comp, __last - __first);
61}
62
63template <class _RandomAccessIterator>
64inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
65void
66push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
67{
68 _VSTD::push_heap(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
69}
70
71_LIBCPP_END_NAMESPACE_STD
72
73_LIBCPP_POP_MACROS
74
75#endif // _LIBCPP___ALGORITHM_PUSH_HEAP_H
lib/libcxx/include/__algorithm/remove.h created+50
......@@ -0,0 +1,50 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_REMOVE_H
10#define _LIBCPP___ALGORITHM_REMOVE_H
11
12#include <__config>
13#include <__algorithm/find.h>
14#include <__algorithm/find_if.h>
15#include <__utility/move.h>
16
17#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
18#pragma GCC system_header
19#endif
20
21_LIBCPP_PUSH_MACROS
22#include <__undef_macros>
23
24_LIBCPP_BEGIN_NAMESPACE_STD
25
26template <class _ForwardIterator, class _Tp>
27_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator
28remove(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_)
29{
30 __first = _VSTD::find(__first, __last, __value_);
31 if (__first != __last)
32 {
33 _ForwardIterator __i = __first;
34 while (++__i != __last)
35 {
36 if (!(*__i == __value_))
37 {
38 *__first = _VSTD::move(*__i);
39 ++__first;
40 }
41 }
42 }
43 return __first;
44}
45
46_LIBCPP_END_NAMESPACE_STD
47
48_LIBCPP_POP_MACROS
49
50#endif // _LIBCPP___ALGORITHM_REMOVE_H
lib/libcxx/include/__algorithm/remove_copy.h created+43
......@@ -0,0 +1,43 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_REMOVE_COPY_H
10#define _LIBCPP___ALGORITHM_REMOVE_COPY_H
11
12#include <__config>
13
14#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
15#pragma GCC system_header
16#endif
17
18_LIBCPP_PUSH_MACROS
19#include <__undef_macros>
20
21_LIBCPP_BEGIN_NAMESPACE_STD
22
23template <class _InputIterator, class _OutputIterator, class _Tp>
24inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
25_OutputIterator
26remove_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, const _Tp& __value_)
27{
28 for (; __first != __last; ++__first)
29 {
30 if (!(*__first == __value_))
31 {
32 *__result = *__first;
33 ++__result;
34 }
35 }
36 return __result;
37}
38
39_LIBCPP_END_NAMESPACE_STD
40
41_LIBCPP_POP_MACROS
42
43#endif // _LIBCPP___ALGORITHM_REMOVE_COPY_H
lib/libcxx/include/__algorithm/remove_copy_if.h created+43
......@@ -0,0 +1,43 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_REMOVE_COPY_IF_H
10#define _LIBCPP___ALGORITHM_REMOVE_COPY_IF_H
11
12#include <__config>
13
14#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
15#pragma GCC system_header
16#endif
17
18_LIBCPP_PUSH_MACROS
19#include <__undef_macros>
20
21_LIBCPP_BEGIN_NAMESPACE_STD
22
23template <class _InputIterator, class _OutputIterator, class _Predicate>
24inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
25_OutputIterator
26remove_copy_if(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _Predicate __pred)
27{
28 for (; __first != __last; ++__first)
29 {
30 if (!__pred(*__first))
31 {
32 *__result = *__first;
33 ++__result;
34 }
35 }
36 return __result;
37}
38
39_LIBCPP_END_NAMESPACE_STD
40
41_LIBCPP_POP_MACROS
42
43#endif // _LIBCPP___ALGORITHM_REMOVE_COPY_IF_H
lib/libcxx/include/__algorithm/remove_if.h created+51
......@@ -0,0 +1,51 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_REMOVE_IF_H
10#define _LIBCPP___ALGORITHM_REMOVE_IF_H
11
12#include <__config>
13#include <__algorithm/find_if.h>
14#include <utility>
15#include <type_traits>
16
17#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
18#pragma GCC system_header
19#endif
20
21_LIBCPP_PUSH_MACROS
22#include <__undef_macros>
23
24_LIBCPP_BEGIN_NAMESPACE_STD
25
26template <class _ForwardIterator, class _Predicate>
27_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator
28remove_if(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred)
29{
30 __first = _VSTD::find_if<_ForwardIterator, typename add_lvalue_reference<_Predicate>::type>
31 (__first, __last, __pred);
32 if (__first != __last)
33 {
34 _ForwardIterator __i = __first;
35 while (++__i != __last)
36 {
37 if (!__pred(*__i))
38 {
39 *__first = _VSTD::move(*__i);
40 ++__first;
41 }
42 }
43 }
44 return __first;
45}
46
47_LIBCPP_END_NAMESPACE_STD
48
49_LIBCPP_POP_MACROS
50
51#endif // _LIBCPP___ALGORITHM_REMOVE_IF_H
lib/libcxx/include/__algorithm/replace.h created+37
......@@ -0,0 +1,37 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_REPLACE_H
10#define _LIBCPP___ALGORITHM_REPLACE_H
11
12#include <__config>
13
14#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
15#pragma GCC system_header
16#endif
17
18_LIBCPP_PUSH_MACROS
19#include <__undef_macros>
20
21_LIBCPP_BEGIN_NAMESPACE_STD
22
23template <class _ForwardIterator, class _Tp>
24inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
25void
26replace(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __old_value, const _Tp& __new_value)
27{
28 for (; __first != __last; ++__first)
29 if (*__first == __old_value)
30 *__first = __new_value;
31}
32
33_LIBCPP_END_NAMESPACE_STD
34
35_LIBCPP_POP_MACROS
36
37#endif // _LIBCPP___ALGORITHM_REPLACE_H
lib/libcxx/include/__algorithm/replace_copy.h created+41
......@@ -0,0 +1,41 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_REPLACE_COPY_H
10#define _LIBCPP___ALGORITHM_REPLACE_COPY_H
11
12#include <__config>
13
14#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
15#pragma GCC system_header
16#endif
17
18_LIBCPP_PUSH_MACROS
19#include <__undef_macros>
20
21_LIBCPP_BEGIN_NAMESPACE_STD
22
23template <class _InputIterator, class _OutputIterator, class _Tp>
24inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
25_OutputIterator
26replace_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result,
27 const _Tp& __old_value, const _Tp& __new_value)
28{
29 for (; __first != __last; ++__first, (void) ++__result)
30 if (*__first == __old_value)
31 *__result = __new_value;
32 else
33 *__result = *__first;
34 return __result;
35}
36
37_LIBCPP_END_NAMESPACE_STD
38
39_LIBCPP_POP_MACROS
40
41#endif // _LIBCPP___ALGORITHM_REPLACE_COPY_H
lib/libcxx/include/__algorithm/replace_copy_if.h created+41
......@@ -0,0 +1,41 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_REPLACE_COPY_IF_H
10#define _LIBCPP___ALGORITHM_REPLACE_COPY_IF_H
11
12#include <__config>
13
14#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
15#pragma GCC system_header
16#endif
17
18_LIBCPP_PUSH_MACROS
19#include <__undef_macros>
20
21_LIBCPP_BEGIN_NAMESPACE_STD
22
23template <class _InputIterator, class _OutputIterator, class _Predicate, class _Tp>
24inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
25_OutputIterator
26replace_copy_if(_InputIterator __first, _InputIterator __last, _OutputIterator __result,
27 _Predicate __pred, const _Tp& __new_value)
28{
29 for (; __first != __last; ++__first, (void) ++__result)
30 if (__pred(*__first))
31 *__result = __new_value;
32 else
33 *__result = *__first;
34 return __result;
35}
36
37_LIBCPP_END_NAMESPACE_STD
38
39_LIBCPP_POP_MACROS
40
41#endif // _LIBCPP___ALGORITHM_REPLACE_COPY_IF_H
lib/libcxx/include/__algorithm/replace_if.h created+37
......@@ -0,0 +1,37 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_REPLACE_IF_H
10#define _LIBCPP___ALGORITHM_REPLACE_IF_H
11
12#include <__config>
13
14#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
15#pragma GCC system_header
16#endif
17
18_LIBCPP_PUSH_MACROS
19#include <__undef_macros>
20
21_LIBCPP_BEGIN_NAMESPACE_STD
22
23template <class _ForwardIterator, class _Predicate, class _Tp>
24inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
25void
26replace_if(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, const _Tp& __new_value)
27{
28 for (; __first != __last; ++__first)
29 if (__pred(*__first))
30 *__first = __new_value;
31}
32
33_LIBCPP_END_NAMESPACE_STD
34
35_LIBCPP_POP_MACROS
36
37#endif // _LIBCPP___ALGORITHM_REPLACE_IF_H
lib/libcxx/include/__algorithm/reverse.h created+61
......@@ -0,0 +1,61 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_REVERSE_H
10#define _LIBCPP___ALGORITHM_REVERSE_H
11
12#include <__config>
13#include <__algorithm/iter_swap.h>
14#include <__iterator/iterator_traits.h>
15
16#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
17#pragma GCC system_header
18#endif
19
20_LIBCPP_PUSH_MACROS
21#include <__undef_macros>
22
23_LIBCPP_BEGIN_NAMESPACE_STD
24
25template <class _BidirectionalIterator>
26inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
27void
28__reverse(_BidirectionalIterator __first, _BidirectionalIterator __last, bidirectional_iterator_tag)
29{
30 while (__first != __last)
31 {
32 if (__first == --__last)
33 break;
34 _VSTD::iter_swap(__first, __last);
35 ++__first;
36 }
37}
38
39template <class _RandomAccessIterator>
40inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
41void
42__reverse(_RandomAccessIterator __first, _RandomAccessIterator __last, random_access_iterator_tag)
43{
44 if (__first != __last)
45 for (; __first < --__last; ++__first)
46 _VSTD::iter_swap(__first, __last);
47}
48
49template <class _BidirectionalIterator>
50inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
51void
52reverse(_BidirectionalIterator __first, _BidirectionalIterator __last)
53{
54 _VSTD::__reverse(__first, __last, typename iterator_traits<_BidirectionalIterator>::iterator_category());
55}
56
57_LIBCPP_END_NAMESPACE_STD
58
59_LIBCPP_POP_MACROS
60
61#endif // _LIBCPP___ALGORITHM_REVERSE_H
lib/libcxx/include/__algorithm/reverse_copy.h created+37
......@@ -0,0 +1,37 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_REVERSE_COPY_H
10#define _LIBCPP___ALGORITHM_REVERSE_COPY_H
11
12#include <__config>
13
14#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
15#pragma GCC system_header
16#endif
17
18_LIBCPP_PUSH_MACROS
19#include <__undef_macros>
20
21_LIBCPP_BEGIN_NAMESPACE_STD
22
23template <class _BidirectionalIterator, class _OutputIterator>
24inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
25_OutputIterator
26reverse_copy(_BidirectionalIterator __first, _BidirectionalIterator __last, _OutputIterator __result)
27{
28 for (; __first != __last; ++__result)
29 *__result = *--__last;
30 return __result;
31}
32
33_LIBCPP_END_NAMESPACE_STD
34
35_LIBCPP_POP_MACROS
36
37#endif // _LIBCPP___ALGORITHM_REVERSE_COPY_H
lib/libcxx/include/__algorithm/rotate.h created+205
......@@ -0,0 +1,205 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_ROTATE_H
10#define _LIBCPP___ALGORITHM_ROTATE_H
11
12#include <__algorithm/move.h>
13#include <__algorithm/move_backward.h>
14#include <__algorithm/swap_ranges.h>
15#include <__config>
16#include <__iterator/iterator_traits.h>
17#include <__iterator/next.h>
18#include <__iterator/prev.h>
19#include <__utility/swap.h>
20#include <iterator>
21
22#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
23#pragma GCC system_header
24#endif
25
26_LIBCPP_PUSH_MACROS
27#include <__undef_macros>
28
29_LIBCPP_BEGIN_NAMESPACE_STD
30
31template <class _ForwardIterator>
32_LIBCPP_CONSTEXPR_AFTER_CXX11 _ForwardIterator
33__rotate_left(_ForwardIterator __first, _ForwardIterator __last)
34{
35 typedef typename iterator_traits<_ForwardIterator>::value_type value_type;
36 value_type __tmp = _VSTD::move(*__first);
37 _ForwardIterator __lm1 = _VSTD::move(_VSTD::next(__first), __last, __first);
38 *__lm1 = _VSTD::move(__tmp);
39 return __lm1;
40}
41
42template <class _BidirectionalIterator>
43_LIBCPP_CONSTEXPR_AFTER_CXX11 _BidirectionalIterator
44__rotate_right(_BidirectionalIterator __first, _BidirectionalIterator __last)
45{
46 typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;
47 _BidirectionalIterator __lm1 = _VSTD::prev(__last);
48 value_type __tmp = _VSTD::move(*__lm1);
49 _BidirectionalIterator __fp1 = _VSTD::move_backward(__first, __lm1, __last);
50 *__first = _VSTD::move(__tmp);
51 return __fp1;
52}
53
54template <class _ForwardIterator>
55_LIBCPP_CONSTEXPR_AFTER_CXX14 _ForwardIterator
56__rotate_forward(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last)
57{
58 _ForwardIterator __i = __middle;
59 while (true)
60 {
61 swap(*__first, *__i);
62 ++__first;
63 if (++__i == __last)
64 break;
65 if (__first == __middle)
66 __middle = __i;
67 }
68 _ForwardIterator __r = __first;
69 if (__first != __middle)
70 {
71 __i = __middle;
72 while (true)
73 {
74 swap(*__first, *__i);
75 ++__first;
76 if (++__i == __last)
77 {
78 if (__first == __middle)
79 break;
80 __i = __middle;
81 }
82 else if (__first == __middle)
83 __middle = __i;
84 }
85 }
86 return __r;
87}
88
89template<typename _Integral>
90inline _LIBCPP_INLINE_VISIBILITY
91_LIBCPP_CONSTEXPR_AFTER_CXX14 _Integral
92__algo_gcd(_Integral __x, _Integral __y)
93{
94 do
95 {
96 _Integral __t = __x % __y;
97 __x = __y;
98 __y = __t;
99 } while (__y);
100 return __x;
101}
102
103template<typename _RandomAccessIterator>
104_LIBCPP_CONSTEXPR_AFTER_CXX14 _RandomAccessIterator
105__rotate_gcd(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last)
106{
107 typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
108 typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
109
110 const difference_type __m1 = __middle - __first;
111 const difference_type __m2 = __last - __middle;
112 if (__m1 == __m2)
113 {
114 _VSTD::swap_ranges(__first, __middle, __middle);
115 return __middle;
116 }
117 const difference_type __g = _VSTD::__algo_gcd(__m1, __m2);
118 for (_RandomAccessIterator __p = __first + __g; __p != __first;)
119 {
120 value_type __t(_VSTD::move(*--__p));
121 _RandomAccessIterator __p1 = __p;
122 _RandomAccessIterator __p2 = __p1 + __m1;
123 do
124 {
125 *__p1 = _VSTD::move(*__p2);
126 __p1 = __p2;
127 const difference_type __d = __last - __p2;
128 if (__m1 < __d)
129 __p2 += __m1;
130 else
131 __p2 = __first + (__m1 - __d);
132 } while (__p2 != __p);
133 *__p1 = _VSTD::move(__t);
134 }
135 return __first + __m2;
136}
137
138template <class _ForwardIterator>
139inline _LIBCPP_INLINE_VISIBILITY
140_LIBCPP_CONSTEXPR_AFTER_CXX11 _ForwardIterator
141__rotate(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last,
142 _VSTD::forward_iterator_tag)
143{
144 typedef typename iterator_traits<_ForwardIterator>::value_type value_type;
145 if (is_trivially_move_assignable<value_type>::value)
146 {
147 if (_VSTD::next(__first) == __middle)
148 return _VSTD::__rotate_left(__first, __last);
149 }
150 return _VSTD::__rotate_forward(__first, __middle, __last);
151}
152
153template <class _BidirectionalIterator>
154inline _LIBCPP_INLINE_VISIBILITY
155_LIBCPP_CONSTEXPR_AFTER_CXX11 _BidirectionalIterator
156__rotate(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last,
157 bidirectional_iterator_tag)
158{
159 typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;
160 if (is_trivially_move_assignable<value_type>::value)
161 {
162 if (_VSTD::next(__first) == __middle)
163 return _VSTD::__rotate_left(__first, __last);
164 if (_VSTD::next(__middle) == __last)
165 return _VSTD::__rotate_right(__first, __last);
166 }
167 return _VSTD::__rotate_forward(__first, __middle, __last);
168}
169
170template <class _RandomAccessIterator>
171inline _LIBCPP_INLINE_VISIBILITY
172_LIBCPP_CONSTEXPR_AFTER_CXX11 _RandomAccessIterator
173__rotate(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last,
174 random_access_iterator_tag)
175{
176 typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
177 if (is_trivially_move_assignable<value_type>::value)
178 {
179 if (_VSTD::next(__first) == __middle)
180 return _VSTD::__rotate_left(__first, __last);
181 if (_VSTD::next(__middle) == __last)
182 return _VSTD::__rotate_right(__first, __last);
183 return _VSTD::__rotate_gcd(__first, __middle, __last);
184 }
185 return _VSTD::__rotate_forward(__first, __middle, __last);
186}
187
188template <class _ForwardIterator>
189inline _LIBCPP_INLINE_VISIBILITY
190_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator
191rotate(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last)
192{
193 if (__first == __middle)
194 return __last;
195 if (__middle == __last)
196 return __first;
197 return _VSTD::__rotate(__first, __middle, __last,
198 typename iterator_traits<_ForwardIterator>::iterator_category());
199}
200
201_LIBCPP_END_NAMESPACE_STD
202
203_LIBCPP_POP_MACROS
204
205#endif // _LIBCPP___ALGORITHM_ROTATE_H
lib/libcxx/include/__algorithm/rotate_copy.h created+38
......@@ -0,0 +1,38 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_ROTATE_COPY_H
10#define _LIBCPP___ALGORITHM_ROTATE_COPY_H
11
12#include <__config>
13#include <__algorithm/copy.h>
14#include <iterator>
15#include <type_traits>
16
17#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
18#pragma GCC system_header
19#endif
20
21_LIBCPP_PUSH_MACROS
22#include <__undef_macros>
23
24_LIBCPP_BEGIN_NAMESPACE_STD
25
26template <class _ForwardIterator, class _OutputIterator>
27inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
28_OutputIterator
29rotate_copy(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last, _OutputIterator __result)
30{
31 return _VSTD::copy(__first, __middle, _VSTD::copy(__middle, __last, __result));
32}
33
34_LIBCPP_END_NAMESPACE_STD
35
36_LIBCPP_POP_MACROS
37
38#endif // _LIBCPP___ALGORITHM_ROTATE_COPY_H
lib/libcxx/include/__algorithm/sample.h created+101
......@@ -0,0 +1,101 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_SAMPLE_H
10#define _LIBCPP___ALGORITHM_SAMPLE_H
11
12#include <__config>
13#include <__algorithm/min.h>
14#include <__random/uniform_int_distribution.h>
15#include <iterator>
16
17#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
18#pragma GCC system_header
19#endif
20
21_LIBCPP_PUSH_MACROS
22#include <__undef_macros>
23
24_LIBCPP_BEGIN_NAMESPACE_STD
25
26template <class _PopulationIterator, class _SampleIterator, class _Distance,
27 class _UniformRandomNumberGenerator>
28_LIBCPP_INLINE_VISIBILITY
29_SampleIterator __sample(_PopulationIterator __first,
30 _PopulationIterator __last, _SampleIterator __output_iter,
31 _Distance __n,
32 _UniformRandomNumberGenerator & __g,
33 input_iterator_tag) {
34
35 _Distance __k = 0;
36 for (; __first != __last && __k < __n; ++__first, (void) ++__k)
37 __output_iter[__k] = *__first;
38 _Distance __sz = __k;
39 for (; __first != __last; ++__first, (void) ++__k) {
40 _Distance __r = uniform_int_distribution<_Distance>(0, __k)(__g);
41 if (__r < __sz)
42 __output_iter[__r] = *__first;
43 }
44 return __output_iter + _VSTD::min(__n, __k);
45}
46
47template <class _PopulationIterator, class _SampleIterator, class _Distance,
48 class _UniformRandomNumberGenerator>
49_LIBCPP_INLINE_VISIBILITY
50_SampleIterator __sample(_PopulationIterator __first,
51 _PopulationIterator __last, _SampleIterator __output_iter,
52 _Distance __n,
53 _UniformRandomNumberGenerator& __g,
54 forward_iterator_tag) {
55 _Distance __unsampled_sz = _VSTD::distance(__first, __last);
56 for (__n = _VSTD::min(__n, __unsampled_sz); __n != 0; ++__first) {
57 _Distance __r = uniform_int_distribution<_Distance>(0, --__unsampled_sz)(__g);
58 if (__r < __n) {
59 *__output_iter++ = *__first;
60 --__n;
61 }
62 }
63 return __output_iter;
64}
65
66template <class _PopulationIterator, class _SampleIterator, class _Distance,
67 class _UniformRandomNumberGenerator>
68_LIBCPP_INLINE_VISIBILITY
69_SampleIterator __sample(_PopulationIterator __first,
70 _PopulationIterator __last, _SampleIterator __output_iter,
71 _Distance __n, _UniformRandomNumberGenerator& __g) {
72 typedef typename iterator_traits<_PopulationIterator>::iterator_category
73 _PopCategory;
74 typedef typename iterator_traits<_PopulationIterator>::difference_type
75 _Difference;
76 static_assert(__is_cpp17_forward_iterator<_PopulationIterator>::value ||
77 __is_cpp17_random_access_iterator<_SampleIterator>::value,
78 "SampleIterator must meet the requirements of RandomAccessIterator");
79 typedef typename common_type<_Distance, _Difference>::type _CommonType;
80 _LIBCPP_ASSERT(__n >= 0, "N must be a positive number.");
81 return _VSTD::__sample(
82 __first, __last, __output_iter, _CommonType(__n),
83 __g, _PopCategory());
84}
85
86#if _LIBCPP_STD_VER > 14
87template <class _PopulationIterator, class _SampleIterator, class _Distance,
88 class _UniformRandomNumberGenerator>
89inline _LIBCPP_INLINE_VISIBILITY
90_SampleIterator sample(_PopulationIterator __first,
91 _PopulationIterator __last, _SampleIterator __output_iter,
92 _Distance __n, _UniformRandomNumberGenerator&& __g) {
93 return _VSTD::__sample(__first, __last, __output_iter, __n, __g);
94}
95#endif // _LIBCPP_STD_VER > 14
96
97_LIBCPP_END_NAMESPACE_STD
98
99_LIBCPP_POP_MACROS
100
101#endif // _LIBCPP___ALGORITHM_SAMPLE_H
lib/libcxx/include/__algorithm/search.h created+131
......@@ -0,0 +1,131 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___ALGORITHM_SEARCH_H
11#define _LIBCPP___ALGORITHM_SEARCH_H
12
13#include <__algorithm/comp.h>
14#include <__config>
15#include <__iterator/iterator_traits.h>
16#include <type_traits>
17#include <utility>
18
19#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
20#pragma GCC system_header
21#endif
22
23_LIBCPP_PUSH_MACROS
24#include <__undef_macros>
25
26_LIBCPP_BEGIN_NAMESPACE_STD
27
28template <class _BinaryPredicate, class _ForwardIterator1, class _ForwardIterator2>
29pair<_ForwardIterator1, _ForwardIterator1>
30 _LIBCPP_CONSTEXPR_AFTER_CXX11 __search(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
31 _ForwardIterator2 __first2, _ForwardIterator2 __last2,
32 _BinaryPredicate __pred, forward_iterator_tag, forward_iterator_tag) {
33 if (__first2 == __last2)
34 return _VSTD::make_pair(__first1, __first1); // Everything matches an empty sequence
35 while (true) {
36 // Find first element in sequence 1 that matchs *__first2, with a mininum of loop checks
37 while (true) {
38 if (__first1 == __last1) // return __last1 if no element matches *__first2
39 return _VSTD::make_pair(__last1, __last1);
40 if (__pred(*__first1, *__first2))
41 break;
42 ++__first1;
43 }
44 // *__first1 matches *__first2, now match elements after here
45 _ForwardIterator1 __m1 = __first1;
46 _ForwardIterator2 __m2 = __first2;
47 while (true) {
48 if (++__m2 == __last2) // If pattern exhausted, __first1 is the answer (works for 1 element pattern)
49 return _VSTD::make_pair(__first1, __m1);
50 if (++__m1 == __last1) // Otherwise if source exhaused, pattern not found
51 return _VSTD::make_pair(__last1, __last1);
52 if (!__pred(*__m1, *__m2)) // if there is a mismatch, restart with a new __first1
53 {
54 ++__first1;
55 break;
56 } // else there is a match, check next elements
57 }
58 }
59}
60
61template <class _BinaryPredicate, class _RandomAccessIterator1, class _RandomAccessIterator2>
62_LIBCPP_CONSTEXPR_AFTER_CXX11 pair<_RandomAccessIterator1, _RandomAccessIterator1>
63__search(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2,
64 _RandomAccessIterator2 __last2, _BinaryPredicate __pred, random_access_iterator_tag,
65 random_access_iterator_tag) {
66 typedef typename iterator_traits<_RandomAccessIterator1>::difference_type _D1;
67 typedef typename iterator_traits<_RandomAccessIterator2>::difference_type _D2;
68 // Take advantage of knowing source and pattern lengths. Stop short when source is smaller than pattern
69 const _D2 __len2 = __last2 - __first2;
70 if (__len2 == 0)
71 return _VSTD::make_pair(__first1, __first1);
72 const _D1 __len1 = __last1 - __first1;
73 if (__len1 < __len2)
74 return _VSTD::make_pair(__last1, __last1);
75 const _RandomAccessIterator1 __s = __last1 - (__len2 - 1); // Start of pattern match can't go beyond here
76
77 while (true) {
78 while (true) {
79 if (__first1 == __s)
80 return _VSTD::make_pair(__last1, __last1);
81 if (__pred(*__first1, *__first2))
82 break;
83 ++__first1;
84 }
85
86 _RandomAccessIterator1 __m1 = __first1;
87 _RandomAccessIterator2 __m2 = __first2;
88 while (true) {
89 if (++__m2 == __last2)
90 return _VSTD::make_pair(__first1, __first1 + __len2);
91 ++__m1; // no need to check range on __m1 because __s guarantees we have enough source
92 if (!__pred(*__m1, *__m2)) {
93 ++__first1;
94 break;
95 }
96 }
97 }
98}
99
100template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
101_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator1
102search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2,
103 _BinaryPredicate __pred) {
104 return _VSTD::__search<typename add_lvalue_reference<_BinaryPredicate>::type>(
105 __first1, __last1, __first2, __last2, __pred,
106 typename iterator_traits<_ForwardIterator1>::iterator_category(),
107 typename iterator_traits<_ForwardIterator2>::iterator_category()).first;
108}
109
110template <class _ForwardIterator1, class _ForwardIterator2>
111_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator1
112search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2) {
113 typedef typename iterator_traits<_ForwardIterator1>::value_type __v1;
114 typedef typename iterator_traits<_ForwardIterator2>::value_type __v2;
115 return _VSTD::search(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>());
116}
117
118#if _LIBCPP_STD_VER > 14
119template <class _ForwardIterator, class _Searcher>
120_LIBCPP_NODISCARD_EXT _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator
121search(_ForwardIterator __f, _ForwardIterator __l, const _Searcher& __s) {
122 return __s(__f, __l).first;
123}
124
125#endif
126
127_LIBCPP_END_NAMESPACE_STD
128
129_LIBCPP_POP_MACROS
130
131#endif // _LIBCPP___ALGORITHM_SEARCH_H
lib/libcxx/include/__algorithm/search_n.h created+116
......@@ -0,0 +1,116 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___ALGORITHM_SEARCH_N_H
11#define _LIBCPP___ALGORITHM_SEARCH_N_H
12
13#include <__config>
14#include <__algorithm/comp.h>
15#include <__iterator/iterator_traits.h>
16#include <type_traits>
17
18#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
19#pragma GCC system_header
20#endif
21
22_LIBCPP_PUSH_MACROS
23#include <__undef_macros>
24
25_LIBCPP_BEGIN_NAMESPACE_STD
26
27template <class _BinaryPredicate, class _ForwardIterator, class _Size, class _Tp>
28_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator __search_n(_ForwardIterator __first, _ForwardIterator __last,
29 _Size __count, const _Tp& __value_, _BinaryPredicate __pred,
30 forward_iterator_tag) {
31 if (__count <= 0)
32 return __first;
33 while (true) {
34 // Find first element in sequence that matchs __value_, with a mininum of loop checks
35 while (true) {
36 if (__first == __last) // return __last if no element matches __value_
37 return __last;
38 if (__pred(*__first, __value_))
39 break;
40 ++__first;
41 }
42 // *__first matches __value_, now match elements after here
43 _ForwardIterator __m = __first;
44 _Size __c(0);
45 while (true) {
46 if (++__c == __count) // If pattern exhausted, __first is the answer (works for 1 element pattern)
47 return __first;
48 if (++__m == __last) // Otherwise if source exhaused, pattern not found
49 return __last;
50 if (!__pred(*__m, __value_)) // if there is a mismatch, restart with a new __first
51 {
52 __first = __m;
53 ++__first;
54 break;
55 } // else there is a match, check next elements
56 }
57 }
58}
59
60template <class _BinaryPredicate, class _RandomAccessIterator, class _Size, class _Tp>
61_LIBCPP_CONSTEXPR_AFTER_CXX17 _RandomAccessIterator __search_n(_RandomAccessIterator __first,
62 _RandomAccessIterator __last, _Size __count,
63 const _Tp& __value_, _BinaryPredicate __pred,
64 random_access_iterator_tag) {
65 if (__count <= 0)
66 return __first;
67 _Size __len = static_cast<_Size>(__last - __first);
68 if (__len < __count)
69 return __last;
70 const _RandomAccessIterator __s = __last - (__count - 1); // Start of pattern match can't go beyond here
71 while (true) {
72 // Find first element in sequence that matchs __value_, with a mininum of loop checks
73 while (true) {
74 if (__first >= __s) // return __last if no element matches __value_
75 return __last;
76 if (__pred(*__first, __value_))
77 break;
78 ++__first;
79 }
80 // *__first matches __value_, now match elements after here
81 _RandomAccessIterator __m = __first;
82 _Size __c(0);
83 while (true) {
84 if (++__c == __count) // If pattern exhausted, __first is the answer (works for 1 element pattern)
85 return __first;
86 ++__m; // no need to check range on __m because __s guarantees we have enough source
87 if (!__pred(*__m, __value_)) // if there is a mismatch, restart with a new __first
88 {
89 __first = __m;
90 ++__first;
91 break;
92 } // else there is a match, check next elements
93 }
94 }
95}
96
97template <class _ForwardIterator, class _Size, class _Tp, class _BinaryPredicate>
98_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator search_n(
99 _ForwardIterator __first, _ForwardIterator __last, _Size __count, const _Tp& __value_, _BinaryPredicate __pred) {
100 return _VSTD::__search_n<typename add_lvalue_reference<_BinaryPredicate>::type>(
101 __first, __last, _VSTD::__convert_to_integral(__count), __value_, __pred,
102 typename iterator_traits<_ForwardIterator>::iterator_category());
103}
104
105template <class _ForwardIterator, class _Size, class _Tp>
106_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator
107search_n(_ForwardIterator __first, _ForwardIterator __last, _Size __count, const _Tp& __value_) {
108 typedef typename iterator_traits<_ForwardIterator>::value_type __v;
109 return _VSTD::search_n(__first, __last, _VSTD::__convert_to_integral(__count), __value_, __equal_to<__v, _Tp>());
110}
111
112_LIBCPP_END_NAMESPACE_STD
113
114_LIBCPP_POP_MACROS
115
116#endif // _LIBCPP___ALGORITHM_SEARCH_N_H
lib/libcxx/include/__algorithm/set_difference.h created+77
......@@ -0,0 +1,77 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_SET_DIFFERENCE_H
10#define _LIBCPP___ALGORITHM_SET_DIFFERENCE_H
11
12#include <__config>
13#include <__algorithm/comp.h>
14#include <__algorithm/comp_ref_type.h>
15#include <__algorithm/copy.h>
16#include <__iterator/iterator_traits.h>
17
18#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
19#pragma GCC system_header
20#endif
21
22_LIBCPP_PUSH_MACROS
23#include <__undef_macros>
24
25_LIBCPP_BEGIN_NAMESPACE_STD
26
27template <class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator>
28_LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator
29__set_difference(_InputIterator1 __first1, _InputIterator1 __last1,
30 _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)
31{
32 while (__first1 != __last1)
33 {
34 if (__first2 == __last2)
35 return _VSTD::copy(__first1, __last1, __result);
36 if (__comp(*__first1, *__first2))
37 {
38 *__result = *__first1;
39 ++__result;
40 ++__first1;
41 }
42 else
43 {
44 if (!__comp(*__first2, *__first1))
45 ++__first1;
46 ++__first2;
47 }
48 }
49 return __result;
50}
51
52template <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _Compare>
53inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
54_OutputIterator
55set_difference(_InputIterator1 __first1, _InputIterator1 __last1,
56 _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)
57{
58 typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
59 return _VSTD::__set_difference<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp);
60}
61
62template <class _InputIterator1, class _InputIterator2, class _OutputIterator>
63inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
64_OutputIterator
65set_difference(_InputIterator1 __first1, _InputIterator1 __last1,
66 _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result)
67{
68 return _VSTD::set_difference(__first1, __last1, __first2, __last2, __result,
69 __less<typename iterator_traits<_InputIterator1>::value_type,
70 typename iterator_traits<_InputIterator2>::value_type>());
71}
72
73_LIBCPP_END_NAMESPACE_STD
74
75_LIBCPP_POP_MACROS
76
77#endif // _LIBCPP___ALGORITHM_SET_DIFFERENCE_H
lib/libcxx/include/__algorithm/set_intersection.h created+74
......@@ -0,0 +1,74 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_SET_INTERSECTION_H
10#define _LIBCPP___ALGORITHM_SET_INTERSECTION_H
11
12#include <__config>
13#include <__algorithm/comp.h>
14#include <__algorithm/comp_ref_type.h>
15#include <__iterator/iterator_traits.h>
16
17#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
18#pragma GCC system_header
19#endif
20
21_LIBCPP_PUSH_MACROS
22#include <__undef_macros>
23
24_LIBCPP_BEGIN_NAMESPACE_STD
25
26template <class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator>
27_LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator
28__set_intersection(_InputIterator1 __first1, _InputIterator1 __last1,
29 _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)
30{
31 while (__first1 != __last1 && __first2 != __last2)
32 {
33 if (__comp(*__first1, *__first2))
34 ++__first1;
35 else
36 {
37 if (!__comp(*__first2, *__first1))
38 {
39 *__result = *__first1;
40 ++__result;
41 ++__first1;
42 }
43 ++__first2;
44 }
45 }
46 return __result;
47}
48
49template <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _Compare>
50inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
51_OutputIterator
52set_intersection(_InputIterator1 __first1, _InputIterator1 __last1,
53 _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)
54{
55 typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
56 return _VSTD::__set_intersection<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp);
57}
58
59template <class _InputIterator1, class _InputIterator2, class _OutputIterator>
60inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
61_OutputIterator
62set_intersection(_InputIterator1 __first1, _InputIterator1 __last1,
63 _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result)
64{
65 return _VSTD::set_intersection(__first1, __last1, __first2, __last2, __result,
66 __less<typename iterator_traits<_InputIterator1>::value_type,
67 typename iterator_traits<_InputIterator2>::value_type>());
68}
69
70_LIBCPP_END_NAMESPACE_STD
71
72_LIBCPP_POP_MACROS
73
74#endif // _LIBCPP___ALGORITHM_SET_INTERSECTION_H
lib/libcxx/include/__algorithm/set_symmetric_difference.h created+82
......@@ -0,0 +1,82 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_SET_SYMMETRIC_DIFFERENCE_H
10#define _LIBCPP___ALGORITHM_SET_SYMMETRIC_DIFFERENCE_H
11
12#include <__config>
13#include <__algorithm/comp.h>
14#include <__algorithm/comp_ref_type.h>
15#include <__algorithm/copy.h>
16#include <__iterator/iterator_traits.h>
17
18#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
19#pragma GCC system_header
20#endif
21
22_LIBCPP_PUSH_MACROS
23#include <__undef_macros>
24
25_LIBCPP_BEGIN_NAMESPACE_STD
26
27template <class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator>
28_LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator
29__set_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1,
30 _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)
31{
32 while (__first1 != __last1)
33 {
34 if (__first2 == __last2)
35 return _VSTD::copy(__first1, __last1, __result);
36 if (__comp(*__first1, *__first2))
37 {
38 *__result = *__first1;
39 ++__result;
40 ++__first1;
41 }
42 else
43 {
44 if (__comp(*__first2, *__first1))
45 {
46 *__result = *__first2;
47 ++__result;
48 }
49 else
50 ++__first1;
51 ++__first2;
52 }
53 }
54 return _VSTD::copy(__first2, __last2, __result);
55}
56
57template <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _Compare>
58inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
59_OutputIterator
60set_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1,
61 _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)
62{
63 typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
64 return _VSTD::__set_symmetric_difference<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp);
65}
66
67template <class _InputIterator1, class _InputIterator2, class _OutputIterator>
68inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
69_OutputIterator
70set_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1,
71 _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result)
72{
73 return _VSTD::set_symmetric_difference(__first1, __last1, __first2, __last2, __result,
74 __less<typename iterator_traits<_InputIterator1>::value_type,
75 typename iterator_traits<_InputIterator2>::value_type>());
76}
77
78_LIBCPP_END_NAMESPACE_STD
79
80_LIBCPP_POP_MACROS
81
82#endif // _LIBCPP___ALGORITHM_SET_SYMMETRIC_DIFFERENCE_H
lib/libcxx/include/__algorithm/set_union.h created+77
......@@ -0,0 +1,77 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_SET_UNION_H
10#define _LIBCPP___ALGORITHM_SET_UNION_H
11
12#include <__config>
13#include <__algorithm/comp.h>
14#include <__algorithm/comp_ref_type.h>
15#include <__algorithm/copy.h>
16#include <__iterator/iterator_traits.h>
17
18#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
19#pragma GCC system_header
20#endif
21
22_LIBCPP_PUSH_MACROS
23#include <__undef_macros>
24
25_LIBCPP_BEGIN_NAMESPACE_STD
26
27template <class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator>
28_LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator
29__set_union(_InputIterator1 __first1, _InputIterator1 __last1,
30 _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)
31{
32 for (; __first1 != __last1; ++__result)
33 {
34 if (__first2 == __last2)
35 return _VSTD::copy(__first1, __last1, __result);
36 if (__comp(*__first2, *__first1))
37 {
38 *__result = *__first2;
39 ++__first2;
40 }
41 else
42 {
43 if (!__comp(*__first1, *__first2))
44 ++__first2;
45 *__result = *__first1;
46 ++__first1;
47 }
48 }
49 return _VSTD::copy(__first2, __last2, __result);
50}
51
52template <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _Compare>
53inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
54_OutputIterator
55set_union(_InputIterator1 __first1, _InputIterator1 __last1,
56 _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)
57{
58 typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
59 return _VSTD::__set_union<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp);
60}
61
62template <class _InputIterator1, class _InputIterator2, class _OutputIterator>
63inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
64_OutputIterator
65set_union(_InputIterator1 __first1, _InputIterator1 __last1,
66 _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result)
67{
68 return _VSTD::set_union(__first1, __last1, __first2, __last2, __result,
69 __less<typename iterator_traits<_InputIterator1>::value_type,
70 typename iterator_traits<_InputIterator2>::value_type>());
71}
72
73_LIBCPP_END_NAMESPACE_STD
74
75_LIBCPP_POP_MACROS
76
77#endif // _LIBCPP___ALGORITHM_SET_UNION_H
lib/libcxx/include/__algorithm/shift_left.h created+61
......@@ -0,0 +1,61 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_SHIFT_LEFT_H
10#define _LIBCPP___ALGORITHM_SHIFT_LEFT_H
11
12#include <__config>
13#include <__algorithm/move.h>
14#include <__iterator/iterator_traits.h>
15#include <type_traits> // swap
16
17#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
18#pragma GCC system_header
19#endif
20
21_LIBCPP_PUSH_MACROS
22#include <__undef_macros>
23
24_LIBCPP_BEGIN_NAMESPACE_STD
25
26#if _LIBCPP_STD_VER > 17
27
28template <class _ForwardIterator>
29inline _LIBCPP_INLINE_VISIBILITY constexpr
30_ForwardIterator
31shift_left(_ForwardIterator __first, _ForwardIterator __last,
32 typename iterator_traits<_ForwardIterator>::difference_type __n)
33{
34 if (__n == 0) {
35 return __last;
36 }
37
38 _ForwardIterator __m = __first;
39 if constexpr (__is_cpp17_random_access_iterator<_ForwardIterator>::value) {
40 if (__n >= __last - __first) {
41 return __first;
42 }
43 __m += __n;
44 } else {
45 for (; __n > 0; --__n) {
46 if (__m == __last) {
47 return __first;
48 }
49 ++__m;
50 }
51 }
52 return _VSTD::move(__m, __last, __first);
53}
54
55#endif // _LIBCPP_STD_VER > 17
56
57_LIBCPP_END_NAMESPACE_STD
58
59_LIBCPP_POP_MACROS
60
61#endif // _LIBCPP___ALGORITHM_SHIFT_LEFT_H
lib/libcxx/include/__algorithm/shift_right.h created+106
......@@ -0,0 +1,106 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_SHIFT_RIGHT_H
10#define _LIBCPP___ALGORITHM_SHIFT_RIGHT_H
11
12#include <__config>
13#include <__algorithm/move.h>
14#include <__algorithm/move_backward.h>
15#include <__algorithm/swap_ranges.h>
16#include <__iterator/iterator_traits.h>
17#include <type_traits> // swap
18
19#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
20#pragma GCC system_header
21#endif
22
23_LIBCPP_PUSH_MACROS
24#include <__undef_macros>
25
26_LIBCPP_BEGIN_NAMESPACE_STD
27
28#if _LIBCPP_STD_VER > 17
29
30template <class _ForwardIterator>
31inline _LIBCPP_INLINE_VISIBILITY constexpr
32_ForwardIterator
33shift_right(_ForwardIterator __first, _ForwardIterator __last,
34 typename iterator_traits<_ForwardIterator>::difference_type __n)
35{
36 if (__n == 0) {
37 return __first;
38 }
39
40 if constexpr (__is_cpp17_random_access_iterator<_ForwardIterator>::value) {
41 decltype(__n) __d = __last - __first;
42 if (__n >= __d) {
43 return __last;
44 }
45 _ForwardIterator __m = __first + (__d - __n);
46 return _VSTD::move_backward(__first, __m, __last);
47 } else if constexpr (__is_cpp17_bidirectional_iterator<_ForwardIterator>::value) {
48 _ForwardIterator __m = __last;
49 for (; __n > 0; --__n) {
50 if (__m == __first) {
51 return __last;
52 }
53 --__m;
54 }
55 return _VSTD::move_backward(__first, __m, __last);
56 } else {
57 _ForwardIterator __ret = __first;
58 for (; __n > 0; --__n) {
59 if (__ret == __last) {
60 return __last;
61 }
62 ++__ret;
63 }
64
65 // We have an __n-element scratch space from __first to __ret.
66 // Slide an __n-element window [__trail, __lead) from left to right.
67 // We're essentially doing swap_ranges(__first, __ret, __trail, __lead)
68 // over and over; but once __lead reaches __last we needn't bother
69 // to save the values of elements [__trail, __last).
70
71 auto __trail = __first;
72 auto __lead = __ret;
73 while (__trail != __ret) {
74 if (__lead == __last) {
75 _VSTD::move(__first, __trail, __ret);
76 return __ret;
77 }
78 ++__trail;
79 ++__lead;
80 }
81
82 _ForwardIterator __mid = __first;
83 while (true) {
84 if (__lead == __last) {
85 __trail = _VSTD::move(__mid, __ret, __trail);
86 _VSTD::move(__first, __mid, __trail);
87 return __ret;
88 }
89 swap(*__mid, *__trail);
90 ++__mid;
91 ++__trail;
92 ++__lead;
93 if (__mid == __ret) {
94 __mid = __first;
95 }
96 }
97 }
98}
99
100#endif // _LIBCPP_STD_VER > 17
101
102_LIBCPP_END_NAMESPACE_STD
103
104_LIBCPP_POP_MACROS
105
106#endif // _LIBCPP___ALGORITHM_SHIFT_RIGHT_H
lib/libcxx/include/__algorithm/shuffle.h created+127
......@@ -0,0 +1,127 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_SHUFFLE_H
10#define _LIBCPP___ALGORITHM_SHUFFLE_H
11
12#include <__config>
13#include <__iterator/iterator_traits.h>
14#include <__random/uniform_int_distribution.h>
15#include <__utility/swap.h>
16#include <cstddef>
17#include <cstdint>
18
19#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
20#pragma GCC system_header
21#endif
22
23_LIBCPP_PUSH_MACROS
24#include <__undef_macros>
25
26_LIBCPP_BEGIN_NAMESPACE_STD
27
28
29#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_RANDOM_SHUFFLE) \
30 || defined(_LIBCPP_BUILDING_LIBRARY)
31class _LIBCPP_TYPE_VIS __rs_default;
32
33_LIBCPP_FUNC_VIS __rs_default __rs_get();
34
35class _LIBCPP_TYPE_VIS __rs_default
36{
37 static unsigned __c_;
38
39 __rs_default();
40public:
41 typedef uint_fast32_t result_type;
42
43 static const result_type _Min = 0;
44 static const result_type _Max = 0xFFFFFFFF;
45
46 __rs_default(const __rs_default&);
47 ~__rs_default();
48
49 result_type operator()();
50
51 static _LIBCPP_CONSTEXPR result_type min() {return _Min;}
52 static _LIBCPP_CONSTEXPR result_type max() {return _Max;}
53
54 friend _LIBCPP_FUNC_VIS __rs_default __rs_get();
55};
56
57_LIBCPP_FUNC_VIS __rs_default __rs_get();
58
59template <class _RandomAccessIterator>
60_LIBCPP_DEPRECATED_IN_CXX14 void
61random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last)
62{
63 typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
64 typedef uniform_int_distribution<ptrdiff_t> _Dp;
65 typedef typename _Dp::param_type _Pp;
66 difference_type __d = __last - __first;
67 if (__d > 1)
68 {
69 _Dp __uid;
70 __rs_default __g = __rs_get();
71 for (--__last, (void) --__d; __first < __last; ++__first, (void) --__d)
72 {
73 difference_type __i = __uid(__g, _Pp(0, __d));
74 if (__i != difference_type(0))
75 swap(*__first, *(__first + __i));
76 }
77 }
78}
79
80template <class _RandomAccessIterator, class _RandomNumberGenerator>
81_LIBCPP_DEPRECATED_IN_CXX14 void
82random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last,
83#ifndef _LIBCPP_CXX03_LANG
84 _RandomNumberGenerator&& __rand)
85#else
86 _RandomNumberGenerator& __rand)
87#endif
88{
89 typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
90 difference_type __d = __last - __first;
91 if (__d > 1)
92 {
93 for (--__last; __first < __last; ++__first, (void) --__d)
94 {
95 difference_type __i = __rand(__d);
96 if (__i != difference_type(0))
97 swap(*__first, *(__first + __i));
98 }
99 }
100}
101#endif
102
103template<class _RandomAccessIterator, class _UniformRandomNumberGenerator>
104 void shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last,
105 _UniformRandomNumberGenerator&& __g)
106{
107 typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
108 typedef uniform_int_distribution<ptrdiff_t> _Dp;
109 typedef typename _Dp::param_type _Pp;
110 difference_type __d = __last - __first;
111 if (__d > 1)
112 {
113 _Dp __uid;
114 for (--__last, (void) --__d; __first < __last; ++__first, (void) --__d)
115 {
116 difference_type __i = __uid(__g, _Pp(0, __d));
117 if (__i != difference_type(0))
118 swap(*__first, *(__first + __i));
119 }
120 }
121}
122
123_LIBCPP_END_NAMESPACE_STD
124
125_LIBCPP_POP_MACROS
126
127#endif // _LIBCPP___ALGORITHM_SHUFFLE_H
lib/libcxx/include/__algorithm/sift_down.h created+84
......@@ -0,0 +1,84 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_SIFT_DOWN_H
10#define _LIBCPP___ALGORITHM_SIFT_DOWN_H
11
12#include <__config>
13#include <__iterator/iterator_traits.h>
14#include <__utility/move.h>
15
16#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
17#pragma GCC system_header
18#endif
19
20_LIBCPP_PUSH_MACROS
21#include <__undef_macros>
22
23_LIBCPP_BEGIN_NAMESPACE_STD
24
25template <class _Compare, class _RandomAccessIterator>
26_LIBCPP_CONSTEXPR_AFTER_CXX11 void
27__sift_down(_RandomAccessIterator __first, _RandomAccessIterator /*__last*/,
28 _Compare __comp,
29 typename iterator_traits<_RandomAccessIterator>::difference_type __len,
30 _RandomAccessIterator __start)
31{
32 typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
33 typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
34 // left-child of __start is at 2 * __start + 1
35 // right-child of __start is at 2 * __start + 2
36 difference_type __child = __start - __first;
37
38 if (__len < 2 || (__len - 2) / 2 < __child)
39 return;
40
41 __child = 2 * __child + 1;
42 _RandomAccessIterator __child_i = __first + __child;
43
44 if ((__child + 1) < __len && __comp(*__child_i, *(__child_i + 1))) {
45 // right-child exists and is greater than left-child
46 ++__child_i;
47 ++__child;
48 }
49
50 // check if we are in heap-order
51 if (__comp(*__child_i, *__start))
52 // we are, __start is larger than it's largest child
53 return;
54
55 value_type __top(_VSTD::move(*__start));
56 do
57 {
58 // we are not in heap-order, swap the parent with its largest child
59 *__start = _VSTD::move(*__child_i);
60 __start = __child_i;
61
62 if ((__len - 2) / 2 < __child)
63 break;
64
65 // recompute the child based off of the updated parent
66 __child = 2 * __child + 1;
67 __child_i = __first + __child;
68
69 if ((__child + 1) < __len && __comp(*__child_i, *(__child_i + 1))) {
70 // right-child exists and is greater than left-child
71 ++__child_i;
72 ++__child;
73 }
74
75 // check if we are in heap-order
76 } while (!__comp(*__child_i, __top));
77 *__start = _VSTD::move(__top);
78}
79
80_LIBCPP_END_NAMESPACE_STD
81
82_LIBCPP_POP_MACROS
83
84#endif // _LIBCPP___ALGORITHM_SIFT_DOWN_H
lib/libcxx/include/__algorithm/sort.h created+530
......@@ -0,0 +1,530 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_SORT_H
10#define _LIBCPP___ALGORITHM_SORT_H
11
12#include <__config>
13#include <__algorithm/comp.h>
14#include <__algorithm/comp_ref_type.h>
15#include <__algorithm/min_element.h>
16#include <__algorithm/partial_sort.h>
17#include <__algorithm/unwrap_iter.h>
18#include <__utility/swap.h>
19#include <memory>
20#include <type_traits> // swap
21
22#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
23#pragma GCC system_header
24#endif
25
26_LIBCPP_PUSH_MACROS
27#include <__undef_macros>
28
29_LIBCPP_BEGIN_NAMESPACE_STD
30
31// stable, 2-3 compares, 0-2 swaps
32
33template <class _Compare, class _ForwardIterator>
34_LIBCPP_CONSTEXPR_AFTER_CXX11 unsigned
35__sort3(_ForwardIterator __x, _ForwardIterator __y, _ForwardIterator __z, _Compare __c)
36{
37 unsigned __r = 0;
38 if (!__c(*__y, *__x)) // if x <= y
39 {
40 if (!__c(*__z, *__y)) // if y <= z
41 return __r; // x <= y && y <= z
42 // x <= y && y > z
43 swap(*__y, *__z); // x <= z && y < z
44 __r = 1;
45 if (__c(*__y, *__x)) // if x > y
46 {
47 swap(*__x, *__y); // x < y && y <= z
48 __r = 2;
49 }
50 return __r; // x <= y && y < z
51 }
52 if (__c(*__z, *__y)) // x > y, if y > z
53 {
54 swap(*__x, *__z); // x < y && y < z
55 __r = 1;
56 return __r;
57 }
58 swap(*__x, *__y); // x > y && y <= z
59 __r = 1; // x < y && x <= z
60 if (__c(*__z, *__y)) // if y > z
61 {
62 swap(*__y, *__z); // x <= y && y < z
63 __r = 2;
64 }
65 return __r;
66} // x <= y && y <= z
67
68// stable, 3-6 compares, 0-5 swaps
69
70template <class _Compare, class _ForwardIterator>
71unsigned
72__sort4(_ForwardIterator __x1, _ForwardIterator __x2, _ForwardIterator __x3,
73 _ForwardIterator __x4, _Compare __c)
74{
75 unsigned __r = _VSTD::__sort3<_Compare>(__x1, __x2, __x3, __c);
76 if (__c(*__x4, *__x3))
77 {
78 swap(*__x3, *__x4);
79 ++__r;
80 if (__c(*__x3, *__x2))
81 {
82 swap(*__x2, *__x3);
83 ++__r;
84 if (__c(*__x2, *__x1))
85 {
86 swap(*__x1, *__x2);
87 ++__r;
88 }
89 }
90 }
91 return __r;
92}
93
94// stable, 4-10 compares, 0-9 swaps
95
96template <class _Compare, class _ForwardIterator>
97_LIBCPP_HIDDEN
98unsigned
99__sort5(_ForwardIterator __x1, _ForwardIterator __x2, _ForwardIterator __x3,
100 _ForwardIterator __x4, _ForwardIterator __x5, _Compare __c)
101{
102 unsigned __r = _VSTD::__sort4<_Compare>(__x1, __x2, __x3, __x4, __c);
103 if (__c(*__x5, *__x4))
104 {
105 swap(*__x4, *__x5);
106 ++__r;
107 if (__c(*__x4, *__x3))
108 {
109 swap(*__x3, *__x4);
110 ++__r;
111 if (__c(*__x3, *__x2))
112 {
113 swap(*__x2, *__x3);
114 ++__r;
115 if (__c(*__x2, *__x1))
116 {
117 swap(*__x1, *__x2);
118 ++__r;
119 }
120 }
121 }
122 }
123 return __r;
124}
125
126// Assumes size > 0
127template <class _Compare, class _BidirectionalIterator>
128_LIBCPP_CONSTEXPR_AFTER_CXX11 void
129__selection_sort(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp)
130{
131 _BidirectionalIterator __lm1 = __last;
132 for (--__lm1; __first != __lm1; ++__first)
133 {
134 _BidirectionalIterator __i = _VSTD::min_element<_BidirectionalIterator,
135 typename add_lvalue_reference<_Compare>::type>
136 (__first, __last, __comp);
137 if (__i != __first)
138 swap(*__first, *__i);
139 }
140}
141
142template <class _Compare, class _BidirectionalIterator>
143void
144__insertion_sort(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp)
145{
146 typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;
147 if (__first != __last)
148 {
149 _BidirectionalIterator __i = __first;
150 for (++__i; __i != __last; ++__i)
151 {
152 _BidirectionalIterator __j = __i;
153 value_type __t(_VSTD::move(*__j));
154 for (_BidirectionalIterator __k = __i; __k != __first && __comp(__t, *--__k); --__j)
155 *__j = _VSTD::move(*__k);
156 *__j = _VSTD::move(__t);
157 }
158 }
159}
160
161template <class _Compare, class _RandomAccessIterator>
162void
163__insertion_sort_3(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
164{
165 typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
166 _RandomAccessIterator __j = __first+2;
167 _VSTD::__sort3<_Compare>(__first, __first+1, __j, __comp);
168 for (_RandomAccessIterator __i = __j+1; __i != __last; ++__i)
169 {
170 if (__comp(*__i, *__j))
171 {
172 value_type __t(_VSTD::move(*__i));
173 _RandomAccessIterator __k = __j;
174 __j = __i;
175 do
176 {
177 *__j = _VSTD::move(*__k);
178 __j = __k;
179 } while (__j != __first && __comp(__t, *--__k));
180 *__j = _VSTD::move(__t);
181 }
182 __j = __i;
183 }
184}
185
186template <class _Compare, class _RandomAccessIterator>
187bool
188__insertion_sort_incomplete(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
189{
190 switch (__last - __first)
191 {
192 case 0:
193 case 1:
194 return true;
195 case 2:
196 if (__comp(*--__last, *__first))
197 swap(*__first, *__last);
198 return true;
199 case 3:
200 _VSTD::__sort3<_Compare>(__first, __first+1, --__last, __comp);
201 return true;
202 case 4:
203 _VSTD::__sort4<_Compare>(__first, __first+1, __first+2, --__last, __comp);
204 return true;
205 case 5:
206 _VSTD::__sort5<_Compare>(__first, __first+1, __first+2, __first+3, --__last, __comp);
207 return true;
208 }
209 typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
210 _RandomAccessIterator __j = __first+2;
211 _VSTD::__sort3<_Compare>(__first, __first+1, __j, __comp);
212 const unsigned __limit = 8;
213 unsigned __count = 0;
214 for (_RandomAccessIterator __i = __j+1; __i != __last; ++__i)
215 {
216 if (__comp(*__i, *__j))
217 {
218 value_type __t(_VSTD::move(*__i));
219 _RandomAccessIterator __k = __j;
220 __j = __i;
221 do
222 {
223 *__j = _VSTD::move(*__k);
224 __j = __k;
225 } while (__j != __first && __comp(__t, *--__k));
226 *__j = _VSTD::move(__t);
227 if (++__count == __limit)
228 return ++__i == __last;
229 }
230 __j = __i;
231 }
232 return true;
233}
234
235template <class _Compare, class _BidirectionalIterator>
236void
237__insertion_sort_move(_BidirectionalIterator __first1, _BidirectionalIterator __last1,
238 typename iterator_traits<_BidirectionalIterator>::value_type* __first2, _Compare __comp)
239{
240 typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;
241 if (__first1 != __last1)
242 {
243 __destruct_n __d(0);
244 unique_ptr<value_type, __destruct_n&> __h(__first2, __d);
245 value_type* __last2 = __first2;
246 ::new ((void*)__last2) value_type(_VSTD::move(*__first1));
247 __d.template __incr<value_type>();
248 for (++__last2; ++__first1 != __last1; ++__last2)
249 {
250 value_type* __j2 = __last2;
251 value_type* __i2 = __j2;
252 if (__comp(*__first1, *--__i2))
253 {
254 ::new ((void*)__j2) value_type(_VSTD::move(*__i2));
255 __d.template __incr<value_type>();
256 for (--__j2; __i2 != __first2 && __comp(*__first1, *--__i2); --__j2)
257 *__j2 = _VSTD::move(*__i2);
258 *__j2 = _VSTD::move(*__first1);
259 }
260 else
261 {
262 ::new ((void*)__j2) value_type(_VSTD::move(*__first1));
263 __d.template __incr<value_type>();
264 }
265 }
266 __h.release();
267 }
268}
269
270template <class _Compare, class _RandomAccessIterator>
271void
272__sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
273{
274 typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
275 typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
276 const difference_type __limit = is_trivially_copy_constructible<value_type>::value &&
277 is_trivially_copy_assignable<value_type>::value ? 30 : 6;
278 while (true)
279 {
280 __restart:
281 difference_type __len = __last - __first;
282 switch (__len)
283 {
284 case 0:
285 case 1:
286 return;
287 case 2:
288 if (__comp(*--__last, *__first))
289 swap(*__first, *__last);
290 return;
291 case 3:
292 _VSTD::__sort3<_Compare>(__first, __first+1, --__last, __comp);
293 return;
294 case 4:
295 _VSTD::__sort4<_Compare>(__first, __first+1, __first+2, --__last, __comp);
296 return;
297 case 5:
298 _VSTD::__sort5<_Compare>(__first, __first+1, __first+2, __first+3, --__last, __comp);
299 return;
300 }
301 if (__len <= __limit)
302 {
303 _VSTD::__insertion_sort_3<_Compare>(__first, __last, __comp);
304 return;
305 }
306 // __len > 5
307 _RandomAccessIterator __m = __first;
308 _RandomAccessIterator __lm1 = __last;
309 --__lm1;
310 unsigned __n_swaps;
311 {
312 difference_type __delta;
313 if (__len >= 1000)
314 {
315 __delta = __len/2;
316 __m += __delta;
317 __delta /= 2;
318 __n_swaps = _VSTD::__sort5<_Compare>(__first, __first + __delta, __m, __m+__delta, __lm1, __comp);
319 }
320 else
321 {
322 __delta = __len/2;
323 __m += __delta;
324 __n_swaps = _VSTD::__sort3<_Compare>(__first, __m, __lm1, __comp);
325 }
326 }
327 // *__m is median
328 // partition [__first, __m) < *__m and *__m <= [__m, __last)
329 // (this inhibits tossing elements equivalent to __m around unnecessarily)
330 _RandomAccessIterator __i = __first;
331 _RandomAccessIterator __j = __lm1;
332 // j points beyond range to be tested, *__m is known to be <= *__lm1
333 // The search going up is known to be guarded but the search coming down isn't.
334 // Prime the downward search with a guard.
335 if (!__comp(*__i, *__m)) // if *__first == *__m
336 {
337 // *__first == *__m, *__first doesn't go in first part
338 // manually guard downward moving __j against __i
339 while (true)
340 {
341 if (__i == --__j)
342 {
343 // *__first == *__m, *__m <= all other elements
344 // Parition instead into [__first, __i) == *__first and *__first < [__i, __last)
345 ++__i; // __first + 1
346 __j = __last;
347 if (!__comp(*__first, *--__j)) // we need a guard if *__first == *(__last-1)
348 {
349 while (true)
350 {
351 if (__i == __j)
352 return; // [__first, __last) all equivalent elements
353 if (__comp(*__first, *__i))
354 {
355 swap(*__i, *__j);
356 ++__n_swaps;
357 ++__i;
358 break;
359 }
360 ++__i;
361 }
362 }
363 // [__first, __i) == *__first and *__first < [__j, __last) and __j == __last - 1
364 if (__i == __j)
365 return;
366 while (true)
367 {
368 while (!__comp(*__first, *__i))
369 ++__i;
370 while (__comp(*__first, *--__j))
371 ;
372 if (__i >= __j)
373 break;
374 swap(*__i, *__j);
375 ++__n_swaps;
376 ++__i;
377 }
378 // [__first, __i) == *__first and *__first < [__i, __last)
379 // The first part is sorted, sort the second part
380 // _VSTD::__sort<_Compare>(__i, __last, __comp);
381 __first = __i;
382 goto __restart;
383 }
384 if (__comp(*__j, *__m))
385 {
386 swap(*__i, *__j);
387 ++__n_swaps;
388 break; // found guard for downward moving __j, now use unguarded partition
389 }
390 }
391 }
392 // It is known that *__i < *__m
393 ++__i;
394 // j points beyond range to be tested, *__m is known to be <= *__lm1
395 // if not yet partitioned...
396 if (__i < __j)
397 {
398 // known that *(__i - 1) < *__m
399 // known that __i <= __m
400 while (true)
401 {
402 // __m still guards upward moving __i
403 while (__comp(*__i, *__m))
404 ++__i;
405 // It is now known that a guard exists for downward moving __j
406 while (!__comp(*--__j, *__m))
407 ;
408 if (__i > __j)
409 break;
410 swap(*__i, *__j);
411 ++__n_swaps;
412 // It is known that __m != __j
413 // If __m just moved, follow it
414 if (__m == __i)
415 __m = __j;
416 ++__i;
417 }
418 }
419 // [__first, __i) < *__m and *__m <= [__i, __last)
420 if (__i != __m && __comp(*__m, *__i))
421 {
422 swap(*__i, *__m);
423 ++__n_swaps;
424 }
425 // [__first, __i) < *__i and *__i <= [__i+1, __last)
426 // If we were given a perfect partition, see if insertion sort is quick...
427 if (__n_swaps == 0)
428 {
429 bool __fs = _VSTD::__insertion_sort_incomplete<_Compare>(__first, __i, __comp);
430 if (_VSTD::__insertion_sort_incomplete<_Compare>(__i+1, __last, __comp))
431 {
432 if (__fs)
433 return;
434 __last = __i;
435 continue;
436 }
437 else
438 {
439 if (__fs)
440 {
441 __first = ++__i;
442 continue;
443 }
444 }
445 }
446 // sort smaller range with recursive call and larger with tail recursion elimination
447 if (__i - __first < __last - __i)
448 {
449 _VSTD::__sort<_Compare>(__first, __i, __comp);
450 // _VSTD::__sort<_Compare>(__i+1, __last, __comp);
451 __first = ++__i;
452 }
453 else
454 {
455 _VSTD::__sort<_Compare>(__i+1, __last, __comp);
456 // _VSTD::__sort<_Compare>(__first, __i, __comp);
457 __last = __i;
458 }
459 }
460}
461
462template <class _Compare, class _Tp>
463inline _LIBCPP_INLINE_VISIBILITY
464void
465__sort(_Tp** __first, _Tp** __last, __less<_Tp*>&)
466{
467 __less<uintptr_t> __comp;
468 _VSTD::__sort<__less<uintptr_t>&, uintptr_t*>((uintptr_t*)__first, (uintptr_t*)__last, __comp);
469}
470
471_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<char>&, char*>(char*, char*, __less<char>&))
472_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<wchar_t>&, wchar_t*>(wchar_t*, wchar_t*, __less<wchar_t>&))
473_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<signed char>&, signed char*>(signed char*, signed char*, __less<signed char>&))
474_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<unsigned char>&, unsigned char*>(unsigned char*, unsigned char*, __less<unsigned char>&))
475_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<short>&, short*>(short*, short*, __less<short>&))
476_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<unsigned short>&, unsigned short*>(unsigned short*, unsigned short*, __less<unsigned short>&))
477_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<int>&, int*>(int*, int*, __less<int>&))
478_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<unsigned>&, unsigned*>(unsigned*, unsigned*, __less<unsigned>&))
479_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<long>&, long*>(long*, long*, __less<long>&))
480_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<unsigned long>&, unsigned long*>(unsigned long*, unsigned long*, __less<unsigned long>&))
481_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<long long>&, long long*>(long long*, long long*, __less<long long>&))
482_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<unsigned long long>&, unsigned long long*>(unsigned long long*, unsigned long long*, __less<unsigned long long>&))
483_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<float>&, float*>(float*, float*, __less<float>&))
484_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<double>&, double*>(double*, double*, __less<double>&))
485_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<long double>&, long double*>(long double*, long double*, __less<long double>&))
486
487_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<char>&, char*>(char*, char*, __less<char>&))
488_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<wchar_t>&, wchar_t*>(wchar_t*, wchar_t*, __less<wchar_t>&))
489_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<signed char>&, signed char*>(signed char*, signed char*, __less<signed char>&))
490_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned char>&, unsigned char*>(unsigned char*, unsigned char*, __less<unsigned char>&))
491_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<short>&, short*>(short*, short*, __less<short>&))
492_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned short>&, unsigned short*>(unsigned short*, unsigned short*, __less<unsigned short>&))
493_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<int>&, int*>(int*, int*, __less<int>&))
494_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned>&, unsigned*>(unsigned*, unsigned*, __less<unsigned>&))
495_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<long>&, long*>(long*, long*, __less<long>&))
496_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned long>&, unsigned long*>(unsigned long*, unsigned long*, __less<unsigned long>&))
497_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<long long>&, long long*>(long long*, long long*, __less<long long>&))
498_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned long long>&, unsigned long long*>(unsigned long long*, unsigned long long*, __less<unsigned long long>&))
499_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<float>&, float*>(float*, float*, __less<float>&))
500_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<double>&, double*>(double*, double*, __less<double>&))
501_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<long double>&, long double*>(long double*, long double*, __less<long double>&))
502
503_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS unsigned __sort5<__less<long double>&, long double*>(long double*, long double*, long double*, long double*, long double*, __less<long double>&))
504
505template <class _RandomAccessIterator, class _Compare>
506inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
507void
508sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
509{
510 typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
511 if (__libcpp_is_constant_evaluated()) {
512 _VSTD::__partial_sort<_Comp_ref>(__first, __last, __last, _Comp_ref(__comp));
513 } else {
514 _VSTD::__sort<_Comp_ref>(_VSTD::__unwrap_iter(__first), _VSTD::__unwrap_iter(__last), _Comp_ref(__comp));
515 }
516}
517
518template <class _RandomAccessIterator>
519inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
520void
521sort(_RandomAccessIterator __first, _RandomAccessIterator __last)
522{
523 _VSTD::sort(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
524}
525
526_LIBCPP_END_NAMESPACE_STD
527
528_LIBCPP_POP_MACROS
529
530#endif // _LIBCPP___ALGORITHM_SORT_H
lib/libcxx/include/__algorithm/sort_heap.h created+58
......@@ -0,0 +1,58 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_SORT_HEAP_H
10#define _LIBCPP___ALGORITHM_SORT_HEAP_H
11
12#include <__config>
13#include <__algorithm/comp.h>
14#include <__algorithm/comp_ref_type.h>
15#include <__algorithm/pop_heap.h>
16#include <__iterator/iterator_traits.h>
17#include <type_traits> // swap
18
19#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
20#pragma GCC system_header
21#endif
22
23_LIBCPP_PUSH_MACROS
24#include <__undef_macros>
25
26_LIBCPP_BEGIN_NAMESPACE_STD
27
28template <class _Compare, class _RandomAccessIterator>
29_LIBCPP_CONSTEXPR_AFTER_CXX17 void
30__sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
31{
32 typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
33 for (difference_type __n = __last - __first; __n > 1; --__last, (void) --__n)
34 _VSTD::__pop_heap<_Compare>(__first, __last, __comp, __n);
35}
36
37template <class _RandomAccessIterator, class _Compare>
38inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
39void
40sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
41{
42 typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
43 _VSTD::__sort_heap<_Comp_ref>(__first, __last, __comp);
44}
45
46template <class _RandomAccessIterator>
47inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
48void
49sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
50{
51 _VSTD::sort_heap(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
52}
53
54_LIBCPP_END_NAMESPACE_STD
55
56_LIBCPP_POP_MACROS
57
58#endif // _LIBCPP___ALGORITHM_SORT_HEAP_H
lib/libcxx/include/__algorithm/stable_partition.h created+305
......@@ -0,0 +1,305 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_STABLE_PARTITION_H
10#define _LIBCPP___ALGORITHM_STABLE_PARTITION_H
11
12#include <__config>
13#include <__algorithm/rotate.h>
14#include <__iterator/iterator_traits.h>
15#include <__utility/swap.h>
16#include <memory>
17
18#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
19#pragma GCC system_header
20#endif
21
22_LIBCPP_PUSH_MACROS
23#include <__undef_macros>
24
25_LIBCPP_BEGIN_NAMESPACE_STD
26
27template <class _Predicate, class _ForwardIterator, class _Distance, class _Pair>
28_ForwardIterator
29__stable_partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred,
30 _Distance __len, _Pair __p, forward_iterator_tag __fit)
31{
32 // *__first is known to be false
33 // __len >= 1
34 if (__len == 1)
35 return __first;
36 if (__len == 2)
37 {
38 _ForwardIterator __m = __first;
39 if (__pred(*++__m))
40 {
41 swap(*__first, *__m);
42 return __m;
43 }
44 return __first;
45 }
46 if (__len <= __p.second)
47 { // The buffer is big enough to use
48 typedef typename iterator_traits<_ForwardIterator>::value_type value_type;
49 __destruct_n __d(0);
50 unique_ptr<value_type, __destruct_n&> __h(__p.first, __d);
51 // Move the falses into the temporary buffer, and the trues to the front of the line
52 // Update __first to always point to the end of the trues
53 value_type* __t = __p.first;
54 ::new ((void*)__t) value_type(_VSTD::move(*__first));
55 __d.template __incr<value_type>();
56 ++__t;
57 _ForwardIterator __i = __first;
58 while (++__i != __last)
59 {
60 if (__pred(*__i))
61 {
62 *__first = _VSTD::move(*__i);
63 ++__first;
64 }
65 else
66 {
67 ::new ((void*)__t) value_type(_VSTD::move(*__i));
68 __d.template __incr<value_type>();
69 ++__t;
70 }
71 }
72 // All trues now at start of range, all falses in buffer
73 // Move falses back into range, but don't mess up __first which points to first false
74 __i = __first;
75 for (value_type* __t2 = __p.first; __t2 < __t; ++__t2, (void) ++__i)
76 *__i = _VSTD::move(*__t2);
77 // __h destructs moved-from values out of the temp buffer, but doesn't deallocate buffer
78 return __first;
79 }
80 // Else not enough buffer, do in place
81 // __len >= 3
82 _ForwardIterator __m = __first;
83 _Distance __len2 = __len / 2; // __len2 >= 2
84 _VSTD::advance(__m, __len2);
85 // recurse on [__first, __m), *__first know to be false
86 // F?????????????????
87 // f m l
88 typedef typename add_lvalue_reference<_Predicate>::type _PredRef;
89 _ForwardIterator __first_false = _VSTD::__stable_partition<_PredRef>(__first, __m, __pred, __len2, __p, __fit);
90 // TTTFFFFF??????????
91 // f ff m l
92 // recurse on [__m, __last], except increase __m until *(__m) is false, *__last know to be true
93 _ForwardIterator __m1 = __m;
94 _ForwardIterator __second_false = __last;
95 _Distance __len_half = __len - __len2;
96 while (__pred(*__m1))
97 {
98 if (++__m1 == __last)
99 goto __second_half_done;
100 --__len_half;
101 }
102 // TTTFFFFFTTTF??????
103 // f ff m m1 l
104 __second_false = _VSTD::__stable_partition<_PredRef>(__m1, __last, __pred, __len_half, __p, __fit);
105__second_half_done:
106 // TTTFFFFFTTTTTFFFFF
107 // f ff m sf l
108 return _VSTD::rotate(__first_false, __m, __second_false);
109 // TTTTTTTTFFFFFFFFFF
110 // |
111}
112
113template <class _Predicate, class _ForwardIterator>
114_ForwardIterator
115__stable_partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred,
116 forward_iterator_tag)
117{
118 const unsigned __alloc_limit = 3; // might want to make this a function of trivial assignment
119 // Either prove all true and return __first or point to first false
120 while (true)
121 {
122 if (__first == __last)
123 return __first;
124 if (!__pred(*__first))
125 break;
126 ++__first;
127 }
128 // We now have a reduced range [__first, __last)
129 // *__first is known to be false
130 typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type;
131 typedef typename iterator_traits<_ForwardIterator>::value_type value_type;
132 difference_type __len = _VSTD::distance(__first, __last);
133 pair<value_type*, ptrdiff_t> __p(0, 0);
134 unique_ptr<value_type, __return_temporary_buffer> __h;
135 if (__len >= __alloc_limit)
136 {
137 __p = _VSTD::get_temporary_buffer<value_type>(__len);
138 __h.reset(__p.first);
139 }
140 return _VSTD::__stable_partition<typename add_lvalue_reference<_Predicate>::type>
141 (__first, __last, __pred, __len, __p, forward_iterator_tag());
142}
143
144template <class _Predicate, class _BidirectionalIterator, class _Distance, class _Pair>
145_BidirectionalIterator
146__stable_partition(_BidirectionalIterator __first, _BidirectionalIterator __last, _Predicate __pred,
147 _Distance __len, _Pair __p, bidirectional_iterator_tag __bit)
148{
149 // *__first is known to be false
150 // *__last is known to be true
151 // __len >= 2
152 if (__len == 2)
153 {
154 swap(*__first, *__last);
155 return __last;
156 }
157 if (__len == 3)
158 {
159 _BidirectionalIterator __m = __first;
160 if (__pred(*++__m))
161 {
162 swap(*__first, *__m);
163 swap(*__m, *__last);
164 return __last;
165 }
166 swap(*__m, *__last);
167 swap(*__first, *__m);
168 return __m;
169 }
170 if (__len <= __p.second)
171 { // The buffer is big enough to use
172 typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;
173 __destruct_n __d(0);
174 unique_ptr<value_type, __destruct_n&> __h(__p.first, __d);
175 // Move the falses into the temporary buffer, and the trues to the front of the line
176 // Update __first to always point to the end of the trues
177 value_type* __t = __p.first;
178 ::new ((void*)__t) value_type(_VSTD::move(*__first));
179 __d.template __incr<value_type>();
180 ++__t;
181 _BidirectionalIterator __i = __first;
182 while (++__i != __last)
183 {
184 if (__pred(*__i))
185 {
186 *__first = _VSTD::move(*__i);
187 ++__first;
188 }
189 else
190 {
191 ::new ((void*)__t) value_type(_VSTD::move(*__i));
192 __d.template __incr<value_type>();
193 ++__t;
194 }
195 }
196 // move *__last, known to be true
197 *__first = _VSTD::move(*__i);
198 __i = ++__first;
199 // All trues now at start of range, all falses in buffer
200 // Move falses back into range, but don't mess up __first which points to first false
201 for (value_type* __t2 = __p.first; __t2 < __t; ++__t2, (void) ++__i)
202 *__i = _VSTD::move(*__t2);
203 // __h destructs moved-from values out of the temp buffer, but doesn't deallocate buffer
204 return __first;
205 }
206 // Else not enough buffer, do in place
207 // __len >= 4
208 _BidirectionalIterator __m = __first;
209 _Distance __len2 = __len / 2; // __len2 >= 2
210 _VSTD::advance(__m, __len2);
211 // recurse on [__first, __m-1], except reduce __m-1 until *(__m-1) is true, *__first know to be false
212 // F????????????????T
213 // f m l
214 _BidirectionalIterator __m1 = __m;
215 _BidirectionalIterator __first_false = __first;
216 _Distance __len_half = __len2;
217 while (!__pred(*--__m1))
218 {
219 if (__m1 == __first)
220 goto __first_half_done;
221 --__len_half;
222 }
223 // F???TFFF?????????T
224 // f m1 m l
225 typedef typename add_lvalue_reference<_Predicate>::type _PredRef;
226 __first_false = _VSTD::__stable_partition<_PredRef>(__first, __m1, __pred, __len_half, __p, __bit);
227__first_half_done:
228 // TTTFFFFF?????????T
229 // f ff m l
230 // recurse on [__m, __last], except increase __m until *(__m) is false, *__last know to be true
231 __m1 = __m;
232 _BidirectionalIterator __second_false = __last;
233 ++__second_false;
234 __len_half = __len - __len2;
235 while (__pred(*__m1))
236 {
237 if (++__m1 == __last)
238 goto __second_half_done;
239 --__len_half;
240 }
241 // TTTFFFFFTTTF?????T
242 // f ff m m1 l
243 __second_false = _VSTD::__stable_partition<_PredRef>(__m1, __last, __pred, __len_half, __p, __bit);
244__second_half_done:
245 // TTTFFFFFTTTTTFFFFF
246 // f ff m sf l
247 return _VSTD::rotate(__first_false, __m, __second_false);
248 // TTTTTTTTFFFFFFFFFF
249 // |
250}
251
252template <class _Predicate, class _BidirectionalIterator>
253_BidirectionalIterator
254__stable_partition(_BidirectionalIterator __first, _BidirectionalIterator __last, _Predicate __pred,
255 bidirectional_iterator_tag)
256{
257 typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type;
258 typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;
259 const difference_type __alloc_limit = 4; // might want to make this a function of trivial assignment
260 // Either prove all true and return __first or point to first false
261 while (true)
262 {
263 if (__first == __last)
264 return __first;
265 if (!__pred(*__first))
266 break;
267 ++__first;
268 }
269 // __first points to first false, everything prior to __first is already set.
270 // Either prove [__first, __last) is all false and return __first, or point __last to last true
271 do
272 {
273 if (__first == --__last)
274 return __first;
275 } while (!__pred(*__last));
276 // We now have a reduced range [__first, __last]
277 // *__first is known to be false
278 // *__last is known to be true
279 // __len >= 2
280 difference_type __len = _VSTD::distance(__first, __last) + 1;
281 pair<value_type*, ptrdiff_t> __p(0, 0);
282 unique_ptr<value_type, __return_temporary_buffer> __h;
283 if (__len >= __alloc_limit)
284 {
285 __p = _VSTD::get_temporary_buffer<value_type>(__len);
286 __h.reset(__p.first);
287 }
288 return _VSTD::__stable_partition<typename add_lvalue_reference<_Predicate>::type>
289 (__first, __last, __pred, __len, __p, bidirectional_iterator_tag());
290}
291
292template <class _ForwardIterator, class _Predicate>
293inline _LIBCPP_INLINE_VISIBILITY
294_ForwardIterator
295stable_partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred)
296{
297 return _VSTD::__stable_partition<typename add_lvalue_reference<_Predicate>::type>
298 (__first, __last, __pred, typename iterator_traits<_ForwardIterator>::iterator_category());
299}
300
301_LIBCPP_END_NAMESPACE_STD
302
303_LIBCPP_POP_MACROS
304
305#endif // _LIBCPP___ALGORITHM_STABLE_PARTITION_H
lib/libcxx/include/__algorithm/stable_sort.h created+235
......@@ -0,0 +1,235 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_STABLE_SORT_H
10#define _LIBCPP___ALGORITHM_STABLE_SORT_H
11
12#include <__config>
13#include <__algorithm/comp.h>
14#include <__algorithm/comp_ref_type.h>
15#include <__algorithm/inplace_merge.h>
16#include <__algorithm/sort.h>
17#include <__iterator/iterator_traits.h>
18#include <__utility/swap.h>
19#include <memory>
20#include <type_traits> // swap
21
22#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
23#pragma GCC system_header
24#endif
25
26_LIBCPP_PUSH_MACROS
27#include <__undef_macros>
28
29_LIBCPP_BEGIN_NAMESPACE_STD
30
31template <class _Compare, class _InputIterator1, class _InputIterator2>
32void
33__merge_move_construct(_InputIterator1 __first1, _InputIterator1 __last1,
34 _InputIterator2 __first2, _InputIterator2 __last2,
35 typename iterator_traits<_InputIterator1>::value_type* __result, _Compare __comp)
36{
37 typedef typename iterator_traits<_InputIterator1>::value_type value_type;
38 __destruct_n __d(0);
39 unique_ptr<value_type, __destruct_n&> __h(__result, __d);
40 for (; true; ++__result)
41 {
42 if (__first1 == __last1)
43 {
44 for (; __first2 != __last2; ++__first2, ++__result, (void)__d.template __incr<value_type>())
45 ::new ((void*)__result) value_type(_VSTD::move(*__first2));
46 __h.release();
47 return;
48 }
49 if (__first2 == __last2)
50 {
51 for (; __first1 != __last1; ++__first1, ++__result, (void)__d.template __incr<value_type>())
52 ::new ((void*)__result) value_type(_VSTD::move(*__first1));
53 __h.release();
54 return;
55 }
56 if (__comp(*__first2, *__first1))
57 {
58 ::new ((void*)__result) value_type(_VSTD::move(*__first2));
59 __d.template __incr<value_type>();
60 ++__first2;
61 }
62 else
63 {
64 ::new ((void*)__result) value_type(_VSTD::move(*__first1));
65 __d.template __incr<value_type>();
66 ++__first1;
67 }
68 }
69}
70
71template <class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator>
72void
73__merge_move_assign(_InputIterator1 __first1, _InputIterator1 __last1,
74 _InputIterator2 __first2, _InputIterator2 __last2,
75 _OutputIterator __result, _Compare __comp)
76{
77 for (; __first1 != __last1; ++__result)
78 {
79 if (__first2 == __last2)
80 {
81 for (; __first1 != __last1; ++__first1, (void) ++__result)
82 *__result = _VSTD::move(*__first1);
83 return;
84 }
85 if (__comp(*__first2, *__first1))
86 {
87 *__result = _VSTD::move(*__first2);
88 ++__first2;
89 }
90 else
91 {
92 *__result = _VSTD::move(*__first1);
93 ++__first1;
94 }
95 }
96 for (; __first2 != __last2; ++__first2, (void) ++__result)
97 *__result = _VSTD::move(*__first2);
98}
99
100template <class _Compare, class _RandomAccessIterator>
101void
102__stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp,
103 typename iterator_traits<_RandomAccessIterator>::difference_type __len,
104 typename iterator_traits<_RandomAccessIterator>::value_type* __buff, ptrdiff_t __buff_size);
105
106template <class _Compare, class _RandomAccessIterator>
107void
108__stable_sort_move(_RandomAccessIterator __first1, _RandomAccessIterator __last1, _Compare __comp,
109 typename iterator_traits<_RandomAccessIterator>::difference_type __len,
110 typename iterator_traits<_RandomAccessIterator>::value_type* __first2)
111{
112 typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
113 switch (__len)
114 {
115 case 0:
116 return;
117 case 1:
118 ::new ((void*)__first2) value_type(_VSTD::move(*__first1));
119 return;
120 case 2:
121 __destruct_n __d(0);
122 unique_ptr<value_type, __destruct_n&> __h2(__first2, __d);
123 if (__comp(*--__last1, *__first1))
124 {
125 ::new ((void*)__first2) value_type(_VSTD::move(*__last1));
126 __d.template __incr<value_type>();
127 ++__first2;
128 ::new ((void*)__first2) value_type(_VSTD::move(*__first1));
129 }
130 else
131 {
132 ::new ((void*)__first2) value_type(_VSTD::move(*__first1));
133 __d.template __incr<value_type>();
134 ++__first2;
135 ::new ((void*)__first2) value_type(_VSTD::move(*__last1));
136 }
137 __h2.release();
138 return;
139 }
140 if (__len <= 8)
141 {
142 _VSTD::__insertion_sort_move<_Compare>(__first1, __last1, __first2, __comp);
143 return;
144 }
145 typename iterator_traits<_RandomAccessIterator>::difference_type __l2 = __len / 2;
146 _RandomAccessIterator __m = __first1 + __l2;
147 _VSTD::__stable_sort<_Compare>(__first1, __m, __comp, __l2, __first2, __l2);
148 _VSTD::__stable_sort<_Compare>(__m, __last1, __comp, __len - __l2, __first2 + __l2, __len - __l2);
149 _VSTD::__merge_move_construct<_Compare>(__first1, __m, __m, __last1, __first2, __comp);
150}
151
152template <class _Tp>
153struct __stable_sort_switch
154{
155 static const unsigned value = 128*is_trivially_copy_assignable<_Tp>::value;
156};
157
158template <class _Compare, class _RandomAccessIterator>
159void
160__stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp,
161 typename iterator_traits<_RandomAccessIterator>::difference_type __len,
162 typename iterator_traits<_RandomAccessIterator>::value_type* __buff, ptrdiff_t __buff_size)
163{
164 typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
165 typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
166 switch (__len)
167 {
168 case 0:
169 case 1:
170 return;
171 case 2:
172 if (__comp(*--__last, *__first))
173 swap(*__first, *__last);
174 return;
175 }
176 if (__len <= static_cast<difference_type>(__stable_sort_switch<value_type>::value))
177 {
178 _VSTD::__insertion_sort<_Compare>(__first, __last, __comp);
179 return;
180 }
181 typename iterator_traits<_RandomAccessIterator>::difference_type __l2 = __len / 2;
182 _RandomAccessIterator __m = __first + __l2;
183 if (__len <= __buff_size)
184 {
185 __destruct_n __d(0);
186 unique_ptr<value_type, __destruct_n&> __h2(__buff, __d);
187 _VSTD::__stable_sort_move<_Compare>(__first, __m, __comp, __l2, __buff);
188 __d.__set(__l2, (value_type*)nullptr);
189 _VSTD::__stable_sort_move<_Compare>(__m, __last, __comp, __len - __l2, __buff + __l2);
190 __d.__set(__len, (value_type*)nullptr);
191 _VSTD::__merge_move_assign<_Compare>(__buff, __buff + __l2, __buff + __l2, __buff + __len, __first, __comp);
192// _VSTD::__merge<_Compare>(move_iterator<value_type*>(__buff),
193// move_iterator<value_type*>(__buff + __l2),
194// move_iterator<_RandomAccessIterator>(__buff + __l2),
195// move_iterator<_RandomAccessIterator>(__buff + __len),
196// __first, __comp);
197 return;
198 }
199 _VSTD::__stable_sort<_Compare>(__first, __m, __comp, __l2, __buff, __buff_size);
200 _VSTD::__stable_sort<_Compare>(__m, __last, __comp, __len - __l2, __buff, __buff_size);
201 _VSTD::__inplace_merge<_Compare>(__first, __m, __last, __comp, __l2, __len - __l2, __buff, __buff_size);
202}
203
204template <class _RandomAccessIterator, class _Compare>
205inline _LIBCPP_INLINE_VISIBILITY
206void
207stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
208{
209 typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
210 typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
211 difference_type __len = __last - __first;
212 pair<value_type*, ptrdiff_t> __buf(0, 0);
213 unique_ptr<value_type, __return_temporary_buffer> __h;
214 if (__len > static_cast<difference_type>(__stable_sort_switch<value_type>::value))
215 {
216 __buf = _VSTD::get_temporary_buffer<value_type>(__len);
217 __h.reset(__buf.first);
218 }
219 typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
220 _VSTD::__stable_sort<_Comp_ref>(__first, __last, __comp, __len, __buf.first, __buf.second);
221}
222
223template <class _RandomAccessIterator>
224inline _LIBCPP_INLINE_VISIBILITY
225void
226stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last)
227{
228 _VSTD::stable_sort(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
229}
230
231_LIBCPP_END_NAMESPACE_STD
232
233_LIBCPP_POP_MACROS
234
235#endif // _LIBCPP___ALGORITHM_STABLE_SORT_H
lib/libcxx/include/__algorithm/swap_ranges.h created+37
......@@ -0,0 +1,37 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_SWAP_RANGES_H
10#define _LIBCPP___ALGORITHM_SWAP_RANGES_H
11
12#include <__config>
13#include <__utility/swap.h>
14#include <type_traits>
15
16#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
17#pragma GCC system_header
18#endif
19
20_LIBCPP_PUSH_MACROS
21#include <__undef_macros>
22
23_LIBCPP_BEGIN_NAMESPACE_STD
24
25template <class _ForwardIterator1, class _ForwardIterator2>
26inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator2
27swap_ranges(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2) {
28 for (; __first1 != __last1; ++__first1, (void)++__first2)
29 swap(*__first1, *__first2);
30 return __first2;
31}
32
33_LIBCPP_END_NAMESPACE_STD
34
35_LIBCPP_POP_MACROS
36
37#endif // _LIBCPP___ALGORITHM_SWAP_RANGES_H
lib/libcxx/include/__algorithm/transform.h created+48
......@@ -0,0 +1,48 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_TRANSFORM_H
10#define _LIBCPP___ALGORITHM_TRANSFORM_H
11
12#include <__config>
13
14#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
15#pragma GCC system_header
16#endif
17
18_LIBCPP_PUSH_MACROS
19#include <__undef_macros>
20
21_LIBCPP_BEGIN_NAMESPACE_STD
22
23template <class _InputIterator, class _OutputIterator, class _UnaryOperation>
24inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
25_OutputIterator
26transform(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _UnaryOperation __op)
27{
28 for (; __first != __last; ++__first, (void) ++__result)
29 *__result = __op(*__first);
30 return __result;
31}
32
33template <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _BinaryOperation>
34inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
35_OutputIterator
36transform(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2,
37 _OutputIterator __result, _BinaryOperation __binary_op)
38{
39 for (; __first1 != __last1; ++__first1, (void) ++__first2, ++__result)
40 *__result = __binary_op(*__first1, *__first2);
41 return __result;
42}
43
44_LIBCPP_END_NAMESPACE_STD
45
46_LIBCPP_POP_MACROS
47
48#endif // _LIBCPP___ALGORITHM_TRANSFORM_H
lib/libcxx/include/__algorithm/unique.h created+63
......@@ -0,0 +1,63 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_UNIQUE_H
10#define _LIBCPP___ALGORITHM_UNIQUE_H
11
12#include <__config>
13#include <__algorithm/comp.h>
14#include <__algorithm/adjacent_find.h>
15#include <__iterator/iterator_traits.h>
16#include <__utility/move.h>
17#include <type_traits>
18
19#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
20#pragma GCC system_header
21#endif
22
23_LIBCPP_PUSH_MACROS
24#include <__undef_macros>
25
26_LIBCPP_BEGIN_NAMESPACE_STD
27
28// unique
29
30template <class _ForwardIterator, class _BinaryPredicate>
31_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator
32unique(_ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred)
33{
34 __first = _VSTD::adjacent_find<_ForwardIterator, typename add_lvalue_reference<_BinaryPredicate>::type>
35 (__first, __last, __pred);
36 if (__first != __last)
37 {
38 // ... a a ? ...
39 // f i
40 _ForwardIterator __i = __first;
41 for (++__i; ++__i != __last;)
42 if (!__pred(*__first, *__i))
43 *++__first = _VSTD::move(*__i);
44 ++__first;
45 }
46 return __first;
47}
48
49template <class _ForwardIterator>
50_LIBCPP_NODISCARD_EXT inline
51_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
52_ForwardIterator
53unique(_ForwardIterator __first, _ForwardIterator __last)
54{
55 typedef typename iterator_traits<_ForwardIterator>::value_type __v;
56 return _VSTD::unique(__first, __last, __equal_to<__v>());
57}
58
59_LIBCPP_END_NAMESPACE_STD
60
61_LIBCPP_POP_MACROS
62
63#endif // _LIBCPP___ALGORITHM_UNIQUE_H
lib/libcxx/include/__algorithm/unique_copy.h created+114
......@@ -0,0 +1,114 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_UNIQUE_COPY_H
10#define _LIBCPP___ALGORITHM_UNIQUE_COPY_H
11
12#include <__config>
13#include <__algorithm/comp.h>
14#include <__iterator/iterator_traits.h>
15#include <utility>
16#include <type_traits>
17
18#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
19#pragma GCC system_header
20#endif
21
22_LIBCPP_PUSH_MACROS
23#include <__undef_macros>
24
25_LIBCPP_BEGIN_NAMESPACE_STD
26
27template <class _BinaryPredicate, class _InputIterator, class _OutputIterator>
28_LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator
29__unique_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _BinaryPredicate __pred,
30 input_iterator_tag, output_iterator_tag)
31{
32 if (__first != __last)
33 {
34 typename iterator_traits<_InputIterator>::value_type __t(*__first);
35 *__result = __t;
36 ++__result;
37 while (++__first != __last)
38 {
39 if (!__pred(__t, *__first))
40 {
41 __t = *__first;
42 *__result = __t;
43 ++__result;
44 }
45 }
46 }
47 return __result;
48}
49
50template <class _BinaryPredicate, class _ForwardIterator, class _OutputIterator>
51_LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator
52__unique_copy(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result, _BinaryPredicate __pred,
53 forward_iterator_tag, output_iterator_tag)
54{
55 if (__first != __last)
56 {
57 _ForwardIterator __i = __first;
58 *__result = *__i;
59 ++__result;
60 while (++__first != __last)
61 {
62 if (!__pred(*__i, *__first))
63 {
64 *__result = *__first;
65 ++__result;
66 __i = __first;
67 }
68 }
69 }
70 return __result;
71}
72
73template <class _BinaryPredicate, class _InputIterator, class _ForwardIterator>
74_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator
75__unique_copy(_InputIterator __first, _InputIterator __last, _ForwardIterator __result, _BinaryPredicate __pred,
76 input_iterator_tag, forward_iterator_tag)
77{
78 if (__first != __last)
79 {
80 *__result = *__first;
81 while (++__first != __last)
82 if (!__pred(*__result, *__first))
83 *++__result = *__first;
84 ++__result;
85 }
86 return __result;
87}
88
89template <class _InputIterator, class _OutputIterator, class _BinaryPredicate>
90inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
91_OutputIterator
92unique_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _BinaryPredicate __pred)
93{
94 return _VSTD::__unique_copy<typename add_lvalue_reference<_BinaryPredicate>::type>
95 (__first, __last, __result, __pred,
96 typename iterator_traits<_InputIterator>::iterator_category(),
97 typename iterator_traits<_OutputIterator>::iterator_category());
98}
99
100template <class _InputIterator, class _OutputIterator>
101inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
102_OutputIterator
103unique_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
104{
105 typedef typename iterator_traits<_InputIterator>::value_type __v;
106 return _VSTD::unique_copy(__first, __last, __result, __equal_to<__v>());
107}
108
109
110_LIBCPP_END_NAMESPACE_STD
111
112_LIBCPP_POP_MACROS
113
114#endif // _LIBCPP___ALGORITHM_UNIQUE_COPY_H
lib/libcxx/include/__algorithm/unwrap_iter.h created+87
......@@ -0,0 +1,87 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_UNWRAP_ITER_H
10#define _LIBCPP___ALGORITHM_UNWRAP_ITER_H
11
12#include <__config>
13#include <iterator>
14#include <__memory/pointer_traits.h>
15#include <type_traits>
16
17#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
18#pragma GCC system_header
19#endif
20
21_LIBCPP_PUSH_MACROS
22#include <__undef_macros>
23
24_LIBCPP_BEGIN_NAMESPACE_STD
25
26// The job of __unwrap_iter is to lower contiguous iterators (such as
27// vector<T>::iterator) into pointers, to reduce the number of template
28// instantiations and to enable pointer-based optimizations e.g. in std::copy.
29// For iterators that are not contiguous, it must be a no-op.
30// In debug mode, we don't do this.
31//
32// __unwrap_iter is non-constexpr for user-defined iterators whose
33// `to_address` and/or `operator->` is non-constexpr. This is okay; but we
34// try to avoid doing __unwrap_iter in constant-evaluated contexts anyway.
35//
36// Some algorithms (e.g. std::copy, but not std::sort) need to convert an
37// "unwrapped" result back into a contiguous iterator. Since contiguous iterators
38// are random-access, we can do this portably using iterator arithmetic; this
39// is the job of __rewrap_iter.
40
41template <class _Iter, bool = __is_cpp17_contiguous_iterator<_Iter>::value>
42struct __unwrap_iter_impl {
43 static _LIBCPP_CONSTEXPR _Iter
44 __apply(_Iter __i) _NOEXCEPT {
45 return __i;
46 }
47};
48
49#if _LIBCPP_DEBUG_LEVEL < 2
50
51template <class _Iter>
52struct __unwrap_iter_impl<_Iter, true> {
53 static _LIBCPP_CONSTEXPR decltype(_VSTD::__to_address(declval<_Iter>()))
54 __apply(_Iter __i) _NOEXCEPT {
55 return _VSTD::__to_address(__i);
56 }
57};
58
59#endif // _LIBCPP_DEBUG_LEVEL < 2
60
61template<class _Iter, class _Impl = __unwrap_iter_impl<_Iter> >
62inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
63decltype(_Impl::__apply(declval<_Iter>()))
64__unwrap_iter(_Iter __i) _NOEXCEPT
65{
66 return _Impl::__apply(__i);
67}
68
69template<class _OrigIter>
70_OrigIter __rewrap_iter(_OrigIter, _OrigIter __result)
71{
72 return __result;
73}
74
75template<class _OrigIter, class _UnwrappedIter>
76_OrigIter __rewrap_iter(_OrigIter __first, _UnwrappedIter __result)
77{
78 // Precondition: __result is reachable from __first
79 // Precondition: _OrigIter is a contiguous iterator
80 return __first + (__result - _VSTD::__unwrap_iter(__first));
81}
82
83_LIBCPP_END_NAMESPACE_STD
84
85_LIBCPP_POP_MACROS
86
87#endif // _LIBCPP___ALGORITHM_UNWRAP_ITER_H
lib/libcxx/include/__algorithm/upper_bound.h created+72
......@@ -0,0 +1,72 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_UPPER_BOUND_H
10#define _LIBCPP___ALGORITHM_UPPER_BOUND_H
11
12#include <__config>
13#include <__algorithm/comp.h>
14#include <__algorithm/half_positive.h>
15#include <iterator>
16
17#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
18#pragma GCC system_header
19#endif
20
21_LIBCPP_PUSH_MACROS
22#include <__undef_macros>
23
24_LIBCPP_BEGIN_NAMESPACE_STD
25
26template <class _Compare, class _ForwardIterator, class _Tp>
27_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator
28__upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp)
29{
30 typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type;
31 difference_type __len = _VSTD::distance(__first, __last);
32 while (__len != 0)
33 {
34 difference_type __l2 = _VSTD::__half_positive(__len);
35 _ForwardIterator __m = __first;
36 _VSTD::advance(__m, __l2);
37 if (__comp(__value_, *__m))
38 __len = __l2;
39 else
40 {
41 __first = ++__m;
42 __len -= __l2 + 1;
43 }
44 }
45 return __first;
46}
47
48template <class _ForwardIterator, class _Tp, class _Compare>
49_LIBCPP_NODISCARD_EXT inline
50_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
51_ForwardIterator
52upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp)
53{
54 typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
55 return _VSTD::__upper_bound<_Comp_ref>(__first, __last, __value_, __comp);
56}
57
58template <class _ForwardIterator, class _Tp>
59_LIBCPP_NODISCARD_EXT inline
60_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
61_ForwardIterator
62upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_)
63{
64 return _VSTD::upper_bound(__first, __last, __value_,
65 __less<_Tp, typename iterator_traits<_ForwardIterator>::value_type>());
66}
67
68_LIBCPP_END_NAMESPACE_STD
69
70_LIBCPP_POP_MACROS
71
72#endif // _LIBCPP___ALGORITHM_UPPER_BOUND_H
lib/libcxx/include/__availability+66-2
......@@ -43,6 +43,14 @@
4343// as unavailable. When vendors decide to ship the feature as part of their
4444// shared library, they can update the markup appropriately.
4545//
46// Furthermore, many features in the standard library have corresponding
47// feature-test macros. When a feature is made unavailable on some deployment
48// target, a macro should be defined to signal that it is unavailable. That
49// macro can then be picked up when feature-test macros are generated (see
50// generate_feature_test_macro_components.py) to make sure that feature-test
51// macros don't announce a feature as being implemented if it has been marked
52// as unavailable.
53//
4654// Note that this mechanism is disabled by default in the "upstream" libc++.
4755// Availability annotations are only meaningful when shipping libc++ inside
4856// a platform (i.e. as a system library), and so vendors that want them should
......@@ -76,6 +84,8 @@
7684 // This controls the availability of std::shared_mutex and std::shared_timed_mutex,
7785 // which were added to the dylib later.
7886# define _LIBCPP_AVAILABILITY_SHARED_MUTEX
87// # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_mutex
88// # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_timed_mutex
7989
8090 // These macros control the availability of std::bad_optional_access and
8191 // other exception types. These were put in the shared library to prevent
......@@ -114,6 +124,7 @@
114124# define _LIBCPP_AVAILABILITY_FILESYSTEM
115125# define _LIBCPP_AVAILABILITY_FILESYSTEM_PUSH
116126# define _LIBCPP_AVAILABILITY_FILESYSTEM_POP
127// # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_filesystem
117128
118129 // This controls the availability of std::to_chars.
119130# define _LIBCPP_AVAILABILITY_TO_CHARS
......@@ -122,6 +133,17 @@
122133 // which requires shared library support for various operations
123134 // (see libcxx/src/atomic.cpp).
124135# define _LIBCPP_AVAILABILITY_SYNC
136// # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_atomic_wait
137// # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_barrier
138// # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_latch
139// # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_semaphore
140
141 // This controls the availability of the C++20 format library.
142 // The library is in development and not ABI stable yet. Currently
143 // P2216 is aiming to be retroactively accepted in C++20. This paper
144 // contains ABI breaking changes.
145# define _LIBCPP_AVAILABILITY_FORMAT
146// # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_format
125147
126148#elif defined(__APPLE__)
127149
......@@ -130,6 +152,14 @@
130152 __attribute__((availability(ios,strict,introduced=10.0))) \
131153 __attribute__((availability(tvos,strict,introduced=10.0))) \
132154 __attribute__((availability(watchos,strict,introduced=3.0)))
155# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101200) || \
156 (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 100000) || \
157 (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 100000) || \
158 (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 30000)
159# define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_mutex
160# define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_timed_mutex
161# endif
162
133163# define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS \
134164 __attribute__((availability(macosx,strict,introduced=10.13))) \
135165 __attribute__((availability(ios,strict,introduced=11.0))) \
......@@ -139,27 +169,34 @@
139169 _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS
140170# define _LIBCPP_AVAILABILITY_BAD_ANY_CAST \
141171 _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS
172
142173# define _LIBCPP_AVAILABILITY_UNCAUGHT_EXCEPTIONS \
143174 __attribute__((availability(macosx,strict,introduced=10.12))) \
144175 __attribute__((availability(ios,strict,introduced=10.0))) \
145176 __attribute__((availability(tvos,strict,introduced=10.0))) \
146177 __attribute__((availability(watchos,strict,introduced=3.0)))
178
147179# define _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE \
148180 __attribute__((availability(macosx,strict,introduced=10.12))) \
149181 __attribute__((availability(ios,strict,introduced=10.0))) \
150182 __attribute__((availability(tvos,strict,introduced=10.0))) \
151183 __attribute__((availability(watchos,strict,introduced=3.0)))
184
152185# define _LIBCPP_AVAILABILITY_FUTURE_ERROR \
153186 __attribute__((availability(ios,strict,introduced=6.0)))
187
154188# define _LIBCPP_AVAILABILITY_TYPEINFO_VTABLE \
155189 __attribute__((availability(macosx,strict,introduced=10.9))) \
156190 __attribute__((availability(ios,strict,introduced=7.0)))
191
157192# define _LIBCPP_AVAILABILITY_LOCALE_CATEGORY \
158193 __attribute__((availability(macosx,strict,introduced=10.9))) \
159194 __attribute__((availability(ios,strict,introduced=7.0)))
195
160196# define _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR \
161197 __attribute__((availability(macosx,strict,introduced=10.9))) \
162198 __attribute__((availability(ios,strict,introduced=7.0)))
199
163200# define _LIBCPP_AVAILABILITY_FILESYSTEM \
164201 __attribute__((availability(macosx,strict,introduced=10.15))) \
165202 __attribute__((availability(ios,strict,introduced=13.0))) \
......@@ -175,11 +212,38 @@
175212 _Pragma("clang attribute pop") \
176213 _Pragma("clang attribute pop") \
177214 _Pragma("clang attribute pop")
215# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101500) || \
216 (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 130000) || \
217 (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 130000) || \
218 (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 60000)
219# define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_filesystem
220# endif
221
178222# define _LIBCPP_AVAILABILITY_TO_CHARS \
179223 _LIBCPP_AVAILABILITY_FILESYSTEM
224
180225# define _LIBCPP_AVAILABILITY_SYNC \
181 __attribute__((unavailable))
226 __attribute__((availability(macosx,strict,introduced=11.0))) \
227 __attribute__((availability(ios,strict,introduced=14.0))) \
228 __attribute__((availability(tvos,strict,introduced=14.0))) \
229 __attribute__((availability(watchos,strict,introduced=7.0)))
230# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 110000) || \
231 (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 140000) || \
232 (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 140000) || \
233 (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 70000)
234# define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_atomic_wait
235# define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_barrier
236# define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_latch
237# define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_semaphore
238# endif
182239
240 // This controls the availability of the C++20 format library.
241 // The library is in development and not ABI stable yet. Currently
242 // P2216 is aiming to be retroactively accepted in C++20. This paper
243 // contains ABI breaking changes.
244# define _LIBCPP_AVAILABILITY_FORMAT \
245 __attribute__((unavailable))
246# define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_format
183247#else
184248
185249// ...New vendors can add availability markup here...
......@@ -203,4 +267,4 @@
203267# define _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS
204268#endif
205269
206#endif // _LIBCPP___AVAILABILITY
270#endif // _LIBCPP___AVAILABILITY
lib/libcxx/include/__bit_reference+17-19
......@@ -1114,28 +1114,26 @@ public:
11141114#endif
11151115 {}
11161116
1117 // avoid re-declaring a copy constructor for the non-const version.
1118 using __type_for_copy_to_const =
1119 _If<_IsConst, __bit_iterator<_Cp, false>, struct __private_nat>;
1120
1117 // When _IsConst=false, this is the copy constructor.
1118 // It is non-trivial. Making it trivial would break ABI.
1119 // When _IsConst=true, this is a converting constructor;
1120 // the copy and move constructors are implicitly generated
1121 // and trivial.
11211122 _LIBCPP_INLINE_VISIBILITY
1122 __bit_iterator(const __type_for_copy_to_const& __it) _NOEXCEPT
1123 __bit_iterator(const __bit_iterator<_Cp, false>& __it) _NOEXCEPT
11231124 : __seg_(__it.__seg_), __ctz_(__it.__ctz_) {}
11241125
1125 // The non-const __bit_iterator has historically had a non-trivial
1126 // copy constructor (as a quirk of its construction). We need to maintain
1127 // this for ABI purposes.
1128 using __type_for_abi_non_trivial_copy_ctor =
1129 _If<!_IsConst, __bit_iterator, struct __private_nat>;
1130
1131 _LIBCPP_INLINE_VISIBILITY
1132 __bit_iterator(__type_for_abi_non_trivial_copy_ctor const& __it) _NOEXCEPT
1133 : __seg_(__it.__seg_), __ctz_(__it.__ctz_) {}
1134
1135 // Always declare the copy assignment operator since the implicit declaration
1136 // is deprecated.
1126 // When _IsConst=false, we have a user-provided copy constructor,
1127 // so we must also provide a copy assignment operator because
1128 // the implicit generation of a defaulted one is deprecated.
1129 // When _IsConst=true, the assignment operators are
1130 // implicitly generated and trivial.
11371131 _LIBCPP_INLINE_VISIBILITY
1138 __bit_iterator& operator=(__bit_iterator const&) = default;
1132 __bit_iterator& operator=(const _If<_IsConst, struct __private_nat, __bit_iterator>& __it) {
1133 __seg_ = __it.__seg_;
1134 __ctz_ = __it.__ctz_;
1135 return *this;
1136 }
11391137
11401138 _LIBCPP_INLINE_VISIBILITY reference operator*() const _NOEXCEPT
11411139 {return reference(__seg_, __storage_type(1) << __ctz_);}
......@@ -1302,4 +1300,4 @@ _LIBCPP_END_NAMESPACE_STD
13021300
13031301_LIBCPP_POP_MACROS
13041302
1305#endif // _LIBCPP___BIT_REFERENCE
1303#endif // _LIBCPP___BIT_REFERENCE
lib/libcxx/include/__bits+1-2
......@@ -76,7 +76,6 @@ inline _LIBCPP_INLINE_VISIBILITY
7676int __libcpp_ctz(unsigned long long __x) {
7777 unsigned long __where;
7878#if defined(_LIBCPP_HAS_BITSCAN64)
79 (defined(_M_AMD64) || defined(__x86_64__))
8079 if (_BitScanForward64(&__where, __x))
8180 return static_cast<int>(__where);
8281#else
......@@ -143,4 +142,4 @@ _LIBCPP_END_NAMESPACE_STD
143142
144143_LIBCPP_POP_MACROS
145144
146#endif // _LIBCPP__BITS
145#endif // _LIBCPP___BITS
lib/libcxx/include/__bsd_locale_fallbacks.h+2-2
......@@ -13,9 +13,9 @@
1313#ifndef _LIBCPP_BSD_LOCALE_FALLBACKS_DEFAULTS_H
1414#define _LIBCPP_BSD_LOCALE_FALLBACKS_DEFAULTS_H
1515
16#include <stdlib.h>
17#include <stdarg.h>
1816#include <memory>
17#include <stdarg.h>
18#include <stdlib.h>
1919
2020#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2121#pragma GCC system_header
lib/libcxx/include/__config+136-127
......@@ -32,7 +32,7 @@
3232# define _GNUC_VER_NEW 0
3333#endif
3434
35#define _LIBCPP_VERSION 12000
35#define _LIBCPP_VERSION 13000
3636
3737#ifndef _LIBCPP_ABI_VERSION
3838# define _LIBCPP_ABI_VERSION 1
......@@ -54,7 +54,7 @@
5454# else
5555# define _LIBCPP_STD_VER 21 // current year, or date of c++2b ratification
5656# endif
57#endif // _LIBCPP_STD_VER
57#endif // _LIBCPP_STD_VER
5858
5959#if defined(__ELF__)
6060# define _LIBCPP_OBJECT_FORMAT_ELF 1
......@@ -86,17 +86,18 @@
8686// provided under the alternate keyword __nullptr, which changes the mangling
8787// of nullptr_t. This option is ABI incompatible with GCC in C++03 mode.
8888# define _LIBCPP_ABI_ALWAYS_USE_CXX11_NULLPTR
89// Define the `pointer_safety` enum as a C++11 strongly typed enumeration
90// instead of as a class simulating an enum. If this option is enabled
91// `pointer_safety` and `get_pointer_safety()` will no longer be available
92// in C++03.
93# define _LIBCPP_ABI_POINTER_SAFETY_ENUM_TYPE
9489// Define a key function for `bad_function_call` in the library, to centralize
9590// its vtable and typeinfo to libc++ rather than having all other libraries
9691// using that class define their own copies.
9792# define _LIBCPP_ABI_BAD_FUNCTION_CALL_KEY_FUNCTION
9893// Enable optimized version of __do_get_(un)signed which avoids redundant copies.
9994# define _LIBCPP_ABI_OPTIMIZED_LOCALE_NUM_GET
95// In C++20 and later, don't derive std::plus from std::binary_function,
96// nor std::negate from std::unary_function.
97# define _LIBCPP_ABI_NO_BINDER_BASES
98// Give reverse_iterator<T> one data member of type T, not two.
99// Also, in C++17 and later, don't derive iterator types from std::iterator.
100# define _LIBCPP_ABI_NO_ITERATOR_BASES
100101// Use the smallest possible integer type to represent the index of the variant.
101102// Previously libc++ used "unsigned int" exclusively.
102103# define _LIBCPP_ABI_VARIANT_INDEX_TYPE_OPTIMIZATION
......@@ -104,6 +105,8 @@
104105# define _LIBCPP_ABI_OPTIMIZED_FUNCTION
105106// All the regex constants must be distinct and nonzero.
106107# define _LIBCPP_ABI_REGEX_CONSTANTS_NONZERO
108// Use raw pointers, not wrapped ones, for std::span's iterator type.
109# define _LIBCPP_ABI_SPAN_POINTER_ITERATORS
107110// Re-worked external template instantiations for std::string with a focus on
108111// performance and fast-path inlining.
109112# define _LIBCPP_ABI_STRING_OPTIMIZED_EXTERNAL_INSTANTIATION
......@@ -181,11 +184,12 @@
181184#define __has_include(...) 0
182185#endif
183186
184#if defined(__clang__)
185# define _LIBCPP_COMPILER_CLANG
186# ifndef __apple_build_version__
187# define _LIBCPP_CLANG_VER (__clang_major__ * 100 + __clang_minor__)
188# endif
187#if defined(__apple_build_version__)
188# define _LIBCPP_COMPILER_CLANG_BASED
189# define _LIBCPP_APPLE_CLANG_VER (__apple_build_version__ / 10000)
190#elif defined(__clang__)
191# define _LIBCPP_COMPILER_CLANG_BASED
192# define _LIBCPP_CLANG_VER (__clang_major__ * 100 + __clang_minor__)
189193#elif defined(__GNUC__)
190194# define _LIBCPP_COMPILER_GCC
191195#elif defined(_MSC_VER)
......@@ -235,13 +239,13 @@
235239# if __LITTLE_ENDIAN__
236240# define _LIBCPP_LITTLE_ENDIAN
237241# endif // __LITTLE_ENDIAN__
238#endif // __LITTLE_ENDIAN__
242#endif // __LITTLE_ENDIAN__
239243
240244#ifdef __BIG_ENDIAN__
241245# if __BIG_ENDIAN__
242246# define _LIBCPP_BIG_ENDIAN
243247# endif // __BIG_ENDIAN__
244#endif // __BIG_ENDIAN__
248#endif // __BIG_ENDIAN__
245249
246250#ifdef __BYTE_ORDER__
247251# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
......@@ -262,7 +266,7 @@
262266# ifndef __LONG_LONG_SUPPORTED
263267# define _LIBCPP_HAS_NO_LONG_LONG
264268# endif // __LONG_LONG_SUPPORTED
265#endif // __FreeBSD__
269#endif // __FreeBSD__
266270
267271#if defined(__NetBSD__) || defined(__OpenBSD__)
268272# include <sys/endian.h>
......@@ -271,7 +275,7 @@
271275# else // _BYTE_ORDER == _LITTLE_ENDIAN
272276# define _LIBCPP_BIG_ENDIAN
273277# endif // _BYTE_ORDER == _LITTLE_ENDIAN
274#endif // defined(__NetBSD__) || defined(__OpenBSD__)
278#endif // defined(__NetBSD__) || defined(__OpenBSD__)
275279
276280#if defined(_WIN32)
277281# define _LIBCPP_WIN32API
......@@ -340,7 +344,7 @@
340344# else // __BYTE_ORDER == __BIG_ENDIAN
341345# error unable to determine endian
342346# endif
343#endif // !defined(_LIBCPP_LITTLE_ENDIAN) && !defined(_LIBCPP_BIG_ENDIAN)
347#endif // !defined(_LIBCPP_LITTLE_ENDIAN) && !defined(_LIBCPP_BIG_ENDIAN)
344348
345349#if __has_attribute(__no_sanitize__) && !defined(_LIBCPP_COMPILER_GCC)
346350# define _LIBCPP_NO_CFI __attribute__((__no_sanitize__("cfi")))
......@@ -348,7 +352,7 @@
348352# define _LIBCPP_NO_CFI
349353#endif
350354
351#if __ISO_C_VISIBLE >= 2011 || __cplusplus >= 201103L
355#if (defined(__ISO_C_VISIBLE) && (__ISO_C_VISIBLE >= 2011)) || __cplusplus >= 201103L
352356# if defined(__FreeBSD__)
353357# define _LIBCPP_HAS_ALIGNED_ALLOC
354358# define _LIBCPP_HAS_QUICK_EXIT
......@@ -387,13 +391,16 @@
387391# define _LIBCPP_HAS_QUICK_EXIT
388392# define _LIBCPP_HAS_TIMESPEC_GET
389393# endif
394# elif defined(_LIBCPP_MSVCRT)
395 // Using Microsoft's C Runtime library, not MinGW
396# define _LIBCPP_HAS_TIMESPEC_GET
390397# elif defined(__APPLE__)
391398 // timespec_get and aligned_alloc were introduced in macOS 10.15 and
392399 // aligned releases
393# if (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 101500 || \
394 __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ >= 130000 || \
395 __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ >= 130000 || \
396 __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ >= 60000)
400# if ((defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 101500) || \
401 (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ >= 130000) || \
402 (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ >= 130000) || \
403 (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ >= 60000))
397404# define _LIBCPP_HAS_ALIGNED_ALLOC
398405# define _LIBCPP_HAS_TIMESPEC_GET
399406# endif
......@@ -402,7 +409,7 @@
402409
403410#ifndef _LIBCPP_CXX03_LANG
404411# define _LIBCPP_ALIGNOF(_Tp) alignof(_Tp)
405#elif defined(_LIBCPP_COMPILER_CLANG)
412#elif defined(_LIBCPP_COMPILER_CLANG_BASED)
406413# define _LIBCPP_ALIGNOF(_Tp) _Alignof(_Tp)
407414#else
408415# error "We don't know a correct way to implement alignof(T) in C++03 outside of Clang"
......@@ -410,7 +417,7 @@
410417
411418#define _LIBCPP_PREFERRED_ALIGNOF(_Tp) __alignof(_Tp)
412419
413#if defined(_LIBCPP_COMPILER_CLANG)
420#if defined(_LIBCPP_COMPILER_CLANG_BASED)
414421
415422#if defined(_LIBCPP_ALTERNATE_STRING_LAYOUT)
416423# error _LIBCPP_ALTERNATE_STRING_LAYOUT is deprecated, please use _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT instead
......@@ -484,12 +491,12 @@ typedef __char32_t char32_t;
484491#define _LIBCPP_HAS_NO_NOEXCEPT
485492#endif
486493
487#if !defined(_LIBCPP_HAS_NO_ASAN) && !__has_feature(address_sanitizer)
494#if !__has_feature(address_sanitizer)
488495#define _LIBCPP_HAS_NO_ASAN
489496#endif
490497
491498// Allow for build-time disabling of unsigned integer sanitization
492#if !defined(_LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK) && __has_attribute(no_sanitize)
499#if __has_attribute(no_sanitize)
493500#define _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK __attribute__((__no_sanitize__("unsigned-integer-overflow")))
494501#endif
495502
......@@ -508,8 +515,8 @@ typedef __char32_t char32_t;
508515#define _LIBCPP_ALWAYS_INLINE __attribute__ ((__always_inline__))
509516
510517// Literal operators ""d and ""y are supported starting with LLVM Clang 8 and AppleClang 10.0.1
511#if (defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER < 800) || \
512 (defined(__apple_build_version__) && __apple_build_version__ < 10010000)
518#if (defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER < 800) || \
519 (defined(_LIBCPP_APPLE_CLANG_VER) && _LIBCPP_APPLE_CLANG_VER < 1001)
513520#define _LIBCPP_HAS_NO_CXX20_CHRONO_LITERALS
514521#endif
515522
......@@ -522,7 +529,7 @@ typedef __char32_t char32_t;
522529
523530#define _LIBCPP_NORETURN __attribute__((noreturn))
524531
525#if !__EXCEPTIONS
532#if !defined(__EXCEPTIONS)
526533# define _LIBCPP_NO_EXCEPTIONS
527534#endif
528535
......@@ -536,7 +543,7 @@ typedef __char32_t char32_t;
536543#define _LIBCPP_HAS_NO_VARIABLE_TEMPLATES
537544#endif
538545
539#if !defined(_LIBCPP_HAS_NO_ASAN) && !defined(__SANITIZE_ADDRESS__)
546#if !defined(__SANITIZE_ADDRESS__)
540547#define _LIBCPP_HAS_NO_ASAN
541548#endif
542549
......@@ -640,6 +647,7 @@ typedef __char32_t char32_t;
640647#define _LIBCPP_HIDDEN
641648#define _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
642649#define _LIBCPP_TEMPLATE_VIS
650#define _LIBCPP_TEMPLATE_DATA_VIS
643651#define _LIBCPP_ENUM_VIS
644652
645653#endif // defined(_LIBCPP_OBJECT_FORMAT_COFF)
......@@ -689,6 +697,14 @@ typedef __char32_t char32_t;
689697# endif
690698#endif
691699
700#ifndef _LIBCPP_TEMPLATE_DATA_VIS
701# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS)
702# define _LIBCPP_TEMPLATE_DATA_VIS __attribute__ ((__visibility__("default")))
703# else
704# define _LIBCPP_TEMPLATE_DATA_VIS
705# endif
706#endif
707
692708#ifndef _LIBCPP_EXPORTED_FROM_ABI
693709# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS)
694710# define _LIBCPP_EXPORTED_FROM_ABI __attribute__((__visibility__("default")))
......@@ -792,10 +808,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
792808
793809#define _VSTD_FS _VSTD::__fs::filesystem
794810
795#ifndef _LIBCPP_PREFERRED_OVERLOAD
796# if __has_attribute(__enable_if__)
797# define _LIBCPP_PREFERRED_OVERLOAD __attribute__ ((__enable_if__(true, "")))
798# endif
811#if __has_attribute(__enable_if__)
812# define _LIBCPP_PREFERRED_OVERLOAD __attribute__ ((__enable_if__(true, "")))
799813#endif
800814
801815#ifndef _LIBCPP_HAS_NO_NOEXCEPT
......@@ -809,7 +823,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
809823#ifdef _LIBCPP_HAS_NO_UNICODE_CHARS
810824typedef unsigned short char16_t;
811825typedef unsigned int char32_t;
812#endif // _LIBCPP_HAS_NO_UNICODE_CHARS
826#endif // _LIBCPP_HAS_NO_UNICODE_CHARS
813827
814828#ifndef __SIZEOF_INT128__
815829#define _LIBCPP_HAS_NO_INT128
......@@ -818,7 +832,7 @@ typedef unsigned int char32_t;
818832#ifdef _LIBCPP_CXX03_LANG
819833# define static_assert(...) _Static_assert(__VA_ARGS__)
820834# define decltype(...) __decltype(__VA_ARGS__)
821#endif // _LIBCPP_CXX03_LANG
835#endif // _LIBCPP_CXX03_LANG
822836
823837#ifdef _LIBCPP_CXX03_LANG
824838# define _LIBCPP_CONSTEXPR
......@@ -832,6 +846,14 @@ typedef unsigned int char32_t;
832846# define _LIBCPP_CONSTEVAL consteval
833847#endif
834848
849#if !defined(__cpp_concepts) || __cpp_concepts < 201907L
850#define _LIBCPP_HAS_NO_CONCEPTS
851#endif
852
853#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_HAS_NO_CONCEPTS)
854#define _LIBCPP_HAS_NO_RANGES
855#endif
856
835857#ifdef _LIBCPP_CXX03_LANG
836858# define _LIBCPP_DEFAULT {}
837859#else
......@@ -850,11 +872,10 @@ typedef unsigned int char32_t;
850872# define _LIBCPP_NOALIAS
851873#endif
852874
853#if __has_feature(cxx_explicit_conversions) || defined(__IBMCPP__) || \
854 (!defined(_LIBCPP_CXX03_LANG) && defined(__GNUC__)) // All supported GCC versions
855# define _LIBCPP_EXPLICIT explicit
875#if __has_attribute(using_if_exists)
876# define _LIBCPP_USING_IF_EXISTS __attribute__((using_if_exists))
856877#else
857# define _LIBCPP_EXPLICIT
878# define _LIBCPP_USING_IF_EXISTS
858879#endif
859880
860881#ifdef _LIBCPP_HAS_NO_STRONG_ENUMS
......@@ -868,7 +889,7 @@ typedef unsigned int char32_t;
868889#else // _LIBCPP_HAS_NO_STRONG_ENUMS
869890# define _LIBCPP_DECLARE_STRONG_ENUM(x) enum class _LIBCPP_ENUM_VIS x
870891# define _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(x)
871#endif // _LIBCPP_HAS_NO_STRONG_ENUMS
892#endif // _LIBCPP_HAS_NO_STRONG_ENUMS
872893
873894// _LIBCPP_DEBUG potential values:
874895// - undefined: No assertions. This is the default.
......@@ -884,33 +905,25 @@ typedef unsigned int char32_t;
884905# error Supported values for _LIBCPP_DEBUG are 0 and 1
885906#endif
886907
887// _LIBCPP_DEBUG_LEVEL is always defined to one of [0, 1, 2] at this point
888#if _LIBCPP_DEBUG_LEVEL >= 1 && !defined(_LIBCPP_DISABLE_EXTERN_TEMPLATE)
889# define _LIBCPP_EXTERN_TEMPLATE(...)
890#endif
891
892#ifdef _LIBCPP_DISABLE_EXTERN_TEMPLATE
893# define _LIBCPP_EXTERN_TEMPLATE(...)
894# define _LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(...)
895#endif
896
897#ifndef _LIBCPP_EXTERN_TEMPLATE
898#define _LIBCPP_EXTERN_TEMPLATE(...) extern template __VA_ARGS__;
899#endif
900
901// When the Debug mode is enabled, we disable extern declarations because we
902// don't want to use the functions compiled in the library, which might not
903// have had the debug mode enabled when built. However, some extern declarations
904// need to be used, because code correctness depends on it (several instances
905// in the <locale>). Those special declarations are declared with
906// _LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE, which is enabled even
907// when the debug mode is enabled.
908#ifndef _LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE
909# define _LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(...) extern template __VA_ARGS__;
910#endif
911
912#ifndef _LIBCPP_EXTERN_TEMPLATE_DEFINE
913#define _LIBCPP_EXTERN_TEMPLATE_DEFINE(...) template __VA_ARGS__;
908// Libc++ allows disabling extern template instantiation declarations by
909// means of users defining _LIBCPP_DISABLE_EXTERN_TEMPLATE.
910//
911// Furthermore, when the Debug mode is enabled, we disable extern declarations
912// when building user code because we don't want to use the functions compiled
913// in the library, which might not have had the debug mode enabled when built.
914// However, some extern declarations need to be used, because code correctness
915// depends on it (several instances in <locale>). Those special declarations
916// are declared with _LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE, which is enabled
917// even when the debug mode is enabled.
918#if defined(_LIBCPP_DISABLE_EXTERN_TEMPLATE)
919# define _LIBCPP_EXTERN_TEMPLATE(...) /* nothing */
920# define _LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(...) /* nothing */
921#elif _LIBCPP_DEBUG_LEVEL >= 1 && !defined(_LIBCPP_BUILDING_LIBRARY)
922# define _LIBCPP_EXTERN_TEMPLATE(...) /* nothing */
923# define _LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(...) extern template __VA_ARGS__;
924#else
925# define _LIBCPP_EXTERN_TEMPLATE(...) extern template __VA_ARGS__;
926# define _LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(...) extern template __VA_ARGS__;
914927#endif
915928
916929#if defined(__APPLE__) || defined(__FreeBSD__) || defined(_LIBCPP_MSVCRT_LIKE) || \
......@@ -918,13 +931,6 @@ typedef unsigned int char32_t;
918931#define _LIBCPP_LOCALE__L_EXTENSIONS 1
919932#endif
920933
921#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
922// Most unix variants have catopen. These are the specific ones that don't.
923# if !defined(__BIONIC__) && !defined(_NEWLIB_VERSION)
924# define _LIBCPP_HAS_CATOPEN 1
925# endif
926#endif
927
928934#ifdef __FreeBSD__
929935#define _DECLARE_C99_LDBL_MATH 1
930936#endif
......@@ -948,9 +954,8 @@ typedef unsigned int char32_t;
948954# endif
949955#endif // defined(__APPLE__)
950956
951#if !defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION) && \
952 (defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION) || \
953 (!defined(__cpp_aligned_new) || __cpp_aligned_new < 201606))
957#if defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION) || \
958 (!defined(__cpp_aligned_new) || __cpp_aligned_new < 201606)
954959# define _LIBCPP_HAS_NO_ALIGNED_ALLOCATION
955960#endif
956961
......@@ -963,7 +968,7 @@ typedef unsigned int char32_t;
963968#endif
964969
965970#if _LIBCPP_STD_VER <= 17 || !defined(__cpp_char8_t)
966#define _LIBCPP_NO_HAS_CHAR8_T
971#define _LIBCPP_HAS_NO_CHAR8_T
967972#endif
968973
969974// Deprecation macros.
......@@ -1006,24 +1011,23 @@ typedef unsigned int char32_t;
10061011# define _LIBCPP_DEPRECATED_IN_CXX20
10071012#endif
10081013
1009#if !defined(_LIBCPP_NO_HAS_CHAR8_T)
1014#if !defined(_LIBCPP_HAS_NO_CHAR8_T)
10101015# define _LIBCPP_DEPRECATED_WITH_CHAR8_T _LIBCPP_DEPRECATED
10111016#else
10121017# define _LIBCPP_DEPRECATED_WITH_CHAR8_T
10131018#endif
10141019
10151020// Macros to enter and leave a state where deprecation warnings are suppressed.
1016#if !defined(_LIBCPP_SUPPRESS_DEPRECATED_PUSH) && \
1017 (defined(_LIBCPP_COMPILER_CLANG) || defined(_LIBCPP_COMPILER_GCC))
1018# define _LIBCPP_SUPPRESS_DEPRECATED_PUSH \
1019 _Pragma("GCC diagnostic push") \
1020 _Pragma("GCC diagnostic ignored \"-Wdeprecated\"")
1021# define _LIBCPP_SUPPRESS_DEPRECATED_POP \
1022 _Pragma("GCC diagnostic pop")
1023#endif
1024#if !defined(_LIBCPP_SUPPRESS_DEPRECATED_PUSH)
1025# define _LIBCPP_SUPPRESS_DEPRECATED_PUSH
1026# define _LIBCPP_SUPPRESS_DEPRECATED_POP
1021#if defined(_LIBCPP_COMPILER_CLANG_BASED) || defined(_LIBCPP_COMPILER_GCC)
1022# define _LIBCPP_SUPPRESS_DEPRECATED_PUSH \
1023 _Pragma("GCC diagnostic push") \
1024 _Pragma("GCC diagnostic ignored \"-Wdeprecated\"") \
1025 _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
1026# define _LIBCPP_SUPPRESS_DEPRECATED_POP \
1027 _Pragma("GCC diagnostic pop")
1028#else
1029# define _LIBCPP_SUPPRESS_DEPRECATED_PUSH
1030# define _LIBCPP_SUPPRESS_DEPRECATED_POP
10271031#endif
10281032
10291033#if _LIBCPP_STD_VER <= 11
......@@ -1054,7 +1058,7 @@ typedef unsigned int char32_t;
10541058// NODISCARD macros to the correct attribute.
10551059#if __has_cpp_attribute(nodiscard) || defined(_LIBCPP_COMPILER_MSVC)
10561060# define _LIBCPP_NODISCARD_ATTRIBUTE [[nodiscard]]
1057#elif defined(_LIBCPP_COMPILER_CLANG) && !defined(_LIBCPP_CXX03_LANG)
1061#elif defined(_LIBCPP_COMPILER_CLANG_BASED) && !defined(_LIBCPP_CXX03_LANG)
10581062# define _LIBCPP_NODISCARD_ATTRIBUTE [[clang::warn_unused_result]]
10591063#else
10601064// We can't use GCC's [[gnu::warn_unused_result]] and
......@@ -1084,12 +1088,10 @@ typedef unsigned int char32_t;
10841088# define _LIBCPP_INLINE_VAR
10851089#endif
10861090
1087#ifndef _LIBCPP_CONSTEXPR_IF_NODEBUG
10881091#if defined(_LIBCPP_DEBUG) || defined(_LIBCPP_HAS_NO_CXX14_CONSTEXPR)
1089#define _LIBCPP_CONSTEXPR_IF_NODEBUG
1092# define _LIBCPP_CONSTEXPR_IF_NODEBUG
10901093#else
1091#define _LIBCPP_CONSTEXPR_IF_NODEBUG constexpr
1092#endif
1094# define _LIBCPP_CONSTEXPR_IF_NODEBUG constexpr
10931095#endif
10941096
10951097#if __has_attribute(no_destroy)
......@@ -1104,7 +1106,7 @@ extern "C" _LIBCPP_FUNC_VIS void __sanitizer_annotate_contiguous_container(
11041106#endif
11051107
11061108// Try to find out if RTTI is disabled.
1107#if defined(_LIBCPP_COMPILER_CLANG) && !__has_feature(cxx_rtti)
1109#if defined(_LIBCPP_COMPILER_CLANG_BASED) && !__has_feature(cxx_rtti)
11081110# define _LIBCPP_NO_RTTI
11091111#elif defined(__GNUC__) && !defined(__GXX_RTTI)
11101112# define _LIBCPP_NO_RTTI
......@@ -1132,6 +1134,7 @@ extern "C" _LIBCPP_FUNC_VIS void __sanitizer_annotate_contiguous_container(
11321134 defined(__CloudABI__) || \
11331135 defined(__sun__) || \
11341136 defined(__MVS__) || \
1137 defined(_AIX) || \
11351138 (defined(__MINGW32__) && __has_include(<pthread.h>))
11361139# define _LIBCPP_HAS_THREAD_API_PTHREAD
11371140# elif defined(__Fuchsia__)
......@@ -1218,12 +1221,10 @@ extern "C" _LIBCPP_FUNC_VIS void __sanitizer_annotate_contiguous_container(
12181221#endif
12191222
12201223// Some systems do not provide gets() in their C library, for security reasons.
1221#ifndef _LIBCPP_C_HAS_NO_GETS
1222# if defined(_LIBCPP_MSVCRT) || \
1223 (defined(__FreeBSD_version) && __FreeBSD_version >= 1300043) || \
1224 defined(__OpenBSD__)
1225# define _LIBCPP_C_HAS_NO_GETS
1226# endif
1224#if defined(_LIBCPP_MSVCRT) || \
1225 (defined(__FreeBSD_version) && __FreeBSD_version >= 1300043) || \
1226 defined(__OpenBSD__)
1227# define _LIBCPP_C_HAS_NO_GETS
12271228#endif
12281229
12291230#if defined(__BIONIC__) || defined(__CloudABI__) || defined(__NuttX__) || \
......@@ -1273,13 +1274,11 @@ extern "C" _LIBCPP_FUNC_VIS void __sanitizer_annotate_contiguous_container(
12731274# endif
12741275#endif
12751276
1276#ifndef _LIBCPP_THREAD_SAFETY_ANNOTATION
1277# ifdef _LIBCPP_HAS_THREAD_SAFETY_ANNOTATIONS
1278# define _LIBCPP_THREAD_SAFETY_ANNOTATION(x) __attribute__((x))
1279# else
1280# define _LIBCPP_THREAD_SAFETY_ANNOTATION(x)
1281# endif
1282#endif // _LIBCPP_THREAD_SAFETY_ANNOTATION
1277#ifdef _LIBCPP_HAS_THREAD_SAFETY_ANNOTATIONS
1278# define _LIBCPP_THREAD_SAFETY_ANNOTATION(x) __attribute__((x))
1279#else
1280# define _LIBCPP_THREAD_SAFETY_ANNOTATION(x)
1281#endif
12831282
12841283#if __has_attribute(require_constant_initialization)
12851284# define _LIBCPP_SAFE_STATIC __attribute__((__require_constant_initialization__))
......@@ -1295,12 +1294,6 @@ extern "C" _LIBCPP_FUNC_VIS void __sanitizer_annotate_contiguous_container(
12951294#define _LIBCPP_HAS_NO_BUILTIN_IS_CONSTANT_EVALUATED
12961295#endif
12971296
1298#if !defined(_LIBCPP_HAS_NO_OFF_T_FUNCTIONS)
1299# if defined(_LIBCPP_MSVCRT) || defined(_NEWLIB_VERSION)
1300# define _LIBCPP_HAS_NO_OFF_T_FUNCTIONS
1301# endif
1302#endif
1303
13041297#if __has_attribute(diagnose_if) && !defined(_LIBCPP_DISABLE_ADDITIONAL_DIAGNOSTICS)
13051298# define _LIBCPP_DIAGNOSE_WARNING(...) \
13061299 __attribute__((diagnose_if(__VA_ARGS__, "warning")))
......@@ -1328,14 +1321,17 @@ extern "C" _LIBCPP_FUNC_VIS void __sanitizer_annotate_contiguous_container(
13281321#define _LIBCPP_NODEBUG
13291322#endif
13301323
1331#ifndef _LIBCPP_NODEBUG_TYPE
1332#if __has_attribute(__nodebug__) && \
1333 (defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER >= 900)
1334#define _LIBCPP_NODEBUG_TYPE __attribute__((nodebug))
1324#if __has_attribute(__nodebug__) && (defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER >= 900)
1325# define _LIBCPP_NODEBUG_TYPE __attribute__((nodebug))
13351326#else
1336#define _LIBCPP_NODEBUG_TYPE
1327# define _LIBCPP_NODEBUG_TYPE
1328#endif
1329
1330#if __has_attribute(__standalone_debug__)
1331#define _LIBCPP_STANDALONE_DEBUG __attribute__((__standalone_debug__))
1332#else
1333#define _LIBCPP_STANDALONE_DEBUG
13371334#endif
1338#endif // !defined(_LIBCPP_NODEBUG_TYPE)
13391335
13401336#if __has_attribute(__preferred_name__)
13411337#define _LIBCPP_PREFERRED_NAME(x) __attribute__((__preferred_name__(x)))
......@@ -1352,11 +1348,19 @@ extern "C" _LIBCPP_FUNC_VIS void __sanitizer_annotate_contiguous_container(
13521348
13531349#if defined(_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES)
13541350#define _LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR
1355#define _LIBCPP_ENABLE_CXX17_REMOVED_UNEXPECTED_FUNCTIONS
1356#define _LIBCPP_ENABLE_CXX17_REMOVED_RANDOM_SHUFFLE
13571351#define _LIBCPP_ENABLE_CXX17_REMOVED_BINDERS
1352#define _LIBCPP_ENABLE_CXX17_REMOVED_RANDOM_SHUFFLE
1353#define _LIBCPP_ENABLE_CXX17_REMOVED_UNEXPECTED_FUNCTIONS
13581354#endif // _LIBCPP_ENABLE_CXX17_REMOVED_FEATURES
13591355
1356#if defined(_LIBCPP_ENABLE_CXX20_REMOVED_FEATURES)
1357#define _LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS
1358#define _LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS
1359#define _LIBCPP_ENABLE_CXX20_REMOVED_NEGATORS
1360#define _LIBCPP_ENABLE_CXX20_REMOVED_RAW_STORAGE_ITERATOR
1361#define _LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS
1362#endif // _LIBCPP_ENABLE_CXX20_REMOVED_FEATURES
1363
13601364#if !defined(__cpp_deduction_guides) || __cpp_deduction_guides < 201611
13611365#define _LIBCPP_HAS_NO_DEDUCTION_GUIDES
13621366#endif
......@@ -1405,7 +1409,7 @@ extern "C" _LIBCPP_FUNC_VIS void __sanitizer_annotate_contiguous_container(
14051409
14061410#ifndef _LIBCPP_NO_AUTO_LINK
14071411# if defined(_LIBCPP_ABI_MICROSOFT) && !defined(_LIBCPP_BUILDING_LIBRARY)
1408# if defined(_DLL)
1412# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS)
14091413# pragma comment(lib, "c++.lib")
14101414# else
14111415# pragma comment(lib, "libc++.lib")
......@@ -1413,8 +1417,6 @@ extern "C" _LIBCPP_FUNC_VIS void __sanitizer_annotate_contiguous_container(
14131417# endif // defined(_LIBCPP_ABI_MICROSOFT) && !defined(_LIBCPP_BUILDING_LIBRARY)
14141418#endif // _LIBCPP_NO_AUTO_LINK
14151419
1416#define _LIBCPP_UNUSED_VAR(x) ((void)(x))
1417
14181420// Configures the fopen close-on-exec mode character, if any. This string will
14191421// be appended to any mode string used by fstream for fopen/fdopen.
14201422//
......@@ -1445,6 +1447,13 @@ extern "C" _LIBCPP_FUNC_VIS void __sanitizer_annotate_contiguous_container(
14451447# define _LIBCPP_INIT_PRIORITY_MAX
14461448#endif
14471449
1450#if defined(__GNUC__) || defined(__clang__)
1451#define _LIBCPP_FORMAT_PRINTF(a, b) \
1452 __attribute__((__format__(__printf__, a, b)))
1453#else
1454#define _LIBCPP_FORMAT_PRINTF(a, b)
1455#endif
1456
14481457#endif // __cplusplus
14491458
14501459#endif // _LIBCPP_CONFIG
lib/libcxx/include/__config_site.in deleted-40
......@@ -1,40 +0,0 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP_CONFIG_SITE
10#define _LIBCPP_CONFIG_SITE
11
12#cmakedefine _LIBCPP_ABI_VERSION @_LIBCPP_ABI_VERSION@
13#cmakedefine _LIBCPP_ABI_UNSTABLE
14#cmakedefine _LIBCPP_ABI_FORCE_ITANIUM
15#cmakedefine _LIBCPP_ABI_FORCE_MICROSOFT
16#cmakedefine _LIBCPP_HIDE_FROM_ABI_PER_TU_BY_DEFAULT
17#cmakedefine _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
18#cmakedefine _LIBCPP_HAS_NO_STDIN
19#cmakedefine _LIBCPP_HAS_NO_STDOUT
20#cmakedefine _LIBCPP_HAS_NO_THREADS
21#cmakedefine _LIBCPP_HAS_NO_MONOTONIC_CLOCK
22#cmakedefine _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS
23#cmakedefine _LIBCPP_HAS_MUSL_LIBC
24#cmakedefine _LIBCPP_HAS_THREAD_API_PTHREAD
25#cmakedefine _LIBCPP_HAS_THREAD_API_EXTERNAL
26#cmakedefine _LIBCPP_HAS_THREAD_API_WIN32
27#cmakedefine _LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL
28#cmakedefine _LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS
29#cmakedefine _LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS
30#cmakedefine _LIBCPP_NO_VCRUNTIME
31#cmakedefine _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION @_LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION@
32#cmakedefine _LIBCPP_ABI_NAMESPACE @_LIBCPP_ABI_NAMESPACE@
33#cmakedefine _LIBCPP_HAS_NO_FILESYSTEM_LIBRARY
34#cmakedefine _LIBCPP_HAS_PARALLEL_ALGORITHMS
35#cmakedefine _LIBCPP_HAS_NO_RANDOM_DEVICE
36#cmakedefine _LIBCPP_HAS_NO_LOCALIZATION
37
38@_LIBCPP_ABI_DEFINES@
39
40#endif // _LIBCPP_CONFIG_SITE
lib/libcxx/include/__debug+1-1
......@@ -270,4 +270,4 @@ _LIBCPP_FUNC_VIS const __libcpp_db* __get_const_db();
270270
271271_LIBCPP_END_NAMESPACE_STD
272272
273#endif // _LIBCPP_DEBUG_H
273#endif // _LIBCPP_DEBUG_H
lib/libcxx/include/__errc+1-1
......@@ -214,4 +214,4 @@ _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(errc)
214214
215215_LIBCPP_END_NAMESPACE_STD
216216
217#endif // _LIBCPP___ERRC
217#endif // _LIBCPP___ERRC
lib/libcxx/include/__format/format_error.h created+56
......@@ -0,0 +1,56 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___FORMAT_FORMAT_ERROR_H
11#define _LIBCPP___FORMAT_FORMAT_ERROR_H
12
13#include <__config>
14#include <stdexcept>
15
16#ifdef _LIBCPP_NO_EXCEPTIONS
17#include <cstdlib>
18#endif
19
20#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
21#pragma GCC system_header
22#endif
23
24_LIBCPP_PUSH_MACROS
25#include <__undef_macros>
26
27_LIBCPP_BEGIN_NAMESPACE_STD
28
29#if _LIBCPP_STD_VER > 17
30
31class _LIBCPP_EXCEPTION_ABI format_error : public runtime_error {
32public:
33 _LIBCPP_HIDE_FROM_ABI explicit format_error(const string& __s)
34 : runtime_error(__s) {}
35 _LIBCPP_HIDE_FROM_ABI explicit format_error(const char* __s)
36 : runtime_error(__s) {}
37 virtual ~format_error() noexcept;
38};
39
40_LIBCPP_NORETURN inline _LIBCPP_HIDE_FROM_ABI void
41__throw_format_error(const char* __s) {
42#ifndef _LIBCPP_NO_EXCEPTIONS
43 throw format_error(__s);
44#else
45 (void)__s;
46 _VSTD::abort();
47#endif
48}
49
50#endif //_LIBCPP_STD_VER > 17
51
52_LIBCPP_END_NAMESPACE_STD
53
54_LIBCPP_POP_MACROS
55
56#endif // _LIBCPP___FORMAT_FORMAT_ERROR_H
lib/libcxx/include/__format/format_parse_context.h created+113
......@@ -0,0 +1,113 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___FORMAT_FORMAT_PARSE_CONTEXT_H
11#define _LIBCPP___FORMAT_FORMAT_PARSE_CONTEXT_H
12
13#include <__config>
14#include <__format/format_error.h>
15#include <string_view>
16
17#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
18#pragma GCC system_header
19#endif
20
21_LIBCPP_PUSH_MACROS
22#include <__undef_macros>
23
24_LIBCPP_BEGIN_NAMESPACE_STD
25
26#if _LIBCPP_STD_VER > 17
27
28// TODO FMT Remove this once we require compilers with proper C++20 support.
29// If the compiler has no concepts support, the format header will be disabled.
30// Without concepts support enable_if needs to be used and that too much effort
31// to support compilers with partial C++20 support.
32#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && \
33 !defined(_LIBCPP_HAS_NO_BUILTIN_IS_CONSTANT_EVALUATED)
34
35template <class _CharT>
36class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT basic_format_parse_context {
37public:
38 using char_type = _CharT;
39 using const_iterator = typename basic_string_view<_CharT>::const_iterator;
40 using iterator = const_iterator;
41
42 _LIBCPP_HIDE_FROM_ABI
43 constexpr explicit basic_format_parse_context(basic_string_view<_CharT> __fmt,
44 size_t __num_args = 0) noexcept
45 : __begin_(__fmt.begin()),
46 __end_(__fmt.end()),
47 __indexing_(__unknown),
48 __next_arg_id_(0),
49 __num_args_(__num_args) {}
50
51 basic_format_parse_context(const basic_format_parse_context&) = delete;
52 basic_format_parse_context&
53 operator=(const basic_format_parse_context&) = delete;
54
55 _LIBCPP_HIDE_FROM_ABI constexpr const_iterator begin() const noexcept {
56 return __begin_;
57 }
58 _LIBCPP_HIDE_FROM_ABI constexpr const_iterator end() const noexcept {
59 return __end_;
60 }
61 _LIBCPP_HIDE_FROM_ABI constexpr void advance_to(const_iterator __it) {
62 __begin_ = __it;
63 }
64
65 _LIBCPP_HIDE_FROM_ABI constexpr size_t next_arg_id() {
66 if (__indexing_ == __manual)
67 __throw_format_error("Using automatic argument numbering in manual "
68 "argument numbering mode");
69
70 if (__indexing_ == __unknown)
71 __indexing_ = __automatic;
72 return __next_arg_id_++;
73 }
74 _LIBCPP_HIDE_FROM_ABI constexpr void check_arg_id(size_t __id) {
75 if (__indexing_ == __automatic)
76 __throw_format_error("Using manual argument numbering in automatic "
77 "argument numbering mode");
78
79 if (__indexing_ == __unknown)
80 __indexing_ = __manual;
81
82 // Throws an exception to make the expression a non core constant
83 // expression as required by:
84 // [format.parse.ctx]/11
85 // Remarks: Call expressions where id >= num_args_ are not core constant
86 // expressions ([expr.const]).
87 // Note: the Throws clause [format.parse.ctx]/10 doesn't specify the
88 // behavior when id >= num_args_.
89 if (is_constant_evaluated() && __id >= __num_args_)
90 __throw_format_error("Argument index outside the valid range");
91 }
92
93private:
94 iterator __begin_;
95 iterator __end_;
96 enum _Indexing { __unknown, __manual, __automatic };
97 _Indexing __indexing_;
98 size_t __next_arg_id_;
99 size_t __num_args_;
100};
101
102using format_parse_context = basic_format_parse_context<char>;
103using wformat_parse_context = basic_format_parse_context<wchar_t>;
104
105#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_BUILTIN_IS_CONSTANT_EVALUATED)
106
107#endif //_LIBCPP_STD_VER > 17
108
109_LIBCPP_END_NAMESPACE_STD
110
111_LIBCPP_POP_MACROS
112
113#endif // _LIBCPP___FORMAT_FORMAT_PARSE_CONTEXT_H
lib/libcxx/include/__function_like.h created+56
......@@ -0,0 +1,56 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___ITERATOR_FUNCTION_LIKE_H
11#define _LIBCPP___ITERATOR_FUNCTION_LIKE_H
12
13#include <__config>
14
15#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
16#pragma GCC system_header
17#endif
18
19_LIBCPP_PUSH_MACROS
20#include <__undef_macros>
21
22_LIBCPP_BEGIN_NAMESPACE_STD
23
24#if !defined(_LIBCPP_HAS_NO_RANGES)
25
26namespace ranges {
27// Per [range.iter.ops.general] and [algorithms.requirements], functions in namespace std::ranges
28// can't be found by ADL and inhibit ADL when found by unqualified lookup. The easiest way to
29// facilitate this is to use function objects.
30//
31// Since these are still standard library functions, we use `__function_like` to eliminate most of
32// the properties that function objects get by default (e.g. semiregularity, addressability), to
33// limit the surface area of the unintended public interface, so as to curb the effect of Hyrum's
34// law.
35struct __function_like {
36 __function_like() = delete;
37 __function_like(__function_like const&) = delete;
38 __function_like& operator=(__function_like const&) = delete;
39
40 void operator&() const = delete;
41
42 struct __tag { };
43
44protected:
45 constexpr explicit __function_like(__tag) noexcept {}
46 ~__function_like() = default;
47};
48} // namespace ranges
49
50#endif // !defined(_LIBCPP_HAS_NO_RANGES)
51
52_LIBCPP_END_NAMESPACE_STD
53
54_LIBCPP_POP_MACROS
55
56#endif // _LIBCPP___ITERATOR_FUNCTION_LIKE_H
lib/libcxx/include/__functional/binary_function.h created+31
......@@ -0,0 +1,31 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___FUNCTIONAL_BINARY_FUNCTION_H
11#define _LIBCPP___FUNCTIONAL_BINARY_FUNCTION_H
12
13#include <__config>
14
15#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
16#pragma GCC system_header
17#endif
18
19_LIBCPP_BEGIN_NAMESPACE_STD
20
21template <class _Arg1, class _Arg2, class _Result>
22struct _LIBCPP_TEMPLATE_VIS binary_function
23{
24 typedef _Arg1 first_argument_type;
25 typedef _Arg2 second_argument_type;
26 typedef _Result result_type;
27};
28
29_LIBCPP_END_NAMESPACE_STD
30
31#endif // _LIBCPP___FUNCTIONAL_BINARY_FUNCTION_H
lib/libcxx/include/__functional/binary_negate.h created+50
......@@ -0,0 +1,50 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___FUNCTIONAL_BINARY_NEGATE_H
11#define _LIBCPP___FUNCTIONAL_BINARY_NEGATE_H
12
13#include <__config>
14#include <__functional/binary_function.h>
15
16#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
17#pragma GCC system_header
18#endif
19
20_LIBCPP_BEGIN_NAMESPACE_STD
21
22#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_NEGATORS)
23
24template <class _Predicate>
25class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 binary_negate
26 : public binary_function<typename _Predicate::first_argument_type,
27 typename _Predicate::second_argument_type,
28 bool>
29{
30 _Predicate __pred_;
31public:
32 _LIBCPP_INLINE_VISIBILITY explicit _LIBCPP_CONSTEXPR_AFTER_CXX11
33 binary_negate(const _Predicate& __pred) : __pred_(__pred) {}
34
35 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
36 bool operator()(const typename _Predicate::first_argument_type& __x,
37 const typename _Predicate::second_argument_type& __y) const
38 {return !__pred_(__x, __y);}
39};
40
41template <class _Predicate>
42_LIBCPP_DEPRECATED_IN_CXX17 inline _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
43binary_negate<_Predicate>
44not2(const _Predicate& __pred) {return binary_negate<_Predicate>(__pred);}
45
46#endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_NEGATORS)
47
48_LIBCPP_END_NAMESPACE_STD
49
50#endif // _LIBCPP___FUNCTIONAL_BINARY_NEGATE_H
lib/libcxx/include/__functional/bind.h created+386
......@@ -0,0 +1,386 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___FUNCTIONAL_BIND_H
11#define _LIBCPP___FUNCTIONAL_BIND_H
12
13#include <__config>
14#include <__functional/weak_result_type.h>
15#include <__functional/invoke.h>
16#include <cstddef>
17#include <tuple>
18#include <type_traits>
19
20#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
21#pragma GCC system_header
22#endif
23
24_LIBCPP_BEGIN_NAMESPACE_STD
25
26template<class _Tp> struct __is_bind_expression : public false_type {};
27template<class _Tp> struct _LIBCPP_TEMPLATE_VIS is_bind_expression
28 : public __is_bind_expression<typename remove_cv<_Tp>::type> {};
29
30#if _LIBCPP_STD_VER > 14
31template <class _Tp>
32_LIBCPP_INLINE_VAR constexpr size_t is_bind_expression_v = is_bind_expression<_Tp>::value;
33#endif
34
35template<class _Tp> struct __is_placeholder : public integral_constant<int, 0> {};
36template<class _Tp> struct _LIBCPP_TEMPLATE_VIS is_placeholder
37 : public __is_placeholder<typename remove_cv<_Tp>::type> {};
38
39#if _LIBCPP_STD_VER > 14
40template <class _Tp>
41_LIBCPP_INLINE_VAR constexpr size_t is_placeholder_v = is_placeholder<_Tp>::value;
42#endif
43
44namespace placeholders
45{
46
47template <int _Np> struct __ph {};
48
49#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY)
50_LIBCPP_FUNC_VIS extern const __ph<1> _1;
51_LIBCPP_FUNC_VIS extern const __ph<2> _2;
52_LIBCPP_FUNC_VIS extern const __ph<3> _3;
53_LIBCPP_FUNC_VIS extern const __ph<4> _4;
54_LIBCPP_FUNC_VIS extern const __ph<5> _5;
55_LIBCPP_FUNC_VIS extern const __ph<6> _6;
56_LIBCPP_FUNC_VIS extern const __ph<7> _7;
57_LIBCPP_FUNC_VIS extern const __ph<8> _8;
58_LIBCPP_FUNC_VIS extern const __ph<9> _9;
59_LIBCPP_FUNC_VIS extern const __ph<10> _10;
60#else
61/* _LIBCPP_INLINE_VAR */ constexpr __ph<1> _1{};
62/* _LIBCPP_INLINE_VAR */ constexpr __ph<2> _2{};
63/* _LIBCPP_INLINE_VAR */ constexpr __ph<3> _3{};
64/* _LIBCPP_INLINE_VAR */ constexpr __ph<4> _4{};
65/* _LIBCPP_INLINE_VAR */ constexpr __ph<5> _5{};
66/* _LIBCPP_INLINE_VAR */ constexpr __ph<6> _6{};
67/* _LIBCPP_INLINE_VAR */ constexpr __ph<7> _7{};
68/* _LIBCPP_INLINE_VAR */ constexpr __ph<8> _8{};
69/* _LIBCPP_INLINE_VAR */ constexpr __ph<9> _9{};
70/* _LIBCPP_INLINE_VAR */ constexpr __ph<10> _10{};
71#endif // defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY)
72
73} // placeholders
74
75template<int _Np>
76struct __is_placeholder<placeholders::__ph<_Np> >
77 : public integral_constant<int, _Np> {};
78
79
80#ifndef _LIBCPP_CXX03_LANG
81
82template <class _Tp, class _Uj>
83inline _LIBCPP_INLINE_VISIBILITY
84_Tp&
85__mu(reference_wrapper<_Tp> __t, _Uj&)
86{
87 return __t.get();
88}
89
90template <class _Ti, class ..._Uj, size_t ..._Indx>
91inline _LIBCPP_INLINE_VISIBILITY
92typename __invoke_of<_Ti&, _Uj...>::type
93__mu_expand(_Ti& __ti, tuple<_Uj...>& __uj, __tuple_indices<_Indx...>)
94{
95 return __ti(_VSTD::forward<_Uj>(_VSTD::get<_Indx>(__uj))...);
96}
97
98template <class _Ti, class ..._Uj>
99inline _LIBCPP_INLINE_VISIBILITY
100typename _EnableIf
101<
102 is_bind_expression<_Ti>::value,
103 __invoke_of<_Ti&, _Uj...>
104>::type
105__mu(_Ti& __ti, tuple<_Uj...>& __uj)
106{
107 typedef typename __make_tuple_indices<sizeof...(_Uj)>::type __indices;
108 return _VSTD::__mu_expand(__ti, __uj, __indices());
109}
110
111template <bool IsPh, class _Ti, class _Uj>
112struct __mu_return2 {};
113
114template <class _Ti, class _Uj>
115struct __mu_return2<true, _Ti, _Uj>
116{
117 typedef typename tuple_element<is_placeholder<_Ti>::value - 1, _Uj>::type type;
118};
119
120template <class _Ti, class _Uj>
121inline _LIBCPP_INLINE_VISIBILITY
122typename enable_if
123<
124 0 < is_placeholder<_Ti>::value,
125 typename __mu_return2<0 < is_placeholder<_Ti>::value, _Ti, _Uj>::type
126>::type
127__mu(_Ti&, _Uj& __uj)
128{
129 const size_t _Indx = is_placeholder<_Ti>::value - 1;
130 return _VSTD::forward<typename tuple_element<_Indx, _Uj>::type>(_VSTD::get<_Indx>(__uj));
131}
132
133template <class _Ti, class _Uj>
134inline _LIBCPP_INLINE_VISIBILITY
135typename enable_if
136<
137 !is_bind_expression<_Ti>::value &&
138 is_placeholder<_Ti>::value == 0 &&
139 !__is_reference_wrapper<_Ti>::value,
140 _Ti&
141>::type
142__mu(_Ti& __ti, _Uj&)
143{
144 return __ti;
145}
146
147template <class _Ti, bool IsReferenceWrapper, bool IsBindEx, bool IsPh,
148 class _TupleUj>
149struct __mu_return_impl;
150
151template <bool _Invokable, class _Ti, class ..._Uj>
152struct __mu_return_invokable // false
153{
154 typedef __nat type;
155};
156
157template <class _Ti, class ..._Uj>
158struct __mu_return_invokable<true, _Ti, _Uj...>
159{
160 typedef typename __invoke_of<_Ti&, _Uj...>::type type;
161};
162
163template <class _Ti, class ..._Uj>
164struct __mu_return_impl<_Ti, false, true, false, tuple<_Uj...> >
165 : public __mu_return_invokable<__invokable<_Ti&, _Uj...>::value, _Ti, _Uj...>
166{
167};
168
169template <class _Ti, class _TupleUj>
170struct __mu_return_impl<_Ti, false, false, true, _TupleUj>
171{
172 typedef typename tuple_element<is_placeholder<_Ti>::value - 1,
173 _TupleUj>::type&& type;
174};
175
176template <class _Ti, class _TupleUj>
177struct __mu_return_impl<_Ti, true, false, false, _TupleUj>
178{
179 typedef typename _Ti::type& type;
180};
181
182template <class _Ti, class _TupleUj>
183struct __mu_return_impl<_Ti, false, false, false, _TupleUj>
184{
185 typedef _Ti& type;
186};
187
188template <class _Ti, class _TupleUj>
189struct __mu_return
190 : public __mu_return_impl<_Ti,
191 __is_reference_wrapper<_Ti>::value,
192 is_bind_expression<_Ti>::value,
193 0 < is_placeholder<_Ti>::value &&
194 is_placeholder<_Ti>::value <= tuple_size<_TupleUj>::value,
195 _TupleUj>
196{
197};
198
199template <class _Fp, class _BoundArgs, class _TupleUj>
200struct __is_valid_bind_return
201{
202 static const bool value = false;
203};
204
205template <class _Fp, class ..._BoundArgs, class _TupleUj>
206struct __is_valid_bind_return<_Fp, tuple<_BoundArgs...>, _TupleUj>
207{
208 static const bool value = __invokable<_Fp,
209 typename __mu_return<_BoundArgs, _TupleUj>::type...>::value;
210};
211
212template <class _Fp, class ..._BoundArgs, class _TupleUj>
213struct __is_valid_bind_return<_Fp, const tuple<_BoundArgs...>, _TupleUj>
214{
215 static const bool value = __invokable<_Fp,
216 typename __mu_return<const _BoundArgs, _TupleUj>::type...>::value;
217};
218
219template <class _Fp, class _BoundArgs, class _TupleUj,
220 bool = __is_valid_bind_return<_Fp, _BoundArgs, _TupleUj>::value>
221struct __bind_return;
222
223template <class _Fp, class ..._BoundArgs, class _TupleUj>
224struct __bind_return<_Fp, tuple<_BoundArgs...>, _TupleUj, true>
225{
226 typedef typename __invoke_of
227 <
228 _Fp&,
229 typename __mu_return
230 <
231 _BoundArgs,
232 _TupleUj
233 >::type...
234 >::type type;
235};
236
237template <class _Fp, class ..._BoundArgs, class _TupleUj>
238struct __bind_return<_Fp, const tuple<_BoundArgs...>, _TupleUj, true>
239{
240 typedef typename __invoke_of
241 <
242 _Fp&,
243 typename __mu_return
244 <
245 const _BoundArgs,
246 _TupleUj
247 >::type...
248 >::type type;
249};
250
251template <class _Fp, class _BoundArgs, size_t ..._Indx, class _Args>
252inline _LIBCPP_INLINE_VISIBILITY
253typename __bind_return<_Fp, _BoundArgs, _Args>::type
254__apply_functor(_Fp& __f, _BoundArgs& __bound_args, __tuple_indices<_Indx...>,
255 _Args&& __args)
256{
257 return _VSTD::__invoke(__f, _VSTD::__mu(_VSTD::get<_Indx>(__bound_args), __args)...);
258}
259
260template<class _Fp, class ..._BoundArgs>
261class __bind
262#if _LIBCPP_STD_VER <= 17 || !defined(_LIBCPP_ABI_NO_BINDER_BASES)
263 : public __weak_result_type<typename decay<_Fp>::type>
264#endif
265{
266protected:
267 typedef typename decay<_Fp>::type _Fd;
268 typedef tuple<typename decay<_BoundArgs>::type...> _Td;
269private:
270 _Fd __f_;
271 _Td __bound_args_;
272
273 typedef typename __make_tuple_indices<sizeof...(_BoundArgs)>::type __indices;
274public:
275 template <class _Gp, class ..._BA,
276 class = typename enable_if
277 <
278 is_constructible<_Fd, _Gp>::value &&
279 !is_same<typename remove_reference<_Gp>::type,
280 __bind>::value
281 >::type>
282 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
283 explicit __bind(_Gp&& __f, _BA&& ...__bound_args)
284 : __f_(_VSTD::forward<_Gp>(__f)),
285 __bound_args_(_VSTD::forward<_BA>(__bound_args)...) {}
286
287 template <class ..._Args>
288 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
289 typename __bind_return<_Fd, _Td, tuple<_Args&&...> >::type
290 operator()(_Args&& ...__args)
291 {
292 return _VSTD::__apply_functor(__f_, __bound_args_, __indices(),
293 tuple<_Args&&...>(_VSTD::forward<_Args>(__args)...));
294 }
295
296 template <class ..._Args>
297 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
298 typename __bind_return<const _Fd, const _Td, tuple<_Args&&...> >::type
299 operator()(_Args&& ...__args) const
300 {
301 return _VSTD::__apply_functor(__f_, __bound_args_, __indices(),
302 tuple<_Args&&...>(_VSTD::forward<_Args>(__args)...));
303 }
304};
305
306template<class _Fp, class ..._BoundArgs>
307struct __is_bind_expression<__bind<_Fp, _BoundArgs...> > : public true_type {};
308
309template<class _Rp, class _Fp, class ..._BoundArgs>
310class __bind_r
311 : public __bind<_Fp, _BoundArgs...>
312{
313 typedef __bind<_Fp, _BoundArgs...> base;
314 typedef typename base::_Fd _Fd;
315 typedef typename base::_Td _Td;
316public:
317 typedef _Rp result_type;
318
319
320 template <class _Gp, class ..._BA,
321 class = typename enable_if
322 <
323 is_constructible<_Fd, _Gp>::value &&
324 !is_same<typename remove_reference<_Gp>::type,
325 __bind_r>::value
326 >::type>
327 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
328 explicit __bind_r(_Gp&& __f, _BA&& ...__bound_args)
329 : base(_VSTD::forward<_Gp>(__f),
330 _VSTD::forward<_BA>(__bound_args)...) {}
331
332 template <class ..._Args>
333 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
334 typename enable_if
335 <
336 is_convertible<typename __bind_return<_Fd, _Td, tuple<_Args&&...> >::type,
337 result_type>::value || is_void<_Rp>::value,
338 result_type
339 >::type
340 operator()(_Args&& ...__args)
341 {
342 typedef __invoke_void_return_wrapper<_Rp> _Invoker;
343 return _Invoker::__call(static_cast<base&>(*this), _VSTD::forward<_Args>(__args)...);
344 }
345
346 template <class ..._Args>
347 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
348 typename enable_if
349 <
350 is_convertible<typename __bind_return<const _Fd, const _Td, tuple<_Args&&...> >::type,
351 result_type>::value || is_void<_Rp>::value,
352 result_type
353 >::type
354 operator()(_Args&& ...__args) const
355 {
356 typedef __invoke_void_return_wrapper<_Rp> _Invoker;
357 return _Invoker::__call(static_cast<base const&>(*this), _VSTD::forward<_Args>(__args)...);
358 }
359};
360
361template<class _Rp, class _Fp, class ..._BoundArgs>
362struct __is_bind_expression<__bind_r<_Rp, _Fp, _BoundArgs...> > : public true_type {};
363
364template<class _Fp, class ..._BoundArgs>
365inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
366__bind<_Fp, _BoundArgs...>
367bind(_Fp&& __f, _BoundArgs&&... __bound_args)
368{
369 typedef __bind<_Fp, _BoundArgs...> type;
370 return type(_VSTD::forward<_Fp>(__f), _VSTD::forward<_BoundArgs>(__bound_args)...);
371}
372
373template<class _Rp, class _Fp, class ..._BoundArgs>
374inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
375__bind_r<_Rp, _Fp, _BoundArgs...>
376bind(_Fp&& __f, _BoundArgs&&... __bound_args)
377{
378 typedef __bind_r<_Rp, _Fp, _BoundArgs...> type;
379 return type(_VSTD::forward<_Fp>(__f), _VSTD::forward<_BoundArgs>(__bound_args)...);
380}
381
382#endif // _LIBCPP_CXX03_LANG
383
384_LIBCPP_END_NAMESPACE_STD
385
386#endif // _LIBCPP___FUNCTIONAL_BIND_H
lib/libcxx/include/__functional/bind_front.h created+52
......@@ -0,0 +1,52 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___FUNCTIONAL_BIND_FRONT_H
11#define _LIBCPP___FUNCTIONAL_BIND_FRONT_H
12
13#include <__config>
14#include <__functional/perfect_forward.h>
15#include <__functional/invoke.h>
16#include <type_traits>
17#include <utility>
18
19#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
20#pragma GCC system_header
21#endif
22
23_LIBCPP_BEGIN_NAMESPACE_STD
24
25#if _LIBCPP_STD_VER > 17
26
27struct __bind_front_op
28{
29 template<class... _Args>
30 constexpr static auto __call(_Args&&... __args)
31 noexcept(noexcept(_VSTD::invoke(_VSTD::forward<_Args>(__args)...)))
32 -> decltype( _VSTD::invoke(_VSTD::forward<_Args>(__args)...))
33 { return _VSTD::invoke(_VSTD::forward<_Args>(__args)...); }
34};
35
36template<class _Fn, class... _Args,
37 class = _EnableIf<conjunction<is_constructible<decay_t<_Fn>, _Fn>,
38 is_move_constructible<decay_t<_Fn>>,
39 is_constructible<decay_t<_Args>, _Args>...,
40 is_move_constructible<decay_t<_Args>>...
41 >::value>>
42constexpr auto bind_front(_Fn&& __f, _Args&&... __args)
43{
44 return __perfect_forward<__bind_front_op, _Fn, _Args...>(_VSTD::forward<_Fn>(__f),
45 _VSTD::forward<_Args>(__args)...);
46}
47
48#endif // _LIBCPP_STD_VER > 17
49
50_LIBCPP_END_NAMESPACE_STD
51
52#endif // _LIBCPP___FUNCTIONAL_BIND_FRONT_H
lib/libcxx/include/__functional/binder1st.h created+54
......@@ -0,0 +1,54 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___FUNCTIONAL_BINDER1ST_H
11#define _LIBCPP___FUNCTIONAL_BINDER1ST_H
12
13#include <__config>
14#include <__functional/unary_function.h>
15
16#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
17#pragma GCC system_header
18#endif
19
20_LIBCPP_BEGIN_NAMESPACE_STD
21
22#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS)
23
24template <class __Operation>
25class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 binder1st
26 : public unary_function<typename __Operation::second_argument_type,
27 typename __Operation::result_type>
28{
29protected:
30 __Operation op;
31 typename __Operation::first_argument_type value;
32public:
33 _LIBCPP_INLINE_VISIBILITY binder1st(const __Operation& __x,
34 const typename __Operation::first_argument_type __y)
35 : op(__x), value(__y) {}
36 _LIBCPP_INLINE_VISIBILITY typename __Operation::result_type operator()
37 (typename __Operation::second_argument_type& __x) const
38 {return op(value, __x);}
39 _LIBCPP_INLINE_VISIBILITY typename __Operation::result_type operator()
40 (const typename __Operation::second_argument_type& __x) const
41 {return op(value, __x);}
42};
43
44template <class __Operation, class _Tp>
45_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY
46binder1st<__Operation>
47bind1st(const __Operation& __op, const _Tp& __x)
48 {return binder1st<__Operation>(__op, __x);}
49
50#endif // _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS)
51
52_LIBCPP_END_NAMESPACE_STD
53
54#endif // _LIBCPP___FUNCTIONAL_BINDER1ST_H
lib/libcxx/include/__functional/binder2nd.h created+54
......@@ -0,0 +1,54 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___FUNCTIONAL_BINDER2ND_H
11#define _LIBCPP___FUNCTIONAL_BINDER2ND_H
12
13#include <__config>
14#include <__functional/unary_function.h>
15
16#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
17#pragma GCC system_header
18#endif
19
20_LIBCPP_BEGIN_NAMESPACE_STD
21
22#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS)
23
24template <class __Operation>
25class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 binder2nd
26 : public unary_function<typename __Operation::first_argument_type,
27 typename __Operation::result_type>
28{
29protected:
30 __Operation op;
31 typename __Operation::second_argument_type value;
32public:
33 _LIBCPP_INLINE_VISIBILITY
34 binder2nd(const __Operation& __x, const typename __Operation::second_argument_type __y)
35 : op(__x), value(__y) {}
36 _LIBCPP_INLINE_VISIBILITY typename __Operation::result_type operator()
37 ( typename __Operation::first_argument_type& __x) const
38 {return op(__x, value);}
39 _LIBCPP_INLINE_VISIBILITY typename __Operation::result_type operator()
40 (const typename __Operation::first_argument_type& __x) const
41 {return op(__x, value);}
42};
43
44template <class __Operation, class _Tp>
45_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY
46binder2nd<__Operation>
47bind2nd(const __Operation& __op, const _Tp& __x)
48 {return binder2nd<__Operation>(__op, __x);}
49
50#endif // _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS)
51
52_LIBCPP_END_NAMESPACE_STD
53
54#endif // _LIBCPP___FUNCTIONAL_BINDER2ND_H
lib/libcxx/include/__functional/default_searcher.h created+56
......@@ -0,0 +1,56 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___FUNCTIONAL_DEFAULT_SEARCHER_H
11#define _LIBCPP___FUNCTIONAL_DEFAULT_SEARCHER_H
12
13#include <__algorithm/search.h>
14#include <__config>
15#include <__functional/operations.h>
16#include <__iterator/iterator_traits.h>
17#include <utility>
18
19#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
20#pragma GCC system_header
21#endif
22
23_LIBCPP_BEGIN_NAMESPACE_STD
24
25#if _LIBCPP_STD_VER > 14
26
27// default searcher
28template<class _ForwardIterator, class _BinaryPredicate = equal_to<>>
29class _LIBCPP_TEMPLATE_VIS default_searcher {
30public:
31 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
32 default_searcher(_ForwardIterator __f, _ForwardIterator __l,
33 _BinaryPredicate __p = _BinaryPredicate())
34 : __first_(__f), __last_(__l), __pred_(__p) {}
35
36 template <typename _ForwardIterator2>
37 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
38 pair<_ForwardIterator2, _ForwardIterator2>
39 operator () (_ForwardIterator2 __f, _ForwardIterator2 __l) const
40 {
41 return _VSTD::__search(__f, __l, __first_, __last_, __pred_,
42 typename iterator_traits<_ForwardIterator>::iterator_category(),
43 typename iterator_traits<_ForwardIterator2>::iterator_category());
44 }
45
46private:
47 _ForwardIterator __first_;
48 _ForwardIterator __last_;
49 _BinaryPredicate __pred_;
50 };
51
52#endif // _LIBCPP_STD_VER > 14
53
54_LIBCPP_END_NAMESPACE_STD
55
56#endif // _LIBCPP___FUNCTIONAL_DEFAULT_SEARCHER_H
lib/libcxx/include/__functional/function.h created+2809
......@@ -0,0 +1,2809 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___FUNCTIONAL_FUNCTION_H
11#define _LIBCPP___FUNCTIONAL_FUNCTION_H
12
13#include <__config>
14#include <__functional/binary_function.h>
15#include <__functional/invoke.h>
16#include <__functional/unary_function.h>
17#include <__iterator/iterator_traits.h>
18#include <__memory/allocator_traits.h>
19#include <__memory/compressed_pair.h>
20#include <__memory/shared_ptr.h>
21#include <exception>
22#include <memory> // TODO: replace with <__memory/__builtin_new_allocator.h>
23#include <type_traits>
24#include <utility>
25
26#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
27#pragma GCC system_header
28#endif
29
30_LIBCPP_BEGIN_NAMESPACE_STD
31
32// bad_function_call
33
34class _LIBCPP_EXCEPTION_ABI bad_function_call
35 : public exception
36{
37#ifdef _LIBCPP_ABI_BAD_FUNCTION_CALL_KEY_FUNCTION
38public:
39 virtual ~bad_function_call() _NOEXCEPT;
40
41 virtual const char* what() const _NOEXCEPT;
42#endif
43};
44
45_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
46void __throw_bad_function_call()
47{
48#ifndef _LIBCPP_NO_EXCEPTIONS
49 throw bad_function_call();
50#else
51 _VSTD::abort();
52#endif
53}
54
55#if defined(_LIBCPP_CXX03_LANG) && !defined(_LIBCPP_DISABLE_DEPRECATION_WARNINGS) && __has_attribute(deprecated)
56# define _LIBCPP_DEPRECATED_CXX03_FUNCTION \
57 __attribute__((deprecated("Using std::function in C++03 is not supported anymore. Please upgrade to C++11 or later, or use a different type")))
58#else
59# define _LIBCPP_DEPRECATED_CXX03_FUNCTION /* nothing */
60#endif
61
62template<class _Fp> class _LIBCPP_DEPRECATED_CXX03_FUNCTION _LIBCPP_TEMPLATE_VIS function; // undefined
63
64namespace __function
65{
66
67template<class _Rp>
68struct __maybe_derive_from_unary_function
69{
70};
71
72template<class _Rp, class _A1>
73struct __maybe_derive_from_unary_function<_Rp(_A1)>
74 : public unary_function<_A1, _Rp>
75{
76};
77
78template<class _Rp>
79struct __maybe_derive_from_binary_function
80{
81};
82
83template<class _Rp, class _A1, class _A2>
84struct __maybe_derive_from_binary_function<_Rp(_A1, _A2)>
85 : public binary_function<_A1, _A2, _Rp>
86{
87};
88
89template <class _Fp>
90_LIBCPP_INLINE_VISIBILITY
91bool __not_null(_Fp const&) { return true; }
92
93template <class _Fp>
94_LIBCPP_INLINE_VISIBILITY
95bool __not_null(_Fp* __ptr) { return __ptr; }
96
97template <class _Ret, class _Class>
98_LIBCPP_INLINE_VISIBILITY
99bool __not_null(_Ret _Class::*__ptr) { return __ptr; }
100
101template <class _Fp>
102_LIBCPP_INLINE_VISIBILITY
103bool __not_null(function<_Fp> const& __f) { return !!__f; }
104
105#ifdef _LIBCPP_HAS_EXTENSION_BLOCKS
106template <class _Rp, class ..._Args>
107_LIBCPP_INLINE_VISIBILITY
108bool __not_null(_Rp (^__p)(_Args...)) { return __p; }
109#endif
110
111} // namespace __function
112
113#ifndef _LIBCPP_CXX03_LANG
114
115namespace __function {
116
117// __alloc_func holds a functor and an allocator.
118
119template <class _Fp, class _Ap, class _FB> class __alloc_func;
120template <class _Fp, class _FB>
121class __default_alloc_func;
122
123template <class _Fp, class _Ap, class _Rp, class... _ArgTypes>
124class __alloc_func<_Fp, _Ap, _Rp(_ArgTypes...)>
125{
126 __compressed_pair<_Fp, _Ap> __f_;
127
128 public:
129 typedef _LIBCPP_NODEBUG_TYPE _Fp _Target;
130 typedef _LIBCPP_NODEBUG_TYPE _Ap _Alloc;
131
132 _LIBCPP_INLINE_VISIBILITY
133 const _Target& __target() const { return __f_.first(); }
134
135 // WIN32 APIs may define __allocator, so use __get_allocator instead.
136 _LIBCPP_INLINE_VISIBILITY
137 const _Alloc& __get_allocator() const { return __f_.second(); }
138
139 _LIBCPP_INLINE_VISIBILITY
140 explicit __alloc_func(_Target&& __f)
141 : __f_(piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__f)),
142 _VSTD::forward_as_tuple())
143 {
144 }
145
146 _LIBCPP_INLINE_VISIBILITY
147 explicit __alloc_func(const _Target& __f, const _Alloc& __a)
148 : __f_(piecewise_construct, _VSTD::forward_as_tuple(__f),
149 _VSTD::forward_as_tuple(__a))
150 {
151 }
152
153 _LIBCPP_INLINE_VISIBILITY
154 explicit __alloc_func(const _Target& __f, _Alloc&& __a)
155 : __f_(piecewise_construct, _VSTD::forward_as_tuple(__f),
156 _VSTD::forward_as_tuple(_VSTD::move(__a)))
157 {
158 }
159
160 _LIBCPP_INLINE_VISIBILITY
161 explicit __alloc_func(_Target&& __f, _Alloc&& __a)
162 : __f_(piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__f)),
163 _VSTD::forward_as_tuple(_VSTD::move(__a)))
164 {
165 }
166
167 _LIBCPP_INLINE_VISIBILITY
168 _Rp operator()(_ArgTypes&&... __arg)
169 {
170 typedef __invoke_void_return_wrapper<_Rp> _Invoker;
171 return _Invoker::__call(__f_.first(),
172 _VSTD::forward<_ArgTypes>(__arg)...);
173 }
174
175 _LIBCPP_INLINE_VISIBILITY
176 __alloc_func* __clone() const
177 {
178 typedef allocator_traits<_Alloc> __alloc_traits;
179 typedef
180 typename __rebind_alloc_helper<__alloc_traits, __alloc_func>::type
181 _AA;
182 _AA __a(__f_.second());
183 typedef __allocator_destructor<_AA> _Dp;
184 unique_ptr<__alloc_func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
185 ::new ((void*)__hold.get()) __alloc_func(__f_.first(), _Alloc(__a));
186 return __hold.release();
187 }
188
189 _LIBCPP_INLINE_VISIBILITY
190 void destroy() _NOEXCEPT { __f_.~__compressed_pair<_Target, _Alloc>(); }
191
192 static void __destroy_and_delete(__alloc_func* __f) {
193 typedef allocator_traits<_Alloc> __alloc_traits;
194 typedef typename __rebind_alloc_helper<__alloc_traits, __alloc_func>::type
195 _FunAlloc;
196 _FunAlloc __a(__f->__get_allocator());
197 __f->destroy();
198 __a.deallocate(__f, 1);
199 }
200};
201
202template <class _Fp, class _Rp, class... _ArgTypes>
203class __default_alloc_func<_Fp, _Rp(_ArgTypes...)> {
204 _Fp __f_;
205
206public:
207 typedef _LIBCPP_NODEBUG_TYPE _Fp _Target;
208
209 _LIBCPP_INLINE_VISIBILITY
210 const _Target& __target() const { return __f_; }
211
212 _LIBCPP_INLINE_VISIBILITY
213 explicit __default_alloc_func(_Target&& __f) : __f_(_VSTD::move(__f)) {}
214
215 _LIBCPP_INLINE_VISIBILITY
216 explicit __default_alloc_func(const _Target& __f) : __f_(__f) {}
217
218 _LIBCPP_INLINE_VISIBILITY
219 _Rp operator()(_ArgTypes&&... __arg) {
220 typedef __invoke_void_return_wrapper<_Rp> _Invoker;
221 return _Invoker::__call(__f_, _VSTD::forward<_ArgTypes>(__arg)...);
222 }
223
224 _LIBCPP_INLINE_VISIBILITY
225 __default_alloc_func* __clone() const {
226 __builtin_new_allocator::__holder_t __hold =
227 __builtin_new_allocator::__allocate_type<__default_alloc_func>(1);
228 __default_alloc_func* __res =
229 ::new ((void*)__hold.get()) __default_alloc_func(__f_);
230 (void)__hold.release();
231 return __res;
232 }
233
234 _LIBCPP_INLINE_VISIBILITY
235 void destroy() _NOEXCEPT { __f_.~_Target(); }
236
237 static void __destroy_and_delete(__default_alloc_func* __f) {
238 __f->destroy();
239 __builtin_new_allocator::__deallocate_type<__default_alloc_func>(__f, 1);
240 }
241};
242
243// __base provides an abstract interface for copyable functors.
244
245template<class _Fp> class _LIBCPP_TEMPLATE_VIS __base;
246
247template<class _Rp, class ..._ArgTypes>
248class __base<_Rp(_ArgTypes...)>
249{
250 __base(const __base&);
251 __base& operator=(const __base&);
252public:
253 _LIBCPP_INLINE_VISIBILITY __base() {}
254 _LIBCPP_INLINE_VISIBILITY virtual ~__base() {}
255 virtual __base* __clone() const = 0;
256 virtual void __clone(__base*) const = 0;
257 virtual void destroy() _NOEXCEPT = 0;
258 virtual void destroy_deallocate() _NOEXCEPT = 0;
259 virtual _Rp operator()(_ArgTypes&& ...) = 0;
260#ifndef _LIBCPP_NO_RTTI
261 virtual const void* target(const type_info&) const _NOEXCEPT = 0;
262 virtual const std::type_info& target_type() const _NOEXCEPT = 0;
263#endif // _LIBCPP_NO_RTTI
264};
265
266// __func implements __base for a given functor type.
267
268template<class _FD, class _Alloc, class _FB> class __func;
269
270template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
271class __func<_Fp, _Alloc, _Rp(_ArgTypes...)>
272 : public __base<_Rp(_ArgTypes...)>
273{
274 __alloc_func<_Fp, _Alloc, _Rp(_ArgTypes...)> __f_;
275public:
276 _LIBCPP_INLINE_VISIBILITY
277 explicit __func(_Fp&& __f)
278 : __f_(_VSTD::move(__f)) {}
279
280 _LIBCPP_INLINE_VISIBILITY
281 explicit __func(const _Fp& __f, const _Alloc& __a)
282 : __f_(__f, __a) {}
283
284 _LIBCPP_INLINE_VISIBILITY
285 explicit __func(const _Fp& __f, _Alloc&& __a)
286 : __f_(__f, _VSTD::move(__a)) {}
287
288 _LIBCPP_INLINE_VISIBILITY
289 explicit __func(_Fp&& __f, _Alloc&& __a)
290 : __f_(_VSTD::move(__f), _VSTD::move(__a)) {}
291
292 virtual __base<_Rp(_ArgTypes...)>* __clone() const;
293 virtual void __clone(__base<_Rp(_ArgTypes...)>*) const;
294 virtual void destroy() _NOEXCEPT;
295 virtual void destroy_deallocate() _NOEXCEPT;
296 virtual _Rp operator()(_ArgTypes&&... __arg);
297#ifndef _LIBCPP_NO_RTTI
298 virtual const void* target(const type_info&) const _NOEXCEPT;
299 virtual const std::type_info& target_type() const _NOEXCEPT;
300#endif // _LIBCPP_NO_RTTI
301};
302
303template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
304__base<_Rp(_ArgTypes...)>*
305__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__clone() const
306{
307 typedef allocator_traits<_Alloc> __alloc_traits;
308 typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
309 _Ap __a(__f_.__get_allocator());
310 typedef __allocator_destructor<_Ap> _Dp;
311 unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
312 ::new ((void*)__hold.get()) __func(__f_.__target(), _Alloc(__a));
313 return __hold.release();
314}
315
316template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
317void
318__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__clone(__base<_Rp(_ArgTypes...)>* __p) const
319{
320 ::new ((void*)__p) __func(__f_.__target(), __f_.__get_allocator());
321}
322
323template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
324void
325__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy() _NOEXCEPT
326{
327 __f_.destroy();
328}
329
330template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
331void
332__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate() _NOEXCEPT
333{
334 typedef allocator_traits<_Alloc> __alloc_traits;
335 typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
336 _Ap __a(__f_.__get_allocator());
337 __f_.destroy();
338 __a.deallocate(this, 1);
339}
340
341template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
342_Rp
343__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg)
344{
345 return __f_(_VSTD::forward<_ArgTypes>(__arg)...);
346}
347
348#ifndef _LIBCPP_NO_RTTI
349
350template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
351const void*
352__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::target(const type_info& __ti) const _NOEXCEPT
353{
354 if (__ti == typeid(_Fp))
355 return &__f_.__target();
356 return nullptr;
357}
358
359template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
360const std::type_info&
361__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::target_type() const _NOEXCEPT
362{
363 return typeid(_Fp);
364}
365
366#endif // _LIBCPP_NO_RTTI
367
368// __value_func creates a value-type from a __func.
369
370template <class _Fp> class __value_func;
371
372template <class _Rp, class... _ArgTypes> class __value_func<_Rp(_ArgTypes...)>
373{
374 typename aligned_storage<3 * sizeof(void*)>::type __buf_;
375
376 typedef __base<_Rp(_ArgTypes...)> __func;
377 __func* __f_;
378
379 _LIBCPP_NO_CFI static __func* __as_base(void* p)
380 {
381 return reinterpret_cast<__func*>(p);
382 }
383
384 public:
385 _LIBCPP_INLINE_VISIBILITY
386 __value_func() _NOEXCEPT : __f_(nullptr) {}
387
388 template <class _Fp, class _Alloc>
389 _LIBCPP_INLINE_VISIBILITY __value_func(_Fp&& __f, const _Alloc& __a)
390 : __f_(nullptr)
391 {
392 typedef allocator_traits<_Alloc> __alloc_traits;
393 typedef __function::__func<_Fp, _Alloc, _Rp(_ArgTypes...)> _Fun;
394 typedef typename __rebind_alloc_helper<__alloc_traits, _Fun>::type
395 _FunAlloc;
396
397 if (__function::__not_null(__f))
398 {
399 _FunAlloc __af(__a);
400 if (sizeof(_Fun) <= sizeof(__buf_) &&
401 is_nothrow_copy_constructible<_Fp>::value &&
402 is_nothrow_copy_constructible<_FunAlloc>::value)
403 {
404 __f_ =
405 ::new ((void*)&__buf_) _Fun(_VSTD::move(__f), _Alloc(__af));
406 }
407 else
408 {
409 typedef __allocator_destructor<_FunAlloc> _Dp;
410 unique_ptr<__func, _Dp> __hold(__af.allocate(1), _Dp(__af, 1));
411 ::new ((void*)__hold.get()) _Fun(_VSTD::move(__f), _Alloc(__a));
412 __f_ = __hold.release();
413 }
414 }
415 }
416
417 template <class _Fp,
418 class = typename enable_if<!is_same<typename decay<_Fp>::type, __value_func>::value>::type>
419 _LIBCPP_INLINE_VISIBILITY explicit __value_func(_Fp&& __f)
420 : __value_func(_VSTD::forward<_Fp>(__f), allocator<_Fp>()) {}
421
422 _LIBCPP_INLINE_VISIBILITY
423 __value_func(const __value_func& __f)
424 {
425 if (__f.__f_ == nullptr)
426 __f_ = nullptr;
427 else if ((void*)__f.__f_ == &__f.__buf_)
428 {
429 __f_ = __as_base(&__buf_);
430 __f.__f_->__clone(__f_);
431 }
432 else
433 __f_ = __f.__f_->__clone();
434 }
435
436 _LIBCPP_INLINE_VISIBILITY
437 __value_func(__value_func&& __f) _NOEXCEPT
438 {
439 if (__f.__f_ == nullptr)
440 __f_ = nullptr;
441 else if ((void*)__f.__f_ == &__f.__buf_)
442 {
443 __f_ = __as_base(&__buf_);
444 __f.__f_->__clone(__f_);
445 }
446 else
447 {
448 __f_ = __f.__f_;
449 __f.__f_ = nullptr;
450 }
451 }
452
453 _LIBCPP_INLINE_VISIBILITY
454 ~__value_func()
455 {
456 if ((void*)__f_ == &__buf_)
457 __f_->destroy();
458 else if (__f_)
459 __f_->destroy_deallocate();
460 }
461
462 _LIBCPP_INLINE_VISIBILITY
463 __value_func& operator=(__value_func&& __f)
464 {
465 *this = nullptr;
466 if (__f.__f_ == nullptr)
467 __f_ = nullptr;
468 else if ((void*)__f.__f_ == &__f.__buf_)
469 {
470 __f_ = __as_base(&__buf_);
471 __f.__f_->__clone(__f_);
472 }
473 else
474 {
475 __f_ = __f.__f_;
476 __f.__f_ = nullptr;
477 }
478 return *this;
479 }
480
481 _LIBCPP_INLINE_VISIBILITY
482 __value_func& operator=(nullptr_t)
483 {
484 __func* __f = __f_;
485 __f_ = nullptr;
486 if ((void*)__f == &__buf_)
487 __f->destroy();
488 else if (__f)
489 __f->destroy_deallocate();
490 return *this;
491 }
492
493 _LIBCPP_INLINE_VISIBILITY
494 _Rp operator()(_ArgTypes&&... __args) const
495 {
496 if (__f_ == nullptr)
497 __throw_bad_function_call();
498 return (*__f_)(_VSTD::forward<_ArgTypes>(__args)...);
499 }
500
501 _LIBCPP_INLINE_VISIBILITY
502 void swap(__value_func& __f) _NOEXCEPT
503 {
504 if (&__f == this)
505 return;
506 if ((void*)__f_ == &__buf_ && (void*)__f.__f_ == &__f.__buf_)
507 {
508 typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
509 __func* __t = __as_base(&__tempbuf);
510 __f_->__clone(__t);
511 __f_->destroy();
512 __f_ = nullptr;
513 __f.__f_->__clone(__as_base(&__buf_));
514 __f.__f_->destroy();
515 __f.__f_ = nullptr;
516 __f_ = __as_base(&__buf_);
517 __t->__clone(__as_base(&__f.__buf_));
518 __t->destroy();
519 __f.__f_ = __as_base(&__f.__buf_);
520 }
521 else if ((void*)__f_ == &__buf_)
522 {
523 __f_->__clone(__as_base(&__f.__buf_));
524 __f_->destroy();
525 __f_ = __f.__f_;
526 __f.__f_ = __as_base(&__f.__buf_);
527 }
528 else if ((void*)__f.__f_ == &__f.__buf_)
529 {
530 __f.__f_->__clone(__as_base(&__buf_));
531 __f.__f_->destroy();
532 __f.__f_ = __f_;
533 __f_ = __as_base(&__buf_);
534 }
535 else
536 _VSTD::swap(__f_, __f.__f_);
537 }
538
539 _LIBCPP_INLINE_VISIBILITY
540 explicit operator bool() const _NOEXCEPT { return __f_ != nullptr; }
541
542#ifndef _LIBCPP_NO_RTTI
543 _LIBCPP_INLINE_VISIBILITY
544 const std::type_info& target_type() const _NOEXCEPT
545 {
546 if (__f_ == nullptr)
547 return typeid(void);
548 return __f_->target_type();
549 }
550
551 template <typename _Tp>
552 _LIBCPP_INLINE_VISIBILITY const _Tp* target() const _NOEXCEPT
553 {
554 if (__f_ == nullptr)
555 return nullptr;
556 return (const _Tp*)__f_->target(typeid(_Tp));
557 }
558#endif // _LIBCPP_NO_RTTI
559};
560
561// Storage for a functor object, to be used with __policy to manage copy and
562// destruction.
563union __policy_storage
564{
565 mutable char __small[sizeof(void*) * 2];
566 void* __large;
567};
568
569// True if _Fun can safely be held in __policy_storage.__small.
570template <typename _Fun>
571struct __use_small_storage
572 : public integral_constant<
573 bool, sizeof(_Fun) <= sizeof(__policy_storage) &&
574 _LIBCPP_ALIGNOF(_Fun) <= _LIBCPP_ALIGNOF(__policy_storage) &&
575 is_trivially_copy_constructible<_Fun>::value &&
576 is_trivially_destructible<_Fun>::value> {};
577
578// Policy contains information about how to copy, destroy, and move the
579// underlying functor. You can think of it as a vtable of sorts.
580struct __policy
581{
582 // Used to copy or destroy __large values. null for trivial objects.
583 void* (*const __clone)(const void*);
584 void (*const __destroy)(void*);
585
586 // True if this is the null policy (no value).
587 const bool __is_null;
588
589 // The target type. May be null if RTTI is disabled.
590 const std::type_info* const __type_info;
591
592 // Returns a pointer to a static policy object suitable for the functor
593 // type.
594 template <typename _Fun>
595 _LIBCPP_INLINE_VISIBILITY static const __policy* __create()
596 {
597 return __choose_policy<_Fun>(__use_small_storage<_Fun>());
598 }
599
600 _LIBCPP_INLINE_VISIBILITY
601 static const __policy* __create_empty()
602 {
603 static const _LIBCPP_CONSTEXPR __policy __policy_ = {nullptr, nullptr,
604 true,
605#ifndef _LIBCPP_NO_RTTI
606 &typeid(void)
607#else
608 nullptr
609#endif
610 };
611 return &__policy_;
612 }
613
614 private:
615 template <typename _Fun> static void* __large_clone(const void* __s)
616 {
617 const _Fun* __f = static_cast<const _Fun*>(__s);
618 return __f->__clone();
619 }
620
621 template <typename _Fun>
622 static void __large_destroy(void* __s) {
623 _Fun::__destroy_and_delete(static_cast<_Fun*>(__s));
624 }
625
626 template <typename _Fun>
627 _LIBCPP_INLINE_VISIBILITY static const __policy*
628 __choose_policy(/* is_small = */ false_type) {
629 static const _LIBCPP_CONSTEXPR __policy __policy_ = {
630 &__large_clone<_Fun>, &__large_destroy<_Fun>, false,
631#ifndef _LIBCPP_NO_RTTI
632 &typeid(typename _Fun::_Target)
633#else
634 nullptr
635#endif
636 };
637 return &__policy_;
638 }
639
640 template <typename _Fun>
641 _LIBCPP_INLINE_VISIBILITY static const __policy*
642 __choose_policy(/* is_small = */ true_type)
643 {
644 static const _LIBCPP_CONSTEXPR __policy __policy_ = {
645 nullptr, nullptr, false,
646#ifndef _LIBCPP_NO_RTTI
647 &typeid(typename _Fun::_Target)
648#else
649 nullptr
650#endif
651 };
652 return &__policy_;
653 }
654};
655
656// Used to choose between perfect forwarding or pass-by-value. Pass-by-value is
657// faster for types that can be passed in registers.
658template <typename _Tp>
659using __fast_forward =
660 typename conditional<is_scalar<_Tp>::value, _Tp, _Tp&&>::type;
661
662// __policy_invoker calls an instance of __alloc_func held in __policy_storage.
663
664template <class _Fp> struct __policy_invoker;
665
666template <class _Rp, class... _ArgTypes>
667struct __policy_invoker<_Rp(_ArgTypes...)>
668{
669 typedef _Rp (*__Call)(const __policy_storage*,
670 __fast_forward<_ArgTypes>...);
671
672 __Call __call_;
673
674 // Creates an invoker that throws bad_function_call.
675 _LIBCPP_INLINE_VISIBILITY
676 __policy_invoker() : __call_(&__call_empty) {}
677
678 // Creates an invoker that calls the given instance of __func.
679 template <typename _Fun>
680 _LIBCPP_INLINE_VISIBILITY static __policy_invoker __create()
681 {
682 return __policy_invoker(&__call_impl<_Fun>);
683 }
684
685 private:
686 _LIBCPP_INLINE_VISIBILITY
687 explicit __policy_invoker(__Call __c) : __call_(__c) {}
688
689 static _Rp __call_empty(const __policy_storage*,
690 __fast_forward<_ArgTypes>...)
691 {
692 __throw_bad_function_call();
693 }
694
695 template <typename _Fun>
696 static _Rp __call_impl(const __policy_storage* __buf,
697 __fast_forward<_ArgTypes>... __args)
698 {
699 _Fun* __f = reinterpret_cast<_Fun*>(__use_small_storage<_Fun>::value
700 ? &__buf->__small
701 : __buf->__large);
702 return (*__f)(_VSTD::forward<_ArgTypes>(__args)...);
703 }
704};
705
706// __policy_func uses a __policy and __policy_invoker to create a type-erased,
707// copyable functor.
708
709template <class _Fp> class __policy_func;
710
711template <class _Rp, class... _ArgTypes> class __policy_func<_Rp(_ArgTypes...)>
712{
713 // Inline storage for small objects.
714 __policy_storage __buf_;
715
716 // Calls the value stored in __buf_. This could technically be part of
717 // policy, but storing it here eliminates a level of indirection inside
718 // operator().
719 typedef __function::__policy_invoker<_Rp(_ArgTypes...)> __invoker;
720 __invoker __invoker_;
721
722 // The policy that describes how to move / copy / destroy __buf_. Never
723 // null, even if the function is empty.
724 const __policy* __policy_;
725
726 public:
727 _LIBCPP_INLINE_VISIBILITY
728 __policy_func() : __policy_(__policy::__create_empty()) {}
729
730 template <class _Fp, class _Alloc>
731 _LIBCPP_INLINE_VISIBILITY __policy_func(_Fp&& __f, const _Alloc& __a)
732 : __policy_(__policy::__create_empty())
733 {
734 typedef __alloc_func<_Fp, _Alloc, _Rp(_ArgTypes...)> _Fun;
735 typedef allocator_traits<_Alloc> __alloc_traits;
736 typedef typename __rebind_alloc_helper<__alloc_traits, _Fun>::type
737 _FunAlloc;
738
739 if (__function::__not_null(__f))
740 {
741 __invoker_ = __invoker::template __create<_Fun>();
742 __policy_ = __policy::__create<_Fun>();
743
744 _FunAlloc __af(__a);
745 if (__use_small_storage<_Fun>())
746 {
747 ::new ((void*)&__buf_.__small)
748 _Fun(_VSTD::move(__f), _Alloc(__af));
749 }
750 else
751 {
752 typedef __allocator_destructor<_FunAlloc> _Dp;
753 unique_ptr<_Fun, _Dp> __hold(__af.allocate(1), _Dp(__af, 1));
754 ::new ((void*)__hold.get())
755 _Fun(_VSTD::move(__f), _Alloc(__af));
756 __buf_.__large = __hold.release();
757 }
758 }
759 }
760
761 template <class _Fp, class = typename enable_if<!is_same<typename decay<_Fp>::type, __policy_func>::value>::type>
762 _LIBCPP_INLINE_VISIBILITY explicit __policy_func(_Fp&& __f)
763 : __policy_(__policy::__create_empty()) {
764 typedef __default_alloc_func<_Fp, _Rp(_ArgTypes...)> _Fun;
765
766 if (__function::__not_null(__f)) {
767 __invoker_ = __invoker::template __create<_Fun>();
768 __policy_ = __policy::__create<_Fun>();
769 if (__use_small_storage<_Fun>()) {
770 ::new ((void*)&__buf_.__small) _Fun(_VSTD::move(__f));
771 } else {
772 __builtin_new_allocator::__holder_t __hold =
773 __builtin_new_allocator::__allocate_type<_Fun>(1);
774 __buf_.__large = ::new ((void*)__hold.get()) _Fun(_VSTD::move(__f));
775 (void)__hold.release();
776 }
777 }
778 }
779
780 _LIBCPP_INLINE_VISIBILITY
781 __policy_func(const __policy_func& __f)
782 : __buf_(__f.__buf_), __invoker_(__f.__invoker_),
783 __policy_(__f.__policy_)
784 {
785 if (__policy_->__clone)
786 __buf_.__large = __policy_->__clone(__f.__buf_.__large);
787 }
788
789 _LIBCPP_INLINE_VISIBILITY
790 __policy_func(__policy_func&& __f)
791 : __buf_(__f.__buf_), __invoker_(__f.__invoker_),
792 __policy_(__f.__policy_)
793 {
794 if (__policy_->__destroy)
795 {
796 __f.__policy_ = __policy::__create_empty();
797 __f.__invoker_ = __invoker();
798 }
799 }
800
801 _LIBCPP_INLINE_VISIBILITY
802 ~__policy_func()
803 {
804 if (__policy_->__destroy)
805 __policy_->__destroy(__buf_.__large);
806 }
807
808 _LIBCPP_INLINE_VISIBILITY
809 __policy_func& operator=(__policy_func&& __f)
810 {
811 *this = nullptr;
812 __buf_ = __f.__buf_;
813 __invoker_ = __f.__invoker_;
814 __policy_ = __f.__policy_;
815 __f.__policy_ = __policy::__create_empty();
816 __f.__invoker_ = __invoker();
817 return *this;
818 }
819
820 _LIBCPP_INLINE_VISIBILITY
821 __policy_func& operator=(nullptr_t)
822 {
823 const __policy* __p = __policy_;
824 __policy_ = __policy::__create_empty();
825 __invoker_ = __invoker();
826 if (__p->__destroy)
827 __p->__destroy(__buf_.__large);
828 return *this;
829 }
830
831 _LIBCPP_INLINE_VISIBILITY
832 _Rp operator()(_ArgTypes&&... __args) const
833 {
834 return __invoker_.__call_(_VSTD::addressof(__buf_),
835 _VSTD::forward<_ArgTypes>(__args)...);
836 }
837
838 _LIBCPP_INLINE_VISIBILITY
839 void swap(__policy_func& __f)
840 {
841 _VSTD::swap(__invoker_, __f.__invoker_);
842 _VSTD::swap(__policy_, __f.__policy_);
843 _VSTD::swap(__buf_, __f.__buf_);
844 }
845
846 _LIBCPP_INLINE_VISIBILITY
847 explicit operator bool() const _NOEXCEPT
848 {
849 return !__policy_->__is_null;
850 }
851
852#ifndef _LIBCPP_NO_RTTI
853 _LIBCPP_INLINE_VISIBILITY
854 const std::type_info& target_type() const _NOEXCEPT
855 {
856 return *__policy_->__type_info;
857 }
858
859 template <typename _Tp>
860 _LIBCPP_INLINE_VISIBILITY const _Tp* target() const _NOEXCEPT
861 {
862 if (__policy_->__is_null || typeid(_Tp) != *__policy_->__type_info)
863 return nullptr;
864 if (__policy_->__clone) // Out of line storage.
865 return reinterpret_cast<const _Tp*>(__buf_.__large);
866 else
867 return reinterpret_cast<const _Tp*>(&__buf_.__small);
868 }
869#endif // _LIBCPP_NO_RTTI
870};
871
872#if defined(_LIBCPP_HAS_BLOCKS_RUNTIME) && !defined(_LIBCPP_HAS_OBJC_ARC)
873
874extern "C" void *_Block_copy(const void *);
875extern "C" void _Block_release(const void *);
876
877template<class _Rp1, class ..._ArgTypes1, class _Alloc, class _Rp, class ..._ArgTypes>
878class __func<_Rp1(^)(_ArgTypes1...), _Alloc, _Rp(_ArgTypes...)>
879 : public __base<_Rp(_ArgTypes...)>
880{
881 typedef _Rp1(^__block_type)(_ArgTypes1...);
882 __block_type __f_;
883
884public:
885 _LIBCPP_INLINE_VISIBILITY
886 explicit __func(__block_type const& __f)
887 : __f_(reinterpret_cast<__block_type>(__f ? _Block_copy(__f) : nullptr))
888 { }
889
890 // [TODO] add && to save on a retain
891
892 _LIBCPP_INLINE_VISIBILITY
893 explicit __func(__block_type __f, const _Alloc& /* unused */)
894 : __f_(reinterpret_cast<__block_type>(__f ? _Block_copy(__f) : nullptr))
895 { }
896
897 virtual __base<_Rp(_ArgTypes...)>* __clone() const {
898 _LIBCPP_ASSERT(false,
899 "Block pointers are just pointers, so they should always fit into "
900 "std::function's small buffer optimization. This function should "
901 "never be invoked.");
902 return nullptr;
903 }
904
905 virtual void __clone(__base<_Rp(_ArgTypes...)>* __p) const {
906 ::new ((void*)__p) __func(__f_);
907 }
908
909 virtual void destroy() _NOEXCEPT {
910 if (__f_)
911 _Block_release(__f_);
912 __f_ = 0;
913 }
914
915 virtual void destroy_deallocate() _NOEXCEPT {
916 _LIBCPP_ASSERT(false,
917 "Block pointers are just pointers, so they should always fit into "
918 "std::function's small buffer optimization. This function should "
919 "never be invoked.");
920 }
921
922 virtual _Rp operator()(_ArgTypes&& ... __arg) {
923 return _VSTD::__invoke(__f_, _VSTD::forward<_ArgTypes>(__arg)...);
924 }
925
926#ifndef _LIBCPP_NO_RTTI
927 virtual const void* target(type_info const& __ti) const _NOEXCEPT {
928 if (__ti == typeid(__func::__block_type))
929 return &__f_;
930 return (const void*)nullptr;
931 }
932
933 virtual const std::type_info& target_type() const _NOEXCEPT {
934 return typeid(__func::__block_type);
935 }
936#endif // _LIBCPP_NO_RTTI
937};
938
939#endif // _LIBCPP_HAS_EXTENSION_BLOCKS && !_LIBCPP_HAS_OBJC_ARC
940
941} // __function
942
943template<class _Rp, class ..._ArgTypes>
944class _LIBCPP_TEMPLATE_VIS function<_Rp(_ArgTypes...)>
945#if _LIBCPP_STD_VER <= 17 || !defined(_LIBCPP_ABI_NO_BINDER_BASES)
946 : public __function::__maybe_derive_from_unary_function<_Rp(_ArgTypes...)>,
947 public __function::__maybe_derive_from_binary_function<_Rp(_ArgTypes...)>
948#endif
949{
950#ifndef _LIBCPP_ABI_OPTIMIZED_FUNCTION
951 typedef __function::__value_func<_Rp(_ArgTypes...)> __func;
952#else
953 typedef __function::__policy_func<_Rp(_ArgTypes...)> __func;
954#endif
955
956 __func __f_;
957
958 template <class _Fp, bool = _And<
959 _IsNotSame<__uncvref_t<_Fp>, function>,
960 __invokable<_Fp, _ArgTypes...>
961 >::value>
962 struct __callable;
963 template <class _Fp>
964 struct __callable<_Fp, true>
965 {
966 static const bool value = is_void<_Rp>::value ||
967 __is_core_convertible<typename __invoke_of<_Fp, _ArgTypes...>::type,
968 _Rp>::value;
969 };
970 template <class _Fp>
971 struct __callable<_Fp, false>
972 {
973 static const bool value = false;
974 };
975
976 template <class _Fp>
977 using _EnableIfLValueCallable = typename enable_if<__callable<_Fp&>::value>::type;
978public:
979 typedef _Rp result_type;
980
981 // construct/copy/destroy:
982 _LIBCPP_INLINE_VISIBILITY
983 function() _NOEXCEPT { }
984 _LIBCPP_INLINE_VISIBILITY
985 function(nullptr_t) _NOEXCEPT {}
986 function(const function&);
987 function(function&&) _NOEXCEPT;
988 template<class _Fp, class = _EnableIfLValueCallable<_Fp>>
989 function(_Fp);
990
991#if _LIBCPP_STD_VER <= 14
992 template<class _Alloc>
993 _LIBCPP_INLINE_VISIBILITY
994 function(allocator_arg_t, const _Alloc&) _NOEXCEPT {}
995 template<class _Alloc>
996 _LIBCPP_INLINE_VISIBILITY
997 function(allocator_arg_t, const _Alloc&, nullptr_t) _NOEXCEPT {}
998 template<class _Alloc>
999 function(allocator_arg_t, const _Alloc&, const function&);
1000 template<class _Alloc>
1001 function(allocator_arg_t, const _Alloc&, function&&);
1002 template<class _Fp, class _Alloc, class = _EnableIfLValueCallable<_Fp>>
1003 function(allocator_arg_t, const _Alloc& __a, _Fp __f);
1004#endif
1005
1006 function& operator=(const function&);
1007 function& operator=(function&&) _NOEXCEPT;
1008 function& operator=(nullptr_t) _NOEXCEPT;
1009 template<class _Fp, class = _EnableIfLValueCallable<typename decay<_Fp>::type>>
1010 function& operator=(_Fp&&);
1011
1012 ~function();
1013
1014 // function modifiers:
1015 void swap(function&) _NOEXCEPT;
1016
1017#if _LIBCPP_STD_VER <= 14
1018 template<class _Fp, class _Alloc>
1019 _LIBCPP_INLINE_VISIBILITY
1020 void assign(_Fp&& __f, const _Alloc& __a)
1021 {function(allocator_arg, __a, _VSTD::forward<_Fp>(__f)).swap(*this);}
1022#endif
1023
1024 // function capacity:
1025 _LIBCPP_INLINE_VISIBILITY
1026 explicit operator bool() const _NOEXCEPT {
1027 return static_cast<bool>(__f_);
1028 }
1029
1030 // deleted overloads close possible hole in the type system
1031 template<class _R2, class... _ArgTypes2>
1032 bool operator==(const function<_R2(_ArgTypes2...)>&) const = delete;
1033 template<class _R2, class... _ArgTypes2>
1034 bool operator!=(const function<_R2(_ArgTypes2...)>&) const = delete;
1035public:
1036 // function invocation:
1037 _Rp operator()(_ArgTypes...) const;
1038
1039#ifndef _LIBCPP_NO_RTTI
1040 // function target access:
1041 const std::type_info& target_type() const _NOEXCEPT;
1042 template <typename _Tp> _Tp* target() _NOEXCEPT;
1043 template <typename _Tp> const _Tp* target() const _NOEXCEPT;
1044#endif // _LIBCPP_NO_RTTI
1045};
1046
1047#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
1048template<class _Rp, class ..._Ap>
1049function(_Rp(*)(_Ap...)) -> function<_Rp(_Ap...)>;
1050
1051template<class _Fp>
1052struct __strip_signature;
1053
1054template<class _Rp, class _Gp, class ..._Ap>
1055struct __strip_signature<_Rp (_Gp::*) (_Ap...)> { using type = _Rp(_Ap...); };
1056template<class _Rp, class _Gp, class ..._Ap>
1057struct __strip_signature<_Rp (_Gp::*) (_Ap...) const> { using type = _Rp(_Ap...); };
1058template<class _Rp, class _Gp, class ..._Ap>
1059struct __strip_signature<_Rp (_Gp::*) (_Ap...) volatile> { using type = _Rp(_Ap...); };
1060template<class _Rp, class _Gp, class ..._Ap>
1061struct __strip_signature<_Rp (_Gp::*) (_Ap...) const volatile> { using type = _Rp(_Ap...); };
1062
1063template<class _Rp, class _Gp, class ..._Ap>
1064struct __strip_signature<_Rp (_Gp::*) (_Ap...) &> { using type = _Rp(_Ap...); };
1065template<class _Rp, class _Gp, class ..._Ap>
1066struct __strip_signature<_Rp (_Gp::*) (_Ap...) const &> { using type = _Rp(_Ap...); };
1067template<class _Rp, class _Gp, class ..._Ap>
1068struct __strip_signature<_Rp (_Gp::*) (_Ap...) volatile &> { using type = _Rp(_Ap...); };
1069template<class _Rp, class _Gp, class ..._Ap>
1070struct __strip_signature<_Rp (_Gp::*) (_Ap...) const volatile &> { using type = _Rp(_Ap...); };
1071
1072template<class _Rp, class _Gp, class ..._Ap>
1073struct __strip_signature<_Rp (_Gp::*) (_Ap...) noexcept> { using type = _Rp(_Ap...); };
1074template<class _Rp, class _Gp, class ..._Ap>
1075struct __strip_signature<_Rp (_Gp::*) (_Ap...) const noexcept> { using type = _Rp(_Ap...); };
1076template<class _Rp, class _Gp, class ..._Ap>
1077struct __strip_signature<_Rp (_Gp::*) (_Ap...) volatile noexcept> { using type = _Rp(_Ap...); };
1078template<class _Rp, class _Gp, class ..._Ap>
1079struct __strip_signature<_Rp (_Gp::*) (_Ap...) const volatile noexcept> { using type = _Rp(_Ap...); };
1080
1081template<class _Rp, class _Gp, class ..._Ap>
1082struct __strip_signature<_Rp (_Gp::*) (_Ap...) & noexcept> { using type = _Rp(_Ap...); };
1083template<class _Rp, class _Gp, class ..._Ap>
1084struct __strip_signature<_Rp (_Gp::*) (_Ap...) const & noexcept> { using type = _Rp(_Ap...); };
1085template<class _Rp, class _Gp, class ..._Ap>
1086struct __strip_signature<_Rp (_Gp::*) (_Ap...) volatile & noexcept> { using type = _Rp(_Ap...); };
1087template<class _Rp, class _Gp, class ..._Ap>
1088struct __strip_signature<_Rp (_Gp::*) (_Ap...) const volatile & noexcept> { using type = _Rp(_Ap...); };
1089
1090template<class _Fp, class _Stripped = typename __strip_signature<decltype(&_Fp::operator())>::type>
1091function(_Fp) -> function<_Stripped>;
1092#endif // !_LIBCPP_HAS_NO_DEDUCTION_GUIDES
1093
1094template<class _Rp, class ..._ArgTypes>
1095function<_Rp(_ArgTypes...)>::function(const function& __f) : __f_(__f.__f_) {}
1096
1097#if _LIBCPP_STD_VER <= 14
1098template<class _Rp, class ..._ArgTypes>
1099template <class _Alloc>
1100function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&,
1101 const function& __f) : __f_(__f.__f_) {}
1102#endif
1103
1104template <class _Rp, class... _ArgTypes>
1105function<_Rp(_ArgTypes...)>::function(function&& __f) _NOEXCEPT
1106 : __f_(_VSTD::move(__f.__f_)) {}
1107
1108#if _LIBCPP_STD_VER <= 14
1109template<class _Rp, class ..._ArgTypes>
1110template <class _Alloc>
1111function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&,
1112 function&& __f)
1113 : __f_(_VSTD::move(__f.__f_)) {}
1114#endif
1115
1116template <class _Rp, class... _ArgTypes>
1117template <class _Fp, class>
1118function<_Rp(_ArgTypes...)>::function(_Fp __f) : __f_(_VSTD::move(__f)) {}
1119
1120#if _LIBCPP_STD_VER <= 14
1121template <class _Rp, class... _ArgTypes>
1122template <class _Fp, class _Alloc, class>
1123function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc& __a,
1124 _Fp __f)
1125 : __f_(_VSTD::move(__f), __a) {}
1126#endif
1127
1128template<class _Rp, class ..._ArgTypes>
1129function<_Rp(_ArgTypes...)>&
1130function<_Rp(_ArgTypes...)>::operator=(const function& __f)
1131{
1132 function(__f).swap(*this);
1133 return *this;
1134}
1135
1136template<class _Rp, class ..._ArgTypes>
1137function<_Rp(_ArgTypes...)>&
1138function<_Rp(_ArgTypes...)>::operator=(function&& __f) _NOEXCEPT
1139{
1140 __f_ = _VSTD::move(__f.__f_);
1141 return *this;
1142}
1143
1144template<class _Rp, class ..._ArgTypes>
1145function<_Rp(_ArgTypes...)>&
1146function<_Rp(_ArgTypes...)>::operator=(nullptr_t) _NOEXCEPT
1147{
1148 __f_ = nullptr;
1149 return *this;
1150}
1151
1152template<class _Rp, class ..._ArgTypes>
1153template <class _Fp, class>
1154function<_Rp(_ArgTypes...)>&
1155function<_Rp(_ArgTypes...)>::operator=(_Fp&& __f)
1156{
1157 function(_VSTD::forward<_Fp>(__f)).swap(*this);
1158 return *this;
1159}
1160
1161template<class _Rp, class ..._ArgTypes>
1162function<_Rp(_ArgTypes...)>::~function() {}
1163
1164template<class _Rp, class ..._ArgTypes>
1165void
1166function<_Rp(_ArgTypes...)>::swap(function& __f) _NOEXCEPT
1167{
1168 __f_.swap(__f.__f_);
1169}
1170
1171template<class _Rp, class ..._ArgTypes>
1172_Rp
1173function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const
1174{
1175 return __f_(_VSTD::forward<_ArgTypes>(__arg)...);
1176}
1177
1178#ifndef _LIBCPP_NO_RTTI
1179
1180template<class _Rp, class ..._ArgTypes>
1181const std::type_info&
1182function<_Rp(_ArgTypes...)>::target_type() const _NOEXCEPT
1183{
1184 return __f_.target_type();
1185}
1186
1187template<class _Rp, class ..._ArgTypes>
1188template <typename _Tp>
1189_Tp*
1190function<_Rp(_ArgTypes...)>::target() _NOEXCEPT
1191{
1192 return (_Tp*)(__f_.template target<_Tp>());
1193}
1194
1195template<class _Rp, class ..._ArgTypes>
1196template <typename _Tp>
1197const _Tp*
1198function<_Rp(_ArgTypes...)>::target() const _NOEXCEPT
1199{
1200 return __f_.template target<_Tp>();
1201}
1202
1203#endif // _LIBCPP_NO_RTTI
1204
1205template <class _Rp, class... _ArgTypes>
1206inline _LIBCPP_INLINE_VISIBILITY
1207bool
1208operator==(const function<_Rp(_ArgTypes...)>& __f, nullptr_t) _NOEXCEPT {return !__f;}
1209
1210template <class _Rp, class... _ArgTypes>
1211inline _LIBCPP_INLINE_VISIBILITY
1212bool
1213operator==(nullptr_t, const function<_Rp(_ArgTypes...)>& __f) _NOEXCEPT {return !__f;}
1214
1215template <class _Rp, class... _ArgTypes>
1216inline _LIBCPP_INLINE_VISIBILITY
1217bool
1218operator!=(const function<_Rp(_ArgTypes...)>& __f, nullptr_t) _NOEXCEPT {return (bool)__f;}
1219
1220template <class _Rp, class... _ArgTypes>
1221inline _LIBCPP_INLINE_VISIBILITY
1222bool
1223operator!=(nullptr_t, const function<_Rp(_ArgTypes...)>& __f) _NOEXCEPT {return (bool)__f;}
1224
1225template <class _Rp, class... _ArgTypes>
1226inline _LIBCPP_INLINE_VISIBILITY
1227void
1228swap(function<_Rp(_ArgTypes...)>& __x, function<_Rp(_ArgTypes...)>& __y) _NOEXCEPT
1229{return __x.swap(__y);}
1230
1231#else // _LIBCPP_CXX03_LANG
1232
1233namespace __function {
1234
1235template<class _Fp> class __base;
1236
1237template<class _Rp>
1238class __base<_Rp()>
1239{
1240 __base(const __base&);
1241 __base& operator=(const __base&);
1242public:
1243 __base() {}
1244 virtual ~__base() {}
1245 virtual __base* __clone() const = 0;
1246 virtual void __clone(__base*) const = 0;
1247 virtual void destroy() = 0;
1248 virtual void destroy_deallocate() = 0;
1249 virtual _Rp operator()() = 0;
1250#ifndef _LIBCPP_NO_RTTI
1251 virtual const void* target(const type_info&) const = 0;
1252 virtual const std::type_info& target_type() const = 0;
1253#endif // _LIBCPP_NO_RTTI
1254};
1255
1256template<class _Rp, class _A0>
1257class __base<_Rp(_A0)>
1258{
1259 __base(const __base&);
1260 __base& operator=(const __base&);
1261public:
1262 __base() {}
1263 virtual ~__base() {}
1264 virtual __base* __clone() const = 0;
1265 virtual void __clone(__base*) const = 0;
1266 virtual void destroy() = 0;
1267 virtual void destroy_deallocate() = 0;
1268 virtual _Rp operator()(_A0) = 0;
1269#ifndef _LIBCPP_NO_RTTI
1270 virtual const void* target(const type_info&) const = 0;
1271 virtual const std::type_info& target_type() const = 0;
1272#endif // _LIBCPP_NO_RTTI
1273};
1274
1275template<class _Rp, class _A0, class _A1>
1276class __base<_Rp(_A0, _A1)>
1277{
1278 __base(const __base&);
1279 __base& operator=(const __base&);
1280public:
1281 __base() {}
1282 virtual ~__base() {}
1283 virtual __base* __clone() const = 0;
1284 virtual void __clone(__base*) const = 0;
1285 virtual void destroy() = 0;
1286 virtual void destroy_deallocate() = 0;
1287 virtual _Rp operator()(_A0, _A1) = 0;
1288#ifndef _LIBCPP_NO_RTTI
1289 virtual const void* target(const type_info&) const = 0;
1290 virtual const std::type_info& target_type() const = 0;
1291#endif // _LIBCPP_NO_RTTI
1292};
1293
1294template<class _Rp, class _A0, class _A1, class _A2>
1295class __base<_Rp(_A0, _A1, _A2)>
1296{
1297 __base(const __base&);
1298 __base& operator=(const __base&);
1299public:
1300 __base() {}
1301 virtual ~__base() {}
1302 virtual __base* __clone() const = 0;
1303 virtual void __clone(__base*) const = 0;
1304 virtual void destroy() = 0;
1305 virtual void destroy_deallocate() = 0;
1306 virtual _Rp operator()(_A0, _A1, _A2) = 0;
1307#ifndef _LIBCPP_NO_RTTI
1308 virtual const void* target(const type_info&) const = 0;
1309 virtual const std::type_info& target_type() const = 0;
1310#endif // _LIBCPP_NO_RTTI
1311};
1312
1313template<class _FD, class _Alloc, class _FB> class __func;
1314
1315template<class _Fp, class _Alloc, class _Rp>
1316class __func<_Fp, _Alloc, _Rp()>
1317 : public __base<_Rp()>
1318{
1319 __compressed_pair<_Fp, _Alloc> __f_;
1320public:
1321 explicit __func(_Fp __f) : __f_(_VSTD::move(__f), __default_init_tag()) {}
1322 explicit __func(_Fp __f, _Alloc __a) : __f_(_VSTD::move(__f), _VSTD::move(__a)) {}
1323 virtual __base<_Rp()>* __clone() const;
1324 virtual void __clone(__base<_Rp()>*) const;
1325 virtual void destroy();
1326 virtual void destroy_deallocate();
1327 virtual _Rp operator()();
1328#ifndef _LIBCPP_NO_RTTI
1329 virtual const void* target(const type_info&) const;
1330 virtual const std::type_info& target_type() const;
1331#endif // _LIBCPP_NO_RTTI
1332};
1333
1334template<class _Fp, class _Alloc, class _Rp>
1335__base<_Rp()>*
1336__func<_Fp, _Alloc, _Rp()>::__clone() const
1337{
1338 typedef allocator_traits<_Alloc> __alloc_traits;
1339 typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
1340 _Ap __a(__f_.second());
1341 typedef __allocator_destructor<_Ap> _Dp;
1342 unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1343 ::new ((void*)__hold.get()) __func(__f_.first(), _Alloc(__a));
1344 return __hold.release();
1345}
1346
1347template<class _Fp, class _Alloc, class _Rp>
1348void
1349__func<_Fp, _Alloc, _Rp()>::__clone(__base<_Rp()>* __p) const
1350{
1351 ::new ((void*)__p) __func(__f_.first(), __f_.second());
1352}
1353
1354template<class _Fp, class _Alloc, class _Rp>
1355void
1356__func<_Fp, _Alloc, _Rp()>::destroy()
1357{
1358 __f_.~__compressed_pair<_Fp, _Alloc>();
1359}
1360
1361template<class _Fp, class _Alloc, class _Rp>
1362void
1363__func<_Fp, _Alloc, _Rp()>::destroy_deallocate()
1364{
1365 typedef allocator_traits<_Alloc> __alloc_traits;
1366 typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
1367 _Ap __a(__f_.second());
1368 __f_.~__compressed_pair<_Fp, _Alloc>();
1369 __a.deallocate(this, 1);
1370}
1371
1372template<class _Fp, class _Alloc, class _Rp>
1373_Rp
1374__func<_Fp, _Alloc, _Rp()>::operator()()
1375{
1376 typedef __invoke_void_return_wrapper<_Rp> _Invoker;
1377 return _Invoker::__call(__f_.first());
1378}
1379
1380#ifndef _LIBCPP_NO_RTTI
1381
1382template<class _Fp, class _Alloc, class _Rp>
1383const void*
1384__func<_Fp, _Alloc, _Rp()>::target(const type_info& __ti) const
1385{
1386 if (__ti == typeid(_Fp))
1387 return &__f_.first();
1388 return (const void*)0;
1389}
1390
1391template<class _Fp, class _Alloc, class _Rp>
1392const std::type_info&
1393__func<_Fp, _Alloc, _Rp()>::target_type() const
1394{
1395 return typeid(_Fp);
1396}
1397
1398#endif // _LIBCPP_NO_RTTI
1399
1400template<class _Fp, class _Alloc, class _Rp, class _A0>
1401class __func<_Fp, _Alloc, _Rp(_A0)>
1402 : public __base<_Rp(_A0)>
1403{
1404 __compressed_pair<_Fp, _Alloc> __f_;
1405public:
1406 _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f) : __f_(_VSTD::move(__f), __default_init_tag()) {}
1407 _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f, _Alloc __a)
1408 : __f_(_VSTD::move(__f), _VSTD::move(__a)) {}
1409 virtual __base<_Rp(_A0)>* __clone() const;
1410 virtual void __clone(__base<_Rp(_A0)>*) const;
1411 virtual void destroy();
1412 virtual void destroy_deallocate();
1413 virtual _Rp operator()(_A0);
1414#ifndef _LIBCPP_NO_RTTI
1415 virtual const void* target(const type_info&) const;
1416 virtual const std::type_info& target_type() const;
1417#endif // _LIBCPP_NO_RTTI
1418};
1419
1420template<class _Fp, class _Alloc, class _Rp, class _A0>
1421__base<_Rp(_A0)>*
1422__func<_Fp, _Alloc, _Rp(_A0)>::__clone() const
1423{
1424 typedef allocator_traits<_Alloc> __alloc_traits;
1425 typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
1426 _Ap __a(__f_.second());
1427 typedef __allocator_destructor<_Ap> _Dp;
1428 unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1429 ::new ((void*)__hold.get()) __func(__f_.first(), _Alloc(__a));
1430 return __hold.release();
1431}
1432
1433template<class _Fp, class _Alloc, class _Rp, class _A0>
1434void
1435__func<_Fp, _Alloc, _Rp(_A0)>::__clone(__base<_Rp(_A0)>* __p) const
1436{
1437 ::new ((void*)__p) __func(__f_.first(), __f_.second());
1438}
1439
1440template<class _Fp, class _Alloc, class _Rp, class _A0>
1441void
1442__func<_Fp, _Alloc, _Rp(_A0)>::destroy()
1443{
1444 __f_.~__compressed_pair<_Fp, _Alloc>();
1445}
1446
1447template<class _Fp, class _Alloc, class _Rp, class _A0>
1448void
1449__func<_Fp, _Alloc, _Rp(_A0)>::destroy_deallocate()
1450{
1451 typedef allocator_traits<_Alloc> __alloc_traits;
1452 typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
1453 _Ap __a(__f_.second());
1454 __f_.~__compressed_pair<_Fp, _Alloc>();
1455 __a.deallocate(this, 1);
1456}
1457
1458template<class _Fp, class _Alloc, class _Rp, class _A0>
1459_Rp
1460__func<_Fp, _Alloc, _Rp(_A0)>::operator()(_A0 __a0)
1461{
1462 typedef __invoke_void_return_wrapper<_Rp> _Invoker;
1463 return _Invoker::__call(__f_.first(), __a0);
1464}
1465
1466#ifndef _LIBCPP_NO_RTTI
1467
1468template<class _Fp, class _Alloc, class _Rp, class _A0>
1469const void*
1470__func<_Fp, _Alloc, _Rp(_A0)>::target(const type_info& __ti) const
1471{
1472 if (__ti == typeid(_Fp))
1473 return &__f_.first();
1474 return (const void*)0;
1475}
1476
1477template<class _Fp, class _Alloc, class _Rp, class _A0>
1478const std::type_info&
1479__func<_Fp, _Alloc, _Rp(_A0)>::target_type() const
1480{
1481 return typeid(_Fp);
1482}
1483
1484#endif // _LIBCPP_NO_RTTI
1485
1486template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
1487class __func<_Fp, _Alloc, _Rp(_A0, _A1)>
1488 : public __base<_Rp(_A0, _A1)>
1489{
1490 __compressed_pair<_Fp, _Alloc> __f_;
1491public:
1492 _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f) : __f_(_VSTD::move(__f), __default_init_tag()) {}
1493 _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f, _Alloc __a)
1494 : __f_(_VSTD::move(__f), _VSTD::move(__a)) {}
1495 virtual __base<_Rp(_A0, _A1)>* __clone() const;
1496 virtual void __clone(__base<_Rp(_A0, _A1)>*) const;
1497 virtual void destroy();
1498 virtual void destroy_deallocate();
1499 virtual _Rp operator()(_A0, _A1);
1500#ifndef _LIBCPP_NO_RTTI
1501 virtual const void* target(const type_info&) const;
1502 virtual const std::type_info& target_type() const;
1503#endif // _LIBCPP_NO_RTTI
1504};
1505
1506template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
1507__base<_Rp(_A0, _A1)>*
1508__func<_Fp, _Alloc, _Rp(_A0, _A1)>::__clone() const
1509{
1510 typedef allocator_traits<_Alloc> __alloc_traits;
1511 typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
1512 _Ap __a(__f_.second());
1513 typedef __allocator_destructor<_Ap> _Dp;
1514 unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1515 ::new ((void*)__hold.get()) __func(__f_.first(), _Alloc(__a));
1516 return __hold.release();
1517}
1518
1519template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
1520void
1521__func<_Fp, _Alloc, _Rp(_A0, _A1)>::__clone(__base<_Rp(_A0, _A1)>* __p) const
1522{
1523 ::new ((void*)__p) __func(__f_.first(), __f_.second());
1524}
1525
1526template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
1527void
1528__func<_Fp, _Alloc, _Rp(_A0, _A1)>::destroy()
1529{
1530 __f_.~__compressed_pair<_Fp, _Alloc>();
1531}
1532
1533template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
1534void
1535__func<_Fp, _Alloc, _Rp(_A0, _A1)>::destroy_deallocate()
1536{
1537 typedef allocator_traits<_Alloc> __alloc_traits;
1538 typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
1539 _Ap __a(__f_.second());
1540 __f_.~__compressed_pair<_Fp, _Alloc>();
1541 __a.deallocate(this, 1);
1542}
1543
1544template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
1545_Rp
1546__func<_Fp, _Alloc, _Rp(_A0, _A1)>::operator()(_A0 __a0, _A1 __a1)
1547{
1548 typedef __invoke_void_return_wrapper<_Rp> _Invoker;
1549 return _Invoker::__call(__f_.first(), __a0, __a1);
1550}
1551
1552#ifndef _LIBCPP_NO_RTTI
1553
1554template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
1555const void*
1556__func<_Fp, _Alloc, _Rp(_A0, _A1)>::target(const type_info& __ti) const
1557{
1558 if (__ti == typeid(_Fp))
1559 return &__f_.first();
1560 return (const void*)0;
1561}
1562
1563template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
1564const std::type_info&
1565__func<_Fp, _Alloc, _Rp(_A0, _A1)>::target_type() const
1566{
1567 return typeid(_Fp);
1568}
1569
1570#endif // _LIBCPP_NO_RTTI
1571
1572template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
1573class __func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>
1574 : public __base<_Rp(_A0, _A1, _A2)>
1575{
1576 __compressed_pair<_Fp, _Alloc> __f_;
1577public:
1578 _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f) : __f_(_VSTD::move(__f), __default_init_tag()) {}
1579 _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f, _Alloc __a)
1580 : __f_(_VSTD::move(__f), _VSTD::move(__a)) {}
1581 virtual __base<_Rp(_A0, _A1, _A2)>* __clone() const;
1582 virtual void __clone(__base<_Rp(_A0, _A1, _A2)>*) const;
1583 virtual void destroy();
1584 virtual void destroy_deallocate();
1585 virtual _Rp operator()(_A0, _A1, _A2);
1586#ifndef _LIBCPP_NO_RTTI
1587 virtual const void* target(const type_info&) const;
1588 virtual const std::type_info& target_type() const;
1589#endif // _LIBCPP_NO_RTTI
1590};
1591
1592template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
1593__base<_Rp(_A0, _A1, _A2)>*
1594__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::__clone() const
1595{
1596 typedef allocator_traits<_Alloc> __alloc_traits;
1597 typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
1598 _Ap __a(__f_.second());
1599 typedef __allocator_destructor<_Ap> _Dp;
1600 unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1601 ::new ((void*)__hold.get()) __func(__f_.first(), _Alloc(__a));
1602 return __hold.release();
1603}
1604
1605template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
1606void
1607__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::__clone(__base<_Rp(_A0, _A1, _A2)>* __p) const
1608{
1609 ::new ((void*)__p) __func(__f_.first(), __f_.second());
1610}
1611
1612template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
1613void
1614__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::destroy()
1615{
1616 __f_.~__compressed_pair<_Fp, _Alloc>();
1617}
1618
1619template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
1620void
1621__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::destroy_deallocate()
1622{
1623 typedef allocator_traits<_Alloc> __alloc_traits;
1624 typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
1625 _Ap __a(__f_.second());
1626 __f_.~__compressed_pair<_Fp, _Alloc>();
1627 __a.deallocate(this, 1);
1628}
1629
1630template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
1631_Rp
1632__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::operator()(_A0 __a0, _A1 __a1, _A2 __a2)
1633{
1634 typedef __invoke_void_return_wrapper<_Rp> _Invoker;
1635 return _Invoker::__call(__f_.first(), __a0, __a1, __a2);
1636}
1637
1638#ifndef _LIBCPP_NO_RTTI
1639
1640template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
1641const void*
1642__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::target(const type_info& __ti) const
1643{
1644 if (__ti == typeid(_Fp))
1645 return &__f_.first();
1646 return (const void*)0;
1647}
1648
1649template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
1650const std::type_info&
1651__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::target_type() const
1652{
1653 return typeid(_Fp);
1654}
1655
1656#endif // _LIBCPP_NO_RTTI
1657
1658} // __function
1659
1660template<class _Rp>
1661class _LIBCPP_TEMPLATE_VIS function<_Rp()>
1662{
1663 typedef __function::__base<_Rp()> __base;
1664 aligned_storage<3*sizeof(void*)>::type __buf_;
1665 __base* __f_;
1666
1667public:
1668 typedef _Rp result_type;
1669
1670 // 20.7.16.2.1, construct/copy/destroy:
1671 _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {}
1672 _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {}
1673 function(const function&);
1674 template<class _Fp>
1675 function(_Fp,
1676 typename enable_if<!is_integral<_Fp>::value>::type* = 0);
1677
1678 template<class _Alloc>
1679 _LIBCPP_INLINE_VISIBILITY
1680 function(allocator_arg_t, const _Alloc&) : __f_(0) {}
1681 template<class _Alloc>
1682 _LIBCPP_INLINE_VISIBILITY
1683 function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {}
1684 template<class _Alloc>
1685 function(allocator_arg_t, const _Alloc&, const function&);
1686 template<class _Fp, class _Alloc>
1687 function(allocator_arg_t, const _Alloc& __a, _Fp __f,
1688 typename enable_if<!is_integral<_Fp>::value>::type* = 0);
1689
1690 function& operator=(const function&);
1691 function& operator=(nullptr_t);
1692 template<class _Fp>
1693 typename enable_if
1694 <
1695 !is_integral<_Fp>::value,
1696 function&
1697 >::type
1698 operator=(_Fp);
1699
1700 ~function();
1701
1702 // 20.7.16.2.2, function modifiers:
1703 void swap(function&);
1704 template<class _Fp, class _Alloc>
1705 _LIBCPP_INLINE_VISIBILITY
1706 void assign(_Fp __f, const _Alloc& __a)
1707 {function(allocator_arg, __a, __f).swap(*this);}
1708
1709 // 20.7.16.2.3, function capacity:
1710 _LIBCPP_INLINE_VISIBILITY explicit operator bool() const {return __f_;}
1711
1712private:
1713 // deleted overloads close possible hole in the type system
1714 template<class _R2>
1715 bool operator==(const function<_R2()>&) const;// = delete;
1716 template<class _R2>
1717 bool operator!=(const function<_R2()>&) const;// = delete;
1718public:
1719 // 20.7.16.2.4, function invocation:
1720 _Rp operator()() const;
1721
1722#ifndef _LIBCPP_NO_RTTI
1723 // 20.7.16.2.5, function target access:
1724 const std::type_info& target_type() const;
1725 template <typename _Tp> _Tp* target();
1726 template <typename _Tp> const _Tp* target() const;
1727#endif // _LIBCPP_NO_RTTI
1728};
1729
1730template<class _Rp>
1731function<_Rp()>::function(const function& __f)
1732{
1733 if (__f.__f_ == 0)
1734 __f_ = 0;
1735 else if (__f.__f_ == (const __base*)&__f.__buf_)
1736 {
1737 __f_ = (__base*)&__buf_;
1738 __f.__f_->__clone(__f_);
1739 }
1740 else
1741 __f_ = __f.__f_->__clone();
1742}
1743
1744template<class _Rp>
1745template<class _Alloc>
1746function<_Rp()>::function(allocator_arg_t, const _Alloc&, const function& __f)
1747{
1748 if (__f.__f_ == 0)
1749 __f_ = 0;
1750 else if (__f.__f_ == (const __base*)&__f.__buf_)
1751 {
1752 __f_ = (__base*)&__buf_;
1753 __f.__f_->__clone(__f_);
1754 }
1755 else
1756 __f_ = __f.__f_->__clone();
1757}
1758
1759template<class _Rp>
1760template <class _Fp>
1761function<_Rp()>::function(_Fp __f,
1762 typename enable_if<!is_integral<_Fp>::value>::type*)
1763 : __f_(0)
1764{
1765 if (__function::__not_null(__f))
1766 {
1767 typedef __function::__func<_Fp, allocator<_Fp>, _Rp()> _FF;
1768 if (sizeof(_FF) <= sizeof(__buf_))
1769 {
1770 __f_ = (__base*)&__buf_;
1771 ::new ((void*)__f_) _FF(__f);
1772 }
1773 else
1774 {
1775 typedef allocator<_FF> _Ap;
1776 _Ap __a;
1777 typedef __allocator_destructor<_Ap> _Dp;
1778 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1779 ::new ((void*)__hold.get()) _FF(__f, allocator<_Fp>(__a));
1780 __f_ = __hold.release();
1781 }
1782 }
1783}
1784
1785template<class _Rp>
1786template <class _Fp, class _Alloc>
1787function<_Rp()>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f,
1788 typename enable_if<!is_integral<_Fp>::value>::type*)
1789 : __f_(0)
1790{
1791 typedef allocator_traits<_Alloc> __alloc_traits;
1792 if (__function::__not_null(__f))
1793 {
1794 typedef __function::__func<_Fp, _Alloc, _Rp()> _FF;
1795 if (sizeof(_FF) <= sizeof(__buf_))
1796 {
1797 __f_ = (__base*)&__buf_;
1798 ::new ((void*)__f_) _FF(__f, __a0);
1799 }
1800 else
1801 {
1802 typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap;
1803 _Ap __a(__a0);
1804 typedef __allocator_destructor<_Ap> _Dp;
1805 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1806 ::new ((void*)__hold.get()) _FF(__f, _Alloc(__a));
1807 __f_ = __hold.release();
1808 }
1809 }
1810}
1811
1812template<class _Rp>
1813function<_Rp()>&
1814function<_Rp()>::operator=(const function& __f)
1815{
1816 if (__f)
1817 function(__f).swap(*this);
1818 else
1819 *this = nullptr;
1820 return *this;
1821}
1822
1823template<class _Rp>
1824function<_Rp()>&
1825function<_Rp()>::operator=(nullptr_t)
1826{
1827 __base* __t = __f_;
1828 __f_ = 0;
1829 if (__t == (__base*)&__buf_)
1830 __t->destroy();
1831 else if (__t)
1832 __t->destroy_deallocate();
1833 return *this;
1834}
1835
1836template<class _Rp>
1837template <class _Fp>
1838typename enable_if
1839<
1840 !is_integral<_Fp>::value,
1841 function<_Rp()>&
1842>::type
1843function<_Rp()>::operator=(_Fp __f)
1844{
1845 function(_VSTD::move(__f)).swap(*this);
1846 return *this;
1847}
1848
1849template<class _Rp>
1850function<_Rp()>::~function()
1851{
1852 if (__f_ == (__base*)&__buf_)
1853 __f_->destroy();
1854 else if (__f_)
1855 __f_->destroy_deallocate();
1856}
1857
1858template<class _Rp>
1859void
1860function<_Rp()>::swap(function& __f)
1861{
1862 if (_VSTD::addressof(__f) == this)
1863 return;
1864 if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
1865 {
1866 typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
1867 __base* __t = (__base*)&__tempbuf;
1868 __f_->__clone(__t);
1869 __f_->destroy();
1870 __f_ = 0;
1871 __f.__f_->__clone((__base*)&__buf_);
1872 __f.__f_->destroy();
1873 __f.__f_ = 0;
1874 __f_ = (__base*)&__buf_;
1875 __t->__clone((__base*)&__f.__buf_);
1876 __t->destroy();
1877 __f.__f_ = (__base*)&__f.__buf_;
1878 }
1879 else if (__f_ == (__base*)&__buf_)
1880 {
1881 __f_->__clone((__base*)&__f.__buf_);
1882 __f_->destroy();
1883 __f_ = __f.__f_;
1884 __f.__f_ = (__base*)&__f.__buf_;
1885 }
1886 else if (__f.__f_ == (__base*)&__f.__buf_)
1887 {
1888 __f.__f_->__clone((__base*)&__buf_);
1889 __f.__f_->destroy();
1890 __f.__f_ = __f_;
1891 __f_ = (__base*)&__buf_;
1892 }
1893 else
1894 _VSTD::swap(__f_, __f.__f_);
1895}
1896
1897template<class _Rp>
1898_Rp
1899function<_Rp()>::operator()() const
1900{
1901 if (__f_ == 0)
1902 __throw_bad_function_call();
1903 return (*__f_)();
1904}
1905
1906#ifndef _LIBCPP_NO_RTTI
1907
1908template<class _Rp>
1909const std::type_info&
1910function<_Rp()>::target_type() const
1911{
1912 if (__f_ == 0)
1913 return typeid(void);
1914 return __f_->target_type();
1915}
1916
1917template<class _Rp>
1918template <typename _Tp>
1919_Tp*
1920function<_Rp()>::target()
1921{
1922 if (__f_ == 0)
1923 return (_Tp*)0;
1924 return (_Tp*) const_cast<void *>(__f_->target(typeid(_Tp)));
1925}
1926
1927template<class _Rp>
1928template <typename _Tp>
1929const _Tp*
1930function<_Rp()>::target() const
1931{
1932 if (__f_ == 0)
1933 return (const _Tp*)0;
1934 return (const _Tp*)__f_->target(typeid(_Tp));
1935}
1936
1937#endif // _LIBCPP_NO_RTTI
1938
1939template<class _Rp, class _A0>
1940class _LIBCPP_TEMPLATE_VIS function<_Rp(_A0)>
1941 : public unary_function<_A0, _Rp>
1942{
1943 typedef __function::__base<_Rp(_A0)> __base;
1944 aligned_storage<3*sizeof(void*)>::type __buf_;
1945 __base* __f_;
1946
1947public:
1948 typedef _Rp result_type;
1949
1950 // 20.7.16.2.1, construct/copy/destroy:
1951 _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {}
1952 _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {}
1953 function(const function&);
1954 template<class _Fp>
1955 function(_Fp,
1956 typename enable_if<!is_integral<_Fp>::value>::type* = 0);
1957
1958 template<class _Alloc>
1959 _LIBCPP_INLINE_VISIBILITY
1960 function(allocator_arg_t, const _Alloc&) : __f_(0) {}
1961 template<class _Alloc>
1962 _LIBCPP_INLINE_VISIBILITY
1963 function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {}
1964 template<class _Alloc>
1965 function(allocator_arg_t, const _Alloc&, const function&);
1966 template<class _Fp, class _Alloc>
1967 function(allocator_arg_t, const _Alloc& __a, _Fp __f,
1968 typename enable_if<!is_integral<_Fp>::value>::type* = 0);
1969
1970 function& operator=(const function&);
1971 function& operator=(nullptr_t);
1972 template<class _Fp>
1973 typename enable_if
1974 <
1975 !is_integral<_Fp>::value,
1976 function&
1977 >::type
1978 operator=(_Fp);
1979
1980 ~function();
1981
1982 // 20.7.16.2.2, function modifiers:
1983 void swap(function&);
1984 template<class _Fp, class _Alloc>
1985 _LIBCPP_INLINE_VISIBILITY
1986 void assign(_Fp __f, const _Alloc& __a)
1987 {function(allocator_arg, __a, __f).swap(*this);}
1988
1989 // 20.7.16.2.3, function capacity:
1990 _LIBCPP_INLINE_VISIBILITY explicit operator bool() const {return __f_;}
1991
1992private:
1993 // deleted overloads close possible hole in the type system
1994 template<class _R2, class _B0>
1995 bool operator==(const function<_R2(_B0)>&) const;// = delete;
1996 template<class _R2, class _B0>
1997 bool operator!=(const function<_R2(_B0)>&) const;// = delete;
1998public:
1999 // 20.7.16.2.4, function invocation:
2000 _Rp operator()(_A0) const;
2001
2002#ifndef _LIBCPP_NO_RTTI
2003 // 20.7.16.2.5, function target access:
2004 const std::type_info& target_type() const;
2005 template <typename _Tp> _Tp* target();
2006 template <typename _Tp> const _Tp* target() const;
2007#endif // _LIBCPP_NO_RTTI
2008};
2009
2010template<class _Rp, class _A0>
2011function<_Rp(_A0)>::function(const function& __f)
2012{
2013 if (__f.__f_ == 0)
2014 __f_ = 0;
2015 else if (__f.__f_ == (const __base*)&__f.__buf_)
2016 {
2017 __f_ = (__base*)&__buf_;
2018 __f.__f_->__clone(__f_);
2019 }
2020 else
2021 __f_ = __f.__f_->__clone();
2022}
2023
2024template<class _Rp, class _A0>
2025template<class _Alloc>
2026function<_Rp(_A0)>::function(allocator_arg_t, const _Alloc&, const function& __f)
2027{
2028 if (__f.__f_ == 0)
2029 __f_ = 0;
2030 else if (__f.__f_ == (const __base*)&__f.__buf_)
2031 {
2032 __f_ = (__base*)&__buf_;
2033 __f.__f_->__clone(__f_);
2034 }
2035 else
2036 __f_ = __f.__f_->__clone();
2037}
2038
2039template<class _Rp, class _A0>
2040template <class _Fp>
2041function<_Rp(_A0)>::function(_Fp __f,
2042 typename enable_if<!is_integral<_Fp>::value>::type*)
2043 : __f_(0)
2044{
2045 if (__function::__not_null(__f))
2046 {
2047 typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_A0)> _FF;
2048 if (sizeof(_FF) <= sizeof(__buf_))
2049 {
2050 __f_ = (__base*)&__buf_;
2051 ::new ((void*)__f_) _FF(__f);
2052 }
2053 else
2054 {
2055 typedef allocator<_FF> _Ap;
2056 _Ap __a;
2057 typedef __allocator_destructor<_Ap> _Dp;
2058 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
2059 ::new ((void*)__hold.get()) _FF(__f, allocator<_Fp>(__a));
2060 __f_ = __hold.release();
2061 }
2062 }
2063}
2064
2065template<class _Rp, class _A0>
2066template <class _Fp, class _Alloc>
2067function<_Rp(_A0)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f,
2068 typename enable_if<!is_integral<_Fp>::value>::type*)
2069 : __f_(0)
2070{
2071 typedef allocator_traits<_Alloc> __alloc_traits;
2072 if (__function::__not_null(__f))
2073 {
2074 typedef __function::__func<_Fp, _Alloc, _Rp(_A0)> _FF;
2075 if (sizeof(_FF) <= sizeof(__buf_))
2076 {
2077 __f_ = (__base*)&__buf_;
2078 ::new ((void*)__f_) _FF(__f, __a0);
2079 }
2080 else
2081 {
2082 typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap;
2083 _Ap __a(__a0);
2084 typedef __allocator_destructor<_Ap> _Dp;
2085 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
2086 ::new ((void*)__hold.get()) _FF(__f, _Alloc(__a));
2087 __f_ = __hold.release();
2088 }
2089 }
2090}
2091
2092template<class _Rp, class _A0>
2093function<_Rp(_A0)>&
2094function<_Rp(_A0)>::operator=(const function& __f)
2095{
2096 if (__f)
2097 function(__f).swap(*this);
2098 else
2099 *this = nullptr;
2100 return *this;
2101}
2102
2103template<class _Rp, class _A0>
2104function<_Rp(_A0)>&
2105function<_Rp(_A0)>::operator=(nullptr_t)
2106{
2107 __base* __t = __f_;
2108 __f_ = 0;
2109 if (__t == (__base*)&__buf_)
2110 __t->destroy();
2111 else if (__t)
2112 __t->destroy_deallocate();
2113 return *this;
2114}
2115
2116template<class _Rp, class _A0>
2117template <class _Fp>
2118typename enable_if
2119<
2120 !is_integral<_Fp>::value,
2121 function<_Rp(_A0)>&
2122>::type
2123function<_Rp(_A0)>::operator=(_Fp __f)
2124{
2125 function(_VSTD::move(__f)).swap(*this);
2126 return *this;
2127}
2128
2129template<class _Rp, class _A0>
2130function<_Rp(_A0)>::~function()
2131{
2132 if (__f_ == (__base*)&__buf_)
2133 __f_->destroy();
2134 else if (__f_)
2135 __f_->destroy_deallocate();
2136}
2137
2138template<class _Rp, class _A0>
2139void
2140function<_Rp(_A0)>::swap(function& __f)
2141{
2142 if (_VSTD::addressof(__f) == this)
2143 return;
2144 if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
2145 {
2146 typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
2147 __base* __t = (__base*)&__tempbuf;
2148 __f_->__clone(__t);
2149 __f_->destroy();
2150 __f_ = 0;
2151 __f.__f_->__clone((__base*)&__buf_);
2152 __f.__f_->destroy();
2153 __f.__f_ = 0;
2154 __f_ = (__base*)&__buf_;
2155 __t->__clone((__base*)&__f.__buf_);
2156 __t->destroy();
2157 __f.__f_ = (__base*)&__f.__buf_;
2158 }
2159 else if (__f_ == (__base*)&__buf_)
2160 {
2161 __f_->__clone((__base*)&__f.__buf_);
2162 __f_->destroy();
2163 __f_ = __f.__f_;
2164 __f.__f_ = (__base*)&__f.__buf_;
2165 }
2166 else if (__f.__f_ == (__base*)&__f.__buf_)
2167 {
2168 __f.__f_->__clone((__base*)&__buf_);
2169 __f.__f_->destroy();
2170 __f.__f_ = __f_;
2171 __f_ = (__base*)&__buf_;
2172 }
2173 else
2174 _VSTD::swap(__f_, __f.__f_);
2175}
2176
2177template<class _Rp, class _A0>
2178_Rp
2179function<_Rp(_A0)>::operator()(_A0 __a0) const
2180{
2181 if (__f_ == 0)
2182 __throw_bad_function_call();
2183 return (*__f_)(__a0);
2184}
2185
2186#ifndef _LIBCPP_NO_RTTI
2187
2188template<class _Rp, class _A0>
2189const std::type_info&
2190function<_Rp(_A0)>::target_type() const
2191{
2192 if (__f_ == 0)
2193 return typeid(void);
2194 return __f_->target_type();
2195}
2196
2197template<class _Rp, class _A0>
2198template <typename _Tp>
2199_Tp*
2200function<_Rp(_A0)>::target()
2201{
2202 if (__f_ == 0)
2203 return (_Tp*)0;
2204 return (_Tp*) const_cast<void *>(__f_->target(typeid(_Tp)));
2205}
2206
2207template<class _Rp, class _A0>
2208template <typename _Tp>
2209const _Tp*
2210function<_Rp(_A0)>::target() const
2211{
2212 if (__f_ == 0)
2213 return (const _Tp*)0;
2214 return (const _Tp*)__f_->target(typeid(_Tp));
2215}
2216
2217#endif // _LIBCPP_NO_RTTI
2218
2219template<class _Rp, class _A0, class _A1>
2220class _LIBCPP_TEMPLATE_VIS function<_Rp(_A0, _A1)>
2221 : public binary_function<_A0, _A1, _Rp>
2222{
2223 typedef __function::__base<_Rp(_A0, _A1)> __base;
2224 aligned_storage<3*sizeof(void*)>::type __buf_;
2225 __base* __f_;
2226
2227public:
2228 typedef _Rp result_type;
2229
2230 // 20.7.16.2.1, construct/copy/destroy:
2231 _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {}
2232 _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {}
2233 function(const function&);
2234 template<class _Fp>
2235 function(_Fp,
2236 typename enable_if<!is_integral<_Fp>::value>::type* = 0);
2237
2238 template<class _Alloc>
2239 _LIBCPP_INLINE_VISIBILITY
2240 function(allocator_arg_t, const _Alloc&) : __f_(0) {}
2241 template<class _Alloc>
2242 _LIBCPP_INLINE_VISIBILITY
2243 function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {}
2244 template<class _Alloc>
2245 function(allocator_arg_t, const _Alloc&, const function&);
2246 template<class _Fp, class _Alloc>
2247 function(allocator_arg_t, const _Alloc& __a, _Fp __f,
2248 typename enable_if<!is_integral<_Fp>::value>::type* = 0);
2249
2250 function& operator=(const function&);
2251 function& operator=(nullptr_t);
2252 template<class _Fp>
2253 typename enable_if
2254 <
2255 !is_integral<_Fp>::value,
2256 function&
2257 >::type
2258 operator=(_Fp);
2259
2260 ~function();
2261
2262 // 20.7.16.2.2, function modifiers:
2263 void swap(function&);
2264 template<class _Fp, class _Alloc>
2265 _LIBCPP_INLINE_VISIBILITY
2266 void assign(_Fp __f, const _Alloc& __a)
2267 {function(allocator_arg, __a, __f).swap(*this);}
2268
2269 // 20.7.16.2.3, function capacity:
2270 _LIBCPP_INLINE_VISIBILITY explicit operator bool() const {return __f_;}
2271
2272private:
2273 // deleted overloads close possible hole in the type system
2274 template<class _R2, class _B0, class _B1>
2275 bool operator==(const function<_R2(_B0, _B1)>&) const;// = delete;
2276 template<class _R2, class _B0, class _B1>
2277 bool operator!=(const function<_R2(_B0, _B1)>&) const;// = delete;
2278public:
2279 // 20.7.16.2.4, function invocation:
2280 _Rp operator()(_A0, _A1) const;
2281
2282#ifndef _LIBCPP_NO_RTTI
2283 // 20.7.16.2.5, function target access:
2284 const std::type_info& target_type() const;
2285 template <typename _Tp> _Tp* target();
2286 template <typename _Tp> const _Tp* target() const;
2287#endif // _LIBCPP_NO_RTTI
2288};
2289
2290template<class _Rp, class _A0, class _A1>
2291function<_Rp(_A0, _A1)>::function(const function& __f)
2292{
2293 if (__f.__f_ == 0)
2294 __f_ = 0;
2295 else if (__f.__f_ == (const __base*)&__f.__buf_)
2296 {
2297 __f_ = (__base*)&__buf_;
2298 __f.__f_->__clone(__f_);
2299 }
2300 else
2301 __f_ = __f.__f_->__clone();
2302}
2303
2304template<class _Rp, class _A0, class _A1>
2305template<class _Alloc>
2306function<_Rp(_A0, _A1)>::function(allocator_arg_t, const _Alloc&, const function& __f)
2307{
2308 if (__f.__f_ == 0)
2309 __f_ = 0;
2310 else if (__f.__f_ == (const __base*)&__f.__buf_)
2311 {
2312 __f_ = (__base*)&__buf_;
2313 __f.__f_->__clone(__f_);
2314 }
2315 else
2316 __f_ = __f.__f_->__clone();
2317}
2318
2319template<class _Rp, class _A0, class _A1>
2320template <class _Fp>
2321function<_Rp(_A0, _A1)>::function(_Fp __f,
2322 typename enable_if<!is_integral<_Fp>::value>::type*)
2323 : __f_(0)
2324{
2325 if (__function::__not_null(__f))
2326 {
2327 typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_A0, _A1)> _FF;
2328 if (sizeof(_FF) <= sizeof(__buf_))
2329 {
2330 __f_ = (__base*)&__buf_;
2331 ::new ((void*)__f_) _FF(__f);
2332 }
2333 else
2334 {
2335 typedef allocator<_FF> _Ap;
2336 _Ap __a;
2337 typedef __allocator_destructor<_Ap> _Dp;
2338 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
2339 ::new ((void*)__hold.get()) _FF(__f, allocator<_Fp>(__a));
2340 __f_ = __hold.release();
2341 }
2342 }
2343}
2344
2345template<class _Rp, class _A0, class _A1>
2346template <class _Fp, class _Alloc>
2347function<_Rp(_A0, _A1)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f,
2348 typename enable_if<!is_integral<_Fp>::value>::type*)
2349 : __f_(0)
2350{
2351 typedef allocator_traits<_Alloc> __alloc_traits;
2352 if (__function::__not_null(__f))
2353 {
2354 typedef __function::__func<_Fp, _Alloc, _Rp(_A0, _A1)> _FF;
2355 if (sizeof(_FF) <= sizeof(__buf_))
2356 {
2357 __f_ = (__base*)&__buf_;
2358 ::new ((void*)__f_) _FF(__f, __a0);
2359 }
2360 else
2361 {
2362 typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap;
2363 _Ap __a(__a0);
2364 typedef __allocator_destructor<_Ap> _Dp;
2365 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
2366 ::new ((void*)__hold.get()) _FF(__f, _Alloc(__a));
2367 __f_ = __hold.release();
2368 }
2369 }
2370}
2371
2372template<class _Rp, class _A0, class _A1>
2373function<_Rp(_A0, _A1)>&
2374function<_Rp(_A0, _A1)>::operator=(const function& __f)
2375{
2376 if (__f)
2377 function(__f).swap(*this);
2378 else
2379 *this = nullptr;
2380 return *this;
2381}
2382
2383template<class _Rp, class _A0, class _A1>
2384function<_Rp(_A0, _A1)>&
2385function<_Rp(_A0, _A1)>::operator=(nullptr_t)
2386{
2387 __base* __t = __f_;
2388 __f_ = 0;
2389 if (__t == (__base*)&__buf_)
2390 __t->destroy();
2391 else if (__t)
2392 __t->destroy_deallocate();
2393 return *this;
2394}
2395
2396template<class _Rp, class _A0, class _A1>
2397template <class _Fp>
2398typename enable_if
2399<
2400 !is_integral<_Fp>::value,
2401 function<_Rp(_A0, _A1)>&
2402>::type
2403function<_Rp(_A0, _A1)>::operator=(_Fp __f)
2404{
2405 function(_VSTD::move(__f)).swap(*this);
2406 return *this;
2407}
2408
2409template<class _Rp, class _A0, class _A1>
2410function<_Rp(_A0, _A1)>::~function()
2411{
2412 if (__f_ == (__base*)&__buf_)
2413 __f_->destroy();
2414 else if (__f_)
2415 __f_->destroy_deallocate();
2416}
2417
2418template<class _Rp, class _A0, class _A1>
2419void
2420function<_Rp(_A0, _A1)>::swap(function& __f)
2421{
2422 if (_VSTD::addressof(__f) == this)
2423 return;
2424 if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
2425 {
2426 typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
2427 __base* __t = (__base*)&__tempbuf;
2428 __f_->__clone(__t);
2429 __f_->destroy();
2430 __f_ = 0;
2431 __f.__f_->__clone((__base*)&__buf_);
2432 __f.__f_->destroy();
2433 __f.__f_ = 0;
2434 __f_ = (__base*)&__buf_;
2435 __t->__clone((__base*)&__f.__buf_);
2436 __t->destroy();
2437 __f.__f_ = (__base*)&__f.__buf_;
2438 }
2439 else if (__f_ == (__base*)&__buf_)
2440 {
2441 __f_->__clone((__base*)&__f.__buf_);
2442 __f_->destroy();
2443 __f_ = __f.__f_;
2444 __f.__f_ = (__base*)&__f.__buf_;
2445 }
2446 else if (__f.__f_ == (__base*)&__f.__buf_)
2447 {
2448 __f.__f_->__clone((__base*)&__buf_);
2449 __f.__f_->destroy();
2450 __f.__f_ = __f_;
2451 __f_ = (__base*)&__buf_;
2452 }
2453 else
2454 _VSTD::swap(__f_, __f.__f_);
2455}
2456
2457template<class _Rp, class _A0, class _A1>
2458_Rp
2459function<_Rp(_A0, _A1)>::operator()(_A0 __a0, _A1 __a1) const
2460{
2461 if (__f_ == 0)
2462 __throw_bad_function_call();
2463 return (*__f_)(__a0, __a1);
2464}
2465
2466#ifndef _LIBCPP_NO_RTTI
2467
2468template<class _Rp, class _A0, class _A1>
2469const std::type_info&
2470function<_Rp(_A0, _A1)>::target_type() const
2471{
2472 if (__f_ == 0)
2473 return typeid(void);
2474 return __f_->target_type();
2475}
2476
2477template<class _Rp, class _A0, class _A1>
2478template <typename _Tp>
2479_Tp*
2480function<_Rp(_A0, _A1)>::target()
2481{
2482 if (__f_ == 0)
2483 return (_Tp*)0;
2484 return (_Tp*) const_cast<void *>(__f_->target(typeid(_Tp)));
2485}
2486
2487template<class _Rp, class _A0, class _A1>
2488template <typename _Tp>
2489const _Tp*
2490function<_Rp(_A0, _A1)>::target() const
2491{
2492 if (__f_ == 0)
2493 return (const _Tp*)0;
2494 return (const _Tp*)__f_->target(typeid(_Tp));
2495}
2496
2497#endif // _LIBCPP_NO_RTTI
2498
2499template<class _Rp, class _A0, class _A1, class _A2>
2500class _LIBCPP_TEMPLATE_VIS function<_Rp(_A0, _A1, _A2)>
2501{
2502 typedef __function::__base<_Rp(_A0, _A1, _A2)> __base;
2503 aligned_storage<3*sizeof(void*)>::type __buf_;
2504 __base* __f_;
2505
2506public:
2507 typedef _Rp result_type;
2508
2509 // 20.7.16.2.1, construct/copy/destroy:
2510 _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {}
2511 _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {}
2512 function(const function&);
2513 template<class _Fp>
2514 function(_Fp,
2515 typename enable_if<!is_integral<_Fp>::value>::type* = 0);
2516
2517 template<class _Alloc>
2518 _LIBCPP_INLINE_VISIBILITY
2519 function(allocator_arg_t, const _Alloc&) : __f_(0) {}
2520 template<class _Alloc>
2521 _LIBCPP_INLINE_VISIBILITY
2522 function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {}
2523 template<class _Alloc>
2524 function(allocator_arg_t, const _Alloc&, const function&);
2525 template<class _Fp, class _Alloc>
2526 function(allocator_arg_t, const _Alloc& __a, _Fp __f,
2527 typename enable_if<!is_integral<_Fp>::value>::type* = 0);
2528
2529 function& operator=(const function&);
2530 function& operator=(nullptr_t);
2531 template<class _Fp>
2532 typename enable_if
2533 <
2534 !is_integral<_Fp>::value,
2535 function&
2536 >::type
2537 operator=(_Fp);
2538
2539 ~function();
2540
2541 // 20.7.16.2.2, function modifiers:
2542 void swap(function&);
2543 template<class _Fp, class _Alloc>
2544 _LIBCPP_INLINE_VISIBILITY
2545 void assign(_Fp __f, const _Alloc& __a)
2546 {function(allocator_arg, __a, __f).swap(*this);}
2547
2548 // 20.7.16.2.3, function capacity:
2549 _LIBCPP_INLINE_VISIBILITY explicit operator bool() const {return __f_;}
2550
2551private:
2552 // deleted overloads close possible hole in the type system
2553 template<class _R2, class _B0, class _B1, class _B2>
2554 bool operator==(const function<_R2(_B0, _B1, _B2)>&) const;// = delete;
2555 template<class _R2, class _B0, class _B1, class _B2>
2556 bool operator!=(const function<_R2(_B0, _B1, _B2)>&) const;// = delete;
2557public:
2558 // 20.7.16.2.4, function invocation:
2559 _Rp operator()(_A0, _A1, _A2) const;
2560
2561#ifndef _LIBCPP_NO_RTTI
2562 // 20.7.16.2.5, function target access:
2563 const std::type_info& target_type() const;
2564 template <typename _Tp> _Tp* target();
2565 template <typename _Tp> const _Tp* target() const;
2566#endif // _LIBCPP_NO_RTTI
2567};
2568
2569template<class _Rp, class _A0, class _A1, class _A2>
2570function<_Rp(_A0, _A1, _A2)>::function(const function& __f)
2571{
2572 if (__f.__f_ == 0)
2573 __f_ = 0;
2574 else if (__f.__f_ == (const __base*)&__f.__buf_)
2575 {
2576 __f_ = (__base*)&__buf_;
2577 __f.__f_->__clone(__f_);
2578 }
2579 else
2580 __f_ = __f.__f_->__clone();
2581}
2582
2583template<class _Rp, class _A0, class _A1, class _A2>
2584template<class _Alloc>
2585function<_Rp(_A0, _A1, _A2)>::function(allocator_arg_t, const _Alloc&,
2586 const function& __f)
2587{
2588 if (__f.__f_ == 0)
2589 __f_ = 0;
2590 else if (__f.__f_ == (const __base*)&__f.__buf_)
2591 {
2592 __f_ = (__base*)&__buf_;
2593 __f.__f_->__clone(__f_);
2594 }
2595 else
2596 __f_ = __f.__f_->__clone();
2597}
2598
2599template<class _Rp, class _A0, class _A1, class _A2>
2600template <class _Fp>
2601function<_Rp(_A0, _A1, _A2)>::function(_Fp __f,
2602 typename enable_if<!is_integral<_Fp>::value>::type*)
2603 : __f_(0)
2604{
2605 if (__function::__not_null(__f))
2606 {
2607 typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_A0, _A1, _A2)> _FF;
2608 if (sizeof(_FF) <= sizeof(__buf_))
2609 {
2610 __f_ = (__base*)&__buf_;
2611 ::new ((void*)__f_) _FF(__f);
2612 }
2613 else
2614 {
2615 typedef allocator<_FF> _Ap;
2616 _Ap __a;
2617 typedef __allocator_destructor<_Ap> _Dp;
2618 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
2619 ::new ((void*)__hold.get()) _FF(__f, allocator<_Fp>(__a));
2620 __f_ = __hold.release();
2621 }
2622 }
2623}
2624
2625template<class _Rp, class _A0, class _A1, class _A2>
2626template <class _Fp, class _Alloc>
2627function<_Rp(_A0, _A1, _A2)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f,
2628 typename enable_if<!is_integral<_Fp>::value>::type*)
2629 : __f_(0)
2630{
2631 typedef allocator_traits<_Alloc> __alloc_traits;
2632 if (__function::__not_null(__f))
2633 {
2634 typedef __function::__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)> _FF;
2635 if (sizeof(_FF) <= sizeof(__buf_))
2636 {
2637 __f_ = (__base*)&__buf_;
2638 ::new ((void*)__f_) _FF(__f, __a0);
2639 }
2640 else
2641 {
2642 typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap;
2643 _Ap __a(__a0);
2644 typedef __allocator_destructor<_Ap> _Dp;
2645 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
2646 ::new ((void*)__hold.get()) _FF(__f, _Alloc(__a));
2647 __f_ = __hold.release();
2648 }
2649 }
2650}
2651
2652template<class _Rp, class _A0, class _A1, class _A2>
2653function<_Rp(_A0, _A1, _A2)>&
2654function<_Rp(_A0, _A1, _A2)>::operator=(const function& __f)
2655{
2656 if (__f)
2657 function(__f).swap(*this);
2658 else
2659 *this = nullptr;
2660 return *this;
2661}
2662
2663template<class _Rp, class _A0, class _A1, class _A2>
2664function<_Rp(_A0, _A1, _A2)>&
2665function<_Rp(_A0, _A1, _A2)>::operator=(nullptr_t)
2666{
2667 __base* __t = __f_;
2668 __f_ = 0;
2669 if (__t == (__base*)&__buf_)
2670 __t->destroy();
2671 else if (__t)
2672 __t->destroy_deallocate();
2673 return *this;
2674}
2675
2676template<class _Rp, class _A0, class _A1, class _A2>
2677template <class _Fp>
2678typename enable_if
2679<
2680 !is_integral<_Fp>::value,
2681 function<_Rp(_A0, _A1, _A2)>&
2682>::type
2683function<_Rp(_A0, _A1, _A2)>::operator=(_Fp __f)
2684{
2685 function(_VSTD::move(__f)).swap(*this);
2686 return *this;
2687}
2688
2689template<class _Rp, class _A0, class _A1, class _A2>
2690function<_Rp(_A0, _A1, _A2)>::~function()
2691{
2692 if (__f_ == (__base*)&__buf_)
2693 __f_->destroy();
2694 else if (__f_)
2695 __f_->destroy_deallocate();
2696}
2697
2698template<class _Rp, class _A0, class _A1, class _A2>
2699void
2700function<_Rp(_A0, _A1, _A2)>::swap(function& __f)
2701{
2702 if (_VSTD::addressof(__f) == this)
2703 return;
2704 if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
2705 {
2706 typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
2707 __base* __t = (__base*)&__tempbuf;
2708 __f_->__clone(__t);
2709 __f_->destroy();
2710 __f_ = 0;
2711 __f.__f_->__clone((__base*)&__buf_);
2712 __f.__f_->destroy();
2713 __f.__f_ = 0;
2714 __f_ = (__base*)&__buf_;
2715 __t->__clone((__base*)&__f.__buf_);
2716 __t->destroy();
2717 __f.__f_ = (__base*)&__f.__buf_;
2718 }
2719 else if (__f_ == (__base*)&__buf_)
2720 {
2721 __f_->__clone((__base*)&__f.__buf_);
2722 __f_->destroy();
2723 __f_ = __f.__f_;
2724 __f.__f_ = (__base*)&__f.__buf_;
2725 }
2726 else if (__f.__f_ == (__base*)&__f.__buf_)
2727 {
2728 __f.__f_->__clone((__base*)&__buf_);
2729 __f.__f_->destroy();
2730 __f.__f_ = __f_;
2731 __f_ = (__base*)&__buf_;
2732 }
2733 else
2734 _VSTD::swap(__f_, __f.__f_);
2735}
2736
2737template<class _Rp, class _A0, class _A1, class _A2>
2738_Rp
2739function<_Rp(_A0, _A1, _A2)>::operator()(_A0 __a0, _A1 __a1, _A2 __a2) const
2740{
2741 if (__f_ == 0)
2742 __throw_bad_function_call();
2743 return (*__f_)(__a0, __a1, __a2);
2744}
2745
2746#ifndef _LIBCPP_NO_RTTI
2747
2748template<class _Rp, class _A0, class _A1, class _A2>
2749const std::type_info&
2750function<_Rp(_A0, _A1, _A2)>::target_type() const
2751{
2752 if (__f_ == 0)
2753 return typeid(void);
2754 return __f_->target_type();
2755}
2756
2757template<class _Rp, class _A0, class _A1, class _A2>
2758template <typename _Tp>
2759_Tp*
2760function<_Rp(_A0, _A1, _A2)>::target()
2761{
2762 if (__f_ == 0)
2763 return (_Tp*)0;
2764 return (_Tp*) const_cast<void *>(__f_->target(typeid(_Tp)));
2765}
2766
2767template<class _Rp, class _A0, class _A1, class _A2>
2768template <typename _Tp>
2769const _Tp*
2770function<_Rp(_A0, _A1, _A2)>::target() const
2771{
2772 if (__f_ == 0)
2773 return (const _Tp*)0;
2774 return (const _Tp*)__f_->target(typeid(_Tp));
2775}
2776
2777#endif // _LIBCPP_NO_RTTI
2778
2779template <class _Fp>
2780inline _LIBCPP_INLINE_VISIBILITY
2781bool
2782operator==(const function<_Fp>& __f, nullptr_t) {return !__f;}
2783
2784template <class _Fp>
2785inline _LIBCPP_INLINE_VISIBILITY
2786bool
2787operator==(nullptr_t, const function<_Fp>& __f) {return !__f;}
2788
2789template <class _Fp>
2790inline _LIBCPP_INLINE_VISIBILITY
2791bool
2792operator!=(const function<_Fp>& __f, nullptr_t) {return (bool)__f;}
2793
2794template <class _Fp>
2795inline _LIBCPP_INLINE_VISIBILITY
2796bool
2797operator!=(nullptr_t, const function<_Fp>& __f) {return (bool)__f;}
2798
2799template <class _Fp>
2800inline _LIBCPP_INLINE_VISIBILITY
2801void
2802swap(function<_Fp>& __x, function<_Fp>& __y)
2803{return __x.swap(__y);}
2804
2805#endif
2806
2807_LIBCPP_END_NAMESPACE_STD
2808
2809#endif // _LIBCPP___FUNCTIONAL_FUNCTION_H
lib/libcxx/include/__functional/hash.h created+873
......@@ -0,0 +1,873 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___FUNCTIONAL_HASH_H
10#define _LIBCPP___FUNCTIONAL_HASH_H
11
12#include <__config>
13#include <__functional/unary_function.h>
14#include <__tuple>
15#include <__utility/forward.h>
16#include <__utility/move.h>
17#include <__utility/pair.h>
18#include <__utility/swap.h>
19#include <cstdint>
20#include <cstring>
21#include <cstddef>
22#include <limits>
23#include <type_traits>
24
25#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
26#pragma GCC system_header
27#endif
28
29_LIBCPP_PUSH_MACROS
30#include <__undef_macros>
31
32_LIBCPP_BEGIN_NAMESPACE_STD
33
34template <class _Size>
35inline _LIBCPP_INLINE_VISIBILITY
36_Size
37__loadword(const void* __p)
38{
39 _Size __r;
40 _VSTD::memcpy(&__r, __p, sizeof(__r));
41 return __r;
42}
43
44// We use murmur2 when size_t is 32 bits, and cityhash64 when size_t
45// is 64 bits. This is because cityhash64 uses 64bit x 64bit
46// multiplication, which can be very slow on 32-bit systems.
47template <class _Size, size_t = sizeof(_Size)*__CHAR_BIT__>
48struct __murmur2_or_cityhash;
49
50template <class _Size>
51struct __murmur2_or_cityhash<_Size, 32>
52{
53 inline _Size operator()(const void* __key, _Size __len)
54 _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK;
55};
56
57// murmur2
58template <class _Size>
59_Size
60__murmur2_or_cityhash<_Size, 32>::operator()(const void* __key, _Size __len)
61{
62 const _Size __m = 0x5bd1e995;
63 const _Size __r = 24;
64 _Size __h = __len;
65 const unsigned char* __data = static_cast<const unsigned char*>(__key);
66 for (; __len >= 4; __data += 4, __len -= 4)
67 {
68 _Size __k = __loadword<_Size>(__data);
69 __k *= __m;
70 __k ^= __k >> __r;
71 __k *= __m;
72 __h *= __m;
73 __h ^= __k;
74 }
75 switch (__len)
76 {
77 case 3:
78 __h ^= static_cast<_Size>(__data[2] << 16);
79 _LIBCPP_FALLTHROUGH();
80 case 2:
81 __h ^= static_cast<_Size>(__data[1] << 8);
82 _LIBCPP_FALLTHROUGH();
83 case 1:
84 __h ^= __data[0];
85 __h *= __m;
86 }
87 __h ^= __h >> 13;
88 __h *= __m;
89 __h ^= __h >> 15;
90 return __h;
91}
92
93template <class _Size>
94struct __murmur2_or_cityhash<_Size, 64>
95{
96 inline _Size operator()(const void* __key, _Size __len) _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK;
97
98 private:
99 // Some primes between 2^63 and 2^64.
100 static const _Size __k0 = 0xc3a5c85c97cb3127ULL;
101 static const _Size __k1 = 0xb492b66fbe98f273ULL;
102 static const _Size __k2 = 0x9ae16a3b2f90404fULL;
103 static const _Size __k3 = 0xc949d7c7509e6557ULL;
104
105 static _Size __rotate(_Size __val, int __shift) {
106 return __shift == 0 ? __val : ((__val >> __shift) | (__val << (64 - __shift)));
107 }
108
109 static _Size __rotate_by_at_least_1(_Size __val, int __shift) {
110 return (__val >> __shift) | (__val << (64 - __shift));
111 }
112
113 static _Size __shift_mix(_Size __val) {
114 return __val ^ (__val >> 47);
115 }
116
117 static _Size __hash_len_16(_Size __u, _Size __v)
118 _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
119 {
120 const _Size __mul = 0x9ddfea08eb382d69ULL;
121 _Size __a = (__u ^ __v) * __mul;
122 __a ^= (__a >> 47);
123 _Size __b = (__v ^ __a) * __mul;
124 __b ^= (__b >> 47);
125 __b *= __mul;
126 return __b;
127 }
128
129 static _Size __hash_len_0_to_16(const char* __s, _Size __len)
130 _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
131 {
132 if (__len > 8) {
133 const _Size __a = __loadword<_Size>(__s);
134 const _Size __b = __loadword<_Size>(__s + __len - 8);
135 return __hash_len_16(__a, __rotate_by_at_least_1(__b + __len, __len)) ^ __b;
136 }
137 if (__len >= 4) {
138 const uint32_t __a = __loadword<uint32_t>(__s);
139 const uint32_t __b = __loadword<uint32_t>(__s + __len - 4);
140 return __hash_len_16(__len + (__a << 3), __b);
141 }
142 if (__len > 0) {
143 const unsigned char __a = static_cast<unsigned char>(__s[0]);
144 const unsigned char __b = static_cast<unsigned char>(__s[__len >> 1]);
145 const unsigned char __c = static_cast<unsigned char>(__s[__len - 1]);
146 const uint32_t __y = static_cast<uint32_t>(__a) +
147 (static_cast<uint32_t>(__b) << 8);
148 const uint32_t __z = __len + (static_cast<uint32_t>(__c) << 2);
149 return __shift_mix(__y * __k2 ^ __z * __k3) * __k2;
150 }
151 return __k2;
152 }
153
154 static _Size __hash_len_17_to_32(const char *__s, _Size __len)
155 _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
156 {
157 const _Size __a = __loadword<_Size>(__s) * __k1;
158 const _Size __b = __loadword<_Size>(__s + 8);
159 const _Size __c = __loadword<_Size>(__s + __len - 8) * __k2;
160 const _Size __d = __loadword<_Size>(__s + __len - 16) * __k0;
161 return __hash_len_16(__rotate(__a - __b, 43) + __rotate(__c, 30) + __d,
162 __a + __rotate(__b ^ __k3, 20) - __c + __len);
163 }
164
165 // Return a 16-byte hash for 48 bytes. Quick and dirty.
166 // Callers do best to use "random-looking" values for a and b.
167 static pair<_Size, _Size> __weak_hash_len_32_with_seeds(
168 _Size __w, _Size __x, _Size __y, _Size __z, _Size __a, _Size __b)
169 _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
170 {
171 __a += __w;
172 __b = __rotate(__b + __a + __z, 21);
173 const _Size __c = __a;
174 __a += __x;
175 __a += __y;
176 __b += __rotate(__a, 44);
177 return pair<_Size, _Size>(__a + __z, __b + __c);
178 }
179
180 // Return a 16-byte hash for s[0] ... s[31], a, and b. Quick and dirty.
181 static pair<_Size, _Size> __weak_hash_len_32_with_seeds(
182 const char* __s, _Size __a, _Size __b)
183 _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
184 {
185 return __weak_hash_len_32_with_seeds(__loadword<_Size>(__s),
186 __loadword<_Size>(__s + 8),
187 __loadword<_Size>(__s + 16),
188 __loadword<_Size>(__s + 24),
189 __a,
190 __b);
191 }
192
193 // Return an 8-byte hash for 33 to 64 bytes.
194 static _Size __hash_len_33_to_64(const char *__s, size_t __len)
195 _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
196 {
197 _Size __z = __loadword<_Size>(__s + 24);
198 _Size __a = __loadword<_Size>(__s) +
199 (__len + __loadword<_Size>(__s + __len - 16)) * __k0;
200 _Size __b = __rotate(__a + __z, 52);
201 _Size __c = __rotate(__a, 37);
202 __a += __loadword<_Size>(__s + 8);
203 __c += __rotate(__a, 7);
204 __a += __loadword<_Size>(__s + 16);
205 _Size __vf = __a + __z;
206 _Size __vs = __b + __rotate(__a, 31) + __c;
207 __a = __loadword<_Size>(__s + 16) + __loadword<_Size>(__s + __len - 32);
208 __z += __loadword<_Size>(__s + __len - 8);
209 __b = __rotate(__a + __z, 52);
210 __c = __rotate(__a, 37);
211 __a += __loadword<_Size>(__s + __len - 24);
212 __c += __rotate(__a, 7);
213 __a += __loadword<_Size>(__s + __len - 16);
214 _Size __wf = __a + __z;
215 _Size __ws = __b + __rotate(__a, 31) + __c;
216 _Size __r = __shift_mix((__vf + __ws) * __k2 + (__wf + __vs) * __k0);
217 return __shift_mix(__r * __k0 + __vs) * __k2;
218 }
219};
220
221// cityhash64
222template <class _Size>
223_Size
224__murmur2_or_cityhash<_Size, 64>::operator()(const void* __key, _Size __len)
225{
226 const char* __s = static_cast<const char*>(__key);
227 if (__len <= 32) {
228 if (__len <= 16) {
229 return __hash_len_0_to_16(__s, __len);
230 } else {
231 return __hash_len_17_to_32(__s, __len);
232 }
233 } else if (__len <= 64) {
234 return __hash_len_33_to_64(__s, __len);
235 }
236
237 // For strings over 64 bytes we hash the end first, and then as we
238 // loop we keep 56 bytes of state: v, w, x, y, and z.
239 _Size __x = __loadword<_Size>(__s + __len - 40);
240 _Size __y = __loadword<_Size>(__s + __len - 16) +
241 __loadword<_Size>(__s + __len - 56);
242 _Size __z = __hash_len_16(__loadword<_Size>(__s + __len - 48) + __len,
243 __loadword<_Size>(__s + __len - 24));
244 pair<_Size, _Size> __v = __weak_hash_len_32_with_seeds(__s + __len - 64, __len, __z);
245 pair<_Size, _Size> __w = __weak_hash_len_32_with_seeds(__s + __len - 32, __y + __k1, __x);
246 __x = __x * __k1 + __loadword<_Size>(__s);
247
248 // Decrease len to the nearest multiple of 64, and operate on 64-byte chunks.
249 __len = (__len - 1) & ~static_cast<_Size>(63);
250 do {
251 __x = __rotate(__x + __y + __v.first + __loadword<_Size>(__s + 8), 37) * __k1;
252 __y = __rotate(__y + __v.second + __loadword<_Size>(__s + 48), 42) * __k1;
253 __x ^= __w.second;
254 __y += __v.first + __loadword<_Size>(__s + 40);
255 __z = __rotate(__z + __w.first, 33) * __k1;
256 __v = __weak_hash_len_32_with_seeds(__s, __v.second * __k1, __x + __w.first);
257 __w = __weak_hash_len_32_with_seeds(__s + 32, __z + __w.second,
258 __y + __loadword<_Size>(__s + 16));
259 _VSTD::swap(__z, __x);
260 __s += 64;
261 __len -= 64;
262 } while (__len != 0);
263 return __hash_len_16(
264 __hash_len_16(__v.first, __w.first) + __shift_mix(__y) * __k1 + __z,
265 __hash_len_16(__v.second, __w.second) + __x);
266}
267
268template <class _Tp, size_t = sizeof(_Tp) / sizeof(size_t)>
269struct __scalar_hash;
270
271_LIBCPP_SUPPRESS_DEPRECATED_PUSH
272template <class _Tp>
273struct __scalar_hash<_Tp, 0>
274#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
275 : public unary_function<_Tp, size_t>
276#endif
277{
278_LIBCPP_SUPPRESS_DEPRECATED_POP
279#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
280 _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
281 _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp argument_type;
282#endif
283 _LIBCPP_INLINE_VISIBILITY
284 size_t operator()(_Tp __v) const _NOEXCEPT
285 {
286 union
287 {
288 _Tp __t;
289 size_t __a;
290 } __u;
291 __u.__a = 0;
292 __u.__t = __v;
293 return __u.__a;
294 }
295};
296
297_LIBCPP_SUPPRESS_DEPRECATED_PUSH
298template <class _Tp>
299struct __scalar_hash<_Tp, 1>
300#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
301 : public unary_function<_Tp, size_t>
302#endif
303{
304_LIBCPP_SUPPRESS_DEPRECATED_POP
305#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
306 _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
307 _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp argument_type;
308#endif
309 _LIBCPP_INLINE_VISIBILITY
310 size_t operator()(_Tp __v) const _NOEXCEPT
311 {
312 union
313 {
314 _Tp __t;
315 size_t __a;
316 } __u;
317 __u.__t = __v;
318 return __u.__a;
319 }
320};
321
322_LIBCPP_SUPPRESS_DEPRECATED_PUSH
323template <class _Tp>
324struct __scalar_hash<_Tp, 2>
325#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
326 : public unary_function<_Tp, size_t>
327#endif
328{
329_LIBCPP_SUPPRESS_DEPRECATED_POP
330#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
331 _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
332 _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp argument_type;
333#endif
334 _LIBCPP_INLINE_VISIBILITY
335 size_t operator()(_Tp __v) const _NOEXCEPT
336 {
337 union
338 {
339 _Tp __t;
340 struct
341 {
342 size_t __a;
343 size_t __b;
344 } __s;
345 } __u;
346 __u.__t = __v;
347 return __murmur2_or_cityhash<size_t>()(&__u, sizeof(__u));
348 }
349};
350
351_LIBCPP_SUPPRESS_DEPRECATED_PUSH
352template <class _Tp>
353struct __scalar_hash<_Tp, 3>
354#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
355 : public unary_function<_Tp, size_t>
356#endif
357{
358_LIBCPP_SUPPRESS_DEPRECATED_POP
359#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
360 _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
361 _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp argument_type;
362#endif
363 _LIBCPP_INLINE_VISIBILITY
364 size_t operator()(_Tp __v) const _NOEXCEPT
365 {
366 union
367 {
368 _Tp __t;
369 struct
370 {
371 size_t __a;
372 size_t __b;
373 size_t __c;
374 } __s;
375 } __u;
376 __u.__t = __v;
377 return __murmur2_or_cityhash<size_t>()(&__u, sizeof(__u));
378 }
379};
380
381_LIBCPP_SUPPRESS_DEPRECATED_PUSH
382template <class _Tp>
383struct __scalar_hash<_Tp, 4>
384#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
385 : public unary_function<_Tp, size_t>
386#endif
387{
388_LIBCPP_SUPPRESS_DEPRECATED_POP
389#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
390 _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
391 _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp argument_type;
392#endif
393 _LIBCPP_INLINE_VISIBILITY
394 size_t operator()(_Tp __v) const _NOEXCEPT
395 {
396 union
397 {
398 _Tp __t;
399 struct
400 {
401 size_t __a;
402 size_t __b;
403 size_t __c;
404 size_t __d;
405 } __s;
406 } __u;
407 __u.__t = __v;
408 return __murmur2_or_cityhash<size_t>()(&__u, sizeof(__u));
409 }
410};
411
412struct _PairT {
413 size_t first;
414 size_t second;
415};
416
417_LIBCPP_INLINE_VISIBILITY
418inline size_t __hash_combine(size_t __lhs, size_t __rhs) _NOEXCEPT {
419 typedef __scalar_hash<_PairT> _HashT;
420 const _PairT __p = {__lhs, __rhs};
421 return _HashT()(__p);
422}
423
424_LIBCPP_SUPPRESS_DEPRECATED_PUSH
425template<class _Tp>
426struct _LIBCPP_TEMPLATE_VIS hash<_Tp*>
427#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
428 : public unary_function<_Tp*, size_t>
429#endif
430{
431_LIBCPP_SUPPRESS_DEPRECATED_POP
432#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
433 _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
434 _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp* argument_type;
435#endif
436 _LIBCPP_INLINE_VISIBILITY
437 size_t operator()(_Tp* __v) const _NOEXCEPT
438 {
439 union
440 {
441 _Tp* __t;
442 size_t __a;
443 } __u;
444 __u.__t = __v;
445 return __murmur2_or_cityhash<size_t>()(&__u, sizeof(__u));
446 }
447};
448
449_LIBCPP_SUPPRESS_DEPRECATED_PUSH
450template <>
451struct _LIBCPP_TEMPLATE_VIS hash<bool>
452#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
453 : public unary_function<bool, size_t>
454#endif
455{
456_LIBCPP_SUPPRESS_DEPRECATED_POP
457#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
458 _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
459 _LIBCPP_DEPRECATED_IN_CXX17 typedef bool argument_type;
460#endif
461 _LIBCPP_INLINE_VISIBILITY
462 size_t operator()(bool __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
463};
464
465_LIBCPP_SUPPRESS_DEPRECATED_PUSH
466template <>
467struct _LIBCPP_TEMPLATE_VIS hash<char>
468#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
469 : public unary_function<char, size_t>
470#endif
471{
472_LIBCPP_SUPPRESS_DEPRECATED_POP
473#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
474 _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
475 _LIBCPP_DEPRECATED_IN_CXX17 typedef char argument_type;
476#endif
477 _LIBCPP_INLINE_VISIBILITY
478 size_t operator()(char __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
479};
480
481_LIBCPP_SUPPRESS_DEPRECATED_PUSH
482template <>
483struct _LIBCPP_TEMPLATE_VIS hash<signed char>
484#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
485 : public unary_function<signed char, size_t>
486#endif
487{
488_LIBCPP_SUPPRESS_DEPRECATED_POP
489#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
490 _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
491 _LIBCPP_DEPRECATED_IN_CXX17 typedef signed char argument_type;
492#endif
493 _LIBCPP_INLINE_VISIBILITY
494 size_t operator()(signed char __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
495};
496
497_LIBCPP_SUPPRESS_DEPRECATED_PUSH
498template <>
499struct _LIBCPP_TEMPLATE_VIS hash<unsigned char>
500#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
501 : public unary_function<unsigned char, size_t>
502#endif
503{
504_LIBCPP_SUPPRESS_DEPRECATED_POP
505#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
506 _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
507 _LIBCPP_DEPRECATED_IN_CXX17 typedef unsigned char argument_type;
508#endif
509 _LIBCPP_INLINE_VISIBILITY
510 size_t operator()(unsigned char __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
511};
512
513#ifndef _LIBCPP_HAS_NO_CHAR8_T
514_LIBCPP_SUPPRESS_DEPRECATED_PUSH
515template <>
516struct _LIBCPP_TEMPLATE_VIS hash<char8_t>
517#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
518 : public unary_function<char8_t, size_t>
519#endif
520{
521_LIBCPP_SUPPRESS_DEPRECATED_POP
522#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
523 _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
524 _LIBCPP_DEPRECATED_IN_CXX17 typedef char8_t argument_type;
525#endif
526 _LIBCPP_INLINE_VISIBILITY
527 size_t operator()(char8_t __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
528};
529#endif // !_LIBCPP_HAS_NO_CHAR8_T
530
531#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
532
533_LIBCPP_SUPPRESS_DEPRECATED_PUSH
534template <>
535struct _LIBCPP_TEMPLATE_VIS hash<char16_t>
536#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
537 : public unary_function<char16_t, size_t>
538#endif
539{
540_LIBCPP_SUPPRESS_DEPRECATED_POP
541#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
542 _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
543 _LIBCPP_DEPRECATED_IN_CXX17 typedef char16_t argument_type;
544#endif
545 _LIBCPP_INLINE_VISIBILITY
546 size_t operator()(char16_t __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
547};
548
549_LIBCPP_SUPPRESS_DEPRECATED_PUSH
550template <>
551struct _LIBCPP_TEMPLATE_VIS hash<char32_t>
552#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
553 : public unary_function<char32_t, size_t>
554#endif
555{
556_LIBCPP_SUPPRESS_DEPRECATED_POP
557#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
558 _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
559 _LIBCPP_DEPRECATED_IN_CXX17 typedef char32_t argument_type;
560#endif
561 _LIBCPP_INLINE_VISIBILITY
562 size_t operator()(char32_t __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
563};
564
565#endif // _LIBCPP_HAS_NO_UNICODE_CHARS
566
567_LIBCPP_SUPPRESS_DEPRECATED_PUSH
568template <>
569struct _LIBCPP_TEMPLATE_VIS hash<wchar_t>
570#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
571 : public unary_function<wchar_t, size_t>
572#endif
573{
574_LIBCPP_SUPPRESS_DEPRECATED_POP
575#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
576 _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
577 _LIBCPP_DEPRECATED_IN_CXX17 typedef wchar_t argument_type;
578#endif
579 _LIBCPP_INLINE_VISIBILITY
580 size_t operator()(wchar_t __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
581};
582
583_LIBCPP_SUPPRESS_DEPRECATED_PUSH
584template <>
585struct _LIBCPP_TEMPLATE_VIS hash<short>
586#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
587 : public unary_function<short, size_t>
588#endif
589{
590_LIBCPP_SUPPRESS_DEPRECATED_POP
591#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
592 _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
593 _LIBCPP_DEPRECATED_IN_CXX17 typedef short argument_type;
594#endif
595 _LIBCPP_INLINE_VISIBILITY
596 size_t operator()(short __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
597};
598
599_LIBCPP_SUPPRESS_DEPRECATED_PUSH
600template <>
601struct _LIBCPP_TEMPLATE_VIS hash<unsigned short>
602#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
603 : public unary_function<unsigned short, size_t>
604#endif
605{
606_LIBCPP_SUPPRESS_DEPRECATED_POP
607#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
608 _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
609 _LIBCPP_DEPRECATED_IN_CXX17 typedef unsigned short argument_type;
610#endif
611 _LIBCPP_INLINE_VISIBILITY
612 size_t operator()(unsigned short __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
613};
614
615_LIBCPP_SUPPRESS_DEPRECATED_PUSH
616template <>
617struct _LIBCPP_TEMPLATE_VIS hash<int>
618#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
619 : public unary_function<int, size_t>
620#endif
621{
622_LIBCPP_SUPPRESS_DEPRECATED_POP
623#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
624 _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
625 _LIBCPP_DEPRECATED_IN_CXX17 typedef int argument_type;
626#endif
627 _LIBCPP_INLINE_VISIBILITY
628 size_t operator()(int __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
629};
630
631_LIBCPP_SUPPRESS_DEPRECATED_PUSH
632template <>
633struct _LIBCPP_TEMPLATE_VIS hash<unsigned int>
634#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
635 : public unary_function<unsigned int, size_t>
636#endif
637{
638_LIBCPP_SUPPRESS_DEPRECATED_POP
639#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
640 _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
641 _LIBCPP_DEPRECATED_IN_CXX17 typedef unsigned int argument_type;
642#endif
643 _LIBCPP_INLINE_VISIBILITY
644 size_t operator()(unsigned int __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
645};
646
647_LIBCPP_SUPPRESS_DEPRECATED_PUSH
648template <>
649struct _LIBCPP_TEMPLATE_VIS hash<long>
650#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
651 : public unary_function<long, size_t>
652#endif
653{
654_LIBCPP_SUPPRESS_DEPRECATED_POP
655#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
656 _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
657 _LIBCPP_DEPRECATED_IN_CXX17 typedef long argument_type;
658#endif
659 _LIBCPP_INLINE_VISIBILITY
660 size_t operator()(long __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
661};
662
663_LIBCPP_SUPPRESS_DEPRECATED_PUSH
664template <>
665struct _LIBCPP_TEMPLATE_VIS hash<unsigned long>
666#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
667 : public unary_function<unsigned long, size_t>
668#endif
669{
670_LIBCPP_SUPPRESS_DEPRECATED_POP
671#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
672 _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
673 _LIBCPP_DEPRECATED_IN_CXX17 typedef unsigned long argument_type;
674#endif
675 _LIBCPP_INLINE_VISIBILITY
676 size_t operator()(unsigned long __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
677};
678
679template <>
680struct _LIBCPP_TEMPLATE_VIS hash<long long>
681 : public __scalar_hash<long long>
682{
683};
684
685template <>
686struct _LIBCPP_TEMPLATE_VIS hash<unsigned long long>
687 : public __scalar_hash<unsigned long long>
688{
689};
690
691#ifndef _LIBCPP_HAS_NO_INT128
692
693template <>
694struct _LIBCPP_TEMPLATE_VIS hash<__int128_t>
695 : public __scalar_hash<__int128_t>
696{
697};
698
699template <>
700struct _LIBCPP_TEMPLATE_VIS hash<__uint128_t>
701 : public __scalar_hash<__uint128_t>
702{
703};
704
705#endif
706
707template <>
708struct _LIBCPP_TEMPLATE_VIS hash<float>
709 : public __scalar_hash<float>
710{
711 _LIBCPP_INLINE_VISIBILITY
712 size_t operator()(float __v) const _NOEXCEPT
713 {
714 // -0.0 and 0.0 should return same hash
715 if (__v == 0.0f)
716 return 0;
717 return __scalar_hash<float>::operator()(__v);
718 }
719};
720
721template <>
722struct _LIBCPP_TEMPLATE_VIS hash<double>
723 : public __scalar_hash<double>
724{
725 _LIBCPP_INLINE_VISIBILITY
726 size_t operator()(double __v) const _NOEXCEPT
727 {
728 // -0.0 and 0.0 should return same hash
729 if (__v == 0.0)
730 return 0;
731 return __scalar_hash<double>::operator()(__v);
732 }
733};
734
735template <>
736struct _LIBCPP_TEMPLATE_VIS hash<long double>
737 : public __scalar_hash<long double>
738{
739 _LIBCPP_INLINE_VISIBILITY
740 size_t operator()(long double __v) const _NOEXCEPT
741 {
742 // -0.0 and 0.0 should return same hash
743 if (__v == 0.0L)
744 return 0;
745#if defined(__i386__) || (defined(__x86_64__) && defined(__ILP32__))
746 // Zero out padding bits
747 union
748 {
749 long double __t;
750 struct
751 {
752 size_t __a;
753 size_t __b;
754 size_t __c;
755 size_t __d;
756 } __s;
757 } __u;
758 __u.__s.__a = 0;
759 __u.__s.__b = 0;
760 __u.__s.__c = 0;
761 __u.__s.__d = 0;
762 __u.__t = __v;
763 return __u.__s.__a ^ __u.__s.__b ^ __u.__s.__c ^ __u.__s.__d;
764#elif defined(__x86_64__)
765 // Zero out padding bits
766 union
767 {
768 long double __t;
769 struct
770 {
771 size_t __a;
772 size_t __b;
773 } __s;
774 } __u;
775 __u.__s.__a = 0;
776 __u.__s.__b = 0;
777 __u.__t = __v;
778 return __u.__s.__a ^ __u.__s.__b;
779#else
780 return __scalar_hash<long double>::operator()(__v);
781#endif
782 }
783};
784
785#if _LIBCPP_STD_VER > 11
786
787_LIBCPP_SUPPRESS_DEPRECATED_PUSH
788template <class _Tp, bool = is_enum<_Tp>::value>
789struct _LIBCPP_TEMPLATE_VIS __enum_hash
790#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
791 : public unary_function<_Tp, size_t>
792#endif
793{
794_LIBCPP_SUPPRESS_DEPRECATED_POP
795#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
796 _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
797 _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp argument_type;
798#endif
799 _LIBCPP_INLINE_VISIBILITY
800 size_t operator()(_Tp __v) const _NOEXCEPT
801 {
802 typedef typename underlying_type<_Tp>::type type;
803 return hash<type>{}(static_cast<type>(__v));
804 }
805};
806template <class _Tp>
807struct _LIBCPP_TEMPLATE_VIS __enum_hash<_Tp, false> {
808 __enum_hash() = delete;
809 __enum_hash(__enum_hash const&) = delete;
810 __enum_hash& operator=(__enum_hash const&) = delete;
811};
812
813template <class _Tp>
814struct _LIBCPP_TEMPLATE_VIS hash : public __enum_hash<_Tp>
815{
816};
817#endif
818
819#if _LIBCPP_STD_VER > 14
820
821_LIBCPP_SUPPRESS_DEPRECATED_PUSH
822template <>
823struct _LIBCPP_TEMPLATE_VIS hash<nullptr_t>
824#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
825 : public unary_function<nullptr_t, size_t>
826#endif
827{
828_LIBCPP_SUPPRESS_DEPRECATED_POP
829#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
830 _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
831 _LIBCPP_DEPRECATED_IN_CXX17 typedef nullptr_t argument_type;
832#endif
833 _LIBCPP_INLINE_VISIBILITY
834 size_t operator()(nullptr_t) const _NOEXCEPT {
835 return 662607004ull;
836 }
837};
838#endif
839
840#ifndef _LIBCPP_CXX03_LANG
841template <class _Key, class _Hash>
842using __check_hash_requirements _LIBCPP_NODEBUG_TYPE = integral_constant<bool,
843 is_copy_constructible<_Hash>::value &&
844 is_move_constructible<_Hash>::value &&
845 __invokable_r<size_t, _Hash, _Key const&>::value
846>;
847
848template <class _Key, class _Hash = hash<_Key> >
849using __has_enabled_hash _LIBCPP_NODEBUG_TYPE = integral_constant<bool,
850 __check_hash_requirements<_Key, _Hash>::value &&
851 is_default_constructible<_Hash>::value
852>;
853
854#if _LIBCPP_STD_VER > 14
855template <class _Type, class>
856using __enable_hash_helper_imp _LIBCPP_NODEBUG_TYPE = _Type;
857
858template <class _Type, class ..._Keys>
859using __enable_hash_helper _LIBCPP_NODEBUG_TYPE = __enable_hash_helper_imp<_Type,
860 typename enable_if<__all<__has_enabled_hash<_Keys>::value...>::value>::type
861>;
862#else
863template <class _Type, class ...>
864using __enable_hash_helper _LIBCPP_NODEBUG_TYPE = _Type;
865#endif
866
867#endif // !_LIBCPP_CXX03_LANG
868
869_LIBCPP_END_NAMESPACE_STD
870
871_LIBCPP_POP_MACROS
872
873#endif // _LIBCPP___FUNCTIONAL_HASH_H
lib/libcxx/include/__functional/identity.h created+37
......@@ -0,0 +1,37 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___FUNCTIONAL_IDENTITY_H
11#define _LIBCPP___FUNCTIONAL_IDENTITY_H
12
13#include <__config>
14#include <utility>
15
16#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
17#pragma GCC system_header
18#endif
19
20_LIBCPP_BEGIN_NAMESPACE_STD
21
22#if _LIBCPP_STD_VER > 17
23
24struct identity {
25 template<class _Tp>
26 _LIBCPP_NODISCARD_EXT constexpr _Tp&& operator()(_Tp&& __t) const noexcept
27 {
28 return _VSTD::forward<_Tp>(__t);
29 }
30
31 using is_transparent = void;
32};
33#endif // _LIBCPP_STD_VER > 17
34
35_LIBCPP_END_NAMESPACE_STD
36
37#endif // _LIBCPP___FUNCTIONAL_IDENTITY_H
lib/libcxx/include/__functional/invoke.h created+100
......@@ -0,0 +1,100 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___FUNCTIONAL_INVOKE_H
11#define _LIBCPP___FUNCTIONAL_INVOKE_H
12
13#include <__config>
14#include <__functional/weak_result_type.h>
15#include <__utility/forward.h>
16#include <type_traits>
17
18#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
19#pragma GCC system_header
20#endif
21
22_LIBCPP_BEGIN_NAMESPACE_STD
23
24template <class _Ret, bool = is_void<_Ret>::value>
25struct __invoke_void_return_wrapper
26{
27#ifndef _LIBCPP_CXX03_LANG
28 template <class ..._Args>
29 static _Ret __call(_Args&&... __args) {
30 return _VSTD::__invoke(_VSTD::forward<_Args>(__args)...);
31 }
32#else
33 template <class _Fn>
34 static _Ret __call(_Fn __f) {
35 return _VSTD::__invoke(__f);
36 }
37
38 template <class _Fn, class _A0>
39 static _Ret __call(_Fn __f, _A0& __a0) {
40 return _VSTD::__invoke(__f, __a0);
41 }
42
43 template <class _Fn, class _A0, class _A1>
44 static _Ret __call(_Fn __f, _A0& __a0, _A1& __a1) {
45 return _VSTD::__invoke(__f, __a0, __a1);
46 }
47
48 template <class _Fn, class _A0, class _A1, class _A2>
49 static _Ret __call(_Fn __f, _A0& __a0, _A1& __a1, _A2& __a2){
50 return _VSTD::__invoke(__f, __a0, __a1, __a2);
51 }
52#endif
53};
54
55template <class _Ret>
56struct __invoke_void_return_wrapper<_Ret, true>
57{
58#ifndef _LIBCPP_CXX03_LANG
59 template <class ..._Args>
60 static void __call(_Args&&... __args) {
61 _VSTD::__invoke(_VSTD::forward<_Args>(__args)...);
62 }
63#else
64 template <class _Fn>
65 static void __call(_Fn __f) {
66 _VSTD::__invoke(__f);
67 }
68
69 template <class _Fn, class _A0>
70 static void __call(_Fn __f, _A0& __a0) {
71 _VSTD::__invoke(__f, __a0);
72 }
73
74 template <class _Fn, class _A0, class _A1>
75 static void __call(_Fn __f, _A0& __a0, _A1& __a1) {
76 _VSTD::__invoke(__f, __a0, __a1);
77 }
78
79 template <class _Fn, class _A0, class _A1, class _A2>
80 static void __call(_Fn __f, _A0& __a0, _A1& __a1, _A2& __a2) {
81 _VSTD::__invoke(__f, __a0, __a1, __a2);
82 }
83#endif
84};
85
86#if _LIBCPP_STD_VER > 14
87
88template <class _Fn, class ..._Args>
89_LIBCPP_CONSTEXPR_AFTER_CXX17 invoke_result_t<_Fn, _Args...>
90invoke(_Fn&& __f, _Args&&... __args)
91 noexcept(is_nothrow_invocable_v<_Fn, _Args...>)
92{
93 return _VSTD::__invoke(_VSTD::forward<_Fn>(__f), _VSTD::forward<_Args>(__args)...);
94}
95
96#endif // _LIBCPP_STD_VER > 14
97
98_LIBCPP_END_NAMESPACE_STD
99
100#endif // _LIBCPP___FUNCTIONAL_INVOKE_H
lib/libcxx/include/__functional/is_transparent.h created+36
......@@ -0,0 +1,36 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___FUNCTIONAL_IS_TRANSPARENT
11#define _LIBCPP___FUNCTIONAL_IS_TRANSPARENT
12
13#include <__config>
14#include <type_traits>
15
16#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
17#pragma GCC system_header
18#endif
19
20_LIBCPP_BEGIN_NAMESPACE_STD
21
22#if _LIBCPP_STD_VER > 11
23
24template <class _Tp, class, class = void>
25struct __is_transparent : false_type {};
26
27template <class _Tp, class _Up>
28struct __is_transparent<_Tp, _Up,
29 typename __void_t<typename _Tp::is_transparent>::type>
30 : true_type {};
31
32#endif
33
34_LIBCPP_END_NAMESPACE_STD
35
36#endif // _LIBCPP___FUNCTIONAL_IS_TRANSPARENT
lib/libcxx/include/__functional/mem_fn.h created+161
......@@ -0,0 +1,161 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___FUNCTIONAL_MEM_FN_H
11#define _LIBCPP___FUNCTIONAL_MEM_FN_H
12
13#include <__config>
14#include <__functional/weak_result_type.h>
15#include <__functional/binary_function.h>
16#include <__functional/invoke.h>
17#include <utility>
18
19#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
20#pragma GCC system_header
21#endif
22
23_LIBCPP_BEGIN_NAMESPACE_STD
24
25template <class _Tp>
26class __mem_fn
27#if _LIBCPP_STD_VER <= 17 || !defined(_LIBCPP_ABI_NO_BINDER_BASES)
28 : public __weak_result_type<_Tp>
29#endif
30{
31public:
32 // types
33 typedef _Tp type;
34private:
35 type __f_;
36
37public:
38 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
39 __mem_fn(type __f) _NOEXCEPT : __f_(__f) {}
40
41#ifndef _LIBCPP_CXX03_LANG
42 // invoke
43 template <class... _ArgTypes>
44 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
45 typename __invoke_return<type, _ArgTypes...>::type
46 operator() (_ArgTypes&&... __args) const {
47 return _VSTD::__invoke(__f_, _VSTD::forward<_ArgTypes>(__args)...);
48 }
49#else
50
51 template <class _A0>
52 _LIBCPP_INLINE_VISIBILITY
53 typename __invoke_return0<type, _A0>::type
54 operator() (_A0& __a0) const {
55 return _VSTD::__invoke(__f_, __a0);
56 }
57
58 template <class _A0>
59 _LIBCPP_INLINE_VISIBILITY
60 typename __invoke_return0<type, _A0 const>::type
61 operator() (_A0 const& __a0) const {
62 return _VSTD::__invoke(__f_, __a0);
63 }
64
65 template <class _A0, class _A1>
66 _LIBCPP_INLINE_VISIBILITY
67 typename __invoke_return1<type, _A0, _A1>::type
68 operator() (_A0& __a0, _A1& __a1) const {
69 return _VSTD::__invoke(__f_, __a0, __a1);
70 }
71
72 template <class _A0, class _A1>
73 _LIBCPP_INLINE_VISIBILITY
74 typename __invoke_return1<type, _A0 const, _A1>::type
75 operator() (_A0 const& __a0, _A1& __a1) const {
76 return _VSTD::__invoke(__f_, __a0, __a1);
77 }
78
79 template <class _A0, class _A1>
80 _LIBCPP_INLINE_VISIBILITY
81 typename __invoke_return1<type, _A0, _A1 const>::type
82 operator() (_A0& __a0, _A1 const& __a1) const {
83 return _VSTD::__invoke(__f_, __a0, __a1);
84 }
85
86 template <class _A0, class _A1>
87 _LIBCPP_INLINE_VISIBILITY
88 typename __invoke_return1<type, _A0 const, _A1 const>::type
89 operator() (_A0 const& __a0, _A1 const& __a1) const {
90 return _VSTD::__invoke(__f_, __a0, __a1);
91 }
92
93 template <class _A0, class _A1, class _A2>
94 _LIBCPP_INLINE_VISIBILITY
95 typename __invoke_return2<type, _A0, _A1, _A2>::type
96 operator() (_A0& __a0, _A1& __a1, _A2& __a2) const {
97 return _VSTD::__invoke(__f_, __a0, __a1, __a2);
98 }
99
100 template <class _A0, class _A1, class _A2>
101 _LIBCPP_INLINE_VISIBILITY
102 typename __invoke_return2<type, _A0 const, _A1, _A2>::type
103 operator() (_A0 const& __a0, _A1& __a1, _A2& __a2) const {
104 return _VSTD::__invoke(__f_, __a0, __a1, __a2);
105 }
106
107 template <class _A0, class _A1, class _A2>
108 _LIBCPP_INLINE_VISIBILITY
109 typename __invoke_return2<type, _A0, _A1 const, _A2>::type
110 operator() (_A0& __a0, _A1 const& __a1, _A2& __a2) const {
111 return _VSTD::__invoke(__f_, __a0, __a1, __a2);
112 }
113
114 template <class _A0, class _A1, class _A2>
115 _LIBCPP_INLINE_VISIBILITY
116 typename __invoke_return2<type, _A0, _A1, _A2 const>::type
117 operator() (_A0& __a0, _A1& __a1, _A2 const& __a2) const {
118 return _VSTD::__invoke(__f_, __a0, __a1, __a2);
119 }
120
121 template <class _A0, class _A1, class _A2>
122 _LIBCPP_INLINE_VISIBILITY
123 typename __invoke_return2<type, _A0 const, _A1 const, _A2>::type
124 operator() (_A0 const& __a0, _A1 const& __a1, _A2& __a2) const {
125 return _VSTD::__invoke(__f_, __a0, __a1, __a2);
126 }
127
128 template <class _A0, class _A1, class _A2>
129 _LIBCPP_INLINE_VISIBILITY
130 typename __invoke_return2<type, _A0 const, _A1, _A2 const>::type
131 operator() (_A0 const& __a0, _A1& __a1, _A2 const& __a2) const {
132 return _VSTD::__invoke(__f_, __a0, __a1, __a2);
133 }
134
135 template <class _A0, class _A1, class _A2>
136 _LIBCPP_INLINE_VISIBILITY
137 typename __invoke_return2<type, _A0, _A1 const, _A2 const>::type
138 operator() (_A0& __a0, _A1 const& __a1, _A2 const& __a2) const {
139 return _VSTD::__invoke(__f_, __a0, __a1, __a2);
140 }
141
142 template <class _A0, class _A1, class _A2>
143 _LIBCPP_INLINE_VISIBILITY
144 typename __invoke_return2<type, _A0 const, _A1 const, _A2 const>::type
145 operator() (_A0 const& __a0, _A1 const& __a1, _A2 const& __a2) const {
146 return _VSTD::__invoke(__f_, __a0, __a1, __a2);
147 }
148#endif
149};
150
151template<class _Rp, class _Tp>
152inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
153__mem_fn<_Rp _Tp::*>
154mem_fn(_Rp _Tp::* __pm) _NOEXCEPT
155{
156 return __mem_fn<_Rp _Tp::*>(__pm);
157}
158
159_LIBCPP_END_NAMESPACE_STD
160
161#endif // _LIBCPP___FUNCTIONAL_MEM_FN_H
lib/libcxx/include/__functional/mem_fun_ref.h created+173
......@@ -0,0 +1,173 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___FUNCTIONAL_MEM_FUN_REF_H
11#define _LIBCPP___FUNCTIONAL_MEM_FUN_REF_H
12
13#include <__config>
14#include <__functional/unary_function.h>
15#include <__functional/binary_function.h>
16
17#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
18#pragma GCC system_header
19#endif
20
21_LIBCPP_BEGIN_NAMESPACE_STD
22
23#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS)
24
25template<class _Sp, class _Tp>
26class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 mem_fun_t
27 : public unary_function<_Tp*, _Sp>
28{
29 _Sp (_Tp::*__p_)();
30public:
31 _LIBCPP_INLINE_VISIBILITY explicit mem_fun_t(_Sp (_Tp::*__p)())
32 : __p_(__p) {}
33 _LIBCPP_INLINE_VISIBILITY _Sp operator()(_Tp* __p) const
34 {return (__p->*__p_)();}
35};
36
37template<class _Sp, class _Tp, class _Ap>
38class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 mem_fun1_t
39 : public binary_function<_Tp*, _Ap, _Sp>
40{
41 _Sp (_Tp::*__p_)(_Ap);
42public:
43 _LIBCPP_INLINE_VISIBILITY explicit mem_fun1_t(_Sp (_Tp::*__p)(_Ap))
44 : __p_(__p) {}
45 _LIBCPP_INLINE_VISIBILITY _Sp operator()(_Tp* __p, _Ap __x) const
46 {return (__p->*__p_)(__x);}
47};
48
49template<class _Sp, class _Tp>
50_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY
51mem_fun_t<_Sp,_Tp>
52mem_fun(_Sp (_Tp::*__f)())
53 {return mem_fun_t<_Sp,_Tp>(__f);}
54
55template<class _Sp, class _Tp, class _Ap>
56_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY
57mem_fun1_t<_Sp,_Tp,_Ap>
58mem_fun(_Sp (_Tp::*__f)(_Ap))
59 {return mem_fun1_t<_Sp,_Tp,_Ap>(__f);}
60
61template<class _Sp, class _Tp>
62class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 mem_fun_ref_t
63 : public unary_function<_Tp, _Sp>
64{
65 _Sp (_Tp::*__p_)();
66public:
67 _LIBCPP_INLINE_VISIBILITY explicit mem_fun_ref_t(_Sp (_Tp::*__p)())
68 : __p_(__p) {}
69 _LIBCPP_INLINE_VISIBILITY _Sp operator()(_Tp& __p) const
70 {return (__p.*__p_)();}
71};
72
73template<class _Sp, class _Tp, class _Ap>
74class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 mem_fun1_ref_t
75 : public binary_function<_Tp, _Ap, _Sp>
76{
77 _Sp (_Tp::*__p_)(_Ap);
78public:
79 _LIBCPP_INLINE_VISIBILITY explicit mem_fun1_ref_t(_Sp (_Tp::*__p)(_Ap))
80 : __p_(__p) {}
81 _LIBCPP_INLINE_VISIBILITY _Sp operator()(_Tp& __p, _Ap __x) const
82 {return (__p.*__p_)(__x);}
83};
84
85template<class _Sp, class _Tp>
86_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY
87mem_fun_ref_t<_Sp,_Tp>
88mem_fun_ref(_Sp (_Tp::*__f)())
89 {return mem_fun_ref_t<_Sp,_Tp>(__f);}
90
91template<class _Sp, class _Tp, class _Ap>
92_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY
93mem_fun1_ref_t<_Sp,_Tp,_Ap>
94mem_fun_ref(_Sp (_Tp::*__f)(_Ap))
95 {return mem_fun1_ref_t<_Sp,_Tp,_Ap>(__f);}
96
97template <class _Sp, class _Tp>
98class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 const_mem_fun_t
99 : public unary_function<const _Tp*, _Sp>
100{
101 _Sp (_Tp::*__p_)() const;
102public:
103 _LIBCPP_INLINE_VISIBILITY explicit const_mem_fun_t(_Sp (_Tp::*__p)() const)
104 : __p_(__p) {}
105 _LIBCPP_INLINE_VISIBILITY _Sp operator()(const _Tp* __p) const
106 {return (__p->*__p_)();}
107};
108
109template <class _Sp, class _Tp, class _Ap>
110class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 const_mem_fun1_t
111 : public binary_function<const _Tp*, _Ap, _Sp>
112{
113 _Sp (_Tp::*__p_)(_Ap) const;
114public:
115 _LIBCPP_INLINE_VISIBILITY explicit const_mem_fun1_t(_Sp (_Tp::*__p)(_Ap) const)
116 : __p_(__p) {}
117 _LIBCPP_INLINE_VISIBILITY _Sp operator()(const _Tp* __p, _Ap __x) const
118 {return (__p->*__p_)(__x);}
119};
120
121template <class _Sp, class _Tp>
122_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY
123const_mem_fun_t<_Sp,_Tp>
124mem_fun(_Sp (_Tp::*__f)() const)
125 {return const_mem_fun_t<_Sp,_Tp>(__f);}
126
127template <class _Sp, class _Tp, class _Ap>
128_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY
129const_mem_fun1_t<_Sp,_Tp,_Ap>
130mem_fun(_Sp (_Tp::*__f)(_Ap) const)
131 {return const_mem_fun1_t<_Sp,_Tp,_Ap>(__f);}
132
133template <class _Sp, class _Tp>
134class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 const_mem_fun_ref_t
135 : public unary_function<_Tp, _Sp>
136{
137 _Sp (_Tp::*__p_)() const;
138public:
139 _LIBCPP_INLINE_VISIBILITY explicit const_mem_fun_ref_t(_Sp (_Tp::*__p)() const)
140 : __p_(__p) {}
141 _LIBCPP_INLINE_VISIBILITY _Sp operator()(const _Tp& __p) const
142 {return (__p.*__p_)();}
143};
144
145template <class _Sp, class _Tp, class _Ap>
146class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 const_mem_fun1_ref_t
147 : public binary_function<_Tp, _Ap, _Sp>
148{
149 _Sp (_Tp::*__p_)(_Ap) const;
150public:
151 _LIBCPP_INLINE_VISIBILITY explicit const_mem_fun1_ref_t(_Sp (_Tp::*__p)(_Ap) const)
152 : __p_(__p) {}
153 _LIBCPP_INLINE_VISIBILITY _Sp operator()(const _Tp& __p, _Ap __x) const
154 {return (__p.*__p_)(__x);}
155};
156
157template <class _Sp, class _Tp>
158_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY
159const_mem_fun_ref_t<_Sp,_Tp>
160mem_fun_ref(_Sp (_Tp::*__f)() const)
161 {return const_mem_fun_ref_t<_Sp,_Tp>(__f);}
162
163template <class _Sp, class _Tp, class _Ap>
164_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY
165const_mem_fun1_ref_t<_Sp,_Tp,_Ap>
166mem_fun_ref(_Sp (_Tp::*__f)(_Ap) const)
167 {return const_mem_fun1_ref_t<_Sp,_Tp,_Ap>(__f);}
168
169#endif // _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS)
170
171_LIBCPP_END_NAMESPACE_STD
172
173#endif // _LIBCPP___FUNCTIONAL_MEM_FUN_REF_H
lib/libcxx/include/__functional/not_fn.h created+47
......@@ -0,0 +1,47 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___FUNCTIONAL_NOT_FN_H
11#define _LIBCPP___FUNCTIONAL_NOT_FN_H
12
13#include <__config>
14#include <__functional/perfect_forward.h>
15#include <__functional/invoke.h>
16#include <utility>
17
18#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
19#pragma GCC system_header
20#endif
21
22_LIBCPP_BEGIN_NAMESPACE_STD
23
24#if _LIBCPP_STD_VER > 14
25
26struct __not_fn_op
27{
28 template<class... _Args>
29 static _LIBCPP_CONSTEXPR_AFTER_CXX17 auto __call(_Args&&... __args)
30 noexcept(noexcept(!_VSTD::invoke(_VSTD::forward<_Args>(__args)...)))
31 -> decltype( !_VSTD::invoke(_VSTD::forward<_Args>(__args)...))
32 { return !_VSTD::invoke(_VSTD::forward<_Args>(__args)...); }
33};
34
35template<class _Fn,
36 class = _EnableIf<is_constructible_v<decay_t<_Fn>, _Fn> &&
37 is_move_constructible_v<_Fn>>>
38_LIBCPP_CONSTEXPR_AFTER_CXX17 auto not_fn(_Fn&& __f)
39{
40 return __perfect_forward<__not_fn_op, _Fn>(_VSTD::forward<_Fn>(__f));
41}
42
43#endif // _LIBCPP_STD_VER > 14
44
45_LIBCPP_END_NAMESPACE_STD
46
47#endif // _LIBCPP___FUNCTIONAL_NOT_FN_H
lib/libcxx/include/__functional/operations.h created+729
......@@ -0,0 +1,729 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___FUNCTIONAL_OPERATIONS_H
11#define _LIBCPP___FUNCTIONAL_OPERATIONS_H
12
13#include <__config>
14#include <__functional/binary_function.h>
15#include <__functional/unary_function.h>
16#include <__utility/forward.h>
17
18#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
19#pragma GCC system_header
20#endif
21
22_LIBCPP_BEGIN_NAMESPACE_STD
23
24// Arithmetic operations
25
26_LIBCPP_SUPPRESS_DEPRECATED_PUSH
27#if _LIBCPP_STD_VER > 11
28template <class _Tp = void>
29#else
30template <class _Tp>
31#endif
32struct _LIBCPP_TEMPLATE_VIS plus
33#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
34 : binary_function<_Tp, _Tp, _Tp>
35#endif
36{
37_LIBCPP_SUPPRESS_DEPRECATED_POP
38 typedef _Tp __result_type; // used by valarray
39#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
40 _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp result_type;
41 _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type;
42 _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type;
43#endif
44 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
45 _Tp operator()(const _Tp& __x, const _Tp& __y) const
46 {return __x + __y;}
47};
48
49#if _LIBCPP_STD_VER > 11
50template <>
51struct _LIBCPP_TEMPLATE_VIS plus<void>
52{
53 template <class _T1, class _T2>
54 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
55 auto operator()(_T1&& __t, _T2&& __u) const
56 _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) + _VSTD::forward<_T2>(__u)))
57 -> decltype (_VSTD::forward<_T1>(__t) + _VSTD::forward<_T2>(__u))
58 { return _VSTD::forward<_T1>(__t) + _VSTD::forward<_T2>(__u); }
59 typedef void is_transparent;
60};
61#endif
62
63_LIBCPP_SUPPRESS_DEPRECATED_PUSH
64#if _LIBCPP_STD_VER > 11
65template <class _Tp = void>
66#else
67template <class _Tp>
68#endif
69struct _LIBCPP_TEMPLATE_VIS minus
70#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
71 : binary_function<_Tp, _Tp, _Tp>
72#endif
73{
74_LIBCPP_SUPPRESS_DEPRECATED_POP
75 typedef _Tp __result_type; // used by valarray
76#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
77 _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp result_type;
78 _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type;
79 _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type;
80#endif
81 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
82 _Tp operator()(const _Tp& __x, const _Tp& __y) const
83 {return __x - __y;}
84};
85
86#if _LIBCPP_STD_VER > 11
87template <>
88struct _LIBCPP_TEMPLATE_VIS minus<void>
89{
90 template <class _T1, class _T2>
91 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
92 auto operator()(_T1&& __t, _T2&& __u) const
93 _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) - _VSTD::forward<_T2>(__u)))
94 -> decltype (_VSTD::forward<_T1>(__t) - _VSTD::forward<_T2>(__u))
95 { return _VSTD::forward<_T1>(__t) - _VSTD::forward<_T2>(__u); }
96 typedef void is_transparent;
97};
98#endif
99
100_LIBCPP_SUPPRESS_DEPRECATED_PUSH
101#if _LIBCPP_STD_VER > 11
102template <class _Tp = void>
103#else
104template <class _Tp>
105#endif
106struct _LIBCPP_TEMPLATE_VIS multiplies
107#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
108 : binary_function<_Tp, _Tp, _Tp>
109#endif
110{
111_LIBCPP_SUPPRESS_DEPRECATED_POP
112 typedef _Tp __result_type; // used by valarray
113#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
114 _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp result_type;
115 _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type;
116 _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type;
117#endif
118 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
119 _Tp operator()(const _Tp& __x, const _Tp& __y) const
120 {return __x * __y;}
121};
122
123#if _LIBCPP_STD_VER > 11
124template <>
125struct _LIBCPP_TEMPLATE_VIS multiplies<void>
126{
127 template <class _T1, class _T2>
128 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
129 auto operator()(_T1&& __t, _T2&& __u) const
130 _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) * _VSTD::forward<_T2>(__u)))
131 -> decltype (_VSTD::forward<_T1>(__t) * _VSTD::forward<_T2>(__u))
132 { return _VSTD::forward<_T1>(__t) * _VSTD::forward<_T2>(__u); }
133 typedef void is_transparent;
134};
135#endif
136
137_LIBCPP_SUPPRESS_DEPRECATED_PUSH
138#if _LIBCPP_STD_VER > 11
139template <class _Tp = void>
140#else
141template <class _Tp>
142#endif
143struct _LIBCPP_TEMPLATE_VIS divides
144#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
145 : binary_function<_Tp, _Tp, _Tp>
146#endif
147{
148_LIBCPP_SUPPRESS_DEPRECATED_POP
149 typedef _Tp __result_type; // used by valarray
150#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
151 _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp result_type;
152 _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type;
153 _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type;
154#endif
155 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
156 _Tp operator()(const _Tp& __x, const _Tp& __y) const
157 {return __x / __y;}
158};
159
160#if _LIBCPP_STD_VER > 11
161template <>
162struct _LIBCPP_TEMPLATE_VIS divides<void>
163{
164 template <class _T1, class _T2>
165 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
166 auto operator()(_T1&& __t, _T2&& __u) const
167 _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) / _VSTD::forward<_T2>(__u)))
168 -> decltype (_VSTD::forward<_T1>(__t) / _VSTD::forward<_T2>(__u))
169 { return _VSTD::forward<_T1>(__t) / _VSTD::forward<_T2>(__u); }
170 typedef void is_transparent;
171};
172#endif
173
174_LIBCPP_SUPPRESS_DEPRECATED_PUSH
175#if _LIBCPP_STD_VER > 11
176template <class _Tp = void>
177#else
178template <class _Tp>
179#endif
180struct _LIBCPP_TEMPLATE_VIS modulus
181#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
182 : binary_function<_Tp, _Tp, _Tp>
183#endif
184{
185_LIBCPP_SUPPRESS_DEPRECATED_POP
186 typedef _Tp __result_type; // used by valarray
187#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
188 _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp result_type;
189 _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type;
190 _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type;
191#endif
192 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
193 _Tp operator()(const _Tp& __x, const _Tp& __y) const
194 {return __x % __y;}
195};
196
197#if _LIBCPP_STD_VER > 11
198template <>
199struct _LIBCPP_TEMPLATE_VIS modulus<void>
200{
201 template <class _T1, class _T2>
202 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
203 auto operator()(_T1&& __t, _T2&& __u) const
204 _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) % _VSTD::forward<_T2>(__u)))
205 -> decltype (_VSTD::forward<_T1>(__t) % _VSTD::forward<_T2>(__u))
206 { return _VSTD::forward<_T1>(__t) % _VSTD::forward<_T2>(__u); }
207 typedef void is_transparent;
208};
209#endif
210
211_LIBCPP_SUPPRESS_DEPRECATED_PUSH
212#if _LIBCPP_STD_VER > 11
213template <class _Tp = void>
214#else
215template <class _Tp>
216#endif
217struct _LIBCPP_TEMPLATE_VIS negate
218#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
219 : unary_function<_Tp, _Tp>
220#endif
221{
222_LIBCPP_SUPPRESS_DEPRECATED_POP
223 typedef _Tp __result_type; // used by valarray
224#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
225 _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp result_type;
226 _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp argument_type;
227#endif
228 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
229 _Tp operator()(const _Tp& __x) const
230 {return -__x;}
231};
232
233#if _LIBCPP_STD_VER > 11
234template <>
235struct _LIBCPP_TEMPLATE_VIS negate<void>
236{
237 template <class _Tp>
238 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
239 auto operator()(_Tp&& __x) const
240 _NOEXCEPT_(noexcept(- _VSTD::forward<_Tp>(__x)))
241 -> decltype (- _VSTD::forward<_Tp>(__x))
242 { return - _VSTD::forward<_Tp>(__x); }
243 typedef void is_transparent;
244};
245#endif
246
247// Bitwise operations
248
249_LIBCPP_SUPPRESS_DEPRECATED_PUSH
250#if _LIBCPP_STD_VER > 11
251template <class _Tp = void>
252#else
253template <class _Tp>
254#endif
255struct _LIBCPP_TEMPLATE_VIS bit_and
256#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
257 : binary_function<_Tp, _Tp, _Tp>
258#endif
259{
260_LIBCPP_SUPPRESS_DEPRECATED_POP
261 typedef _Tp __result_type; // used by valarray
262#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
263 _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp result_type;
264 _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type;
265 _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type;
266#endif
267 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
268 _Tp operator()(const _Tp& __x, const _Tp& __y) const
269 {return __x & __y;}
270};
271
272#if _LIBCPP_STD_VER > 11
273template <>
274struct _LIBCPP_TEMPLATE_VIS bit_and<void>
275{
276 template <class _T1, class _T2>
277 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
278 auto operator()(_T1&& __t, _T2&& __u) const
279 _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) & _VSTD::forward<_T2>(__u)))
280 -> decltype (_VSTD::forward<_T1>(__t) & _VSTD::forward<_T2>(__u))
281 { return _VSTD::forward<_T1>(__t) & _VSTD::forward<_T2>(__u); }
282 typedef void is_transparent;
283};
284#endif
285
286#if _LIBCPP_STD_VER > 11
287_LIBCPP_SUPPRESS_DEPRECATED_PUSH
288template <class _Tp = void>
289struct _LIBCPP_TEMPLATE_VIS bit_not
290#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
291 : unary_function<_Tp, _Tp>
292#endif
293{
294_LIBCPP_SUPPRESS_DEPRECATED_POP
295#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
296 _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp result_type;
297 _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp argument_type;
298#endif
299 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
300 _Tp operator()(const _Tp& __x) const
301 {return ~__x;}
302};
303
304template <>
305struct _LIBCPP_TEMPLATE_VIS bit_not<void>
306{
307 template <class _Tp>
308 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
309 auto operator()(_Tp&& __x) const
310 _NOEXCEPT_(noexcept(~_VSTD::forward<_Tp>(__x)))
311 -> decltype (~_VSTD::forward<_Tp>(__x))
312 { return ~_VSTD::forward<_Tp>(__x); }
313 typedef void is_transparent;
314};
315#endif
316
317_LIBCPP_SUPPRESS_DEPRECATED_PUSH
318#if _LIBCPP_STD_VER > 11
319template <class _Tp = void>
320#else
321template <class _Tp>
322#endif
323struct _LIBCPP_TEMPLATE_VIS bit_or
324#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
325 : binary_function<_Tp, _Tp, _Tp>
326#endif
327{
328_LIBCPP_SUPPRESS_DEPRECATED_POP
329 typedef _Tp __result_type; // used by valarray
330#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
331 _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp result_type;
332 _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type;
333 _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type;
334#endif
335 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
336 _Tp operator()(const _Tp& __x, const _Tp& __y) const
337 {return __x | __y;}
338};
339
340#if _LIBCPP_STD_VER > 11
341template <>
342struct _LIBCPP_TEMPLATE_VIS bit_or<void>
343{
344 template <class _T1, class _T2>
345 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
346 auto operator()(_T1&& __t, _T2&& __u) const
347 _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) | _VSTD::forward<_T2>(__u)))
348 -> decltype (_VSTD::forward<_T1>(__t) | _VSTD::forward<_T2>(__u))
349 { return _VSTD::forward<_T1>(__t) | _VSTD::forward<_T2>(__u); }
350 typedef void is_transparent;
351};
352#endif
353
354_LIBCPP_SUPPRESS_DEPRECATED_PUSH
355#if _LIBCPP_STD_VER > 11
356template <class _Tp = void>
357#else
358template <class _Tp>
359#endif
360struct _LIBCPP_TEMPLATE_VIS bit_xor
361#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
362 : binary_function<_Tp, _Tp, _Tp>
363#endif
364{
365_LIBCPP_SUPPRESS_DEPRECATED_POP
366 typedef _Tp __result_type; // used by valarray
367#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
368 _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp result_type;
369 _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type;
370 _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type;
371#endif
372 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
373 _Tp operator()(const _Tp& __x, const _Tp& __y) const
374 {return __x ^ __y;}
375};
376
377#if _LIBCPP_STD_VER > 11
378template <>
379struct _LIBCPP_TEMPLATE_VIS bit_xor<void>
380{
381 template <class _T1, class _T2>
382 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
383 auto operator()(_T1&& __t, _T2&& __u) const
384 _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) ^ _VSTD::forward<_T2>(__u)))
385 -> decltype (_VSTD::forward<_T1>(__t) ^ _VSTD::forward<_T2>(__u))
386 { return _VSTD::forward<_T1>(__t) ^ _VSTD::forward<_T2>(__u); }
387 typedef void is_transparent;
388};
389#endif
390
391// Comparison operations
392
393_LIBCPP_SUPPRESS_DEPRECATED_PUSH
394#if _LIBCPP_STD_VER > 11
395template <class _Tp = void>
396#else
397template <class _Tp>
398#endif
399struct _LIBCPP_TEMPLATE_VIS equal_to
400#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
401 : binary_function<_Tp, _Tp, bool>
402#endif
403{
404_LIBCPP_SUPPRESS_DEPRECATED_POP
405 typedef bool __result_type; // used by valarray
406#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
407 _LIBCPP_DEPRECATED_IN_CXX17 typedef bool result_type;
408 _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type;
409 _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type;
410#endif
411 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
412 bool operator()(const _Tp& __x, const _Tp& __y) const
413 {return __x == __y;}
414};
415
416#if _LIBCPP_STD_VER > 11
417template <>
418struct _LIBCPP_TEMPLATE_VIS equal_to<void>
419{
420 template <class _T1, class _T2>
421 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
422 auto operator()(_T1&& __t, _T2&& __u) const
423 _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) == _VSTD::forward<_T2>(__u)))
424 -> decltype (_VSTD::forward<_T1>(__t) == _VSTD::forward<_T2>(__u))
425 { return _VSTD::forward<_T1>(__t) == _VSTD::forward<_T2>(__u); }
426 typedef void is_transparent;
427};
428#endif
429
430_LIBCPP_SUPPRESS_DEPRECATED_PUSH
431#if _LIBCPP_STD_VER > 11
432template <class _Tp = void>
433#else
434template <class _Tp>
435#endif
436struct _LIBCPP_TEMPLATE_VIS not_equal_to
437#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
438 : binary_function<_Tp, _Tp, bool>
439#endif
440{
441_LIBCPP_SUPPRESS_DEPRECATED_POP
442 typedef bool __result_type; // used by valarray
443#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
444 _LIBCPP_DEPRECATED_IN_CXX17 typedef bool result_type;
445 _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type;
446 _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type;
447#endif
448 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
449 bool operator()(const _Tp& __x, const _Tp& __y) const
450 {return __x != __y;}
451};
452
453#if _LIBCPP_STD_VER > 11
454template <>
455struct _LIBCPP_TEMPLATE_VIS not_equal_to<void>
456{
457 template <class _T1, class _T2>
458 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
459 auto operator()(_T1&& __t, _T2&& __u) const
460 _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) != _VSTD::forward<_T2>(__u)))
461 -> decltype (_VSTD::forward<_T1>(__t) != _VSTD::forward<_T2>(__u))
462 { return _VSTD::forward<_T1>(__t) != _VSTD::forward<_T2>(__u); }
463 typedef void is_transparent;
464};
465#endif
466
467_LIBCPP_SUPPRESS_DEPRECATED_PUSH
468#if _LIBCPP_STD_VER > 11
469template <class _Tp = void>
470#else
471template <class _Tp>
472#endif
473struct _LIBCPP_TEMPLATE_VIS less
474#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
475 : binary_function<_Tp, _Tp, bool>
476#endif
477{
478_LIBCPP_SUPPRESS_DEPRECATED_POP
479 typedef bool __result_type; // used by valarray
480#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
481 _LIBCPP_DEPRECATED_IN_CXX17 typedef bool result_type;
482 _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type;
483 _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type;
484#endif
485 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
486 bool operator()(const _Tp& __x, const _Tp& __y) const
487 {return __x < __y;}
488};
489
490#if _LIBCPP_STD_VER > 11
491template <>
492struct _LIBCPP_TEMPLATE_VIS less<void>
493{
494 template <class _T1, class _T2>
495 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
496 auto operator()(_T1&& __t, _T2&& __u) const
497 _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) < _VSTD::forward<_T2>(__u)))
498 -> decltype (_VSTD::forward<_T1>(__t) < _VSTD::forward<_T2>(__u))
499 { return _VSTD::forward<_T1>(__t) < _VSTD::forward<_T2>(__u); }
500 typedef void is_transparent;
501};
502#endif
503
504_LIBCPP_SUPPRESS_DEPRECATED_PUSH
505#if _LIBCPP_STD_VER > 11
506template <class _Tp = void>
507#else
508template <class _Tp>
509#endif
510struct _LIBCPP_TEMPLATE_VIS less_equal
511#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
512 : binary_function<_Tp, _Tp, bool>
513#endif
514{
515_LIBCPP_SUPPRESS_DEPRECATED_POP
516 typedef bool __result_type; // used by valarray
517#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
518 _LIBCPP_DEPRECATED_IN_CXX17 typedef bool result_type;
519 _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type;
520 _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type;
521#endif
522 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
523 bool operator()(const _Tp& __x, const _Tp& __y) const
524 {return __x <= __y;}
525};
526
527#if _LIBCPP_STD_VER > 11
528template <>
529struct _LIBCPP_TEMPLATE_VIS less_equal<void>
530{
531 template <class _T1, class _T2>
532 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
533 auto operator()(_T1&& __t, _T2&& __u) const
534 _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) <= _VSTD::forward<_T2>(__u)))
535 -> decltype (_VSTD::forward<_T1>(__t) <= _VSTD::forward<_T2>(__u))
536 { return _VSTD::forward<_T1>(__t) <= _VSTD::forward<_T2>(__u); }
537 typedef void is_transparent;
538};
539#endif
540
541_LIBCPP_SUPPRESS_DEPRECATED_PUSH
542#if _LIBCPP_STD_VER > 11
543template <class _Tp = void>
544#else
545template <class _Tp>
546#endif
547struct _LIBCPP_TEMPLATE_VIS greater_equal
548#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
549 : binary_function<_Tp, _Tp, bool>
550#endif
551{
552_LIBCPP_SUPPRESS_DEPRECATED_POP
553 typedef bool __result_type; // used by valarray
554#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
555 _LIBCPP_DEPRECATED_IN_CXX17 typedef bool result_type;
556 _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type;
557 _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type;
558#endif
559 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
560 bool operator()(const _Tp& __x, const _Tp& __y) const
561 {return __x >= __y;}
562};
563
564#if _LIBCPP_STD_VER > 11
565template <>
566struct _LIBCPP_TEMPLATE_VIS greater_equal<void>
567{
568 template <class _T1, class _T2>
569 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
570 auto operator()(_T1&& __t, _T2&& __u) const
571 _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) >= _VSTD::forward<_T2>(__u)))
572 -> decltype (_VSTD::forward<_T1>(__t) >= _VSTD::forward<_T2>(__u))
573 { return _VSTD::forward<_T1>(__t) >= _VSTD::forward<_T2>(__u); }
574 typedef void is_transparent;
575};
576#endif
577
578_LIBCPP_SUPPRESS_DEPRECATED_PUSH
579#if _LIBCPP_STD_VER > 11
580template <class _Tp = void>
581#else
582template <class _Tp>
583#endif
584struct _LIBCPP_TEMPLATE_VIS greater
585#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
586 : binary_function<_Tp, _Tp, bool>
587#endif
588{
589_LIBCPP_SUPPRESS_DEPRECATED_POP
590 typedef bool __result_type; // used by valarray
591#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
592 _LIBCPP_DEPRECATED_IN_CXX17 typedef bool result_type;
593 _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type;
594 _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type;
595#endif
596 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
597 bool operator()(const _Tp& __x, const _Tp& __y) const
598 {return __x > __y;}
599};
600
601#if _LIBCPP_STD_VER > 11
602template <>
603struct _LIBCPP_TEMPLATE_VIS greater<void>
604{
605 template <class _T1, class _T2>
606 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
607 auto operator()(_T1&& __t, _T2&& __u) const
608 _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) > _VSTD::forward<_T2>(__u)))
609 -> decltype (_VSTD::forward<_T1>(__t) > _VSTD::forward<_T2>(__u))
610 { return _VSTD::forward<_T1>(__t) > _VSTD::forward<_T2>(__u); }
611 typedef void is_transparent;
612};
613#endif
614
615// Logical operations
616
617_LIBCPP_SUPPRESS_DEPRECATED_PUSH
618#if _LIBCPP_STD_VER > 11
619template <class _Tp = void>
620#else
621template <class _Tp>
622#endif
623struct _LIBCPP_TEMPLATE_VIS logical_and
624#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
625 : binary_function<_Tp, _Tp, bool>
626#endif
627{
628_LIBCPP_SUPPRESS_DEPRECATED_POP
629 typedef bool __result_type; // used by valarray
630#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
631 _LIBCPP_DEPRECATED_IN_CXX17 typedef bool result_type;
632 _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type;
633 _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type;
634#endif
635 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
636 bool operator()(const _Tp& __x, const _Tp& __y) const
637 {return __x && __y;}
638};
639
640#if _LIBCPP_STD_VER > 11
641template <>
642struct _LIBCPP_TEMPLATE_VIS logical_and<void>
643{
644 template <class _T1, class _T2>
645 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
646 auto operator()(_T1&& __t, _T2&& __u) const
647 _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) && _VSTD::forward<_T2>(__u)))
648 -> decltype (_VSTD::forward<_T1>(__t) && _VSTD::forward<_T2>(__u))
649 { return _VSTD::forward<_T1>(__t) && _VSTD::forward<_T2>(__u); }
650 typedef void is_transparent;
651};
652#endif
653
654_LIBCPP_SUPPRESS_DEPRECATED_PUSH
655#if _LIBCPP_STD_VER > 11
656template <class _Tp = void>
657#else
658template <class _Tp>
659#endif
660struct _LIBCPP_TEMPLATE_VIS logical_not
661#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
662 : unary_function<_Tp, bool>
663#endif
664{
665_LIBCPP_SUPPRESS_DEPRECATED_POP
666 typedef bool __result_type; // used by valarray
667#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
668 _LIBCPP_DEPRECATED_IN_CXX17 typedef bool result_type;
669 _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp argument_type;
670#endif
671 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
672 bool operator()(const _Tp& __x) const
673 {return !__x;}
674};
675
676#if _LIBCPP_STD_VER > 11
677template <>
678struct _LIBCPP_TEMPLATE_VIS logical_not<void>
679{
680 template <class _Tp>
681 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
682 auto operator()(_Tp&& __x) const
683 _NOEXCEPT_(noexcept(!_VSTD::forward<_Tp>(__x)))
684 -> decltype (!_VSTD::forward<_Tp>(__x))
685 { return !_VSTD::forward<_Tp>(__x); }
686 typedef void is_transparent;
687};
688#endif
689
690_LIBCPP_SUPPRESS_DEPRECATED_PUSH
691#if _LIBCPP_STD_VER > 11
692template <class _Tp = void>
693#else
694template <class _Tp>
695#endif
696struct _LIBCPP_TEMPLATE_VIS logical_or
697#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
698 : binary_function<_Tp, _Tp, bool>
699#endif
700{
701_LIBCPP_SUPPRESS_DEPRECATED_POP
702 typedef bool __result_type; // used by valarray
703#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
704 _LIBCPP_DEPRECATED_IN_CXX17 typedef bool result_type;
705 _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type;
706 _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type;
707#endif
708 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
709 bool operator()(const _Tp& __x, const _Tp& __y) const
710 {return __x || __y;}
711};
712
713#if _LIBCPP_STD_VER > 11
714template <>
715struct _LIBCPP_TEMPLATE_VIS logical_or<void>
716{
717 template <class _T1, class _T2>
718 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
719 auto operator()(_T1&& __t, _T2&& __u) const
720 _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) || _VSTD::forward<_T2>(__u)))
721 -> decltype (_VSTD::forward<_T1>(__t) || _VSTD::forward<_T2>(__u))
722 { return _VSTD::forward<_T1>(__t) || _VSTD::forward<_T2>(__u); }
723 typedef void is_transparent;
724};
725#endif
726
727_LIBCPP_END_NAMESPACE_STD
728
729#endif // _LIBCPP___FUNCTIONAL_OPERATIONS_H
lib/libcxx/include/__functional/perfect_forward.h created+88
......@@ -0,0 +1,88 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___FUNCTIONAL_PERFECT_FORWARD_H
11#define _LIBCPP___FUNCTIONAL_PERFECT_FORWARD_H
12
13#include <__config>
14#include <tuple>
15#include <type_traits>
16#include <utility>
17
18#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
19#pragma GCC system_header
20#endif
21
22_LIBCPP_BEGIN_NAMESPACE_STD
23
24#if _LIBCPP_STD_VER > 14
25
26template<class _Op, class _Tuple,
27 class _Idxs = typename __make_tuple_indices<tuple_size<_Tuple>::value>::type>
28struct __perfect_forward_impl;
29
30template<class _Op, class... _Bound, size_t... _Idxs>
31struct __perfect_forward_impl<_Op, __tuple_types<_Bound...>, __tuple_indices<_Idxs...>>
32{
33 tuple<_Bound...> __bound_;
34
35 template<class... _Args>
36 _LIBCPP_INLINE_VISIBILITY constexpr auto operator()(_Args&&... __args) &
37 noexcept(noexcept(_Op::__call(_VSTD::get<_Idxs>(__bound_)..., _VSTD::forward<_Args>(__args)...)))
38 -> decltype( _Op::__call(_VSTD::get<_Idxs>(__bound_)..., _VSTD::forward<_Args>(__args)...))
39 {return _Op::__call(_VSTD::get<_Idxs>(__bound_)..., _VSTD::forward<_Args>(__args)...);}
40
41 template<class... _Args>
42 _LIBCPP_INLINE_VISIBILITY constexpr auto operator()(_Args&&... __args) const&
43 noexcept(noexcept(_Op::__call(_VSTD::get<_Idxs>(__bound_)..., _VSTD::forward<_Args>(__args)...)))
44 -> decltype( _Op::__call(_VSTD::get<_Idxs>(__bound_)..., _VSTD::forward<_Args>(__args)...))
45 {return _Op::__call(_VSTD::get<_Idxs>(__bound_)..., _VSTD::forward<_Args>(__args)...);}
46
47 template<class... _Args>
48 _LIBCPP_INLINE_VISIBILITY constexpr auto operator()(_Args&&... __args) &&
49 noexcept(noexcept(_Op::__call(_VSTD::get<_Idxs>(_VSTD::move(__bound_))...,
50 _VSTD::forward<_Args>(__args)...)))
51 -> decltype( _Op::__call(_VSTD::get<_Idxs>(_VSTD::move(__bound_))...,
52 _VSTD::forward<_Args>(__args)...))
53 {return _Op::__call(_VSTD::get<_Idxs>(_VSTD::move(__bound_))...,
54 _VSTD::forward<_Args>(__args)...);}
55
56 template<class... _Args>
57 _LIBCPP_INLINE_VISIBILITY constexpr auto operator()(_Args&&... __args) const&&
58 noexcept(noexcept(_Op::__call(_VSTD::get<_Idxs>(_VSTD::move(__bound_))...,
59 _VSTD::forward<_Args>(__args)...)))
60 -> decltype( _Op::__call(_VSTD::get<_Idxs>(_VSTD::move(__bound_))...,
61 _VSTD::forward<_Args>(__args)...))
62 {return _Op::__call(_VSTD::get<_Idxs>(_VSTD::move(__bound_))...,
63 _VSTD::forward<_Args>(__args)...);}
64
65 template<class _Fn = typename tuple_element<0, tuple<_Bound...>>::type,
66 class = _EnableIf<is_copy_constructible_v<_Fn>>>
67 constexpr __perfect_forward_impl(__perfect_forward_impl const& __other)
68 : __bound_(__other.__bound_) {}
69
70 template<class _Fn = typename tuple_element<0, tuple<_Bound...>>::type,
71 class = _EnableIf<is_move_constructible_v<_Fn>>>
72 constexpr __perfect_forward_impl(__perfect_forward_impl && __other)
73 : __bound_(_VSTD::move(__other.__bound_)) {}
74
75 template<class... _BoundArgs>
76 explicit constexpr __perfect_forward_impl(_BoundArgs&&... __bound) :
77 __bound_(_VSTD::forward<_BoundArgs>(__bound)...) { }
78};
79
80template<class _Op, class... _Args>
81using __perfect_forward =
82 __perfect_forward_impl<_Op, __tuple_types<decay_t<_Args>...>>;
83
84#endif // _LIBCPP_STD_VER > 14
85
86_LIBCPP_END_NAMESPACE_STD
87
88#endif // _LIBCPP___FUNCTIONAL_PERFECT_FORWARD_H
lib/libcxx/include/__functional/pointer_to_binary_function.h created+46
......@@ -0,0 +1,46 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___FUNCTIONAL_POINTER_TO_BINARY_FUNCTION_H
11#define _LIBCPP___FUNCTIONAL_POINTER_TO_BINARY_FUNCTION_H
12
13#include <__config>
14#include <__functional/binary_function.h>
15
16#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
17#pragma GCC system_header
18#endif
19
20_LIBCPP_BEGIN_NAMESPACE_STD
21
22#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS)
23
24template <class _Arg1, class _Arg2, class _Result>
25class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 pointer_to_binary_function
26 : public binary_function<_Arg1, _Arg2, _Result>
27{
28 _Result (*__f_)(_Arg1, _Arg2);
29public:
30 _LIBCPP_INLINE_VISIBILITY explicit pointer_to_binary_function(_Result (*__f)(_Arg1, _Arg2))
31 : __f_(__f) {}
32 _LIBCPP_INLINE_VISIBILITY _Result operator()(_Arg1 __x, _Arg2 __y) const
33 {return __f_(__x, __y);}
34};
35
36template <class _Arg1, class _Arg2, class _Result>
37_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY
38pointer_to_binary_function<_Arg1,_Arg2,_Result>
39ptr_fun(_Result (*__f)(_Arg1,_Arg2))
40 {return pointer_to_binary_function<_Arg1,_Arg2,_Result>(__f);}
41
42#endif
43
44_LIBCPP_END_NAMESPACE_STD
45
46#endif // _LIBCPP___FUNCTIONAL_POINTER_TO_BINARY_FUNCTION_H
lib/libcxx/include/__functional/pointer_to_unary_function.h created+46
......@@ -0,0 +1,46 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___FUNCTIONAL_POINTER_TO_UNARY_FUNCTION_H
11#define _LIBCPP___FUNCTIONAL_POINTER_TO_UNARY_FUNCTION_H
12
13#include <__config>
14#include <__functional/unary_function.h>
15
16#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
17#pragma GCC system_header
18#endif
19
20_LIBCPP_BEGIN_NAMESPACE_STD
21
22#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS)
23
24template <class _Arg, class _Result>
25class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 pointer_to_unary_function
26 : public unary_function<_Arg, _Result>
27{
28 _Result (*__f_)(_Arg);
29public:
30 _LIBCPP_INLINE_VISIBILITY explicit pointer_to_unary_function(_Result (*__f)(_Arg))
31 : __f_(__f) {}
32 _LIBCPP_INLINE_VISIBILITY _Result operator()(_Arg __x) const
33 {return __f_(__x);}
34};
35
36template <class _Arg, class _Result>
37_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY
38pointer_to_unary_function<_Arg,_Result>
39ptr_fun(_Result (*__f)(_Arg))
40 {return pointer_to_unary_function<_Arg,_Result>(__f);}
41
42#endif // _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS)
43
44_LIBCPP_END_NAMESPACE_STD
45
46#endif // _LIBCPP___FUNCTIONAL_POINTER_TO_UNARY_FUNCTION_H
lib/libcxx/include/__functional/ranges_operations.h created+97
......@@ -0,0 +1,97 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___FUNCTIONAL_RANGES_OPERATIONS_H
11#define _LIBCPP___FUNCTIONAL_RANGES_OPERATIONS_H
12
13#include <__config>
14#include <concepts>
15#include <utility>
16
17#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
18#pragma GCC system_header
19#endif
20
21_LIBCPP_BEGIN_NAMESPACE_STD
22
23#if !defined(_LIBCPP_HAS_NO_RANGES)
24namespace ranges {
25
26struct equal_to {
27 template <class _Tp, class _Up>
28 requires equality_comparable_with<_Tp, _Up>
29 [[nodiscard]] constexpr bool operator()(_Tp &&__t, _Up &&__u) const
30 noexcept(noexcept(bool(_VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u)))) {
31 return _VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u);
32 }
33
34 using is_transparent = void;
35};
36
37struct not_equal_to {
38 template <class _Tp, class _Up>
39 requires equality_comparable_with<_Tp, _Up>
40 [[nodiscard]] constexpr bool operator()(_Tp &&__t, _Up &&__u) const
41 noexcept(noexcept(bool(!(_VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u))))) {
42 return !(_VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u));
43 }
44
45 using is_transparent = void;
46};
47
48struct less {
49 template <class _Tp, class _Up>
50 requires totally_ordered_with<_Tp, _Up>
51 [[nodiscard]] constexpr bool operator()(_Tp &&__t, _Up &&__u) const
52 noexcept(noexcept(bool(_VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u)))) {
53 return _VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u);
54 }
55
56 using is_transparent = void;
57};
58
59struct less_equal {
60 template <class _Tp, class _Up>
61 requires totally_ordered_with<_Tp, _Up>
62 [[nodiscard]] constexpr bool operator()(_Tp &&__t, _Up &&__u) const
63 noexcept(noexcept(bool(!(_VSTD::forward<_Up>(__u) < _VSTD::forward<_Tp>(__t))))) {
64 return !(_VSTD::forward<_Up>(__u) < _VSTD::forward<_Tp>(__t));
65 }
66
67 using is_transparent = void;
68};
69
70struct greater {
71 template <class _Tp, class _Up>
72 requires totally_ordered_with<_Tp, _Up>
73 [[nodiscard]] constexpr bool operator()(_Tp &&__t, _Up &&__u) const
74 noexcept(noexcept(bool(_VSTD::forward<_Up>(__u) < _VSTD::forward<_Tp>(__t)))) {
75 return _VSTD::forward<_Up>(__u) < _VSTD::forward<_Tp>(__t);
76 }
77
78 using is_transparent = void;
79};
80
81struct greater_equal {
82 template <class _Tp, class _Up>
83 requires totally_ordered_with<_Tp, _Up>
84 [[nodiscard]] constexpr bool operator()(_Tp &&__t, _Up &&__u) const
85 noexcept(noexcept(bool(!(_VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u))))) {
86 return !(_VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u));
87 }
88
89 using is_transparent = void;
90};
91
92} // namespace ranges
93#endif // !defined(_LIBCPP_HAS_NO_RANGES)
94
95_LIBCPP_END_NAMESPACE_STD
96
97#endif // _LIBCPP___FUNCTIONAL_RANGES_OPERATIONS_H
lib/libcxx/include/__functional/reference_wrapper.h created+223
......@@ -0,0 +1,223 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___FUNCTIONAL_REFERENCE_WRAPPER_H
11#define _LIBCPP___FUNCTIONAL_REFERENCE_WRAPPER_H
12
13#include <__config>
14#include <__functional/weak_result_type.h>
15#include <__memory/addressof.h>
16#include <__utility/forward.h>
17#include <type_traits>
18
19#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
20#pragma GCC system_header
21#endif
22
23_LIBCPP_BEGIN_NAMESPACE_STD
24
25template <class _Tp>
26class _LIBCPP_TEMPLATE_VIS reference_wrapper
27#if _LIBCPP_STD_VER <= 17 || !defined(_LIBCPP_ABI_NO_BINDER_BASES)
28 : public __weak_result_type<_Tp>
29#endif
30{
31public:
32 // types
33 typedef _Tp type;
34private:
35 type* __f_;
36
37#ifndef _LIBCPP_CXX03_LANG
38 static void __fun(_Tp&) _NOEXCEPT;
39 static void __fun(_Tp&&) = delete;
40#endif
41
42public:
43 // construct/copy/destroy
44#ifdef _LIBCPP_CXX03_LANG
45 _LIBCPP_INLINE_VISIBILITY
46 reference_wrapper(type& __f) _NOEXCEPT
47 : __f_(_VSTD::addressof(__f)) {}
48#else
49 template <class _Up, class = _EnableIf<!__is_same_uncvref<_Up, reference_wrapper>::value, decltype(__fun(declval<_Up>())) >>
50 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
51 reference_wrapper(_Up&& __u) _NOEXCEPT_(noexcept(__fun(declval<_Up>()))) {
52 type& __f = static_cast<_Up&&>(__u);
53 __f_ = _VSTD::addressof(__f);
54 }
55#endif
56
57 // access
58 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
59 operator type&() const _NOEXCEPT {return *__f_;}
60 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
61 type& get() const _NOEXCEPT {return *__f_;}
62
63#ifndef _LIBCPP_CXX03_LANG
64 // invoke
65 template <class... _ArgTypes>
66 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
67 typename __invoke_of<type&, _ArgTypes...>::type
68 operator() (_ArgTypes&&... __args) const {
69 return _VSTD::__invoke(get(), _VSTD::forward<_ArgTypes>(__args)...);
70 }
71#else
72
73 _LIBCPP_INLINE_VISIBILITY
74 typename __invoke_return<type>::type
75 operator() () const {
76 return _VSTD::__invoke(get());
77 }
78
79 template <class _A0>
80 _LIBCPP_INLINE_VISIBILITY
81 typename __invoke_return0<type, _A0>::type
82 operator() (_A0& __a0) const {
83 return _VSTD::__invoke(get(), __a0);
84 }
85
86 template <class _A0>
87 _LIBCPP_INLINE_VISIBILITY
88 typename __invoke_return0<type, _A0 const>::type
89 operator() (_A0 const& __a0) const {
90 return _VSTD::__invoke(get(), __a0);
91 }
92
93 template <class _A0, class _A1>
94 _LIBCPP_INLINE_VISIBILITY
95 typename __invoke_return1<type, _A0, _A1>::type
96 operator() (_A0& __a0, _A1& __a1) const {
97 return _VSTD::__invoke(get(), __a0, __a1);
98 }
99
100 template <class _A0, class _A1>
101 _LIBCPP_INLINE_VISIBILITY
102 typename __invoke_return1<type, _A0 const, _A1>::type
103 operator() (_A0 const& __a0, _A1& __a1) const {
104 return _VSTD::__invoke(get(), __a0, __a1);
105 }
106
107 template <class _A0, class _A1>
108 _LIBCPP_INLINE_VISIBILITY
109 typename __invoke_return1<type, _A0, _A1 const>::type
110 operator() (_A0& __a0, _A1 const& __a1) const {
111 return _VSTD::__invoke(get(), __a0, __a1);
112 }
113
114 template <class _A0, class _A1>
115 _LIBCPP_INLINE_VISIBILITY
116 typename __invoke_return1<type, _A0 const, _A1 const>::type
117 operator() (_A0 const& __a0, _A1 const& __a1) const {
118 return _VSTD::__invoke(get(), __a0, __a1);
119 }
120
121 template <class _A0, class _A1, class _A2>
122 _LIBCPP_INLINE_VISIBILITY
123 typename __invoke_return2<type, _A0, _A1, _A2>::type
124 operator() (_A0& __a0, _A1& __a1, _A2& __a2) const {
125 return _VSTD::__invoke(get(), __a0, __a1, __a2);
126 }
127
128 template <class _A0, class _A1, class _A2>
129 _LIBCPP_INLINE_VISIBILITY
130 typename __invoke_return2<type, _A0 const, _A1, _A2>::type
131 operator() (_A0 const& __a0, _A1& __a1, _A2& __a2) const {
132 return _VSTD::__invoke(get(), __a0, __a1, __a2);
133 }
134
135 template <class _A0, class _A1, class _A2>
136 _LIBCPP_INLINE_VISIBILITY
137 typename __invoke_return2<type, _A0, _A1 const, _A2>::type
138 operator() (_A0& __a0, _A1 const& __a1, _A2& __a2) const {
139 return _VSTD::__invoke(get(), __a0, __a1, __a2);
140 }
141
142 template <class _A0, class _A1, class _A2>
143 _LIBCPP_INLINE_VISIBILITY
144 typename __invoke_return2<type, _A0, _A1, _A2 const>::type
145 operator() (_A0& __a0, _A1& __a1, _A2 const& __a2) const {
146 return _VSTD::__invoke(get(), __a0, __a1, __a2);
147 }
148
149 template <class _A0, class _A1, class _A2>
150 _LIBCPP_INLINE_VISIBILITY
151 typename __invoke_return2<type, _A0 const, _A1 const, _A2>::type
152 operator() (_A0 const& __a0, _A1 const& __a1, _A2& __a2) const {
153 return _VSTD::__invoke(get(), __a0, __a1, __a2);
154 }
155
156 template <class _A0, class _A1, class _A2>
157 _LIBCPP_INLINE_VISIBILITY
158 typename __invoke_return2<type, _A0 const, _A1, _A2 const>::type
159 operator() (_A0 const& __a0, _A1& __a1, _A2 const& __a2) const {
160 return _VSTD::__invoke(get(), __a0, __a1, __a2);
161 }
162
163 template <class _A0, class _A1, class _A2>
164 _LIBCPP_INLINE_VISIBILITY
165 typename __invoke_return2<type, _A0, _A1 const, _A2 const>::type
166 operator() (_A0& __a0, _A1 const& __a1, _A2 const& __a2) const {
167 return _VSTD::__invoke(get(), __a0, __a1, __a2);
168 }
169
170 template <class _A0, class _A1, class _A2>
171 _LIBCPP_INLINE_VISIBILITY
172 typename __invoke_return2<type, _A0 const, _A1 const, _A2 const>::type
173 operator() (_A0 const& __a0, _A1 const& __a1, _A2 const& __a2) const {
174 return _VSTD::__invoke(get(), __a0, __a1, __a2);
175 }
176#endif // _LIBCPP_CXX03_LANG
177};
178
179#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
180template <class _Tp>
181reference_wrapper(_Tp&) -> reference_wrapper<_Tp>;
182#endif
183
184template <class _Tp>
185inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
186reference_wrapper<_Tp>
187ref(_Tp& __t) _NOEXCEPT
188{
189 return reference_wrapper<_Tp>(__t);
190}
191
192template <class _Tp>
193inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
194reference_wrapper<_Tp>
195ref(reference_wrapper<_Tp> __t) _NOEXCEPT
196{
197 return _VSTD::ref(__t.get());
198}
199
200template <class _Tp>
201inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
202reference_wrapper<const _Tp>
203cref(const _Tp& __t) _NOEXCEPT
204{
205 return reference_wrapper<const _Tp>(__t);
206}
207
208template <class _Tp>
209inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
210reference_wrapper<const _Tp>
211cref(reference_wrapper<_Tp> __t) _NOEXCEPT
212{
213 return _VSTD::cref(__t.get());
214}
215
216#ifndef _LIBCPP_CXX03_LANG
217template <class _Tp> void ref(const _Tp&&) = delete;
218template <class _Tp> void cref(const _Tp&&) = delete;
219#endif
220
221_LIBCPP_END_NAMESPACE_STD
222
223#endif // _LIBCPP___FUNCTIONAL_REFERENCE_WRAPPER_H
lib/libcxx/include/__functional/unary_function.h created+34
......@@ -0,0 +1,34 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___FUNCTIONAL_UNARY_FUNCTION_H
10#define _LIBCPP___FUNCTIONAL_UNARY_FUNCTION_H
11
12#include <__config>
13
14#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
15#pragma GCC system_header
16#endif
17
18_LIBCPP_PUSH_MACROS
19#include <__undef_macros>
20
21_LIBCPP_BEGIN_NAMESPACE_STD
22
23template <class _Arg, class _Result>
24struct _LIBCPP_TEMPLATE_VIS unary_function
25{
26 typedef _Arg argument_type;
27 typedef _Result result_type;
28};
29
30_LIBCPP_END_NAMESPACE_STD
31
32_LIBCPP_POP_MACROS
33
34#endif // _LIBCPP___FUNCTIONAL_UNARY_FUNCTION_H
lib/libcxx/include/__functional/unary_negate.h created+47
......@@ -0,0 +1,47 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___FUNCTIONAL_UNARY_NEGATE_H
11#define _LIBCPP___FUNCTIONAL_UNARY_NEGATE_H
12
13#include <__config>
14#include <__functional/unary_function.h>
15
16#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
17#pragma GCC system_header
18#endif
19
20_LIBCPP_BEGIN_NAMESPACE_STD
21
22#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_NEGATORS)
23
24template <class _Predicate>
25class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 unary_negate
26 : public unary_function<typename _Predicate::argument_type, bool>
27{
28 _Predicate __pred_;
29public:
30 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
31 explicit unary_negate(const _Predicate& __pred)
32 : __pred_(__pred) {}
33 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
34 bool operator()(const typename _Predicate::argument_type& __x) const
35 {return !__pred_(__x);}
36};
37
38template <class _Predicate>
39_LIBCPP_DEPRECATED_IN_CXX17 inline _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
40unary_negate<_Predicate>
41not1(const _Predicate& __pred) {return unary_negate<_Predicate>(__pred);}
42
43#endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_NEGATORS)
44
45_LIBCPP_END_NAMESPACE_STD
46
47#endif // _LIBCPP___FUNCTIONAL_UNARY_NEGATE_H
lib/libcxx/include/__functional/unwrap_ref.h created+62
......@@ -0,0 +1,62 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___FUNCTIONAL_UNWRAP_REF_H
10#define _LIBCPP___FUNCTIONAL_UNWRAP_REF_H
11
12#include <__config>
13
14#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
15#pragma GCC system_header
16#endif
17
18_LIBCPP_PUSH_MACROS
19#include <__undef_macros>
20
21_LIBCPP_BEGIN_NAMESPACE_STD
22
23template <class _Tp>
24struct __unwrap_reference { typedef _LIBCPP_NODEBUG_TYPE _Tp type; };
25
26template <class _Tp>
27class reference_wrapper;
28
29template <class _Tp>
30struct __unwrap_reference<reference_wrapper<_Tp> > { typedef _LIBCPP_NODEBUG_TYPE _Tp& type; };
31
32template <class _Tp>
33struct decay;
34
35#if _LIBCPP_STD_VER > 17
36template <class _Tp>
37struct unwrap_reference : __unwrap_reference<_Tp> { };
38
39template <class _Tp>
40using unwrap_reference_t = typename unwrap_reference<_Tp>::type;
41
42template <class _Tp>
43struct unwrap_ref_decay : unwrap_reference<typename decay<_Tp>::type> { };
44
45template <class _Tp>
46using unwrap_ref_decay_t = typename unwrap_ref_decay<_Tp>::type;
47#endif // > C++17
48
49template <class _Tp>
50struct __unwrap_ref_decay
51#if _LIBCPP_STD_VER > 17
52 : unwrap_ref_decay<_Tp>
53#else
54 : __unwrap_reference<typename decay<_Tp>::type>
55#endif
56{ };
57
58_LIBCPP_END_NAMESPACE_STD
59
60_LIBCPP_POP_MACROS
61
62#endif // _LIBCPP___FUNCTIONAL_UNWRAP_REF_H
lib/libcxx/include/__functional/weak_result_type.h created+481
......@@ -0,0 +1,481 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___FUNCTIONAL_WEAK_RESULT_TYPE_H
11#define _LIBCPP___FUNCTIONAL_WEAK_RESULT_TYPE_H
12
13#include <__config>
14#include <__functional/binary_function.h>
15#include <__functional/unary_function.h>
16#include <type_traits>
17
18#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
19#pragma GCC system_header
20#endif
21
22_LIBCPP_BEGIN_NAMESPACE_STD
23
24template <class _Tp>
25struct __has_result_type
26{
27private:
28 struct __two {char __lx; char __lxx;};
29 template <class _Up> static __two __test(...);
30 template <class _Up> static char __test(typename _Up::result_type* = 0);
31public:
32 static const bool value = sizeof(__test<_Tp>(0)) == 1;
33};
34
35// __weak_result_type
36
37template <class _Tp>
38struct __derives_from_unary_function
39{
40private:
41 struct __two {char __lx; char __lxx;};
42 static __two __test(...);
43 template <class _Ap, class _Rp>
44 static unary_function<_Ap, _Rp>
45 __test(const volatile unary_function<_Ap, _Rp>*);
46public:
47 static const bool value = !is_same<decltype(__test((_Tp*)0)), __two>::value;
48 typedef decltype(__test((_Tp*)0)) type;
49};
50
51template <class _Tp>
52struct __derives_from_binary_function
53{
54private:
55 struct __two {char __lx; char __lxx;};
56 static __two __test(...);
57 template <class _A1, class _A2, class _Rp>
58 static binary_function<_A1, _A2, _Rp>
59 __test(const volatile binary_function<_A1, _A2, _Rp>*);
60public:
61 static const bool value = !is_same<decltype(__test((_Tp*)0)), __two>::value;
62 typedef decltype(__test((_Tp*)0)) type;
63};
64
65template <class _Tp, bool = __derives_from_unary_function<_Tp>::value>
66struct __maybe_derive_from_unary_function // bool is true
67 : public __derives_from_unary_function<_Tp>::type
68{
69};
70
71template <class _Tp>
72struct __maybe_derive_from_unary_function<_Tp, false>
73{
74};
75
76template <class _Tp, bool = __derives_from_binary_function<_Tp>::value>
77struct __maybe_derive_from_binary_function // bool is true
78 : public __derives_from_binary_function<_Tp>::type
79{
80};
81
82template <class _Tp>
83struct __maybe_derive_from_binary_function<_Tp, false>
84{
85};
86
87template <class _Tp, bool = __has_result_type<_Tp>::value>
88struct __weak_result_type_imp // bool is true
89 : public __maybe_derive_from_unary_function<_Tp>,
90 public __maybe_derive_from_binary_function<_Tp>
91{
92 typedef _LIBCPP_NODEBUG_TYPE typename _Tp::result_type result_type;
93};
94
95template <class _Tp>
96struct __weak_result_type_imp<_Tp, false>
97 : public __maybe_derive_from_unary_function<_Tp>,
98 public __maybe_derive_from_binary_function<_Tp>
99{
100};
101
102template <class _Tp>
103struct __weak_result_type
104 : public __weak_result_type_imp<_Tp>
105{
106};
107
108// 0 argument case
109
110template <class _Rp>
111struct __weak_result_type<_Rp ()>
112{
113 typedef _LIBCPP_NODEBUG_TYPE _Rp result_type;
114};
115
116template <class _Rp>
117struct __weak_result_type<_Rp (&)()>
118{
119 typedef _LIBCPP_NODEBUG_TYPE _Rp result_type;
120};
121
122template <class _Rp>
123struct __weak_result_type<_Rp (*)()>
124{
125 typedef _LIBCPP_NODEBUG_TYPE _Rp result_type;
126};
127
128// 1 argument case
129
130template <class _Rp, class _A1>
131struct __weak_result_type<_Rp (_A1)>
132 : public unary_function<_A1, _Rp>
133{
134};
135
136template <class _Rp, class _A1>
137struct __weak_result_type<_Rp (&)(_A1)>
138 : public unary_function<_A1, _Rp>
139{
140};
141
142template <class _Rp, class _A1>
143struct __weak_result_type<_Rp (*)(_A1)>
144 : public unary_function<_A1, _Rp>
145{
146};
147
148template <class _Rp, class _Cp>
149struct __weak_result_type<_Rp (_Cp::*)()>
150 : public unary_function<_Cp*, _Rp>
151{
152};
153
154template <class _Rp, class _Cp>
155struct __weak_result_type<_Rp (_Cp::*)() const>
156 : public unary_function<const _Cp*, _Rp>
157{
158};
159
160template <class _Rp, class _Cp>
161struct __weak_result_type<_Rp (_Cp::*)() volatile>
162 : public unary_function<volatile _Cp*, _Rp>
163{
164};
165
166template <class _Rp, class _Cp>
167struct __weak_result_type<_Rp (_Cp::*)() const volatile>
168 : public unary_function<const volatile _Cp*, _Rp>
169{
170};
171
172// 2 argument case
173
174template <class _Rp, class _A1, class _A2>
175struct __weak_result_type<_Rp (_A1, _A2)>
176 : public binary_function<_A1, _A2, _Rp>
177{
178};
179
180template <class _Rp, class _A1, class _A2>
181struct __weak_result_type<_Rp (*)(_A1, _A2)>
182 : public binary_function<_A1, _A2, _Rp>
183{
184};
185
186template <class _Rp, class _A1, class _A2>
187struct __weak_result_type<_Rp (&)(_A1, _A2)>
188 : public binary_function<_A1, _A2, _Rp>
189{
190};
191
192template <class _Rp, class _Cp, class _A1>
193struct __weak_result_type<_Rp (_Cp::*)(_A1)>
194 : public binary_function<_Cp*, _A1, _Rp>
195{
196};
197
198template <class _Rp, class _Cp, class _A1>
199struct __weak_result_type<_Rp (_Cp::*)(_A1) const>
200 : public binary_function<const _Cp*, _A1, _Rp>
201{
202};
203
204template <class _Rp, class _Cp, class _A1>
205struct __weak_result_type<_Rp (_Cp::*)(_A1) volatile>
206 : public binary_function<volatile _Cp*, _A1, _Rp>
207{
208};
209
210template <class _Rp, class _Cp, class _A1>
211struct __weak_result_type<_Rp (_Cp::*)(_A1) const volatile>
212 : public binary_function<const volatile _Cp*, _A1, _Rp>
213{
214};
215
216
217#ifndef _LIBCPP_CXX03_LANG
218// 3 or more arguments
219
220template <class _Rp, class _A1, class _A2, class _A3, class ..._A4>
221struct __weak_result_type<_Rp (_A1, _A2, _A3, _A4...)>
222{
223 typedef _Rp result_type;
224};
225
226template <class _Rp, class _A1, class _A2, class _A3, class ..._A4>
227struct __weak_result_type<_Rp (&)(_A1, _A2, _A3, _A4...)>
228{
229 typedef _Rp result_type;
230};
231
232template <class _Rp, class _A1, class _A2, class _A3, class ..._A4>
233struct __weak_result_type<_Rp (*)(_A1, _A2, _A3, _A4...)>
234{
235 typedef _Rp result_type;
236};
237
238template <class _Rp, class _Cp, class _A1, class _A2, class ..._A3>
239struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...)>
240{
241 typedef _Rp result_type;
242};
243
244template <class _Rp, class _Cp, class _A1, class _A2, class ..._A3>
245struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) const>
246{
247 typedef _Rp result_type;
248};
249
250template <class _Rp, class _Cp, class _A1, class _A2, class ..._A3>
251struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) volatile>
252{
253 typedef _Rp result_type;
254};
255
256template <class _Rp, class _Cp, class _A1, class _A2, class ..._A3>
257struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) const volatile>
258{
259 typedef _Rp result_type;
260};
261
262template <class _Tp, class ..._Args>
263struct __invoke_return
264{
265 typedef decltype(_VSTD::__invoke(declval<_Tp>(), declval<_Args>()...)) type;
266};
267
268#else // defined(_LIBCPP_CXX03_LANG)
269
270template <class _Ret, class _T1, bool _IsFunc, bool _IsBase>
271struct __enable_invoke_imp;
272
273template <class _Ret, class _T1>
274struct __enable_invoke_imp<_Ret, _T1, true, true> {
275 typedef _Ret _Bullet1;
276 typedef _Bullet1 type;
277};
278
279template <class _Ret, class _T1>
280struct __enable_invoke_imp<_Ret, _T1, true, false> {
281 typedef _Ret _Bullet2;
282 typedef _Bullet2 type;
283};
284
285template <class _Ret, class _T1>
286struct __enable_invoke_imp<_Ret, _T1, false, true> {
287 typedef typename add_lvalue_reference<
288 typename __apply_cv<_T1, _Ret>::type
289 >::type _Bullet3;
290 typedef _Bullet3 type;
291};
292
293template <class _Ret, class _T1>
294struct __enable_invoke_imp<_Ret, _T1, false, false> {
295 typedef typename add_lvalue_reference<
296 typename __apply_cv<decltype(*declval<_T1>()), _Ret>::type
297 >::type _Bullet4;
298 typedef _Bullet4 type;
299};
300
301template <class _Ret, class _T1>
302struct __enable_invoke_imp<_Ret, _T1*, false, false> {
303 typedef typename add_lvalue_reference<
304 typename __apply_cv<_T1, _Ret>::type
305 >::type _Bullet4;
306 typedef _Bullet4 type;
307};
308
309template <class _Fn, class _T1,
310 class _Traits = __member_pointer_traits<_Fn>,
311 class _Ret = typename _Traits::_ReturnType,
312 class _Class = typename _Traits::_ClassType>
313struct __enable_invoke : __enable_invoke_imp<
314 _Ret, _T1,
315 is_member_function_pointer<_Fn>::value,
316 is_base_of<_Class, typename remove_reference<_T1>::type>::value>
317{
318};
319
320__nat __invoke(__any, ...);
321
322// first bullet
323
324template <class _Fn, class _T1>
325inline _LIBCPP_INLINE_VISIBILITY
326typename __enable_invoke<_Fn, _T1>::_Bullet1
327__invoke(_Fn __f, _T1& __t1) {
328 return (__t1.*__f)();
329}
330
331template <class _Fn, class _T1, class _A0>
332inline _LIBCPP_INLINE_VISIBILITY
333typename __enable_invoke<_Fn, _T1>::_Bullet1
334__invoke(_Fn __f, _T1& __t1, _A0& __a0) {
335 return (__t1.*__f)(__a0);
336}
337
338template <class _Fn, class _T1, class _A0, class _A1>
339inline _LIBCPP_INLINE_VISIBILITY
340typename __enable_invoke<_Fn, _T1>::_Bullet1
341__invoke(_Fn __f, _T1& __t1, _A0& __a0, _A1& __a1) {
342 return (__t1.*__f)(__a0, __a1);
343}
344
345template <class _Fn, class _T1, class _A0, class _A1, class _A2>
346inline _LIBCPP_INLINE_VISIBILITY
347typename __enable_invoke<_Fn, _T1>::_Bullet1
348__invoke(_Fn __f, _T1& __t1, _A0& __a0, _A1& __a1, _A2& __a2) {
349 return (__t1.*__f)(__a0, __a1, __a2);
350}
351
352template <class _Fn, class _T1>
353inline _LIBCPP_INLINE_VISIBILITY
354typename __enable_invoke<_Fn, _T1>::_Bullet2
355__invoke(_Fn __f, _T1& __t1) {
356 return ((*__t1).*__f)();
357}
358
359template <class _Fn, class _T1, class _A0>
360inline _LIBCPP_INLINE_VISIBILITY
361typename __enable_invoke<_Fn, _T1>::_Bullet2
362__invoke(_Fn __f, _T1& __t1, _A0& __a0) {
363 return ((*__t1).*__f)(__a0);
364}
365
366template <class _Fn, class _T1, class _A0, class _A1>
367inline _LIBCPP_INLINE_VISIBILITY
368typename __enable_invoke<_Fn, _T1>::_Bullet2
369__invoke(_Fn __f, _T1& __t1, _A0& __a0, _A1& __a1) {
370 return ((*__t1).*__f)(__a0, __a1);
371}
372
373template <class _Fn, class _T1, class _A0, class _A1, class _A2>
374inline _LIBCPP_INLINE_VISIBILITY
375typename __enable_invoke<_Fn, _T1>::_Bullet2
376__invoke(_Fn __f, _T1& __t1, _A0& __a0, _A1& __a1, _A2& __a2) {
377 return ((*__t1).*__f)(__a0, __a1, __a2);
378}
379
380template <class _Fn, class _T1>
381inline _LIBCPP_INLINE_VISIBILITY
382typename __enable_invoke<_Fn, _T1>::_Bullet3
383__invoke(_Fn __f, _T1& __t1) {
384 return __t1.*__f;
385}
386
387template <class _Fn, class _T1>
388inline _LIBCPP_INLINE_VISIBILITY
389typename __enable_invoke<_Fn, _T1>::_Bullet4
390__invoke(_Fn __f, _T1& __t1) {
391 return (*__t1).*__f;
392}
393
394// fifth bullet
395
396template <class _Fp>
397inline _LIBCPP_INLINE_VISIBILITY
398decltype(declval<_Fp&>()())
399__invoke(_Fp& __f)
400{
401 return __f();
402}
403
404template <class _Fp, class _A0>
405inline _LIBCPP_INLINE_VISIBILITY
406decltype(declval<_Fp&>()(declval<_A0&>()))
407__invoke(_Fp& __f, _A0& __a0)
408{
409 return __f(__a0);
410}
411
412template <class _Fp, class _A0, class _A1>
413inline _LIBCPP_INLINE_VISIBILITY
414decltype(declval<_Fp&>()(declval<_A0&>(), declval<_A1&>()))
415__invoke(_Fp& __f, _A0& __a0, _A1& __a1)
416{
417 return __f(__a0, __a1);
418}
419
420template <class _Fp, class _A0, class _A1, class _A2>
421inline _LIBCPP_INLINE_VISIBILITY
422decltype(declval<_Fp&>()(declval<_A0&>(), declval<_A1&>(), declval<_A2&>()))
423__invoke(_Fp& __f, _A0& __a0, _A1& __a1, _A2& __a2)
424{
425 return __f(__a0, __a1, __a2);
426}
427
428template <class _Fp, bool = __has_result_type<__weak_result_type<_Fp> >::value>
429struct __invoke_return
430{
431 typedef typename __weak_result_type<_Fp>::result_type type;
432};
433
434template <class _Fp>
435struct __invoke_return<_Fp, false>
436{
437 typedef decltype(_VSTD::__invoke(declval<_Fp&>())) type;
438};
439
440template <class _Tp, class _A0>
441struct __invoke_return0
442{
443 typedef decltype(_VSTD::__invoke(declval<_Tp&>(), declval<_A0&>())) type;
444};
445
446template <class _Rp, class _Tp, class _A0>
447struct __invoke_return0<_Rp _Tp::*, _A0>
448{
449 typedef typename __enable_invoke<_Rp _Tp::*, _A0>::type type;
450};
451
452template <class _Tp, class _A0, class _A1>
453struct __invoke_return1
454{
455 typedef decltype(_VSTD::__invoke(declval<_Tp&>(), declval<_A0&>(),
456 declval<_A1&>())) type;
457};
458
459template <class _Rp, class _Class, class _A0, class _A1>
460struct __invoke_return1<_Rp _Class::*, _A0, _A1> {
461 typedef typename __enable_invoke<_Rp _Class::*, _A0>::type type;
462};
463
464template <class _Tp, class _A0, class _A1, class _A2>
465struct __invoke_return2
466{
467 typedef decltype(_VSTD::__invoke(declval<_Tp&>(), declval<_A0&>(),
468 declval<_A1&>(),
469 declval<_A2&>())) type;
470};
471
472template <class _Ret, class _Class, class _A0, class _A1, class _A2>
473struct __invoke_return2<_Ret _Class::*, _A0, _A1, _A2> {
474 typedef typename __enable_invoke<_Ret _Class::*, _A0>::type type;
475};
476
477#endif // !defined(_LIBCPP_CXX03_LANG)
478
479_LIBCPP_END_NAMESPACE_STD
480
481#endif // _LIBCPP___FUNCTIONAL_WEAK_RESULT_TYPE_H
lib/libcxx/include/__functional_03 deleted-1591
......@@ -1,1591 +0,0 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP_FUNCTIONAL_03
11#define _LIBCPP_FUNCTIONAL_03
12
13// manual variadic expansion for <functional>
14
15#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
16#pragma GCC system_header
17#endif
18
19namespace __function {
20
21template<class _Fp> class __base;
22
23template<class _Rp>
24class __base<_Rp()>
25{
26 __base(const __base&);
27 __base& operator=(const __base&);
28public:
29 __base() {}
30 virtual ~__base() {}
31 virtual __base* __clone() const = 0;
32 virtual void __clone(__base*) const = 0;
33 virtual void destroy() = 0;
34 virtual void destroy_deallocate() = 0;
35 virtual _Rp operator()() = 0;
36#ifndef _LIBCPP_NO_RTTI
37 virtual const void* target(const type_info&) const = 0;
38 virtual const std::type_info& target_type() const = 0;
39#endif // _LIBCPP_NO_RTTI
40};
41
42template<class _Rp, class _A0>
43class __base<_Rp(_A0)>
44{
45 __base(const __base&);
46 __base& operator=(const __base&);
47public:
48 __base() {}
49 virtual ~__base() {}
50 virtual __base* __clone() const = 0;
51 virtual void __clone(__base*) const = 0;
52 virtual void destroy() = 0;
53 virtual void destroy_deallocate() = 0;
54 virtual _Rp operator()(_A0) = 0;
55#ifndef _LIBCPP_NO_RTTI
56 virtual const void* target(const type_info&) const = 0;
57 virtual const std::type_info& target_type() const = 0;
58#endif // _LIBCPP_NO_RTTI
59};
60
61template<class _Rp, class _A0, class _A1>
62class __base<_Rp(_A0, _A1)>
63{
64 __base(const __base&);
65 __base& operator=(const __base&);
66public:
67 __base() {}
68 virtual ~__base() {}
69 virtual __base* __clone() const = 0;
70 virtual void __clone(__base*) const = 0;
71 virtual void destroy() = 0;
72 virtual void destroy_deallocate() = 0;
73 virtual _Rp operator()(_A0, _A1) = 0;
74#ifndef _LIBCPP_NO_RTTI
75 virtual const void* target(const type_info&) const = 0;
76 virtual const std::type_info& target_type() const = 0;
77#endif // _LIBCPP_NO_RTTI
78};
79
80template<class _Rp, class _A0, class _A1, class _A2>
81class __base<_Rp(_A0, _A1, _A2)>
82{
83 __base(const __base&);
84 __base& operator=(const __base&);
85public:
86 __base() {}
87 virtual ~__base() {}
88 virtual __base* __clone() const = 0;
89 virtual void __clone(__base*) const = 0;
90 virtual void destroy() = 0;
91 virtual void destroy_deallocate() = 0;
92 virtual _Rp operator()(_A0, _A1, _A2) = 0;
93#ifndef _LIBCPP_NO_RTTI
94 virtual const void* target(const type_info&) const = 0;
95 virtual const std::type_info& target_type() const = 0;
96#endif // _LIBCPP_NO_RTTI
97};
98
99template<class _FD, class _Alloc, class _FB> class __func;
100
101template<class _Fp, class _Alloc, class _Rp>
102class __func<_Fp, _Alloc, _Rp()>
103 : public __base<_Rp()>
104{
105 __compressed_pair<_Fp, _Alloc> __f_;
106public:
107 explicit __func(_Fp __f) : __f_(_VSTD::move(__f), __default_init_tag()) {}
108 explicit __func(_Fp __f, _Alloc __a) : __f_(_VSTD::move(__f), _VSTD::move(__a)) {}
109 virtual __base<_Rp()>* __clone() const;
110 virtual void __clone(__base<_Rp()>*) const;
111 virtual void destroy();
112 virtual void destroy_deallocate();
113 virtual _Rp operator()();
114#ifndef _LIBCPP_NO_RTTI
115 virtual const void* target(const type_info&) const;
116 virtual const std::type_info& target_type() const;
117#endif // _LIBCPP_NO_RTTI
118};
119
120template<class _Fp, class _Alloc, class _Rp>
121__base<_Rp()>*
122__func<_Fp, _Alloc, _Rp()>::__clone() const
123{
124 typedef allocator_traits<_Alloc> __alloc_traits;
125 typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
126 _Ap __a(__f_.second());
127 typedef __allocator_destructor<_Ap> _Dp;
128 unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
129 ::new ((void*)__hold.get()) __func(__f_.first(), _Alloc(__a));
130 return __hold.release();
131}
132
133template<class _Fp, class _Alloc, class _Rp>
134void
135__func<_Fp, _Alloc, _Rp()>::__clone(__base<_Rp()>* __p) const
136{
137 ::new ((void*)__p) __func(__f_.first(), __f_.second());
138}
139
140template<class _Fp, class _Alloc, class _Rp>
141void
142__func<_Fp, _Alloc, _Rp()>::destroy()
143{
144 __f_.~__compressed_pair<_Fp, _Alloc>();
145}
146
147template<class _Fp, class _Alloc, class _Rp>
148void
149__func<_Fp, _Alloc, _Rp()>::destroy_deallocate()
150{
151 typedef allocator_traits<_Alloc> __alloc_traits;
152 typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
153 _Ap __a(__f_.second());
154 __f_.~__compressed_pair<_Fp, _Alloc>();
155 __a.deallocate(this, 1);
156}
157
158template<class _Fp, class _Alloc, class _Rp>
159_Rp
160__func<_Fp, _Alloc, _Rp()>::operator()()
161{
162 typedef __invoke_void_return_wrapper<_Rp> _Invoker;
163 return _Invoker::__call(__f_.first());
164}
165
166#ifndef _LIBCPP_NO_RTTI
167
168template<class _Fp, class _Alloc, class _Rp>
169const void*
170__func<_Fp, _Alloc, _Rp()>::target(const type_info& __ti) const
171{
172 if (__ti == typeid(_Fp))
173 return &__f_.first();
174 return (const void*)0;
175}
176
177template<class _Fp, class _Alloc, class _Rp>
178const std::type_info&
179__func<_Fp, _Alloc, _Rp()>::target_type() const
180{
181 return typeid(_Fp);
182}
183
184#endif // _LIBCPP_NO_RTTI
185
186template<class _Fp, class _Alloc, class _Rp, class _A0>
187class __func<_Fp, _Alloc, _Rp(_A0)>
188 : public __base<_Rp(_A0)>
189{
190 __compressed_pair<_Fp, _Alloc> __f_;
191public:
192 _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f) : __f_(_VSTD::move(__f), __default_init_tag()) {}
193 _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f, _Alloc __a)
194 : __f_(_VSTD::move(__f), _VSTD::move(__a)) {}
195 virtual __base<_Rp(_A0)>* __clone() const;
196 virtual void __clone(__base<_Rp(_A0)>*) const;
197 virtual void destroy();
198 virtual void destroy_deallocate();
199 virtual _Rp operator()(_A0);
200#ifndef _LIBCPP_NO_RTTI
201 virtual const void* target(const type_info&) const;
202 virtual const std::type_info& target_type() const;
203#endif // _LIBCPP_NO_RTTI
204};
205
206template<class _Fp, class _Alloc, class _Rp, class _A0>
207__base<_Rp(_A0)>*
208__func<_Fp, _Alloc, _Rp(_A0)>::__clone() const
209{
210 typedef allocator_traits<_Alloc> __alloc_traits;
211 typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
212 _Ap __a(__f_.second());
213 typedef __allocator_destructor<_Ap> _Dp;
214 unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
215 ::new ((void*)__hold.get()) __func(__f_.first(), _Alloc(__a));
216 return __hold.release();
217}
218
219template<class _Fp, class _Alloc, class _Rp, class _A0>
220void
221__func<_Fp, _Alloc, _Rp(_A0)>::__clone(__base<_Rp(_A0)>* __p) const
222{
223 ::new ((void*)__p) __func(__f_.first(), __f_.second());
224}
225
226template<class _Fp, class _Alloc, class _Rp, class _A0>
227void
228__func<_Fp, _Alloc, _Rp(_A0)>::destroy()
229{
230 __f_.~__compressed_pair<_Fp, _Alloc>();
231}
232
233template<class _Fp, class _Alloc, class _Rp, class _A0>
234void
235__func<_Fp, _Alloc, _Rp(_A0)>::destroy_deallocate()
236{
237 typedef allocator_traits<_Alloc> __alloc_traits;
238 typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
239 _Ap __a(__f_.second());
240 __f_.~__compressed_pair<_Fp, _Alloc>();
241 __a.deallocate(this, 1);
242}
243
244template<class _Fp, class _Alloc, class _Rp, class _A0>
245_Rp
246__func<_Fp, _Alloc, _Rp(_A0)>::operator()(_A0 __a0)
247{
248 typedef __invoke_void_return_wrapper<_Rp> _Invoker;
249 return _Invoker::__call(__f_.first(), __a0);
250}
251
252#ifndef _LIBCPP_NO_RTTI
253
254template<class _Fp, class _Alloc, class _Rp, class _A0>
255const void*
256__func<_Fp, _Alloc, _Rp(_A0)>::target(const type_info& __ti) const
257{
258 if (__ti == typeid(_Fp))
259 return &__f_.first();
260 return (const void*)0;
261}
262
263template<class _Fp, class _Alloc, class _Rp, class _A0>
264const std::type_info&
265__func<_Fp, _Alloc, _Rp(_A0)>::target_type() const
266{
267 return typeid(_Fp);
268}
269
270#endif // _LIBCPP_NO_RTTI
271
272template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
273class __func<_Fp, _Alloc, _Rp(_A0, _A1)>
274 : public __base<_Rp(_A0, _A1)>
275{
276 __compressed_pair<_Fp, _Alloc> __f_;
277public:
278 _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f) : __f_(_VSTD::move(__f), __default_init_tag()) {}
279 _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f, _Alloc __a)
280 : __f_(_VSTD::move(__f), _VSTD::move(__a)) {}
281 virtual __base<_Rp(_A0, _A1)>* __clone() const;
282 virtual void __clone(__base<_Rp(_A0, _A1)>*) const;
283 virtual void destroy();
284 virtual void destroy_deallocate();
285 virtual _Rp operator()(_A0, _A1);
286#ifndef _LIBCPP_NO_RTTI
287 virtual const void* target(const type_info&) const;
288 virtual const std::type_info& target_type() const;
289#endif // _LIBCPP_NO_RTTI
290};
291
292template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
293__base<_Rp(_A0, _A1)>*
294__func<_Fp, _Alloc, _Rp(_A0, _A1)>::__clone() const
295{
296 typedef allocator_traits<_Alloc> __alloc_traits;
297 typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
298 _Ap __a(__f_.second());
299 typedef __allocator_destructor<_Ap> _Dp;
300 unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
301 ::new ((void*)__hold.get()) __func(__f_.first(), _Alloc(__a));
302 return __hold.release();
303}
304
305template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
306void
307__func<_Fp, _Alloc, _Rp(_A0, _A1)>::__clone(__base<_Rp(_A0, _A1)>* __p) const
308{
309 ::new ((void*)__p) __func(__f_.first(), __f_.second());
310}
311
312template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
313void
314__func<_Fp, _Alloc, _Rp(_A0, _A1)>::destroy()
315{
316 __f_.~__compressed_pair<_Fp, _Alloc>();
317}
318
319template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
320void
321__func<_Fp, _Alloc, _Rp(_A0, _A1)>::destroy_deallocate()
322{
323 typedef allocator_traits<_Alloc> __alloc_traits;
324 typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
325 _Ap __a(__f_.second());
326 __f_.~__compressed_pair<_Fp, _Alloc>();
327 __a.deallocate(this, 1);
328}
329
330template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
331_Rp
332__func<_Fp, _Alloc, _Rp(_A0, _A1)>::operator()(_A0 __a0, _A1 __a1)
333{
334 typedef __invoke_void_return_wrapper<_Rp> _Invoker;
335 return _Invoker::__call(__f_.first(), __a0, __a1);
336}
337
338#ifndef _LIBCPP_NO_RTTI
339
340template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
341const void*
342__func<_Fp, _Alloc, _Rp(_A0, _A1)>::target(const type_info& __ti) const
343{
344 if (__ti == typeid(_Fp))
345 return &__f_.first();
346 return (const void*)0;
347}
348
349template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
350const std::type_info&
351__func<_Fp, _Alloc, _Rp(_A0, _A1)>::target_type() const
352{
353 return typeid(_Fp);
354}
355
356#endif // _LIBCPP_NO_RTTI
357
358template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
359class __func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>
360 : public __base<_Rp(_A0, _A1, _A2)>
361{
362 __compressed_pair<_Fp, _Alloc> __f_;
363public:
364 _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f) : __f_(_VSTD::move(__f), __default_init_tag()) {}
365 _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f, _Alloc __a)
366 : __f_(_VSTD::move(__f), _VSTD::move(__a)) {}
367 virtual __base<_Rp(_A0, _A1, _A2)>* __clone() const;
368 virtual void __clone(__base<_Rp(_A0, _A1, _A2)>*) const;
369 virtual void destroy();
370 virtual void destroy_deallocate();
371 virtual _Rp operator()(_A0, _A1, _A2);
372#ifndef _LIBCPP_NO_RTTI
373 virtual const void* target(const type_info&) const;
374 virtual const std::type_info& target_type() const;
375#endif // _LIBCPP_NO_RTTI
376};
377
378template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
379__base<_Rp(_A0, _A1, _A2)>*
380__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::__clone() const
381{
382 typedef allocator_traits<_Alloc> __alloc_traits;
383 typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
384 _Ap __a(__f_.second());
385 typedef __allocator_destructor<_Ap> _Dp;
386 unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
387 ::new ((void*)__hold.get()) __func(__f_.first(), _Alloc(__a));
388 return __hold.release();
389}
390
391template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
392void
393__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::__clone(__base<_Rp(_A0, _A1, _A2)>* __p) const
394{
395 ::new ((void*)__p) __func(__f_.first(), __f_.second());
396}
397
398template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
399void
400__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::destroy()
401{
402 __f_.~__compressed_pair<_Fp, _Alloc>();
403}
404
405template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
406void
407__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::destroy_deallocate()
408{
409 typedef allocator_traits<_Alloc> __alloc_traits;
410 typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
411 _Ap __a(__f_.second());
412 __f_.~__compressed_pair<_Fp, _Alloc>();
413 __a.deallocate(this, 1);
414}
415
416template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
417_Rp
418__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::operator()(_A0 __a0, _A1 __a1, _A2 __a2)
419{
420 typedef __invoke_void_return_wrapper<_Rp> _Invoker;
421 return _Invoker::__call(__f_.first(), __a0, __a1, __a2);
422}
423
424#ifndef _LIBCPP_NO_RTTI
425
426template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
427const void*
428__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::target(const type_info& __ti) const
429{
430 if (__ti == typeid(_Fp))
431 return &__f_.first();
432 return (const void*)0;
433}
434
435template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
436const std::type_info&
437__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::target_type() const
438{
439 return typeid(_Fp);
440}
441
442#endif // _LIBCPP_NO_RTTI
443
444} // __function
445
446template<class _Rp>
447class _LIBCPP_TEMPLATE_VIS function<_Rp()>
448{
449 typedef __function::__base<_Rp()> __base;
450 aligned_storage<3*sizeof(void*)>::type __buf_;
451 __base* __f_;
452
453public:
454 typedef _Rp result_type;
455
456 // 20.7.16.2.1, construct/copy/destroy:
457 _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {}
458 _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {}
459 function(const function&);
460 template<class _Fp>
461 function(_Fp,
462 typename enable_if<!is_integral<_Fp>::value>::type* = 0);
463
464 template<class _Alloc>
465 _LIBCPP_INLINE_VISIBILITY
466 function(allocator_arg_t, const _Alloc&) : __f_(0) {}
467 template<class _Alloc>
468 _LIBCPP_INLINE_VISIBILITY
469 function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {}
470 template<class _Alloc>
471 function(allocator_arg_t, const _Alloc&, const function&);
472 template<class _Fp, class _Alloc>
473 function(allocator_arg_t, const _Alloc& __a, _Fp __f,
474 typename enable_if<!is_integral<_Fp>::value>::type* = 0);
475
476 function& operator=(const function&);
477 function& operator=(nullptr_t);
478 template<class _Fp>
479 typename enable_if
480 <
481 !is_integral<_Fp>::value,
482 function&
483 >::type
484 operator=(_Fp);
485
486 ~function();
487
488 // 20.7.16.2.2, function modifiers:
489 void swap(function&);
490 template<class _Fp, class _Alloc>
491 _LIBCPP_INLINE_VISIBILITY
492 void assign(_Fp __f, const _Alloc& __a)
493 {function(allocator_arg, __a, __f).swap(*this);}
494
495 // 20.7.16.2.3, function capacity:
496 _LIBCPP_INLINE_VISIBILITY operator bool() const {return __f_;}
497
498private:
499 // deleted overloads close possible hole in the type system
500 template<class _R2>
501 bool operator==(const function<_R2()>&) const;// = delete;
502 template<class _R2>
503 bool operator!=(const function<_R2()>&) const;// = delete;
504public:
505 // 20.7.16.2.4, function invocation:
506 _Rp operator()() const;
507
508#ifndef _LIBCPP_NO_RTTI
509 // 20.7.16.2.5, function target access:
510 const std::type_info& target_type() const;
511 template <typename _Tp> _Tp* target();
512 template <typename _Tp> const _Tp* target() const;
513#endif // _LIBCPP_NO_RTTI
514};
515
516template<class _Rp>
517function<_Rp()>::function(const function& __f)
518{
519 if (__f.__f_ == 0)
520 __f_ = 0;
521 else if (__f.__f_ == (const __base*)&__f.__buf_)
522 {
523 __f_ = (__base*)&__buf_;
524 __f.__f_->__clone(__f_);
525 }
526 else
527 __f_ = __f.__f_->__clone();
528}
529
530template<class _Rp>
531template<class _Alloc>
532function<_Rp()>::function(allocator_arg_t, const _Alloc&, const function& __f)
533{
534 if (__f.__f_ == 0)
535 __f_ = 0;
536 else if (__f.__f_ == (const __base*)&__f.__buf_)
537 {
538 __f_ = (__base*)&__buf_;
539 __f.__f_->__clone(__f_);
540 }
541 else
542 __f_ = __f.__f_->__clone();
543}
544
545template<class _Rp>
546template <class _Fp>
547function<_Rp()>::function(_Fp __f,
548 typename enable_if<!is_integral<_Fp>::value>::type*)
549 : __f_(0)
550{
551 if (__function::__not_null(__f))
552 {
553 typedef __function::__func<_Fp, allocator<_Fp>, _Rp()> _FF;
554 if (sizeof(_FF) <= sizeof(__buf_))
555 {
556 __f_ = (__base*)&__buf_;
557 ::new ((void*)__f_) _FF(__f);
558 }
559 else
560 {
561 typedef allocator<_FF> _Ap;
562 _Ap __a;
563 typedef __allocator_destructor<_Ap> _Dp;
564 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
565 ::new ((void*)__hold.get()) _FF(__f, allocator<_Fp>(__a));
566 __f_ = __hold.release();
567 }
568 }
569}
570
571template<class _Rp>
572template <class _Fp, class _Alloc>
573function<_Rp()>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f,
574 typename enable_if<!is_integral<_Fp>::value>::type*)
575 : __f_(0)
576{
577 typedef allocator_traits<_Alloc> __alloc_traits;
578 if (__function::__not_null(__f))
579 {
580 typedef __function::__func<_Fp, _Alloc, _Rp()> _FF;
581 if (sizeof(_FF) <= sizeof(__buf_))
582 {
583 __f_ = (__base*)&__buf_;
584 ::new ((void*)__f_) _FF(__f, __a0);
585 }
586 else
587 {
588 typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap;
589 _Ap __a(__a0);
590 typedef __allocator_destructor<_Ap> _Dp;
591 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
592 ::new ((void*)__hold.get()) _FF(__f, _Alloc(__a));
593 __f_ = __hold.release();
594 }
595 }
596}
597
598template<class _Rp>
599function<_Rp()>&
600function<_Rp()>::operator=(const function& __f)
601{
602 if (__f)
603 function(__f).swap(*this);
604 else
605 *this = nullptr;
606 return *this;
607}
608
609template<class _Rp>
610function<_Rp()>&
611function<_Rp()>::operator=(nullptr_t)
612{
613 __base* __t = __f_;
614 __f_ = 0;
615 if (__t == (__base*)&__buf_)
616 __t->destroy();
617 else if (__t)
618 __t->destroy_deallocate();
619 return *this;
620}
621
622template<class _Rp>
623template <class _Fp>
624typename enable_if
625<
626 !is_integral<_Fp>::value,
627 function<_Rp()>&
628>::type
629function<_Rp()>::operator=(_Fp __f)
630{
631 function(_VSTD::move(__f)).swap(*this);
632 return *this;
633}
634
635template<class _Rp>
636function<_Rp()>::~function()
637{
638 if (__f_ == (__base*)&__buf_)
639 __f_->destroy();
640 else if (__f_)
641 __f_->destroy_deallocate();
642}
643
644template<class _Rp>
645void
646function<_Rp()>::swap(function& __f)
647{
648 if (_VSTD::addressof(__f) == this)
649 return;
650 if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
651 {
652 typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
653 __base* __t = (__base*)&__tempbuf;
654 __f_->__clone(__t);
655 __f_->destroy();
656 __f_ = 0;
657 __f.__f_->__clone((__base*)&__buf_);
658 __f.__f_->destroy();
659 __f.__f_ = 0;
660 __f_ = (__base*)&__buf_;
661 __t->__clone((__base*)&__f.__buf_);
662 __t->destroy();
663 __f.__f_ = (__base*)&__f.__buf_;
664 }
665 else if (__f_ == (__base*)&__buf_)
666 {
667 __f_->__clone((__base*)&__f.__buf_);
668 __f_->destroy();
669 __f_ = __f.__f_;
670 __f.__f_ = (__base*)&__f.__buf_;
671 }
672 else if (__f.__f_ == (__base*)&__f.__buf_)
673 {
674 __f.__f_->__clone((__base*)&__buf_);
675 __f.__f_->destroy();
676 __f.__f_ = __f_;
677 __f_ = (__base*)&__buf_;
678 }
679 else
680 _VSTD::swap(__f_, __f.__f_);
681}
682
683template<class _Rp>
684_Rp
685function<_Rp()>::operator()() const
686{
687 if (__f_ == 0)
688 __throw_bad_function_call();
689 return (*__f_)();
690}
691
692#ifndef _LIBCPP_NO_RTTI
693
694template<class _Rp>
695const std::type_info&
696function<_Rp()>::target_type() const
697{
698 if (__f_ == 0)
699 return typeid(void);
700 return __f_->target_type();
701}
702
703template<class _Rp>
704template <typename _Tp>
705_Tp*
706function<_Rp()>::target()
707{
708 if (__f_ == 0)
709 return (_Tp*)0;
710 return (_Tp*) const_cast<void *>(__f_->target(typeid(_Tp)));
711}
712
713template<class _Rp>
714template <typename _Tp>
715const _Tp*
716function<_Rp()>::target() const
717{
718 if (__f_ == 0)
719 return (const _Tp*)0;
720 return (const _Tp*)__f_->target(typeid(_Tp));
721}
722
723#endif // _LIBCPP_NO_RTTI
724
725template<class _Rp, class _A0>
726class _LIBCPP_TEMPLATE_VIS function<_Rp(_A0)>
727 : public unary_function<_A0, _Rp>
728{
729 typedef __function::__base<_Rp(_A0)> __base;
730 aligned_storage<3*sizeof(void*)>::type __buf_;
731 __base* __f_;
732
733public:
734 typedef _Rp result_type;
735
736 // 20.7.16.2.1, construct/copy/destroy:
737 _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {}
738 _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {}
739 function(const function&);
740 template<class _Fp>
741 function(_Fp,
742 typename enable_if<!is_integral<_Fp>::value>::type* = 0);
743
744 template<class _Alloc>
745 _LIBCPP_INLINE_VISIBILITY
746 function(allocator_arg_t, const _Alloc&) : __f_(0) {}
747 template<class _Alloc>
748 _LIBCPP_INLINE_VISIBILITY
749 function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {}
750 template<class _Alloc>
751 function(allocator_arg_t, const _Alloc&, const function&);
752 template<class _Fp, class _Alloc>
753 function(allocator_arg_t, const _Alloc& __a, _Fp __f,
754 typename enable_if<!is_integral<_Fp>::value>::type* = 0);
755
756 function& operator=(const function&);
757 function& operator=(nullptr_t);
758 template<class _Fp>
759 typename enable_if
760 <
761 !is_integral<_Fp>::value,
762 function&
763 >::type
764 operator=(_Fp);
765
766 ~function();
767
768 // 20.7.16.2.2, function modifiers:
769 void swap(function&);
770 template<class _Fp, class _Alloc>
771 _LIBCPP_INLINE_VISIBILITY
772 void assign(_Fp __f, const _Alloc& __a)
773 {function(allocator_arg, __a, __f).swap(*this);}
774
775 // 20.7.16.2.3, function capacity:
776 _LIBCPP_INLINE_VISIBILITY operator bool() const {return __f_;}
777
778private:
779 // deleted overloads close possible hole in the type system
780 template<class _R2, class _B0>
781 bool operator==(const function<_R2(_B0)>&) const;// = delete;
782 template<class _R2, class _B0>
783 bool operator!=(const function<_R2(_B0)>&) const;// = delete;
784public:
785 // 20.7.16.2.4, function invocation:
786 _Rp operator()(_A0) const;
787
788#ifndef _LIBCPP_NO_RTTI
789 // 20.7.16.2.5, function target access:
790 const std::type_info& target_type() const;
791 template <typename _Tp> _Tp* target();
792 template <typename _Tp> const _Tp* target() const;
793#endif // _LIBCPP_NO_RTTI
794};
795
796template<class _Rp, class _A0>
797function<_Rp(_A0)>::function(const function& __f)
798{
799 if (__f.__f_ == 0)
800 __f_ = 0;
801 else if (__f.__f_ == (const __base*)&__f.__buf_)
802 {
803 __f_ = (__base*)&__buf_;
804 __f.__f_->__clone(__f_);
805 }
806 else
807 __f_ = __f.__f_->__clone();
808}
809
810template<class _Rp, class _A0>
811template<class _Alloc>
812function<_Rp(_A0)>::function(allocator_arg_t, const _Alloc&, const function& __f)
813{
814 if (__f.__f_ == 0)
815 __f_ = 0;
816 else if (__f.__f_ == (const __base*)&__f.__buf_)
817 {
818 __f_ = (__base*)&__buf_;
819 __f.__f_->__clone(__f_);
820 }
821 else
822 __f_ = __f.__f_->__clone();
823}
824
825template<class _Rp, class _A0>
826template <class _Fp>
827function<_Rp(_A0)>::function(_Fp __f,
828 typename enable_if<!is_integral<_Fp>::value>::type*)
829 : __f_(0)
830{
831 if (__function::__not_null(__f))
832 {
833 typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_A0)> _FF;
834 if (sizeof(_FF) <= sizeof(__buf_))
835 {
836 __f_ = (__base*)&__buf_;
837 ::new ((void*)__f_) _FF(__f);
838 }
839 else
840 {
841 typedef allocator<_FF> _Ap;
842 _Ap __a;
843 typedef __allocator_destructor<_Ap> _Dp;
844 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
845 ::new ((void*)__hold.get()) _FF(__f, allocator<_Fp>(__a));
846 __f_ = __hold.release();
847 }
848 }
849}
850
851template<class _Rp, class _A0>
852template <class _Fp, class _Alloc>
853function<_Rp(_A0)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f,
854 typename enable_if<!is_integral<_Fp>::value>::type*)
855 : __f_(0)
856{
857 typedef allocator_traits<_Alloc> __alloc_traits;
858 if (__function::__not_null(__f))
859 {
860 typedef __function::__func<_Fp, _Alloc, _Rp(_A0)> _FF;
861 if (sizeof(_FF) <= sizeof(__buf_))
862 {
863 __f_ = (__base*)&__buf_;
864 ::new ((void*)__f_) _FF(__f, __a0);
865 }
866 else
867 {
868 typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap;
869 _Ap __a(__a0);
870 typedef __allocator_destructor<_Ap> _Dp;
871 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
872 ::new ((void*)__hold.get()) _FF(__f, _Alloc(__a));
873 __f_ = __hold.release();
874 }
875 }
876}
877
878template<class _Rp, class _A0>
879function<_Rp(_A0)>&
880function<_Rp(_A0)>::operator=(const function& __f)
881{
882 if (__f)
883 function(__f).swap(*this);
884 else
885 *this = nullptr;
886 return *this;
887}
888
889template<class _Rp, class _A0>
890function<_Rp(_A0)>&
891function<_Rp(_A0)>::operator=(nullptr_t)
892{
893 __base* __t = __f_;
894 __f_ = 0;
895 if (__t == (__base*)&__buf_)
896 __t->destroy();
897 else if (__t)
898 __t->destroy_deallocate();
899 return *this;
900}
901
902template<class _Rp, class _A0>
903template <class _Fp>
904typename enable_if
905<
906 !is_integral<_Fp>::value,
907 function<_Rp(_A0)>&
908>::type
909function<_Rp(_A0)>::operator=(_Fp __f)
910{
911 function(_VSTD::move(__f)).swap(*this);
912 return *this;
913}
914
915template<class _Rp, class _A0>
916function<_Rp(_A0)>::~function()
917{
918 if (__f_ == (__base*)&__buf_)
919 __f_->destroy();
920 else if (__f_)
921 __f_->destroy_deallocate();
922}
923
924template<class _Rp, class _A0>
925void
926function<_Rp(_A0)>::swap(function& __f)
927{
928 if (_VSTD::addressof(__f) == this)
929 return;
930 if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
931 {
932 typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
933 __base* __t = (__base*)&__tempbuf;
934 __f_->__clone(__t);
935 __f_->destroy();
936 __f_ = 0;
937 __f.__f_->__clone((__base*)&__buf_);
938 __f.__f_->destroy();
939 __f.__f_ = 0;
940 __f_ = (__base*)&__buf_;
941 __t->__clone((__base*)&__f.__buf_);
942 __t->destroy();
943 __f.__f_ = (__base*)&__f.__buf_;
944 }
945 else if (__f_ == (__base*)&__buf_)
946 {
947 __f_->__clone((__base*)&__f.__buf_);
948 __f_->destroy();
949 __f_ = __f.__f_;
950 __f.__f_ = (__base*)&__f.__buf_;
951 }
952 else if (__f.__f_ == (__base*)&__f.__buf_)
953 {
954 __f.__f_->__clone((__base*)&__buf_);
955 __f.__f_->destroy();
956 __f.__f_ = __f_;
957 __f_ = (__base*)&__buf_;
958 }
959 else
960 _VSTD::swap(__f_, __f.__f_);
961}
962
963template<class _Rp, class _A0>
964_Rp
965function<_Rp(_A0)>::operator()(_A0 __a0) const
966{
967 if (__f_ == 0)
968 __throw_bad_function_call();
969 return (*__f_)(__a0);
970}
971
972#ifndef _LIBCPP_NO_RTTI
973
974template<class _Rp, class _A0>
975const std::type_info&
976function<_Rp(_A0)>::target_type() const
977{
978 if (__f_ == 0)
979 return typeid(void);
980 return __f_->target_type();
981}
982
983template<class _Rp, class _A0>
984template <typename _Tp>
985_Tp*
986function<_Rp(_A0)>::target()
987{
988 if (__f_ == 0)
989 return (_Tp*)0;
990 return (_Tp*) const_cast<void *>(__f_->target(typeid(_Tp)));
991}
992
993template<class _Rp, class _A0>
994template <typename _Tp>
995const _Tp*
996function<_Rp(_A0)>::target() const
997{
998 if (__f_ == 0)
999 return (const _Tp*)0;
1000 return (const _Tp*)__f_->target(typeid(_Tp));
1001}
1002
1003#endif // _LIBCPP_NO_RTTI
1004
1005template<class _Rp, class _A0, class _A1>
1006class _LIBCPP_TEMPLATE_VIS function<_Rp(_A0, _A1)>
1007 : public binary_function<_A0, _A1, _Rp>
1008{
1009 typedef __function::__base<_Rp(_A0, _A1)> __base;
1010 aligned_storage<3*sizeof(void*)>::type __buf_;
1011 __base* __f_;
1012
1013public:
1014 typedef _Rp result_type;
1015
1016 // 20.7.16.2.1, construct/copy/destroy:
1017 _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {}
1018 _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {}
1019 function(const function&);
1020 template<class _Fp>
1021 function(_Fp,
1022 typename enable_if<!is_integral<_Fp>::value>::type* = 0);
1023
1024 template<class _Alloc>
1025 _LIBCPP_INLINE_VISIBILITY
1026 function(allocator_arg_t, const _Alloc&) : __f_(0) {}
1027 template<class _Alloc>
1028 _LIBCPP_INLINE_VISIBILITY
1029 function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {}
1030 template<class _Alloc>
1031 function(allocator_arg_t, const _Alloc&, const function&);
1032 template<class _Fp, class _Alloc>
1033 function(allocator_arg_t, const _Alloc& __a, _Fp __f,
1034 typename enable_if<!is_integral<_Fp>::value>::type* = 0);
1035
1036 function& operator=(const function&);
1037 function& operator=(nullptr_t);
1038 template<class _Fp>
1039 typename enable_if
1040 <
1041 !is_integral<_Fp>::value,
1042 function&
1043 >::type
1044 operator=(_Fp);
1045
1046 ~function();
1047
1048 // 20.7.16.2.2, function modifiers:
1049 void swap(function&);
1050 template<class _Fp, class _Alloc>
1051 _LIBCPP_INLINE_VISIBILITY
1052 void assign(_Fp __f, const _Alloc& __a)
1053 {function(allocator_arg, __a, __f).swap(*this);}
1054
1055 // 20.7.16.2.3, function capacity:
1056 operator bool() const {return __f_;}
1057
1058private:
1059 // deleted overloads close possible hole in the type system
1060 template<class _R2, class _B0, class _B1>
1061 bool operator==(const function<_R2(_B0, _B1)>&) const;// = delete;
1062 template<class _R2, class _B0, class _B1>
1063 bool operator!=(const function<_R2(_B0, _B1)>&) const;// = delete;
1064public:
1065 // 20.7.16.2.4, function invocation:
1066 _Rp operator()(_A0, _A1) const;
1067
1068#ifndef _LIBCPP_NO_RTTI
1069 // 20.7.16.2.5, function target access:
1070 const std::type_info& target_type() const;
1071 template <typename _Tp> _Tp* target();
1072 template <typename _Tp> const _Tp* target() const;
1073#endif // _LIBCPP_NO_RTTI
1074};
1075
1076template<class _Rp, class _A0, class _A1>
1077function<_Rp(_A0, _A1)>::function(const function& __f)
1078{
1079 if (__f.__f_ == 0)
1080 __f_ = 0;
1081 else if (__f.__f_ == (const __base*)&__f.__buf_)
1082 {
1083 __f_ = (__base*)&__buf_;
1084 __f.__f_->__clone(__f_);
1085 }
1086 else
1087 __f_ = __f.__f_->__clone();
1088}
1089
1090template<class _Rp, class _A0, class _A1>
1091template<class _Alloc>
1092function<_Rp(_A0, _A1)>::function(allocator_arg_t, const _Alloc&, const function& __f)
1093{
1094 if (__f.__f_ == 0)
1095 __f_ = 0;
1096 else if (__f.__f_ == (const __base*)&__f.__buf_)
1097 {
1098 __f_ = (__base*)&__buf_;
1099 __f.__f_->__clone(__f_);
1100 }
1101 else
1102 __f_ = __f.__f_->__clone();
1103}
1104
1105template<class _Rp, class _A0, class _A1>
1106template <class _Fp>
1107function<_Rp(_A0, _A1)>::function(_Fp __f,
1108 typename enable_if<!is_integral<_Fp>::value>::type*)
1109 : __f_(0)
1110{
1111 if (__function::__not_null(__f))
1112 {
1113 typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_A0, _A1)> _FF;
1114 if (sizeof(_FF) <= sizeof(__buf_))
1115 {
1116 __f_ = (__base*)&__buf_;
1117 ::new ((void*)__f_) _FF(__f);
1118 }
1119 else
1120 {
1121 typedef allocator<_FF> _Ap;
1122 _Ap __a;
1123 typedef __allocator_destructor<_Ap> _Dp;
1124 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1125 ::new ((void*)__hold.get()) _FF(__f, allocator<_Fp>(__a));
1126 __f_ = __hold.release();
1127 }
1128 }
1129}
1130
1131template<class _Rp, class _A0, class _A1>
1132template <class _Fp, class _Alloc>
1133function<_Rp(_A0, _A1)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f,
1134 typename enable_if<!is_integral<_Fp>::value>::type*)
1135 : __f_(0)
1136{
1137 typedef allocator_traits<_Alloc> __alloc_traits;
1138 if (__function::__not_null(__f))
1139 {
1140 typedef __function::__func<_Fp, _Alloc, _Rp(_A0, _A1)> _FF;
1141 if (sizeof(_FF) <= sizeof(__buf_))
1142 {
1143 __f_ = (__base*)&__buf_;
1144 ::new ((void*)__f_) _FF(__f, __a0);
1145 }
1146 else
1147 {
1148 typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap;
1149 _Ap __a(__a0);
1150 typedef __allocator_destructor<_Ap> _Dp;
1151 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1152 ::new ((void*)__hold.get()) _FF(__f, _Alloc(__a));
1153 __f_ = __hold.release();
1154 }
1155 }
1156}
1157
1158template<class _Rp, class _A0, class _A1>
1159function<_Rp(_A0, _A1)>&
1160function<_Rp(_A0, _A1)>::operator=(const function& __f)
1161{
1162 if (__f)
1163 function(__f).swap(*this);
1164 else
1165 *this = nullptr;
1166 return *this;
1167}
1168
1169template<class _Rp, class _A0, class _A1>
1170function<_Rp(_A0, _A1)>&
1171function<_Rp(_A0, _A1)>::operator=(nullptr_t)
1172{
1173 __base* __t = __f_;
1174 __f_ = 0;
1175 if (__t == (__base*)&__buf_)
1176 __t->destroy();
1177 else if (__t)
1178 __t->destroy_deallocate();
1179 return *this;
1180}
1181
1182template<class _Rp, class _A0, class _A1>
1183template <class _Fp>
1184typename enable_if
1185<
1186 !is_integral<_Fp>::value,
1187 function<_Rp(_A0, _A1)>&
1188>::type
1189function<_Rp(_A0, _A1)>::operator=(_Fp __f)
1190{
1191 function(_VSTD::move(__f)).swap(*this);
1192 return *this;
1193}
1194
1195template<class _Rp, class _A0, class _A1>
1196function<_Rp(_A0, _A1)>::~function()
1197{
1198 if (__f_ == (__base*)&__buf_)
1199 __f_->destroy();
1200 else if (__f_)
1201 __f_->destroy_deallocate();
1202}
1203
1204template<class _Rp, class _A0, class _A1>
1205void
1206function<_Rp(_A0, _A1)>::swap(function& __f)
1207{
1208 if (_VSTD::addressof(__f) == this)
1209 return;
1210 if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
1211 {
1212 typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
1213 __base* __t = (__base*)&__tempbuf;
1214 __f_->__clone(__t);
1215 __f_->destroy();
1216 __f_ = 0;
1217 __f.__f_->__clone((__base*)&__buf_);
1218 __f.__f_->destroy();
1219 __f.__f_ = 0;
1220 __f_ = (__base*)&__buf_;
1221 __t->__clone((__base*)&__f.__buf_);
1222 __t->destroy();
1223 __f.__f_ = (__base*)&__f.__buf_;
1224 }
1225 else if (__f_ == (__base*)&__buf_)
1226 {
1227 __f_->__clone((__base*)&__f.__buf_);
1228 __f_->destroy();
1229 __f_ = __f.__f_;
1230 __f.__f_ = (__base*)&__f.__buf_;
1231 }
1232 else if (__f.__f_ == (__base*)&__f.__buf_)
1233 {
1234 __f.__f_->__clone((__base*)&__buf_);
1235 __f.__f_->destroy();
1236 __f.__f_ = __f_;
1237 __f_ = (__base*)&__buf_;
1238 }
1239 else
1240 _VSTD::swap(__f_, __f.__f_);
1241}
1242
1243template<class _Rp, class _A0, class _A1>
1244_Rp
1245function<_Rp(_A0, _A1)>::operator()(_A0 __a0, _A1 __a1) const
1246{
1247 if (__f_ == 0)
1248 __throw_bad_function_call();
1249 return (*__f_)(__a0, __a1);
1250}
1251
1252#ifndef _LIBCPP_NO_RTTI
1253
1254template<class _Rp, class _A0, class _A1>
1255const std::type_info&
1256function<_Rp(_A0, _A1)>::target_type() const
1257{
1258 if (__f_ == 0)
1259 return typeid(void);
1260 return __f_->target_type();
1261}
1262
1263template<class _Rp, class _A0, class _A1>
1264template <typename _Tp>
1265_Tp*
1266function<_Rp(_A0, _A1)>::target()
1267{
1268 if (__f_ == 0)
1269 return (_Tp*)0;
1270 return (_Tp*) const_cast<void *>(__f_->target(typeid(_Tp)));
1271}
1272
1273template<class _Rp, class _A0, class _A1>
1274template <typename _Tp>
1275const _Tp*
1276function<_Rp(_A0, _A1)>::target() const
1277{
1278 if (__f_ == 0)
1279 return (const _Tp*)0;
1280 return (const _Tp*)__f_->target(typeid(_Tp));
1281}
1282
1283#endif // _LIBCPP_NO_RTTI
1284
1285template<class _Rp, class _A0, class _A1, class _A2>
1286class _LIBCPP_TEMPLATE_VIS function<_Rp(_A0, _A1, _A2)>
1287{
1288 typedef __function::__base<_Rp(_A0, _A1, _A2)> __base;
1289 aligned_storage<3*sizeof(void*)>::type __buf_;
1290 __base* __f_;
1291
1292public:
1293 typedef _Rp result_type;
1294
1295 // 20.7.16.2.1, construct/copy/destroy:
1296 _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {}
1297 _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {}
1298 function(const function&);
1299 template<class _Fp>
1300 function(_Fp,
1301 typename enable_if<!is_integral<_Fp>::value>::type* = 0);
1302
1303 template<class _Alloc>
1304 _LIBCPP_INLINE_VISIBILITY
1305 function(allocator_arg_t, const _Alloc&) : __f_(0) {}
1306 template<class _Alloc>
1307 _LIBCPP_INLINE_VISIBILITY
1308 function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {}
1309 template<class _Alloc>
1310 function(allocator_arg_t, const _Alloc&, const function&);
1311 template<class _Fp, class _Alloc>
1312 function(allocator_arg_t, const _Alloc& __a, _Fp __f,
1313 typename enable_if<!is_integral<_Fp>::value>::type* = 0);
1314
1315 function& operator=(const function&);
1316 function& operator=(nullptr_t);
1317 template<class _Fp>
1318 typename enable_if
1319 <
1320 !is_integral<_Fp>::value,
1321 function&
1322 >::type
1323 operator=(_Fp);
1324
1325 ~function();
1326
1327 // 20.7.16.2.2, function modifiers:
1328 void swap(function&);
1329 template<class _Fp, class _Alloc>
1330 _LIBCPP_INLINE_VISIBILITY
1331 void assign(_Fp __f, const _Alloc& __a)
1332 {function(allocator_arg, __a, __f).swap(*this);}
1333
1334 // 20.7.16.2.3, function capacity:
1335 _LIBCPP_INLINE_VISIBILITY operator bool() const {return __f_;}
1336
1337private:
1338 // deleted overloads close possible hole in the type system
1339 template<class _R2, class _B0, class _B1, class _B2>
1340 bool operator==(const function<_R2(_B0, _B1, _B2)>&) const;// = delete;
1341 template<class _R2, class _B0, class _B1, class _B2>
1342 bool operator!=(const function<_R2(_B0, _B1, _B2)>&) const;// = delete;
1343public:
1344 // 20.7.16.2.4, function invocation:
1345 _Rp operator()(_A0, _A1, _A2) const;
1346
1347#ifndef _LIBCPP_NO_RTTI
1348 // 20.7.16.2.5, function target access:
1349 const std::type_info& target_type() const;
1350 template <typename _Tp> _Tp* target();
1351 template <typename _Tp> const _Tp* target() const;
1352#endif // _LIBCPP_NO_RTTI
1353};
1354
1355template<class _Rp, class _A0, class _A1, class _A2>
1356function<_Rp(_A0, _A1, _A2)>::function(const function& __f)
1357{
1358 if (__f.__f_ == 0)
1359 __f_ = 0;
1360 else if (__f.__f_ == (const __base*)&__f.__buf_)
1361 {
1362 __f_ = (__base*)&__buf_;
1363 __f.__f_->__clone(__f_);
1364 }
1365 else
1366 __f_ = __f.__f_->__clone();
1367}
1368
1369template<class _Rp, class _A0, class _A1, class _A2>
1370template<class _Alloc>
1371function<_Rp(_A0, _A1, _A2)>::function(allocator_arg_t, const _Alloc&,
1372 const function& __f)
1373{
1374 if (__f.__f_ == 0)
1375 __f_ = 0;
1376 else if (__f.__f_ == (const __base*)&__f.__buf_)
1377 {
1378 __f_ = (__base*)&__buf_;
1379 __f.__f_->__clone(__f_);
1380 }
1381 else
1382 __f_ = __f.__f_->__clone();
1383}
1384
1385template<class _Rp, class _A0, class _A1, class _A2>
1386template <class _Fp>
1387function<_Rp(_A0, _A1, _A2)>::function(_Fp __f,
1388 typename enable_if<!is_integral<_Fp>::value>::type*)
1389 : __f_(0)
1390{
1391 if (__function::__not_null(__f))
1392 {
1393 typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_A0, _A1, _A2)> _FF;
1394 if (sizeof(_FF) <= sizeof(__buf_))
1395 {
1396 __f_ = (__base*)&__buf_;
1397 ::new ((void*)__f_) _FF(__f);
1398 }
1399 else
1400 {
1401 typedef allocator<_FF> _Ap;
1402 _Ap __a;
1403 typedef __allocator_destructor<_Ap> _Dp;
1404 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1405 ::new ((void*)__hold.get()) _FF(__f, allocator<_Fp>(__a));
1406 __f_ = __hold.release();
1407 }
1408 }
1409}
1410
1411template<class _Rp, class _A0, class _A1, class _A2>
1412template <class _Fp, class _Alloc>
1413function<_Rp(_A0, _A1, _A2)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f,
1414 typename enable_if<!is_integral<_Fp>::value>::type*)
1415 : __f_(0)
1416{
1417 typedef allocator_traits<_Alloc> __alloc_traits;
1418 if (__function::__not_null(__f))
1419 {
1420 typedef __function::__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)> _FF;
1421 if (sizeof(_FF) <= sizeof(__buf_))
1422 {
1423 __f_ = (__base*)&__buf_;
1424 ::new ((void*)__f_) _FF(__f, __a0);
1425 }
1426 else
1427 {
1428 typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap;
1429 _Ap __a(__a0);
1430 typedef __allocator_destructor<_Ap> _Dp;
1431 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1432 ::new ((void*)__hold.get()) _FF(__f, _Alloc(__a));
1433 __f_ = __hold.release();
1434 }
1435 }
1436}
1437
1438template<class _Rp, class _A0, class _A1, class _A2>
1439function<_Rp(_A0, _A1, _A2)>&
1440function<_Rp(_A0, _A1, _A2)>::operator=(const function& __f)
1441{
1442 if (__f)
1443 function(__f).swap(*this);
1444 else
1445 *this = nullptr;
1446 return *this;
1447}
1448
1449template<class _Rp, class _A0, class _A1, class _A2>
1450function<_Rp(_A0, _A1, _A2)>&
1451function<_Rp(_A0, _A1, _A2)>::operator=(nullptr_t)
1452{
1453 __base* __t = __f_;
1454 __f_ = 0;
1455 if (__t == (__base*)&__buf_)
1456 __t->destroy();
1457 else if (__t)
1458 __t->destroy_deallocate();
1459 return *this;
1460}
1461
1462template<class _Rp, class _A0, class _A1, class _A2>
1463template <class _Fp>
1464typename enable_if
1465<
1466 !is_integral<_Fp>::value,
1467 function<_Rp(_A0, _A1, _A2)>&
1468>::type
1469function<_Rp(_A0, _A1, _A2)>::operator=(_Fp __f)
1470{
1471 function(_VSTD::move(__f)).swap(*this);
1472 return *this;
1473}
1474
1475template<class _Rp, class _A0, class _A1, class _A2>
1476function<_Rp(_A0, _A1, _A2)>::~function()
1477{
1478 if (__f_ == (__base*)&__buf_)
1479 __f_->destroy();
1480 else if (__f_)
1481 __f_->destroy_deallocate();
1482}
1483
1484template<class _Rp, class _A0, class _A1, class _A2>
1485void
1486function<_Rp(_A0, _A1, _A2)>::swap(function& __f)
1487{
1488 if (_VSTD::addressof(__f) == this)
1489 return;
1490 if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
1491 {
1492 typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
1493 __base* __t = (__base*)&__tempbuf;
1494 __f_->__clone(__t);
1495 __f_->destroy();
1496 __f_ = 0;
1497 __f.__f_->__clone((__base*)&__buf_);
1498 __f.__f_->destroy();
1499 __f.__f_ = 0;
1500 __f_ = (__base*)&__buf_;
1501 __t->__clone((__base*)&__f.__buf_);
1502 __t->destroy();
1503 __f.__f_ = (__base*)&__f.__buf_;
1504 }
1505 else if (__f_ == (__base*)&__buf_)
1506 {
1507 __f_->__clone((__base*)&__f.__buf_);
1508 __f_->destroy();
1509 __f_ = __f.__f_;
1510 __f.__f_ = (__base*)&__f.__buf_;
1511 }
1512 else if (__f.__f_ == (__base*)&__f.__buf_)
1513 {
1514 __f.__f_->__clone((__base*)&__buf_);
1515 __f.__f_->destroy();
1516 __f.__f_ = __f_;
1517 __f_ = (__base*)&__buf_;
1518 }
1519 else
1520 _VSTD::swap(__f_, __f.__f_);
1521}
1522
1523template<class _Rp, class _A0, class _A1, class _A2>
1524_Rp
1525function<_Rp(_A0, _A1, _A2)>::operator()(_A0 __a0, _A1 __a1, _A2 __a2) const
1526{
1527 if (__f_ == 0)
1528 __throw_bad_function_call();
1529 return (*__f_)(__a0, __a1, __a2);
1530}
1531
1532#ifndef _LIBCPP_NO_RTTI
1533
1534template<class _Rp, class _A0, class _A1, class _A2>
1535const std::type_info&
1536function<_Rp(_A0, _A1, _A2)>::target_type() const
1537{
1538 if (__f_ == 0)
1539 return typeid(void);
1540 return __f_->target_type();
1541}
1542
1543template<class _Rp, class _A0, class _A1, class _A2>
1544template <typename _Tp>
1545_Tp*
1546function<_Rp(_A0, _A1, _A2)>::target()
1547{
1548 if (__f_ == 0)
1549 return (_Tp*)0;
1550 return (_Tp*) const_cast<void *>(__f_->target(typeid(_Tp)));
1551}
1552
1553template<class _Rp, class _A0, class _A1, class _A2>
1554template <typename _Tp>
1555const _Tp*
1556function<_Rp(_A0, _A1, _A2)>::target() const
1557{
1558 if (__f_ == 0)
1559 return (const _Tp*)0;
1560 return (const _Tp*)__f_->target(typeid(_Tp));
1561}
1562
1563#endif // _LIBCPP_NO_RTTI
1564
1565template <class _Fp>
1566inline _LIBCPP_INLINE_VISIBILITY
1567bool
1568operator==(const function<_Fp>& __f, nullptr_t) {return !__f;}
1569
1570template <class _Fp>
1571inline _LIBCPP_INLINE_VISIBILITY
1572bool
1573operator==(nullptr_t, const function<_Fp>& __f) {return !__f;}
1574
1575template <class _Fp>
1576inline _LIBCPP_INLINE_VISIBILITY
1577bool
1578operator!=(const function<_Fp>& __f, nullptr_t) {return (bool)__f;}
1579
1580template <class _Fp>
1581inline _LIBCPP_INLINE_VISIBILITY
1582bool
1583operator!=(nullptr_t, const function<_Fp>& __f) {return (bool)__f;}
1584
1585template <class _Fp>
1586inline _LIBCPP_INLINE_VISIBILITY
1587void
1588swap(function<_Fp>& __x, function<_Fp>& __y)
1589{return __x.swap(__y);}
1590
1591#endif // _LIBCPP_FUNCTIONAL_03
lib/libcxx/include/__functional_base+11-634
......@@ -11,645 +11,22 @@
1111#define _LIBCPP_FUNCTIONAL_BASE
1212
1313#include <__config>
14#include <type_traits>
15#include <typeinfo>
14#include <__functional/binary_function.h>
15#include <__functional/invoke.h>
16#include <__functional/operations.h>
17#include <__functional/reference_wrapper.h>
18#include <__functional/unary_function.h>
19#include <__functional/weak_result_type.h>
20#include <__memory/allocator_arg_t.h>
21#include <__memory/uses_allocator.h>
1622#include <exception>
1723#include <new>
24#include <type_traits>
25#include <typeinfo>
1826#include <utility>
1927
2028#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2129#pragma GCC system_header
2230#endif
2331
24_LIBCPP_BEGIN_NAMESPACE_STD
25
26template <class _Arg1, class _Arg2, class _Result>
27struct _LIBCPP_TEMPLATE_VIS binary_function
28{
29 typedef _Arg1 first_argument_type;
30 typedef _Arg2 second_argument_type;
31 typedef _Result result_type;
32};
33
34template <class _Tp>
35struct __has_result_type
36{
37private:
38 struct __two {char __lx; char __lxx;};
39 template <class _Up> static __two __test(...);
40 template <class _Up> static char __test(typename _Up::result_type* = 0);
41public:
42 static const bool value = sizeof(__test<_Tp>(0)) == 1;
43};
44
45#if _LIBCPP_STD_VER > 11
46template <class _Tp = void>
47#else
48template <class _Tp>
49#endif
50struct _LIBCPP_TEMPLATE_VIS less : binary_function<_Tp, _Tp, bool>
51{
52 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
53 bool operator()(const _Tp& __x, const _Tp& __y) const
54 {return __x < __y;}
55};
56
57#if _LIBCPP_STD_VER > 11
58template <>
59struct _LIBCPP_TEMPLATE_VIS less<void>
60{
61 template <class _T1, class _T2>
62 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
63 auto operator()(_T1&& __t, _T2&& __u) const
64 _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) < _VSTD::forward<_T2>(__u)))
65 -> decltype (_VSTD::forward<_T1>(__t) < _VSTD::forward<_T2>(__u))
66 { return _VSTD::forward<_T1>(__t) < _VSTD::forward<_T2>(__u); }
67 typedef void is_transparent;
68};
69#endif
70
71// __weak_result_type
72
73template <class _Tp>
74struct __derives_from_unary_function
75{
76private:
77 struct __two {char __lx; char __lxx;};
78 static __two __test(...);
79 template <class _Ap, class _Rp>
80 static unary_function<_Ap, _Rp>
81 __test(const volatile unary_function<_Ap, _Rp>*);
82public:
83 static const bool value = !is_same<decltype(__test((_Tp*)0)), __two>::value;
84 typedef decltype(__test((_Tp*)0)) type;
85};
86
87template <class _Tp>
88struct __derives_from_binary_function
89{
90private:
91 struct __two {char __lx; char __lxx;};
92 static __two __test(...);
93 template <class _A1, class _A2, class _Rp>
94 static binary_function<_A1, _A2, _Rp>
95 __test(const volatile binary_function<_A1, _A2, _Rp>*);
96public:
97 static const bool value = !is_same<decltype(__test((_Tp*)0)), __two>::value;
98 typedef decltype(__test((_Tp*)0)) type;
99};
100
101template <class _Tp, bool = __derives_from_unary_function<_Tp>::value>
102struct __maybe_derive_from_unary_function // bool is true
103 : public __derives_from_unary_function<_Tp>::type
104{
105};
106
107template <class _Tp>
108struct __maybe_derive_from_unary_function<_Tp, false>
109{
110};
111
112template <class _Tp, bool = __derives_from_binary_function<_Tp>::value>
113struct __maybe_derive_from_binary_function // bool is true
114 : public __derives_from_binary_function<_Tp>::type
115{
116};
117
118template <class _Tp>
119struct __maybe_derive_from_binary_function<_Tp, false>
120{
121};
122
123template <class _Tp, bool = __has_result_type<_Tp>::value>
124struct __weak_result_type_imp // bool is true
125 : public __maybe_derive_from_unary_function<_Tp>,
126 public __maybe_derive_from_binary_function<_Tp>
127{
128 typedef _LIBCPP_NODEBUG_TYPE typename _Tp::result_type result_type;
129};
130
131template <class _Tp>
132struct __weak_result_type_imp<_Tp, false>
133 : public __maybe_derive_from_unary_function<_Tp>,
134 public __maybe_derive_from_binary_function<_Tp>
135{
136};
137
138template <class _Tp>
139struct __weak_result_type
140 : public __weak_result_type_imp<_Tp>
141{
142};
143
144// 0 argument case
145
146template <class _Rp>
147struct __weak_result_type<_Rp ()>
148{
149 typedef _LIBCPP_NODEBUG_TYPE _Rp result_type;
150};
151
152template <class _Rp>
153struct __weak_result_type<_Rp (&)()>
154{
155 typedef _LIBCPP_NODEBUG_TYPE _Rp result_type;
156};
157
158template <class _Rp>
159struct __weak_result_type<_Rp (*)()>
160{
161 typedef _LIBCPP_NODEBUG_TYPE _Rp result_type;
162};
163
164// 1 argument case
165
166template <class _Rp, class _A1>
167struct __weak_result_type<_Rp (_A1)>
168 : public unary_function<_A1, _Rp>
169{
170};
171
172template <class _Rp, class _A1>
173struct __weak_result_type<_Rp (&)(_A1)>
174 : public unary_function<_A1, _Rp>
175{
176};
177
178template <class _Rp, class _A1>
179struct __weak_result_type<_Rp (*)(_A1)>
180 : public unary_function<_A1, _Rp>
181{
182};
183
184template <class _Rp, class _Cp>
185struct __weak_result_type<_Rp (_Cp::*)()>
186 : public unary_function<_Cp*, _Rp>
187{
188};
189
190template <class _Rp, class _Cp>
191struct __weak_result_type<_Rp (_Cp::*)() const>
192 : public unary_function<const _Cp*, _Rp>
193{
194};
195
196template <class _Rp, class _Cp>
197struct __weak_result_type<_Rp (_Cp::*)() volatile>
198 : public unary_function<volatile _Cp*, _Rp>
199{
200};
201
202template <class _Rp, class _Cp>
203struct __weak_result_type<_Rp (_Cp::*)() const volatile>
204 : public unary_function<const volatile _Cp*, _Rp>
205{
206};
207
208// 2 argument case
209
210template <class _Rp, class _A1, class _A2>
211struct __weak_result_type<_Rp (_A1, _A2)>
212 : public binary_function<_A1, _A2, _Rp>
213{
214};
215
216template <class _Rp, class _A1, class _A2>
217struct __weak_result_type<_Rp (*)(_A1, _A2)>
218 : public binary_function<_A1, _A2, _Rp>
219{
220};
221
222template <class _Rp, class _A1, class _A2>
223struct __weak_result_type<_Rp (&)(_A1, _A2)>
224 : public binary_function<_A1, _A2, _Rp>
225{
226};
227
228template <class _Rp, class _Cp, class _A1>
229struct __weak_result_type<_Rp (_Cp::*)(_A1)>
230 : public binary_function<_Cp*, _A1, _Rp>
231{
232};
233
234template <class _Rp, class _Cp, class _A1>
235struct __weak_result_type<_Rp (_Cp::*)(_A1) const>
236 : public binary_function<const _Cp*, _A1, _Rp>
237{
238};
239
240template <class _Rp, class _Cp, class _A1>
241struct __weak_result_type<_Rp (_Cp::*)(_A1) volatile>
242 : public binary_function<volatile _Cp*, _A1, _Rp>
243{
244};
245
246template <class _Rp, class _Cp, class _A1>
247struct __weak_result_type<_Rp (_Cp::*)(_A1) const volatile>
248 : public binary_function<const volatile _Cp*, _A1, _Rp>
249{
250};
251
252
253#ifndef _LIBCPP_CXX03_LANG
254// 3 or more arguments
255
256template <class _Rp, class _A1, class _A2, class _A3, class ..._A4>
257struct __weak_result_type<_Rp (_A1, _A2, _A3, _A4...)>
258{
259 typedef _Rp result_type;
260};
261
262template <class _Rp, class _A1, class _A2, class _A3, class ..._A4>
263struct __weak_result_type<_Rp (&)(_A1, _A2, _A3, _A4...)>
264{
265 typedef _Rp result_type;
266};
267
268template <class _Rp, class _A1, class _A2, class _A3, class ..._A4>
269struct __weak_result_type<_Rp (*)(_A1, _A2, _A3, _A4...)>
270{
271 typedef _Rp result_type;
272};
273
274template <class _Rp, class _Cp, class _A1, class _A2, class ..._A3>
275struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...)>
276{
277 typedef _Rp result_type;
278};
279
280template <class _Rp, class _Cp, class _A1, class _A2, class ..._A3>
281struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) const>
282{
283 typedef _Rp result_type;
284};
285
286template <class _Rp, class _Cp, class _A1, class _A2, class ..._A3>
287struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) volatile>
288{
289 typedef _Rp result_type;
290};
291
292template <class _Rp, class _Cp, class _A1, class _A2, class ..._A3>
293struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) const volatile>
294{
295 typedef _Rp result_type;
296};
297
298template <class _Tp, class ..._Args>
299struct __invoke_return
300{
301 typedef decltype(_VSTD::__invoke(declval<_Tp>(), declval<_Args>()...)) type;
302};
303
304#else // defined(_LIBCPP_CXX03_LANG)
305
306#include <__functional_base_03>
307
308#endif // !defined(_LIBCPP_CXX03_LANG)
309
310
311template <class _Ret, bool = is_void<_Ret>::value>
312struct __invoke_void_return_wrapper
313{
314#ifndef _LIBCPP_CXX03_LANG
315 template <class ..._Args>
316 static _Ret __call(_Args&&... __args) {
317 return _VSTD::__invoke(_VSTD::forward<_Args>(__args)...);
318 }
319#else
320 template <class _Fn>
321 static _Ret __call(_Fn __f) {
322 return _VSTD::__invoke(__f);
323 }
324
325 template <class _Fn, class _A0>
326 static _Ret __call(_Fn __f, _A0& __a0) {
327 return _VSTD::__invoke(__f, __a0);
328 }
329
330 template <class _Fn, class _A0, class _A1>
331 static _Ret __call(_Fn __f, _A0& __a0, _A1& __a1) {
332 return _VSTD::__invoke(__f, __a0, __a1);
333 }
334
335 template <class _Fn, class _A0, class _A1, class _A2>
336 static _Ret __call(_Fn __f, _A0& __a0, _A1& __a1, _A2& __a2){
337 return _VSTD::__invoke(__f, __a0, __a1, __a2);
338 }
339#endif
340};
341
342template <class _Ret>
343struct __invoke_void_return_wrapper<_Ret, true>
344{
345#ifndef _LIBCPP_CXX03_LANG
346 template <class ..._Args>
347 static void __call(_Args&&... __args) {
348 _VSTD::__invoke(_VSTD::forward<_Args>(__args)...);
349 }
350#else
351 template <class _Fn>
352 static void __call(_Fn __f) {
353 _VSTD::__invoke(__f);
354 }
355
356 template <class _Fn, class _A0>
357 static void __call(_Fn __f, _A0& __a0) {
358 _VSTD::__invoke(__f, __a0);
359 }
360
361 template <class _Fn, class _A0, class _A1>
362 static void __call(_Fn __f, _A0& __a0, _A1& __a1) {
363 _VSTD::__invoke(__f, __a0, __a1);
364 }
365
366 template <class _Fn, class _A0, class _A1, class _A2>
367 static void __call(_Fn __f, _A0& __a0, _A1& __a1, _A2& __a2) {
368 _VSTD::__invoke(__f, __a0, __a1, __a2);
369 }
370#endif
371};
372
373template <class _Tp>
374class _LIBCPP_TEMPLATE_VIS reference_wrapper
375 : public __weak_result_type<_Tp>
376{
377public:
378 // types
379 typedef _Tp type;
380private:
381 type* __f_;
382
383public:
384 // construct/copy/destroy
385 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
386 reference_wrapper(type& __f) _NOEXCEPT
387 : __f_(_VSTD::addressof(__f)) {}
388#ifndef _LIBCPP_CXX03_LANG
389 private: reference_wrapper(type&&); public: // = delete; // do not bind to temps
390#endif
391
392 // access
393 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
394 operator type&() const _NOEXCEPT {return *__f_;}
395 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
396 type& get() const _NOEXCEPT {return *__f_;}
397
398#ifndef _LIBCPP_CXX03_LANG
399 // invoke
400 template <class... _ArgTypes>
401 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
402 typename __invoke_of<type&, _ArgTypes...>::type
403 operator() (_ArgTypes&&... __args) const {
404 return _VSTD::__invoke(get(), _VSTD::forward<_ArgTypes>(__args)...);
405 }
406#else
407
408 _LIBCPP_INLINE_VISIBILITY
409 typename __invoke_return<type>::type
410 operator() () const {
411 return _VSTD::__invoke(get());
412 }
413
414 template <class _A0>
415 _LIBCPP_INLINE_VISIBILITY
416 typename __invoke_return0<type, _A0>::type
417 operator() (_A0& __a0) const {
418 return _VSTD::__invoke(get(), __a0);
419 }
420
421 template <class _A0>
422 _LIBCPP_INLINE_VISIBILITY
423 typename __invoke_return0<type, _A0 const>::type
424 operator() (_A0 const& __a0) const {
425 return _VSTD::__invoke(get(), __a0);
426 }
427
428 template <class _A0, class _A1>
429 _LIBCPP_INLINE_VISIBILITY
430 typename __invoke_return1<type, _A0, _A1>::type
431 operator() (_A0& __a0, _A1& __a1) const {
432 return _VSTD::__invoke(get(), __a0, __a1);
433 }
434
435 template <class _A0, class _A1>
436 _LIBCPP_INLINE_VISIBILITY
437 typename __invoke_return1<type, _A0 const, _A1>::type
438 operator() (_A0 const& __a0, _A1& __a1) const {
439 return _VSTD::__invoke(get(), __a0, __a1);
440 }
441
442 template <class _A0, class _A1>
443 _LIBCPP_INLINE_VISIBILITY
444 typename __invoke_return1<type, _A0, _A1 const>::type
445 operator() (_A0& __a0, _A1 const& __a1) const {
446 return _VSTD::__invoke(get(), __a0, __a1);
447 }
448
449 template <class _A0, class _A1>
450 _LIBCPP_INLINE_VISIBILITY
451 typename __invoke_return1<type, _A0 const, _A1 const>::type
452 operator() (_A0 const& __a0, _A1 const& __a1) const {
453 return _VSTD::__invoke(get(), __a0, __a1);
454 }
455
456 template <class _A0, class _A1, class _A2>
457 _LIBCPP_INLINE_VISIBILITY
458 typename __invoke_return2<type, _A0, _A1, _A2>::type
459 operator() (_A0& __a0, _A1& __a1, _A2& __a2) const {
460 return _VSTD::__invoke(get(), __a0, __a1, __a2);
461 }
462
463 template <class _A0, class _A1, class _A2>
464 _LIBCPP_INLINE_VISIBILITY
465 typename __invoke_return2<type, _A0 const, _A1, _A2>::type
466 operator() (_A0 const& __a0, _A1& __a1, _A2& __a2) const {
467 return _VSTD::__invoke(get(), __a0, __a1, __a2);
468 }
469
470 template <class _A0, class _A1, class _A2>
471 _LIBCPP_INLINE_VISIBILITY
472 typename __invoke_return2<type, _A0, _A1 const, _A2>::type
473 operator() (_A0& __a0, _A1 const& __a1, _A2& __a2) const {
474 return _VSTD::__invoke(get(), __a0, __a1, __a2);
475 }
476
477 template <class _A0, class _A1, class _A2>
478 _LIBCPP_INLINE_VISIBILITY
479 typename __invoke_return2<type, _A0, _A1, _A2 const>::type
480 operator() (_A0& __a0, _A1& __a1, _A2 const& __a2) const {
481 return _VSTD::__invoke(get(), __a0, __a1, __a2);
482 }
483
484 template <class _A0, class _A1, class _A2>
485 _LIBCPP_INLINE_VISIBILITY
486 typename __invoke_return2<type, _A0 const, _A1 const, _A2>::type
487 operator() (_A0 const& __a0, _A1 const& __a1, _A2& __a2) const {
488 return _VSTD::__invoke(get(), __a0, __a1, __a2);
489 }
490
491 template <class _A0, class _A1, class _A2>
492 _LIBCPP_INLINE_VISIBILITY
493 typename __invoke_return2<type, _A0 const, _A1, _A2 const>::type
494 operator() (_A0 const& __a0, _A1& __a1, _A2 const& __a2) const {
495 return _VSTD::__invoke(get(), __a0, __a1, __a2);
496 }
497
498 template <class _A0, class _A1, class _A2>
499 _LIBCPP_INLINE_VISIBILITY
500 typename __invoke_return2<type, _A0, _A1 const, _A2 const>::type
501 operator() (_A0& __a0, _A1 const& __a1, _A2 const& __a2) const {
502 return _VSTD::__invoke(get(), __a0, __a1, __a2);
503 }
504
505 template <class _A0, class _A1, class _A2>
506 _LIBCPP_INLINE_VISIBILITY
507 typename __invoke_return2<type, _A0 const, _A1 const, _A2 const>::type
508 operator() (_A0 const& __a0, _A1 const& __a1, _A2 const& __a2) const {
509 return _VSTD::__invoke(get(), __a0, __a1, __a2);
510 }
511#endif // _LIBCPP_CXX03_LANG
512};
513
514
515template <class _Tp>
516inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
517reference_wrapper<_Tp>
518ref(_Tp& __t) _NOEXCEPT
519{
520 return reference_wrapper<_Tp>(__t);
521}
522
523template <class _Tp>
524inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
525reference_wrapper<_Tp>
526ref(reference_wrapper<_Tp> __t) _NOEXCEPT
527{
528 return _VSTD::ref(__t.get());
529}
530
531template <class _Tp>
532inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
533reference_wrapper<const _Tp>
534cref(const _Tp& __t) _NOEXCEPT
535{
536 return reference_wrapper<const _Tp>(__t);
537}
538
539template <class _Tp>
540inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
541reference_wrapper<const _Tp>
542cref(reference_wrapper<_Tp> __t) _NOEXCEPT
543{
544 return _VSTD::cref(__t.get());
545}
546
547#ifndef _LIBCPP_CXX03_LANG
548template <class _Tp> void ref(const _Tp&&) = delete;
549template <class _Tp> void cref(const _Tp&&) = delete;
550#endif
551
552#if _LIBCPP_STD_VER > 11
553template <class _Tp, class, class = void>
554struct __is_transparent : false_type {};
555
556template <class _Tp, class _Up>
557struct __is_transparent<_Tp, _Up,
558 typename __void_t<typename _Tp::is_transparent>::type>
559 : true_type {};
560#endif
561
562// allocator_arg_t
563
564struct _LIBCPP_TEMPLATE_VIS allocator_arg_t { explicit allocator_arg_t() = default; };
565
566#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY)
567extern _LIBCPP_EXPORTED_FROM_ABI const allocator_arg_t allocator_arg;
568#else
569/* _LIBCPP_INLINE_VAR */ constexpr allocator_arg_t allocator_arg = allocator_arg_t();
570#endif
571
572// uses_allocator
573
574template <class _Tp>
575struct __has_allocator_type
576{
577private:
578 struct __two {char __lx; char __lxx;};
579 template <class _Up> static __two __test(...);
580 template <class _Up> static char __test(typename _Up::allocator_type* = 0);
581public:
582 static const bool value = sizeof(__test<_Tp>(0)) == 1;
583};
584
585template <class _Tp, class _Alloc, bool = __has_allocator_type<_Tp>::value>
586struct __uses_allocator
587 : public integral_constant<bool,
588 is_convertible<_Alloc, typename _Tp::allocator_type>::value>
589{
590};
591
592template <class _Tp, class _Alloc>
593struct __uses_allocator<_Tp, _Alloc, false>
594 : public false_type
595{
596};
597
598template <class _Tp, class _Alloc>
599struct _LIBCPP_TEMPLATE_VIS uses_allocator
600 : public __uses_allocator<_Tp, _Alloc>
601{
602};
603
604#if _LIBCPP_STD_VER > 14
605template <class _Tp, class _Alloc>
606_LIBCPP_INLINE_VAR constexpr size_t uses_allocator_v = uses_allocator<_Tp, _Alloc>::value;
607#endif
608
609#ifndef _LIBCPP_CXX03_LANG
610
611// allocator construction
612
613template <class _Tp, class _Alloc, class ..._Args>
614struct __uses_alloc_ctor_imp
615{
616 typedef _LIBCPP_NODEBUG_TYPE typename __uncvref<_Alloc>::type _RawAlloc;
617 static const bool __ua = uses_allocator<_Tp, _RawAlloc>::value;
618 static const bool __ic =
619 is_constructible<_Tp, allocator_arg_t, _Alloc, _Args...>::value;
620 static const int value = __ua ? 2 - __ic : 0;
621};
622
623template <class _Tp, class _Alloc, class ..._Args>
624struct __uses_alloc_ctor
625 : integral_constant<int, __uses_alloc_ctor_imp<_Tp, _Alloc, _Args...>::value>
626 {};
627
628template <class _Tp, class _Allocator, class... _Args>
629inline _LIBCPP_INLINE_VISIBILITY
630void __user_alloc_construct_impl (integral_constant<int, 0>, _Tp *__storage, const _Allocator &, _Args &&... __args )
631{
632 new (__storage) _Tp (_VSTD::forward<_Args>(__args)...);
633}
634
635// FIXME: This should have a version which takes a non-const alloc.
636template <class _Tp, class _Allocator, class... _Args>
637inline _LIBCPP_INLINE_VISIBILITY
638void __user_alloc_construct_impl (integral_constant<int, 1>, _Tp *__storage, const _Allocator &__a, _Args &&... __args )
639{
640 new (__storage) _Tp (allocator_arg, __a, _VSTD::forward<_Args>(__args)...);
641}
642
643// FIXME: This should have a version which takes a non-const alloc.
644template <class _Tp, class _Allocator, class... _Args>
645inline _LIBCPP_INLINE_VISIBILITY
646void __user_alloc_construct_impl (integral_constant<int, 2>, _Tp *__storage, const _Allocator &__a, _Args &&... __args )
647{
648 new (__storage) _Tp (_VSTD::forward<_Args>(__args)..., __a);
649}
650
651#endif // _LIBCPP_CXX03_LANG
652
653_LIBCPP_END_NAMESPACE_STD
654
655#endif // _LIBCPP_FUNCTIONAL_BASE
32#endif // _LIBCPP_FUNCTIONAL_BASE
lib/libcxx/include/__functional_base_03 deleted-223
......@@ -1,223 +0,0 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP_FUNCTIONAL_BASE_03
11#define _LIBCPP_FUNCTIONAL_BASE_03
12
13// manual variadic expansion for <functional>
14
15// __invoke
16
17template <class _Ret, class _T1, bool _IsFunc, bool _IsBase>
18struct __enable_invoke_imp;
19
20template <class _Ret, class _T1>
21struct __enable_invoke_imp<_Ret, _T1, true, true> {
22 typedef _Ret _Bullet1;
23 typedef _Bullet1 type;
24};
25
26template <class _Ret, class _T1>
27struct __enable_invoke_imp<_Ret, _T1, true, false> {
28 typedef _Ret _Bullet2;
29 typedef _Bullet2 type;
30};
31
32template <class _Ret, class _T1>
33struct __enable_invoke_imp<_Ret, _T1, false, true> {
34 typedef typename add_lvalue_reference<
35 typename __apply_cv<_T1, _Ret>::type
36 >::type _Bullet3;
37 typedef _Bullet3 type;
38};
39
40template <class _Ret, class _T1>
41struct __enable_invoke_imp<_Ret, _T1, false, false> {
42 typedef typename add_lvalue_reference<
43 typename __apply_cv<decltype(*declval<_T1>()), _Ret>::type
44 >::type _Bullet4;
45 typedef _Bullet4 type;
46};
47
48template <class _Ret, class _T1>
49struct __enable_invoke_imp<_Ret, _T1*, false, false> {
50 typedef typename add_lvalue_reference<
51 typename __apply_cv<_T1, _Ret>::type
52 >::type _Bullet4;
53 typedef _Bullet4 type;
54};
55
56template <class _Fn, class _T1,
57 class _Traits = __member_pointer_traits<_Fn>,
58 class _Ret = typename _Traits::_ReturnType,
59 class _Class = typename _Traits::_ClassType>
60struct __enable_invoke : __enable_invoke_imp<
61 _Ret, _T1,
62 is_member_function_pointer<_Fn>::value,
63 is_base_of<_Class, typename remove_reference<_T1>::type>::value>
64{
65};
66
67__nat __invoke(__any, ...);
68
69// first bullet
70
71template <class _Fn, class _T1>
72inline _LIBCPP_INLINE_VISIBILITY
73typename __enable_invoke<_Fn, _T1>::_Bullet1
74__invoke(_Fn __f, _T1& __t1) {
75 return (__t1.*__f)();
76}
77
78template <class _Fn, class _T1, class _A0>
79inline _LIBCPP_INLINE_VISIBILITY
80typename __enable_invoke<_Fn, _T1>::_Bullet1
81__invoke(_Fn __f, _T1& __t1, _A0& __a0) {
82 return (__t1.*__f)(__a0);
83}
84
85template <class _Fn, class _T1, class _A0, class _A1>
86inline _LIBCPP_INLINE_VISIBILITY
87typename __enable_invoke<_Fn, _T1>::_Bullet1
88__invoke(_Fn __f, _T1& __t1, _A0& __a0, _A1& __a1) {
89 return (__t1.*__f)(__a0, __a1);
90}
91
92template <class _Fn, class _T1, class _A0, class _A1, class _A2>
93inline _LIBCPP_INLINE_VISIBILITY
94typename __enable_invoke<_Fn, _T1>::_Bullet1
95__invoke(_Fn __f, _T1& __t1, _A0& __a0, _A1& __a1, _A2& __a2) {
96 return (__t1.*__f)(__a0, __a1, __a2);
97}
98
99template <class _Fn, class _T1>
100inline _LIBCPP_INLINE_VISIBILITY
101typename __enable_invoke<_Fn, _T1>::_Bullet2
102__invoke(_Fn __f, _T1& __t1) {
103 return ((*__t1).*__f)();
104}
105
106template <class _Fn, class _T1, class _A0>
107inline _LIBCPP_INLINE_VISIBILITY
108typename __enable_invoke<_Fn, _T1>::_Bullet2
109__invoke(_Fn __f, _T1& __t1, _A0& __a0) {
110 return ((*__t1).*__f)(__a0);
111}
112
113template <class _Fn, class _T1, class _A0, class _A1>
114inline _LIBCPP_INLINE_VISIBILITY
115typename __enable_invoke<_Fn, _T1>::_Bullet2
116__invoke(_Fn __f, _T1& __t1, _A0& __a0, _A1& __a1) {
117 return ((*__t1).*__f)(__a0, __a1);
118}
119
120template <class _Fn, class _T1, class _A0, class _A1, class _A2>
121inline _LIBCPP_INLINE_VISIBILITY
122typename __enable_invoke<_Fn, _T1>::_Bullet2
123__invoke(_Fn __f, _T1& __t1, _A0& __a0, _A1& __a1, _A2& __a2) {
124 return ((*__t1).*__f)(__a0, __a1, __a2);
125}
126
127template <class _Fn, class _T1>
128inline _LIBCPP_INLINE_VISIBILITY
129typename __enable_invoke<_Fn, _T1>::_Bullet3
130__invoke(_Fn __f, _T1& __t1) {
131 return __t1.*__f;
132}
133
134template <class _Fn, class _T1>
135inline _LIBCPP_INLINE_VISIBILITY
136typename __enable_invoke<_Fn, _T1>::_Bullet4
137__invoke(_Fn __f, _T1& __t1) {
138 return (*__t1).*__f;
139}
140
141// fifth bullet
142
143template <class _Fp>
144inline _LIBCPP_INLINE_VISIBILITY
145decltype(declval<_Fp&>()())
146__invoke(_Fp& __f)
147{
148 return __f();
149}
150
151template <class _Fp, class _A0>
152inline _LIBCPP_INLINE_VISIBILITY
153decltype(declval<_Fp&>()(declval<_A0&>()))
154__invoke(_Fp& __f, _A0& __a0)
155{
156 return __f(__a0);
157}
158
159template <class _Fp, class _A0, class _A1>
160inline _LIBCPP_INLINE_VISIBILITY
161decltype(declval<_Fp&>()(declval<_A0&>(), declval<_A1&>()))
162__invoke(_Fp& __f, _A0& __a0, _A1& __a1)
163{
164 return __f(__a0, __a1);
165}
166
167template <class _Fp, class _A0, class _A1, class _A2>
168inline _LIBCPP_INLINE_VISIBILITY
169decltype(declval<_Fp&>()(declval<_A0&>(), declval<_A1&>(), declval<_A2&>()))
170__invoke(_Fp& __f, _A0& __a0, _A1& __a1, _A2& __a2)
171{
172 return __f(__a0, __a1, __a2);
173}
174
175template <class _Fp, bool = __has_result_type<__weak_result_type<_Fp> >::value>
176struct __invoke_return
177{
178 typedef typename __weak_result_type<_Fp>::result_type type;
179};
180
181template <class _Fp>
182struct __invoke_return<_Fp, false>
183{
184 typedef decltype(_VSTD::__invoke(declval<_Fp&>())) type;
185};
186
187template <class _Tp, class _A0>
188struct __invoke_return0
189{
190 typedef decltype(_VSTD::__invoke(declval<_Tp&>(), declval<_A0&>())) type;
191};
192
193template <class _Rp, class _Tp, class _A0>
194struct __invoke_return0<_Rp _Tp::*, _A0>
195{
196 typedef typename __enable_invoke<_Rp _Tp::*, _A0>::type type;
197};
198
199template <class _Tp, class _A0, class _A1>
200struct __invoke_return1
201{
202 typedef decltype(_VSTD::__invoke(declval<_Tp&>(), declval<_A0&>(),
203 declval<_A1&>())) type;
204};
205
206template <class _Rp, class _Class, class _A0, class _A1>
207struct __invoke_return1<_Rp _Class::*, _A0, _A1> {
208 typedef typename __enable_invoke<_Rp _Class::*, _A0>::type type;
209};
210
211template <class _Tp, class _A0, class _A1, class _A2>
212struct __invoke_return2
213{
214 typedef decltype(_VSTD::__invoke(declval<_Tp&>(), declval<_A0&>(),
215 declval<_A1&>(),
216 declval<_A2&>())) type;
217};
218
219template <class _Ret, class _Class, class _A0, class _A1, class _A2>
220struct __invoke_return2<_Ret _Class::*, _A0, _A1, _A2> {
221 typedef typename __enable_invoke<_Ret _Class::*, _A0>::type type;
222};
223#endif // _LIBCPP_FUNCTIONAL_BASE_03
lib/libcxx/include/__hash_table+33-33
......@@ -10,16 +10,16 @@
1010#ifndef _LIBCPP__HASH_TABLE
1111#define _LIBCPP__HASH_TABLE
1212
13#include <__bits> // __libcpp_clz
1314#include <__config>
14#include <initializer_list>
15#include <memory>
16#include <iterator>
15#include <__debug>
1716#include <algorithm>
1817#include <cmath>
19#include <utility>
18#include <initializer_list>
19#include <iterator>
20#include <memory>
2021#include <type_traits>
21
22#include <__debug>
22#include <utility>
2323
2424#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2525#pragma GCC system_header
......@@ -89,7 +89,7 @@ struct __hash_node_base
8989};
9090
9191template <class _Tp, class _VoidPtr>
92struct __hash_node
92struct _LIBCPP_STANDALONE_DEBUG __hash_node
9393 : public __hash_node_base
9494 <
9595 typename __rebind_pointer<_VoidPtr, __hash_node<_Tp, _VoidPtr> >::type
......@@ -317,7 +317,7 @@ public:
317317 }
318318 return *this;
319319 }
320#endif // _LIBCPP_DEBUG_LEVEL == 2
320#endif // _LIBCPP_DEBUG_LEVEL == 2
321321
322322 _LIBCPP_INLINE_VISIBILITY
323323 reference operator*() const {
......@@ -336,7 +336,7 @@ public:
336336 _LIBCPP_INLINE_VISIBILITY
337337 __hash_iterator& operator++() {
338338 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
339 "Attempted to increment non-incrementable unordered container iterator");
339 "Attempted to increment a non-incrementable unordered container iterator");
340340 __node_ = __node_->__next_;
341341 return *this;
342342 }
......@@ -438,7 +438,7 @@ public:
438438 }
439439 return *this;
440440 }
441#endif // _LIBCPP_DEBUG_LEVEL == 2
441#endif // _LIBCPP_DEBUG_LEVEL == 2
442442
443443 _LIBCPP_INLINE_VISIBILITY
444444 reference operator*() const {
......@@ -456,7 +456,7 @@ public:
456456 _LIBCPP_INLINE_VISIBILITY
457457 __hash_const_iterator& operator++() {
458458 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
459 "Attempted to increment non-incrementable unordered container const_iterator");
459 "Attempted to increment a non-incrementable unordered container const_iterator");
460460 __node_ = __node_->__next_;
461461 return *this;
462462 }
......@@ -550,7 +550,7 @@ public:
550550 }
551551 return *this;
552552 }
553#endif // _LIBCPP_DEBUG_LEVEL == 2
553#endif // _LIBCPP_DEBUG_LEVEL == 2
554554
555555 _LIBCPP_INLINE_VISIBILITY
556556 reference operator*() const {
......@@ -569,7 +569,7 @@ public:
569569 _LIBCPP_INLINE_VISIBILITY
570570 __hash_local_iterator& operator++() {
571571 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
572 "Attempted to increment non-incrementable unordered container local_iterator");
572 "Attempted to increment a non-incrementable unordered container local_iterator");
573573 __node_ = __node_->__next_;
574574 if (__node_ != nullptr && __constrain_hash(__node_->__hash(), __bucket_count_) != __bucket_)
575575 __node_ = nullptr;
......@@ -695,7 +695,7 @@ public:
695695 }
696696 return *this;
697697 }
698#endif // _LIBCPP_DEBUG_LEVEL == 2
698#endif // _LIBCPP_DEBUG_LEVEL == 2
699699
700700 _LIBCPP_INLINE_VISIBILITY
701701 reference operator*() const {
......@@ -714,7 +714,7 @@ public:
714714 _LIBCPP_INLINE_VISIBILITY
715715 __hash_const_local_iterator& operator++() {
716716 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
717 "Attempted to increment non-incrementable unordered container const_local_iterator");
717 "Attempted to increment a non-incrementable unordered container const_local_iterator");
718718 __node_ = __node_->__next_;
719719 if (__node_ != nullptr && __constrain_hash(__node_->__hash(), __bucket_count_) != __bucket_)
720720 __node_ = nullptr;
......@@ -741,9 +741,9 @@ public:
741741private:
742742#if _LIBCPP_DEBUG_LEVEL == 2
743743 _LIBCPP_INLINE_VISIBILITY
744 __hash_const_local_iterator(__next_pointer __node, size_t __bucket,
744 __hash_const_local_iterator(__next_pointer __node_ptr, size_t __bucket,
745745 size_t __bucket_count, const void* __c) _NOEXCEPT
746 : __node_(__node),
746 : __node_(__node_ptr),
747747 __bucket_(__bucket),
748748 __bucket_count_(__bucket_count)
749749 {
......@@ -753,9 +753,9 @@ private:
753753 }
754754#else
755755 _LIBCPP_INLINE_VISIBILITY
756 __hash_const_local_iterator(__next_pointer __node, size_t __bucket,
756 __hash_const_local_iterator(__next_pointer __node_ptr, size_t __bucket,
757757 size_t __bucket_count) _NOEXCEPT
758 : __node_(__node),
758 : __node_(__node_ptr),
759759 __bucket_(__bucket),
760760 __bucket_count_(__bucket_count)
761761 {
......@@ -1337,7 +1337,7 @@ public:
13371337 bool __addable(const const_iterator* __i, ptrdiff_t __n) const;
13381338 bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const;
13391339
1340#endif // _LIBCPP_DEBUG_LEVEL == 2
1340#endif // _LIBCPP_DEBUG_LEVEL == 2
13411341
13421342private:
13431343 void __rehash(size_type __n);
......@@ -1645,7 +1645,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign(
16451645#ifndef _LIBCPP_NO_EXCEPTIONS
16461646 try
16471647 {
1648#endif // _LIBCPP_NO_EXCEPTIONS
1648#endif // _LIBCPP_NO_EXCEPTIONS
16491649 const_iterator __i = __u.begin();
16501650 while (__cache != nullptr && __u.size() != 0)
16511651 {
......@@ -1662,7 +1662,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign(
16621662 __deallocate_node(__cache);
16631663 throw;
16641664 }
1665#endif // _LIBCPP_NO_EXCEPTIONS
1665#endif // _LIBCPP_NO_EXCEPTIONS
16661666 __deallocate_node(__cache);
16671667 }
16681668 const_iterator __i = __u.begin();
......@@ -1707,7 +1707,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_unique(_InputIterator __first
17071707#ifndef _LIBCPP_NO_EXCEPTIONS
17081708 try
17091709 {
1710#endif // _LIBCPP_NO_EXCEPTIONS
1710#endif // _LIBCPP_NO_EXCEPTIONS
17111711 for (; __cache != nullptr && __first != __last; ++__first)
17121712 {
17131713 __cache->__upcast()->__value_ = *__first;
......@@ -1722,7 +1722,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_unique(_InputIterator __first
17221722 __deallocate_node(__cache);
17231723 throw;
17241724 }
1725#endif // _LIBCPP_NO_EXCEPTIONS
1725#endif // _LIBCPP_NO_EXCEPTIONS
17261726 __deallocate_node(__cache);
17271727 }
17281728 for (; __first != __last; ++__first)
......@@ -1747,7 +1747,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_multi(_InputIterator __first,
17471747#ifndef _LIBCPP_NO_EXCEPTIONS
17481748 try
17491749 {
1750#endif // _LIBCPP_NO_EXCEPTIONS
1750#endif // _LIBCPP_NO_EXCEPTIONS
17511751 for (; __cache != nullptr && __first != __last; ++__first)
17521752 {
17531753 __cache->__upcast()->__value_ = *__first;
......@@ -1762,7 +1762,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_multi(_InputIterator __first,
17621762 __deallocate_node(__cache);
17631763 throw;
17641764 }
1765#endif // _LIBCPP_NO_EXCEPTIONS
1765#endif // _LIBCPP_NO_EXCEPTIONS
17661766 __deallocate_node(__cache);
17671767 }
17681768 for (; __first != __last; ++__first)
......@@ -2299,7 +2299,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_merge_multi(
22992299 __node_insert_multi_perform(__src_ptr, __pn);
23002300 }
23012301}
2302#endif // _LIBCPP_STD_VER > 14
2302#endif // _LIBCPP_STD_VER > 14
23032303
23042304template <class _Tp, class _Hash, class _Equal, class _Alloc>
23052305void
......@@ -2506,11 +2506,11 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::erase(const_iterator __first,
25062506{
25072507#if _LIBCPP_DEBUG_LEVEL == 2
25082508 _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__first) == this,
2509 "unodered container::erase(iterator, iterator) called with an iterator not"
2510 " referring to this unodered container");
2509 "unordered container::erase(iterator, iterator) called with an iterator not"
2510 " referring to this container");
25112511 _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__last) == this,
2512 "unodered container::erase(iterator, iterator) called with an iterator not"
2513 " referring to this unodered container");
2512 "unordered container::erase(iterator, iterator) called with an iterator not"
2513 " referring to this container");
25142514#endif
25152515 for (const_iterator __p = __first; __first != __last; __p = __first)
25162516 {
......@@ -2804,10 +2804,10 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__subscriptable(const const_iterator*,
28042804 return false;
28052805}
28062806
2807#endif // _LIBCPP_DEBUG_LEVEL == 2
2807#endif // _LIBCPP_DEBUG_LEVEL == 2
28082808
28092809_LIBCPP_END_NAMESPACE_STD
28102810
28112811_LIBCPP_POP_MACROS
28122812
2813#endif // _LIBCPP__HASH_TABLE
2813#endif // _LIBCPP__HASH_TABLE
lib/libcxx/include/__iterator/access.h created+134
......@@ -0,0 +1,134 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___ITERATOR_ACCESS_H
11#define _LIBCPP___ITERATOR_ACCESS_H
12
13#include <__config>
14#include <cstddef>
15
16#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
17#pragma GCC system_header
18#endif
19
20_LIBCPP_PUSH_MACROS
21#include <__undef_macros>
22
23_LIBCPP_BEGIN_NAMESPACE_STD
24
25template <class _Tp, size_t _Np>
26_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
27_Tp*
28begin(_Tp (&__array)[_Np])
29{
30 return __array;
31}
32
33template <class _Tp, size_t _Np>
34_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
35_Tp*
36end(_Tp (&__array)[_Np])
37{
38 return __array + _Np;
39}
40
41#if !defined(_LIBCPP_CXX03_LANG)
42
43template <class _Cp>
44_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
45auto
46begin(_Cp& __c) -> decltype(__c.begin())
47{
48 return __c.begin();
49}
50
51template <class _Cp>
52_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
53auto
54begin(const _Cp& __c) -> decltype(__c.begin())
55{
56 return __c.begin();
57}
58
59template <class _Cp>
60_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
61auto
62end(_Cp& __c) -> decltype(__c.end())
63{
64 return __c.end();
65}
66
67template <class _Cp>
68_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
69auto
70end(const _Cp& __c) -> decltype(__c.end())
71{
72 return __c.end();
73}
74
75#if _LIBCPP_STD_VER > 11
76
77template <class _Cp>
78_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
79auto cbegin(const _Cp& __c) -> decltype(_VSTD::begin(__c))
80{
81 return _VSTD::begin(__c);
82}
83
84template <class _Cp>
85_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
86auto cend(const _Cp& __c) -> decltype(_VSTD::end(__c))
87{
88 return _VSTD::end(__c);
89}
90
91#endif
92
93
94#else // defined(_LIBCPP_CXX03_LANG)
95
96template <class _Cp>
97_LIBCPP_INLINE_VISIBILITY
98typename _Cp::iterator
99begin(_Cp& __c)
100{
101 return __c.begin();
102}
103
104template <class _Cp>
105_LIBCPP_INLINE_VISIBILITY
106typename _Cp::const_iterator
107begin(const _Cp& __c)
108{
109 return __c.begin();
110}
111
112template <class _Cp>
113_LIBCPP_INLINE_VISIBILITY
114typename _Cp::iterator
115end(_Cp& __c)
116{
117 return __c.end();
118}
119
120template <class _Cp>
121_LIBCPP_INLINE_VISIBILITY
122typename _Cp::const_iterator
123end(const _Cp& __c)
124{
125 return __c.end();
126}
127
128#endif // !defined(_LIBCPP_CXX03_LANG)
129
130_LIBCPP_END_NAMESPACE_STD
131
132_LIBCPP_POP_MACROS
133
134#endif // _LIBCPP___ITERATOR_ACCESS_H
lib/libcxx/include/__iterator/advance.h created+200
......@@ -0,0 +1,200 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___ITERATOR_ADVANCE_H
11#define _LIBCPP___ITERATOR_ADVANCE_H
12
13#include <__config>
14#include <__debug>
15#include <__function_like.h>
16#include <__iterator/concepts.h>
17#include <__iterator/incrementable_traits.h>
18#include <__iterator/iterator_traits.h>
19#include <__utility/move.h>
20#include <cstdlib>
21#include <concepts>
22#include <limits>
23#include <type_traits>
24
25#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
26#pragma GCC system_header
27#endif
28
29_LIBCPP_PUSH_MACROS
30#include <__undef_macros>
31
32_LIBCPP_BEGIN_NAMESPACE_STD
33
34template <class _InputIter>
35_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14
36void __advance(_InputIter& __i, typename iterator_traits<_InputIter>::difference_type __n, input_iterator_tag) {
37 for (; __n > 0; --__n)
38 ++__i;
39}
40
41template <class _BiDirIter>
42_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14
43void __advance(_BiDirIter& __i, typename iterator_traits<_BiDirIter>::difference_type __n, bidirectional_iterator_tag) {
44 if (__n >= 0)
45 for (; __n > 0; --__n)
46 ++__i;
47 else
48 for (; __n < 0; ++__n)
49 --__i;
50}
51
52template <class _RandIter>
53_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14
54void __advance(_RandIter& __i, typename iterator_traits<_RandIter>::difference_type __n, random_access_iterator_tag) {
55 __i += __n;
56}
57
58template <
59 class _InputIter, class _Distance,
60 class _IntegralDistance = decltype(_VSTD::__convert_to_integral(declval<_Distance>())),
61 class = _EnableIf<is_integral<_IntegralDistance>::value> >
62_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14
63void advance(_InputIter& __i, _Distance __orig_n) {
64 typedef typename iterator_traits<_InputIter>::difference_type _Difference;
65 _Difference __n = static_cast<_Difference>(_VSTD::__convert_to_integral(__orig_n));
66 _LIBCPP_ASSERT(__n >= 0 || __is_cpp17_bidirectional_iterator<_InputIter>::value,
67 "Attempt to advance(it, n) with negative n on a non-bidirectional iterator");
68 _VSTD::__advance(__i, __n, typename iterator_traits<_InputIter>::iterator_category());
69}
70
71#if !defined(_LIBCPP_HAS_NO_RANGES)
72
73namespace ranges {
74// [range.iter.op.advance]
75struct __advance_fn final : private __function_like {
76private:
77 template <class _Tp>
78 _LIBCPP_HIDE_FROM_ABI
79 static constexpr _Tp __magnitude_geq(_Tp __a, _Tp __b) noexcept {
80 return __a < 0 ? (__a <= __b) : (__a >= __b);
81 }
82
83 template <class _Ip>
84 _LIBCPP_HIDE_FROM_ABI
85 static constexpr void __advance_forward(_Ip& __i, iter_difference_t<_Ip> __n) {
86 while (__n > 0) {
87 --__n;
88 ++__i;
89 }
90 }
91
92 template <class _Ip>
93 _LIBCPP_HIDE_FROM_ABI
94 static constexpr void __advance_backward(_Ip& __i, iter_difference_t<_Ip> __n) {
95 while (__n < 0) {
96 ++__n;
97 --__i;
98 }
99 }
100
101public:
102 constexpr explicit __advance_fn(__tag __x) noexcept : __function_like(__x) {}
103
104 // Preconditions: If `I` does not model `bidirectional_iterator`, `n` is not negative.
105 template <input_or_output_iterator _Ip>
106 _LIBCPP_HIDE_FROM_ABI
107 constexpr void operator()(_Ip& __i, iter_difference_t<_Ip> __n) const {
108 _LIBCPP_ASSERT(__n >= 0 || bidirectional_iterator<_Ip>,
109 "If `n < 0`, then `bidirectional_iterator<I>` must be true.");
110
111 // If `I` models `random_access_iterator`, equivalent to `i += n`.
112 if constexpr (random_access_iterator<_Ip>) {
113 __i += __n;
114 return;
115 } else if constexpr (bidirectional_iterator<_Ip>) {
116 // Otherwise, if `n` is non-negative, increments `i` by `n`.
117 __advance_forward(__i, __n);
118 // Otherwise, decrements `i` by `-n`.
119 __advance_backward(__i, __n);
120 return;
121 } else {
122 // Otherwise, if `n` is non-negative, increments `i` by `n`.
123 __advance_forward(__i, __n);
124 return;
125 }
126 }
127
128 // Preconditions: Either `assignable_from<I&, S> || sized_sentinel_for<S, I>` is modeled, or [i, bound) denotes a range.
129 template <input_or_output_iterator _Ip, sentinel_for<_Ip> _Sp>
130 _LIBCPP_HIDE_FROM_ABI
131 constexpr void operator()(_Ip& __i, _Sp __bound) const {
132 // If `I` and `S` model `assignable_from<I&, S>`, equivalent to `i = std::move(bound)`.
133 if constexpr (assignable_from<_Ip&, _Sp>) {
134 __i = _VSTD::move(__bound);
135 }
136 // Otherwise, if `S` and `I` model `sized_sentinel_for<S, I>`, equivalent to `ranges::advance(i, bound - i)`.
137 else if constexpr (sized_sentinel_for<_Sp, _Ip>) {
138 (*this)(__i, __bound - __i);
139 }
140 // Otherwise, while `bool(i != bound)` is true, increments `i`.
141 else {
142 while (__i != __bound) {
143 ++__i;
144 }
145 }
146 }
147
148 // Preconditions:
149 // * If `n > 0`, [i, bound) denotes a range.
150 // * If `n == 0`, [i, bound) or [bound, i) denotes a range.
151 // * If `n < 0`, [bound, i) denotes a range, `I` models `bidirectional_iterator`, and `I` and `S` model `same_as<I, S>`.
152 // Returns: `n - M`, where `M` is the difference between the the ending and starting position.
153 template <input_or_output_iterator _Ip, sentinel_for<_Ip> _Sp>
154 _LIBCPP_HIDE_FROM_ABI
155 constexpr iter_difference_t<_Ip> operator()(_Ip& __i, iter_difference_t<_Ip> __n, _Sp __bound) const {
156 _LIBCPP_ASSERT((__n >= 0) || (bidirectional_iterator<_Ip> && same_as<_Ip, _Sp>),
157 "If `n < 0`, then `bidirectional_iterator<I> && same_as<I, S>` must be true.");
158 // If `S` and `I` model `sized_sentinel_for<S, I>`:
159 if constexpr (sized_sentinel_for<_Sp, _Ip>) {
160 // If |n| >= |bound - i|, equivalent to `ranges::advance(i, bound)`.
161 if (const auto __M = __bound - __i; __magnitude_geq(__n, __M)) {
162 (*this)(__i, __bound);
163 return __n - __M;
164 }
165
166 // Otherwise, equivalent to `ranges::advance(i, n)`.
167 (*this)(__i, __n);
168 return 0;
169 } else {
170 // Otherwise, if `n` is non-negative, while `bool(i != bound)` is true, increments `i` but at
171 // most `n` times.
172 while (__i != __bound && __n > 0) {
173 ++__i;
174 --__n;
175 }
176
177 // Otherwise, while `bool(i != bound)` is true, decrements `i` but at most `-n` times.
178 if constexpr (bidirectional_iterator<_Ip> && same_as<_Ip, _Sp>) {
179 while (__i != __bound && __n < 0) {
180 --__i;
181 ++__n;
182 }
183 }
184 return __n;
185 }
186
187 _LIBCPP_UNREACHABLE();
188 }
189};
190
191inline constexpr auto advance = __advance_fn(__function_like::__tag());
192} // namespace ranges
193
194#endif // !defined(_LIBCPP_HAS_NO_RANGES)
195
196_LIBCPP_END_NAMESPACE_STD
197
198_LIBCPP_POP_MACROS
199
200#endif // _LIBCPP___ITERATOR_ADVANCE_H
lib/libcxx/include/__iterator/back_insert_iterator.h created+75
......@@ -0,0 +1,75 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___ITERATOR_BACK_INSERT_ITERATOR_H
11#define _LIBCPP___ITERATOR_BACK_INSERT_ITERATOR_H
12
13#include <__config>
14#include <__iterator/iterator.h>
15#include <__iterator/iterator_traits.h>
16#include <__memory/addressof.h>
17#include <__utility/move.h>
18#include <cstddef>
19
20#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
21#pragma GCC system_header
22#endif
23
24_LIBCPP_PUSH_MACROS
25#include <__undef_macros>
26
27_LIBCPP_BEGIN_NAMESPACE_STD
28
29_LIBCPP_SUPPRESS_DEPRECATED_PUSH
30template <class _Container>
31class _LIBCPP_TEMPLATE_VIS back_insert_iterator
32#if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES)
33 : public iterator<output_iterator_tag, void, void, void, void>
34#endif
35{
36_LIBCPP_SUPPRESS_DEPRECATED_POP
37protected:
38 _Container* container;
39public:
40 typedef output_iterator_tag iterator_category;
41 typedef void value_type;
42#if _LIBCPP_STD_VER > 17
43 typedef ptrdiff_t difference_type;
44#else
45 typedef void difference_type;
46#endif
47 typedef void pointer;
48 typedef void reference;
49 typedef _Container container_type;
50
51 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 explicit back_insert_iterator(_Container& __x) : container(_VSTD::addressof(__x)) {}
52 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 back_insert_iterator& operator=(const typename _Container::value_type& __value_)
53 {container->push_back(__value_); return *this;}
54#ifndef _LIBCPP_CXX03_LANG
55 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 back_insert_iterator& operator=(typename _Container::value_type&& __value_)
56 {container->push_back(_VSTD::move(__value_)); return *this;}
57#endif // _LIBCPP_CXX03_LANG
58 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 back_insert_iterator& operator*() {return *this;}
59 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 back_insert_iterator& operator++() {return *this;}
60 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 back_insert_iterator operator++(int) {return *this;}
61};
62
63template <class _Container>
64inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
65back_insert_iterator<_Container>
66back_inserter(_Container& __x)
67{
68 return back_insert_iterator<_Container>(__x);
69}
70
71_LIBCPP_END_NAMESPACE_STD
72
73_LIBCPP_POP_MACROS
74
75#endif // _LIBCPP___ITERATOR_BACK_INSERT_ITERATOR_H
lib/libcxx/include/__iterator/common_iterator.h created+301
......@@ -0,0 +1,301 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___ITERATOR_COMMON_ITERATOR_H
11#define _LIBCPP___ITERATOR_COMMON_ITERATOR_H
12
13#include <__config>
14#include <__debug>
15#include <__iterator/concepts.h>
16#include <__iterator/incrementable_traits.h>
17#include <__iterator/iter_move.h>
18#include <__iterator/iter_swap.h>
19#include <__iterator/iterator_traits.h>
20#include <__iterator/readable_traits.h>
21#include <concepts>
22#include <variant>
23
24#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
25#pragma GCC system_header
26#endif
27
28_LIBCPP_PUSH_MACROS
29#include <__undef_macros>
30
31_LIBCPP_BEGIN_NAMESPACE_STD
32
33#if !defined(_LIBCPP_HAS_NO_RANGES)
34
35template<input_or_output_iterator _Iter, sentinel_for<_Iter> _Sent>
36 requires (!same_as<_Iter, _Sent> && copyable<_Iter>)
37class common_iterator {
38 class __proxy {
39 friend common_iterator;
40
41 iter_value_t<_Iter> __value;
42 // We can move __x because the only caller verifies that __x is not a reference.
43 constexpr __proxy(iter_reference_t<_Iter>&& __x)
44 : __value(_VSTD::move(__x)) {}
45
46 public:
47 const iter_value_t<_Iter>* operator->() const {
48 return _VSTD::addressof(__value);
49 }
50 };
51
52 class __postfix_proxy {
53 friend common_iterator;
54
55 iter_value_t<_Iter> __value;
56 constexpr __postfix_proxy(iter_reference_t<_Iter>&& __x)
57 : __value(_VSTD::forward<iter_reference_t<_Iter>>(__x)) {}
58
59 public:
60 constexpr static bool __valid_for_iter =
61 constructible_from<iter_value_t<_Iter>, iter_reference_t<_Iter>> &&
62 move_constructible<iter_value_t<_Iter>>;
63
64 const iter_value_t<_Iter>& operator*() const {
65 return __value;
66 }
67 };
68
69public:
70 variant<_Iter, _Sent> __hold_;
71
72 common_iterator() requires default_initializable<_Iter> = default;
73
74 constexpr common_iterator(_Iter __i) : __hold_(in_place_type<_Iter>, _VSTD::move(__i)) {}
75 constexpr common_iterator(_Sent __s) : __hold_(in_place_type<_Sent>, _VSTD::move(__s)) {}
76
77 template<class _I2, class _S2>
78 requires convertible_to<const _I2&, _Iter> && convertible_to<const _S2&, _Sent>
79 constexpr common_iterator(const common_iterator<_I2, _S2>& __other)
80 : __hold_([&]() -> variant<_Iter, _Sent> {
81 _LIBCPP_ASSERT(!__other.__hold_.valueless_by_exception(), "Constructed from valueless iterator.");
82 if (__other.__hold_.index() == 0)
83 return variant<_Iter, _Sent>{in_place_index<0>, _VSTD::__unchecked_get<0>(__other.__hold_)};
84 return variant<_Iter, _Sent>{in_place_index<1>, _VSTD::__unchecked_get<1>(__other.__hold_)};
85 }()) {}
86
87 template<class _I2, class _S2>
88 requires convertible_to<const _I2&, _Iter> && convertible_to<const _S2&, _Sent> &&
89 assignable_from<_Iter&, const _I2&> && assignable_from<_Sent&, const _S2&>
90 common_iterator& operator=(const common_iterator<_I2, _S2>& __other) {
91 _LIBCPP_ASSERT(!__other.__hold_.valueless_by_exception(), "Assigned from valueless iterator.");
92
93 auto __idx = __hold_.index();
94 auto __other_idx = __other.__hold_.index();
95
96 // If they're the same index, just assign.
97 if (__idx == 0 && __other_idx == 0)
98 _VSTD::__unchecked_get<0>(__hold_) = _VSTD::__unchecked_get<0>(__other.__hold_);
99 else if (__idx == 1 && __other_idx == 1)
100 _VSTD::__unchecked_get<1>(__hold_) = _VSTD::__unchecked_get<1>(__other.__hold_);
101
102 // Otherwise replace with the oposite element.
103 else if (__other_idx == 1)
104 __hold_.template emplace<1>(_VSTD::__unchecked_get<1>(__other.__hold_));
105 else if (__other_idx == 0)
106 __hold_.template emplace<0>(_VSTD::__unchecked_get<0>(__other.__hold_));
107
108 return *this;
109 }
110
111 decltype(auto) operator*()
112 {
113 _LIBCPP_ASSERT(holds_alternative<_Iter>(__hold_),
114 "Cannot dereference sentinel. Common iterator not holding an iterator.");
115 return *_VSTD::__unchecked_get<_Iter>(__hold_);
116 }
117
118 decltype(auto) operator*() const
119 requires __dereferenceable<const _Iter>
120 {
121 _LIBCPP_ASSERT(holds_alternative<_Iter>(__hold_),
122 "Cannot dereference sentinel. Common iterator not holding an iterator.");
123 return *_VSTD::__unchecked_get<_Iter>(__hold_);
124 }
125
126 template<class _I2 = _Iter>
127 decltype(auto) operator->() const
128 requires indirectly_readable<const _I2> &&
129 (requires(const _I2& __i) { __i.operator->(); } ||
130 is_reference_v<iter_reference_t<_I2>> ||
131 constructible_from<iter_value_t<_I2>, iter_reference_t<_I2>>)
132 {
133 _LIBCPP_ASSERT(holds_alternative<_Iter>(__hold_),
134 "Cannot dereference sentinel. Common iterator not holding an iterator.");
135
136 if constexpr (is_pointer_v<_Iter> || requires(const _Iter& __i) { __i.operator->(); }) {
137 return _VSTD::__unchecked_get<_Iter>(__hold_);
138 } else if constexpr (is_reference_v<iter_reference_t<_Iter>>) {
139 auto&& __tmp = *_VSTD::__unchecked_get<_Iter>(__hold_);
140 return _VSTD::addressof(__tmp);
141 } else {
142 return __proxy(*_VSTD::__unchecked_get<_Iter>(__hold_));
143 }
144 }
145
146 common_iterator& operator++() {
147 _LIBCPP_ASSERT(holds_alternative<_Iter>(__hold_),
148 "Cannot increment sentinel. Common iterator not holding an iterator.");
149 ++_VSTD::__unchecked_get<_Iter>(__hold_); return *this;
150 }
151
152 decltype(auto) operator++(int) {
153 _LIBCPP_ASSERT(holds_alternative<_Iter>(__hold_),
154 "Cannot increment sentinel. Common iterator not holding an iterator.");
155
156 if constexpr (forward_iterator<_Iter>) {
157 auto __tmp = *this;
158 ++*this;
159 return __tmp;
160 } else if constexpr (requires (_Iter& __i) { { *__i++ } -> __referenceable; } ||
161 !__postfix_proxy::__valid_for_iter) {
162 return _VSTD::__unchecked_get<_Iter>(__hold_)++;
163 } else {
164 __postfix_proxy __p(**this);
165 ++*this;
166 return __p;
167 }
168 }
169
170 template<class _I2, sentinel_for<_Iter> _S2>
171 requires sentinel_for<_Sent, _I2>
172 friend bool operator==(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) {
173 _LIBCPP_ASSERT(!__x.__hold_.valueless_by_exception() &&
174 !__y.__hold_.valueless_by_exception(),
175 "One or both common_iterators are valueless. (Cannot compare valueless iterators.)");
176
177 auto __x_index = __x.__hold_.index();
178 auto __y_index = __y.__hold_.index();
179
180 if (__x_index == __y_index)
181 return true;
182
183 if (__x_index == 0)
184 return _VSTD::__unchecked_get<_Iter>(__x.__hold_) == _VSTD::__unchecked_get<_S2>(__y.__hold_);
185
186 return _VSTD::__unchecked_get<_Sent>(__x.__hold_) == _VSTD::__unchecked_get<_I2>(__y.__hold_);
187 }
188
189 template<class _I2, sentinel_for<_Iter> _S2>
190 requires sentinel_for<_Sent, _I2> && equality_comparable_with<_Iter, _I2>
191 friend bool operator==(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) {
192 _LIBCPP_ASSERT(!__x.__hold_.valueless_by_exception() &&
193 !__y.__hold_.valueless_by_exception(),
194 "One or both common_iterators are valueless. (Cannot compare valueless iterators.)");
195
196 auto __x_index = __x.__hold_.index();
197 auto __y_index = __y.__hold_.index();
198
199 if (__x_index == 1 && __y_index == 1)
200 return true;
201
202 if (__x_index == 0 && __y_index == 0)
203 return _VSTD::__unchecked_get<_Iter>(__x.__hold_) == _VSTD::__unchecked_get<_I2>(__y.__hold_);
204
205 if (__x_index == 0)
206 return _VSTD::__unchecked_get<_Iter>(__x.__hold_) == _VSTD::__unchecked_get<_S2>(__y.__hold_);
207
208 return _VSTD::__unchecked_get<_Sent>(__x.__hold_) == _VSTD::__unchecked_get<_I2>(__y.__hold_);
209 }
210
211 template<sized_sentinel_for<_Iter> _I2, sized_sentinel_for<_Iter> _S2>
212 requires sized_sentinel_for<_Sent, _I2>
213 friend iter_difference_t<_I2> operator-(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) {
214 _LIBCPP_ASSERT(!__x.__hold_.valueless_by_exception() &&
215 !__y.__hold_.valueless_by_exception(),
216 "One or both common_iterators are valueless. (Cannot subtract valueless iterators.)");
217
218 auto __x_index = __x.__hold_.index();
219 auto __y_index = __y.__hold_.index();
220
221 if (__x_index == 1 && __y_index == 1)
222 return 0;
223
224 if (__x_index == 0 && __y_index == 0)
225 return _VSTD::__unchecked_get<_Iter>(__x.__hold_) - _VSTD::__unchecked_get<_I2>(__y.__hold_);
226
227 if (__x_index == 0)
228 return _VSTD::__unchecked_get<_Iter>(__x.__hold_) - _VSTD::__unchecked_get<_S2>(__y.__hold_);
229
230 return _VSTD::__unchecked_get<_Sent>(__x.__hold_) - _VSTD::__unchecked_get<_I2>(__y.__hold_);
231 }
232
233 friend iter_rvalue_reference_t<_Iter> iter_move(const common_iterator& __i)
234 noexcept(noexcept(ranges::iter_move(declval<const _Iter&>())))
235 requires input_iterator<_Iter>
236 {
237 _LIBCPP_ASSERT(holds_alternative<_Iter>(__i.__hold_),
238 "Cannot iter_move a sentinel. Common iterator not holding an iterator.");
239 return ranges::iter_move( _VSTD::__unchecked_get<_Iter>(__i.__hold_));
240 }
241
242 template<indirectly_swappable<_Iter> _I2, class _S2>
243 friend void iter_swap(const common_iterator& __x, const common_iterator<_I2, _S2>& __y)
244 noexcept(noexcept(ranges::iter_swap(declval<const _Iter&>(), declval<const _I2&>())))
245 {
246 _LIBCPP_ASSERT(holds_alternative<_Iter>(__x.__hold_),
247 "Cannot swap __y with a sentinel. Common iterator (__x) not holding an iterator.");
248 _LIBCPP_ASSERT(holds_alternative<_Iter>(__y.__hold_),
249 "Cannot swap __x with a sentinel. Common iterator (__y) not holding an iterator.");
250 return ranges::iter_swap( _VSTD::__unchecked_get<_Iter>(__x.__hold_), _VSTD::__unchecked_get<_Iter>(__y.__hold_));
251 }
252};
253
254template<class _Iter, class _Sent>
255struct incrementable_traits<common_iterator<_Iter, _Sent>> {
256 using difference_type = iter_difference_t<_Iter>;
257};
258
259template<class _Iter>
260concept __denotes_forward_iter =
261 requires { typename iterator_traits<_Iter>::iterator_category; } &&
262 derived_from<typename iterator_traits<_Iter>::iterator_category, forward_iterator_tag>;
263
264template<class _Iter, class _Sent>
265concept __common_iter_has_ptr_op = requires(const common_iterator<_Iter, _Sent>& __a) {
266 __a.operator->();
267};
268
269template<class, class>
270struct __arrow_type_or_void {
271 using type = void;
272};
273
274template<class _Iter, class _Sent>
275 requires __common_iter_has_ptr_op<_Iter, _Sent>
276struct __arrow_type_or_void<_Iter, _Sent> {
277 using type = decltype(declval<const common_iterator<_Iter, _Sent>>().operator->());
278};
279
280template<class _Iter, class _Sent>
281struct iterator_traits<common_iterator<_Iter, _Sent>> {
282 using iterator_concept = _If<forward_iterator<_Iter>,
283 forward_iterator_tag,
284 input_iterator_tag>;
285 using iterator_category = _If<__denotes_forward_iter<_Iter>,
286 forward_iterator_tag,
287 input_iterator_tag>;
288 using pointer = typename __arrow_type_or_void<_Iter, _Sent>::type;
289 using value_type = iter_value_t<_Iter>;
290 using difference_type = iter_difference_t<_Iter>;
291 using reference = iter_reference_t<_Iter>;
292};
293
294
295#endif // !defined(_LIBCPP_HAS_NO_RANGES)
296
297_LIBCPP_END_NAMESPACE_STD
298
299_LIBCPP_POP_MACROS
300
301#endif // _LIBCPP___ITERATOR_COMMON_ITERATOR_H
lib/libcxx/include/__iterator/concepts.h created+272
......@@ -0,0 +1,272 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___ITERATOR_CONCEPTS_H
11#define _LIBCPP___ITERATOR_CONCEPTS_H
12
13#include <__config>
14#include <__iterator/incrementable_traits.h>
15#include <__iterator/iter_move.h>
16#include <__iterator/iterator_traits.h>
17#include <__iterator/readable_traits.h>
18#include <__memory/pointer_traits.h>
19#include <__utility/forward.h>
20#include <concepts>
21#include <type_traits>
22
23#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
24#pragma GCC system_header
25#endif
26
27_LIBCPP_PUSH_MACROS
28#include <__undef_macros>
29
30_LIBCPP_BEGIN_NAMESPACE_STD
31
32#if !defined(_LIBCPP_HAS_NO_RANGES)
33
34// clang-format off
35
36// [iterator.concept.readable]
37template<class _In>
38concept __indirectly_readable_impl =
39 requires(const _In __i) {
40 typename iter_value_t<_In>;
41 typename iter_reference_t<_In>;
42 typename iter_rvalue_reference_t<_In>;
43 { *__i } -> same_as<iter_reference_t<_In>>;
44 { ranges::iter_move(__i) } -> same_as<iter_rvalue_reference_t<_In>>;
45 } &&
46 common_reference_with<iter_reference_t<_In>&&, iter_value_t<_In>&> &&
47 common_reference_with<iter_reference_t<_In>&&, iter_rvalue_reference_t<_In>&&> &&
48 common_reference_with<iter_rvalue_reference_t<_In>&&, const iter_value_t<_In>&>;
49
50template<class _In>
51concept indirectly_readable = __indirectly_readable_impl<remove_cvref_t<_In>>;
52
53template<indirectly_readable _Tp>
54using iter_common_reference_t = common_reference_t<iter_reference_t<_Tp>, iter_value_t<_Tp>&>;
55
56// [iterator.concept.writable]
57template<class _Out, class _Tp>
58concept indirectly_writable =
59 requires(_Out&& __o, _Tp&& __t) {
60 *__o = _VSTD::forward<_Tp>(__t); // not required to be equality-preserving
61 *_VSTD::forward<_Out>(__o) = _VSTD::forward<_Tp>(__t); // not required to be equality-preserving
62 const_cast<const iter_reference_t<_Out>&&>(*__o) = _VSTD::forward<_Tp>(__t); // not required to be equality-preserving
63 const_cast<const iter_reference_t<_Out>&&>(*_VSTD::forward<_Out>(__o)) = _VSTD::forward<_Tp>(__t); // not required to be equality-preserving
64 };
65
66// [iterator.concept.winc]
67template<class _Tp>
68concept __integer_like = integral<_Tp> && !same_as<_Tp, bool>;
69
70template<class _Tp>
71concept __signed_integer_like = signed_integral<_Tp>;
72
73template<class _Ip>
74concept weakly_incrementable =
75 movable<_Ip> &&
76 requires(_Ip __i) {
77 typename iter_difference_t<_Ip>;
78 requires __signed_integer_like<iter_difference_t<_Ip>>;
79 { ++__i } -> same_as<_Ip&>; // not required to be equality-preserving
80 __i++; // not required to be equality-preserving
81 };
82
83// [iterator.concept.inc]
84template<class _Ip>
85concept incrementable =
86 regular<_Ip> &&
87 weakly_incrementable<_Ip> &&
88 requires(_Ip __i) {
89 { __i++ } -> same_as<_Ip>;
90 };
91
92// [iterator.concept.iterator]
93template<class _Ip>
94concept input_or_output_iterator =
95 requires(_Ip __i) {
96 { *__i } -> __referenceable;
97 } &&
98 weakly_incrementable<_Ip>;
99
100// [iterator.concept.sentinel]
101template<class _Sp, class _Ip>
102concept sentinel_for =
103 semiregular<_Sp> &&
104 input_or_output_iterator<_Ip> &&
105 __weakly_equality_comparable_with<_Sp, _Ip>;
106
107template<class, class>
108inline constexpr bool disable_sized_sentinel_for = false;
109
110template<class _Sp, class _Ip>
111concept sized_sentinel_for =
112 sentinel_for<_Sp, _Ip> &&
113 !disable_sized_sentinel_for<remove_cv_t<_Sp>, remove_cv_t<_Ip>> &&
114 requires(const _Ip& __i, const _Sp& __s) {
115 { __s - __i } -> same_as<iter_difference_t<_Ip>>;
116 { __i - __s } -> same_as<iter_difference_t<_Ip>>;
117 };
118
119// [iterator.concept.input]
120template<class _Ip>
121concept input_iterator =
122 input_or_output_iterator<_Ip> &&
123 indirectly_readable<_Ip> &&
124 requires { typename _ITER_CONCEPT<_Ip>; } &&
125 derived_from<_ITER_CONCEPT<_Ip>, input_iterator_tag>;
126
127// [iterator.concept.output]
128template<class _Ip, class _Tp>
129concept output_iterator =
130 input_or_output_iterator<_Ip> &&
131 indirectly_writable<_Ip, _Tp> &&
132 requires (_Ip __it, _Tp&& __t) {
133 *__it++ = _VSTD::forward<_Tp>(__t); // not required to be equality-preserving
134 };
135
136// [iterator.concept.forward]
137template<class _Ip>
138concept forward_iterator =
139 input_iterator<_Ip> &&
140 derived_from<_ITER_CONCEPT<_Ip>, forward_iterator_tag> &&
141 incrementable<_Ip> &&
142 sentinel_for<_Ip, _Ip>;
143
144// [iterator.concept.bidir]
145template<class _Ip>
146concept bidirectional_iterator =
147 forward_iterator<_Ip> &&
148 derived_from<_ITER_CONCEPT<_Ip>, bidirectional_iterator_tag> &&
149 requires(_Ip __i) {
150 { --__i } -> same_as<_Ip&>;
151 { __i-- } -> same_as<_Ip>;
152 };
153
154template<class _Ip>
155concept random_access_iterator =
156 bidirectional_iterator<_Ip> &&
157 derived_from<_ITER_CONCEPT<_Ip>, random_access_iterator_tag> &&
158 totally_ordered<_Ip> &&
159 sized_sentinel_for<_Ip, _Ip> &&
160 requires(_Ip __i, const _Ip __j, const iter_difference_t<_Ip> __n) {
161 { __i += __n } -> same_as<_Ip&>;
162 { __j + __n } -> same_as<_Ip>;
163 { __n + __j } -> same_as<_Ip>;
164 { __i -= __n } -> same_as<_Ip&>;
165 { __j - __n } -> same_as<_Ip>;
166 { __j[__n] } -> same_as<iter_reference_t<_Ip>>;
167 };
168
169template<class _Ip>
170concept contiguous_iterator =
171 random_access_iterator<_Ip> &&
172 derived_from<_ITER_CONCEPT<_Ip>, contiguous_iterator_tag> &&
173 is_lvalue_reference_v<iter_reference_t<_Ip>> &&
174 same_as<iter_value_t<_Ip>, remove_cvref_t<iter_reference_t<_Ip>>> &&
175 (is_pointer_v<_Ip> || requires { sizeof(__pointer_traits_element_type<_Ip>); }) &&
176 requires(const _Ip& __i) {
177 { _VSTD::to_address(__i) } -> same_as<add_pointer_t<iter_reference_t<_Ip>>>;
178 };
179
180template<class _Ip>
181concept __has_arrow = input_iterator<_Ip> && (is_pointer_v<_Ip> || requires(_Ip __i) { __i.operator->(); });
182
183// [indirectcallable.indirectinvocable]
184template<class _Fp, class _It>
185concept indirectly_unary_invocable =
186 indirectly_readable<_It> &&
187 copy_constructible<_Fp> &&
188 invocable<_Fp&, iter_value_t<_It>&> &&
189 invocable<_Fp&, iter_reference_t<_It>> &&
190 invocable<_Fp&, iter_common_reference_t<_It>> &&
191 common_reference_with<
192 invoke_result_t<_Fp&, iter_value_t<_It>&>,
193 invoke_result_t<_Fp&, iter_reference_t<_It>>>;
194
195template<class _Fp, class _It>
196concept indirectly_regular_unary_invocable =
197 indirectly_readable<_It> &&
198 copy_constructible<_Fp> &&
199 regular_invocable<_Fp&, iter_value_t<_It>&> &&
200 regular_invocable<_Fp&, iter_reference_t<_It>> &&
201 regular_invocable<_Fp&, iter_common_reference_t<_It>> &&
202 common_reference_with<
203 invoke_result_t<_Fp&, iter_value_t<_It>&>,
204 invoke_result_t<_Fp&, iter_reference_t<_It>>>;
205
206template<class _Fp, class _It>
207concept indirect_unary_predicate =
208 indirectly_readable<_It> &&
209 copy_constructible<_Fp> &&
210 predicate<_Fp&, iter_value_t<_It>&> &&
211 predicate<_Fp&, iter_reference_t<_It>> &&
212 predicate<_Fp&, iter_common_reference_t<_It>>;
213
214template<class _Fp, class _It1, class _It2>
215concept indirect_binary_predicate =
216 indirectly_readable<_It1> && indirectly_readable<_It2> &&
217 copy_constructible<_Fp> &&
218 predicate<_Fp&, iter_value_t<_It1>&, iter_value_t<_It2>&> &&
219 predicate<_Fp&, iter_value_t<_It1>&, iter_reference_t<_It2>> &&
220 predicate<_Fp&, iter_reference_t<_It1>, iter_value_t<_It2>&> &&
221 predicate<_Fp&, iter_reference_t<_It1>, iter_reference_t<_It2>> &&
222 predicate<_Fp&, iter_common_reference_t<_It1>, iter_common_reference_t<_It2>>;
223
224template<class _Fp, class _It1, class _It2 = _It1>
225concept indirect_equivalence_relation =
226 indirectly_readable<_It1> && indirectly_readable<_It2> &&
227 copy_constructible<_Fp> &&
228 equivalence_relation<_Fp&, iter_value_t<_It1>&, iter_value_t<_It2>&> &&
229 equivalence_relation<_Fp&, iter_value_t<_It1>&, iter_reference_t<_It2>> &&
230 equivalence_relation<_Fp&, iter_reference_t<_It1>, iter_value_t<_It2>&> &&
231 equivalence_relation<_Fp&, iter_reference_t<_It1>, iter_reference_t<_It2>> &&
232 equivalence_relation<_Fp&, iter_common_reference_t<_It1>, iter_common_reference_t<_It2>>;
233
234template<class _Fp, class _It1, class _It2 = _It1>
235concept indirect_strict_weak_order =
236 indirectly_readable<_It1> && indirectly_readable<_It2> &&
237 copy_constructible<_Fp> &&
238 strict_weak_order<_Fp&, iter_value_t<_It1>&, iter_value_t<_It2>&> &&
239 strict_weak_order<_Fp&, iter_value_t<_It1>&, iter_reference_t<_It2>> &&
240 strict_weak_order<_Fp&, iter_reference_t<_It1>, iter_value_t<_It2>&> &&
241 strict_weak_order<_Fp&, iter_reference_t<_It1>, iter_reference_t<_It2>> &&
242 strict_weak_order<_Fp&, iter_common_reference_t<_It1>, iter_common_reference_t<_It2>>;
243
244template<class _Fp, class... _Its>
245 requires (indirectly_readable<_Its> && ...) && invocable<_Fp, iter_reference_t<_Its>...>
246using indirect_result_t = invoke_result_t<_Fp, iter_reference_t<_Its>...>;
247
248template<class _In, class _Out>
249concept indirectly_movable =
250 indirectly_readable<_In> &&
251 indirectly_writable<_Out, iter_rvalue_reference_t<_In>>;
252
253template<class _In, class _Out>
254concept indirectly_movable_storable =
255 indirectly_movable<_In, _Out> &&
256 indirectly_writable<_Out, iter_value_t<_In>> &&
257 movable<iter_value_t<_In>> &&
258 constructible_from<iter_value_t<_In>, iter_rvalue_reference_t<_In>> &&
259 assignable_from<iter_value_t<_In>&, iter_rvalue_reference_t<_In>>;
260
261// Note: indirectly_swappable is located in iter_swap.h to prevent a dependency cycle
262// (both iter_swap and indirectly_swappable require indirectly_readable).
263
264// clang-format on
265
266#endif // !defined(_LIBCPP_HAS_NO_RANGES)
267
268_LIBCPP_END_NAMESPACE_STD
269
270_LIBCPP_POP_MACROS
271
272#endif // _LIBCPP___ITERATOR_CONCEPTS_H
lib/libcxx/include/__iterator/counted_iterator.h created+306
......@@ -0,0 +1,306 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9#ifndef _LIBCPP___ITERATOR_COUNTED_ITERATOR_H
10#define _LIBCPP___ITERATOR_COUNTED_ITERATOR_H
11
12#include <__config>
13#include <__debug>
14#include <__iterator/concepts.h>
15#include <__iterator/default_sentinel.h>
16#include <__iterator/iter_move.h>
17#include <__iterator/iter_swap.h>
18#include <__iterator/incrementable_traits.h>
19#include <__iterator/iterator_traits.h>
20#include <__iterator/readable_traits.h>
21#include <__memory/pointer_traits.h>
22#include <concepts>
23#include <type_traits>
24
25#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
26#pragma GCC system_header
27#endif
28
29_LIBCPP_PUSH_MACROS
30#include <__undef_macros>
31
32_LIBCPP_BEGIN_NAMESPACE_STD
33
34#if !defined(_LIBCPP_HAS_NO_RANGES)
35
36template<class>
37struct __counted_iterator_concept {};
38
39template<class _Iter>
40 requires requires { typename _Iter::iterator_concept; }
41struct __counted_iterator_concept<_Iter> {
42 using iterator_concept = typename _Iter::iterator_concept;
43};
44
45template<class>
46struct __counted_iterator_category {};
47
48template<class _Iter>
49 requires requires { typename _Iter::iterator_category; }
50struct __counted_iterator_category<_Iter> {
51 using iterator_category = typename _Iter::iterator_category;
52};
53
54template<class>
55struct __counted_iterator_value_type {};
56
57template<indirectly_readable _Iter>
58struct __counted_iterator_value_type<_Iter> {
59 using value_type = iter_value_t<_Iter>;
60};
61
62template<input_or_output_iterator _Iter>
63class counted_iterator
64 : public __counted_iterator_concept<_Iter>
65 , public __counted_iterator_category<_Iter>
66 , public __counted_iterator_value_type<_Iter>
67{
68public:
69 [[no_unique_address]] _Iter __current_ = _Iter();
70 iter_difference_t<_Iter> __count_ = 0;
71
72 using iterator_type = _Iter;
73 using difference_type = iter_difference_t<_Iter>;
74
75 _LIBCPP_HIDE_FROM_ABI
76 constexpr counted_iterator() requires default_initializable<_Iter> = default;
77
78 _LIBCPP_HIDE_FROM_ABI
79 constexpr counted_iterator(_Iter __iter, iter_difference_t<_Iter> __n)
80 : __current_(_VSTD::move(__iter)), __count_(__n) {
81 _LIBCPP_ASSERT(__n >= 0, "__n must not be negative.");
82 }
83
84 template<class _I2>
85 requires convertible_to<const _I2&, _Iter>
86 _LIBCPP_HIDE_FROM_ABI
87 constexpr counted_iterator(const counted_iterator<_I2>& __other)
88 : __current_(__other.__current_), __count_(__other.__count_) {}
89
90 template<class _I2>
91 requires assignable_from<_Iter&, const _I2&>
92 _LIBCPP_HIDE_FROM_ABI
93 constexpr counted_iterator& operator=(const counted_iterator<_I2>& __other) {
94 __current_ = __other.__current_;
95 __count_ = __other.__count_;
96 return *this;
97 }
98
99 _LIBCPP_HIDE_FROM_ABI
100 constexpr const _Iter& base() const& { return __current_; }
101
102 _LIBCPP_HIDE_FROM_ABI
103 constexpr _Iter base() && { return _VSTD::move(__current_); }
104
105 _LIBCPP_HIDE_FROM_ABI
106 constexpr iter_difference_t<_Iter> count() const noexcept { return __count_; }
107
108 _LIBCPP_HIDE_FROM_ABI
109 constexpr decltype(auto) operator*() {
110 _LIBCPP_ASSERT(__count_ > 0, "Iterator is equal to or past end.");
111 return *__current_;
112 }
113
114 _LIBCPP_HIDE_FROM_ABI
115 constexpr decltype(auto) operator*() const
116 requires __dereferenceable<const _Iter>
117 {
118 _LIBCPP_ASSERT(__count_ > 0, "Iterator is equal to or past end.");
119 return *__current_;
120 }
121
122 _LIBCPP_HIDE_FROM_ABI
123 constexpr auto operator->() const noexcept
124 requires contiguous_iterator<_Iter>
125 {
126 return _VSTD::to_address(__current_);
127 }
128
129 _LIBCPP_HIDE_FROM_ABI
130 constexpr counted_iterator& operator++() {
131 _LIBCPP_ASSERT(__count_ > 0, "Iterator already at or past end.");
132 ++__current_;
133 --__count_;
134 return *this;
135 }
136
137 _LIBCPP_HIDE_FROM_ABI
138 decltype(auto) operator++(int) {
139 _LIBCPP_ASSERT(__count_ > 0, "Iterator already at or past end.");
140 --__count_;
141#ifndef _LIBCPP_NO_EXCEPTIONS
142 try { return __current_++; }
143 catch(...) { ++__count_; throw; }
144#else
145 return __current_++;
146#endif // _LIBCPP_NO_EXCEPTIONS
147 }
148
149 _LIBCPP_HIDE_FROM_ABI
150 constexpr counted_iterator operator++(int)
151 requires forward_iterator<_Iter>
152 {
153 _LIBCPP_ASSERT(__count_ > 0, "Iterator already at or past end.");
154 counted_iterator __tmp = *this;
155 ++*this;
156 return __tmp;
157 }
158
159 _LIBCPP_HIDE_FROM_ABI
160 constexpr counted_iterator& operator--()
161 requires bidirectional_iterator<_Iter>
162 {
163 --__current_;
164 ++__count_;
165 return *this;
166 }
167
168 _LIBCPP_HIDE_FROM_ABI
169 constexpr counted_iterator operator--(int)
170 requires bidirectional_iterator<_Iter>
171 {
172 counted_iterator __tmp = *this;
173 --*this;
174 return __tmp;
175 }
176
177 _LIBCPP_HIDE_FROM_ABI
178 constexpr counted_iterator operator+(iter_difference_t<_Iter> __n) const
179 requires random_access_iterator<_Iter>
180 {
181 return counted_iterator(__current_ + __n, __count_ - __n);
182 }
183
184 _LIBCPP_HIDE_FROM_ABI
185 friend constexpr counted_iterator operator+(
186 iter_difference_t<_Iter> __n, const counted_iterator& __x)
187 requires random_access_iterator<_Iter>
188 {
189 return __x + __n;
190 }
191
192 _LIBCPP_HIDE_FROM_ABI
193 constexpr counted_iterator& operator+=(iter_difference_t<_Iter> __n)
194 requires random_access_iterator<_Iter>
195 {
196 _LIBCPP_ASSERT(__n <= __count_, "Cannot advance iterator past end.");
197 __current_ += __n;
198 __count_ -= __n;
199 return *this;
200 }
201
202 _LIBCPP_HIDE_FROM_ABI
203 constexpr counted_iterator operator-(iter_difference_t<_Iter> __n) const
204 requires random_access_iterator<_Iter>
205 {
206 return counted_iterator(__current_ - __n, __count_ + __n);
207 }
208
209 template<common_with<_Iter> _I2>
210 _LIBCPP_HIDE_FROM_ABI
211 friend constexpr iter_difference_t<_I2> operator-(
212 const counted_iterator& __lhs, const counted_iterator<_I2>& __rhs)
213 {
214 return __rhs.__count_ - __lhs.__count_;
215 }
216
217 _LIBCPP_HIDE_FROM_ABI
218 friend constexpr iter_difference_t<_Iter> operator-(
219 const counted_iterator& __lhs, default_sentinel_t)
220 {
221 return -__lhs.__count_;
222 }
223
224 _LIBCPP_HIDE_FROM_ABI
225 friend constexpr iter_difference_t<_Iter> operator-(
226 default_sentinel_t, const counted_iterator& __rhs)
227 {
228 return __rhs.__count_;
229 }
230
231 _LIBCPP_HIDE_FROM_ABI
232 constexpr counted_iterator& operator-=(iter_difference_t<_Iter> __n)
233 requires random_access_iterator<_Iter>
234 {
235 _LIBCPP_ASSERT(-__n <= __count_, "Attempt to subtract too large of a size: "
236 "counted_iterator would be decremented before the "
237 "first element of its range.");
238 __current_ -= __n;
239 __count_ += __n;
240 return *this;
241 }
242
243 _LIBCPP_HIDE_FROM_ABI
244 constexpr decltype(auto) operator[](iter_difference_t<_Iter> __n) const
245 requires random_access_iterator<_Iter>
246 {
247 _LIBCPP_ASSERT(__n < __count_, "Subscript argument must be less than size.");
248 return __current_[__n];
249 }
250
251 template<common_with<_Iter> _I2>
252 _LIBCPP_HIDE_FROM_ABI
253 friend constexpr bool operator==(
254 const counted_iterator& __lhs, const counted_iterator<_I2>& __rhs)
255 {
256 return __lhs.__count_ == __rhs.__count_;
257 }
258
259 _LIBCPP_HIDE_FROM_ABI
260 friend constexpr bool operator==(
261 const counted_iterator& __lhs, default_sentinel_t)
262 {
263 return __lhs.__count_ == 0;
264 }
265
266 template<common_with<_Iter> _I2>
267 friend constexpr strong_ordering operator<=>(
268 const counted_iterator& __lhs, const counted_iterator<_I2>& __rhs)
269 {
270 return __rhs.__count_ <=> __lhs.__count_;
271 }
272
273 _LIBCPP_HIDE_FROM_ABI
274 friend constexpr iter_rvalue_reference_t<_Iter> iter_move(const counted_iterator& __i)
275 noexcept(noexcept(ranges::iter_move(__i.__current_)))
276 requires input_iterator<_Iter>
277 {
278 _LIBCPP_ASSERT(__i.__count_ > 0, "Iterator must not be past end of range.");
279 return ranges::iter_move(__i.__current_);
280 }
281
282 template<indirectly_swappable<_Iter> _I2>
283 _LIBCPP_HIDE_FROM_ABI
284 friend constexpr void iter_swap(const counted_iterator& __x, const counted_iterator<_I2>& __y)
285 noexcept(noexcept(ranges::iter_swap(__x.__current_, __y.__current_)))
286 {
287 _LIBCPP_ASSERT(__x.__count_ > 0 && __y.__count_ > 0,
288 "Iterators must not be past end of range.");
289 return ranges::iter_swap(__x.__current_, __y.__current_);
290 }
291};
292
293template<input_iterator _Iter>
294 requires same_as<_ITER_TRAITS<_Iter>, iterator_traits<_Iter>>
295struct iterator_traits<counted_iterator<_Iter>> : iterator_traits<_Iter> {
296 using pointer = conditional_t<contiguous_iterator<_Iter>,
297 add_pointer_t<iter_reference_t<_Iter>>, void>;
298};
299
300#endif // !defined(_LIBCPP_HAS_NO_RANGES)
301
302_LIBCPP_END_NAMESPACE_STD
303
304_LIBCPP_POP_MACROS
305
306#endif // _LIBCPP___ITERATOR_COUNTED_ITERATOR_H
lib/libcxx/include/__iterator/data.h created+56
......@@ -0,0 +1,56 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___ITERATOR_DATA_H
11#define _LIBCPP___ITERATOR_DATA_H
12
13#include <__config>
14#include <cstddef>
15#include <initializer_list>
16
17#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
18#pragma GCC system_header
19#endif
20
21_LIBCPP_PUSH_MACROS
22#include <__undef_macros>
23
24_LIBCPP_BEGIN_NAMESPACE_STD
25
26#if _LIBCPP_STD_VER > 14
27
28template <class _Cont> constexpr
29_LIBCPP_INLINE_VISIBILITY
30auto data(_Cont& __c)
31_NOEXCEPT_(noexcept(__c.data()))
32-> decltype (__c.data())
33{ return __c.data(); }
34
35template <class _Cont> constexpr
36_LIBCPP_INLINE_VISIBILITY
37auto data(const _Cont& __c)
38_NOEXCEPT_(noexcept(__c.data()))
39-> decltype (__c.data())
40{ return __c.data(); }
41
42template <class _Tp, size_t _Sz>
43_LIBCPP_INLINE_VISIBILITY
44constexpr _Tp* data(_Tp (&__array)[_Sz]) noexcept { return __array; }
45
46template <class _Ep>
47_LIBCPP_INLINE_VISIBILITY
48constexpr const _Ep* data(initializer_list<_Ep> __il) noexcept { return __il.begin(); }
49
50#endif
51
52_LIBCPP_END_NAMESPACE_STD
53
54_LIBCPP_POP_MACROS
55
56#endif // _LIBCPP___ITERATOR_DATA_H
lib/libcxx/include/__iterator/default_sentinel.h created+35
......@@ -0,0 +1,35 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___ITERATOR_DEFAULT_SENTINEL_H
11#define _LIBCPP___ITERATOR_DEFAULT_SENTINEL_H
12
13#include <__config>
14
15#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
16#pragma GCC system_header
17#endif
18
19_LIBCPP_PUSH_MACROS
20#include <__undef_macros>
21
22_LIBCPP_BEGIN_NAMESPACE_STD
23
24#if !defined(_LIBCPP_HAS_NO_RANGES)
25
26struct default_sentinel_t { };
27inline constexpr default_sentinel_t default_sentinel{};
28
29#endif // !defined(_LIBCPP_HAS_NO_RANGES)
30
31_LIBCPP_END_NAMESPACE_STD
32
33_LIBCPP_POP_MACROS
34
35#endif // _LIBCPP___ITERATOR_DEFAULT_SENTINEL_H
lib/libcxx/include/__iterator/distance.h created+56
......@@ -0,0 +1,56 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___ITERATOR_DISTANCE_H
11#define _LIBCPP___ITERATOR_DISTANCE_H
12
13#include <__config>
14#include <__iterator/iterator_traits.h>
15
16#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
17#pragma GCC system_header
18#endif
19
20_LIBCPP_PUSH_MACROS
21#include <__undef_macros>
22
23_LIBCPP_BEGIN_NAMESPACE_STD
24
25template <class _InputIter>
26inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
27typename iterator_traits<_InputIter>::difference_type
28__distance(_InputIter __first, _InputIter __last, input_iterator_tag)
29{
30 typename iterator_traits<_InputIter>::difference_type __r(0);
31 for (; __first != __last; ++__first)
32 ++__r;
33 return __r;
34}
35
36template <class _RandIter>
37inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
38typename iterator_traits<_RandIter>::difference_type
39__distance(_RandIter __first, _RandIter __last, random_access_iterator_tag)
40{
41 return __last - __first;
42}
43
44template <class _InputIter>
45inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
46typename iterator_traits<_InputIter>::difference_type
47distance(_InputIter __first, _InputIter __last)
48{
49 return _VSTD::__distance(__first, __last, typename iterator_traits<_InputIter>::iterator_category());
50}
51
52_LIBCPP_END_NAMESPACE_STD
53
54_LIBCPP_POP_MACROS
55
56#endif // _LIBCPP___ITERATOR_DISTANCE_H
lib/libcxx/include/__iterator/empty.h created+49
......@@ -0,0 +1,49 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___ITERATOR_EMPTY_H
11#define _LIBCPP___ITERATOR_EMPTY_H
12
13#include <__config>
14#include <cstddef>
15#include <initializer_list>
16
17#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
18#pragma GCC system_header
19#endif
20
21_LIBCPP_PUSH_MACROS
22#include <__undef_macros>
23
24_LIBCPP_BEGIN_NAMESPACE_STD
25
26#if _LIBCPP_STD_VER > 14
27
28template <class _Cont>
29_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
30constexpr auto empty(const _Cont& __c)
31_NOEXCEPT_(noexcept(__c.empty()))
32-> decltype (__c.empty())
33{ return __c.empty(); }
34
35template <class _Tp, size_t _Sz>
36_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
37constexpr bool empty(const _Tp (&)[_Sz]) noexcept { return false; }
38
39template <class _Ep>
40_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
41constexpr bool empty(initializer_list<_Ep> __il) noexcept { return __il.size() == 0; }
42
43#endif // _LIBCPP_STD_VER > 14
44
45_LIBCPP_END_NAMESPACE_STD
46
47_LIBCPP_POP_MACROS
48
49#endif // _LIBCPP___ITERATOR_EMPTY_H
lib/libcxx/include/__iterator/erase_if_container.h created+45
......@@ -0,0 +1,45 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___ITERATOR_ERASE_IF_CONTAINER_H
11#define _LIBCPP___ITERATOR_ERASE_IF_CONTAINER_H
12
13#include <__config>
14
15#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
16#pragma GCC system_header
17#endif
18
19_LIBCPP_PUSH_MACROS
20#include <__undef_macros>
21
22_LIBCPP_BEGIN_NAMESPACE_STD
23
24template <class _Container, class _Predicate>
25_LIBCPP_HIDE_FROM_ABI
26typename _Container::size_type
27__libcpp_erase_if_container(_Container& __c, _Predicate& __pred) {
28 typename _Container::size_type __old_size = __c.size();
29
30 const typename _Container::iterator __last = __c.end();
31 for (typename _Container::iterator __iter = __c.begin(); __iter != __last;) {
32 if (__pred(*__iter))
33 __iter = __c.erase(__iter);
34 else
35 ++__iter;
36 }
37
38 return __old_size - __c.size();
39}
40
41_LIBCPP_END_NAMESPACE_STD
42
43_LIBCPP_POP_MACROS
44
45#endif // _LIBCPP___ITERATOR_ERASE_IF_CONTAINER_H
lib/libcxx/include/__iterator/front_insert_iterator.h created+75
......@@ -0,0 +1,75 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___ITERATOR_FRONT_INSERT_ITERATOR_H
11#define _LIBCPP___ITERATOR_FRONT_INSERT_ITERATOR_H
12
13#include <__config>
14#include <__iterator/iterator.h>
15#include <__iterator/iterator_traits.h>
16#include <__memory/addressof.h>
17#include <__utility/move.h>
18#include <cstddef>
19
20#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
21#pragma GCC system_header
22#endif
23
24_LIBCPP_PUSH_MACROS
25#include <__undef_macros>
26
27_LIBCPP_BEGIN_NAMESPACE_STD
28
29_LIBCPP_SUPPRESS_DEPRECATED_PUSH
30template <class _Container>
31class _LIBCPP_TEMPLATE_VIS front_insert_iterator
32#if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES)
33 : public iterator<output_iterator_tag, void, void, void, void>
34#endif
35{
36_LIBCPP_SUPPRESS_DEPRECATED_POP
37protected:
38 _Container* container;
39public:
40 typedef output_iterator_tag iterator_category;
41 typedef void value_type;
42#if _LIBCPP_STD_VER > 17
43 typedef ptrdiff_t difference_type;
44#else
45 typedef void difference_type;
46#endif
47 typedef void pointer;
48 typedef void reference;
49 typedef _Container container_type;
50
51 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 explicit front_insert_iterator(_Container& __x) : container(_VSTD::addressof(__x)) {}
52 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 front_insert_iterator& operator=(const typename _Container::value_type& __value_)
53 {container->push_front(__value_); return *this;}
54#ifndef _LIBCPP_CXX03_LANG
55 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 front_insert_iterator& operator=(typename _Container::value_type&& __value_)
56 {container->push_front(_VSTD::move(__value_)); return *this;}
57#endif // _LIBCPP_CXX03_LANG
58 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 front_insert_iterator& operator*() {return *this;}
59 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 front_insert_iterator& operator++() {return *this;}
60 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 front_insert_iterator operator++(int) {return *this;}
61};
62
63template <class _Container>
64inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
65front_insert_iterator<_Container>
66front_inserter(_Container& __x)
67{
68 return front_insert_iterator<_Container>(__x);
69}
70
71_LIBCPP_END_NAMESPACE_STD
72
73_LIBCPP_POP_MACROS
74
75#endif // _LIBCPP___ITERATOR_FRONT_INSERT_ITERATOR_H
lib/libcxx/include/__iterator/incrementable_traits.h created+77
......@@ -0,0 +1,77 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___ITERATOR_INCREMENTABLE_TRAITS_H
11#define _LIBCPP___ITERATOR_INCREMENTABLE_TRAITS_H
12
13#include <__config>
14#include <concepts>
15#include <type_traits>
16
17#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
18#pragma GCC system_header
19#endif
20
21_LIBCPP_PUSH_MACROS
22#include <__undef_macros>
23
24_LIBCPP_BEGIN_NAMESPACE_STD
25
26#if !defined(_LIBCPP_HAS_NO_RANGES)
27
28// [incrementable.traits]
29template<class> struct incrementable_traits {};
30
31template<class _Tp>
32requires is_object_v<_Tp>
33struct incrementable_traits<_Tp*> {
34 using difference_type = ptrdiff_t;
35};
36
37template<class _Ip>
38struct incrementable_traits<const _Ip> : incrementable_traits<_Ip> {};
39
40template<class _Tp>
41concept __has_member_difference_type = requires { typename _Tp::difference_type; };
42
43template<__has_member_difference_type _Tp>
44struct incrementable_traits<_Tp> {
45 using difference_type = typename _Tp::difference_type;
46};
47
48template<class _Tp>
49concept __has_integral_minus =
50 requires(const _Tp& __x, const _Tp& __y) {
51 { __x - __y } -> integral;
52 };
53
54template<__has_integral_minus _Tp>
55requires (!__has_member_difference_type<_Tp>)
56struct incrementable_traits<_Tp> {
57 using difference_type = make_signed_t<decltype(declval<_Tp>() - declval<_Tp>())>;
58};
59
60template <class>
61struct iterator_traits;
62
63// Let `RI` be `remove_cvref_t<I>`. The type `iter_difference_t<I>` denotes
64// `incrementable_traits<RI>::difference_type` if `iterator_traits<RI>` names a specialization
65// generated from the primary template, and `iterator_traits<RI>::difference_type` otherwise.
66template <class _Ip>
67using iter_difference_t = typename conditional_t<__is_primary_template<iterator_traits<remove_cvref_t<_Ip> > >::value,
68 incrementable_traits<remove_cvref_t<_Ip> >,
69 iterator_traits<remove_cvref_t<_Ip> > >::difference_type;
70
71#endif // !defined(_LIBCPP_HAS_NO_RANGES)
72
73_LIBCPP_END_NAMESPACE_STD
74
75_LIBCPP_POP_MACROS
76
77#endif // _LIBCPP___ITERATOR_INCREMENTABLE_TRAITS_H
lib/libcxx/include/__iterator/insert_iterator.h created+77
......@@ -0,0 +1,77 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___ITERATOR_INSERT_ITERATOR_H
11#define _LIBCPP___ITERATOR_INSERT_ITERATOR_H
12
13#include <__config>
14#include <__iterator/iterator.h>
15#include <__iterator/iterator_traits.h>
16#include <__memory/addressof.h>
17#include <__utility/move.h>
18#include <cstddef>
19
20#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
21#pragma GCC system_header
22#endif
23
24_LIBCPP_PUSH_MACROS
25#include <__undef_macros>
26
27_LIBCPP_BEGIN_NAMESPACE_STD
28
29_LIBCPP_SUPPRESS_DEPRECATED_PUSH
30template <class _Container>
31class _LIBCPP_TEMPLATE_VIS insert_iterator
32#if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES)
33 : public iterator<output_iterator_tag, void, void, void, void>
34#endif
35{
36_LIBCPP_SUPPRESS_DEPRECATED_POP
37protected:
38 _Container* container;
39 typename _Container::iterator iter; // FIXME: `ranges::iterator_t<Container>` in C++20 mode
40public:
41 typedef output_iterator_tag iterator_category;
42 typedef void value_type;
43#if _LIBCPP_STD_VER > 17
44 typedef ptrdiff_t difference_type;
45#else
46 typedef void difference_type;
47#endif
48 typedef void pointer;
49 typedef void reference;
50 typedef _Container container_type;
51
52 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 insert_iterator(_Container& __x, typename _Container::iterator __i)
53 : container(_VSTD::addressof(__x)), iter(__i) {}
54 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 insert_iterator& operator=(const typename _Container::value_type& __value_)
55 {iter = container->insert(iter, __value_); ++iter; return *this;}
56#ifndef _LIBCPP_CXX03_LANG
57 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 insert_iterator& operator=(typename _Container::value_type&& __value_)
58 {iter = container->insert(iter, _VSTD::move(__value_)); ++iter; return *this;}
59#endif // _LIBCPP_CXX03_LANG
60 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 insert_iterator& operator*() {return *this;}
61 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 insert_iterator& operator++() {return *this;}
62 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 insert_iterator& operator++(int) {return *this;}
63};
64
65template <class _Container>
66inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
67insert_iterator<_Container>
68inserter(_Container& __x, typename _Container::iterator __i)
69{
70 return insert_iterator<_Container>(__x, __i);
71}
72
73_LIBCPP_END_NAMESPACE_STD
74
75_LIBCPP_POP_MACROS
76
77#endif // _LIBCPP___ITERATOR_INSERT_ITERATOR_H
lib/libcxx/include/__iterator/istream_iterator.h created+103
......@@ -0,0 +1,103 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___ITERATOR_ISTREAM_ITERATOR_H
11#define _LIBCPP___ITERATOR_ISTREAM_ITERATOR_H
12
13#include <__config>
14#include <__iterator/iterator.h>
15#include <__iterator/iterator_traits.h>
16#include <__memory/addressof.h>
17#include <iosfwd> // for forward declarations of char_traits and basic_istream
18
19#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
20#pragma GCC system_header
21#endif
22
23_LIBCPP_PUSH_MACROS
24#include <__undef_macros>
25
26_LIBCPP_BEGIN_NAMESPACE_STD
27
28_LIBCPP_SUPPRESS_DEPRECATED_PUSH
29template <class _Tp, class _CharT = char,
30 class _Traits = char_traits<_CharT>, class _Distance = ptrdiff_t>
31class _LIBCPP_TEMPLATE_VIS istream_iterator
32#if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES)
33 : public iterator<input_iterator_tag, _Tp, _Distance, const _Tp*, const _Tp&>
34#endif
35{
36_LIBCPP_SUPPRESS_DEPRECATED_POP
37public:
38 typedef input_iterator_tag iterator_category;
39 typedef _Tp value_type;
40 typedef _Distance difference_type;
41 typedef const _Tp* pointer;
42 typedef const _Tp& reference;
43 typedef _CharT char_type;
44 typedef _Traits traits_type;
45 typedef basic_istream<_CharT,_Traits> istream_type;
46private:
47 istream_type* __in_stream_;
48 _Tp __value_;
49public:
50 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR istream_iterator() : __in_stream_(nullptr), __value_() {}
51 _LIBCPP_INLINE_VISIBILITY istream_iterator(istream_type& __s) : __in_stream_(_VSTD::addressof(__s))
52 {
53 if (!(*__in_stream_ >> __value_))
54 __in_stream_ = nullptr;
55 }
56
57 _LIBCPP_INLINE_VISIBILITY const _Tp& operator*() const {return __value_;}
58 _LIBCPP_INLINE_VISIBILITY const _Tp* operator->() const {return _VSTD::addressof((operator*()));}
59 _LIBCPP_INLINE_VISIBILITY istream_iterator& operator++()
60 {
61 if (!(*__in_stream_ >> __value_))
62 __in_stream_ = nullptr;
63 return *this;
64 }
65 _LIBCPP_INLINE_VISIBILITY istream_iterator operator++(int)
66 {istream_iterator __t(*this); ++(*this); return __t;}
67
68 template <class _Up, class _CharU, class _TraitsU, class _DistanceU>
69 friend _LIBCPP_INLINE_VISIBILITY
70 bool
71 operator==(const istream_iterator<_Up, _CharU, _TraitsU, _DistanceU>& __x,
72 const istream_iterator<_Up, _CharU, _TraitsU, _DistanceU>& __y);
73
74 template <class _Up, class _CharU, class _TraitsU, class _DistanceU>
75 friend _LIBCPP_INLINE_VISIBILITY
76 bool
77 operator==(const istream_iterator<_Up, _CharU, _TraitsU, _DistanceU>& __x,
78 const istream_iterator<_Up, _CharU, _TraitsU, _DistanceU>& __y);
79};
80
81template <class _Tp, class _CharT, class _Traits, class _Distance>
82inline _LIBCPP_INLINE_VISIBILITY
83bool
84operator==(const istream_iterator<_Tp, _CharT, _Traits, _Distance>& __x,
85 const istream_iterator<_Tp, _CharT, _Traits, _Distance>& __y)
86{
87 return __x.__in_stream_ == __y.__in_stream_;
88}
89
90template <class _Tp, class _CharT, class _Traits, class _Distance>
91inline _LIBCPP_INLINE_VISIBILITY
92bool
93operator!=(const istream_iterator<_Tp, _CharT, _Traits, _Distance>& __x,
94 const istream_iterator<_Tp, _CharT, _Traits, _Distance>& __y)
95{
96 return !(__x == __y);
97}
98
99_LIBCPP_END_NAMESPACE_STD
100
101_LIBCPP_POP_MACROS
102
103#endif // _LIBCPP___ITERATOR_ISTREAM_ITERATOR_H
lib/libcxx/include/__iterator/istreambuf_iterator.h created+110
......@@ -0,0 +1,110 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___ITERATOR_ISTREAMBUF_ITERATOR_H
11#define _LIBCPP___ITERATOR_ISTREAMBUF_ITERATOR_H
12
13#include <__config>
14#include <__iterator/iterator.h>
15#include <__iterator/iterator_traits.h>
16#include <iosfwd> // for forward declaration of basic_streambuf
17
18#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
19#pragma GCC system_header
20#endif
21
22_LIBCPP_PUSH_MACROS
23#include <__undef_macros>
24
25_LIBCPP_BEGIN_NAMESPACE_STD
26
27_LIBCPP_SUPPRESS_DEPRECATED_PUSH
28template<class _CharT, class _Traits>
29class _LIBCPP_TEMPLATE_VIS istreambuf_iterator
30#if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES)
31 : public iterator<input_iterator_tag, _CharT,
32 typename _Traits::off_type, _CharT*,
33 _CharT>
34#endif
35{
36_LIBCPP_SUPPRESS_DEPRECATED_POP
37public:
38 typedef input_iterator_tag iterator_category;
39 typedef _CharT value_type;
40 typedef typename _Traits::off_type difference_type;
41 typedef _CharT* pointer;
42 typedef _CharT reference;
43 typedef _CharT char_type;
44 typedef _Traits traits_type;
45 typedef typename _Traits::int_type int_type;
46 typedef basic_streambuf<_CharT,_Traits> streambuf_type;
47 typedef basic_istream<_CharT,_Traits> istream_type;
48private:
49 mutable streambuf_type* __sbuf_;
50
51 class __proxy
52 {
53 char_type __keep_;
54 streambuf_type* __sbuf_;
55 _LIBCPP_INLINE_VISIBILITY __proxy(char_type __c, streambuf_type* __s)
56 : __keep_(__c), __sbuf_(__s) {}
57 friend class istreambuf_iterator;
58 public:
59 _LIBCPP_INLINE_VISIBILITY char_type operator*() const {return __keep_;}
60 };
61
62 _LIBCPP_INLINE_VISIBILITY
63 bool __test_for_eof() const
64 {
65 if (__sbuf_ && traits_type::eq_int_type(__sbuf_->sgetc(), traits_type::eof()))
66 __sbuf_ = nullptr;
67 return __sbuf_ == nullptr;
68 }
69public:
70 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR istreambuf_iterator() _NOEXCEPT : __sbuf_(nullptr) {}
71 _LIBCPP_INLINE_VISIBILITY istreambuf_iterator(istream_type& __s) _NOEXCEPT
72 : __sbuf_(__s.rdbuf()) {}
73 _LIBCPP_INLINE_VISIBILITY istreambuf_iterator(streambuf_type* __s) _NOEXCEPT
74 : __sbuf_(__s) {}
75 _LIBCPP_INLINE_VISIBILITY istreambuf_iterator(const __proxy& __p) _NOEXCEPT
76 : __sbuf_(__p.__sbuf_) {}
77
78 _LIBCPP_INLINE_VISIBILITY char_type operator*() const
79 {return static_cast<char_type>(__sbuf_->sgetc());}
80 _LIBCPP_INLINE_VISIBILITY istreambuf_iterator& operator++()
81 {
82 __sbuf_->sbumpc();
83 return *this;
84 }
85 _LIBCPP_INLINE_VISIBILITY __proxy operator++(int)
86 {
87 return __proxy(__sbuf_->sbumpc(), __sbuf_);
88 }
89
90 _LIBCPP_INLINE_VISIBILITY bool equal(const istreambuf_iterator& __b) const
91 {return __test_for_eof() == __b.__test_for_eof();}
92};
93
94template <class _CharT, class _Traits>
95inline _LIBCPP_INLINE_VISIBILITY
96bool operator==(const istreambuf_iterator<_CharT,_Traits>& __a,
97 const istreambuf_iterator<_CharT,_Traits>& __b)
98 {return __a.equal(__b);}
99
100template <class _CharT, class _Traits>
101inline _LIBCPP_INLINE_VISIBILITY
102bool operator!=(const istreambuf_iterator<_CharT,_Traits>& __a,
103 const istreambuf_iterator<_CharT,_Traits>& __b)
104 {return !__a.equal(__b);}
105
106_LIBCPP_END_NAMESPACE_STD
107
108_LIBCPP_POP_MACROS
109
110#endif // _LIBCPP___ITERATOR_ISTREAMBUF_ITERATOR_H
lib/libcxx/include/__iterator/iter_move.h created+91
......@@ -0,0 +1,91 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___ITERATOR_ITER_MOVE_H
11#define _LIBCPP___ITERATOR_ITER_MOVE_H
12
13#include <__config>
14#include <__iterator/iterator_traits.h>
15#include <__utility/forward.h>
16#include <concepts> // __class_or_enum
17#include <type_traits>
18#include <utility>
19
20#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
21#pragma GCC system_header
22#endif
23
24_LIBCPP_PUSH_MACROS
25#include <__undef_macros>
26
27_LIBCPP_BEGIN_NAMESPACE_STD
28
29#if !defined(_LIBCPP_HAS_NO_RANGES)
30
31namespace ranges::__iter_move {
32void iter_move();
33
34template<class _Ip>
35concept __unqualified_iter_move = requires(_Ip&& __i) {
36 iter_move(_VSTD::forward<_Ip>(__i));
37};
38
39// [iterator.cust.move]/1
40// The name ranges::iter_move denotes a customization point object.
41// The expression ranges::iter_move(E) for a subexpression E is
42// expression-equivalent to:
43struct __fn {
44 // [iterator.cust.move]/1.1
45 // iter_move(E), if E has class or enumeration type and iter_move(E) is a
46 // well-formed expression when treated as an unevaluated operand, [...]
47 template<class _Ip>
48 requires __class_or_enum<remove_cvref_t<_Ip>> && __unqualified_iter_move<_Ip>
49 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator()(_Ip&& __i) const
50 noexcept(noexcept(iter_move(_VSTD::forward<_Ip>(__i))))
51 {
52 return iter_move(_VSTD::forward<_Ip>(__i));
53 }
54
55 // [iterator.cust.move]/1.2
56 // Otherwise, if the expression *E is well-formed:
57 // 1.2.1 if *E is an lvalue, std::move(*E);
58 // 1.2.2 otherwise, *E.
59 template<class _Ip>
60 requires (!(__class_or_enum<remove_cvref_t<_Ip>> && __unqualified_iter_move<_Ip>)) &&
61 requires(_Ip&& __i) { *_VSTD::forward<_Ip>(__i); }
62 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator()(_Ip&& __i) const
63 noexcept(noexcept(*_VSTD::forward<_Ip>(__i)))
64 {
65 if constexpr (is_lvalue_reference_v<decltype(*_VSTD::forward<_Ip>(__i))>) {
66 return _VSTD::move(*_VSTD::forward<_Ip>(__i));
67 } else {
68 return *_VSTD::forward<_Ip>(__i);
69 }
70 }
71
72 // [iterator.cust.move]/1.3
73 // Otherwise, ranges::iter_move(E) is ill-formed.
74};
75} // namespace ranges::__iter_move
76
77namespace ranges::inline __cpo {
78 inline constexpr auto iter_move = __iter_move::__fn{};
79}
80
81template<__dereferenceable _Tp>
82requires requires(_Tp& __t) { { ranges::iter_move(__t) } -> __referenceable; }
83using iter_rvalue_reference_t = decltype(ranges::iter_move(declval<_Tp&>()));
84
85#endif // !_LIBCPP_HAS_NO_RANGES
86
87_LIBCPP_END_NAMESPACE_STD
88
89_LIBCPP_POP_MACROS
90
91#endif // _LIBCPP___ITERATOR_ITER_MOVE_H
lib/libcxx/include/__iterator/iter_swap.h created+107
......@@ -0,0 +1,107 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9#ifndef _LIBCPP___ITERATOR_ITER_SWAP_H
10#define _LIBCPP___ITERATOR_ITER_SWAP_H
11
12#include <__config>
13#include <__iterator/concepts.h>
14#include <__iterator/iter_move.h>
15#include <__iterator/iterator_traits.h>
16#include <__iterator/readable_traits.h>
17#include <__ranges/access.h>
18#include <concepts>
19#include <type_traits>
20
21#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
22#pragma GCC system_header
23#endif
24
25_LIBCPP_PUSH_MACROS
26#include <__undef_macros>
27
28_LIBCPP_BEGIN_NAMESPACE_STD
29
30#if !defined(_LIBCPP_HAS_NO_RANGES)
31
32namespace ranges {
33namespace __iter_swap {
34 template<class _I1, class _I2>
35 void iter_swap(_I1, _I2) = delete;
36
37 template<class _T1, class _T2>
38 concept __unqualified_iter_swap = requires(_T1&& __x, _T2&& __y) {
39 iter_swap(_VSTD::forward<_T1>(__x), _VSTD::forward<_T2>(__y));
40 };
41
42 template<class _T1, class _T2>
43 concept __readable_swappable =
44 indirectly_readable<_T1> && indirectly_readable<_T2> &&
45 swappable_with<iter_reference_t<_T1>, iter_reference_t<_T2>>;
46
47 struct __fn {
48 template <class _T1, class _T2>
49 requires __unqualified_iter_swap<_T1, _T2>
50 _LIBCPP_HIDE_FROM_ABI
51 constexpr void operator()(_T1&& __x, _T2&& __y) const
52 noexcept(noexcept(iter_swap(_VSTD::forward<_T1>(__x), _VSTD::forward<_T2>(__y))))
53 {
54 (void)iter_swap(_VSTD::forward<_T1>(__x), _VSTD::forward<_T2>(__y));
55 }
56
57 template <class _T1, class _T2>
58 requires (!__unqualified_iter_swap<_T1, _T2>) &&
59 __readable_swappable<_T1, _T2>
60 _LIBCPP_HIDE_FROM_ABI
61 constexpr void operator()(_T1&& __x, _T2&& __y) const
62 noexcept(noexcept(ranges::swap(*_VSTD::forward<_T1>(__x), *_VSTD::forward<_T2>(__y))))
63 {
64 ranges::swap(*_VSTD::forward<_T1>(__x), *_VSTD::forward<_T2>(__y));
65 }
66
67 template <class _T1, class _T2>
68 requires (!__unqualified_iter_swap<_T1, _T2> &&
69 !__readable_swappable<_T1, _T2>) &&
70 indirectly_movable_storable<_T1, _T2> &&
71 indirectly_movable_storable<_T2, _T1>
72 _LIBCPP_HIDE_FROM_ABI
73 constexpr void operator()(_T1&& __x, _T2&& __y) const
74 noexcept(noexcept(iter_value_t<_T2>(ranges::iter_move(__y))) &&
75 noexcept(*__y = ranges::iter_move(__x)) &&
76 noexcept(*_VSTD::forward<_T1>(__x) = declval<iter_value_t<_T2>>()))
77 {
78 iter_value_t<_T2> __old(ranges::iter_move(__y));
79 *__y = ranges::iter_move(__x);
80 *_VSTD::forward<_T1>(__x) = _VSTD::move(__old);
81 }
82 };
83} // end namespace __iter_swap
84
85inline namespace __cpo {
86 inline constexpr auto iter_swap = __iter_swap::__fn{};
87} // namespace __cpo
88
89} // namespace ranges
90
91template<class _I1, class _I2 = _I1>
92concept indirectly_swappable =
93 indirectly_readable<_I1> && indirectly_readable<_I2> &&
94 requires(const _I1 __i1, const _I2 __i2) {
95 ranges::iter_swap(__i1, __i1);
96 ranges::iter_swap(__i2, __i2);
97 ranges::iter_swap(__i1, __i2);
98 ranges::iter_swap(__i2, __i1);
99 };
100
101#endif // !defined(_LIBCPP_HAS_NO_RANGES)
102
103_LIBCPP_END_NAMESPACE_STD
104
105_LIBCPP_POP_MACROS
106
107#endif // _LIBCPP___ITERATOR_ITER_SWAP_H
lib/libcxx/include/__iterator/iterator.h created+40
......@@ -0,0 +1,40 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___ITERATOR_ITERATOR_H
11#define _LIBCPP___ITERATOR_ITERATOR_H
12
13#include <__config>
14#include <cstddef>
15
16#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
17#pragma GCC system_header
18#endif
19
20_LIBCPP_PUSH_MACROS
21#include <__undef_macros>
22
23_LIBCPP_BEGIN_NAMESPACE_STD
24
25template<class _Category, class _Tp, class _Distance = ptrdiff_t,
26 class _Pointer = _Tp*, class _Reference = _Tp&>
27struct _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 iterator
28{
29 typedef _Tp value_type;
30 typedef _Distance difference_type;
31 typedef _Pointer pointer;
32 typedef _Reference reference;
33 typedef _Category iterator_category;
34};
35
36_LIBCPP_END_NAMESPACE_STD
37
38_LIBCPP_POP_MACROS
39
40#endif // _LIBCPP___ITERATOR_ITERATOR_H
lib/libcxx/include/__iterator/iterator_traits.h created+500
......@@ -0,0 +1,500 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___ITERATOR_ITERATOR_TRAITS_H
11#define _LIBCPP___ITERATOR_ITERATOR_TRAITS_H
12
13#include <__config>
14#include <__iterator/incrementable_traits.h>
15#include <__iterator/readable_traits.h>
16#include <concepts>
17#include <type_traits>
18
19#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
20#pragma GCC system_header
21#endif
22
23_LIBCPP_PUSH_MACROS
24#include <__undef_macros>
25
26_LIBCPP_BEGIN_NAMESPACE_STD
27
28#if !defined(_LIBCPP_HAS_NO_RANGES)
29
30template <class _Tp>
31using __with_reference = _Tp&;
32
33template <class _Tp>
34concept __referenceable = requires {
35 typename __with_reference<_Tp>;
36};
37
38template <class _Tp>
39concept __dereferenceable = requires(_Tp& __t) {
40 { *__t } -> __referenceable; // not required to be equality-preserving
41};
42
43// [iterator.traits]
44template<__dereferenceable _Tp>
45using iter_reference_t = decltype(*declval<_Tp&>());
46
47#endif // !defined(_LIBCPP_HAS_NO_RANGES)
48
49template <class _Iter>
50struct _LIBCPP_TEMPLATE_VIS iterator_traits;
51
52struct _LIBCPP_TEMPLATE_VIS input_iterator_tag {};
53struct _LIBCPP_TEMPLATE_VIS output_iterator_tag {};
54struct _LIBCPP_TEMPLATE_VIS forward_iterator_tag : public input_iterator_tag {};
55struct _LIBCPP_TEMPLATE_VIS bidirectional_iterator_tag : public forward_iterator_tag {};
56struct _LIBCPP_TEMPLATE_VIS random_access_iterator_tag : public bidirectional_iterator_tag {};
57#if _LIBCPP_STD_VER > 17
58struct _LIBCPP_TEMPLATE_VIS contiguous_iterator_tag : public random_access_iterator_tag {};
59#endif
60
61template <class _Iter>
62struct __iter_traits_cache {
63 using type = _If<
64 __is_primary_template<iterator_traits<_Iter> >::value,
65 _Iter,
66 iterator_traits<_Iter>
67 >;
68};
69template <class _Iter>
70using _ITER_TRAITS = typename __iter_traits_cache<_Iter>::type;
71
72struct __iter_concept_concept_test {
73 template <class _Iter>
74 using _Apply = typename _ITER_TRAITS<_Iter>::iterator_concept;
75};
76struct __iter_concept_category_test {
77 template <class _Iter>
78 using _Apply = typename _ITER_TRAITS<_Iter>::iterator_category;
79};
80struct __iter_concept_random_fallback {
81 template <class _Iter>
82 using _Apply = _EnableIf<
83 __is_primary_template<iterator_traits<_Iter> >::value,
84 random_access_iterator_tag
85 >;
86};
87
88template <class _Iter, class _Tester> struct __test_iter_concept
89 : _IsValidExpansion<_Tester::template _Apply, _Iter>,
90 _Tester
91{
92};
93
94template <class _Iter>
95struct __iter_concept_cache {
96 using type = _Or<
97 __test_iter_concept<_Iter, __iter_concept_concept_test>,
98 __test_iter_concept<_Iter, __iter_concept_category_test>,
99 __test_iter_concept<_Iter, __iter_concept_random_fallback>
100 >;
101};
102
103template <class _Iter>
104using _ITER_CONCEPT = typename __iter_concept_cache<_Iter>::type::template _Apply<_Iter>;
105
106
107template <class _Tp>
108struct __has_iterator_typedefs
109{
110private:
111 struct __two {char __lx; char __lxx;};
112 template <class _Up> static __two __test(...);
113 template <class _Up> static char __test(typename __void_t<typename _Up::iterator_category>::type* = 0,
114 typename __void_t<typename _Up::difference_type>::type* = 0,
115 typename __void_t<typename _Up::value_type>::type* = 0,
116 typename __void_t<typename _Up::reference>::type* = 0,
117 typename __void_t<typename _Up::pointer>::type* = 0);
118public:
119 static const bool value = sizeof(__test<_Tp>(0,0,0,0,0)) == 1;
120};
121
122
123template <class _Tp>
124struct __has_iterator_category
125{
126private:
127 struct __two {char __lx; char __lxx;};
128 template <class _Up> static __two __test(...);
129 template <class _Up> static char __test(typename _Up::iterator_category* = nullptr);
130public:
131 static const bool value = sizeof(__test<_Tp>(nullptr)) == 1;
132};
133
134template <class _Tp>
135struct __has_iterator_concept
136{
137private:
138 struct __two {char __lx; char __lxx;};
139 template <class _Up> static __two __test(...);
140 template <class _Up> static char __test(typename _Up::iterator_concept* = nullptr);
141public:
142 static const bool value = sizeof(__test<_Tp>(nullptr)) == 1;
143};
144
145#if !defined(_LIBCPP_HAS_NO_RANGES)
146
147// The `cpp17-*-iterator` exposition-only concepts are easily confused with the Cpp17*Iterator tables,
148// so they've been banished to a namespace that makes it obvious they have a niche use-case.
149namespace __iterator_traits_detail {
150template<class _Ip>
151concept __cpp17_iterator =
152 requires(_Ip __i) {
153 { *__i } -> __referenceable;
154 { ++__i } -> same_as<_Ip&>;
155 { *__i++ } -> __referenceable;
156 } &&
157 copyable<_Ip>;
158
159template<class _Ip>
160concept __cpp17_input_iterator =
161 __cpp17_iterator<_Ip> &&
162 equality_comparable<_Ip> &&
163 requires(_Ip __i) {
164 typename incrementable_traits<_Ip>::difference_type;
165 typename indirectly_readable_traits<_Ip>::value_type;
166 typename common_reference_t<iter_reference_t<_Ip>&&,
167 typename indirectly_readable_traits<_Ip>::value_type&>;
168 typename common_reference_t<decltype(*__i++)&&,
169 typename indirectly_readable_traits<_Ip>::value_type&>;
170 requires signed_integral<typename incrementable_traits<_Ip>::difference_type>;
171 };
172
173template<class _Ip>
174concept __cpp17_forward_iterator =
175 __cpp17_input_iterator<_Ip> &&
176 constructible_from<_Ip> &&
177 is_lvalue_reference_v<iter_reference_t<_Ip>> &&
178 same_as<remove_cvref_t<iter_reference_t<_Ip>>,
179 typename indirectly_readable_traits<_Ip>::value_type> &&
180 requires(_Ip __i) {
181 { __i++ } -> convertible_to<_Ip const&>;
182 { *__i++ } -> same_as<iter_reference_t<_Ip>>;
183 };
184
185template<class _Ip>
186concept __cpp17_bidirectional_iterator =
187 __cpp17_forward_iterator<_Ip> &&
188 requires(_Ip __i) {
189 { --__i } -> same_as<_Ip&>;
190 { __i-- } -> convertible_to<_Ip const&>;
191 { *__i-- } -> same_as<iter_reference_t<_Ip>>;
192 };
193
194template<class _Ip>
195concept __cpp17_random_access_iterator =
196 __cpp17_bidirectional_iterator<_Ip> &&
197 totally_ordered<_Ip> &&
198 requires(_Ip __i, typename incrementable_traits<_Ip>::difference_type __n) {
199 { __i += __n } -> same_as<_Ip&>;
200 { __i -= __n } -> same_as<_Ip&>;
201 { __i + __n } -> same_as<_Ip>;
202 { __n + __i } -> same_as<_Ip>;
203 { __i - __n } -> same_as<_Ip>;
204 { __i - __i } -> same_as<decltype(__n)>;
205 { __i[__n] } -> convertible_to<iter_reference_t<_Ip>>;
206 };
207} // namespace __iterator_traits_detail
208
209template<class _Ip>
210concept __has_member_reference = requires { typename _Ip::reference; };
211
212template<class _Ip>
213concept __has_member_pointer = requires { typename _Ip::pointer; };
214
215template<class _Ip>
216concept __has_member_iterator_category = requires { typename _Ip::iterator_category; };
217
218template<class _Ip>
219concept __specifies_members = requires {
220 typename _Ip::value_type;
221 typename _Ip::difference_type;
222 requires __has_member_reference<_Ip>;
223 requires __has_member_iterator_category<_Ip>;
224 };
225
226template<class>
227struct __iterator_traits_member_pointer_or_void {
228 using type = void;
229};
230
231template<__has_member_pointer _Tp>
232struct __iterator_traits_member_pointer_or_void<_Tp> {
233 using type = typename _Tp::pointer;
234};
235
236template<class _Tp>
237concept __cpp17_iterator_missing_members =
238 !__specifies_members<_Tp> &&
239 __iterator_traits_detail::__cpp17_iterator<_Tp>;
240
241template<class _Tp>
242concept __cpp17_input_iterator_missing_members =
243 __cpp17_iterator_missing_members<_Tp> &&
244 __iterator_traits_detail::__cpp17_input_iterator<_Tp>;
245
246// Otherwise, `pointer` names `void`.
247template<class>
248struct __iterator_traits_member_pointer_or_arrow_or_void { using type = void; };
249
250// [iterator.traits]/3.2.1
251// If the qualified-id `I::pointer` is valid and denotes a type, `pointer` names that type.
252template<__has_member_pointer _Ip>
253struct __iterator_traits_member_pointer_or_arrow_or_void<_Ip> { using type = typename _Ip::pointer; };
254
255// Otherwise, if `decltype(declval<I&>().operator->())` is well-formed, then `pointer` names that
256// type.
257template<class _Ip>
258 requires requires(_Ip& __i) { __i.operator->(); } && (!__has_member_pointer<_Ip>)
259struct __iterator_traits_member_pointer_or_arrow_or_void<_Ip> {
260 using type = decltype(declval<_Ip&>().operator->());
261};
262
263// Otherwise, `reference` names `iter-reference-t<I>`.
264template<class _Ip>
265struct __iterator_traits_member_reference { using type = iter_reference_t<_Ip>; };
266
267// [iterator.traits]/3.2.2
268// If the qualified-id `I::reference` is valid and denotes a type, `reference` names that type.
269template<__has_member_reference _Ip>
270struct __iterator_traits_member_reference<_Ip> { using type = typename _Ip::reference; };
271
272// [iterator.traits]/3.2.3.4
273// input_iterator_tag
274template<class _Ip>
275struct __deduce_iterator_category {
276 using type = input_iterator_tag;
277};
278
279// [iterator.traits]/3.2.3.1
280// `random_access_iterator_tag` if `I` satisfies `cpp17-random-access-iterator`, or otherwise
281template<__iterator_traits_detail::__cpp17_random_access_iterator _Ip>
282struct __deduce_iterator_category<_Ip> {
283 using type = random_access_iterator_tag;
284};
285
286// [iterator.traits]/3.2.3.2
287// `bidirectional_iterator_tag` if `I` satisfies `cpp17-bidirectional-iterator`, or otherwise
288template<__iterator_traits_detail::__cpp17_bidirectional_iterator _Ip>
289struct __deduce_iterator_category<_Ip> {
290 using type = bidirectional_iterator_tag;
291};
292
293// [iterator.traits]/3.2.3.3
294// `forward_iterator_tag` if `I` satisfies `cpp17-forward-iterator`, or otherwise
295template<__iterator_traits_detail::__cpp17_forward_iterator _Ip>
296struct __deduce_iterator_category<_Ip> {
297 using type = forward_iterator_tag;
298};
299
300template<class _Ip>
301struct __iterator_traits_iterator_category : __deduce_iterator_category<_Ip> {};
302
303// [iterator.traits]/3.2.3
304// If the qualified-id `I::iterator-category` is valid and denotes a type, `iterator-category` names
305// that type.
306template<__has_member_iterator_category _Ip>
307struct __iterator_traits_iterator_category<_Ip> {
308 using type = typename _Ip::iterator_category;
309};
310
311// otherwise, it names void.
312template<class>
313struct __iterator_traits_difference_type { using type = void; };
314
315// If the qualified-id `incrementable_traits<I>::difference_type` is valid and denotes a type, then
316// `difference_type` names that type;
317template<class _Ip>
318requires requires { typename incrementable_traits<_Ip>::difference_type; }
319struct __iterator_traits_difference_type<_Ip> {
320 using type = typename incrementable_traits<_Ip>::difference_type;
321};
322
323// [iterator.traits]/3.4
324// Otherwise, `iterator_traits<I>` has no members by any of the above names.
325template<class>
326struct __iterator_traits {};
327
328// [iterator.traits]/3.1
329// If `I` has valid ([temp.deduct]) member types `difference-type`, `value-type`, `reference`, and
330// `iterator-category`, then `iterator-traits<I>` has the following publicly accessible members:
331template<__specifies_members _Ip>
332struct __iterator_traits<_Ip> {
333 using iterator_category = typename _Ip::iterator_category;
334 using value_type = typename _Ip::value_type;
335 using difference_type = typename _Ip::difference_type;
336 using pointer = typename __iterator_traits_member_pointer_or_void<_Ip>::type;
337 using reference = typename _Ip::reference;
338};
339
340// [iterator.traits]/3.2
341// Otherwise, if `I` satisfies the exposition-only concept `cpp17-input-iterator`,
342// `iterator-traits<I>` has the following publicly accessible members:
343template<__cpp17_input_iterator_missing_members _Ip>
344struct __iterator_traits<_Ip> {
345 using iterator_category = typename __iterator_traits_iterator_category<_Ip>::type;
346 using value_type = typename indirectly_readable_traits<_Ip>::value_type;
347 using difference_type = typename incrementable_traits<_Ip>::difference_type;
348 using pointer = typename __iterator_traits_member_pointer_or_arrow_or_void<_Ip>::type;
349 using reference = typename __iterator_traits_member_reference<_Ip>::type;
350};
351
352// Otherwise, if `I` satisfies the exposition-only concept `cpp17-iterator`, then
353// `iterator_traits<I>` has the following publicly accessible members:
354template<__cpp17_iterator_missing_members _Ip>
355struct __iterator_traits<_Ip> {
356 using iterator_category = output_iterator_tag;
357 using value_type = void;
358 using difference_type = typename __iterator_traits_difference_type<_Ip>::type;
359 using pointer = void;
360 using reference = void;
361};
362
363template<class _Ip>
364struct iterator_traits : __iterator_traits<_Ip> {
365 using __primary_template = iterator_traits;
366};
367
368#else // !defined(_LIBCPP_HAS_NO_RANGES)
369
370template <class _Iter, bool> struct __iterator_traits {};
371
372template <class _Iter, bool> struct __iterator_traits_impl {};
373
374template <class _Iter>
375struct __iterator_traits_impl<_Iter, true>
376{
377 typedef typename _Iter::difference_type difference_type;
378 typedef typename _Iter::value_type value_type;
379 typedef typename _Iter::pointer pointer;
380 typedef typename _Iter::reference reference;
381 typedef typename _Iter::iterator_category iterator_category;
382};
383
384template <class _Iter>
385struct __iterator_traits<_Iter, true>
386 : __iterator_traits_impl
387 <
388 _Iter,
389 is_convertible<typename _Iter::iterator_category, input_iterator_tag>::value ||
390 is_convertible<typename _Iter::iterator_category, output_iterator_tag>::value
391 >
392{};
393
394// iterator_traits<Iterator> will only have the nested types if Iterator::iterator_category
395// exists. Else iterator_traits<Iterator> will be an empty class. This is a
396// conforming extension which allows some programs to compile and behave as
397// the client expects instead of failing at compile time.
398
399template <class _Iter>
400struct _LIBCPP_TEMPLATE_VIS iterator_traits
401 : __iterator_traits<_Iter, __has_iterator_typedefs<_Iter>::value> {
402
403 using __primary_template = iterator_traits;
404};
405#endif // !defined(_LIBCPP_HAS_NO_RANGES)
406
407template<class _Tp>
408#if !defined(_LIBCPP_HAS_NO_RANGES)
409requires is_object_v<_Tp>
410#endif
411struct _LIBCPP_TEMPLATE_VIS iterator_traits<_Tp*>
412{
413 typedef ptrdiff_t difference_type;
414 typedef typename remove_cv<_Tp>::type value_type;
415 typedef _Tp* pointer;
416 typedef _Tp& reference;
417 typedef random_access_iterator_tag iterator_category;
418#if _LIBCPP_STD_VER > 17
419 typedef contiguous_iterator_tag iterator_concept;
420#endif
421};
422
423template <class _Tp, class _Up, bool = __has_iterator_category<iterator_traits<_Tp> >::value>
424struct __has_iterator_category_convertible_to
425 : is_convertible<typename iterator_traits<_Tp>::iterator_category, _Up>
426{};
427
428template <class _Tp, class _Up>
429struct __has_iterator_category_convertible_to<_Tp, _Up, false> : false_type {};
430
431template <class _Tp, class _Up, bool = __has_iterator_concept<_Tp>::value>
432struct __has_iterator_concept_convertible_to
433 : is_convertible<typename _Tp::iterator_concept, _Up>
434{};
435
436template <class _Tp, class _Up>
437struct __has_iterator_concept_convertible_to<_Tp, _Up, false> : false_type {};
438
439template <class _Tp>
440struct __is_cpp17_input_iterator : public __has_iterator_category_convertible_to<_Tp, input_iterator_tag> {};
441
442template <class _Tp>
443struct __is_cpp17_forward_iterator : public __has_iterator_category_convertible_to<_Tp, forward_iterator_tag> {};
444
445template <class _Tp>
446struct __is_cpp17_bidirectional_iterator : public __has_iterator_category_convertible_to<_Tp, bidirectional_iterator_tag> {};
447
448template <class _Tp>
449struct __is_cpp17_random_access_iterator : public __has_iterator_category_convertible_to<_Tp, random_access_iterator_tag> {};
450
451// __is_cpp17_contiguous_iterator determines if an iterator is known by
452// libc++ to be contiguous, either because it advertises itself as such
453// (in C++20) or because it is a pointer type or a known trivial wrapper
454// around a (possibly fancy) pointer type, such as __wrap_iter<T*>.
455// Such iterators receive special "contiguous" optimizations in
456// std::copy and std::sort.
457//
458#if _LIBCPP_STD_VER > 17
459template <class _Tp>
460struct __is_cpp17_contiguous_iterator : _Or<
461 __has_iterator_category_convertible_to<_Tp, contiguous_iterator_tag>,
462 __has_iterator_concept_convertible_to<_Tp, contiguous_iterator_tag>
463> {};
464#else
465template <class _Tp>
466struct __is_cpp17_contiguous_iterator : false_type {};
467#endif
468
469// Any native pointer which is an iterator is also a contiguous iterator.
470template <class _Up>
471struct __is_cpp17_contiguous_iterator<_Up*> : true_type {};
472
473
474template <class _Tp>
475struct __is_exactly_cpp17_input_iterator
476 : public integral_constant<bool,
477 __has_iterator_category_convertible_to<_Tp, input_iterator_tag>::value &&
478 !__has_iterator_category_convertible_to<_Tp, forward_iterator_tag>::value> {};
479
480#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
481template<class _InputIterator>
482using __iter_value_type = typename iterator_traits<_InputIterator>::value_type;
483
484template<class _InputIterator>
485using __iter_key_type = remove_const_t<typename iterator_traits<_InputIterator>::value_type::first_type>;
486
487template<class _InputIterator>
488using __iter_mapped_type = typename iterator_traits<_InputIterator>::value_type::second_type;
489
490template<class _InputIterator>
491using __iter_to_alloc_type = pair<
492 add_const_t<typename iterator_traits<_InputIterator>::value_type::first_type>,
493 typename iterator_traits<_InputIterator>::value_type::second_type>;
494#endif // _LIBCPP_HAS_NO_DEDUCTION_GUIDES
495
496_LIBCPP_END_NAMESPACE_STD
497
498_LIBCPP_POP_MACROS
499
500#endif // _LIBCPP___ITERATOR_ITERATOR_TRAITS_H
lib/libcxx/include/__iterator/move_iterator.h created+189
......@@ -0,0 +1,189 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___ITERATOR_MOVE_ITERATOR_H
11#define _LIBCPP___ITERATOR_MOVE_ITERATOR_H
12
13#include <__config>
14#include <__iterator/iterator_traits.h>
15#include <type_traits>
16
17#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
18#pragma GCC system_header
19#endif
20
21_LIBCPP_PUSH_MACROS
22#include <__undef_macros>
23
24_LIBCPP_BEGIN_NAMESPACE_STD
25
26template <class _Iter>
27class _LIBCPP_TEMPLATE_VIS move_iterator
28{
29private:
30 _Iter __i;
31public:
32 typedef _Iter iterator_type;
33 typedef typename iterator_traits<iterator_type>::value_type value_type;
34 typedef typename iterator_traits<iterator_type>::difference_type difference_type;
35 typedef iterator_type pointer;
36 typedef _If<__is_cpp17_random_access_iterator<_Iter>::value,
37 random_access_iterator_tag,
38 typename iterator_traits<_Iter>::iterator_category> iterator_category;
39#if _LIBCPP_STD_VER > 17
40 typedef input_iterator_tag iterator_concept;
41#endif
42
43#ifndef _LIBCPP_CXX03_LANG
44 typedef typename iterator_traits<iterator_type>::reference __reference;
45 typedef typename conditional<
46 is_reference<__reference>::value,
47 typename remove_reference<__reference>::type&&,
48 __reference
49 >::type reference;
50#else
51 typedef typename iterator_traits<iterator_type>::reference reference;
52#endif
53
54 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
55 move_iterator() : __i() {}
56
57 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
58 explicit move_iterator(_Iter __x) : __i(__x) {}
59
60 template <class _Up, class = _EnableIf<
61 !is_same<_Up, _Iter>::value && is_convertible<_Up const&, _Iter>::value
62 > >
63 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
64 move_iterator(const move_iterator<_Up>& __u) : __i(__u.base()) {}
65
66 template <class _Up, class = _EnableIf<
67 !is_same<_Up, _Iter>::value &&
68 is_convertible<_Up const&, _Iter>::value &&
69 is_assignable<_Iter&, _Up const&>::value
70 > >
71 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
72 move_iterator& operator=(const move_iterator<_Up>& __u) {
73 __i = __u.base();
74 return *this;
75 }
76
77 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 _Iter base() const {return __i;}
78 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
79 reference operator*() const { return static_cast<reference>(*__i); }
80 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
81 pointer operator->() const { return __i;}
82 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
83 move_iterator& operator++() {++__i; return *this;}
84 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
85 move_iterator operator++(int) {move_iterator __tmp(*this); ++__i; return __tmp;}
86 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
87 move_iterator& operator--() {--__i; return *this;}
88 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
89 move_iterator operator--(int) {move_iterator __tmp(*this); --__i; return __tmp;}
90 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
91 move_iterator operator+ (difference_type __n) const {return move_iterator(__i + __n);}
92 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
93 move_iterator& operator+=(difference_type __n) {__i += __n; return *this;}
94 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
95 move_iterator operator- (difference_type __n) const {return move_iterator(__i - __n);}
96 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
97 move_iterator& operator-=(difference_type __n) {__i -= __n; return *this;}
98 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
99 reference operator[](difference_type __n) const { return static_cast<reference>(__i[__n]); }
100};
101
102template <class _Iter1, class _Iter2>
103inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
104bool
105operator==(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
106{
107 return __x.base() == __y.base();
108}
109
110template <class _Iter1, class _Iter2>
111inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
112bool
113operator<(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
114{
115 return __x.base() < __y.base();
116}
117
118template <class _Iter1, class _Iter2>
119inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
120bool
121operator!=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
122{
123 return __x.base() != __y.base();
124}
125
126template <class _Iter1, class _Iter2>
127inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
128bool
129operator>(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
130{
131 return __x.base() > __y.base();
132}
133
134template <class _Iter1, class _Iter2>
135inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
136bool
137operator>=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
138{
139 return __x.base() >= __y.base();
140}
141
142template <class _Iter1, class _Iter2>
143inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
144bool
145operator<=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
146{
147 return __x.base() <= __y.base();
148}
149
150#ifndef _LIBCPP_CXX03_LANG
151template <class _Iter1, class _Iter2>
152inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
153auto
154operator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
155-> decltype(__x.base() - __y.base())
156{
157 return __x.base() - __y.base();
158}
159#else
160template <class _Iter1, class _Iter2>
161inline _LIBCPP_INLINE_VISIBILITY
162typename move_iterator<_Iter1>::difference_type
163operator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
164{
165 return __x.base() - __y.base();
166}
167#endif
168
169template <class _Iter>
170inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
171move_iterator<_Iter>
172operator+(typename move_iterator<_Iter>::difference_type __n, const move_iterator<_Iter>& __x)
173{
174 return move_iterator<_Iter>(__x.base() + __n);
175}
176
177template <class _Iter>
178inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
179move_iterator<_Iter>
180make_move_iterator(_Iter __i)
181{
182 return move_iterator<_Iter>(__i);
183}
184
185_LIBCPP_END_NAMESPACE_STD
186
187_LIBCPP_POP_MACROS
188
189#endif // _LIBCPP___ITERATOR_MOVE_ITERATOR_H
lib/libcxx/include/__iterator/next.h created+87
......@@ -0,0 +1,87 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___ITERATOR_NEXT_H
11#define _LIBCPP___ITERATOR_NEXT_H
12
13#include <__config>
14#include <__debug>
15#include <__function_like.h>
16#include <__iterator/advance.h>
17#include <__iterator/concepts.h>
18#include <__iterator/incrementable_traits.h>
19#include <__iterator/iterator_traits.h>
20#include <type_traits>
21
22#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
23#pragma GCC system_header
24#endif
25
26_LIBCPP_PUSH_MACROS
27#include <__undef_macros>
28
29_LIBCPP_BEGIN_NAMESPACE_STD
30
31template <class _InputIter>
32inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
33 typename enable_if<__is_cpp17_input_iterator<_InputIter>::value, _InputIter>::type
34 next(_InputIter __x, typename iterator_traits<_InputIter>::difference_type __n = 1) {
35 _LIBCPP_ASSERT(__n >= 0 || __is_cpp17_bidirectional_iterator<_InputIter>::value,
36 "Attempt to next(it, n) with negative n on a non-bidirectional iterator");
37
38 _VSTD::advance(__x, __n);
39 return __x;
40}
41
42#if !defined(_LIBCPP_HAS_NO_RANGES)
43
44namespace ranges {
45struct __next_fn final : private __function_like {
46 _LIBCPP_HIDE_FROM_ABI
47 constexpr explicit __next_fn(__tag __x) noexcept : __function_like(__x) {}
48
49 template <input_or_output_iterator _Ip>
50 _LIBCPP_HIDE_FROM_ABI
51 constexpr _Ip operator()(_Ip __x) const {
52 ++__x;
53 return __x;
54 }
55
56 template <input_or_output_iterator _Ip>
57 _LIBCPP_HIDE_FROM_ABI
58 constexpr _Ip operator()(_Ip __x, iter_difference_t<_Ip> __n) const {
59 ranges::advance(__x, __n);
60 return __x;
61 }
62
63 template <input_or_output_iterator _Ip, sentinel_for<_Ip> _Sp>
64 _LIBCPP_HIDE_FROM_ABI
65 constexpr _Ip operator()(_Ip __x, _Sp __bound) const {
66 ranges::advance(__x, __bound);
67 return __x;
68 }
69
70 template <input_or_output_iterator _Ip, sentinel_for<_Ip> _Sp>
71 _LIBCPP_HIDE_FROM_ABI
72 constexpr _Ip operator()(_Ip __x, iter_difference_t<_Ip> __n, _Sp __bound) const {
73 ranges::advance(__x, __n, __bound);
74 return __x;
75 }
76};
77
78inline constexpr auto next = __next_fn(__function_like::__tag());
79} // namespace ranges
80
81#endif // !defined(_LIBCPP_HAS_NO_RANGES)
82
83_LIBCPP_END_NAMESPACE_STD
84
85_LIBCPP_POP_MACROS
86
87#endif // _LIBCPP___ITERATOR_PRIMITIVES_H
lib/libcxx/include/__iterator/ostream_iterator.h created+75
......@@ -0,0 +1,75 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___ITERATOR_OSTREAM_ITERATOR_H
11#define _LIBCPP___ITERATOR_OSTREAM_ITERATOR_H
12
13#include <__config>
14#include <__iterator/iterator.h>
15#include <__iterator/iterator_traits.h>
16#include <__memory/addressof.h>
17#include <iosfwd> // for forward declarations of char_traits and basic_ostream
18
19#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
20#pragma GCC system_header
21#endif
22
23_LIBCPP_PUSH_MACROS
24#include <__undef_macros>
25
26_LIBCPP_BEGIN_NAMESPACE_STD
27
28_LIBCPP_SUPPRESS_DEPRECATED_PUSH
29template <class _Tp, class _CharT = char, class _Traits = char_traits<_CharT> >
30class _LIBCPP_TEMPLATE_VIS ostream_iterator
31#if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES)
32 : public iterator<output_iterator_tag, void, void, void, void>
33#endif
34{
35_LIBCPP_SUPPRESS_DEPRECATED_POP
36public:
37 typedef output_iterator_tag iterator_category;
38 typedef void value_type;
39#if _LIBCPP_STD_VER > 17
40 typedef ptrdiff_t difference_type;
41#else
42 typedef void difference_type;
43#endif
44 typedef void pointer;
45 typedef void reference;
46 typedef _CharT char_type;
47 typedef _Traits traits_type;
48 typedef basic_ostream<_CharT, _Traits> ostream_type;
49
50private:
51 ostream_type* __out_stream_;
52 const char_type* __delim_;
53public:
54 _LIBCPP_INLINE_VISIBILITY ostream_iterator(ostream_type& __s) _NOEXCEPT
55 : __out_stream_(_VSTD::addressof(__s)), __delim_(nullptr) {}
56 _LIBCPP_INLINE_VISIBILITY ostream_iterator(ostream_type& __s, const _CharT* __delimiter) _NOEXCEPT
57 : __out_stream_(_VSTD::addressof(__s)), __delim_(__delimiter) {}
58 _LIBCPP_INLINE_VISIBILITY ostream_iterator& operator=(const _Tp& __value_)
59 {
60 *__out_stream_ << __value_;
61 if (__delim_)
62 *__out_stream_ << __delim_;
63 return *this;
64 }
65
66 _LIBCPP_INLINE_VISIBILITY ostream_iterator& operator*() {return *this;}
67 _LIBCPP_INLINE_VISIBILITY ostream_iterator& operator++() {return *this;}
68 _LIBCPP_INLINE_VISIBILITY ostream_iterator& operator++(int) {return *this;}
69};
70
71_LIBCPP_END_NAMESPACE_STD
72
73_LIBCPP_POP_MACROS
74
75#endif // _LIBCPP___ITERATOR_OSTREAM_ITERATOR_H
lib/libcxx/include/__iterator/ostreambuf_iterator.h created+81
......@@ -0,0 +1,81 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___ITERATOR_OSTREAMBUF_ITERATOR_H
11#define _LIBCPP___ITERATOR_OSTREAMBUF_ITERATOR_H
12
13#include <__config>
14#include <__iterator/iterator.h>
15#include <__iterator/iterator_traits.h>
16#include <iosfwd> // for forward declaration of basic_streambuf
17
18#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
19#pragma GCC system_header
20#endif
21
22_LIBCPP_PUSH_MACROS
23#include <__undef_macros>
24
25_LIBCPP_BEGIN_NAMESPACE_STD
26
27_LIBCPP_SUPPRESS_DEPRECATED_PUSH
28template <class _CharT, class _Traits>
29class _LIBCPP_TEMPLATE_VIS ostreambuf_iterator
30#if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES)
31 : public iterator<output_iterator_tag, void, void, void, void>
32#endif
33{
34_LIBCPP_SUPPRESS_DEPRECATED_POP
35public:
36 typedef output_iterator_tag iterator_category;
37 typedef void value_type;
38#if _LIBCPP_STD_VER > 17
39 typedef ptrdiff_t difference_type;
40#else
41 typedef void difference_type;
42#endif
43 typedef void pointer;
44 typedef void reference;
45 typedef _CharT char_type;
46 typedef _Traits traits_type;
47 typedef basic_streambuf<_CharT, _Traits> streambuf_type;
48 typedef basic_ostream<_CharT, _Traits> ostream_type;
49
50private:
51 streambuf_type* __sbuf_;
52public:
53 _LIBCPP_INLINE_VISIBILITY ostreambuf_iterator(ostream_type& __s) _NOEXCEPT
54 : __sbuf_(__s.rdbuf()) {}
55 _LIBCPP_INLINE_VISIBILITY ostreambuf_iterator(streambuf_type* __s) _NOEXCEPT
56 : __sbuf_(__s) {}
57 _LIBCPP_INLINE_VISIBILITY ostreambuf_iterator& operator=(_CharT __c)
58 {
59 if (__sbuf_ && traits_type::eq_int_type(__sbuf_->sputc(__c), traits_type::eof()))
60 __sbuf_ = nullptr;
61 return *this;
62 }
63 _LIBCPP_INLINE_VISIBILITY ostreambuf_iterator& operator*() {return *this;}
64 _LIBCPP_INLINE_VISIBILITY ostreambuf_iterator& operator++() {return *this;}
65 _LIBCPP_INLINE_VISIBILITY ostreambuf_iterator& operator++(int) {return *this;}
66 _LIBCPP_INLINE_VISIBILITY bool failed() const _NOEXCEPT {return __sbuf_ == nullptr;}
67
68 template <class _Ch, class _Tr>
69 friend
70 _LIBCPP_HIDDEN
71 ostreambuf_iterator<_Ch, _Tr>
72 __pad_and_output(ostreambuf_iterator<_Ch, _Tr> __s,
73 const _Ch* __ob, const _Ch* __op, const _Ch* __oe,
74 ios_base& __iob, _Ch __fl);
75};
76
77_LIBCPP_END_NAMESPACE_STD
78
79_LIBCPP_POP_MACROS
80
81#endif // _LIBCPP___ITERATOR_OSTREAMBUF_ITERATOR_H
lib/libcxx/include/__iterator/prev.h created+79
......@@ -0,0 +1,79 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___ITERATOR_PREV_H
11#define _LIBCPP___ITERATOR_PREV_H
12
13#include <__config>
14#include <__debug>
15#include <__function_like.h>
16#include <__iterator/advance.h>
17#include <__iterator/concepts.h>
18#include <__iterator/incrementable_traits.h>
19#include <__iterator/iterator_traits.h>
20#include <type_traits>
21
22#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
23#pragma GCC system_header
24#endif
25
26_LIBCPP_PUSH_MACROS
27#include <__undef_macros>
28
29_LIBCPP_BEGIN_NAMESPACE_STD
30
31template <class _InputIter>
32inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
33 typename enable_if<__is_cpp17_input_iterator<_InputIter>::value, _InputIter>::type
34 prev(_InputIter __x, typename iterator_traits<_InputIter>::difference_type __n = 1) {
35 _LIBCPP_ASSERT(__n <= 0 || __is_cpp17_bidirectional_iterator<_InputIter>::value,
36 "Attempt to prev(it, n) with a positive n on a non-bidirectional iterator");
37 _VSTD::advance(__x, -__n);
38 return __x;
39}
40
41#if !defined(_LIBCPP_HAS_NO_RANGES)
42
43namespace ranges {
44struct __prev_fn final : private __function_like {
45 _LIBCPP_HIDE_FROM_ABI
46 constexpr explicit __prev_fn(__tag __x) noexcept : __function_like(__x) {}
47
48 template <bidirectional_iterator _Ip>
49 _LIBCPP_HIDE_FROM_ABI
50 constexpr _Ip operator()(_Ip __x) const {
51 --__x;
52 return __x;
53 }
54
55 template <bidirectional_iterator _Ip>
56 _LIBCPP_HIDE_FROM_ABI
57 constexpr _Ip operator()(_Ip __x, iter_difference_t<_Ip> __n) const {
58 ranges::advance(__x, -__n);
59 return __x;
60 }
61
62 template <bidirectional_iterator _Ip>
63 _LIBCPP_HIDE_FROM_ABI
64 constexpr _Ip operator()(_Ip __x, iter_difference_t<_Ip> __n, _Ip __bound) const {
65 ranges::advance(__x, -__n, __bound);
66 return __x;
67 }
68};
69
70inline constexpr auto prev = __prev_fn(__function_like::__tag());
71} // namespace ranges
72
73#endif // !defined(_LIBCPP_HAS_NO_RANGES)
74
75_LIBCPP_END_NAMESPACE_STD
76
77_LIBCPP_POP_MACROS
78
79#endif // _LIBCPP___ITERATOR_PREV_H
lib/libcxx/include/__iterator/projected.h created+45
......@@ -0,0 +1,45 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9#ifndef _LIBCPP___ITERATOR_PROJECTED_H
10#define _LIBCPP___ITERATOR_PROJECTED_H
11
12#include <__config>
13#include <__iterator/concepts.h>
14#include <__iterator/incrementable_traits.h>
15#include <type_traits>
16
17#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
18#pragma GCC system_header
19#endif
20
21_LIBCPP_PUSH_MACROS
22#include <__undef_macros>
23
24_LIBCPP_BEGIN_NAMESPACE_STD
25
26#if !defined(_LIBCPP_HAS_NO_RANGES)
27
28template<indirectly_readable _It, indirectly_regular_unary_invocable<_It> _Proj>
29struct projected {
30 using value_type = remove_cvref_t<indirect_result_t<_Proj&, _It>>;
31 indirect_result_t<_Proj&, _It> operator*() const; // not defined
32};
33
34template<weakly_incrementable _It, class _Proj>
35struct incrementable_traits<projected<_It, _Proj>> {
36 using difference_type = iter_difference_t<_It>;
37};
38
39#endif // !defined(_LIBCPP_HAS_NO_RANGES)
40
41_LIBCPP_END_NAMESPACE_STD
42
43_LIBCPP_POP_MACROS
44
45#endif // _LIBCPP___ITERATOR_PROJECTED_H
lib/libcxx/include/__iterator/readable_traits.h created+91
......@@ -0,0 +1,91 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___ITERATOR_READABLE_TRAITS_H
11#define _LIBCPP___ITERATOR_READABLE_TRAITS_H
12
13#include <__config>
14#include <concepts>
15#include <type_traits>
16
17#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
18#pragma GCC system_header
19#endif
20
21_LIBCPP_PUSH_MACROS
22#include <__undef_macros>
23
24_LIBCPP_BEGIN_NAMESPACE_STD
25
26#if !defined(_LIBCPP_HAS_NO_RANGES)
27
28// [readable.traits]
29template<class> struct __cond_value_type {};
30
31template<class _Tp>
32requires is_object_v<_Tp>
33struct __cond_value_type<_Tp> { using value_type = remove_cv_t<_Tp>; };
34
35template<class _Tp>
36concept __has_member_value_type = requires { typename _Tp::value_type; };
37
38template<class _Tp>
39concept __has_member_element_type = requires { typename _Tp::element_type; };
40
41template<class> struct indirectly_readable_traits {};
42
43template<class _Ip>
44requires is_array_v<_Ip>
45struct indirectly_readable_traits<_Ip> {
46 using value_type = remove_cv_t<remove_extent_t<_Ip>>;
47};
48
49template<class _Ip>
50struct indirectly_readable_traits<const _Ip> : indirectly_readable_traits<_Ip> {};
51
52template<class _Tp>
53struct indirectly_readable_traits<_Tp*> : __cond_value_type<_Tp> {};
54
55template<__has_member_value_type _Tp>
56struct indirectly_readable_traits<_Tp>
57 : __cond_value_type<typename _Tp::value_type> {};
58
59template<__has_member_element_type _Tp>
60struct indirectly_readable_traits<_Tp>
61 : __cond_value_type<typename _Tp::element_type> {};
62
63// Pre-emptively applies LWG3541
64template<__has_member_value_type _Tp>
65requires __has_member_element_type<_Tp>
66struct indirectly_readable_traits<_Tp> {};
67template<__has_member_value_type _Tp>
68requires __has_member_element_type<_Tp> &&
69 same_as<remove_cv_t<typename _Tp::element_type>,
70 remove_cv_t<typename _Tp::value_type>>
71struct indirectly_readable_traits<_Tp>
72 : __cond_value_type<typename _Tp::value_type> {};
73
74template <class>
75struct iterator_traits;
76
77// Let `RI` be `remove_cvref_t<I>`. The type `iter_value_t<I>` denotes
78// `indirectly_readable_traits<RI>::value_type` if `iterator_traits<RI>` names a specialization
79// generated from the primary template, and `iterator_traits<RI>::value_type` otherwise.
80template <class _Ip>
81using iter_value_t = typename conditional_t<__is_primary_template<iterator_traits<remove_cvref_t<_Ip> > >::value,
82 indirectly_readable_traits<remove_cvref_t<_Ip> >,
83 iterator_traits<remove_cvref_t<_Ip> > >::value_type;
84
85#endif // !defined(_LIBCPP_HAS_NO_RANGES)
86
87_LIBCPP_END_NAMESPACE_STD
88
89_LIBCPP_POP_MACROS
90
91#endif // _LIBCPP___ITERATOR_READABLE_TRAITS_H
lib/libcxx/include/__iterator/reverse_access.h created+109
......@@ -0,0 +1,109 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___ITERATOR_REVERSE_ACCESS_H
11#define _LIBCPP___ITERATOR_REVERSE_ACCESS_H
12
13#include <__config>
14#include <__iterator/reverse_iterator.h>
15#include <cstddef>
16#include <initializer_list>
17
18#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
19#pragma GCC system_header
20#endif
21
22_LIBCPP_PUSH_MACROS
23#include <__undef_macros>
24
25_LIBCPP_BEGIN_NAMESPACE_STD
26
27#if !defined(_LIBCPP_CXX03_LANG)
28
29#if _LIBCPP_STD_VER > 11
30
31template <class _Tp, size_t _Np>
32_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
33reverse_iterator<_Tp*> rbegin(_Tp (&__array)[_Np])
34{
35 return reverse_iterator<_Tp*>(__array + _Np);
36}
37
38template <class _Tp, size_t _Np>
39_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
40reverse_iterator<_Tp*> rend(_Tp (&__array)[_Np])
41{
42 return reverse_iterator<_Tp*>(__array);
43}
44
45template <class _Ep>
46_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
47reverse_iterator<const _Ep*> rbegin(initializer_list<_Ep> __il)
48{
49 return reverse_iterator<const _Ep*>(__il.end());
50}
51
52template <class _Ep>
53_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
54reverse_iterator<const _Ep*> rend(initializer_list<_Ep> __il)
55{
56 return reverse_iterator<const _Ep*>(__il.begin());
57}
58
59template <class _Cp>
60_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
61auto rbegin(_Cp& __c) -> decltype(__c.rbegin())
62{
63 return __c.rbegin();
64}
65
66template <class _Cp>
67_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
68auto rbegin(const _Cp& __c) -> decltype(__c.rbegin())
69{
70 return __c.rbegin();
71}
72
73template <class _Cp>
74_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
75auto rend(_Cp& __c) -> decltype(__c.rend())
76{
77 return __c.rend();
78}
79
80template <class _Cp>
81_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
82auto rend(const _Cp& __c) -> decltype(__c.rend())
83{
84 return __c.rend();
85}
86
87template <class _Cp>
88_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
89auto crbegin(const _Cp& __c) -> decltype(_VSTD::rbegin(__c))
90{
91 return _VSTD::rbegin(__c);
92}
93
94template <class _Cp>
95_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
96auto crend(const _Cp& __c) -> decltype(_VSTD::rend(__c))
97{
98 return _VSTD::rend(__c);
99}
100
101#endif
102
103#endif // !defined(_LIBCPP_CXX03_LANG)
104
105_LIBCPP_END_NAMESPACE_STD
106
107_LIBCPP_POP_MACROS
108
109#endif // _LIBCPP___ITERATOR_REVERSE_ACCESS_H
lib/libcxx/include/__iterator/reverse_iterator.h created+239
......@@ -0,0 +1,239 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___ITERATOR_REVERSE_ITERATOR_H
11#define _LIBCPP___ITERATOR_REVERSE_ITERATOR_H
12
13#include <__config>
14#include <__iterator/iterator.h>
15#include <__iterator/iterator_traits.h>
16#include <__memory/addressof.h>
17#include <type_traits>
18
19#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
20#pragma GCC system_header
21#endif
22
23_LIBCPP_PUSH_MACROS
24#include <__undef_macros>
25
26_LIBCPP_BEGIN_NAMESPACE_STD
27
28template <class _Tp, class = void>
29struct __is_stashing_iterator : false_type {};
30
31template <class _Tp>
32struct __is_stashing_iterator<_Tp, typename __void_t<typename _Tp::__stashing_iterator_tag>::type>
33 : true_type {};
34
35_LIBCPP_SUPPRESS_DEPRECATED_PUSH
36template <class _Iter>
37class _LIBCPP_TEMPLATE_VIS reverse_iterator
38#if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES)
39 : public iterator<typename iterator_traits<_Iter>::iterator_category,
40 typename iterator_traits<_Iter>::value_type,
41 typename iterator_traits<_Iter>::difference_type,
42 typename iterator_traits<_Iter>::pointer,
43 typename iterator_traits<_Iter>::reference>
44#endif
45{
46_LIBCPP_SUPPRESS_DEPRECATED_POP
47private:
48#ifndef _LIBCPP_ABI_NO_ITERATOR_BASES
49 _Iter __t; // no longer used as of LWG #2360, not removed due to ABI break
50#endif
51
52 static_assert(!__is_stashing_iterator<_Iter>::value,
53 "The specified iterator type cannot be used with reverse_iterator; "
54 "Using stashing iterators with reverse_iterator causes undefined behavior");
55
56protected:
57 _Iter current;
58public:
59 typedef _Iter iterator_type;
60 typedef typename iterator_traits<_Iter>::difference_type difference_type;
61 typedef typename iterator_traits<_Iter>::reference reference;
62 typedef typename iterator_traits<_Iter>::pointer pointer;
63 typedef _If<__is_cpp17_random_access_iterator<_Iter>::value,
64 random_access_iterator_tag,
65 typename iterator_traits<_Iter>::iterator_category> iterator_category;
66 typedef typename iterator_traits<_Iter>::value_type value_type;
67
68#if _LIBCPP_STD_VER > 17
69 typedef _If<__is_cpp17_random_access_iterator<_Iter>::value,
70 random_access_iterator_tag,
71 bidirectional_iterator_tag> iterator_concept;
72#endif
73
74#ifndef _LIBCPP_ABI_NO_ITERATOR_BASES
75 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
76 reverse_iterator() : __t(), current() {}
77
78 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
79 explicit reverse_iterator(_Iter __x) : __t(__x), current(__x) {}
80
81 template <class _Up, class = _EnableIf<
82 !is_same<_Up, _Iter>::value && is_convertible<_Up const&, _Iter>::value
83 > >
84 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
85 reverse_iterator(const reverse_iterator<_Up>& __u)
86 : __t(__u.base()), current(__u.base())
87 { }
88
89 template <class _Up, class = _EnableIf<
90 !is_same<_Up, _Iter>::value &&
91 is_convertible<_Up const&, _Iter>::value &&
92 is_assignable<_Up const&, _Iter>::value
93 > >
94 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
95 reverse_iterator& operator=(const reverse_iterator<_Up>& __u) {
96 __t = current = __u.base();
97 return *this;
98 }
99#else
100 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
101 reverse_iterator() : current() {}
102
103 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
104 explicit reverse_iterator(_Iter __x) : current(__x) {}
105
106 template <class _Up, class = _EnableIf<
107 !is_same<_Up, _Iter>::value && is_convertible<_Up const&, _Iter>::value
108 > >
109 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
110 reverse_iterator(const reverse_iterator<_Up>& __u)
111 : current(__u.base())
112 { }
113
114 template <class _Up, class = _EnableIf<
115 !is_same<_Up, _Iter>::value &&
116 is_convertible<_Up const&, _Iter>::value &&
117 is_assignable<_Up const&, _Iter>::value
118 > >
119 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
120 reverse_iterator& operator=(const reverse_iterator<_Up>& __u) {
121 current = __u.base();
122 return *this;
123 }
124#endif
125 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
126 _Iter base() const {return current;}
127 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
128 reference operator*() const {_Iter __tmp = current; return *--__tmp;}
129 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
130 pointer operator->() const {return _VSTD::addressof(operator*());}
131 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
132 reverse_iterator& operator++() {--current; return *this;}
133 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
134 reverse_iterator operator++(int) {reverse_iterator __tmp(*this); --current; return __tmp;}
135 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
136 reverse_iterator& operator--() {++current; return *this;}
137 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
138 reverse_iterator operator--(int) {reverse_iterator __tmp(*this); ++current; return __tmp;}
139 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
140 reverse_iterator operator+ (difference_type __n) const {return reverse_iterator(current - __n);}
141 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
142 reverse_iterator& operator+=(difference_type __n) {current -= __n; return *this;}
143 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
144 reverse_iterator operator- (difference_type __n) const {return reverse_iterator(current + __n);}
145 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
146 reverse_iterator& operator-=(difference_type __n) {current += __n; return *this;}
147 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
148 reference operator[](difference_type __n) const {return *(*this + __n);}
149};
150
151template <class _Iter1, class _Iter2>
152inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
153bool
154operator==(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
155{
156 return __x.base() == __y.base();
157}
158
159template <class _Iter1, class _Iter2>
160inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
161bool
162operator<(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
163{
164 return __x.base() > __y.base();
165}
166
167template <class _Iter1, class _Iter2>
168inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
169bool
170operator!=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
171{
172 return __x.base() != __y.base();
173}
174
175template <class _Iter1, class _Iter2>
176inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
177bool
178operator>(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
179{
180 return __x.base() < __y.base();
181}
182
183template <class _Iter1, class _Iter2>
184inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
185bool
186operator>=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
187{
188 return __x.base() <= __y.base();
189}
190
191template <class _Iter1, class _Iter2>
192inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
193bool
194operator<=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
195{
196 return __x.base() >= __y.base();
197}
198
199#ifndef _LIBCPP_CXX03_LANG
200template <class _Iter1, class _Iter2>
201inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
202auto
203operator-(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
204-> decltype(__y.base() - __x.base())
205{
206 return __y.base() - __x.base();
207}
208#else
209template <class _Iter1, class _Iter2>
210inline _LIBCPP_INLINE_VISIBILITY
211typename reverse_iterator<_Iter1>::difference_type
212operator-(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
213{
214 return __y.base() - __x.base();
215}
216#endif
217
218template <class _Iter>
219inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
220reverse_iterator<_Iter>
221operator+(typename reverse_iterator<_Iter>::difference_type __n, const reverse_iterator<_Iter>& __x)
222{
223 return reverse_iterator<_Iter>(__x.base() - __n);
224}
225
226#if _LIBCPP_STD_VER > 11
227template <class _Iter>
228inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
229reverse_iterator<_Iter> make_reverse_iterator(_Iter __i)
230{
231 return reverse_iterator<_Iter>(__i);
232}
233#endif
234
235_LIBCPP_END_NAMESPACE_STD
236
237_LIBCPP_POP_MACROS
238
239#endif // _LIBCPP___ITERATOR_REVERSE_ITERATOR_H
lib/libcxx/include/__iterator/size.h created+58
......@@ -0,0 +1,58 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___ITERATOR_SIZE_H
11#define _LIBCPP___ITERATOR_SIZE_H
12
13#include <__config>
14#include <cstddef>
15#include <type_traits>
16
17#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
18#pragma GCC system_header
19#endif
20
21_LIBCPP_PUSH_MACROS
22#include <__undef_macros>
23
24_LIBCPP_BEGIN_NAMESPACE_STD
25
26#if _LIBCPP_STD_VER > 14
27
28template <class _Cont>
29_LIBCPP_INLINE_VISIBILITY
30constexpr auto size(const _Cont& __c)
31_NOEXCEPT_(noexcept(__c.size()))
32-> decltype (__c.size())
33{ return __c.size(); }
34
35template <class _Tp, size_t _Sz>
36_LIBCPP_INLINE_VISIBILITY
37constexpr size_t size(const _Tp (&)[_Sz]) noexcept { return _Sz; }
38
39#if _LIBCPP_STD_VER > 17
40template <class _Cont>
41_LIBCPP_INLINE_VISIBILITY
42constexpr auto ssize(const _Cont& __c)
43_NOEXCEPT_(noexcept(static_cast<common_type_t<ptrdiff_t, make_signed_t<decltype(__c.size())>>>(__c.size())))
44-> common_type_t<ptrdiff_t, make_signed_t<decltype(__c.size())>>
45{ return static_cast<common_type_t<ptrdiff_t, make_signed_t<decltype(__c.size())>>>(__c.size()); }
46
47template <class _Tp, ptrdiff_t _Sz>
48_LIBCPP_INLINE_VISIBILITY
49constexpr ptrdiff_t ssize(const _Tp (&)[_Sz]) noexcept { return _Sz; }
50#endif
51
52#endif // _LIBCPP_STD_VER > 14
53
54_LIBCPP_END_NAMESPACE_STD
55
56_LIBCPP_POP_MACROS
57
58#endif // _LIBCPP___ITERATOR_SIZE_H
lib/libcxx/include/__iterator/wrap_iter.h created+300
......@@ -0,0 +1,300 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___ITERATOR_WRAP_ITER_H
11#define _LIBCPP___ITERATOR_WRAP_ITER_H
12
13#include <__config>
14#include <__debug>
15#include <__iterator/iterator_traits.h>
16#include <__memory/pointer_traits.h> // __to_address
17#include <type_traits>
18
19#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
20#pragma GCC system_header
21#endif
22
23_LIBCPP_PUSH_MACROS
24#include <__undef_macros>
25
26_LIBCPP_BEGIN_NAMESPACE_STD
27
28template <class _Iter>
29class __wrap_iter
30{
31public:
32 typedef _Iter iterator_type;
33 typedef typename iterator_traits<iterator_type>::value_type value_type;
34 typedef typename iterator_traits<iterator_type>::difference_type difference_type;
35 typedef typename iterator_traits<iterator_type>::pointer pointer;
36 typedef typename iterator_traits<iterator_type>::reference reference;
37 typedef typename iterator_traits<iterator_type>::iterator_category iterator_category;
38#if _LIBCPP_STD_VER > 17
39 typedef contiguous_iterator_tag iterator_concept;
40#endif
41
42private:
43 iterator_type __i;
44public:
45 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter() _NOEXCEPT
46#if _LIBCPP_STD_VER > 11
47 : __i{}
48#endif
49 {
50#if _LIBCPP_DEBUG_LEVEL == 2
51 __get_db()->__insert_i(this);
52#endif
53 }
54 template <class _Up> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
55 __wrap_iter(const __wrap_iter<_Up>& __u,
56 typename enable_if<is_convertible<_Up, iterator_type>::value>::type* = nullptr) _NOEXCEPT
57 : __i(__u.base())
58 {
59#if _LIBCPP_DEBUG_LEVEL == 2
60 __get_db()->__iterator_copy(this, &__u);
61#endif
62 }
63#if _LIBCPP_DEBUG_LEVEL == 2
64 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
65 __wrap_iter(const __wrap_iter& __x)
66 : __i(__x.base())
67 {
68 __get_db()->__iterator_copy(this, &__x);
69 }
70 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
71 __wrap_iter& operator=(const __wrap_iter& __x)
72 {
73 if (this != &__x)
74 {
75 __get_db()->__iterator_copy(this, &__x);
76 __i = __x.__i;
77 }
78 return *this;
79 }
80 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
81 ~__wrap_iter()
82 {
83 __get_db()->__erase_i(this);
84 }
85#endif
86 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG reference operator*() const _NOEXCEPT
87 {
88#if _LIBCPP_DEBUG_LEVEL == 2
89 _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
90 "Attempted to dereference a non-dereferenceable iterator");
91#endif
92 return *__i;
93 }
94 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG pointer operator->() const _NOEXCEPT
95 {
96#if _LIBCPP_DEBUG_LEVEL == 2
97 _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
98 "Attempted to dereference a non-dereferenceable iterator");
99#endif
100 return _VSTD::__to_address(__i);
101 }
102 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter& operator++() _NOEXCEPT
103 {
104#if _LIBCPP_DEBUG_LEVEL == 2
105 _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
106 "Attempted to increment a non-incrementable iterator");
107#endif
108 ++__i;
109 return *this;
110 }
111 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter operator++(int) _NOEXCEPT
112 {__wrap_iter __tmp(*this); ++(*this); return __tmp;}
113
114 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter& operator--() _NOEXCEPT
115 {
116#if _LIBCPP_DEBUG_LEVEL == 2
117 _LIBCPP_ASSERT(__get_const_db()->__decrementable(this),
118 "Attempted to decrement a non-decrementable iterator");
119#endif
120 --__i;
121 return *this;
122 }
123 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter operator--(int) _NOEXCEPT
124 {__wrap_iter __tmp(*this); --(*this); return __tmp;}
125 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter operator+ (difference_type __n) const _NOEXCEPT
126 {__wrap_iter __w(*this); __w += __n; return __w;}
127 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter& operator+=(difference_type __n) _NOEXCEPT
128 {
129#if _LIBCPP_DEBUG_LEVEL == 2
130 _LIBCPP_ASSERT(__get_const_db()->__addable(this, __n),
131 "Attempted to add/subtract an iterator outside its valid range");
132#endif
133 __i += __n;
134 return *this;
135 }
136 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter operator- (difference_type __n) const _NOEXCEPT
137 {return *this + (-__n);}
138 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter& operator-=(difference_type __n) _NOEXCEPT
139 {*this += -__n; return *this;}
140 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG reference operator[](difference_type __n) const _NOEXCEPT
141 {
142#if _LIBCPP_DEBUG_LEVEL == 2
143 _LIBCPP_ASSERT(__get_const_db()->__subscriptable(this, __n),
144 "Attempted to subscript an iterator outside its valid range");
145#endif
146 return __i[__n];
147 }
148
149 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG iterator_type base() const _NOEXCEPT {return __i;}
150
151private:
152#if _LIBCPP_DEBUG_LEVEL == 2
153 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter(const void* __p, iterator_type __x) : __i(__x)
154 {
155 __get_db()->__insert_ic(this, __p);
156 }
157#else
158 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter(iterator_type __x) _NOEXCEPT : __i(__x) {}
159#endif
160
161 template <class _Up> friend class __wrap_iter;
162 template <class _CharT, class _Traits, class _Alloc> friend class basic_string;
163 template <class _Tp, class _Alloc> friend class _LIBCPP_TEMPLATE_VIS vector;
164 template <class _Tp, size_t> friend class _LIBCPP_TEMPLATE_VIS span;
165};
166
167template <class _Iter1>
168_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
169bool operator==(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT
170{
171 return __x.base() == __y.base();
172}
173
174template <class _Iter1, class _Iter2>
175_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
176bool operator==(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
177{
178 return __x.base() == __y.base();
179}
180
181template <class _Iter1>
182_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
183bool operator<(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT
184{
185#if _LIBCPP_DEBUG_LEVEL == 2
186 _LIBCPP_ASSERT(__get_const_db()->__less_than_comparable(&__x, &__y),
187 "Attempted to compare incomparable iterators");
188#endif
189 return __x.base() < __y.base();
190}
191
192template <class _Iter1, class _Iter2>
193_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
194bool operator<(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
195{
196#if _LIBCPP_DEBUG_LEVEL == 2
197 _LIBCPP_ASSERT(__get_const_db()->__less_than_comparable(&__x, &__y),
198 "Attempted to compare incomparable iterators");
199#endif
200 return __x.base() < __y.base();
201}
202
203template <class _Iter1>
204_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
205bool operator!=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT
206{
207 return !(__x == __y);
208}
209
210template <class _Iter1, class _Iter2>
211_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
212bool operator!=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
213{
214 return !(__x == __y);
215}
216
217template <class _Iter1>
218_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
219bool operator>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT
220{
221 return __y < __x;
222}
223
224template <class _Iter1, class _Iter2>
225_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
226bool operator>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
227{
228 return __y < __x;
229}
230
231template <class _Iter1>
232_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
233bool operator>=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT
234{
235 return !(__x < __y);
236}
237
238template <class _Iter1, class _Iter2>
239_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
240bool operator>=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
241{
242 return !(__x < __y);
243}
244
245template <class _Iter1>
246_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
247bool operator<=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT
248{
249 return !(__y < __x);
250}
251
252template <class _Iter1, class _Iter2>
253_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
254bool operator<=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
255{
256 return !(__y < __x);
257}
258
259template <class _Iter1, class _Iter2>
260_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
261#ifndef _LIBCPP_CXX03_LANG
262auto operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
263 -> decltype(__x.base() - __y.base())
264#else
265typename __wrap_iter<_Iter1>::difference_type
266operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
267#endif // C++03
268{
269#if _LIBCPP_DEBUG_LEVEL == 2
270 _LIBCPP_ASSERT(__get_const_db()->__less_than_comparable(&__x, &__y),
271 "Attempted to subtract incompatible iterators");
272#endif
273 return __x.base() - __y.base();
274}
275
276template <class _Iter1>
277_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
278__wrap_iter<_Iter1> operator+(typename __wrap_iter<_Iter1>::difference_type __n, __wrap_iter<_Iter1> __x) _NOEXCEPT
279{
280 __x += __n;
281 return __x;
282}
283
284#if _LIBCPP_STD_VER <= 17
285template <class _It>
286struct __is_cpp17_contiguous_iterator<__wrap_iter<_It> > : true_type {};
287#endif
288
289template <class _Iter>
290_LIBCPP_CONSTEXPR
291decltype(_VSTD::__to_address(declval<_Iter>()))
292__to_address(__wrap_iter<_Iter> __w) _NOEXCEPT {
293 return _VSTD::__to_address(__w.base());
294}
295
296_LIBCPP_END_NAMESPACE_STD
297
298_LIBCPP_POP_MACROS
299
300#endif // _LIBCPP___ITERATOR_WRAP_ITER_H
lib/libcxx/include/__libcpp_version+1-1
......@@ -1 +1 @@
112000
113000
lib/libcxx/include/__locale+13-13
......@@ -10,8 +10,8 @@
1010#ifndef _LIBCPP___LOCALE
1111#define _LIBCPP___LOCALE
1212
13#include <__config>
1413#include <__availability>
14#include <__config>
1515#include <string>
1616#include <memory>
1717#include <utility>
......@@ -1161,7 +1161,7 @@ protected:
11611161 virtual int do_max_length() const _NOEXCEPT;
11621162};
11631163
1164#ifndef _LIBCPP_NO_HAS_CHAR8_T
1164#ifndef _LIBCPP_HAS_NO_CHAR8_T
11651165
11661166// template <> class codecvt<char16_t, char8_t, mbstate_t> // C++20
11671167
......@@ -1337,7 +1337,7 @@ protected:
13371337 virtual int do_max_length() const _NOEXCEPT;
13381338};
13391339
1340#ifndef _LIBCPP_NO_HAS_CHAR8_T
1340#ifndef _LIBCPP_HAS_NO_CHAR8_T
13411341
13421342// template <> class codecvt<char32_t, char8_t, mbstate_t> // C++20
13431343
......@@ -1455,7 +1455,7 @@ _LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VI
14551455_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<wchar_t, char, mbstate_t>)
14561456_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char16_t, char, mbstate_t>) // deprecated in C++20
14571457_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char32_t, char, mbstate_t>) // deprecated in C++20
1458#ifndef _LIBCPP_NO_HAS_CHAR8_T
1458#ifndef _LIBCPP_HAS_NO_CHAR8_T
14591459_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char16_t, char8_t, mbstate_t>) // C++20
14601460_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char32_t, char8_t, mbstate_t>) // C++20
14611461#endif
......@@ -1484,14 +1484,14 @@ struct __narrow_to_utf8<8>
14841484
14851485_LIBCPP_SUPPRESS_DEPRECATED_PUSH
14861486template <>
1487struct _LIBCPP_TEMPLATE_VIS __narrow_to_utf8<16>
1487struct _LIBCPP_TYPE_VIS __narrow_to_utf8<16>
14881488 : public codecvt<char16_t, char, mbstate_t>
14891489{
14901490 _LIBCPP_INLINE_VISIBILITY
14911491 __narrow_to_utf8() : codecvt<char16_t, char, mbstate_t>(1) {}
14921492_LIBCPP_SUPPRESS_DEPRECATED_POP
14931493
1494 _LIBCPP_EXPORTED_FROM_ABI ~__narrow_to_utf8();
1494 ~__narrow_to_utf8();
14951495
14961496 template <class _OutputIterator, class _CharT>
14971497 _LIBCPP_INLINE_VISIBILITY
......@@ -1520,14 +1520,14 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP
15201520
15211521_LIBCPP_SUPPRESS_DEPRECATED_PUSH
15221522template <>
1523struct _LIBCPP_TEMPLATE_VIS __narrow_to_utf8<32>
1523struct _LIBCPP_TYPE_VIS __narrow_to_utf8<32>
15241524 : public codecvt<char32_t, char, mbstate_t>
15251525{
15261526 _LIBCPP_INLINE_VISIBILITY
15271527 __narrow_to_utf8() : codecvt<char32_t, char, mbstate_t>(1) {}
15281528_LIBCPP_SUPPRESS_DEPRECATED_POP
15291529
1530 _LIBCPP_EXPORTED_FROM_ABI ~__narrow_to_utf8();
1530 ~__narrow_to_utf8();
15311531
15321532 template <class _OutputIterator, class _CharT>
15331533 _LIBCPP_INLINE_VISIBILITY
......@@ -1578,14 +1578,14 @@ struct __widen_from_utf8<8>
15781578
15791579_LIBCPP_SUPPRESS_DEPRECATED_PUSH
15801580template <>
1581struct _LIBCPP_TEMPLATE_VIS __widen_from_utf8<16>
1581struct _LIBCPP_TYPE_VIS __widen_from_utf8<16>
15821582 : public codecvt<char16_t, char, mbstate_t>
15831583{
15841584 _LIBCPP_INLINE_VISIBILITY
15851585 __widen_from_utf8() : codecvt<char16_t, char, mbstate_t>(1) {}
15861586_LIBCPP_SUPPRESS_DEPRECATED_POP
15871587
1588 _LIBCPP_EXPORTED_FROM_ABI ~__widen_from_utf8();
1588 ~__widen_from_utf8();
15891589
15901590 template <class _OutputIterator>
15911591 _LIBCPP_INLINE_VISIBILITY
......@@ -1614,14 +1614,14 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP
16141614
16151615_LIBCPP_SUPPRESS_DEPRECATED_PUSH
16161616template <>
1617struct _LIBCPP_TEMPLATE_VIS __widen_from_utf8<32>
1617struct _LIBCPP_TYPE_VIS __widen_from_utf8<32>
16181618 : public codecvt<char32_t, char, mbstate_t>
16191619{
16201620 _LIBCPP_INLINE_VISIBILITY
16211621 __widen_from_utf8() : codecvt<char32_t, char, mbstate_t>(1) {}
16221622_LIBCPP_SUPPRESS_DEPRECATED_POP
16231623
1624 _LIBCPP_EXPORTED_FROM_ABI ~__widen_from_utf8();
1624 ~__widen_from_utf8();
16251625
16261626 template <class _OutputIterator>
16271627 _LIBCPP_INLINE_VISIBILITY
......@@ -1756,4 +1756,4 @@ private:
17561756
17571757_LIBCPP_END_NAMESPACE_STD
17581758
1759#endif // _LIBCPP___LOCALE
1759#endif // _LIBCPP___LOCALE
lib/libcxx/include/__memory/addressof.h created+96
......@@ -0,0 +1,96 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___MEMORY_ADDRESSOF_H
11#define _LIBCPP___MEMORY_ADDRESSOF_H
12
13#include <__config>
14
15#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
16#pragma GCC system_header
17#endif
18
19_LIBCPP_PUSH_MACROS
20#include <__undef_macros>
21
22_LIBCPP_BEGIN_NAMESPACE_STD
23
24#ifndef _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF
25
26template <class _Tp>
27inline _LIBCPP_CONSTEXPR_AFTER_CXX14
28_LIBCPP_NO_CFI _LIBCPP_INLINE_VISIBILITY
29_Tp*
30addressof(_Tp& __x) _NOEXCEPT
31{
32 return __builtin_addressof(__x);
33}
34
35#else
36
37template <class _Tp>
38inline _LIBCPP_NO_CFI _LIBCPP_INLINE_VISIBILITY
39_Tp*
40addressof(_Tp& __x) _NOEXCEPT
41{
42 return reinterpret_cast<_Tp *>(
43 const_cast<char *>(&reinterpret_cast<const volatile char &>(__x)));
44}
45
46#endif // _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF
47
48#if defined(_LIBCPP_HAS_OBJC_ARC) && !defined(_LIBCPP_PREDEFINED_OBJC_ARC_ADDRESSOF)
49// Objective-C++ Automatic Reference Counting uses qualified pointers
50// that require special addressof() signatures. When
51// _LIBCPP_PREDEFINED_OBJC_ARC_ADDRESSOF is defined, the compiler
52// itself is providing these definitions. Otherwise, we provide them.
53template <class _Tp>
54inline _LIBCPP_INLINE_VISIBILITY
55__strong _Tp*
56addressof(__strong _Tp& __x) _NOEXCEPT
57{
58 return &__x;
59}
60
61#ifdef _LIBCPP_HAS_OBJC_ARC_WEAK
62template <class _Tp>
63inline _LIBCPP_INLINE_VISIBILITY
64__weak _Tp*
65addressof(__weak _Tp& __x) _NOEXCEPT
66{
67 return &__x;
68}
69#endif
70
71template <class _Tp>
72inline _LIBCPP_INLINE_VISIBILITY
73__autoreleasing _Tp*
74addressof(__autoreleasing _Tp& __x) _NOEXCEPT
75{
76 return &__x;
77}
78
79template <class _Tp>
80inline _LIBCPP_INLINE_VISIBILITY
81__unsafe_unretained _Tp*
82addressof(__unsafe_unretained _Tp& __x) _NOEXCEPT
83{
84 return &__x;
85}
86#endif
87
88#if !defined(_LIBCPP_CXX03_LANG)
89template <class _Tp> _Tp* addressof(const _Tp&&) noexcept = delete;
90#endif
91
92_LIBCPP_END_NAMESPACE_STD
93
94_LIBCPP_POP_MACROS
95
96#endif // _LIBCPP___MEMORY_ADDRESSOF_H
lib/libcxx/include/__memory/allocation_guard.h created+89
......@@ -0,0 +1,89 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___MEMORY_ALLOCATION_GUARD_H
11#define _LIBCPP___MEMORY_ALLOCATION_GUARD_H
12
13#include <__config>
14#include <__memory/allocator_traits.h>
15#include <cstddef>
16#include <utility>
17
18#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
19#pragma GCC system_header
20#endif
21
22_LIBCPP_PUSH_MACROS
23#include <__undef_macros>
24
25
26_LIBCPP_BEGIN_NAMESPACE_STD
27
28// Helper class to allocate memory using an Allocator in an exception safe
29// manner.
30//
31// The intended usage of this class is as follows:
32//
33// 0
34// 1 __allocation_guard<SomeAllocator> guard(alloc, 10);
35// 2 do_some_initialization_that_may_throw(guard.__get());
36// 3 save_allocated_pointer_in_a_noexcept_operation(guard.__release_ptr());
37// 4
38//
39// If line (2) throws an exception during initialization of the memory, the
40// guard's destructor will be called, and the memory will be released using
41// Allocator deallocation. Otherwise, we release the memory from the guard on
42// line (3) in an operation that can't throw -- after that, the guard is not
43// responsible for the memory anymore.
44//
45// This is similar to a unique_ptr, except it's easier to use with a
46// custom allocator.
47template<class _Alloc>
48struct __allocation_guard {
49 using _Pointer = typename allocator_traits<_Alloc>::pointer;
50 using _Size = typename allocator_traits<_Alloc>::size_type;
51
52 template<class _AllocT> // we perform the allocator conversion inside the constructor
53 _LIBCPP_HIDE_FROM_ABI
54 explicit __allocation_guard(_AllocT __alloc, _Size __n)
55 : __alloc_(_VSTD::move(__alloc))
56 , __n_(__n)
57 , __ptr_(allocator_traits<_Alloc>::allocate(__alloc_, __n_)) // initialization order is important
58 { }
59
60 _LIBCPP_HIDE_FROM_ABI
61 ~__allocation_guard() _NOEXCEPT {
62 if (__ptr_ != nullptr) {
63 allocator_traits<_Alloc>::deallocate(__alloc_, __ptr_, __n_);
64 }
65 }
66
67 _LIBCPP_HIDE_FROM_ABI
68 _Pointer __release_ptr() _NOEXCEPT { // not called __release() because it's a keyword in objective-c++
69 _Pointer __tmp = __ptr_;
70 __ptr_ = nullptr;
71 return __tmp;
72 }
73
74 _LIBCPP_HIDE_FROM_ABI
75 _Pointer __get() const _NOEXCEPT {
76 return __ptr_;
77 }
78
79private:
80 _Alloc __alloc_;
81 _Size __n_;
82 _Pointer __ptr_;
83};
84
85_LIBCPP_END_NAMESPACE_STD
86
87_LIBCPP_POP_MACROS
88
89#endif // _LIBCPP___MEMORY_ALLOCATION_GUARD_H
lib/libcxx/include/__memory/allocator.h created+254
......@@ -0,0 +1,254 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___MEMORY_ALLOCATOR_H
11#define _LIBCPP___MEMORY_ALLOCATOR_H
12
13#include <__config>
14#include <__memory/allocator_traits.h>
15#include <__utility/forward.h>
16#include <cstddef>
17#include <new>
18#include <stdexcept>
19#include <type_traits>
20
21#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
22#pragma GCC system_header
23#endif
24
25_LIBCPP_PUSH_MACROS
26#include <__undef_macros>
27
28_LIBCPP_BEGIN_NAMESPACE_STD
29
30template <class _Tp> class allocator;
31
32#if _LIBCPP_STD_VER <= 17
33template <>
34class _LIBCPP_TEMPLATE_VIS allocator<void>
35{
36public:
37 _LIBCPP_DEPRECATED_IN_CXX17 typedef void* pointer;
38 _LIBCPP_DEPRECATED_IN_CXX17 typedef const void* const_pointer;
39 _LIBCPP_DEPRECATED_IN_CXX17 typedef void value_type;
40
41 template <class _Up> struct _LIBCPP_DEPRECATED_IN_CXX17 rebind {typedef allocator<_Up> other;};
42};
43
44template <>
45class _LIBCPP_TEMPLATE_VIS allocator<const void>
46{
47public:
48 _LIBCPP_DEPRECATED_IN_CXX17 typedef const void* pointer;
49 _LIBCPP_DEPRECATED_IN_CXX17 typedef const void* const_pointer;
50 _LIBCPP_DEPRECATED_IN_CXX17 typedef const void value_type;
51
52 template <class _Up> struct _LIBCPP_DEPRECATED_IN_CXX17 rebind {typedef allocator<_Up> other;};
53};
54#endif
55
56// This class provides a non-trivial default constructor to the class that derives from it
57// if the condition is satisfied.
58//
59// The second template parameter exists to allow giving a unique type to __non_trivial_if,
60// which makes it possible to avoid breaking the ABI when making this a base class of an
61// existing class. Without that, imagine we have classes D1 and D2, both of which used to
62// have no base classes, but which now derive from __non_trivial_if. The layout of a class
63// that inherits from both D1 and D2 will change because the two __non_trivial_if base
64// classes are not allowed to share the same address.
65//
66// By making those __non_trivial_if base classes unique, we work around this problem and
67// it is safe to start deriving from __non_trivial_if in existing classes.
68template <bool _Cond, class _Unique>
69struct __non_trivial_if { };
70
71template <class _Unique>
72struct __non_trivial_if<true, _Unique> {
73 _LIBCPP_INLINE_VISIBILITY
74 _LIBCPP_CONSTEXPR __non_trivial_if() _NOEXCEPT { }
75};
76
77// allocator
78//
79// Note: For ABI compatibility between C++20 and previous standards, we make
80// allocator<void> trivial in C++20.
81
82template <class _Tp>
83class _LIBCPP_TEMPLATE_VIS allocator
84 : private __non_trivial_if<!is_void<_Tp>::value, allocator<_Tp> >
85{
86public:
87 typedef size_t size_type;
88 typedef ptrdiff_t difference_type;
89 typedef _Tp value_type;
90 typedef true_type propagate_on_container_move_assignment;
91 typedef true_type is_always_equal;
92
93 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
94 allocator() _NOEXCEPT _LIBCPP_DEFAULT
95
96 template <class _Up>
97 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
98 allocator(const allocator<_Up>&) _NOEXCEPT { }
99
100 _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
101 _Tp* allocate(size_t __n) {
102 if (__n > allocator_traits<allocator>::max_size(*this))
103 __throw_length_error("allocator<T>::allocate(size_t n)"
104 " 'n' exceeds maximum supported size");
105 if (__libcpp_is_constant_evaluated()) {
106 return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp)));
107 } else {
108 return static_cast<_Tp*>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)));
109 }
110 }
111
112 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
113 void deallocate(_Tp* __p, size_t __n) _NOEXCEPT {
114 if (__libcpp_is_constant_evaluated()) {
115 ::operator delete(__p);
116 } else {
117 _VSTD::__libcpp_deallocate((void*)__p, __n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp));
118 }
119 }
120
121 // C++20 Removed members
122#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS)
123 _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp* pointer;
124 _LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp* const_pointer;
125 _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp& reference;
126 _LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp& const_reference;
127
128 template <class _Up>
129 struct _LIBCPP_DEPRECATED_IN_CXX17 rebind {
130 typedef allocator<_Up> other;
131 };
132
133 _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY
134 pointer address(reference __x) const _NOEXCEPT {
135 return _VSTD::addressof(__x);
136 }
137 _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY
138 const_pointer address(const_reference __x) const _NOEXCEPT {
139 return _VSTD::addressof(__x);
140 }
141
142 _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_IN_CXX17
143 _Tp* allocate(size_t __n, const void*) {
144 return allocate(__n);
145 }
146
147 _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT {
148 return size_type(~0) / sizeof(_Tp);
149 }
150
151 template <class _Up, class... _Args>
152 _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY
153 void construct(_Up* __p, _Args&&... __args) {
154 ::new ((void*)__p) _Up(_VSTD::forward<_Args>(__args)...);
155 }
156
157 _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY
158 void destroy(pointer __p) {
159 __p->~_Tp();
160 }
161#endif
162};
163
164template <class _Tp>
165class _LIBCPP_TEMPLATE_VIS allocator<const _Tp>
166 : private __non_trivial_if<!is_void<_Tp>::value, allocator<const _Tp> >
167{
168public:
169 typedef size_t size_type;
170 typedef ptrdiff_t difference_type;
171 typedef const _Tp value_type;
172 typedef true_type propagate_on_container_move_assignment;
173 typedef true_type is_always_equal;
174
175 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
176 allocator() _NOEXCEPT _LIBCPP_DEFAULT
177
178 template <class _Up>
179 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
180 allocator(const allocator<_Up>&) _NOEXCEPT { }
181
182 _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
183 const _Tp* allocate(size_t __n) {
184 if (__n > allocator_traits<allocator>::max_size(*this))
185 __throw_length_error("allocator<const T>::allocate(size_t n)"
186 " 'n' exceeds maximum supported size");
187 if (__libcpp_is_constant_evaluated()) {
188 return static_cast<const _Tp*>(::operator new(__n * sizeof(_Tp)));
189 } else {
190 return static_cast<const _Tp*>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)));
191 }
192 }
193
194 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
195 void deallocate(const _Tp* __p, size_t __n) {
196 if (__libcpp_is_constant_evaluated()) {
197 ::operator delete(const_cast<_Tp*>(__p));
198 } else {
199 _VSTD::__libcpp_deallocate((void*) const_cast<_Tp *>(__p), __n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp));
200 }
201 }
202
203 // C++20 Removed members
204#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS)
205 _LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp* pointer;
206 _LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp* const_pointer;
207 _LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp& reference;
208 _LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp& const_reference;
209
210 template <class _Up>
211 struct _LIBCPP_DEPRECATED_IN_CXX17 rebind {
212 typedef allocator<_Up> other;
213 };
214
215 _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY
216 const_pointer address(const_reference __x) const _NOEXCEPT {
217 return _VSTD::addressof(__x);
218 }
219
220 _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_IN_CXX17
221 const _Tp* allocate(size_t __n, const void*) {
222 return allocate(__n);
223 }
224
225 _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT {
226 return size_type(~0) / sizeof(_Tp);
227 }
228
229 template <class _Up, class... _Args>
230 _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY
231 void construct(_Up* __p, _Args&&... __args) {
232 ::new ((void*)__p) _Up(_VSTD::forward<_Args>(__args)...);
233 }
234
235 _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY
236 void destroy(pointer __p) {
237 __p->~_Tp();
238 }
239#endif
240};
241
242template <class _Tp, class _Up>
243inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
244bool operator==(const allocator<_Tp>&, const allocator<_Up>&) _NOEXCEPT {return true;}
245
246template <class _Tp, class _Up>
247inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
248bool operator!=(const allocator<_Tp>&, const allocator<_Up>&) _NOEXCEPT {return false;}
249
250_LIBCPP_END_NAMESPACE_STD
251
252_LIBCPP_POP_MACROS
253
254#endif // _LIBCPP___MEMORY_ALLOCATOR_H
lib/libcxx/include/__memory/allocator_arg_t.h created+78
......@@ -0,0 +1,78 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___FUNCTIONAL___ALLOCATOR_ARG_T_H
11#define _LIBCPP___FUNCTIONAL___ALLOCATOR_ARG_T_H
12
13#include <__config>
14#include <__memory/uses_allocator.h>
15#include <__utility/forward.h>
16#include <type_traits>
17
18#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
19#pragma GCC system_header
20#endif
21
22_LIBCPP_BEGIN_NAMESPACE_STD
23
24struct _LIBCPP_TEMPLATE_VIS allocator_arg_t { explicit allocator_arg_t() = default; };
25
26#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY)
27extern _LIBCPP_EXPORTED_FROM_ABI const allocator_arg_t allocator_arg;
28#else
29/* _LIBCPP_INLINE_VAR */ constexpr allocator_arg_t allocator_arg = allocator_arg_t();
30#endif
31
32#ifndef _LIBCPP_CXX03_LANG
33
34// allocator construction
35
36template <class _Tp, class _Alloc, class ..._Args>
37struct __uses_alloc_ctor_imp
38{
39 typedef _LIBCPP_NODEBUG_TYPE typename __uncvref<_Alloc>::type _RawAlloc;
40 static const bool __ua = uses_allocator<_Tp, _RawAlloc>::value;
41 static const bool __ic =
42 is_constructible<_Tp, allocator_arg_t, _Alloc, _Args...>::value;
43 static const int value = __ua ? 2 - __ic : 0;
44};
45
46template <class _Tp, class _Alloc, class ..._Args>
47struct __uses_alloc_ctor
48 : integral_constant<int, __uses_alloc_ctor_imp<_Tp, _Alloc, _Args...>::value>
49 {};
50
51template <class _Tp, class _Allocator, class... _Args>
52inline _LIBCPP_INLINE_VISIBILITY
53void __user_alloc_construct_impl (integral_constant<int, 0>, _Tp *__storage, const _Allocator &, _Args &&... __args )
54{
55 new (__storage) _Tp (_VSTD::forward<_Args>(__args)...);
56}
57
58// FIXME: This should have a version which takes a non-const alloc.
59template <class _Tp, class _Allocator, class... _Args>
60inline _LIBCPP_INLINE_VISIBILITY
61void __user_alloc_construct_impl (integral_constant<int, 1>, _Tp *__storage, const _Allocator &__a, _Args &&... __args )
62{
63 new (__storage) _Tp (allocator_arg, __a, _VSTD::forward<_Args>(__args)...);
64}
65
66// FIXME: This should have a version which takes a non-const alloc.
67template <class _Tp, class _Allocator, class... _Args>
68inline _LIBCPP_INLINE_VISIBILITY
69void __user_alloc_construct_impl (integral_constant<int, 2>, _Tp *__storage, const _Allocator &__a, _Args &&... __args )
70{
71 new (__storage) _Tp (_VSTD::forward<_Args>(__args)..., __a);
72}
73
74#endif // _LIBCPP_CXX03_LANG
75
76_LIBCPP_END_NAMESPACE_STD
77
78#endif // _LIBCPP___FUNCTIONAL___ALLOCATOR_ARG_T_H
lib/libcxx/include/__memory/allocator_traits.h+8-4
......@@ -11,8 +11,10 @@
1111#define _LIBCPP___MEMORY_ALLOCATOR_TRAITS_H
1212
1313#include <__config>
14#include <__memory/base.h>
14#include <__memory/construct_at.h>
1515#include <__memory/pointer_traits.h>
16#include <__utility/forward.h>
17#include <limits>
1618#include <type_traits>
1719
1820#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
......@@ -253,7 +255,7 @@ struct _LIBCPP_TEMPLATE_VIS allocator_traits
253255 struct rebind_traits {
254256 using other = allocator_traits<typename rebind_alloc<_Tp>::other>;
255257 };
256#endif // _LIBCPP_CXX03_LANG
258#endif // _LIBCPP_CXX03_LANG
257259
258260 _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
259261 static pointer allocate(allocator_type& __a, size_type __n) {
......@@ -360,8 +362,10 @@ struct __rebind_alloc_helper {
360362template <class _Tp>
361363struct __is_default_allocator : false_type { };
362364
365template <class> class allocator;
366
363367template <class _Tp>
364struct __is_default_allocator<_VSTD::allocator<_Tp> > : true_type { };
368struct __is_default_allocator<allocator<_Tp> > : true_type { };
365369
366370// __is_cpp17_move_insertable
367371template <class _Alloc, class = void>
......@@ -398,4 +402,4 @@ _LIBCPP_END_NAMESPACE_STD
398402
399403_LIBCPP_POP_MACROS
400404
401#endif // _LIBCPP___MEMORY_ALLOCATOR_TRAITS_H
405#endif // _LIBCPP___MEMORY_ALLOCATOR_TRAITS_H
lib/libcxx/include/__memory/auto_ptr.h created+86
......@@ -0,0 +1,86 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___MEMORY_AUTO_PTR_H
11#define _LIBCPP___MEMORY_AUTO_PTR_H
12
13#include <__config>
14#include <__nullptr>
15
16#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
17#pragma GCC system_header
18#endif
19
20_LIBCPP_PUSH_MACROS
21#include <__undef_macros>
22
23_LIBCPP_BEGIN_NAMESPACE_STD
24
25template <class _Tp>
26struct _LIBCPP_DEPRECATED_IN_CXX11 auto_ptr_ref
27{
28 _Tp* __ptr_;
29};
30
31template<class _Tp>
32class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 auto_ptr
33{
34private:
35 _Tp* __ptr_;
36public:
37 typedef _Tp element_type;
38
39 _LIBCPP_INLINE_VISIBILITY explicit auto_ptr(_Tp* __p = 0) _NOEXCEPT : __ptr_(__p) {}
40 _LIBCPP_INLINE_VISIBILITY auto_ptr(auto_ptr& __p) _NOEXCEPT : __ptr_(__p.release()) {}
41 template<class _Up> _LIBCPP_INLINE_VISIBILITY auto_ptr(auto_ptr<_Up>& __p) _NOEXCEPT
42 : __ptr_(__p.release()) {}
43 _LIBCPP_INLINE_VISIBILITY auto_ptr& operator=(auto_ptr& __p) _NOEXCEPT
44 {reset(__p.release()); return *this;}
45 template<class _Up> _LIBCPP_INLINE_VISIBILITY auto_ptr& operator=(auto_ptr<_Up>& __p) _NOEXCEPT
46 {reset(__p.release()); return *this;}
47 _LIBCPP_INLINE_VISIBILITY auto_ptr& operator=(auto_ptr_ref<_Tp> __p) _NOEXCEPT
48 {reset(__p.__ptr_); return *this;}
49 _LIBCPP_INLINE_VISIBILITY ~auto_ptr() _NOEXCEPT {delete __ptr_;}
50
51 _LIBCPP_INLINE_VISIBILITY _Tp& operator*() const _NOEXCEPT
52 {return *__ptr_;}
53 _LIBCPP_INLINE_VISIBILITY _Tp* operator->() const _NOEXCEPT {return __ptr_;}
54 _LIBCPP_INLINE_VISIBILITY _Tp* get() const _NOEXCEPT {return __ptr_;}
55 _LIBCPP_INLINE_VISIBILITY _Tp* release() _NOEXCEPT
56 {
57 _Tp* __t = __ptr_;
58 __ptr_ = nullptr;
59 return __t;
60 }
61 _LIBCPP_INLINE_VISIBILITY void reset(_Tp* __p = 0) _NOEXCEPT
62 {
63 if (__ptr_ != __p)
64 delete __ptr_;
65 __ptr_ = __p;
66 }
67
68 _LIBCPP_INLINE_VISIBILITY auto_ptr(auto_ptr_ref<_Tp> __p) _NOEXCEPT : __ptr_(__p.__ptr_) {}
69 template<class _Up> _LIBCPP_INLINE_VISIBILITY operator auto_ptr_ref<_Up>() _NOEXCEPT
70 {auto_ptr_ref<_Up> __t; __t.__ptr_ = release(); return __t;}
71 template<class _Up> _LIBCPP_INLINE_VISIBILITY operator auto_ptr<_Up>() _NOEXCEPT
72 {return auto_ptr<_Up>(release());}
73};
74
75template <>
76class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 auto_ptr<void>
77{
78public:
79 typedef void element_type;
80};
81
82_LIBCPP_END_NAMESPACE_STD
83
84_LIBCPP_POP_MACROS
85
86#endif // _LIBCPP___MEMORY_AUTO_PTR_H
lib/libcxx/include/__memory/base.h deleted-127
......@@ -1,127 +0,0 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___MEMORY_BASE_H
11#define _LIBCPP___MEMORY_BASE_H
12
13#include <__config>
14#include <__debug>
15#include <type_traits>
16
17#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
18#pragma GCC system_header
19#endif
20
21_LIBCPP_PUSH_MACROS
22#include <__undef_macros>
23
24_LIBCPP_BEGIN_NAMESPACE_STD
25
26// addressof
27#ifndef _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF
28
29template <class _Tp>
30inline _LIBCPP_CONSTEXPR_AFTER_CXX14
31_LIBCPP_NO_CFI _LIBCPP_INLINE_VISIBILITY
32_Tp*
33addressof(_Tp& __x) _NOEXCEPT
34{
35 return __builtin_addressof(__x);
36}
37
38#else
39
40template <class _Tp>
41inline _LIBCPP_NO_CFI _LIBCPP_INLINE_VISIBILITY
42_Tp*
43addressof(_Tp& __x) _NOEXCEPT
44{
45 return reinterpret_cast<_Tp *>(
46 const_cast<char *>(&reinterpret_cast<const volatile char &>(__x)));
47}
48
49#endif // _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF
50
51#if defined(_LIBCPP_HAS_OBJC_ARC) && !defined(_LIBCPP_PREDEFINED_OBJC_ARC_ADDRESSOF)
52// Objective-C++ Automatic Reference Counting uses qualified pointers
53// that require special addressof() signatures. When
54// _LIBCPP_PREDEFINED_OBJC_ARC_ADDRESSOF is defined, the compiler
55// itself is providing these definitions. Otherwise, we provide them.
56template <class _Tp>
57inline _LIBCPP_INLINE_VISIBILITY
58__strong _Tp*
59addressof(__strong _Tp& __x) _NOEXCEPT
60{
61 return &__x;
62}
63
64#ifdef _LIBCPP_HAS_OBJC_ARC_WEAK
65template <class _Tp>
66inline _LIBCPP_INLINE_VISIBILITY
67__weak _Tp*
68addressof(__weak _Tp& __x) _NOEXCEPT
69{
70 return &__x;
71}
72#endif
73
74template <class _Tp>
75inline _LIBCPP_INLINE_VISIBILITY
76__autoreleasing _Tp*
77addressof(__autoreleasing _Tp& __x) _NOEXCEPT
78{
79 return &__x;
80}
81
82template <class _Tp>
83inline _LIBCPP_INLINE_VISIBILITY
84__unsafe_unretained _Tp*
85addressof(__unsafe_unretained _Tp& __x) _NOEXCEPT
86{
87 return &__x;
88}
89#endif
90
91#if !defined(_LIBCPP_CXX03_LANG)
92template <class _Tp> _Tp* addressof(const _Tp&&) noexcept = delete;
93#endif
94
95// construct_at
96
97#if _LIBCPP_STD_VER > 17
98
99template<class _Tp, class ..._Args, class = decltype(
100 ::new (_VSTD::declval<void*>()) _Tp(_VSTD::declval<_Args>()...)
101)>
102_LIBCPP_INLINE_VISIBILITY
103constexpr _Tp* construct_at(_Tp* __location, _Args&& ...__args) {
104 _LIBCPP_ASSERT(__location, "null pointer given to construct_at");
105 return ::new ((void*)__location) _Tp(_VSTD::forward<_Args>(__args)...);
106}
107
108#endif
109
110// destroy_at
111
112#if _LIBCPP_STD_VER > 14
113
114template <class _Tp>
115inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
116void destroy_at(_Tp* __loc) {
117 _LIBCPP_ASSERT(__loc, "null pointer given to destroy_at");
118 __loc->~_Tp();
119}
120
121#endif
122
123_LIBCPP_END_NAMESPACE_STD
124
125_LIBCPP_POP_MACROS
126
127#endif // _LIBCPP___MEMORY_BASE_H
lib/libcxx/include/__memory/compressed_pair.h created+201
......@@ -0,0 +1,201 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___MEMORY_COMPRESSED_PAIR_H
11#define _LIBCPP___MEMORY_COMPRESSED_PAIR_H
12
13#include <__config>
14#include <__utility/forward.h>
15#include <tuple> // needed in c++03 for some constructors
16#include <type_traits>
17#include <utility>
18
19#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
20#pragma GCC system_header
21#endif
22
23_LIBCPP_PUSH_MACROS
24#include <__undef_macros>
25
26_LIBCPP_BEGIN_NAMESPACE_STD
27
28// Tag used to default initialize one or both of the pair's elements.
29struct __default_init_tag {};
30struct __value_init_tag {};
31
32template <class _Tp, int _Idx,
33 bool _CanBeEmptyBase =
34 is_empty<_Tp>::value && !__libcpp_is_final<_Tp>::value>
35struct __compressed_pair_elem {
36 typedef _Tp _ParamT;
37 typedef _Tp& reference;
38 typedef const _Tp& const_reference;
39
40 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
41 __compressed_pair_elem(__default_init_tag) {}
42 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
43 __compressed_pair_elem(__value_init_tag) : __value_() {}
44
45 template <class _Up, class = typename enable_if<
46 !is_same<__compressed_pair_elem, typename decay<_Up>::type>::value
47 >::type>
48 _LIBCPP_INLINE_VISIBILITY
49 _LIBCPP_CONSTEXPR explicit
50 __compressed_pair_elem(_Up&& __u)
51 : __value_(_VSTD::forward<_Up>(__u))
52 {
53 }
54
55
56#ifndef _LIBCPP_CXX03_LANG
57 template <class... _Args, size_t... _Indexes>
58 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
59 __compressed_pair_elem(piecewise_construct_t, tuple<_Args...> __args,
60 __tuple_indices<_Indexes...>)
61 : __value_(_VSTD::forward<_Args>(_VSTD::get<_Indexes>(__args))...) {}
62#endif
63
64
65 _LIBCPP_INLINE_VISIBILITY reference __get() _NOEXCEPT { return __value_; }
66 _LIBCPP_INLINE_VISIBILITY
67 const_reference __get() const _NOEXCEPT { return __value_; }
68
69private:
70 _Tp __value_;
71};
72
73template <class _Tp, int _Idx>
74struct __compressed_pair_elem<_Tp, _Idx, true> : private _Tp {
75 typedef _Tp _ParamT;
76 typedef _Tp& reference;
77 typedef const _Tp& const_reference;
78 typedef _Tp __value_type;
79
80 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR __compressed_pair_elem() = default;
81 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
82 __compressed_pair_elem(__default_init_tag) {}
83 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
84 __compressed_pair_elem(__value_init_tag) : __value_type() {}
85
86 template <class _Up, class = typename enable_if<
87 !is_same<__compressed_pair_elem, typename decay<_Up>::type>::value
88 >::type>
89 _LIBCPP_INLINE_VISIBILITY
90 _LIBCPP_CONSTEXPR explicit
91 __compressed_pair_elem(_Up&& __u)
92 : __value_type(_VSTD::forward<_Up>(__u))
93 {}
94
95#ifndef _LIBCPP_CXX03_LANG
96 template <class... _Args, size_t... _Indexes>
97 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
98 __compressed_pair_elem(piecewise_construct_t, tuple<_Args...> __args,
99 __tuple_indices<_Indexes...>)
100 : __value_type(_VSTD::forward<_Args>(_VSTD::get<_Indexes>(__args))...) {}
101#endif
102
103 _LIBCPP_INLINE_VISIBILITY reference __get() _NOEXCEPT { return *this; }
104 _LIBCPP_INLINE_VISIBILITY
105 const_reference __get() const _NOEXCEPT { return *this; }
106};
107
108template <class _T1, class _T2>
109class __compressed_pair : private __compressed_pair_elem<_T1, 0>,
110 private __compressed_pair_elem<_T2, 1> {
111public:
112 // NOTE: This static assert should never fire because __compressed_pair
113 // is *almost never* used in a scenario where it's possible for T1 == T2.
114 // (The exception is std::function where it is possible that the function
115 // object and the allocator have the same type).
116 static_assert((!is_same<_T1, _T2>::value),
117 "__compressed_pair cannot be instantiated when T1 and T2 are the same type; "
118 "The current implementation is NOT ABI-compatible with the previous "
119 "implementation for this configuration");
120
121 typedef _LIBCPP_NODEBUG_TYPE __compressed_pair_elem<_T1, 0> _Base1;
122 typedef _LIBCPP_NODEBUG_TYPE __compressed_pair_elem<_T2, 1> _Base2;
123
124 template <bool _Dummy = true,
125 class = typename enable_if<
126 __dependent_type<is_default_constructible<_T1>, _Dummy>::value &&
127 __dependent_type<is_default_constructible<_T2>, _Dummy>::value
128 >::type
129 >
130 _LIBCPP_INLINE_VISIBILITY
131 _LIBCPP_CONSTEXPR __compressed_pair() : _Base1(__value_init_tag()), _Base2(__value_init_tag()) {}
132
133 template <class _U1, class _U2>
134 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
135 __compressed_pair(_U1&& __t1, _U2&& __t2)
136 : _Base1(_VSTD::forward<_U1>(__t1)), _Base2(_VSTD::forward<_U2>(__t2)) {}
137
138#ifndef _LIBCPP_CXX03_LANG
139 template <class... _Args1, class... _Args2>
140 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
141 __compressed_pair(piecewise_construct_t __pc, tuple<_Args1...> __first_args,
142 tuple<_Args2...> __second_args)
143 : _Base1(__pc, _VSTD::move(__first_args),
144 typename __make_tuple_indices<sizeof...(_Args1)>::type()),
145 _Base2(__pc, _VSTD::move(__second_args),
146 typename __make_tuple_indices<sizeof...(_Args2)>::type()) {}
147#endif
148
149 _LIBCPP_INLINE_VISIBILITY
150 typename _Base1::reference first() _NOEXCEPT {
151 return static_cast<_Base1&>(*this).__get();
152 }
153
154 _LIBCPP_INLINE_VISIBILITY
155 typename _Base1::const_reference first() const _NOEXCEPT {
156 return static_cast<_Base1 const&>(*this).__get();
157 }
158
159 _LIBCPP_INLINE_VISIBILITY
160 typename _Base2::reference second() _NOEXCEPT {
161 return static_cast<_Base2&>(*this).__get();
162 }
163
164 _LIBCPP_INLINE_VISIBILITY
165 typename _Base2::const_reference second() const _NOEXCEPT {
166 return static_cast<_Base2 const&>(*this).__get();
167 }
168
169 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
170 static _Base1* __get_first_base(__compressed_pair* __pair) _NOEXCEPT {
171 return static_cast<_Base1*>(__pair);
172 }
173 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
174 static _Base2* __get_second_base(__compressed_pair* __pair) _NOEXCEPT {
175 return static_cast<_Base2*>(__pair);
176 }
177
178 _LIBCPP_INLINE_VISIBILITY
179 void swap(__compressed_pair& __x)
180 _NOEXCEPT_(__is_nothrow_swappable<_T1>::value &&
181 __is_nothrow_swappable<_T2>::value)
182 {
183 using _VSTD::swap;
184 swap(first(), __x.first());
185 swap(second(), __x.second());
186 }
187};
188
189template <class _T1, class _T2>
190inline _LIBCPP_INLINE_VISIBILITY
191void swap(__compressed_pair<_T1, _T2>& __x, __compressed_pair<_T1, _T2>& __y)
192 _NOEXCEPT_(__is_nothrow_swappable<_T1>::value &&
193 __is_nothrow_swappable<_T2>::value) {
194 __x.swap(__y);
195}
196
197_LIBCPP_END_NAMESPACE_STD
198
199_LIBCPP_POP_MACROS
200
201#endif // _LIBCPP___MEMORY_COMPRESSED_PAIR_H
lib/libcxx/include/__memory/construct_at.h created+59
......@@ -0,0 +1,59 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___MEMORY_CONSTRUCT_AT_H
11#define _LIBCPP___MEMORY_CONSTRUCT_AT_H
12
13#include <__config>
14#include <__debug>
15#include <__utility/forward.h>
16#include <utility>
17
18#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
19#pragma GCC system_header
20#endif
21
22_LIBCPP_PUSH_MACROS
23#include <__undef_macros>
24
25_LIBCPP_BEGIN_NAMESPACE_STD
26
27// construct_at
28
29#if _LIBCPP_STD_VER > 17
30
31template<class _Tp, class ..._Args, class = decltype(
32 ::new (declval<void*>()) _Tp(declval<_Args>()...)
33)>
34_LIBCPP_INLINE_VISIBILITY
35constexpr _Tp* construct_at(_Tp* __location, _Args&& ...__args) {
36 _LIBCPP_ASSERT(__location, "null pointer given to construct_at");
37 return ::new ((void*)__location) _Tp(_VSTD::forward<_Args>(__args)...);
38}
39
40#endif
41
42// destroy_at
43
44#if _LIBCPP_STD_VER > 14
45
46template <class _Tp>
47inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
48void destroy_at(_Tp* __loc) {
49 _LIBCPP_ASSERT(__loc, "null pointer given to destroy_at");
50 __loc->~_Tp();
51}
52
53#endif
54
55_LIBCPP_END_NAMESPACE_STD
56
57_LIBCPP_POP_MACROS
58
59#endif // _LIBCPP___MEMORY_CONSTRUCT_AT_H
lib/libcxx/include/__memory/pointer_safety.h created+57
......@@ -0,0 +1,57 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___MEMORY_POINTER_SAFETY_H
11#define _LIBCPP___MEMORY_POINTER_SAFETY_H
12
13#include <__config>
14#include <cstddef>
15
16#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
17#pragma GCC system_header
18#endif
19
20_LIBCPP_PUSH_MACROS
21#include <__undef_macros>
22
23_LIBCPP_BEGIN_NAMESPACE_STD
24
25#if !defined(_LIBCPP_CXX03_LANG)
26
27enum class pointer_safety : unsigned char {
28 relaxed,
29 preferred,
30 strict
31};
32
33inline _LIBCPP_INLINE_VISIBILITY
34pointer_safety get_pointer_safety() _NOEXCEPT {
35 return pointer_safety::relaxed;
36}
37
38_LIBCPP_FUNC_VIS void declare_reachable(void* __p);
39_LIBCPP_FUNC_VIS void declare_no_pointers(char* __p, size_t __n);
40_LIBCPP_FUNC_VIS void undeclare_no_pointers(char* __p, size_t __n);
41_LIBCPP_FUNC_VIS void* __undeclare_reachable(void* __p);
42
43template <class _Tp>
44inline _LIBCPP_INLINE_VISIBILITY
45_Tp*
46undeclare_reachable(_Tp* __p)
47{
48 return static_cast<_Tp*>(__undeclare_reachable(__p));
49}
50
51#endif // !C++03
52
53_LIBCPP_END_NAMESPACE_STD
54
55_LIBCPP_POP_MACROS
56
57#endif // _LIBCPP___MEMORY_POINTER_SAFETY_H
lib/libcxx/include/__memory/pointer_traits.h+49-2
......@@ -11,6 +11,7 @@
1111#define _LIBCPP___MEMORY_POINTER_TRAITS_H
1212
1313#include <__config>
14#include <__memory/addressof.h>
1415#include <type_traits>
1516
1617#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
......@@ -120,7 +121,7 @@ struct _LIBCPP_TEMPLATE_VIS pointer_traits
120121#else
121122 template <class _Up> struct rebind
122123 {typedef typename __pointer_traits_rebind<pointer, _Up>::type other;};
123#endif // _LIBCPP_CXX03_LANG
124#endif // _LIBCPP_CXX03_LANG
124125
125126private:
126127 struct __nat {};
......@@ -162,8 +163,54 @@ struct __rebind_pointer {
162163#endif
163164};
164165
166// to_address
167
168template <class _Pointer, class = void>
169struct __to_address_helper;
170
171template <class _Tp>
172_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
173_Tp* __to_address(_Tp* __p) _NOEXCEPT {
174 static_assert(!is_function<_Tp>::value, "_Tp is a function type");
175 return __p;
176}
177
178// enable_if is needed here to avoid instantiating checks for fancy pointers on raw pointers
179template <class _Pointer, class = _EnableIf<!is_pointer<_Pointer>::value> >
180_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
181typename decay<decltype(__to_address_helper<_Pointer>::__call(declval<const _Pointer&>()))>::type
182__to_address(const _Pointer& __p) _NOEXCEPT {
183 return __to_address_helper<_Pointer>::__call(__p);
184}
185
186template <class _Pointer, class>
187struct __to_address_helper {
188 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
189 static decltype(_VSTD::__to_address(declval<const _Pointer&>().operator->()))
190 __call(const _Pointer&__p) _NOEXCEPT {
191 return _VSTD::__to_address(__p.operator->());
192 }
193};
194
195template <class _Pointer>
196struct __to_address_helper<_Pointer, decltype((void)pointer_traits<_Pointer>::to_address(declval<const _Pointer&>()))> {
197 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
198 static decltype(pointer_traits<_Pointer>::to_address(declval<const _Pointer&>()))
199 __call(const _Pointer&__p) _NOEXCEPT {
200 return pointer_traits<_Pointer>::to_address(__p);
201 }
202};
203
204#if _LIBCPP_STD_VER > 17
205template <class _Pointer>
206inline _LIBCPP_INLINE_VISIBILITY constexpr
207auto to_address(const _Pointer& __p) noexcept {
208 return _VSTD::__to_address(__p);
209}
210#endif
211
165212_LIBCPP_END_NAMESPACE_STD
166213
167214_LIBCPP_POP_MACROS
168215
169#endif // _LIBCPP___MEMORY_POINTER_TRAITS_H
216#endif // _LIBCPP___MEMORY_POINTER_TRAITS_H
lib/libcxx/include/__memory/raw_storage_iterator.h created+73
......@@ -0,0 +1,73 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___MEMORY_RAW_STORAGE_ITERATOR_H
11#define _LIBCPP___MEMORY_RAW_STORAGE_ITERATOR_H
12
13#include <__config>
14#include <__memory/addressof.h>
15#include <cstddef>
16#include <iterator>
17#include <utility>
18
19#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
20#pragma GCC system_header
21#endif
22
23_LIBCPP_PUSH_MACROS
24#include <__undef_macros>
25
26_LIBCPP_BEGIN_NAMESPACE_STD
27
28#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_RAW_STORAGE_ITERATOR)
29
30_LIBCPP_SUPPRESS_DEPRECATED_PUSH
31template <class _OutputIterator, class _Tp>
32class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 raw_storage_iterator
33#if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES)
34 : public iterator<output_iterator_tag, void, void, void, void>
35#endif
36{
37_LIBCPP_SUPPRESS_DEPRECATED_POP
38private:
39 _OutputIterator __x_;
40public:
41 typedef output_iterator_tag iterator_category;
42 typedef void value_type;
43#if _LIBCPP_STD_VER > 17
44 typedef ptrdiff_t difference_type;
45#else
46 typedef void difference_type;
47#endif
48 typedef void pointer;
49 typedef void reference;
50
51 _LIBCPP_INLINE_VISIBILITY explicit raw_storage_iterator(_OutputIterator __x) : __x_(__x) {}
52 _LIBCPP_INLINE_VISIBILITY raw_storage_iterator& operator*() {return *this;}
53 _LIBCPP_INLINE_VISIBILITY raw_storage_iterator& operator=(const _Tp& __element)
54 {::new ((void*)_VSTD::addressof(*__x_)) _Tp(__element); return *this;}
55#if _LIBCPP_STD_VER >= 14
56 _LIBCPP_INLINE_VISIBILITY raw_storage_iterator& operator=(_Tp&& __element)
57 {::new ((void*)_VSTD::addressof(*__x_)) _Tp(_VSTD::move(__element)); return *this;}
58#endif
59 _LIBCPP_INLINE_VISIBILITY raw_storage_iterator& operator++() {++__x_; return *this;}
60 _LIBCPP_INLINE_VISIBILITY raw_storage_iterator operator++(int)
61 {raw_storage_iterator __t(*this); ++__x_; return __t;}
62#if _LIBCPP_STD_VER >= 14
63 _LIBCPP_INLINE_VISIBILITY _OutputIterator base() const { return __x_; }
64#endif
65};
66
67#endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_RAW_STORAGE_ITERATOR)
68
69_LIBCPP_END_NAMESPACE_STD
70
71_LIBCPP_POP_MACROS
72
73#endif // _LIBCPP___MEMORY_RAW_STORAGE_ITERATOR_H
lib/libcxx/include/__memory/shared_ptr.h created+1879
......@@ -0,0 +1,1879 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___MEMORY_SHARED_PTR_H
11#define _LIBCPP___MEMORY_SHARED_PTR_H
12
13#include <__availability>
14#include <__config>
15#include <__functional_base>
16#include <__functional/binary_function.h>
17#include <__functional/operations.h>
18#include <__functional/reference_wrapper.h>
19#include <__memory/addressof.h>
20#include <__memory/allocation_guard.h>
21#include <__memory/allocator_traits.h>
22#include <__memory/allocator.h>
23#include <__memory/compressed_pair.h>
24#include <__memory/pointer_traits.h>
25#include <__memory/unique_ptr.h>
26#include <__utility/forward.h>
27#include <cstddef>
28#include <cstdlib> // abort
29#include <iosfwd>
30#include <stdexcept>
31#include <typeinfo>
32#include <type_traits>
33#include <utility>
34#if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER)
35# include <atomic>
36#endif
37
38#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
39# include <__memory/auto_ptr.h>
40#endif
41
42#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
43#pragma GCC system_header
44#endif
45
46_LIBCPP_PUSH_MACROS
47#include <__undef_macros>
48
49_LIBCPP_BEGIN_NAMESPACE_STD
50
51template <class _Alloc>
52class __allocator_destructor
53{
54 typedef _LIBCPP_NODEBUG_TYPE allocator_traits<_Alloc> __alloc_traits;
55public:
56 typedef _LIBCPP_NODEBUG_TYPE typename __alloc_traits::pointer pointer;
57 typedef _LIBCPP_NODEBUG_TYPE typename __alloc_traits::size_type size_type;
58private:
59 _Alloc& __alloc_;
60 size_type __s_;
61public:
62 _LIBCPP_INLINE_VISIBILITY __allocator_destructor(_Alloc& __a, size_type __s)
63 _NOEXCEPT
64 : __alloc_(__a), __s_(__s) {}
65 _LIBCPP_INLINE_VISIBILITY
66 void operator()(pointer __p) _NOEXCEPT
67 {__alloc_traits::deallocate(__alloc_, __p, __s_);}
68};
69
70// NOTE: Relaxed and acq/rel atomics (for increment and decrement respectively)
71// should be sufficient for thread safety.
72// See https://llvm.org/PR22803
73#if defined(__clang__) && __has_builtin(__atomic_add_fetch) \
74 && defined(__ATOMIC_RELAXED) \
75 && defined(__ATOMIC_ACQ_REL)
76# define _LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT
77#elif defined(_LIBCPP_COMPILER_GCC)
78# define _LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT
79#endif
80
81template <class _ValueType>
82inline _LIBCPP_INLINE_VISIBILITY
83_ValueType __libcpp_relaxed_load(_ValueType const* __value) {
84#if !defined(_LIBCPP_HAS_NO_THREADS) && \
85 defined(__ATOMIC_RELAXED) && \
86 (__has_builtin(__atomic_load_n) || defined(_LIBCPP_COMPILER_GCC))
87 return __atomic_load_n(__value, __ATOMIC_RELAXED);
88#else
89 return *__value;
90#endif
91}
92
93template <class _ValueType>
94inline _LIBCPP_INLINE_VISIBILITY
95_ValueType __libcpp_acquire_load(_ValueType const* __value) {
96#if !defined(_LIBCPP_HAS_NO_THREADS) && \
97 defined(__ATOMIC_ACQUIRE) && \
98 (__has_builtin(__atomic_load_n) || defined(_LIBCPP_COMPILER_GCC))
99 return __atomic_load_n(__value, __ATOMIC_ACQUIRE);
100#else
101 return *__value;
102#endif
103}
104
105template <class _Tp>
106inline _LIBCPP_INLINE_VISIBILITY _Tp
107__libcpp_atomic_refcount_increment(_Tp& __t) _NOEXCEPT
108{
109#if defined(_LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT) && !defined(_LIBCPP_HAS_NO_THREADS)
110 return __atomic_add_fetch(&__t, 1, __ATOMIC_RELAXED);
111#else
112 return __t += 1;
113#endif
114}
115
116template <class _Tp>
117inline _LIBCPP_INLINE_VISIBILITY _Tp
118__libcpp_atomic_refcount_decrement(_Tp& __t) _NOEXCEPT
119{
120#if defined(_LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT) && !defined(_LIBCPP_HAS_NO_THREADS)
121 return __atomic_add_fetch(&__t, -1, __ATOMIC_ACQ_REL);
122#else
123 return __t -= 1;
124#endif
125}
126
127class _LIBCPP_EXCEPTION_ABI bad_weak_ptr
128 : public std::exception
129{
130public:
131 bad_weak_ptr() _NOEXCEPT = default;
132 bad_weak_ptr(const bad_weak_ptr&) _NOEXCEPT = default;
133 virtual ~bad_weak_ptr() _NOEXCEPT;
134 virtual const char* what() const _NOEXCEPT;
135};
136
137_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
138void __throw_bad_weak_ptr()
139{
140#ifndef _LIBCPP_NO_EXCEPTIONS
141 throw bad_weak_ptr();
142#else
143 _VSTD::abort();
144#endif
145}
146
147template<class _Tp> class _LIBCPP_TEMPLATE_VIS weak_ptr;
148
149class _LIBCPP_TYPE_VIS __shared_count
150{
151 __shared_count(const __shared_count&);
152 __shared_count& operator=(const __shared_count&);
153
154protected:
155 long __shared_owners_;
156 virtual ~__shared_count();
157private:
158 virtual void __on_zero_shared() _NOEXCEPT = 0;
159
160public:
161 _LIBCPP_INLINE_VISIBILITY
162 explicit __shared_count(long __refs = 0) _NOEXCEPT
163 : __shared_owners_(__refs) {}
164
165#if defined(_LIBCPP_BUILDING_LIBRARY) && \
166 defined(_LIBCPP_DEPRECATED_ABI_LEGACY_LIBRARY_DEFINITIONS_FOR_INLINE_FUNCTIONS)
167 void __add_shared() _NOEXCEPT;
168 bool __release_shared() _NOEXCEPT;
169#else
170 _LIBCPP_INLINE_VISIBILITY
171 void __add_shared() _NOEXCEPT {
172 __libcpp_atomic_refcount_increment(__shared_owners_);
173 }
174 _LIBCPP_INLINE_VISIBILITY
175 bool __release_shared() _NOEXCEPT {
176 if (__libcpp_atomic_refcount_decrement(__shared_owners_) == -1) {
177 __on_zero_shared();
178 return true;
179 }
180 return false;
181 }
182#endif
183 _LIBCPP_INLINE_VISIBILITY
184 long use_count() const _NOEXCEPT {
185 return __libcpp_relaxed_load(&__shared_owners_) + 1;
186 }
187};
188
189class _LIBCPP_TYPE_VIS __shared_weak_count
190 : private __shared_count
191{
192 long __shared_weak_owners_;
193
194public:
195 _LIBCPP_INLINE_VISIBILITY
196 explicit __shared_weak_count(long __refs = 0) _NOEXCEPT
197 : __shared_count(__refs),
198 __shared_weak_owners_(__refs) {}
199protected:
200 virtual ~__shared_weak_count();
201
202public:
203#if defined(_LIBCPP_BUILDING_LIBRARY) && \
204 defined(_LIBCPP_DEPRECATED_ABI_LEGACY_LIBRARY_DEFINITIONS_FOR_INLINE_FUNCTIONS)
205 void __add_shared() _NOEXCEPT;
206 void __add_weak() _NOEXCEPT;
207 void __release_shared() _NOEXCEPT;
208#else
209 _LIBCPP_INLINE_VISIBILITY
210 void __add_shared() _NOEXCEPT {
211 __shared_count::__add_shared();
212 }
213 _LIBCPP_INLINE_VISIBILITY
214 void __add_weak() _NOEXCEPT {
215 __libcpp_atomic_refcount_increment(__shared_weak_owners_);
216 }
217 _LIBCPP_INLINE_VISIBILITY
218 void __release_shared() _NOEXCEPT {
219 if (__shared_count::__release_shared())
220 __release_weak();
221 }
222#endif
223 void __release_weak() _NOEXCEPT;
224 _LIBCPP_INLINE_VISIBILITY
225 long use_count() const _NOEXCEPT {return __shared_count::use_count();}
226 __shared_weak_count* lock() _NOEXCEPT;
227
228 virtual const void* __get_deleter(const type_info&) const _NOEXCEPT;
229private:
230 virtual void __on_zero_shared_weak() _NOEXCEPT = 0;
231};
232
233template <class _Tp, class _Dp, class _Alloc>
234class __shared_ptr_pointer
235 : public __shared_weak_count
236{
237 __compressed_pair<__compressed_pair<_Tp, _Dp>, _Alloc> __data_;
238public:
239 _LIBCPP_INLINE_VISIBILITY
240 __shared_ptr_pointer(_Tp __p, _Dp __d, _Alloc __a)
241 : __data_(__compressed_pair<_Tp, _Dp>(__p, _VSTD::move(__d)), _VSTD::move(__a)) {}
242
243#ifndef _LIBCPP_NO_RTTI
244 virtual const void* __get_deleter(const type_info&) const _NOEXCEPT;
245#endif
246
247private:
248 virtual void __on_zero_shared() _NOEXCEPT;
249 virtual void __on_zero_shared_weak() _NOEXCEPT;
250};
251
252#ifndef _LIBCPP_NO_RTTI
253
254template <class _Tp, class _Dp, class _Alloc>
255const void*
256__shared_ptr_pointer<_Tp, _Dp, _Alloc>::__get_deleter(const type_info& __t) const _NOEXCEPT
257{
258 return __t == typeid(_Dp) ? _VSTD::addressof(__data_.first().second()) : nullptr;
259}
260
261#endif // _LIBCPP_NO_RTTI
262
263template <class _Tp, class _Dp, class _Alloc>
264void
265__shared_ptr_pointer<_Tp, _Dp, _Alloc>::__on_zero_shared() _NOEXCEPT
266{
267 __data_.first().second()(__data_.first().first());
268 __data_.first().second().~_Dp();
269}
270
271template <class _Tp, class _Dp, class _Alloc>
272void
273__shared_ptr_pointer<_Tp, _Dp, _Alloc>::__on_zero_shared_weak() _NOEXCEPT
274{
275 typedef typename __allocator_traits_rebind<_Alloc, __shared_ptr_pointer>::type _Al;
276 typedef allocator_traits<_Al> _ATraits;
277 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
278
279 _Al __a(__data_.second());
280 __data_.second().~_Alloc();
281 __a.deallocate(_PTraits::pointer_to(*this), 1);
282}
283
284template <class _Tp, class _Alloc>
285struct __shared_ptr_emplace
286 : __shared_weak_count
287{
288 template<class ..._Args>
289 _LIBCPP_HIDE_FROM_ABI
290 explicit __shared_ptr_emplace(_Alloc __a, _Args&& ...__args)
291 : __storage_(_VSTD::move(__a))
292 {
293#if _LIBCPP_STD_VER > 17
294 using _TpAlloc = typename __allocator_traits_rebind<_Alloc, _Tp>::type;
295 _TpAlloc __tmp(*__get_alloc());
296 allocator_traits<_TpAlloc>::construct(__tmp, __get_elem(), _VSTD::forward<_Args>(__args)...);
297#else
298 ::new ((void*)__get_elem()) _Tp(_VSTD::forward<_Args>(__args)...);
299#endif
300 }
301
302 _LIBCPP_HIDE_FROM_ABI
303 _Alloc* __get_alloc() _NOEXCEPT { return __storage_.__get_alloc(); }
304
305 _LIBCPP_HIDE_FROM_ABI
306 _Tp* __get_elem() _NOEXCEPT { return __storage_.__get_elem(); }
307
308private:
309 virtual void __on_zero_shared() _NOEXCEPT {
310#if _LIBCPP_STD_VER > 17
311 using _TpAlloc = typename __allocator_traits_rebind<_Alloc, _Tp>::type;
312 _TpAlloc __tmp(*__get_alloc());
313 allocator_traits<_TpAlloc>::destroy(__tmp, __get_elem());
314#else
315 __get_elem()->~_Tp();
316#endif
317 }
318
319 virtual void __on_zero_shared_weak() _NOEXCEPT {
320 using _ControlBlockAlloc = typename __allocator_traits_rebind<_Alloc, __shared_ptr_emplace>::type;
321 using _ControlBlockPointer = typename allocator_traits<_ControlBlockAlloc>::pointer;
322 _ControlBlockAlloc __tmp(*__get_alloc());
323 __storage_.~_Storage();
324 allocator_traits<_ControlBlockAlloc>::deallocate(__tmp,
325 pointer_traits<_ControlBlockPointer>::pointer_to(*this), 1);
326 }
327
328 // This class implements the control block for non-array shared pointers created
329 // through `std::allocate_shared` and `std::make_shared`.
330 //
331 // In previous versions of the library, we used a compressed pair to store
332 // both the _Alloc and the _Tp. This implies using EBO, which is incompatible
333 // with Allocator construction for _Tp. To allow implementing P0674 in C++20,
334 // we now use a properly aligned char buffer while making sure that we maintain
335 // the same layout that we had when we used a compressed pair.
336 using _CompressedPair = __compressed_pair<_Alloc, _Tp>;
337 struct _ALIGNAS_TYPE(_CompressedPair) _Storage {
338 char __blob_[sizeof(_CompressedPair)];
339
340 _LIBCPP_HIDE_FROM_ABI explicit _Storage(_Alloc&& __a) {
341 ::new ((void*)__get_alloc()) _Alloc(_VSTD::move(__a));
342 }
343 _LIBCPP_HIDE_FROM_ABI ~_Storage() {
344 __get_alloc()->~_Alloc();
345 }
346 _Alloc* __get_alloc() _NOEXCEPT {
347 _CompressedPair *__as_pair = reinterpret_cast<_CompressedPair*>(__blob_);
348 typename _CompressedPair::_Base1* __first = _CompressedPair::__get_first_base(__as_pair);
349 _Alloc *__alloc = reinterpret_cast<_Alloc*>(__first);
350 return __alloc;
351 }
352 _LIBCPP_NO_CFI _Tp* __get_elem() _NOEXCEPT {
353 _CompressedPair *__as_pair = reinterpret_cast<_CompressedPair*>(__blob_);
354 typename _CompressedPair::_Base2* __second = _CompressedPair::__get_second_base(__as_pair);
355 _Tp *__elem = reinterpret_cast<_Tp*>(__second);
356 return __elem;
357 }
358 };
359
360 static_assert(_LIBCPP_ALIGNOF(_Storage) == _LIBCPP_ALIGNOF(_CompressedPair), "");
361 static_assert(sizeof(_Storage) == sizeof(_CompressedPair), "");
362 _Storage __storage_;
363};
364
365struct __shared_ptr_dummy_rebind_allocator_type;
366template <>
367class _LIBCPP_TEMPLATE_VIS allocator<__shared_ptr_dummy_rebind_allocator_type>
368{
369public:
370 template <class _Other>
371 struct rebind
372 {
373 typedef allocator<_Other> other;
374 };
375};
376
377template<class _Tp> class _LIBCPP_TEMPLATE_VIS enable_shared_from_this;
378
379template<class _Tp, class _Up>
380struct __compatible_with
381#if _LIBCPP_STD_VER > 14
382 : is_convertible<remove_extent_t<_Tp>*, remove_extent_t<_Up>*> {};
383#else
384 : is_convertible<_Tp*, _Up*> {};
385#endif // _LIBCPP_STD_VER > 14
386
387template <class _Ptr, class = void>
388struct __is_deletable : false_type { };
389template <class _Ptr>
390struct __is_deletable<_Ptr, decltype(delete declval<_Ptr>())> : true_type { };
391
392template <class _Ptr, class = void>
393struct __is_array_deletable : false_type { };
394template <class _Ptr>
395struct __is_array_deletable<_Ptr, decltype(delete[] declval<_Ptr>())> : true_type { };
396
397template <class _Dp, class _Pt,
398 class = decltype(declval<_Dp>()(declval<_Pt>()))>
399static true_type __well_formed_deleter_test(int);
400
401template <class, class>
402static false_type __well_formed_deleter_test(...);
403
404template <class _Dp, class _Pt>
405struct __well_formed_deleter : decltype(__well_formed_deleter_test<_Dp, _Pt>(0)) {};
406
407template<class _Dp, class _Tp, class _Yp>
408struct __shared_ptr_deleter_ctor_reqs
409{
410 static const bool value = __compatible_with<_Tp, _Yp>::value &&
411 is_move_constructible<_Dp>::value &&
412 __well_formed_deleter<_Dp, _Tp*>::value;
413};
414
415#if defined(_LIBCPP_ABI_ENABLE_SHARED_PTR_TRIVIAL_ABI)
416# define _LIBCPP_SHARED_PTR_TRIVIAL_ABI __attribute__((trivial_abi))
417#else
418# define _LIBCPP_SHARED_PTR_TRIVIAL_ABI
419#endif
420
421template<class _Tp>
422class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS shared_ptr
423{
424public:
425#if _LIBCPP_STD_VER > 14
426 typedef weak_ptr<_Tp> weak_type;
427 typedef remove_extent_t<_Tp> element_type;
428#else
429 typedef _Tp element_type;
430#endif
431
432private:
433 element_type* __ptr_;
434 __shared_weak_count* __cntrl_;
435
436 struct __nat {int __for_bool_;};
437public:
438 _LIBCPP_INLINE_VISIBILITY
439 _LIBCPP_CONSTEXPR shared_ptr() _NOEXCEPT;
440 _LIBCPP_INLINE_VISIBILITY
441 _LIBCPP_CONSTEXPR shared_ptr(nullptr_t) _NOEXCEPT;
442
443 template<class _Yp, class = _EnableIf<
444 _And<
445 __compatible_with<_Yp, _Tp>
446 // In C++03 we get errors when trying to do SFINAE with the
447 // delete operator, so we always pretend that it's deletable.
448 // The same happens on GCC.
449#if !defined(_LIBCPP_CXX03_LANG) && !defined(_LIBCPP_COMPILER_GCC)
450 , _If<is_array<_Tp>::value, __is_array_deletable<_Yp*>, __is_deletable<_Yp*> >
451#endif
452 >::value
453 > >
454 explicit shared_ptr(_Yp* __p) : __ptr_(__p) {
455 unique_ptr<_Yp> __hold(__p);
456 typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;
457 typedef __shared_ptr_pointer<_Yp*, __shared_ptr_default_delete<_Tp, _Yp>, _AllocT > _CntrlBlk;
458 __cntrl_ = new _CntrlBlk(__p, __shared_ptr_default_delete<_Tp, _Yp>(), _AllocT());
459 __hold.release();
460 __enable_weak_this(__p, __p);
461 }
462
463 template<class _Yp, class _Dp>
464 shared_ptr(_Yp* __p, _Dp __d,
465 typename enable_if<__shared_ptr_deleter_ctor_reqs<_Dp, _Yp, element_type>::value, __nat>::type = __nat());
466 template<class _Yp, class _Dp, class _Alloc>
467 shared_ptr(_Yp* __p, _Dp __d, _Alloc __a,
468 typename enable_if<__shared_ptr_deleter_ctor_reqs<_Dp, _Yp, element_type>::value, __nat>::type = __nat());
469 template <class _Dp> shared_ptr(nullptr_t __p, _Dp __d);
470 template <class _Dp, class _Alloc> shared_ptr(nullptr_t __p, _Dp __d, _Alloc __a);
471 template<class _Yp> _LIBCPP_INLINE_VISIBILITY shared_ptr(const shared_ptr<_Yp>& __r, element_type* __p) _NOEXCEPT;
472 _LIBCPP_INLINE_VISIBILITY
473 shared_ptr(const shared_ptr& __r) _NOEXCEPT;
474 template<class _Yp>
475 _LIBCPP_INLINE_VISIBILITY
476 shared_ptr(const shared_ptr<_Yp>& __r,
477 typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type = __nat())
478 _NOEXCEPT;
479 _LIBCPP_INLINE_VISIBILITY
480 shared_ptr(shared_ptr&& __r) _NOEXCEPT;
481 template<class _Yp> _LIBCPP_INLINE_VISIBILITY shared_ptr(shared_ptr<_Yp>&& __r,
482 typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type = __nat())
483 _NOEXCEPT;
484 template<class _Yp> explicit shared_ptr(const weak_ptr<_Yp>& __r,
485 typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type= __nat());
486#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
487 template<class _Yp>
488 shared_ptr(auto_ptr<_Yp>&& __r,
489 typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type = __nat());
490#endif
491 template <class _Yp, class _Dp>
492 shared_ptr(unique_ptr<_Yp, _Dp>&&,
493 typename enable_if
494 <
495 !is_lvalue_reference<_Dp>::value &&
496 is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
497 __nat
498 >::type = __nat());
499 template <class _Yp, class _Dp>
500 shared_ptr(unique_ptr<_Yp, _Dp>&&,
501 typename enable_if
502 <
503 is_lvalue_reference<_Dp>::value &&
504 is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
505 __nat
506 >::type = __nat());
507
508 ~shared_ptr();
509
510 _LIBCPP_INLINE_VISIBILITY
511 shared_ptr& operator=(const shared_ptr& __r) _NOEXCEPT;
512 template<class _Yp>
513 typename enable_if
514 <
515 __compatible_with<_Yp, element_type>::value,
516 shared_ptr&
517 >::type
518 _LIBCPP_INLINE_VISIBILITY
519 operator=(const shared_ptr<_Yp>& __r) _NOEXCEPT;
520 _LIBCPP_INLINE_VISIBILITY
521 shared_ptr& operator=(shared_ptr&& __r) _NOEXCEPT;
522 template<class _Yp>
523 typename enable_if
524 <
525 __compatible_with<_Yp, element_type>::value,
526 shared_ptr&
527 >::type
528 _LIBCPP_INLINE_VISIBILITY
529 operator=(shared_ptr<_Yp>&& __r);
530#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
531 template<class _Yp>
532 _LIBCPP_INLINE_VISIBILITY
533 typename enable_if
534 <
535 !is_array<_Yp>::value &&
536 is_convertible<_Yp*, element_type*>::value,
537 shared_ptr
538 >::type&
539 operator=(auto_ptr<_Yp>&& __r);
540#endif
541 template <class _Yp, class _Dp>
542 typename enable_if
543 <
544 is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
545 shared_ptr&
546 >::type
547 _LIBCPP_INLINE_VISIBILITY
548 operator=(unique_ptr<_Yp, _Dp>&& __r);
549
550 _LIBCPP_INLINE_VISIBILITY
551 void swap(shared_ptr& __r) _NOEXCEPT;
552 _LIBCPP_INLINE_VISIBILITY
553 void reset() _NOEXCEPT;
554 template<class _Yp>
555 typename enable_if
556 <
557 __compatible_with<_Yp, element_type>::value,
558 void
559 >::type
560 _LIBCPP_INLINE_VISIBILITY
561 reset(_Yp* __p);
562 template<class _Yp, class _Dp>
563 typename enable_if
564 <
565 __compatible_with<_Yp, element_type>::value,
566 void
567 >::type
568 _LIBCPP_INLINE_VISIBILITY
569 reset(_Yp* __p, _Dp __d);
570 template<class _Yp, class _Dp, class _Alloc>
571 typename enable_if
572 <
573 __compatible_with<_Yp, element_type>::value,
574 void
575 >::type
576 _LIBCPP_INLINE_VISIBILITY
577 reset(_Yp* __p, _Dp __d, _Alloc __a);
578
579 _LIBCPP_INLINE_VISIBILITY
580 element_type* get() const _NOEXCEPT {return __ptr_;}
581 _LIBCPP_INLINE_VISIBILITY
582 typename add_lvalue_reference<element_type>::type operator*() const _NOEXCEPT
583 {return *__ptr_;}
584 _LIBCPP_INLINE_VISIBILITY
585 element_type* operator->() const _NOEXCEPT
586 {
587 static_assert(!is_array<_Tp>::value,
588 "std::shared_ptr<T>::operator-> is only valid when T is not an array type.");
589 return __ptr_;
590 }
591 _LIBCPP_INLINE_VISIBILITY
592 long use_count() const _NOEXCEPT {return __cntrl_ ? __cntrl_->use_count() : 0;}
593 _LIBCPP_INLINE_VISIBILITY
594 bool unique() const _NOEXCEPT {return use_count() == 1;}
595 _LIBCPP_INLINE_VISIBILITY
596 explicit operator bool() const _NOEXCEPT {return get() != nullptr;}
597 template <class _Up>
598 _LIBCPP_INLINE_VISIBILITY
599 bool owner_before(shared_ptr<_Up> const& __p) const _NOEXCEPT
600 {return __cntrl_ < __p.__cntrl_;}
601 template <class _Up>
602 _LIBCPP_INLINE_VISIBILITY
603 bool owner_before(weak_ptr<_Up> const& __p) const _NOEXCEPT
604 {return __cntrl_ < __p.__cntrl_;}
605 _LIBCPP_INLINE_VISIBILITY
606 bool
607 __owner_equivalent(const shared_ptr& __p) const
608 {return __cntrl_ == __p.__cntrl_;}
609
610#if _LIBCPP_STD_VER > 14
611 typename add_lvalue_reference<element_type>::type
612 _LIBCPP_INLINE_VISIBILITY
613 operator[](ptrdiff_t __i) const
614 {
615 static_assert(is_array<_Tp>::value,
616 "std::shared_ptr<T>::operator[] is only valid when T is an array type.");
617 return __ptr_[__i];
618 }
619#endif
620
621#ifndef _LIBCPP_NO_RTTI
622 template <class _Dp>
623 _LIBCPP_INLINE_VISIBILITY
624 _Dp* __get_deleter() const _NOEXCEPT
625 {return static_cast<_Dp*>(__cntrl_
626 ? const_cast<void *>(__cntrl_->__get_deleter(typeid(_Dp)))
627 : nullptr);}
628#endif // _LIBCPP_NO_RTTI
629
630 template<class _Yp, class _CntrlBlk>
631 static shared_ptr<_Tp>
632 __create_with_control_block(_Yp* __p, _CntrlBlk* __cntrl) _NOEXCEPT
633 {
634 shared_ptr<_Tp> __r;
635 __r.__ptr_ = __p;
636 __r.__cntrl_ = __cntrl;
637 __r.__enable_weak_this(__r.__ptr_, __r.__ptr_);
638 return __r;
639 }
640
641private:
642 template <class _Yp, bool = is_function<_Yp>::value>
643 struct __shared_ptr_default_allocator
644 {
645 typedef allocator<_Yp> type;
646 };
647
648 template <class _Yp>
649 struct __shared_ptr_default_allocator<_Yp, true>
650 {
651 typedef allocator<__shared_ptr_dummy_rebind_allocator_type> type;
652 };
653
654 template <class _Yp, class _OrigPtr>
655 _LIBCPP_INLINE_VISIBILITY
656 typename enable_if<is_convertible<_OrigPtr*,
657 const enable_shared_from_this<_Yp>*
658 >::value,
659 void>::type
660 __enable_weak_this(const enable_shared_from_this<_Yp>* __e,
661 _OrigPtr* __ptr) _NOEXCEPT
662 {
663 typedef typename remove_cv<_Yp>::type _RawYp;
664 if (__e && __e->__weak_this_.expired())
665 {
666 __e->__weak_this_ = shared_ptr<_RawYp>(*this,
667 const_cast<_RawYp*>(static_cast<const _Yp*>(__ptr)));
668 }
669 }
670
671 _LIBCPP_INLINE_VISIBILITY void __enable_weak_this(...) _NOEXCEPT {}
672
673 template <class, class _Yp>
674 struct __shared_ptr_default_delete
675 : default_delete<_Yp> {};
676
677 template <class _Yp, class _Un, size_t _Sz>
678 struct __shared_ptr_default_delete<_Yp[_Sz], _Un>
679 : default_delete<_Yp[]> {};
680
681 template <class _Yp, class _Un>
682 struct __shared_ptr_default_delete<_Yp[], _Un>
683 : default_delete<_Yp[]> {};
684
685 template <class _Up> friend class _LIBCPP_TEMPLATE_VIS shared_ptr;
686 template <class _Up> friend class _LIBCPP_TEMPLATE_VIS weak_ptr;
687};
688
689#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
690template<class _Tp>
691shared_ptr(weak_ptr<_Tp>) -> shared_ptr<_Tp>;
692template<class _Tp, class _Dp>
693shared_ptr(unique_ptr<_Tp, _Dp>) -> shared_ptr<_Tp>;
694#endif
695
696template<class _Tp>
697inline
698_LIBCPP_CONSTEXPR
699shared_ptr<_Tp>::shared_ptr() _NOEXCEPT
700 : __ptr_(nullptr),
701 __cntrl_(nullptr)
702{
703}
704
705template<class _Tp>
706inline
707_LIBCPP_CONSTEXPR
708shared_ptr<_Tp>::shared_ptr(nullptr_t) _NOEXCEPT
709 : __ptr_(nullptr),
710 __cntrl_(nullptr)
711{
712}
713
714template<class _Tp>
715template<class _Yp, class _Dp>
716shared_ptr<_Tp>::shared_ptr(_Yp* __p, _Dp __d,
717 typename enable_if<__shared_ptr_deleter_ctor_reqs<_Dp, _Yp, element_type>::value, __nat>::type)
718 : __ptr_(__p)
719{
720#ifndef _LIBCPP_NO_EXCEPTIONS
721 try
722 {
723#endif // _LIBCPP_NO_EXCEPTIONS
724 typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;
725 typedef __shared_ptr_pointer<_Yp*, _Dp, _AllocT > _CntrlBlk;
726#ifndef _LIBCPP_CXX03_LANG
727 __cntrl_ = new _CntrlBlk(__p, _VSTD::move(__d), _AllocT());
728#else
729 __cntrl_ = new _CntrlBlk(__p, __d, _AllocT());
730#endif // not _LIBCPP_CXX03_LANG
731 __enable_weak_this(__p, __p);
732#ifndef _LIBCPP_NO_EXCEPTIONS
733 }
734 catch (...)
735 {
736 __d(__p);
737 throw;
738 }
739#endif // _LIBCPP_NO_EXCEPTIONS
740}
741
742template<class _Tp>
743template<class _Dp>
744shared_ptr<_Tp>::shared_ptr(nullptr_t __p, _Dp __d)
745 : __ptr_(nullptr)
746{
747#ifndef _LIBCPP_NO_EXCEPTIONS
748 try
749 {
750#endif // _LIBCPP_NO_EXCEPTIONS
751 typedef typename __shared_ptr_default_allocator<_Tp>::type _AllocT;
752 typedef __shared_ptr_pointer<nullptr_t, _Dp, _AllocT > _CntrlBlk;
753#ifndef _LIBCPP_CXX03_LANG
754 __cntrl_ = new _CntrlBlk(__p, _VSTD::move(__d), _AllocT());
755#else
756 __cntrl_ = new _CntrlBlk(__p, __d, _AllocT());
757#endif // not _LIBCPP_CXX03_LANG
758#ifndef _LIBCPP_NO_EXCEPTIONS
759 }
760 catch (...)
761 {
762 __d(__p);
763 throw;
764 }
765#endif // _LIBCPP_NO_EXCEPTIONS
766}
767
768template<class _Tp>
769template<class _Yp, class _Dp, class _Alloc>
770shared_ptr<_Tp>::shared_ptr(_Yp* __p, _Dp __d, _Alloc __a,
771 typename enable_if<__shared_ptr_deleter_ctor_reqs<_Dp, _Yp, element_type>::value, __nat>::type)
772 : __ptr_(__p)
773{
774#ifndef _LIBCPP_NO_EXCEPTIONS
775 try
776 {
777#endif // _LIBCPP_NO_EXCEPTIONS
778 typedef __shared_ptr_pointer<_Yp*, _Dp, _Alloc> _CntrlBlk;
779 typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _A2;
780 typedef __allocator_destructor<_A2> _D2;
781 _A2 __a2(__a);
782 unique_ptr<_CntrlBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1));
783 ::new ((void*)_VSTD::addressof(*__hold2.get()))
784#ifndef _LIBCPP_CXX03_LANG
785 _CntrlBlk(__p, _VSTD::move(__d), __a);
786#else
787 _CntrlBlk(__p, __d, __a);
788#endif // not _LIBCPP_CXX03_LANG
789 __cntrl_ = _VSTD::addressof(*__hold2.release());
790 __enable_weak_this(__p, __p);
791#ifndef _LIBCPP_NO_EXCEPTIONS
792 }
793 catch (...)
794 {
795 __d(__p);
796 throw;
797 }
798#endif // _LIBCPP_NO_EXCEPTIONS
799}
800
801template<class _Tp>
802template<class _Dp, class _Alloc>
803shared_ptr<_Tp>::shared_ptr(nullptr_t __p, _Dp __d, _Alloc __a)
804 : __ptr_(nullptr)
805{
806#ifndef _LIBCPP_NO_EXCEPTIONS
807 try
808 {
809#endif // _LIBCPP_NO_EXCEPTIONS
810 typedef __shared_ptr_pointer<nullptr_t, _Dp, _Alloc> _CntrlBlk;
811 typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _A2;
812 typedef __allocator_destructor<_A2> _D2;
813 _A2 __a2(__a);
814 unique_ptr<_CntrlBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1));
815 ::new ((void*)_VSTD::addressof(*__hold2.get()))
816#ifndef _LIBCPP_CXX03_LANG
817 _CntrlBlk(__p, _VSTD::move(__d), __a);
818#else
819 _CntrlBlk(__p, __d, __a);
820#endif // not _LIBCPP_CXX03_LANG
821 __cntrl_ = _VSTD::addressof(*__hold2.release());
822#ifndef _LIBCPP_NO_EXCEPTIONS
823 }
824 catch (...)
825 {
826 __d(__p);
827 throw;
828 }
829#endif // _LIBCPP_NO_EXCEPTIONS
830}
831
832template<class _Tp>
833template<class _Yp>
834inline
835shared_ptr<_Tp>::shared_ptr(const shared_ptr<_Yp>& __r, element_type *__p) _NOEXCEPT
836 : __ptr_(__p),
837 __cntrl_(__r.__cntrl_)
838{
839 if (__cntrl_)
840 __cntrl_->__add_shared();
841}
842
843template<class _Tp>
844inline
845shared_ptr<_Tp>::shared_ptr(const shared_ptr& __r) _NOEXCEPT
846 : __ptr_(__r.__ptr_),
847 __cntrl_(__r.__cntrl_)
848{
849 if (__cntrl_)
850 __cntrl_->__add_shared();
851}
852
853template<class _Tp>
854template<class _Yp>
855inline
856shared_ptr<_Tp>::shared_ptr(const shared_ptr<_Yp>& __r,
857 typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type)
858 _NOEXCEPT
859 : __ptr_(__r.__ptr_),
860 __cntrl_(__r.__cntrl_)
861{
862 if (__cntrl_)
863 __cntrl_->__add_shared();
864}
865
866template<class _Tp>
867inline
868shared_ptr<_Tp>::shared_ptr(shared_ptr&& __r) _NOEXCEPT
869 : __ptr_(__r.__ptr_),
870 __cntrl_(__r.__cntrl_)
871{
872 __r.__ptr_ = nullptr;
873 __r.__cntrl_ = nullptr;
874}
875
876template<class _Tp>
877template<class _Yp>
878inline
879shared_ptr<_Tp>::shared_ptr(shared_ptr<_Yp>&& __r,
880 typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type)
881 _NOEXCEPT
882 : __ptr_(__r.__ptr_),
883 __cntrl_(__r.__cntrl_)
884{
885 __r.__ptr_ = nullptr;
886 __r.__cntrl_ = nullptr;
887}
888
889#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
890template<class _Tp>
891template<class _Yp>
892shared_ptr<_Tp>::shared_ptr(auto_ptr<_Yp>&& __r,
893 typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type)
894 : __ptr_(__r.get())
895{
896 typedef __shared_ptr_pointer<_Yp*, default_delete<_Yp>, allocator<_Yp> > _CntrlBlk;
897 __cntrl_ = new _CntrlBlk(__r.get(), default_delete<_Yp>(), allocator<_Yp>());
898 __enable_weak_this(__r.get(), __r.get());
899 __r.release();
900}
901#endif
902
903template<class _Tp>
904template <class _Yp, class _Dp>
905shared_ptr<_Tp>::shared_ptr(unique_ptr<_Yp, _Dp>&& __r,
906 typename enable_if
907 <
908 !is_lvalue_reference<_Dp>::value &&
909 is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
910 __nat
911 >::type)
912 : __ptr_(__r.get())
913{
914#if _LIBCPP_STD_VER > 11
915 if (__ptr_ == nullptr)
916 __cntrl_ = nullptr;
917 else
918#endif
919 {
920 typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;
921 typedef __shared_ptr_pointer<typename unique_ptr<_Yp, _Dp>::pointer, _Dp, _AllocT > _CntrlBlk;
922 __cntrl_ = new _CntrlBlk(__r.get(), __r.get_deleter(), _AllocT());
923 __enable_weak_this(__r.get(), __r.get());
924 }
925 __r.release();
926}
927
928template<class _Tp>
929template <class _Yp, class _Dp>
930shared_ptr<_Tp>::shared_ptr(unique_ptr<_Yp, _Dp>&& __r,
931 typename enable_if
932 <
933 is_lvalue_reference<_Dp>::value &&
934 is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
935 __nat
936 >::type)
937 : __ptr_(__r.get())
938{
939#if _LIBCPP_STD_VER > 11
940 if (__ptr_ == nullptr)
941 __cntrl_ = nullptr;
942 else
943#endif
944 {
945 typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;
946 typedef __shared_ptr_pointer<typename unique_ptr<_Yp, _Dp>::pointer,
947 reference_wrapper<typename remove_reference<_Dp>::type>,
948 _AllocT > _CntrlBlk;
949 __cntrl_ = new _CntrlBlk(__r.get(), _VSTD::ref(__r.get_deleter()), _AllocT());
950 __enable_weak_this(__r.get(), __r.get());
951 }
952 __r.release();
953}
954
955template<class _Tp>
956shared_ptr<_Tp>::~shared_ptr()
957{
958 if (__cntrl_)
959 __cntrl_->__release_shared();
960}
961
962template<class _Tp>
963inline
964shared_ptr<_Tp>&
965shared_ptr<_Tp>::operator=(const shared_ptr& __r) _NOEXCEPT
966{
967 shared_ptr(__r).swap(*this);
968 return *this;
969}
970
971template<class _Tp>
972template<class _Yp>
973inline
974typename enable_if
975<
976 __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value,
977 shared_ptr<_Tp>&
978>::type
979shared_ptr<_Tp>::operator=(const shared_ptr<_Yp>& __r) _NOEXCEPT
980{
981 shared_ptr(__r).swap(*this);
982 return *this;
983}
984
985template<class _Tp>
986inline
987shared_ptr<_Tp>&
988shared_ptr<_Tp>::operator=(shared_ptr&& __r) _NOEXCEPT
989{
990 shared_ptr(_VSTD::move(__r)).swap(*this);
991 return *this;
992}
993
994template<class _Tp>
995template<class _Yp>
996inline
997typename enable_if
998<
999 __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value,
1000 shared_ptr<_Tp>&
1001>::type
1002shared_ptr<_Tp>::operator=(shared_ptr<_Yp>&& __r)
1003{
1004 shared_ptr(_VSTD::move(__r)).swap(*this);
1005 return *this;
1006}
1007
1008#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
1009template<class _Tp>
1010template<class _Yp>
1011inline
1012typename enable_if
1013<
1014 !is_array<_Yp>::value &&
1015 is_convertible<_Yp*, typename shared_ptr<_Tp>::element_type*>::value,
1016 shared_ptr<_Tp>
1017>::type&
1018shared_ptr<_Tp>::operator=(auto_ptr<_Yp>&& __r)
1019{
1020 shared_ptr(_VSTD::move(__r)).swap(*this);
1021 return *this;
1022}
1023#endif
1024
1025template<class _Tp>
1026template <class _Yp, class _Dp>
1027inline
1028typename enable_if
1029<
1030 is_convertible<typename unique_ptr<_Yp, _Dp>::pointer,
1031 typename shared_ptr<_Tp>::element_type*>::value,
1032 shared_ptr<_Tp>&
1033>::type
1034shared_ptr<_Tp>::operator=(unique_ptr<_Yp, _Dp>&& __r)
1035{
1036 shared_ptr(_VSTD::move(__r)).swap(*this);
1037 return *this;
1038}
1039
1040template<class _Tp>
1041inline
1042void
1043shared_ptr<_Tp>::swap(shared_ptr& __r) _NOEXCEPT
1044{
1045 _VSTD::swap(__ptr_, __r.__ptr_);
1046 _VSTD::swap(__cntrl_, __r.__cntrl_);
1047}
1048
1049template<class _Tp>
1050inline
1051void
1052shared_ptr<_Tp>::reset() _NOEXCEPT
1053{
1054 shared_ptr().swap(*this);
1055}
1056
1057template<class _Tp>
1058template<class _Yp>
1059inline
1060typename enable_if
1061<
1062 __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value,
1063 void
1064>::type
1065shared_ptr<_Tp>::reset(_Yp* __p)
1066{
1067 shared_ptr(__p).swap(*this);
1068}
1069
1070template<class _Tp>
1071template<class _Yp, class _Dp>
1072inline
1073typename enable_if
1074<
1075 __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value,
1076 void
1077>::type
1078shared_ptr<_Tp>::reset(_Yp* __p, _Dp __d)
1079{
1080 shared_ptr(__p, __d).swap(*this);
1081}
1082
1083template<class _Tp>
1084template<class _Yp, class _Dp, class _Alloc>
1085inline
1086typename enable_if
1087<
1088 __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value,
1089 void
1090>::type
1091shared_ptr<_Tp>::reset(_Yp* __p, _Dp __d, _Alloc __a)
1092{
1093 shared_ptr(__p, __d, __a).swap(*this);
1094}
1095
1096//
1097// std::allocate_shared and std::make_shared
1098//
1099template<class _Tp, class _Alloc, class ..._Args, class = _EnableIf<!is_array<_Tp>::value> >
1100_LIBCPP_HIDE_FROM_ABI
1101shared_ptr<_Tp> allocate_shared(const _Alloc& __a, _Args&& ...__args)
1102{
1103 using _ControlBlock = __shared_ptr_emplace<_Tp, _Alloc>;
1104 using _ControlBlockAllocator = typename __allocator_traits_rebind<_Alloc, _ControlBlock>::type;
1105 __allocation_guard<_ControlBlockAllocator> __guard(__a, 1);
1106 ::new ((void*)_VSTD::addressof(*__guard.__get())) _ControlBlock(__a, _VSTD::forward<_Args>(__args)...);
1107 auto __control_block = __guard.__release_ptr();
1108 return shared_ptr<_Tp>::__create_with_control_block((*__control_block).__get_elem(), _VSTD::addressof(*__control_block));
1109}
1110
1111template<class _Tp, class ..._Args, class = _EnableIf<!is_array<_Tp>::value> >
1112_LIBCPP_HIDE_FROM_ABI
1113shared_ptr<_Tp> make_shared(_Args&& ...__args)
1114{
1115 return _VSTD::allocate_shared<_Tp>(allocator<_Tp>(), _VSTD::forward<_Args>(__args)...);
1116}
1117
1118template<class _Tp, class _Up>
1119inline _LIBCPP_INLINE_VISIBILITY
1120bool
1121operator==(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
1122{
1123 return __x.get() == __y.get();
1124}
1125
1126template<class _Tp, class _Up>
1127inline _LIBCPP_INLINE_VISIBILITY
1128bool
1129operator!=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
1130{
1131 return !(__x == __y);
1132}
1133
1134template<class _Tp, class _Up>
1135inline _LIBCPP_INLINE_VISIBILITY
1136bool
1137operator<(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
1138{
1139#if _LIBCPP_STD_VER <= 11
1140 typedef typename common_type<_Tp*, _Up*>::type _Vp;
1141 return less<_Vp>()(__x.get(), __y.get());
1142#else
1143 return less<>()(__x.get(), __y.get());
1144#endif
1145
1146}
1147
1148template<class _Tp, class _Up>
1149inline _LIBCPP_INLINE_VISIBILITY
1150bool
1151operator>(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
1152{
1153 return __y < __x;
1154}
1155
1156template<class _Tp, class _Up>
1157inline _LIBCPP_INLINE_VISIBILITY
1158bool
1159operator<=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
1160{
1161 return !(__y < __x);
1162}
1163
1164template<class _Tp, class _Up>
1165inline _LIBCPP_INLINE_VISIBILITY
1166bool
1167operator>=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
1168{
1169 return !(__x < __y);
1170}
1171
1172template<class _Tp>
1173inline _LIBCPP_INLINE_VISIBILITY
1174bool
1175operator==(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
1176{
1177 return !__x;
1178}
1179
1180template<class _Tp>
1181inline _LIBCPP_INLINE_VISIBILITY
1182bool
1183operator==(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
1184{
1185 return !__x;
1186}
1187
1188template<class _Tp>
1189inline _LIBCPP_INLINE_VISIBILITY
1190bool
1191operator!=(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
1192{
1193 return static_cast<bool>(__x);
1194}
1195
1196template<class _Tp>
1197inline _LIBCPP_INLINE_VISIBILITY
1198bool
1199operator!=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
1200{
1201 return static_cast<bool>(__x);
1202}
1203
1204template<class _Tp>
1205inline _LIBCPP_INLINE_VISIBILITY
1206bool
1207operator<(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
1208{
1209 return less<_Tp*>()(__x.get(), nullptr);
1210}
1211
1212template<class _Tp>
1213inline _LIBCPP_INLINE_VISIBILITY
1214bool
1215operator<(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
1216{
1217 return less<_Tp*>()(nullptr, __x.get());
1218}
1219
1220template<class _Tp>
1221inline _LIBCPP_INLINE_VISIBILITY
1222bool
1223operator>(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
1224{
1225 return nullptr < __x;
1226}
1227
1228template<class _Tp>
1229inline _LIBCPP_INLINE_VISIBILITY
1230bool
1231operator>(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
1232{
1233 return __x < nullptr;
1234}
1235
1236template<class _Tp>
1237inline _LIBCPP_INLINE_VISIBILITY
1238bool
1239operator<=(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
1240{
1241 return !(nullptr < __x);
1242}
1243
1244template<class _Tp>
1245inline _LIBCPP_INLINE_VISIBILITY
1246bool
1247operator<=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
1248{
1249 return !(__x < nullptr);
1250}
1251
1252template<class _Tp>
1253inline _LIBCPP_INLINE_VISIBILITY
1254bool
1255operator>=(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
1256{
1257 return !(__x < nullptr);
1258}
1259
1260template<class _Tp>
1261inline _LIBCPP_INLINE_VISIBILITY
1262bool
1263operator>=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
1264{
1265 return !(nullptr < __x);
1266}
1267
1268template<class _Tp>
1269inline _LIBCPP_INLINE_VISIBILITY
1270void
1271swap(shared_ptr<_Tp>& __x, shared_ptr<_Tp>& __y) _NOEXCEPT
1272{
1273 __x.swap(__y);
1274}
1275
1276template<class _Tp, class _Up>
1277inline _LIBCPP_INLINE_VISIBILITY
1278shared_ptr<_Tp>
1279static_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT
1280{
1281 return shared_ptr<_Tp>(__r,
1282 static_cast<
1283 typename shared_ptr<_Tp>::element_type*>(__r.get()));
1284}
1285
1286template<class _Tp, class _Up>
1287inline _LIBCPP_INLINE_VISIBILITY
1288shared_ptr<_Tp>
1289dynamic_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT
1290{
1291 typedef typename shared_ptr<_Tp>::element_type _ET;
1292 _ET* __p = dynamic_cast<_ET*>(__r.get());
1293 return __p ? shared_ptr<_Tp>(__r, __p) : shared_ptr<_Tp>();
1294}
1295
1296template<class _Tp, class _Up>
1297shared_ptr<_Tp>
1298const_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT
1299{
1300 typedef typename shared_ptr<_Tp>::element_type _RTp;
1301 return shared_ptr<_Tp>(__r, const_cast<_RTp*>(__r.get()));
1302}
1303
1304template<class _Tp, class _Up>
1305shared_ptr<_Tp>
1306reinterpret_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT
1307{
1308 return shared_ptr<_Tp>(__r,
1309 reinterpret_cast<
1310 typename shared_ptr<_Tp>::element_type*>(__r.get()));
1311}
1312
1313#ifndef _LIBCPP_NO_RTTI
1314
1315template<class _Dp, class _Tp>
1316inline _LIBCPP_INLINE_VISIBILITY
1317_Dp*
1318get_deleter(const shared_ptr<_Tp>& __p) _NOEXCEPT
1319{
1320 return __p.template __get_deleter<_Dp>();
1321}
1322
1323#endif // _LIBCPP_NO_RTTI
1324
1325template<class _Tp>
1326class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS weak_ptr
1327{
1328public:
1329 typedef _Tp element_type;
1330private:
1331 element_type* __ptr_;
1332 __shared_weak_count* __cntrl_;
1333
1334public:
1335 _LIBCPP_INLINE_VISIBILITY
1336 _LIBCPP_CONSTEXPR weak_ptr() _NOEXCEPT;
1337 template<class _Yp> _LIBCPP_INLINE_VISIBILITY weak_ptr(shared_ptr<_Yp> const& __r,
1338 typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type = 0)
1339 _NOEXCEPT;
1340 _LIBCPP_INLINE_VISIBILITY
1341 weak_ptr(weak_ptr const& __r) _NOEXCEPT;
1342 template<class _Yp> _LIBCPP_INLINE_VISIBILITY weak_ptr(weak_ptr<_Yp> const& __r,
1343 typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type = 0)
1344 _NOEXCEPT;
1345
1346 _LIBCPP_INLINE_VISIBILITY
1347 weak_ptr(weak_ptr&& __r) _NOEXCEPT;
1348 template<class _Yp> _LIBCPP_INLINE_VISIBILITY weak_ptr(weak_ptr<_Yp>&& __r,
1349 typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type = 0)
1350 _NOEXCEPT;
1351 ~weak_ptr();
1352
1353 _LIBCPP_INLINE_VISIBILITY
1354 weak_ptr& operator=(weak_ptr const& __r) _NOEXCEPT;
1355 template<class _Yp>
1356 typename enable_if
1357 <
1358 is_convertible<_Yp*, element_type*>::value,
1359 weak_ptr&
1360 >::type
1361 _LIBCPP_INLINE_VISIBILITY
1362 operator=(weak_ptr<_Yp> const& __r) _NOEXCEPT;
1363
1364 _LIBCPP_INLINE_VISIBILITY
1365 weak_ptr& operator=(weak_ptr&& __r) _NOEXCEPT;
1366 template<class _Yp>
1367 typename enable_if
1368 <
1369 is_convertible<_Yp*, element_type*>::value,
1370 weak_ptr&
1371 >::type
1372 _LIBCPP_INLINE_VISIBILITY
1373 operator=(weak_ptr<_Yp>&& __r) _NOEXCEPT;
1374
1375 template<class _Yp>
1376 typename enable_if
1377 <
1378 is_convertible<_Yp*, element_type*>::value,
1379 weak_ptr&
1380 >::type
1381 _LIBCPP_INLINE_VISIBILITY
1382 operator=(shared_ptr<_Yp> const& __r) _NOEXCEPT;
1383
1384 _LIBCPP_INLINE_VISIBILITY
1385 void swap(weak_ptr& __r) _NOEXCEPT;
1386 _LIBCPP_INLINE_VISIBILITY
1387 void reset() _NOEXCEPT;
1388
1389 _LIBCPP_INLINE_VISIBILITY
1390 long use_count() const _NOEXCEPT
1391 {return __cntrl_ ? __cntrl_->use_count() : 0;}
1392 _LIBCPP_INLINE_VISIBILITY
1393 bool expired() const _NOEXCEPT
1394 {return __cntrl_ == nullptr || __cntrl_->use_count() == 0;}
1395 shared_ptr<_Tp> lock() const _NOEXCEPT;
1396 template<class _Up>
1397 _LIBCPP_INLINE_VISIBILITY
1398 bool owner_before(const shared_ptr<_Up>& __r) const _NOEXCEPT
1399 {return __cntrl_ < __r.__cntrl_;}
1400 template<class _Up>
1401 _LIBCPP_INLINE_VISIBILITY
1402 bool owner_before(const weak_ptr<_Up>& __r) const _NOEXCEPT
1403 {return __cntrl_ < __r.__cntrl_;}
1404
1405 template <class _Up> friend class _LIBCPP_TEMPLATE_VIS weak_ptr;
1406 template <class _Up> friend class _LIBCPP_TEMPLATE_VIS shared_ptr;
1407};
1408
1409#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
1410template<class _Tp>
1411weak_ptr(shared_ptr<_Tp>) -> weak_ptr<_Tp>;
1412#endif
1413
1414template<class _Tp>
1415inline
1416_LIBCPP_CONSTEXPR
1417weak_ptr<_Tp>::weak_ptr() _NOEXCEPT
1418 : __ptr_(nullptr),
1419 __cntrl_(nullptr)
1420{
1421}
1422
1423template<class _Tp>
1424inline
1425weak_ptr<_Tp>::weak_ptr(weak_ptr const& __r) _NOEXCEPT
1426 : __ptr_(__r.__ptr_),
1427 __cntrl_(__r.__cntrl_)
1428{
1429 if (__cntrl_)
1430 __cntrl_->__add_weak();
1431}
1432
1433template<class _Tp>
1434template<class _Yp>
1435inline
1436weak_ptr<_Tp>::weak_ptr(shared_ptr<_Yp> const& __r,
1437 typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type)
1438 _NOEXCEPT
1439 : __ptr_(__r.__ptr_),
1440 __cntrl_(__r.__cntrl_)
1441{
1442 if (__cntrl_)
1443 __cntrl_->__add_weak();
1444}
1445
1446template<class _Tp>
1447template<class _Yp>
1448inline
1449weak_ptr<_Tp>::weak_ptr(weak_ptr<_Yp> const& __r,
1450 typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type)
1451 _NOEXCEPT
1452 : __ptr_(__r.__ptr_),
1453 __cntrl_(__r.__cntrl_)
1454{
1455 if (__cntrl_)
1456 __cntrl_->__add_weak();
1457}
1458
1459template<class _Tp>
1460inline
1461weak_ptr<_Tp>::weak_ptr(weak_ptr&& __r) _NOEXCEPT
1462 : __ptr_(__r.__ptr_),
1463 __cntrl_(__r.__cntrl_)
1464{
1465 __r.__ptr_ = nullptr;
1466 __r.__cntrl_ = nullptr;
1467}
1468
1469template<class _Tp>
1470template<class _Yp>
1471inline
1472weak_ptr<_Tp>::weak_ptr(weak_ptr<_Yp>&& __r,
1473 typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type)
1474 _NOEXCEPT
1475 : __ptr_(__r.__ptr_),
1476 __cntrl_(__r.__cntrl_)
1477{
1478 __r.__ptr_ = nullptr;
1479 __r.__cntrl_ = nullptr;
1480}
1481
1482template<class _Tp>
1483weak_ptr<_Tp>::~weak_ptr()
1484{
1485 if (__cntrl_)
1486 __cntrl_->__release_weak();
1487}
1488
1489template<class _Tp>
1490inline
1491weak_ptr<_Tp>&
1492weak_ptr<_Tp>::operator=(weak_ptr const& __r) _NOEXCEPT
1493{
1494 weak_ptr(__r).swap(*this);
1495 return *this;
1496}
1497
1498template<class _Tp>
1499template<class _Yp>
1500inline
1501typename enable_if
1502<
1503 is_convertible<_Yp*, _Tp*>::value,
1504 weak_ptr<_Tp>&
1505>::type
1506weak_ptr<_Tp>::operator=(weak_ptr<_Yp> const& __r) _NOEXCEPT
1507{
1508 weak_ptr(__r).swap(*this);
1509 return *this;
1510}
1511
1512template<class _Tp>
1513inline
1514weak_ptr<_Tp>&
1515weak_ptr<_Tp>::operator=(weak_ptr&& __r) _NOEXCEPT
1516{
1517 weak_ptr(_VSTD::move(__r)).swap(*this);
1518 return *this;
1519}
1520
1521template<class _Tp>
1522template<class _Yp>
1523inline
1524typename enable_if
1525<
1526 is_convertible<_Yp*, _Tp*>::value,
1527 weak_ptr<_Tp>&
1528>::type
1529weak_ptr<_Tp>::operator=(weak_ptr<_Yp>&& __r) _NOEXCEPT
1530{
1531 weak_ptr(_VSTD::move(__r)).swap(*this);
1532 return *this;
1533}
1534
1535template<class _Tp>
1536template<class _Yp>
1537inline
1538typename enable_if
1539<
1540 is_convertible<_Yp*, _Tp*>::value,
1541 weak_ptr<_Tp>&
1542>::type
1543weak_ptr<_Tp>::operator=(shared_ptr<_Yp> const& __r) _NOEXCEPT
1544{
1545 weak_ptr(__r).swap(*this);
1546 return *this;
1547}
1548
1549template<class _Tp>
1550inline
1551void
1552weak_ptr<_Tp>::swap(weak_ptr& __r) _NOEXCEPT
1553{
1554 _VSTD::swap(__ptr_, __r.__ptr_);
1555 _VSTD::swap(__cntrl_, __r.__cntrl_);
1556}
1557
1558template<class _Tp>
1559inline _LIBCPP_INLINE_VISIBILITY
1560void
1561swap(weak_ptr<_Tp>& __x, weak_ptr<_Tp>& __y) _NOEXCEPT
1562{
1563 __x.swap(__y);
1564}
1565
1566template<class _Tp>
1567inline
1568void
1569weak_ptr<_Tp>::reset() _NOEXCEPT
1570{
1571 weak_ptr().swap(*this);
1572}
1573
1574template<class _Tp>
1575template<class _Yp>
1576shared_ptr<_Tp>::shared_ptr(const weak_ptr<_Yp>& __r,
1577 typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type)
1578 : __ptr_(__r.__ptr_),
1579 __cntrl_(__r.__cntrl_ ? __r.__cntrl_->lock() : __r.__cntrl_)
1580{
1581 if (__cntrl_ == nullptr)
1582 __throw_bad_weak_ptr();
1583}
1584
1585template<class _Tp>
1586shared_ptr<_Tp>
1587weak_ptr<_Tp>::lock() const _NOEXCEPT
1588{
1589 shared_ptr<_Tp> __r;
1590 __r.__cntrl_ = __cntrl_ ? __cntrl_->lock() : __cntrl_;
1591 if (__r.__cntrl_)
1592 __r.__ptr_ = __ptr_;
1593 return __r;
1594}
1595
1596#if _LIBCPP_STD_VER > 14
1597template <class _Tp = void> struct owner_less;
1598#else
1599template <class _Tp> struct owner_less;
1600#endif
1601
1602
1603_LIBCPP_SUPPRESS_DEPRECATED_PUSH
1604template <class _Tp>
1605struct _LIBCPP_TEMPLATE_VIS owner_less<shared_ptr<_Tp> >
1606#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
1607 : binary_function<shared_ptr<_Tp>, shared_ptr<_Tp>, bool>
1608#endif
1609{
1610_LIBCPP_SUPPRESS_DEPRECATED_POP
1611#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
1612 _LIBCPP_DEPRECATED_IN_CXX17 typedef bool result_type;
1613 _LIBCPP_DEPRECATED_IN_CXX17 typedef shared_ptr<_Tp> first_argument_type;
1614 _LIBCPP_DEPRECATED_IN_CXX17 typedef shared_ptr<_Tp> second_argument_type;
1615#endif
1616 _LIBCPP_INLINE_VISIBILITY
1617 bool operator()(shared_ptr<_Tp> const& __x, shared_ptr<_Tp> const& __y) const _NOEXCEPT
1618 {return __x.owner_before(__y);}
1619 _LIBCPP_INLINE_VISIBILITY
1620 bool operator()(shared_ptr<_Tp> const& __x, weak_ptr<_Tp> const& __y) const _NOEXCEPT
1621 {return __x.owner_before(__y);}
1622 _LIBCPP_INLINE_VISIBILITY
1623 bool operator()( weak_ptr<_Tp> const& __x, shared_ptr<_Tp> const& __y) const _NOEXCEPT
1624 {return __x.owner_before(__y);}
1625};
1626
1627_LIBCPP_SUPPRESS_DEPRECATED_PUSH
1628template <class _Tp>
1629struct _LIBCPP_TEMPLATE_VIS owner_less<weak_ptr<_Tp> >
1630#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
1631 : binary_function<weak_ptr<_Tp>, weak_ptr<_Tp>, bool>
1632#endif
1633{
1634_LIBCPP_SUPPRESS_DEPRECATED_POP
1635#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
1636 _LIBCPP_DEPRECATED_IN_CXX17 typedef bool result_type;
1637 _LIBCPP_DEPRECATED_IN_CXX17 typedef weak_ptr<_Tp> first_argument_type;
1638 _LIBCPP_DEPRECATED_IN_CXX17 typedef weak_ptr<_Tp> second_argument_type;
1639#endif
1640 _LIBCPP_INLINE_VISIBILITY
1641 bool operator()( weak_ptr<_Tp> const& __x, weak_ptr<_Tp> const& __y) const _NOEXCEPT
1642 {return __x.owner_before(__y);}
1643 _LIBCPP_INLINE_VISIBILITY
1644 bool operator()(shared_ptr<_Tp> const& __x, weak_ptr<_Tp> const& __y) const _NOEXCEPT
1645 {return __x.owner_before(__y);}
1646 _LIBCPP_INLINE_VISIBILITY
1647 bool operator()( weak_ptr<_Tp> const& __x, shared_ptr<_Tp> const& __y) const _NOEXCEPT
1648 {return __x.owner_before(__y);}
1649};
1650
1651#if _LIBCPP_STD_VER > 14
1652template <>
1653struct _LIBCPP_TEMPLATE_VIS owner_less<void>
1654{
1655 template <class _Tp, class _Up>
1656 _LIBCPP_INLINE_VISIBILITY
1657 bool operator()( shared_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) const _NOEXCEPT
1658 {return __x.owner_before(__y);}
1659 template <class _Tp, class _Up>
1660 _LIBCPP_INLINE_VISIBILITY
1661 bool operator()( shared_ptr<_Tp> const& __x, weak_ptr<_Up> const& __y) const _NOEXCEPT
1662 {return __x.owner_before(__y);}
1663 template <class _Tp, class _Up>
1664 _LIBCPP_INLINE_VISIBILITY
1665 bool operator()( weak_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) const _NOEXCEPT
1666 {return __x.owner_before(__y);}
1667 template <class _Tp, class _Up>
1668 _LIBCPP_INLINE_VISIBILITY
1669 bool operator()( weak_ptr<_Tp> const& __x, weak_ptr<_Up> const& __y) const _NOEXCEPT
1670 {return __x.owner_before(__y);}
1671 typedef void is_transparent;
1672};
1673#endif
1674
1675template<class _Tp>
1676class _LIBCPP_TEMPLATE_VIS enable_shared_from_this
1677{
1678 mutable weak_ptr<_Tp> __weak_this_;
1679protected:
1680 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
1681 enable_shared_from_this() _NOEXCEPT {}
1682 _LIBCPP_INLINE_VISIBILITY
1683 enable_shared_from_this(enable_shared_from_this const&) _NOEXCEPT {}
1684 _LIBCPP_INLINE_VISIBILITY
1685 enable_shared_from_this& operator=(enable_shared_from_this const&) _NOEXCEPT
1686 {return *this;}
1687 _LIBCPP_INLINE_VISIBILITY
1688 ~enable_shared_from_this() {}
1689public:
1690 _LIBCPP_INLINE_VISIBILITY
1691 shared_ptr<_Tp> shared_from_this()
1692 {return shared_ptr<_Tp>(__weak_this_);}
1693 _LIBCPP_INLINE_VISIBILITY
1694 shared_ptr<_Tp const> shared_from_this() const
1695 {return shared_ptr<const _Tp>(__weak_this_);}
1696
1697#if _LIBCPP_STD_VER > 14
1698 _LIBCPP_INLINE_VISIBILITY
1699 weak_ptr<_Tp> weak_from_this() _NOEXCEPT
1700 { return __weak_this_; }
1701
1702 _LIBCPP_INLINE_VISIBILITY
1703 weak_ptr<const _Tp> weak_from_this() const _NOEXCEPT
1704 { return __weak_this_; }
1705#endif // _LIBCPP_STD_VER > 14
1706
1707 template <class _Up> friend class shared_ptr;
1708};
1709
1710template <class _Tp> struct _LIBCPP_TEMPLATE_VIS hash;
1711
1712template <class _Tp>
1713struct _LIBCPP_TEMPLATE_VIS hash<shared_ptr<_Tp> >
1714{
1715#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
1716 _LIBCPP_DEPRECATED_IN_CXX17 typedef shared_ptr<_Tp> argument_type;
1717 _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
1718#endif
1719
1720 _LIBCPP_INLINE_VISIBILITY
1721 size_t operator()(const shared_ptr<_Tp>& __ptr) const _NOEXCEPT
1722 {
1723 return hash<typename shared_ptr<_Tp>::element_type*>()(__ptr.get());
1724 }
1725};
1726
1727template<class _CharT, class _Traits, class _Yp>
1728inline _LIBCPP_INLINE_VISIBILITY
1729basic_ostream<_CharT, _Traits>&
1730operator<<(basic_ostream<_CharT, _Traits>& __os, shared_ptr<_Yp> const& __p);
1731
1732
1733#if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER)
1734
1735class _LIBCPP_TYPE_VIS __sp_mut
1736{
1737 void* __lx;
1738public:
1739 void lock() _NOEXCEPT;
1740 void unlock() _NOEXCEPT;
1741
1742private:
1743 _LIBCPP_CONSTEXPR __sp_mut(void*) _NOEXCEPT;
1744 __sp_mut(const __sp_mut&);
1745 __sp_mut& operator=(const __sp_mut&);
1746
1747 friend _LIBCPP_FUNC_VIS __sp_mut& __get_sp_mut(const void*);
1748};
1749
1750_LIBCPP_FUNC_VIS _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
1751__sp_mut& __get_sp_mut(const void*);
1752
1753template <class _Tp>
1754inline _LIBCPP_INLINE_VISIBILITY
1755bool
1756atomic_is_lock_free(const shared_ptr<_Tp>*)
1757{
1758 return false;
1759}
1760
1761template <class _Tp>
1762_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
1763shared_ptr<_Tp>
1764atomic_load(const shared_ptr<_Tp>* __p)
1765{
1766 __sp_mut& __m = __get_sp_mut(__p);
1767 __m.lock();
1768 shared_ptr<_Tp> __q = *__p;
1769 __m.unlock();
1770 return __q;
1771}
1772
1773template <class _Tp>
1774inline _LIBCPP_INLINE_VISIBILITY
1775_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
1776shared_ptr<_Tp>
1777atomic_load_explicit(const shared_ptr<_Tp>* __p, memory_order)
1778{
1779 return atomic_load(__p);
1780}
1781
1782template <class _Tp>
1783_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
1784void
1785atomic_store(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r)
1786{
1787 __sp_mut& __m = __get_sp_mut(__p);
1788 __m.lock();
1789 __p->swap(__r);
1790 __m.unlock();
1791}
1792
1793template <class _Tp>
1794inline _LIBCPP_INLINE_VISIBILITY
1795_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
1796void
1797atomic_store_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r, memory_order)
1798{
1799 atomic_store(__p, __r);
1800}
1801
1802template <class _Tp>
1803_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
1804shared_ptr<_Tp>
1805atomic_exchange(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r)
1806{
1807 __sp_mut& __m = __get_sp_mut(__p);
1808 __m.lock();
1809 __p->swap(__r);
1810 __m.unlock();
1811 return __r;
1812}
1813
1814template <class _Tp>
1815inline _LIBCPP_INLINE_VISIBILITY
1816_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
1817shared_ptr<_Tp>
1818atomic_exchange_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r, memory_order)
1819{
1820 return atomic_exchange(__p, __r);
1821}
1822
1823template <class _Tp>
1824_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
1825bool
1826atomic_compare_exchange_strong(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v, shared_ptr<_Tp> __w)
1827{
1828 shared_ptr<_Tp> __temp;
1829 __sp_mut& __m = __get_sp_mut(__p);
1830 __m.lock();
1831 if (__p->__owner_equivalent(*__v))
1832 {
1833 _VSTD::swap(__temp, *__p);
1834 *__p = __w;
1835 __m.unlock();
1836 return true;
1837 }
1838 _VSTD::swap(__temp, *__v);
1839 *__v = *__p;
1840 __m.unlock();
1841 return false;
1842}
1843
1844template <class _Tp>
1845inline _LIBCPP_INLINE_VISIBILITY
1846_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
1847bool
1848atomic_compare_exchange_weak(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v, shared_ptr<_Tp> __w)
1849{
1850 return atomic_compare_exchange_strong(__p, __v, __w);
1851}
1852
1853template <class _Tp>
1854inline _LIBCPP_INLINE_VISIBILITY
1855_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
1856bool
1857atomic_compare_exchange_strong_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v,
1858 shared_ptr<_Tp> __w, memory_order, memory_order)
1859{
1860 return atomic_compare_exchange_strong(__p, __v, __w);
1861}
1862
1863template <class _Tp>
1864inline _LIBCPP_INLINE_VISIBILITY
1865_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
1866bool
1867atomic_compare_exchange_weak_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v,
1868 shared_ptr<_Tp> __w, memory_order, memory_order)
1869{
1870 return atomic_compare_exchange_weak(__p, __v, __w);
1871}
1872
1873#endif // !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER)
1874
1875_LIBCPP_END_NAMESPACE_STD
1876
1877_LIBCPP_POP_MACROS
1878
1879#endif // _LIBCPP___MEMORY_SHARED_PTR_H
lib/libcxx/include/__memory/temporary_buffer.h created+89
......@@ -0,0 +1,89 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___MEMORY_TEMPORARY_BUFFER_H
11#define _LIBCPP___MEMORY_TEMPORARY_BUFFER_H
12
13#include <__config>
14#include <cstddef>
15#include <new>
16#include <utility> // pair
17
18#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
19#pragma GCC system_header
20#endif
21
22_LIBCPP_PUSH_MACROS
23#include <__undef_macros>
24
25_LIBCPP_BEGIN_NAMESPACE_STD
26
27template <class _Tp>
28_LIBCPP_NODISCARD_EXT _LIBCPP_NO_CFI
29pair<_Tp*, ptrdiff_t>
30get_temporary_buffer(ptrdiff_t __n) _NOEXCEPT
31{
32 pair<_Tp*, ptrdiff_t> __r(0, 0);
33 const ptrdiff_t __m = (~ptrdiff_t(0) ^
34 ptrdiff_t(ptrdiff_t(1) << (sizeof(ptrdiff_t) * __CHAR_BIT__ - 1)))
35 / sizeof(_Tp);
36 if (__n > __m)
37 __n = __m;
38 while (__n > 0)
39 {
40#if !defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION)
41 if (__is_overaligned_for_new(_LIBCPP_ALIGNOF(_Tp)))
42 {
43 align_val_t __al =
44 align_val_t(alignment_of<_Tp>::value);
45 __r.first = static_cast<_Tp*>(::operator new(
46 __n * sizeof(_Tp), __al, nothrow));
47 } else {
48 __r.first = static_cast<_Tp*>(::operator new(
49 __n * sizeof(_Tp), nothrow));
50 }
51#else
52 if (__is_overaligned_for_new(_LIBCPP_ALIGNOF(_Tp)))
53 {
54 // Since aligned operator new is unavailable, return an empty
55 // buffer rather than one with invalid alignment.
56 return __r;
57 }
58
59 __r.first = static_cast<_Tp*>(::operator new(__n * sizeof(_Tp), nothrow));
60#endif
61
62 if (__r.first)
63 {
64 __r.second = __n;
65 break;
66 }
67 __n /= 2;
68 }
69 return __r;
70}
71
72template <class _Tp>
73inline _LIBCPP_INLINE_VISIBILITY
74void return_temporary_buffer(_Tp* __p) _NOEXCEPT
75{
76 _VSTD::__libcpp_deallocate_unsized((void*)__p, _LIBCPP_ALIGNOF(_Tp));
77}
78
79struct __return_temporary_buffer
80{
81 template <class _Tp>
82 _LIBCPP_INLINE_VISIBILITY void operator()(_Tp* __p) const {_VSTD::return_temporary_buffer(__p);}
83};
84
85_LIBCPP_END_NAMESPACE_STD
86
87_LIBCPP_POP_MACROS
88
89#endif // _LIBCPP___MEMORY_TEMPORARY_BUFFER_H
lib/libcxx/include/__memory/uninitialized_algorithms.h created+261
......@@ -0,0 +1,261 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___MEMORY_UNINITIALIZED_ALGORITHMS_H
11#define _LIBCPP___MEMORY_UNINITIALIZED_ALGORITHMS_H
12
13#include <__config>
14#include <__memory/addressof.h>
15#include <__memory/construct_at.h>
16#include <iterator>
17#include <utility>
18
19#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
20#pragma GCC system_header
21#endif
22
23_LIBCPP_PUSH_MACROS
24#include <__undef_macros>
25
26_LIBCPP_BEGIN_NAMESPACE_STD
27
28template <class _InputIterator, class _ForwardIterator>
29_ForwardIterator
30uninitialized_copy(_InputIterator __f, _InputIterator __l, _ForwardIterator __r)
31{
32 typedef typename iterator_traits<_ForwardIterator>::value_type value_type;
33#ifndef _LIBCPP_NO_EXCEPTIONS
34 _ForwardIterator __s = __r;
35 try
36 {
37#endif
38 for (; __f != __l; ++__f, (void) ++__r)
39 ::new ((void*)_VSTD::addressof(*__r)) value_type(*__f);
40#ifndef _LIBCPP_NO_EXCEPTIONS
41 }
42 catch (...)
43 {
44 for (; __s != __r; ++__s)
45 __s->~value_type();
46 throw;
47 }
48#endif
49 return __r;
50}
51
52template <class _InputIterator, class _Size, class _ForwardIterator>
53_ForwardIterator
54uninitialized_copy_n(_InputIterator __f, _Size __n, _ForwardIterator __r)
55{
56 typedef typename iterator_traits<_ForwardIterator>::value_type value_type;
57#ifndef _LIBCPP_NO_EXCEPTIONS
58 _ForwardIterator __s = __r;
59 try
60 {
61#endif
62 for (; __n > 0; ++__f, (void) ++__r, (void) --__n)
63 ::new ((void*)_VSTD::addressof(*__r)) value_type(*__f);
64#ifndef _LIBCPP_NO_EXCEPTIONS
65 }
66 catch (...)
67 {
68 for (; __s != __r; ++__s)
69 __s->~value_type();
70 throw;
71 }
72#endif
73 return __r;
74}
75
76template <class _ForwardIterator, class _Tp>
77void
78uninitialized_fill(_ForwardIterator __f, _ForwardIterator __l, const _Tp& __x)
79{
80 typedef typename iterator_traits<_ForwardIterator>::value_type value_type;
81#ifndef _LIBCPP_NO_EXCEPTIONS
82 _ForwardIterator __s = __f;
83 try
84 {
85#endif
86 for (; __f != __l; ++__f)
87 ::new ((void*)_VSTD::addressof(*__f)) value_type(__x);
88#ifndef _LIBCPP_NO_EXCEPTIONS
89 }
90 catch (...)
91 {
92 for (; __s != __f; ++__s)
93 __s->~value_type();
94 throw;
95 }
96#endif
97}
98
99template <class _ForwardIterator, class _Size, class _Tp>
100_ForwardIterator
101uninitialized_fill_n(_ForwardIterator __f, _Size __n, const _Tp& __x)
102{
103 typedef typename iterator_traits<_ForwardIterator>::value_type value_type;
104#ifndef _LIBCPP_NO_EXCEPTIONS
105 _ForwardIterator __s = __f;
106 try
107 {
108#endif
109 for (; __n > 0; ++__f, (void) --__n)
110 ::new ((void*)_VSTD::addressof(*__f)) value_type(__x);
111#ifndef _LIBCPP_NO_EXCEPTIONS
112 }
113 catch (...)
114 {
115 for (; __s != __f; ++__s)
116 __s->~value_type();
117 throw;
118 }
119#endif
120 return __f;
121}
122
123#if _LIBCPP_STD_VER > 14
124
125template <class _ForwardIterator>
126inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
127void destroy(_ForwardIterator __first, _ForwardIterator __last) {
128 for (; __first != __last; ++__first)
129 _VSTD::destroy_at(_VSTD::addressof(*__first));
130}
131
132template <class _ForwardIterator, class _Size>
133inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
134_ForwardIterator destroy_n(_ForwardIterator __first, _Size __n) {
135 for (; __n > 0; (void)++__first, --__n)
136 _VSTD::destroy_at(_VSTD::addressof(*__first));
137 return __first;
138}
139
140template <class _ForwardIterator>
141inline _LIBCPP_INLINE_VISIBILITY
142void uninitialized_default_construct(_ForwardIterator __first, _ForwardIterator __last) {
143 using _Vt = typename iterator_traits<_ForwardIterator>::value_type;
144 auto __idx = __first;
145#ifndef _LIBCPP_NO_EXCEPTIONS
146 try {
147#endif
148 for (; __idx != __last; ++__idx)
149 ::new ((void*)_VSTD::addressof(*__idx)) _Vt;
150#ifndef _LIBCPP_NO_EXCEPTIONS
151 } catch (...) {
152 _VSTD::destroy(__first, __idx);
153 throw;
154 }
155#endif
156}
157
158template <class _ForwardIterator, class _Size>
159inline _LIBCPP_INLINE_VISIBILITY
160_ForwardIterator uninitialized_default_construct_n(_ForwardIterator __first, _Size __n) {
161 using _Vt = typename iterator_traits<_ForwardIterator>::value_type;
162 auto __idx = __first;
163#ifndef _LIBCPP_NO_EXCEPTIONS
164 try {
165#endif
166 for (; __n > 0; (void)++__idx, --__n)
167 ::new ((void*)_VSTD::addressof(*__idx)) _Vt;
168 return __idx;
169#ifndef _LIBCPP_NO_EXCEPTIONS
170 } catch (...) {
171 _VSTD::destroy(__first, __idx);
172 throw;
173 }
174#endif
175}
176
177
178template <class _ForwardIterator>
179inline _LIBCPP_INLINE_VISIBILITY
180void uninitialized_value_construct(_ForwardIterator __first, _ForwardIterator __last) {
181 using _Vt = typename iterator_traits<_ForwardIterator>::value_type;
182 auto __idx = __first;
183#ifndef _LIBCPP_NO_EXCEPTIONS
184 try {
185#endif
186 for (; __idx != __last; ++__idx)
187 ::new ((void*)_VSTD::addressof(*__idx)) _Vt();
188#ifndef _LIBCPP_NO_EXCEPTIONS
189 } catch (...) {
190 _VSTD::destroy(__first, __idx);
191 throw;
192 }
193#endif
194}
195
196template <class _ForwardIterator, class _Size>
197inline _LIBCPP_INLINE_VISIBILITY
198_ForwardIterator uninitialized_value_construct_n(_ForwardIterator __first, _Size __n) {
199 using _Vt = typename iterator_traits<_ForwardIterator>::value_type;
200 auto __idx = __first;
201#ifndef _LIBCPP_NO_EXCEPTIONS
202 try {
203#endif
204 for (; __n > 0; (void)++__idx, --__n)
205 ::new ((void*)_VSTD::addressof(*__idx)) _Vt();
206 return __idx;
207#ifndef _LIBCPP_NO_EXCEPTIONS
208 } catch (...) {
209 _VSTD::destroy(__first, __idx);
210 throw;
211 }
212#endif
213}
214
215
216template <class _InputIt, class _ForwardIt>
217inline _LIBCPP_INLINE_VISIBILITY
218_ForwardIt uninitialized_move(_InputIt __first, _InputIt __last, _ForwardIt __first_res) {
219 using _Vt = typename iterator_traits<_ForwardIt>::value_type;
220 auto __idx = __first_res;
221#ifndef _LIBCPP_NO_EXCEPTIONS
222 try {
223#endif
224 for (; __first != __last; (void)++__idx, ++__first)
225 ::new ((void*)_VSTD::addressof(*__idx)) _Vt(_VSTD::move(*__first));
226 return __idx;
227#ifndef _LIBCPP_NO_EXCEPTIONS
228 } catch (...) {
229 _VSTD::destroy(__first_res, __idx);
230 throw;
231 }
232#endif
233}
234
235template <class _InputIt, class _Size, class _ForwardIt>
236inline _LIBCPP_INLINE_VISIBILITY
237pair<_InputIt, _ForwardIt>
238uninitialized_move_n(_InputIt __first, _Size __n, _ForwardIt __first_res) {
239 using _Vt = typename iterator_traits<_ForwardIt>::value_type;
240 auto __idx = __first_res;
241#ifndef _LIBCPP_NO_EXCEPTIONS
242 try {
243#endif
244 for (; __n > 0; ++__idx, (void)++__first, --__n)
245 ::new ((void*)_VSTD::addressof(*__idx)) _Vt(_VSTD::move(*__first));
246 return {__first, __idx};
247#ifndef _LIBCPP_NO_EXCEPTIONS
248 } catch (...) {
249 _VSTD::destroy(__first_res, __idx);
250 throw;
251 }
252#endif
253}
254
255#endif // _LIBCPP_STD_VER > 14
256
257_LIBCPP_END_NAMESPACE_STD
258
259_LIBCPP_POP_MACROS
260
261#endif // _LIBCPP___MEMORY_UNINITIALIZED_ALGORITHMS_H
lib/libcxx/include/__memory/unique_ptr.h created+773
......@@ -0,0 +1,773 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___MEMORY_UNIQUE_PTR_H
11#define _LIBCPP___MEMORY_UNIQUE_PTR_H
12
13#include <__config>
14#include <__functional_base>
15#include <__functional/hash.h>
16#include <__functional/operations.h>
17#include <__memory/allocator_traits.h> // __pointer
18#include <__memory/compressed_pair.h>
19#include <__utility/forward.h>
20#include <cstddef>
21#include <type_traits>
22#include <utility>
23
24#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
25# include <__memory/auto_ptr.h>
26#endif
27
28#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
29#pragma GCC system_header
30#endif
31
32_LIBCPP_PUSH_MACROS
33#include <__undef_macros>
34
35_LIBCPP_BEGIN_NAMESPACE_STD
36
37template <class _Tp>
38struct _LIBCPP_TEMPLATE_VIS default_delete {
39 static_assert(!is_function<_Tp>::value,
40 "default_delete cannot be instantiated for function types");
41#ifndef _LIBCPP_CXX03_LANG
42 _LIBCPP_INLINE_VISIBILITY constexpr default_delete() _NOEXCEPT = default;
43#else
44 _LIBCPP_INLINE_VISIBILITY default_delete() {}
45#endif
46 template <class _Up>
47 _LIBCPP_INLINE_VISIBILITY
48 default_delete(const default_delete<_Up>&,
49 typename enable_if<is_convertible<_Up*, _Tp*>::value>::type* =
50 0) _NOEXCEPT {}
51
52 _LIBCPP_INLINE_VISIBILITY void operator()(_Tp* __ptr) const _NOEXCEPT {
53 static_assert(sizeof(_Tp) > 0,
54 "default_delete can not delete incomplete type");
55 static_assert(!is_void<_Tp>::value,
56 "default_delete can not delete incomplete type");
57 delete __ptr;
58 }
59};
60
61template <class _Tp>
62struct _LIBCPP_TEMPLATE_VIS default_delete<_Tp[]> {
63private:
64 template <class _Up>
65 struct _EnableIfConvertible
66 : enable_if<is_convertible<_Up(*)[], _Tp(*)[]>::value> {};
67
68public:
69#ifndef _LIBCPP_CXX03_LANG
70 _LIBCPP_INLINE_VISIBILITY constexpr default_delete() _NOEXCEPT = default;
71#else
72 _LIBCPP_INLINE_VISIBILITY default_delete() {}
73#endif
74
75 template <class _Up>
76 _LIBCPP_INLINE_VISIBILITY
77 default_delete(const default_delete<_Up[]>&,
78 typename _EnableIfConvertible<_Up>::type* = 0) _NOEXCEPT {}
79
80 template <class _Up>
81 _LIBCPP_INLINE_VISIBILITY
82 typename _EnableIfConvertible<_Up>::type
83 operator()(_Up* __ptr) const _NOEXCEPT {
84 static_assert(sizeof(_Tp) > 0,
85 "default_delete can not delete incomplete type");
86 static_assert(!is_void<_Tp>::value,
87 "default_delete can not delete void type");
88 delete[] __ptr;
89 }
90};
91
92template <class _Deleter>
93struct __unique_ptr_deleter_sfinae {
94 static_assert(!is_reference<_Deleter>::value, "incorrect specialization");
95 typedef const _Deleter& __lval_ref_type;
96 typedef _Deleter&& __good_rval_ref_type;
97 typedef true_type __enable_rval_overload;
98};
99
100template <class _Deleter>
101struct __unique_ptr_deleter_sfinae<_Deleter const&> {
102 typedef const _Deleter& __lval_ref_type;
103 typedef const _Deleter&& __bad_rval_ref_type;
104 typedef false_type __enable_rval_overload;
105};
106
107template <class _Deleter>
108struct __unique_ptr_deleter_sfinae<_Deleter&> {
109 typedef _Deleter& __lval_ref_type;
110 typedef _Deleter&& __bad_rval_ref_type;
111 typedef false_type __enable_rval_overload;
112};
113
114#if defined(_LIBCPP_ABI_ENABLE_UNIQUE_PTR_TRIVIAL_ABI)
115# define _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI __attribute__((trivial_abi))
116#else
117# define _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI
118#endif
119
120template <class _Tp, class _Dp = default_delete<_Tp> >
121class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr {
122public:
123 typedef _Tp element_type;
124 typedef _Dp deleter_type;
125 typedef _LIBCPP_NODEBUG_TYPE typename __pointer<_Tp, deleter_type>::type pointer;
126
127 static_assert(!is_rvalue_reference<deleter_type>::value,
128 "the specified deleter type cannot be an rvalue reference");
129
130private:
131 __compressed_pair<pointer, deleter_type> __ptr_;
132
133 struct __nat { int __for_bool_; };
134
135 typedef _LIBCPP_NODEBUG_TYPE __unique_ptr_deleter_sfinae<_Dp> _DeleterSFINAE;
136
137 template <bool _Dummy>
138 using _LValRefType _LIBCPP_NODEBUG_TYPE =
139 typename __dependent_type<_DeleterSFINAE, _Dummy>::__lval_ref_type;
140
141 template <bool _Dummy>
142 using _GoodRValRefType _LIBCPP_NODEBUG_TYPE =
143 typename __dependent_type<_DeleterSFINAE, _Dummy>::__good_rval_ref_type;
144
145 template <bool _Dummy>
146 using _BadRValRefType _LIBCPP_NODEBUG_TYPE =
147 typename __dependent_type<_DeleterSFINAE, _Dummy>::__bad_rval_ref_type;
148
149 template <bool _Dummy, class _Deleter = typename __dependent_type<
150 __identity<deleter_type>, _Dummy>::type>
151 using _EnableIfDeleterDefaultConstructible _LIBCPP_NODEBUG_TYPE =
152 typename enable_if<is_default_constructible<_Deleter>::value &&
153 !is_pointer<_Deleter>::value>::type;
154
155 template <class _ArgType>
156 using _EnableIfDeleterConstructible _LIBCPP_NODEBUG_TYPE =
157 typename enable_if<is_constructible<deleter_type, _ArgType>::value>::type;
158
159 template <class _UPtr, class _Up>
160 using _EnableIfMoveConvertible _LIBCPP_NODEBUG_TYPE = typename enable_if<
161 is_convertible<typename _UPtr::pointer, pointer>::value &&
162 !is_array<_Up>::value
163 >::type;
164
165 template <class _UDel>
166 using _EnableIfDeleterConvertible _LIBCPP_NODEBUG_TYPE = typename enable_if<
167 (is_reference<_Dp>::value && is_same<_Dp, _UDel>::value) ||
168 (!is_reference<_Dp>::value && is_convertible<_UDel, _Dp>::value)
169 >::type;
170
171 template <class _UDel>
172 using _EnableIfDeleterAssignable = typename enable_if<
173 is_assignable<_Dp&, _UDel&&>::value
174 >::type;
175
176public:
177 template <bool _Dummy = true,
178 class = _EnableIfDeleterDefaultConstructible<_Dummy> >
179 _LIBCPP_INLINE_VISIBILITY
180 _LIBCPP_CONSTEXPR unique_ptr() _NOEXCEPT : __ptr_(pointer(), __default_init_tag()) {}
181
182 template <bool _Dummy = true,
183 class = _EnableIfDeleterDefaultConstructible<_Dummy> >
184 _LIBCPP_INLINE_VISIBILITY
185 _LIBCPP_CONSTEXPR unique_ptr(nullptr_t) _NOEXCEPT : __ptr_(pointer(), __default_init_tag()) {}
186
187 template <bool _Dummy = true,
188 class = _EnableIfDeleterDefaultConstructible<_Dummy> >
189 _LIBCPP_INLINE_VISIBILITY
190 explicit unique_ptr(pointer __p) _NOEXCEPT : __ptr_(__p, __default_init_tag()) {}
191
192 template <bool _Dummy = true,
193 class = _EnableIfDeleterConstructible<_LValRefType<_Dummy> > >
194 _LIBCPP_INLINE_VISIBILITY
195 unique_ptr(pointer __p, _LValRefType<_Dummy> __d) _NOEXCEPT
196 : __ptr_(__p, __d) {}
197
198 template <bool _Dummy = true,
199 class = _EnableIfDeleterConstructible<_GoodRValRefType<_Dummy> > >
200 _LIBCPP_INLINE_VISIBILITY
201 unique_ptr(pointer __p, _GoodRValRefType<_Dummy> __d) _NOEXCEPT
202 : __ptr_(__p, _VSTD::move(__d)) {
203 static_assert(!is_reference<deleter_type>::value,
204 "rvalue deleter bound to reference");
205 }
206
207 template <bool _Dummy = true,
208 class = _EnableIfDeleterConstructible<_BadRValRefType<_Dummy> > >
209 _LIBCPP_INLINE_VISIBILITY
210 unique_ptr(pointer __p, _BadRValRefType<_Dummy> __d) = delete;
211
212 _LIBCPP_INLINE_VISIBILITY
213 unique_ptr(unique_ptr&& __u) _NOEXCEPT
214 : __ptr_(__u.release(), _VSTD::forward<deleter_type>(__u.get_deleter())) {
215 }
216
217 template <class _Up, class _Ep,
218 class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>,
219 class = _EnableIfDeleterConvertible<_Ep>
220 >
221 _LIBCPP_INLINE_VISIBILITY
222 unique_ptr(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT
223 : __ptr_(__u.release(), _VSTD::forward<_Ep>(__u.get_deleter())) {}
224
225#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
226 template <class _Up>
227 _LIBCPP_INLINE_VISIBILITY
228 unique_ptr(auto_ptr<_Up>&& __p,
229 typename enable_if<is_convertible<_Up*, _Tp*>::value &&
230 is_same<_Dp, default_delete<_Tp> >::value,
231 __nat>::type = __nat()) _NOEXCEPT
232 : __ptr_(__p.release(), __default_init_tag()) {}
233#endif
234
235 _LIBCPP_INLINE_VISIBILITY
236 unique_ptr& operator=(unique_ptr&& __u) _NOEXCEPT {
237 reset(__u.release());
238 __ptr_.second() = _VSTD::forward<deleter_type>(__u.get_deleter());
239 return *this;
240 }
241
242 template <class _Up, class _Ep,
243 class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>,
244 class = _EnableIfDeleterAssignable<_Ep>
245 >
246 _LIBCPP_INLINE_VISIBILITY
247 unique_ptr& operator=(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT {
248 reset(__u.release());
249 __ptr_.second() = _VSTD::forward<_Ep>(__u.get_deleter());
250 return *this;
251 }
252
253#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
254 template <class _Up>
255 _LIBCPP_INLINE_VISIBILITY
256 typename enable_if<is_convertible<_Up*, _Tp*>::value &&
257 is_same<_Dp, default_delete<_Tp> >::value,
258 unique_ptr&>::type
259 operator=(auto_ptr<_Up> __p) {
260 reset(__p.release());
261 return *this;
262 }
263#endif
264
265#ifdef _LIBCPP_CXX03_LANG
266 unique_ptr(unique_ptr const&) = delete;
267 unique_ptr& operator=(unique_ptr const&) = delete;
268#endif
269
270
271 _LIBCPP_INLINE_VISIBILITY
272 ~unique_ptr() { reset(); }
273
274 _LIBCPP_INLINE_VISIBILITY
275 unique_ptr& operator=(nullptr_t) _NOEXCEPT {
276 reset();
277 return *this;
278 }
279
280 _LIBCPP_INLINE_VISIBILITY
281 typename add_lvalue_reference<_Tp>::type
282 operator*() const {
283 return *__ptr_.first();
284 }
285 _LIBCPP_INLINE_VISIBILITY
286 pointer operator->() const _NOEXCEPT {
287 return __ptr_.first();
288 }
289 _LIBCPP_INLINE_VISIBILITY
290 pointer get() const _NOEXCEPT {
291 return __ptr_.first();
292 }
293 _LIBCPP_INLINE_VISIBILITY
294 deleter_type& get_deleter() _NOEXCEPT {
295 return __ptr_.second();
296 }
297 _LIBCPP_INLINE_VISIBILITY
298 const deleter_type& get_deleter() const _NOEXCEPT {
299 return __ptr_.second();
300 }
301 _LIBCPP_INLINE_VISIBILITY
302 explicit operator bool() const _NOEXCEPT {
303 return __ptr_.first() != nullptr;
304 }
305
306 _LIBCPP_INLINE_VISIBILITY
307 pointer release() _NOEXCEPT {
308 pointer __t = __ptr_.first();
309 __ptr_.first() = pointer();
310 return __t;
311 }
312
313 _LIBCPP_INLINE_VISIBILITY
314 void reset(pointer __p = pointer()) _NOEXCEPT {
315 pointer __tmp = __ptr_.first();
316 __ptr_.first() = __p;
317 if (__tmp)
318 __ptr_.second()(__tmp);
319 }
320
321 _LIBCPP_INLINE_VISIBILITY
322 void swap(unique_ptr& __u) _NOEXCEPT {
323 __ptr_.swap(__u.__ptr_);
324 }
325};
326
327
328template <class _Tp, class _Dp>
329class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr<_Tp[], _Dp> {
330public:
331 typedef _Tp element_type;
332 typedef _Dp deleter_type;
333 typedef typename __pointer<_Tp, deleter_type>::type pointer;
334
335private:
336 __compressed_pair<pointer, deleter_type> __ptr_;
337
338 template <class _From>
339 struct _CheckArrayPointerConversion : is_same<_From, pointer> {};
340
341 template <class _FromElem>
342 struct _CheckArrayPointerConversion<_FromElem*>
343 : integral_constant<bool,
344 is_same<_FromElem*, pointer>::value ||
345 (is_same<pointer, element_type*>::value &&
346 is_convertible<_FromElem(*)[], element_type(*)[]>::value)
347 >
348 {};
349
350 typedef __unique_ptr_deleter_sfinae<_Dp> _DeleterSFINAE;
351
352 template <bool _Dummy>
353 using _LValRefType _LIBCPP_NODEBUG_TYPE =
354 typename __dependent_type<_DeleterSFINAE, _Dummy>::__lval_ref_type;
355
356 template <bool _Dummy>
357 using _GoodRValRefType _LIBCPP_NODEBUG_TYPE =
358 typename __dependent_type<_DeleterSFINAE, _Dummy>::__good_rval_ref_type;
359
360 template <bool _Dummy>
361 using _BadRValRefType _LIBCPP_NODEBUG_TYPE =
362 typename __dependent_type<_DeleterSFINAE, _Dummy>::__bad_rval_ref_type;
363
364 template <bool _Dummy, class _Deleter = typename __dependent_type<
365 __identity<deleter_type>, _Dummy>::type>
366 using _EnableIfDeleterDefaultConstructible _LIBCPP_NODEBUG_TYPE =
367 typename enable_if<is_default_constructible<_Deleter>::value &&
368 !is_pointer<_Deleter>::value>::type;
369
370 template <class _ArgType>
371 using _EnableIfDeleterConstructible _LIBCPP_NODEBUG_TYPE =
372 typename enable_if<is_constructible<deleter_type, _ArgType>::value>::type;
373
374 template <class _Pp>
375 using _EnableIfPointerConvertible _LIBCPP_NODEBUG_TYPE = typename enable_if<
376 _CheckArrayPointerConversion<_Pp>::value
377 >::type;
378
379 template <class _UPtr, class _Up,
380 class _ElemT = typename _UPtr::element_type>
381 using _EnableIfMoveConvertible _LIBCPP_NODEBUG_TYPE = typename enable_if<
382 is_array<_Up>::value &&
383 is_same<pointer, element_type*>::value &&
384 is_same<typename _UPtr::pointer, _ElemT*>::value &&
385 is_convertible<_ElemT(*)[], element_type(*)[]>::value
386 >::type;
387
388 template <class _UDel>
389 using _EnableIfDeleterConvertible _LIBCPP_NODEBUG_TYPE = typename enable_if<
390 (is_reference<_Dp>::value && is_same<_Dp, _UDel>::value) ||
391 (!is_reference<_Dp>::value && is_convertible<_UDel, _Dp>::value)
392 >::type;
393
394 template <class _UDel>
395 using _EnableIfDeleterAssignable _LIBCPP_NODEBUG_TYPE = typename enable_if<
396 is_assignable<_Dp&, _UDel&&>::value
397 >::type;
398
399public:
400 template <bool _Dummy = true,
401 class = _EnableIfDeleterDefaultConstructible<_Dummy> >
402 _LIBCPP_INLINE_VISIBILITY
403 _LIBCPP_CONSTEXPR unique_ptr() _NOEXCEPT : __ptr_(pointer(), __default_init_tag()) {}
404
405 template <bool _Dummy = true,
406 class = _EnableIfDeleterDefaultConstructible<_Dummy> >
407 _LIBCPP_INLINE_VISIBILITY
408 _LIBCPP_CONSTEXPR unique_ptr(nullptr_t) _NOEXCEPT : __ptr_(pointer(), __default_init_tag()) {}
409
410 template <class _Pp, bool _Dummy = true,
411 class = _EnableIfDeleterDefaultConstructible<_Dummy>,
412 class = _EnableIfPointerConvertible<_Pp> >
413 _LIBCPP_INLINE_VISIBILITY
414 explicit unique_ptr(_Pp __p) _NOEXCEPT
415 : __ptr_(__p, __default_init_tag()) {}
416
417 template <class _Pp, bool _Dummy = true,
418 class = _EnableIfDeleterConstructible<_LValRefType<_Dummy> >,
419 class = _EnableIfPointerConvertible<_Pp> >
420 _LIBCPP_INLINE_VISIBILITY
421 unique_ptr(_Pp __p, _LValRefType<_Dummy> __d) _NOEXCEPT
422 : __ptr_(__p, __d) {}
423
424 template <bool _Dummy = true,
425 class = _EnableIfDeleterConstructible<_LValRefType<_Dummy> > >
426 _LIBCPP_INLINE_VISIBILITY
427 unique_ptr(nullptr_t, _LValRefType<_Dummy> __d) _NOEXCEPT
428 : __ptr_(nullptr, __d) {}
429
430 template <class _Pp, bool _Dummy = true,
431 class = _EnableIfDeleterConstructible<_GoodRValRefType<_Dummy> >,
432 class = _EnableIfPointerConvertible<_Pp> >
433 _LIBCPP_INLINE_VISIBILITY
434 unique_ptr(_Pp __p, _GoodRValRefType<_Dummy> __d) _NOEXCEPT
435 : __ptr_(__p, _VSTD::move(__d)) {
436 static_assert(!is_reference<deleter_type>::value,
437 "rvalue deleter bound to reference");
438 }
439
440 template <bool _Dummy = true,
441 class = _EnableIfDeleterConstructible<_GoodRValRefType<_Dummy> > >
442 _LIBCPP_INLINE_VISIBILITY
443 unique_ptr(nullptr_t, _GoodRValRefType<_Dummy> __d) _NOEXCEPT
444 : __ptr_(nullptr, _VSTD::move(__d)) {
445 static_assert(!is_reference<deleter_type>::value,
446 "rvalue deleter bound to reference");
447 }
448
449 template <class _Pp, bool _Dummy = true,
450 class = _EnableIfDeleterConstructible<_BadRValRefType<_Dummy> >,
451 class = _EnableIfPointerConvertible<_Pp> >
452 _LIBCPP_INLINE_VISIBILITY
453 unique_ptr(_Pp __p, _BadRValRefType<_Dummy> __d) = delete;
454
455 _LIBCPP_INLINE_VISIBILITY
456 unique_ptr(unique_ptr&& __u) _NOEXCEPT
457 : __ptr_(__u.release(), _VSTD::forward<deleter_type>(__u.get_deleter())) {
458 }
459
460 _LIBCPP_INLINE_VISIBILITY
461 unique_ptr& operator=(unique_ptr&& __u) _NOEXCEPT {
462 reset(__u.release());
463 __ptr_.second() = _VSTD::forward<deleter_type>(__u.get_deleter());
464 return *this;
465 }
466
467 template <class _Up, class _Ep,
468 class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>,
469 class = _EnableIfDeleterConvertible<_Ep>
470 >
471 _LIBCPP_INLINE_VISIBILITY
472 unique_ptr(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT
473 : __ptr_(__u.release(), _VSTD::forward<_Ep>(__u.get_deleter())) {
474 }
475
476 template <class _Up, class _Ep,
477 class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>,
478 class = _EnableIfDeleterAssignable<_Ep>
479 >
480 _LIBCPP_INLINE_VISIBILITY
481 unique_ptr&
482 operator=(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT {
483 reset(__u.release());
484 __ptr_.second() = _VSTD::forward<_Ep>(__u.get_deleter());
485 return *this;
486 }
487
488#ifdef _LIBCPP_CXX03_LANG
489 unique_ptr(unique_ptr const&) = delete;
490 unique_ptr& operator=(unique_ptr const&) = delete;
491#endif
492
493public:
494 _LIBCPP_INLINE_VISIBILITY
495 ~unique_ptr() { reset(); }
496
497 _LIBCPP_INLINE_VISIBILITY
498 unique_ptr& operator=(nullptr_t) _NOEXCEPT {
499 reset();
500 return *this;
501 }
502
503 _LIBCPP_INLINE_VISIBILITY
504 typename add_lvalue_reference<_Tp>::type
505 operator[](size_t __i) const {
506 return __ptr_.first()[__i];
507 }
508 _LIBCPP_INLINE_VISIBILITY
509 pointer get() const _NOEXCEPT {
510 return __ptr_.first();
511 }
512
513 _LIBCPP_INLINE_VISIBILITY
514 deleter_type& get_deleter() _NOEXCEPT {
515 return __ptr_.second();
516 }
517
518 _LIBCPP_INLINE_VISIBILITY
519 const deleter_type& get_deleter() const _NOEXCEPT {
520 return __ptr_.second();
521 }
522 _LIBCPP_INLINE_VISIBILITY
523 explicit operator bool() const _NOEXCEPT {
524 return __ptr_.first() != nullptr;
525 }
526
527 _LIBCPP_INLINE_VISIBILITY
528 pointer release() _NOEXCEPT {
529 pointer __t = __ptr_.first();
530 __ptr_.first() = pointer();
531 return __t;
532 }
533
534 template <class _Pp>
535 _LIBCPP_INLINE_VISIBILITY
536 typename enable_if<
537 _CheckArrayPointerConversion<_Pp>::value
538 >::type
539 reset(_Pp __p) _NOEXCEPT {
540 pointer __tmp = __ptr_.first();
541 __ptr_.first() = __p;
542 if (__tmp)
543 __ptr_.second()(__tmp);
544 }
545
546 _LIBCPP_INLINE_VISIBILITY
547 void reset(nullptr_t = nullptr) _NOEXCEPT {
548 pointer __tmp = __ptr_.first();
549 __ptr_.first() = nullptr;
550 if (__tmp)
551 __ptr_.second()(__tmp);
552 }
553
554 _LIBCPP_INLINE_VISIBILITY
555 void swap(unique_ptr& __u) _NOEXCEPT {
556 __ptr_.swap(__u.__ptr_);
557 }
558
559};
560
561template <class _Tp, class _Dp>
562inline _LIBCPP_INLINE_VISIBILITY
563typename enable_if<
564 __is_swappable<_Dp>::value,
565 void
566>::type
567swap(unique_ptr<_Tp, _Dp>& __x, unique_ptr<_Tp, _Dp>& __y) _NOEXCEPT {__x.swap(__y);}
568
569template <class _T1, class _D1, class _T2, class _D2>
570inline _LIBCPP_INLINE_VISIBILITY
571bool
572operator==(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return __x.get() == __y.get();}
573
574template <class _T1, class _D1, class _T2, class _D2>
575inline _LIBCPP_INLINE_VISIBILITY
576bool
577operator!=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return !(__x == __y);}
578
579template <class _T1, class _D1, class _T2, class _D2>
580inline _LIBCPP_INLINE_VISIBILITY
581bool
582operator< (const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y)
583{
584 typedef typename unique_ptr<_T1, _D1>::pointer _P1;
585 typedef typename unique_ptr<_T2, _D2>::pointer _P2;
586 typedef typename common_type<_P1, _P2>::type _Vp;
587 return less<_Vp>()(__x.get(), __y.get());
588}
589
590template <class _T1, class _D1, class _T2, class _D2>
591inline _LIBCPP_INLINE_VISIBILITY
592bool
593operator> (const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return __y < __x;}
594
595template <class _T1, class _D1, class _T2, class _D2>
596inline _LIBCPP_INLINE_VISIBILITY
597bool
598operator<=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return !(__y < __x);}
599
600template <class _T1, class _D1, class _T2, class _D2>
601inline _LIBCPP_INLINE_VISIBILITY
602bool
603operator>=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return !(__x < __y);}
604
605template <class _T1, class _D1>
606inline _LIBCPP_INLINE_VISIBILITY
607bool
608operator==(const unique_ptr<_T1, _D1>& __x, nullptr_t) _NOEXCEPT
609{
610 return !__x;
611}
612
613template <class _T1, class _D1>
614inline _LIBCPP_INLINE_VISIBILITY
615bool
616operator==(nullptr_t, const unique_ptr<_T1, _D1>& __x) _NOEXCEPT
617{
618 return !__x;
619}
620
621template <class _T1, class _D1>
622inline _LIBCPP_INLINE_VISIBILITY
623bool
624operator!=(const unique_ptr<_T1, _D1>& __x, nullptr_t) _NOEXCEPT
625{
626 return static_cast<bool>(__x);
627}
628
629template <class _T1, class _D1>
630inline _LIBCPP_INLINE_VISIBILITY
631bool
632operator!=(nullptr_t, const unique_ptr<_T1, _D1>& __x) _NOEXCEPT
633{
634 return static_cast<bool>(__x);
635}
636
637template <class _T1, class _D1>
638inline _LIBCPP_INLINE_VISIBILITY
639bool
640operator<(const unique_ptr<_T1, _D1>& __x, nullptr_t)
641{
642 typedef typename unique_ptr<_T1, _D1>::pointer _P1;
643 return less<_P1>()(__x.get(), nullptr);
644}
645
646template <class _T1, class _D1>
647inline _LIBCPP_INLINE_VISIBILITY
648bool
649operator<(nullptr_t, const unique_ptr<_T1, _D1>& __x)
650{
651 typedef typename unique_ptr<_T1, _D1>::pointer _P1;
652 return less<_P1>()(nullptr, __x.get());
653}
654
655template <class _T1, class _D1>
656inline _LIBCPP_INLINE_VISIBILITY
657bool
658operator>(const unique_ptr<_T1, _D1>& __x, nullptr_t)
659{
660 return nullptr < __x;
661}
662
663template <class _T1, class _D1>
664inline _LIBCPP_INLINE_VISIBILITY
665bool
666operator>(nullptr_t, const unique_ptr<_T1, _D1>& __x)
667{
668 return __x < nullptr;
669}
670
671template <class _T1, class _D1>
672inline _LIBCPP_INLINE_VISIBILITY
673bool
674operator<=(const unique_ptr<_T1, _D1>& __x, nullptr_t)
675{
676 return !(nullptr < __x);
677}
678
679template <class _T1, class _D1>
680inline _LIBCPP_INLINE_VISIBILITY
681bool
682operator<=(nullptr_t, const unique_ptr<_T1, _D1>& __x)
683{
684 return !(__x < nullptr);
685}
686
687template <class _T1, class _D1>
688inline _LIBCPP_INLINE_VISIBILITY
689bool
690operator>=(const unique_ptr<_T1, _D1>& __x, nullptr_t)
691{
692 return !(__x < nullptr);
693}
694
695template <class _T1, class _D1>
696inline _LIBCPP_INLINE_VISIBILITY
697bool
698operator>=(nullptr_t, const unique_ptr<_T1, _D1>& __x)
699{
700 return !(nullptr < __x);
701}
702
703#if _LIBCPP_STD_VER > 11
704
705template<class _Tp>
706struct __unique_if
707{
708 typedef unique_ptr<_Tp> __unique_single;
709};
710
711template<class _Tp>
712struct __unique_if<_Tp[]>
713{
714 typedef unique_ptr<_Tp[]> __unique_array_unknown_bound;
715};
716
717template<class _Tp, size_t _Np>
718struct __unique_if<_Tp[_Np]>
719{
720 typedef void __unique_array_known_bound;
721};
722
723template<class _Tp, class... _Args>
724inline _LIBCPP_INLINE_VISIBILITY
725typename __unique_if<_Tp>::__unique_single
726make_unique(_Args&&... __args)
727{
728 return unique_ptr<_Tp>(new _Tp(_VSTD::forward<_Args>(__args)...));
729}
730
731template<class _Tp>
732inline _LIBCPP_INLINE_VISIBILITY
733typename __unique_if<_Tp>::__unique_array_unknown_bound
734make_unique(size_t __n)
735{
736 typedef typename remove_extent<_Tp>::type _Up;
737 return unique_ptr<_Tp>(new _Up[__n]());
738}
739
740template<class _Tp, class... _Args>
741 typename __unique_if<_Tp>::__unique_array_known_bound
742 make_unique(_Args&&...) = delete;
743
744#endif // _LIBCPP_STD_VER > 11
745
746template <class _Tp> struct _LIBCPP_TEMPLATE_VIS hash;
747
748template <class _Tp, class _Dp>
749#ifdef _LIBCPP_CXX03_LANG
750struct _LIBCPP_TEMPLATE_VIS hash<unique_ptr<_Tp, _Dp> >
751#else
752struct _LIBCPP_TEMPLATE_VIS hash<__enable_hash_helper<
753 unique_ptr<_Tp, _Dp>, typename unique_ptr<_Tp, _Dp>::pointer> >
754#endif
755{
756#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
757 _LIBCPP_DEPRECATED_IN_CXX17 typedef unique_ptr<_Tp, _Dp> argument_type;
758 _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
759#endif
760
761 _LIBCPP_INLINE_VISIBILITY
762 size_t operator()(const unique_ptr<_Tp, _Dp>& __ptr) const
763 {
764 typedef typename unique_ptr<_Tp, _Dp>::pointer pointer;
765 return hash<pointer>()(__ptr.get());
766 }
767};
768
769_LIBCPP_END_NAMESPACE_STD
770
771_LIBCPP_POP_MACROS
772
773#endif // _LIBCPP___MEMORY_UNIQUE_PTR_H
lib/libcxx/include/__memory/uses_allocator.h created+60
......@@ -0,0 +1,60 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___MEMORY_USES_ALLOCATOR_H
11#define _LIBCPP___MEMORY_USES_ALLOCATOR_H
12
13#include <__config>
14#include <cstddef>
15#include <type_traits>
16
17#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
18#pragma GCC system_header
19#endif
20
21_LIBCPP_BEGIN_NAMESPACE_STD
22
23template <class _Tp>
24struct __has_allocator_type
25{
26private:
27 struct __two {char __lx; char __lxx;};
28 template <class _Up> static __two __test(...);
29 template <class _Up> static char __test(typename _Up::allocator_type* = 0);
30public:
31 static const bool value = sizeof(__test<_Tp>(0)) == 1;
32};
33
34template <class _Tp, class _Alloc, bool = __has_allocator_type<_Tp>::value>
35struct __uses_allocator
36 : public integral_constant<bool,
37 is_convertible<_Alloc, typename _Tp::allocator_type>::value>
38{
39};
40
41template <class _Tp, class _Alloc>
42struct __uses_allocator<_Tp, _Alloc, false>
43 : public false_type
44{
45};
46
47template <class _Tp, class _Alloc>
48struct _LIBCPP_TEMPLATE_VIS uses_allocator
49 : public __uses_allocator<_Tp, _Alloc>
50{
51};
52
53#if _LIBCPP_STD_VER > 14
54template <class _Tp, class _Alloc>
55_LIBCPP_INLINE_VAR constexpr size_t uses_allocator_v = uses_allocator<_Tp, _Alloc>::value;
56#endif
57
58_LIBCPP_END_NAMESPACE_STD
59
60#endif // _LIBCPP___MEMORY_USES_ALLOCATOR_H
lib/libcxx/include/__memory/utilities.h deleted-88
......@@ -1,88 +0,0 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___MEMORY_UTILITIES_H
11#define _LIBCPP___MEMORY_UTILITIES_H
12
13#include <__config>
14#include <__memory/allocator_traits.h>
15#include <cstddef>
16
17#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
18#pragma GCC system_header
19#endif
20
21_LIBCPP_PUSH_MACROS
22#include <__undef_macros>
23
24
25_LIBCPP_BEGIN_NAMESPACE_STD
26
27// Helper class to allocate memory using an Allocator in an exception safe
28// manner.
29//
30// The intended usage of this class is as follows:
31//
32// 0
33// 1 __allocation_guard<SomeAllocator> guard(alloc, 10);
34// 2 do_some_initialization_that_may_throw(guard.__get());
35// 3 save_allocated_pointer_in_a_noexcept_operation(guard.__release_ptr());
36// 4
37//
38// If line (2) throws an exception during initialization of the memory, the
39// guard's destructor will be called, and the memory will be released using
40// Allocator deallocation. Otherwise, we release the memory from the guard on
41// line (3) in an operation that can't throw -- after that, the guard is not
42// responsible for the memory anymore.
43//
44// This is similar to a unique_ptr, except it's easier to use with a
45// custom allocator.
46template<class _Alloc>
47struct __allocation_guard {
48 using _Pointer = typename allocator_traits<_Alloc>::pointer;
49 using _Size = typename allocator_traits<_Alloc>::size_type;
50
51 template<class _AllocT> // we perform the allocator conversion inside the constructor
52 _LIBCPP_HIDE_FROM_ABI
53 explicit __allocation_guard(_AllocT __alloc, _Size __n)
54 : __alloc_(_VSTD::move(__alloc))
55 , __n_(__n)
56 , __ptr_(allocator_traits<_Alloc>::allocate(__alloc_, __n_)) // initialization order is important
57 { }
58
59 _LIBCPP_HIDE_FROM_ABI
60 ~__allocation_guard() _NOEXCEPT {
61 if (__ptr_ != nullptr) {
62 allocator_traits<_Alloc>::deallocate(__alloc_, __ptr_, __n_);
63 }
64 }
65
66 _LIBCPP_HIDE_FROM_ABI
67 _Pointer __release_ptr() _NOEXCEPT { // not called __release() because it's a keyword in objective-c++
68 _Pointer __tmp = __ptr_;
69 __ptr_ = nullptr;
70 return __tmp;
71 }
72
73 _LIBCPP_HIDE_FROM_ABI
74 _Pointer __get() const _NOEXCEPT {
75 return __ptr_;
76 }
77
78private:
79 _Alloc __alloc_;
80 _Size __n_;
81 _Pointer __ptr_;
82};
83
84_LIBCPP_END_NAMESPACE_STD
85
86_LIBCPP_POP_MACROS
87
88#endif // _LIBCPP___MEMORY_UTILITIES_H
lib/libcxx/include/__mutex_base+3-5
......@@ -11,10 +11,9 @@
1111#define _LIBCPP___MUTEX_BASE
1212
1313#include <__config>
14#include <__threading_support>
1415#include <chrono>
1516#include <system_error>
16#include <__threading_support>
17
1817#include <time.h>
1918
2019#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
......@@ -190,8 +189,7 @@ public:
190189 _LIBCPP_INLINE_VISIBILITY
191190 bool owns_lock() const _NOEXCEPT {return __owns_;}
192191 _LIBCPP_INLINE_VISIBILITY
193 _LIBCPP_EXPLICIT
194 operator bool () const _NOEXCEPT {return __owns_;}
192 explicit operator bool() const _NOEXCEPT {return __owns_;}
195193 _LIBCPP_INLINE_VISIBILITY
196194 mutex_type* mutex() const _NOEXCEPT {return __m_;}
197195};
......@@ -526,4 +524,4 @@ _LIBCPP_END_NAMESPACE_STD
526524
527525_LIBCPP_POP_MACROS
528526
529#endif // _LIBCPP___MUTEX_BASE
527#endif // _LIBCPP___MUTEX_BASE
lib/libcxx/include/__node_handle+2-1
......@@ -11,6 +11,7 @@
1111#define _LIBCPP___NODE_HANDLE
1212
1313#include <__config>
14#include <__debug>
1415#include <memory>
1516#include <optional>
1617
......@@ -205,4 +206,4 @@ struct _LIBCPP_TEMPLATE_VIS __insert_return_type
205206_LIBCPP_END_NAMESPACE_STD
206207_LIBCPP_POP_MACROS
207208
208#endif
209#endif // _LIBCPP___NODE_HANDLE
lib/libcxx/include/__nullptr+2-2
......@@ -56,6 +56,6 @@ namespace std
5656 typedef decltype(nullptr) nullptr_t;
5757}
5858
59#endif // _LIBCPP_HAS_NO_NULLPTR
59#endif // _LIBCPP_HAS_NO_NULLPTR
6060
61#endif // _LIBCPP_NULLPTR
61#endif // _LIBCPP_NULLPTR
lib/libcxx/include/__random/uniform_int_distribution.h created+316
......@@ -0,0 +1,316 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___RANDOM_UNIFORM_INT_DISTRIBUTION_H
10#define _LIBCPP___RANDOM_UNIFORM_INT_DISTRIBUTION_H
11
12#include <__bits>
13#include <__config>
14#include <cstddef>
15#include <cstdint>
16#include <iosfwd>
17#include <limits>
18#include <type_traits>
19
20#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
21#pragma GCC system_header
22#endif
23
24_LIBCPP_PUSH_MACROS
25#include <__undef_macros>
26
27_LIBCPP_BEGIN_NAMESPACE_STD
28
29// __independent_bits_engine
30
31template <unsigned long long _Xp, size_t _Rp>
32struct __log2_imp
33{
34 static const size_t value = _Xp & ((unsigned long long)(1) << _Rp) ? _Rp
35 : __log2_imp<_Xp, _Rp - 1>::value;
36};
37
38template <unsigned long long _Xp>
39struct __log2_imp<_Xp, 0>
40{
41 static const size_t value = 0;
42};
43
44template <size_t _Rp>
45struct __log2_imp<0, _Rp>
46{
47 static const size_t value = _Rp + 1;
48};
49
50template <class _UIntType, _UIntType _Xp>
51struct __log2
52{
53 static const size_t value = __log2_imp<_Xp,
54 sizeof(_UIntType) * __CHAR_BIT__ - 1>::value;
55};
56
57template<class _Engine, class _UIntType>
58class __independent_bits_engine
59{
60public:
61 // types
62 typedef _UIntType result_type;
63
64private:
65 typedef typename _Engine::result_type _Engine_result_type;
66 typedef typename conditional
67 <
68 sizeof(_Engine_result_type) <= sizeof(result_type),
69 result_type,
70 _Engine_result_type
71 >::type _Working_result_type;
72
73 _Engine& __e_;
74 size_t __w_;
75 size_t __w0_;
76 size_t __n_;
77 size_t __n0_;
78 _Working_result_type __y0_;
79 _Working_result_type __y1_;
80 _Engine_result_type __mask0_;
81 _Engine_result_type __mask1_;
82
83#ifdef _LIBCPP_CXX03_LANG
84 static const _Working_result_type _Rp = _Engine::_Max - _Engine::_Min
85 + _Working_result_type(1);
86#else
87 static _LIBCPP_CONSTEXPR const _Working_result_type _Rp = _Engine::max() - _Engine::min()
88 + _Working_result_type(1);
89#endif
90 static _LIBCPP_CONSTEXPR const size_t __m = __log2<_Working_result_type, _Rp>::value;
91 static _LIBCPP_CONSTEXPR const size_t _WDt = numeric_limits<_Working_result_type>::digits;
92 static _LIBCPP_CONSTEXPR const size_t _EDt = numeric_limits<_Engine_result_type>::digits;
93
94public:
95 // constructors and seeding functions
96 __independent_bits_engine(_Engine& __e, size_t __w);
97
98 // generating functions
99 result_type operator()() {return __eval(integral_constant<bool, _Rp != 0>());}
100
101private:
102 result_type __eval(false_type);
103 result_type __eval(true_type);
104};
105
106template<class _Engine, class _UIntType>
107__independent_bits_engine<_Engine, _UIntType>
108 ::__independent_bits_engine(_Engine& __e, size_t __w)
109 : __e_(__e),
110 __w_(__w)
111{
112 __n_ = __w_ / __m + (__w_ % __m != 0);
113 __w0_ = __w_ / __n_;
114 if (_Rp == 0)
115 __y0_ = _Rp;
116 else if (__w0_ < _WDt)
117 __y0_ = (_Rp >> __w0_) << __w0_;
118 else
119 __y0_ = 0;
120 if (_Rp - __y0_ > __y0_ / __n_)
121 {
122 ++__n_;
123 __w0_ = __w_ / __n_;
124 if (__w0_ < _WDt)
125 __y0_ = (_Rp >> __w0_) << __w0_;
126 else
127 __y0_ = 0;
128 }
129 __n0_ = __n_ - __w_ % __n_;
130 if (__w0_ < _WDt - 1)
131 __y1_ = (_Rp >> (__w0_ + 1)) << (__w0_ + 1);
132 else
133 __y1_ = 0;
134 __mask0_ = __w0_ > 0 ? _Engine_result_type(~0) >> (_EDt - __w0_) :
135 _Engine_result_type(0);
136 __mask1_ = __w0_ < _EDt - 1 ?
137 _Engine_result_type(~0) >> (_EDt - (__w0_ + 1)) :
138 _Engine_result_type(~0);
139}
140
141template<class _Engine, class _UIntType>
142inline
143_UIntType
144__independent_bits_engine<_Engine, _UIntType>::__eval(false_type)
145{
146 return static_cast<result_type>(__e_() & __mask0_);
147}
148
149template<class _Engine, class _UIntType>
150_UIntType
151__independent_bits_engine<_Engine, _UIntType>::__eval(true_type)
152{
153 const size_t _WRt = numeric_limits<result_type>::digits;
154 result_type _Sp = 0;
155 for (size_t __k = 0; __k < __n0_; ++__k)
156 {
157 _Engine_result_type __u;
158 do
159 {
160 __u = __e_() - _Engine::min();
161 } while (__u >= __y0_);
162 if (__w0_ < _WRt)
163 _Sp <<= __w0_;
164 else
165 _Sp = 0;
166 _Sp += __u & __mask0_;
167 }
168 for (size_t __k = __n0_; __k < __n_; ++__k)
169 {
170 _Engine_result_type __u;
171 do
172 {
173 __u = __e_() - _Engine::min();
174 } while (__u >= __y1_);
175 if (__w0_ < _WRt - 1)
176 _Sp <<= __w0_ + 1;
177 else
178 _Sp = 0;
179 _Sp += __u & __mask1_;
180 }
181 return _Sp;
182}
183
184template<class _IntType = int>
185class uniform_int_distribution
186{
187public:
188 // types
189 typedef _IntType result_type;
190
191 class param_type
192 {
193 result_type __a_;
194 result_type __b_;
195 public:
196 typedef uniform_int_distribution distribution_type;
197
198 explicit param_type(result_type __a = 0,
199 result_type __b = numeric_limits<result_type>::max())
200 : __a_(__a), __b_(__b) {}
201
202 result_type a() const {return __a_;}
203 result_type b() const {return __b_;}
204
205 friend bool operator==(const param_type& __x, const param_type& __y)
206 {return __x.__a_ == __y.__a_ && __x.__b_ == __y.__b_;}
207 friend bool operator!=(const param_type& __x, const param_type& __y)
208 {return !(__x == __y);}
209 };
210
211private:
212 param_type __p_;
213
214public:
215 // constructors and reset functions
216#ifndef _LIBCPP_CXX03_LANG
217 uniform_int_distribution() : uniform_int_distribution(0) {}
218 explicit uniform_int_distribution(
219 result_type __a, result_type __b = numeric_limits<result_type>::max())
220 : __p_(param_type(__a, __b)) {}
221#else
222 explicit uniform_int_distribution(
223 result_type __a = 0,
224 result_type __b = numeric_limits<result_type>::max())
225 : __p_(param_type(__a, __b)) {}
226#endif
227 explicit uniform_int_distribution(const param_type& __p) : __p_(__p) {}
228 void reset() {}
229
230 // generating functions
231 template<class _URNG> result_type operator()(_URNG& __g)
232 {return (*this)(__g, __p_);}
233 template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);
234
235 // property functions
236 result_type a() const {return __p_.a();}
237 result_type b() const {return __p_.b();}
238
239 param_type param() const {return __p_;}
240 void param(const param_type& __p) {__p_ = __p;}
241
242 result_type min() const {return a();}
243 result_type max() const {return b();}
244
245 friend bool operator==(const uniform_int_distribution& __x,
246 const uniform_int_distribution& __y)
247 {return __x.__p_ == __y.__p_;}
248 friend bool operator!=(const uniform_int_distribution& __x,
249 const uniform_int_distribution& __y)
250 {return !(__x == __y);}
251};
252
253template<class _IntType>
254template<class _URNG>
255typename uniform_int_distribution<_IntType>::result_type
256uniform_int_distribution<_IntType>::operator()(_URNG& __g, const param_type& __p)
257_LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
258{
259 typedef typename conditional<sizeof(result_type) <= sizeof(uint32_t),
260 uint32_t, uint64_t>::type _UIntType;
261 const _UIntType _Rp = _UIntType(__p.b()) - _UIntType(__p.a()) + _UIntType(1);
262 if (_Rp == 1)
263 return __p.a();
264 const size_t _Dt = numeric_limits<_UIntType>::digits;
265 typedef __independent_bits_engine<_URNG, _UIntType> _Eng;
266 if (_Rp == 0)
267 return static_cast<result_type>(_Eng(__g, _Dt)());
268 size_t __w = _Dt - __libcpp_clz(_Rp) - 1;
269 if ((_Rp & (numeric_limits<_UIntType>::max() >> (_Dt - __w))) != 0)
270 ++__w;
271 _Eng __e(__g, __w);
272 _UIntType __u;
273 do
274 {
275 __u = __e();
276 } while (__u >= _Rp);
277 return static_cast<result_type>(__u + __p.a());
278}
279
280template <class _CharT, class _Traits, class _IT>
281basic_ostream<_CharT, _Traits>&
282operator<<(basic_ostream<_CharT, _Traits>& __os,
283 const uniform_int_distribution<_IT>& __x)
284{
285 __save_flags<_CharT, _Traits> __lx(__os);
286 typedef basic_ostream<_CharT, _Traits> _Ostream;
287 __os.flags(_Ostream::dec | _Ostream::left);
288 _CharT __sp = __os.widen(' ');
289 __os.fill(__sp);
290 return __os << __x.a() << __sp << __x.b();
291}
292
293template <class _CharT, class _Traits, class _IT>
294basic_istream<_CharT, _Traits>&
295operator>>(basic_istream<_CharT, _Traits>& __is,
296 uniform_int_distribution<_IT>& __x)
297{
298 typedef uniform_int_distribution<_IT> _Eng;
299 typedef typename _Eng::result_type result_type;
300 typedef typename _Eng::param_type param_type;
301 __save_flags<_CharT, _Traits> __lx(__is);
302 typedef basic_istream<_CharT, _Traits> _Istream;
303 __is.flags(_Istream::dec | _Istream::skipws);
304 result_type __a;
305 result_type __b;
306 __is >> __a >> __b;
307 if (!__is.fail())
308 __x.param(param_type(__a, __b));
309 return __is;
310}
311
312_LIBCPP_END_NAMESPACE_STD
313
314_LIBCPP_POP_MACROS
315
316#endif // _LIBCPP___RANDOM_UNIFORM_INT_DISTRIBUTION_H
lib/libcxx/include/__ranges/access.h created+222
......@@ -0,0 +1,222 @@
1// -*- C++ -*-
2//===------------------------ __ranges/access.h ---------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9#ifndef _LIBCPP___RANGES_ACCESS_H
10#define _LIBCPP___RANGES_ACCESS_H
11
12#include <__config>
13#include <__iterator/concepts.h>
14#include <__iterator/readable_traits.h>
15#include <__ranges/enable_borrowed_range.h>
16#include <__utility/__decay_copy.h>
17#include <__utility/forward.h>
18#include <concepts>
19#include <type_traits>
20
21#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
22#pragma GCC system_header
23#endif
24
25_LIBCPP_PUSH_MACROS
26#include <__undef_macros>
27
28_LIBCPP_BEGIN_NAMESPACE_STD
29
30#if !defined(_LIBCPP_HAS_NO_RANGES)
31
32// clang-format off
33
34namespace ranges {
35 template <class _Tp>
36 concept __can_borrow =
37 is_lvalue_reference_v<_Tp> || enable_borrowed_range<remove_cvref_t<_Tp> >;
38
39 template<class _Tp>
40 concept __is_complete = requires { sizeof(_Tp); };
41} // namespace ranges
42
43// [range.access.begin]
44namespace ranges::__begin {
45 template <class _Tp>
46 concept __member_begin =
47 __can_borrow<_Tp> &&
48 requires(_Tp&& __t) {
49 { _VSTD::__decay_copy(__t.begin()) } -> input_or_output_iterator;
50 };
51
52 void begin(auto&) = delete;
53 void begin(const auto&) = delete;
54
55 template <class _Tp>
56 concept __unqualified_begin =
57 !__member_begin<_Tp> &&
58 __can_borrow<_Tp> &&
59 __class_or_enum<remove_cvref_t<_Tp> > &&
60 requires(_Tp && __t) {
61 { _VSTD::__decay_copy(begin(__t)) } -> input_or_output_iterator;
62 };
63
64 struct __fn {
65 template <class _Tp>
66 requires is_array_v<remove_cv_t<_Tp>>
67 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp& __t) const noexcept {
68 constexpr bool __complete = __is_complete<iter_value_t<_Tp> >;
69 if constexpr (__complete) { // used to disable cryptic diagnostic
70 return __t + 0;
71 }
72 else {
73 static_assert(__complete, "`std::ranges::begin` is SFINAE-unfriendly on arrays of an incomplete type.");
74 }
75 }
76
77 template <class _Tp>
78 requires __member_begin<_Tp>
79 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
80 noexcept(noexcept(_VSTD::__decay_copy(__t.begin())))
81 {
82 return __t.begin();
83 }
84
85 template <class _Tp>
86 requires __unqualified_begin<_Tp>
87 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
88 noexcept(noexcept(_VSTD::__decay_copy(begin(__t))))
89 {
90 return begin(__t);
91 }
92
93 void operator()(auto&&) const = delete;
94 };
95} // namespace ranges::__begin
96
97namespace ranges {
98 inline namespace __cpo {
99 inline constexpr auto begin = __begin::__fn{};
100 } // namespace __cpo
101
102 template <class _Tp>
103 using iterator_t = decltype(ranges::begin(declval<_Tp&>()));
104} // namespace ranges
105
106// [range.access.end]
107namespace ranges::__end {
108 template <class _Tp>
109 concept __member_end =
110 __can_borrow<_Tp> &&
111 requires(_Tp&& __t) {
112 typename iterator_t<_Tp>;
113 { _VSTD::__decay_copy(_VSTD::forward<_Tp>(__t).end()) } -> sentinel_for<iterator_t<_Tp> >;
114 };
115
116 void end(auto&) = delete;
117 void end(const auto&) = delete;
118
119 template <class _Tp>
120 concept __unqualified_end =
121 !__member_end<_Tp> &&
122 __can_borrow<_Tp> &&
123 __class_or_enum<remove_cvref_t<_Tp> > &&
124 requires(_Tp && __t) {
125 typename iterator_t<_Tp>;
126 { _VSTD::__decay_copy(end(_VSTD::forward<_Tp>(__t))) } -> sentinel_for<iterator_t<_Tp> >;
127 };
128
129 class __fn {
130 public:
131 template <class _Tp, size_t _Np>
132 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp (&__t)[_Np]) const noexcept {
133 constexpr bool __complete = __is_complete<remove_cv_t<_Tp> >;
134 if constexpr (__complete) { // used to disable cryptic diagnostic
135 return __t + _Np;
136 }
137 else {
138 static_assert(__complete, "`std::ranges::end` is SFINAE-unfriendly on arrays of an incomplete type.");
139 }
140 }
141
142 template <class _Tp>
143 requires __member_end<_Tp>
144 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
145 noexcept(noexcept(_VSTD::__decay_copy(__t.end())))
146 {
147 return _VSTD::forward<_Tp>(__t).end();
148 }
149
150 template <class _Tp>
151 requires __unqualified_end<_Tp>
152 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
153 noexcept(noexcept(_VSTD::__decay_copy(end(__t))))
154 {
155 return end(__t);
156 }
157
158 void operator()(auto&&) const = delete;
159 };
160} // namespace ranges::__end
161
162namespace ranges::inline __cpo {
163 inline constexpr auto end = __end::__fn{};
164} // namespace ranges::__cpo
165
166namespace ranges::__cbegin {
167 struct __fn {
168 template <class _Tp>
169 requires invocable<decltype(ranges::begin), _Tp const&>
170 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp& __t) const
171 noexcept(noexcept(ranges::begin(_VSTD::as_const(__t))))
172 {
173 return ranges::begin(_VSTD::as_const(__t));
174 }
175
176 template <class _Tp>
177 requires is_rvalue_reference_v<_Tp> && invocable<decltype(ranges::begin), _Tp const&&>
178 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
179 noexcept(noexcept(ranges::begin(static_cast<_Tp const&&>(__t))))
180 {
181 return ranges::begin(static_cast<_Tp const&&>(__t));
182 }
183 };
184} // namespace ranges::__cbegin
185
186namespace ranges::inline __cpo {
187 inline constexpr auto cbegin = __cbegin::__fn{};
188} // namespace ranges::__cpo
189
190namespace ranges::__cend {
191 struct __fn {
192 template <class _Tp>
193 requires invocable<decltype(ranges::end), _Tp const&>
194 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp& __t) const
195 noexcept(noexcept(ranges::end(_VSTD::as_const(__t))))
196 {
197 return ranges::end(_VSTD::as_const(__t));
198 }
199
200 template <class _Tp>
201 requires is_rvalue_reference_v<_Tp> && invocable<decltype(ranges::end), _Tp const&&>
202 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
203 noexcept(noexcept(ranges::end(static_cast<_Tp const&&>(__t))))
204 {
205 return ranges::end(static_cast<_Tp const&&>(__t));
206 }
207 };
208} // namespace ranges::__cend
209
210namespace ranges::inline __cpo {
211 inline constexpr auto cend = __cend::__fn{};
212} // namespace ranges::__cpo
213
214// clang-format off
215
216#endif // !defined(_LIBCPP_HAS_NO_RANGES)
217
218_LIBCPP_END_NAMESPACE_STD
219
220_LIBCPP_POP_MACROS
221
222#endif // _LIBCPP___RANGES_ACCESS_H
lib/libcxx/include/__ranges/all.h created+86
......@@ -0,0 +1,86 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9#ifndef _LIBCPP___RANGES_ALL_H
10#define _LIBCPP___RANGES_ALL_H
11
12#include <__config>
13#include <__iterator/concepts.h>
14#include <__iterator/iterator_traits.h>
15#include <__ranges/access.h>
16#include <__ranges/concepts.h>
17#include <__ranges/ref_view.h>
18#include <__ranges/subrange.h>
19#include <__utility/__decay_copy.h>
20#include <__utility/declval.h>
21#include <__utility/forward.h>
22#include <type_traits>
23
24#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
25#pragma GCC system_header
26#endif
27
28_LIBCPP_PUSH_MACROS
29#include <__undef_macros>
30
31_LIBCPP_BEGIN_NAMESPACE_STD
32
33#if !defined(_LIBCPP_HAS_NO_RANGES)
34
35namespace views {
36
37namespace __all {
38 struct __fn {
39 template<class _Tp>
40 requires ranges::view<decay_t<_Tp>>
41 _LIBCPP_HIDE_FROM_ABI
42 constexpr auto operator()(_Tp&& __t) const
43 noexcept(noexcept(_VSTD::__decay_copy(_VSTD::forward<_Tp>(__t))))
44 {
45 return _VSTD::forward<_Tp>(__t);
46 }
47
48 template<class _Tp>
49 requires (!ranges::view<decay_t<_Tp>>) &&
50 requires (_Tp&& __t) { ranges::ref_view{_VSTD::forward<_Tp>(__t)}; }
51 _LIBCPP_HIDE_FROM_ABI
52 constexpr auto operator()(_Tp&& __t) const
53 noexcept(noexcept(ranges::ref_view{_VSTD::forward<_Tp>(__t)}))
54 {
55 return ranges::ref_view{_VSTD::forward<_Tp>(__t)};
56 }
57
58 template<class _Tp>
59 requires (!ranges::view<decay_t<_Tp>> &&
60 !requires (_Tp&& __t) { ranges::ref_view{_VSTD::forward<_Tp>(__t)}; } &&
61 requires (_Tp&& __t) { ranges::subrange{_VSTD::forward<_Tp>(__t)}; })
62 _LIBCPP_HIDE_FROM_ABI
63 constexpr auto operator()(_Tp&& __t) const
64 noexcept(noexcept(ranges::subrange{_VSTD::forward<_Tp>(__t)}))
65 {
66 return ranges::subrange{_VSTD::forward<_Tp>(__t)};
67 }
68 };
69}
70
71inline namespace __cpo {
72 inline constexpr auto all = __all::__fn{};
73} // namespace __cpo
74
75template<ranges::viewable_range _Range>
76using all_t = decltype(views::all(declval<_Range>()));
77
78} // namespace views
79
80#endif // !defined(_LIBCPP_HAS_NO_RANGES)
81
82_LIBCPP_END_NAMESPACE_STD
83
84_LIBCPP_POP_MACROS
85
86#endif // _LIBCPP___RANGES_ALL_H
lib/libcxx/include/__ranges/common_view.h created+113
......@@ -0,0 +1,113 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9#ifndef _LIBCPP___RANGES_COMMON_VIEW_H
10#define _LIBCPP___RANGES_COMMON_VIEW_H
11
12#include <__config>
13#include <__iterator/common_iterator.h>
14#include <__iterator/iterator_traits.h>
15#include <__ranges/access.h>
16#include <__ranges/all.h>
17#include <__ranges/concepts.h>
18#include <__ranges/enable_borrowed_range.h>
19#include <__ranges/size.h>
20#include <__ranges/view_interface.h>
21#include <concepts>
22#include <type_traits>
23
24#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
25#pragma GCC system_header
26#endif
27
28_LIBCPP_PUSH_MACROS
29#include <__undef_macros>
30
31_LIBCPP_BEGIN_NAMESPACE_STD
32
33#if !defined(_LIBCPP_HAS_NO_RANGES)
34
35namespace ranges {
36
37template<view _View>
38 requires (!common_range<_View> && copyable<iterator_t<_View>>)
39class common_view : public view_interface<common_view<_View>> {
40 _View __base_ = _View();
41
42public:
43 _LIBCPP_HIDE_FROM_ABI
44 common_view() requires default_initializable<_View> = default;
45
46 _LIBCPP_HIDE_FROM_ABI
47 constexpr explicit common_view(_View __v) : __base_(_VSTD::move(__v)) { }
48
49 _LIBCPP_HIDE_FROM_ABI
50 constexpr _View base() const& requires copy_constructible<_View> { return __base_; }
51
52 _LIBCPP_HIDE_FROM_ABI
53 constexpr _View base() && { return _VSTD::move(__base_); }
54
55 _LIBCPP_HIDE_FROM_ABI
56 constexpr auto begin() {
57 if constexpr (random_access_range<_View> && sized_range<_View>)
58 return ranges::begin(__base_);
59 else
60 return common_iterator<iterator_t<_View>, sentinel_t<_View>>(ranges::begin(__base_));
61 }
62
63 _LIBCPP_HIDE_FROM_ABI
64 constexpr auto begin() const requires range<const _View> {
65 if constexpr (random_access_range<const _View> && sized_range<const _View>)
66 return ranges::begin(__base_);
67 else
68 return common_iterator<iterator_t<const _View>, sentinel_t<const _View>>(ranges::begin(__base_));
69 }
70
71 _LIBCPP_HIDE_FROM_ABI
72 constexpr auto end() {
73 if constexpr (random_access_range<_View> && sized_range<_View>)
74 return ranges::begin(__base_) + ranges::size(__base_);
75 else
76 return common_iterator<iterator_t<_View>, sentinel_t<_View>>(ranges::end(__base_));
77 }
78
79 _LIBCPP_HIDE_FROM_ABI
80 constexpr auto end() const requires range<const _View> {
81 if constexpr (random_access_range<const _View> && sized_range<const _View>)
82 return ranges::begin(__base_) + ranges::size(__base_);
83 else
84 return common_iterator<iterator_t<const _View>, sentinel_t<const _View>>(ranges::end(__base_));
85 }
86
87 _LIBCPP_HIDE_FROM_ABI
88 constexpr auto size() requires sized_range<_View> {
89 return ranges::size(__base_);
90 }
91
92 _LIBCPP_HIDE_FROM_ABI
93 constexpr auto size() const requires sized_range<const _View> {
94 return ranges::size(__base_);
95 }
96};
97
98template<class _Range>
99common_view(_Range&&)
100 -> common_view<views::all_t<_Range>>;
101
102template<class _View>
103inline constexpr bool enable_borrowed_range<common_view<_View>> = enable_borrowed_range<_View>;
104
105} // namespace ranges
106
107#endif // !defined(_LIBCPP_HAS_NO_RANGES)
108
109_LIBCPP_END_NAMESPACE_STD
110
111_LIBCPP_POP_MACROS
112
113#endif // _LIBCPP___RANGES_COMMON_VIEW_H
lib/libcxx/include/__ranges/concepts.h created+138
......@@ -0,0 +1,138 @@
1// -*- C++ -*-
2//===--------------------- __ranges/concepts.h ----------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9#ifndef _LIBCPP___RANGES_CONCEPTS_H
10#define _LIBCPP___RANGES_CONCEPTS_H
11
12#include <__config>
13#include <__iterator/concepts.h>
14#include <__iterator/incrementable_traits.h>
15#include <__iterator/iter_move.h>
16#include <__iterator/iterator_traits.h>
17#include <__iterator/readable_traits.h>
18#include <__ranges/access.h>
19#include <__ranges/enable_borrowed_range.h>
20#include <__ranges/data.h>
21#include <__ranges/enable_view.h>
22#include <__ranges/size.h>
23#include <concepts>
24#include <type_traits>
25
26#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
27#pragma GCC system_header
28#endif
29
30_LIBCPP_PUSH_MACROS
31#include <__undef_macros>
32
33_LIBCPP_BEGIN_NAMESPACE_STD
34
35// clang-format off
36
37#if !defined(_LIBCPP_HAS_NO_RANGES)
38
39namespace ranges {
40 // [range.range]
41 template <class _Tp>
42 concept range = requires(_Tp& __t) {
43 ranges::begin(__t); // sometimes equality-preserving
44 ranges::end(__t);
45 };
46
47 template<class _Range>
48 concept borrowed_range = range<_Range> &&
49 (is_lvalue_reference_v<_Range> || enable_borrowed_range<remove_cvref_t<_Range>>);
50
51 // `iterator_t` defined in <__ranges/access.h>
52
53 template <range _Rp>
54 using sentinel_t = decltype(ranges::end(declval<_Rp&>()));
55
56 template <range _Rp>
57 using range_difference_t = iter_difference_t<iterator_t<_Rp>>;
58
59 template <range _Rp>
60 using range_value_t = iter_value_t<iterator_t<_Rp>>;
61
62 template <range _Rp>
63 using range_reference_t = iter_reference_t<iterator_t<_Rp>>;
64
65 template <range _Rp>
66 using range_rvalue_reference_t = iter_rvalue_reference_t<iterator_t<_Rp>>;
67
68 // [range.sized]
69 template <class _Tp>
70 concept sized_range = range<_Tp> && requires(_Tp& __t) { ranges::size(__t); };
71
72 template<sized_range _Rp>
73 using range_size_t = decltype(ranges::size(declval<_Rp&>()));
74
75 // `disable_sized_range` defined in `<__ranges/size.h>`
76
77 // [range.view], views
78
79 // `enable_view` defined in <__ranges/enable_view.h>
80 // `view_base` defined in <__ranges/enable_view.h>
81
82 template <class _Tp>
83 concept view =
84 range<_Tp> &&
85 movable<_Tp> &&
86 enable_view<_Tp>;
87
88 template<class _Range>
89 concept __simple_view =
90 view<_Range> && range<const _Range> &&
91 same_as<iterator_t<_Range>, iterator_t<const _Range>> &&
92 same_as<sentinel_t<_Range>, iterator_t<const _Range>>;
93
94 // [range.refinements], other range refinements
95 template <class _Rp, class _Tp>
96 concept output_range = range<_Rp> && output_iterator<iterator_t<_Rp>, _Tp>;
97
98 template <class _Tp>
99 concept input_range = range<_Tp> && input_iterator<iterator_t<_Tp>>;
100
101 template <class _Tp>
102 concept forward_range = input_range<_Tp> && forward_iterator<iterator_t<_Tp>>;
103
104 template <class _Tp>
105 concept bidirectional_range = forward_range<_Tp> && bidirectional_iterator<iterator_t<_Tp>>;
106
107 template <class _Tp>
108 concept random_access_range =
109 bidirectional_range<_Tp> && random_access_iterator<iterator_t<_Tp>>;
110
111 template<class _Tp>
112 concept contiguous_range =
113 random_access_range<_Tp> &&
114 contiguous_iterator<iterator_t<_Tp>> &&
115 requires(_Tp& __t) {
116 { ranges::data(__t) } -> same_as<add_pointer_t<range_reference_t<_Tp>>>;
117 };
118
119 template <class _Tp>
120 concept common_range = range<_Tp> && same_as<iterator_t<_Tp>, sentinel_t<_Tp>>;
121
122 template<class _Tp>
123 concept viewable_range =
124 range<_Tp> && (
125 (view<remove_cvref_t<_Tp>> && constructible_from<remove_cvref_t<_Tp>, _Tp>) ||
126 (!view<remove_cvref_t<_Tp>> && borrowed_range<_Tp>)
127 );
128} // namespace ranges
129
130#endif // !defined(_LIBCPP_HAS_NO_RANGES)
131
132// clang-format on
133
134_LIBCPP_END_NAMESPACE_STD
135
136_LIBCPP_POP_MACROS
137
138#endif // _LIBCPP___RANGES_CONCEPTS_H
lib/libcxx/include/__ranges/copyable_box.h created+175
......@@ -0,0 +1,175 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___RANGES_COPYABLE_BOX_H
11#define _LIBCPP___RANGES_COPYABLE_BOX_H
12
13#include <__config>
14#include <__memory/addressof.h>
15#include <__memory/construct_at.h>
16#include <__utility/move.h>
17#include <concepts>
18#include <optional>
19#include <type_traits>
20
21#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
22#pragma GCC system_header
23#endif
24
25_LIBCPP_PUSH_MACROS
26#include <__undef_macros>
27
28_LIBCPP_BEGIN_NAMESPACE_STD
29
30#if !defined(_LIBCPP_HAS_NO_RANGES)
31
32// __copyable_box allows turning a type that is copy-constructible (but maybe not copy-assignable) into
33// a type that is both copy-constructible and copy-assignable. It does that by introducing an empty state
34// and basically doing destroy-then-copy-construct in the assignment operator. The empty state is necessary
35// to handle the case where the copy construction fails after destroying the object.
36//
37// In some cases, we can completely avoid the use of an empty state; we provide a specialization of
38// __copyable_box that does this, see below for the details.
39
40template<class _Tp>
41concept __copy_constructible_object = copy_constructible<_Tp> && is_object_v<_Tp>;
42
43namespace ranges {
44 // Primary template - uses std::optional and introduces an empty state in case assignment fails.
45 template<__copy_constructible_object _Tp>
46 class __copyable_box {
47 [[no_unique_address]] optional<_Tp> __val_;
48
49 public:
50 template<class ..._Args>
51 requires is_constructible_v<_Tp, _Args...>
52 _LIBCPP_HIDE_FROM_ABI
53 constexpr explicit __copyable_box(in_place_t, _Args&& ...__args)
54 noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
55 : __val_(in_place, _VSTD::forward<_Args>(__args)...)
56 { }
57
58 _LIBCPP_HIDE_FROM_ABI
59 constexpr __copyable_box() noexcept(is_nothrow_default_constructible_v<_Tp>)
60 requires default_initializable<_Tp>
61 : __val_(in_place)
62 { }
63
64 _LIBCPP_HIDE_FROM_ABI __copyable_box(__copyable_box const&) = default;
65 _LIBCPP_HIDE_FROM_ABI __copyable_box(__copyable_box&&) = default;
66
67 _LIBCPP_HIDE_FROM_ABI
68 constexpr __copyable_box& operator=(__copyable_box const& __other)
69 noexcept(is_nothrow_copy_constructible_v<_Tp>)
70 {
71 if (this != _VSTD::addressof(__other)) {
72 if (__other.__has_value()) __val_.emplace(*__other);
73 else __val_.reset();
74 }
75 return *this;
76 }
77
78 _LIBCPP_HIDE_FROM_ABI
79 __copyable_box& operator=(__copyable_box&&) requires movable<_Tp> = default;
80
81 _LIBCPP_HIDE_FROM_ABI
82 constexpr __copyable_box& operator=(__copyable_box&& __other)
83 noexcept(is_nothrow_move_constructible_v<_Tp>)
84 {
85 if (this != _VSTD::addressof(__other)) {
86 if (__other.__has_value()) __val_.emplace(_VSTD::move(*__other));
87 else __val_.reset();
88 }
89 return *this;
90 }
91
92 _LIBCPP_HIDE_FROM_ABI constexpr _Tp const& operator*() const noexcept { return *__val_; }
93 _LIBCPP_HIDE_FROM_ABI constexpr _Tp& operator*() noexcept { return *__val_; }
94 _LIBCPP_HIDE_FROM_ABI constexpr bool __has_value() const noexcept { return __val_.has_value(); }
95 };
96
97 // This partial specialization implements an optimization for when we know we don't need to store
98 // an empty state to represent failure to perform an assignment. For copy-assignment, this happens:
99 //
100 // 1. If the type is copyable (which includes copy-assignment), we can use the type's own assignment operator
101 // directly and avoid using std::optional.
102 // 2. If the type is not copyable, but it is nothrow-copy-constructible, then we can implement assignment as
103 // destroy-and-then-construct and we know it will never fail, so we don't need an empty state.
104 //
105 // The exact same reasoning can be applied for move-assignment, with copyable replaced by movable and
106 // nothrow-copy-constructible replaced by nothrow-move-constructible. This specialization is enabled
107 // whenever we can apply any of these optimizations for both the copy assignment and the move assignment
108 // operator.
109 template<class _Tp>
110 concept __doesnt_need_empty_state_for_copy = copyable<_Tp> || is_nothrow_copy_constructible_v<_Tp>;
111
112 template<class _Tp>
113 concept __doesnt_need_empty_state_for_move = movable<_Tp> || is_nothrow_move_constructible_v<_Tp>;
114
115 template<__copy_constructible_object _Tp>
116 requires __doesnt_need_empty_state_for_copy<_Tp> && __doesnt_need_empty_state_for_move<_Tp>
117 class __copyable_box<_Tp> {
118 [[no_unique_address]] _Tp __val_;
119
120 public:
121 template<class ..._Args>
122 requires is_constructible_v<_Tp, _Args...>
123 _LIBCPP_HIDE_FROM_ABI
124 constexpr explicit __copyable_box(in_place_t, _Args&& ...__args)
125 noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
126 : __val_(_VSTD::forward<_Args>(__args)...)
127 { }
128
129 _LIBCPP_HIDE_FROM_ABI
130 constexpr __copyable_box() noexcept(is_nothrow_default_constructible_v<_Tp>)
131 requires default_initializable<_Tp>
132 : __val_()
133 { }
134
135 _LIBCPP_HIDE_FROM_ABI __copyable_box(__copyable_box const&) = default;
136 _LIBCPP_HIDE_FROM_ABI __copyable_box(__copyable_box&&) = default;
137
138 // Implementation of assignment operators in case we perform optimization (1)
139 _LIBCPP_HIDE_FROM_ABI __copyable_box& operator=(__copyable_box const&) requires copyable<_Tp> = default;
140 _LIBCPP_HIDE_FROM_ABI __copyable_box& operator=(__copyable_box&&) requires movable<_Tp> = default;
141
142 // Implementation of assignment operators in case we perform optimization (2)
143 _LIBCPP_HIDE_FROM_ABI
144 constexpr __copyable_box& operator=(__copyable_box const& __other) noexcept {
145 static_assert(is_nothrow_copy_constructible_v<_Tp>);
146 if (this != _VSTD::addressof(__other)) {
147 _VSTD::destroy_at(_VSTD::addressof(__val_));
148 _VSTD::construct_at(_VSTD::addressof(__val_), __other.__val_);
149 }
150 return *this;
151 }
152
153 _LIBCPP_HIDE_FROM_ABI
154 constexpr __copyable_box& operator=(__copyable_box&& __other) noexcept {
155 static_assert(is_nothrow_move_constructible_v<_Tp>);
156 if (this != _VSTD::addressof(__other)) {
157 _VSTD::destroy_at(_VSTD::addressof(__val_));
158 _VSTD::construct_at(_VSTD::addressof(__val_), _VSTD::move(__other.__val_));
159 }
160 return *this;
161 }
162
163 _LIBCPP_HIDE_FROM_ABI constexpr _Tp const& operator*() const noexcept { return __val_; }
164 _LIBCPP_HIDE_FROM_ABI constexpr _Tp& operator*() noexcept { return __val_; }
165 _LIBCPP_HIDE_FROM_ABI constexpr bool __has_value() const noexcept { return true; }
166 };
167} // namespace ranges
168
169#endif // !defined(_LIBCPP_HAS_NO_RANGES)
170
171_LIBCPP_END_NAMESPACE_STD
172
173_LIBCPP_POP_MACROS
174
175#endif // _LIBCPP___RANGES_COPYABLE_BOX_H
lib/libcxx/include/__ranges/dangling.h created+47
......@@ -0,0 +1,47 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___RANGES_DANGLING_H
11#define _LIBCPP___RANGES_DANGLING_H
12
13#include <__config>
14#include <__ranges/access.h>
15#include <__ranges/concepts.h>
16#include <type_traits>
17
18#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
19#pragma GCC system_header
20#endif
21
22_LIBCPP_PUSH_MACROS
23#include <__undef_macros>
24
25_LIBCPP_BEGIN_NAMESPACE_STD
26
27#if !defined(_LIBCPP_HAS_NO_RANGES)
28
29namespace ranges {
30struct dangling {
31 dangling() = default;
32 _LIBCPP_HIDE_FROM_ABI constexpr dangling(auto&&...) noexcept {}
33};
34
35template <range _Rp>
36using borrowed_iterator_t = _If<borrowed_range<_Rp>, iterator_t<_Rp>, dangling>;
37
38// borrowed_subrange_t defined in <__ranges/subrange.h>
39} // namespace ranges
40
41#endif // !_LIBCPP_HAS_NO_RANGES
42
43_LIBCPP_END_NAMESPACE_STD
44
45_LIBCPP_POP_MACROS
46
47#endif // _LIBCPP___RANGES_DANGLING_H
lib/libcxx/include/__ranges/data.h created+86
......@@ -0,0 +1,86 @@
1// -*- C++ -*-
2//===------------------------ __ranges/data.h ------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9#ifndef _LIBCPP___RANGES_DATA_H
10#define _LIBCPP___RANGES_DATA_H
11
12#include <__config>
13#include <__iterator/concepts.h>
14#include <__iterator/iterator_traits.h>
15#include <__memory/pointer_traits.h>
16#include <__ranges/access.h>
17#include <__utility/forward.h>
18#include <concepts>
19#include <type_traits>
20
21#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
22#pragma GCC system_header
23#endif
24
25_LIBCPP_PUSH_MACROS
26#include <__undef_macros>
27
28_LIBCPP_BEGIN_NAMESPACE_STD
29
30#if !defined(_LIBCPP_HAS_NO_RANGES)
31
32// clang-format off
33namespace ranges {
34// [range.prim.data]
35namespace __data {
36 template <class _Tp>
37 concept __ptr_to_object = is_pointer_v<_Tp> && is_object_v<remove_pointer_t<_Tp>>;
38
39 template <class _Tp>
40 concept __member_data =
41 requires(_Tp&& __t) {
42 { _VSTD::forward<_Tp>(__t) } -> __can_borrow;
43 { __t.data() } -> __ptr_to_object;
44 };
45
46 template <class _Tp>
47 concept __ranges_begin_invocable =
48 !__member_data<_Tp> &&
49 requires(_Tp&& __t) {
50 { _VSTD::forward<_Tp>(__t) } -> __can_borrow;
51 { ranges::begin(_VSTD::forward<_Tp>(__t)) } -> contiguous_iterator;
52 };
53
54 struct __fn {
55 template <__member_data _Tp>
56 requires __can_borrow<_Tp>
57 _LIBCPP_HIDE_FROM_ABI
58 constexpr __ptr_to_object auto operator()(_Tp&& __t) const
59 noexcept(noexcept(__t.data())) {
60 return __t.data();
61 }
62
63 template<__ranges_begin_invocable _Tp>
64 requires __can_borrow<_Tp>
65 _LIBCPP_HIDE_FROM_ABI
66 constexpr __ptr_to_object auto operator()(_Tp&& __t) const
67 noexcept(noexcept(_VSTD::to_address(ranges::begin(_VSTD::forward<_Tp>(__t))))) {
68 return _VSTD::to_address(ranges::begin(_VSTD::forward<_Tp>(__t)));
69 }
70 };
71} // end namespace __data
72
73inline namespace __cpo {
74 inline constexpr const auto data = __data::__fn{};
75} // namespace __cpo
76} // namespace ranges
77
78// clang-format off
79
80#endif // !defined(_LIBCPP_HAS_NO_RANGES)
81
82_LIBCPP_END_NAMESPACE_STD
83
84_LIBCPP_POP_MACROS
85
86#endif // _LIBCPP___RANGES_DATA_H
lib/libcxx/include/__ranges/drop_view.h created+131
......@@ -0,0 +1,131 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9#ifndef _LIBCPP___RANGES_DROP_VIEW_H
10#define _LIBCPP___RANGES_DROP_VIEW_H
11
12#include <__config>
13#include <__iterator/concepts.h>
14#include <__iterator/iterator_traits.h>
15#include <__iterator/next.h>
16#include <__ranges/access.h>
17#include <__ranges/all.h>
18#include <__ranges/concepts.h>
19#include <__ranges/enable_borrowed_range.h>
20#include <__ranges/non_propagating_cache.h>
21#include <__ranges/size.h>
22#include <__ranges/view_interface.h>
23#include <__utility/move.h>
24#include <concepts>
25#include <type_traits>
26
27#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
28#pragma GCC system_header
29#endif
30
31_LIBCPP_PUSH_MACROS
32#include <__undef_macros>
33
34_LIBCPP_BEGIN_NAMESPACE_STD
35
36#if !defined(_LIBCPP_HAS_NO_RANGES)
37
38namespace ranges {
39 template<view _View>
40 class drop_view
41 : public view_interface<drop_view<_View>>
42 {
43 // We cache begin() whenever ranges::next is not guaranteed O(1) to provide an
44 // amortized O(1) begin() method. If this is an input_range, then we cannot cache
45 // begin because begin is not equality preserving.
46 // Note: drop_view<input-range>::begin() is still trivially amortized O(1) because
47 // one can't call begin() on it more than once.
48 static constexpr bool _UseCache = forward_range<_View> && !(random_access_range<_View> && sized_range<_View>);
49 using _Cache = _If<_UseCache, __non_propagating_cache<iterator_t<_View>>, __empty_cache>;
50 [[no_unique_address]] _Cache __cached_begin_ = _Cache();
51 range_difference_t<_View> __count_ = 0;
52 _View __base_ = _View();
53
54public:
55 drop_view() requires default_initializable<_View> = default;
56
57 _LIBCPP_HIDE_FROM_ABI
58 constexpr drop_view(_View __base, range_difference_t<_View> __count)
59 : __count_(__count)
60 , __base_(_VSTD::move(__base))
61 {
62 _LIBCPP_ASSERT(__count_ >= 0, "count must be greater than or equal to zero.");
63 }
64
65 _LIBCPP_HIDE_FROM_ABI constexpr _View base() const& requires copy_constructible<_View> { return __base_; }
66 _LIBCPP_HIDE_FROM_ABI constexpr _View base() && { return _VSTD::move(__base_); }
67
68 _LIBCPP_HIDE_FROM_ABI
69 constexpr auto begin()
70 requires (!(__simple_view<_View> &&
71 random_access_range<const _View> && sized_range<const _View>))
72 {
73 if constexpr (_UseCache)
74 if (__cached_begin_.__has_value())
75 return *__cached_begin_;
76
77 auto __tmp = ranges::next(ranges::begin(__base_), __count_, ranges::end(__base_));
78 if constexpr (_UseCache)
79 __cached_begin_.__set(__tmp);
80 return __tmp;
81 }
82
83 _LIBCPP_HIDE_FROM_ABI
84 constexpr auto begin() const
85 requires random_access_range<const _View> && sized_range<const _View>
86 {
87 return ranges::next(ranges::begin(__base_), __count_, ranges::end(__base_));
88 }
89
90 _LIBCPP_HIDE_FROM_ABI
91 constexpr auto end()
92 requires (!__simple_view<_View>)
93 { return ranges::end(__base_); }
94
95 _LIBCPP_HIDE_FROM_ABI
96 constexpr auto end() const
97 requires range<const _View>
98 { return ranges::end(__base_); }
99
100 _LIBCPP_HIDE_FROM_ABI
101 static constexpr auto __size(auto& __self) {
102 const auto __s = ranges::size(__self.__base_);
103 const auto __c = static_cast<decltype(__s)>(__self.__count_);
104 return __s < __c ? 0 : __s - __c;
105 }
106
107 _LIBCPP_HIDE_FROM_ABI
108 constexpr auto size()
109 requires sized_range<_View>
110 { return __size(*this); }
111
112 _LIBCPP_HIDE_FROM_ABI
113 constexpr auto size() const
114 requires sized_range<const _View>
115 { return __size(*this); }
116 };
117
118 template<class _Range>
119 drop_view(_Range&&, range_difference_t<_Range>) -> drop_view<views::all_t<_Range>>;
120
121 template<class _Tp>
122 inline constexpr bool enable_borrowed_range<drop_view<_Tp>> = enable_borrowed_range<_Tp>;
123} // namespace ranges
124
125#endif // !defined(_LIBCPP_HAS_NO_RANGES)
126
127_LIBCPP_END_NAMESPACE_STD
128
129_LIBCPP_POP_MACROS
130
131#endif // _LIBCPP___RANGES_DROP_VIEW_H
lib/libcxx/include/__ranges/empty.h created+86
......@@ -0,0 +1,86 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9#ifndef _LIBCPP___RANGES_EMPTY_H
10#define _LIBCPP___RANGES_EMPTY_H
11
12#include <__config>
13#include <__iterator/concepts.h>
14#include <__ranges/access.h>
15#include <__ranges/size.h>
16#include <__utility/forward.h>
17#include <type_traits>
18
19#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
20#pragma GCC system_header
21#endif
22
23_LIBCPP_PUSH_MACROS
24#include <__undef_macros>
25
26_LIBCPP_BEGIN_NAMESPACE_STD
27
28#if !defined(_LIBCPP_HAS_NO_RANGES)
29
30// clang-format off
31namespace ranges {
32// [range.prim.empty]
33namespace __empty {
34 template <class _Tp>
35 concept __member_empty = requires(_Tp&& __t) {
36 bool(_VSTD::forward<_Tp>(__t).empty());
37 };
38
39 template<class _Tp>
40 concept __can_invoke_size =
41 !__member_empty<_Tp> &&
42 requires(_Tp&& __t) { ranges::size(_VSTD::forward<_Tp>(__t)); };
43
44 template <class _Tp>
45 concept __can_compare_begin_end =
46 !__member_empty<_Tp> &&
47 !__can_invoke_size<_Tp> &&
48 requires(_Tp&& __t) {
49 bool(ranges::begin(__t) == ranges::end(__t));
50 { ranges::begin(__t) } -> forward_iterator;
51 };
52
53 struct __fn {
54 template <__member_empty _Tp>
55 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Tp&& __t) const
56 noexcept(noexcept(bool(__t.empty()))) {
57 return __t.empty();
58 }
59
60 template <__can_invoke_size _Tp>
61 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Tp&& __t) const
62 noexcept(noexcept(ranges::size(_VSTD::forward<_Tp>(__t)))) {
63 return ranges::size(_VSTD::forward<_Tp>(__t)) == 0;
64 }
65
66 template<__can_compare_begin_end _Tp>
67 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Tp&& __t) const
68 noexcept(noexcept(bool(ranges::begin(__t) == ranges::end(__t)))) {
69 return ranges::begin(__t) == ranges::end(__t);
70 }
71 };
72}
73
74inline namespace __cpo {
75 inline constexpr auto empty = __empty::__fn{};
76} // namespace __cpo
77} // namespace ranges
78// clang-format off
79
80#endif // !defined(_LIBCPP_HAS_NO_RANGES)
81
82_LIBCPP_END_NAMESPACE_STD
83
84_LIBCPP_POP_MACROS
85
86#endif // _LIBCPP___RANGES_EMPTY_H
lib/libcxx/include/__ranges/empty_view.h created+46
......@@ -0,0 +1,46 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9#ifndef _LIBCPP___RANGES_EMPTY_VIEW_H
10#define _LIBCPP___RANGES_EMPTY_VIEW_H
11
12#include <__config>
13#include <__ranges/view_interface.h>
14#include <type_traits>
15
16#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
17#pragma GCC system_header
18#endif
19
20_LIBCPP_PUSH_MACROS
21#include <__undef_macros>
22
23_LIBCPP_BEGIN_NAMESPACE_STD
24
25#if !defined(_LIBCPP_HAS_NO_RANGES)
26
27namespace ranges {
28 template<class _Tp>
29 requires is_object_v<_Tp>
30 class empty_view : public view_interface<empty_view<_Tp>> {
31 public:
32 _LIBCPP_HIDE_FROM_ABI static constexpr _Tp* begin() noexcept { return nullptr; }
33 _LIBCPP_HIDE_FROM_ABI static constexpr _Tp* end() noexcept { return nullptr; }
34 _LIBCPP_HIDE_FROM_ABI static constexpr _Tp* data() noexcept { return nullptr; }
35 _LIBCPP_HIDE_FROM_ABI static constexpr size_t size() noexcept { return 0; }
36 _LIBCPP_HIDE_FROM_ABI static constexpr bool empty() noexcept { return true; }
37 };
38} // namespace ranges
39
40#endif // !defined(_LIBCPP_HAS_NO_RANGES)
41
42_LIBCPP_END_NAMESPACE_STD
43
44_LIBCPP_POP_MACROS
45
46#endif // _LIBCPP___RANGES_EMPTY_VIEW_H
lib/libcxx/include/__ranges/enable_borrowed_range.h created+46
......@@ -0,0 +1,46 @@
1// -*- C++ -*-
2//===------------------ __ranges/enable_borrowed_range.h ------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___RANGES_ENABLE_BORROWED_RANGE_H
11#define _LIBCPP___RANGES_ENABLE_BORROWED_RANGE_H
12
13// These customization variables are used in <span> and <string_view>. The
14// separate header is used to avoid including the entire <ranges> header in
15// <span> and <string_view>.
16
17#include <__config>
18
19#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
20#pragma GCC system_header
21#endif
22
23_LIBCPP_PUSH_MACROS
24#include <__undef_macros>
25
26_LIBCPP_BEGIN_NAMESPACE_STD
27
28#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_RANGES)
29
30namespace ranges
31{
32
33// [range.range], ranges
34
35template <class>
36inline constexpr bool enable_borrowed_range = false;
37
38} // namespace ranges
39
40#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_RANGES)
41
42_LIBCPP_END_NAMESPACE_STD
43
44_LIBCPP_POP_MACROS
45
46#endif // _LIBCPP___RANGES_ENABLE_BORROWED_RANGE_H
lib/libcxx/include/__ranges/enable_view.h created+42
......@@ -0,0 +1,42 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___RANGES_ENABLE_VIEW_H
11#define _LIBCPP___RANGES_ENABLE_VIEW_H
12
13#include <__config>
14#include <concepts>
15
16#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
17#pragma GCC system_header
18#endif
19
20_LIBCPP_PUSH_MACROS
21#include <__undef_macros>
22
23_LIBCPP_BEGIN_NAMESPACE_STD
24
25#if !defined(_LIBCPP_HAS_NO_RANGES)
26
27namespace ranges {
28
29struct view_base { };
30
31template <class _Tp>
32inline constexpr bool enable_view = derived_from<_Tp, view_base>;
33
34} // end namespace ranges
35
36#endif // !_LIBCPP_HAS_NO_RANGES
37
38_LIBCPP_END_NAMESPACE_STD
39
40_LIBCPP_POP_MACROS
41
42#endif // _LIBCPP___RANGES_ENABLE_VIEW_H
lib/libcxx/include/__ranges/non_propagating_cache.h created+99
......@@ -0,0 +1,99 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9#ifndef _LIBCPP___RANGES_NON_PROPAGATING_CACHE_H
10#define _LIBCPP___RANGES_NON_PROPAGATING_CACHE_H
11
12#include <__config>
13#include <__iterator/concepts.h> // indirectly_readable
14#include <__iterator/iterator_traits.h> // iter_reference_t
15#include <__memory/addressof.h>
16#include <concepts> // constructible_from
17#include <optional>
18#include <type_traits>
19
20#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
21#pragma GCC system_header
22#endif
23
24_LIBCPP_PUSH_MACROS
25#include <__undef_macros>
26
27_LIBCPP_BEGIN_NAMESPACE_STD
28
29// clang-format off
30
31#if !defined(_LIBCPP_HAS_NO_RANGES)
32
33namespace ranges {
34 // __non_propagating_cache is a helper type that allows storing an optional value in it,
35 // but which does not copy the source's value when it is copy constructed/assigned to,
36 // and which resets the source's value when it is moved-from.
37 //
38 // This type is used as an implementation detail of some views that need to cache the
39 // result of `begin()` in order to provide an amortized O(1) begin() method. Typically,
40 // we don't want to propagate the value of the cache upon copy because the cached iterator
41 // may refer to internal details of the source view.
42 template<class _Tp>
43 requires is_object_v<_Tp>
44 class _LIBCPP_TEMPLATE_VIS __non_propagating_cache {
45 optional<_Tp> __value_ = nullopt;
46
47 public:
48 _LIBCPP_HIDE_FROM_ABI __non_propagating_cache() = default;
49
50 _LIBCPP_HIDE_FROM_ABI
51 constexpr __non_propagating_cache(__non_propagating_cache const&) noexcept
52 : __value_(nullopt)
53 { }
54
55 _LIBCPP_HIDE_FROM_ABI
56 constexpr __non_propagating_cache(__non_propagating_cache&& __other) noexcept
57 : __value_(nullopt)
58 {
59 __other.__value_.reset();
60 }
61
62 _LIBCPP_HIDE_FROM_ABI
63 constexpr __non_propagating_cache& operator=(__non_propagating_cache const& __other) noexcept {
64 if (this != _VSTD::addressof(__other)) {
65 __value_.reset();
66 }
67 return *this;
68 }
69
70 _LIBCPP_HIDE_FROM_ABI
71 constexpr __non_propagating_cache& operator=(__non_propagating_cache&& __other) noexcept {
72 __value_.reset();
73 __other.__value_.reset();
74 return *this;
75 }
76
77 _LIBCPP_HIDE_FROM_ABI
78 constexpr _Tp& operator*() { return *__value_; }
79 _LIBCPP_HIDE_FROM_ABI
80 constexpr _Tp const& operator*() const { return *__value_; }
81
82 _LIBCPP_HIDE_FROM_ABI
83 constexpr bool __has_value() const { return __value_.has_value(); }
84 _LIBCPP_HIDE_FROM_ABI
85 constexpr void __set(_Tp const& __value) { __value_.emplace(__value); }
86 _LIBCPP_HIDE_FROM_ABI
87 constexpr void __set(_Tp&& __value) { __value_.emplace(_VSTD::move(__value)); }
88 };
89
90 struct __empty_cache { };
91} // namespace ranges
92
93#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_RANGES)
94
95_LIBCPP_END_NAMESPACE_STD
96
97_LIBCPP_POP_MACROS
98
99#endif // _LIBCPP___RANGES_NON_PROPAGATING_CACHE_H
lib/libcxx/include/__ranges/ref_view.h created+87
......@@ -0,0 +1,87 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9#ifndef _LIBCPP___RANGES_REF_VIEW_H
10#define _LIBCPP___RANGES_REF_VIEW_H
11
12#include <__config>
13#include <__iterator/concepts.h>
14#include <__iterator/incrementable_traits.h>
15#include <__iterator/iterator_traits.h>
16#include <__memory/addressof.h>
17#include <__ranges/access.h>
18#include <__ranges/concepts.h>
19#include <__ranges/data.h>
20#include <__ranges/empty.h>
21#include <__ranges/size.h>
22#include <__ranges/view_interface.h>
23#include <concepts>
24#include <type_traits>
25
26#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
27#pragma GCC system_header
28#endif
29
30_LIBCPP_PUSH_MACROS
31#include <__undef_macros>
32
33_LIBCPP_BEGIN_NAMESPACE_STD
34
35#if !defined(_LIBCPP_HAS_NO_RANGES)
36
37namespace ranges {
38 template<range _Range>
39 requires is_object_v<_Range>
40 class ref_view : public view_interface<ref_view<_Range>> {
41 _Range *__range_;
42
43 static void __fun(_Range&);
44 static void __fun(_Range&&) = delete;
45
46public:
47 template<class _Tp>
48 requires __different_from<_Tp, ref_view> &&
49 convertible_to<_Tp, _Range&> && requires { __fun(declval<_Tp>()); }
50 _LIBCPP_HIDE_FROM_ABI
51 constexpr ref_view(_Tp&& __t)
52 : __range_(_VSTD::addressof(static_cast<_Range&>(_VSTD::forward<_Tp>(__t))))
53 {}
54
55 _LIBCPP_HIDE_FROM_ABI constexpr _Range& base() const { return *__range_; }
56
57 _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_Range> begin() const { return ranges::begin(*__range_); }
58 _LIBCPP_HIDE_FROM_ABI constexpr sentinel_t<_Range> end() const { return ranges::end(*__range_); }
59
60 _LIBCPP_HIDE_FROM_ABI
61 constexpr bool empty() const
62 requires requires { ranges::empty(*__range_); }
63 { return ranges::empty(*__range_); }
64
65 _LIBCPP_HIDE_FROM_ABI
66 constexpr auto size() const
67 requires sized_range<_Range>
68 { return ranges::size(*__range_); }
69
70 _LIBCPP_HIDE_FROM_ABI
71 constexpr auto data() const
72 requires contiguous_range<_Range>
73 { return ranges::data(*__range_); }
74 };
75
76 template<class _Range>
77 ref_view(_Range&) -> ref_view<_Range>;
78
79} // namespace ranges
80
81#endif // !defined(_LIBCPP_HAS_NO_RANGES)
82
83_LIBCPP_END_NAMESPACE_STD
84
85_LIBCPP_POP_MACROS
86
87#endif // _LIBCPP___RANGES_REF_VIEW_H
lib/libcxx/include/__ranges/size.h created+132
......@@ -0,0 +1,132 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9#ifndef _LIBCPP___RANGES_SIZE_H
10#define _LIBCPP___RANGES_SIZE_H
11
12#include <__config>
13#include <__iterator/concepts.h>
14#include <__iterator/iterator_traits.h>
15#include <__ranges/access.h>
16#include <__utility/__decay_copy.h>
17#include <__utility/forward.h>
18#include <concepts>
19#include <type_traits>
20
21#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
22#pragma GCC system_header
23#endif
24
25_LIBCPP_PUSH_MACROS
26#include <__undef_macros>
27
28_LIBCPP_BEGIN_NAMESPACE_STD
29
30#if !defined(_LIBCPP_HAS_NO_RANGES)
31
32// clang-format off
33namespace ranges {
34template<class>
35inline constexpr bool disable_sized_range = false;
36
37// [range.prim.size]
38namespace __size {
39 void size(auto&) = delete;
40 void size(const auto&) = delete;
41
42 template <class _Tp>
43 concept __size_enabled = !disable_sized_range<remove_cvref_t<_Tp>>;
44
45 template <class _Tp>
46 concept __member_size = __size_enabled<_Tp> && requires(_Tp&& __t) {
47 { _VSTD::__decay_copy(_VSTD::forward<_Tp>(__t).size()) } -> __integer_like;
48 };
49
50 template <class _Tp>
51 concept __unqualified_size =
52 __size_enabled<_Tp> &&
53 !__member_size<_Tp> &&
54 __class_or_enum<remove_cvref_t<_Tp>> &&
55 requires(_Tp&& __t) {
56 { _VSTD::__decay_copy(size(_VSTD::forward<_Tp>(__t))) } -> __integer_like;
57 };
58
59 template <class _Tp>
60 concept __difference =
61 !__member_size<_Tp> &&
62 !__unqualified_size<_Tp> &&
63 __class_or_enum<remove_cvref_t<_Tp>> &&
64 requires(_Tp&& __t) {
65 { ranges::begin(__t) } -> forward_iterator;
66 { ranges::end(__t) } -> sized_sentinel_for<decltype(ranges::begin(declval<_Tp>()))>;
67 };
68
69 struct __fn {
70 template <class _Tp, size_t _Sz>
71 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr size_t operator()(_Tp (&&)[_Sz]) const noexcept {
72 return _Sz;
73 }
74
75 template <class _Tp, size_t _Sz>
76 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr size_t operator()(_Tp (&)[_Sz]) const noexcept {
77 return _Sz;
78 }
79
80 template <__member_size _Tp>
81 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __integer_like auto operator()(_Tp&& __t) const
82 noexcept(noexcept(_VSTD::forward<_Tp>(__t).size())) {
83 return _VSTD::forward<_Tp>(__t).size();
84 }
85
86 template <__unqualified_size _Tp>
87 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __integer_like auto operator()(_Tp&& __t) const
88 noexcept(noexcept(size(_VSTD::forward<_Tp>(__t)))) {
89 return size(_VSTD::forward<_Tp>(__t));
90 }
91
92 template<__difference _Tp>
93 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __integer_like auto operator()(_Tp&& __t) const
94 noexcept(noexcept(ranges::end(__t) - ranges::begin(__t))) {
95 return _VSTD::__to_unsigned_like(ranges::end(__t) - ranges::begin(__t));
96 }
97 };
98} // end namespace __size
99
100inline namespace __cpo {
101 inline constexpr auto size = __size::__fn{};
102} // namespace __cpo
103
104namespace __ssize {
105 struct __fn {
106 template<class _Tp>
107 requires requires (_Tp&& __t) { ranges::size(__t); }
108 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr integral auto operator()(_Tp&& __t) const
109 noexcept(noexcept(ranges::size(__t))) {
110 using _Signed = make_signed_t<decltype(ranges::size(__t))>;
111 if constexpr (sizeof(ptrdiff_t) > sizeof(_Signed))
112 return static_cast<ptrdiff_t>(ranges::size(__t));
113 else
114 return static_cast<_Signed>(ranges::size(__t));
115 }
116 };
117}
118
119inline namespace __cpo {
120 inline constexpr const auto ssize = __ssize::__fn{};
121} // namespace __cpo
122} // namespace ranges
123
124// clang-format off
125
126#endif // !defined(_LIBCPP_HAS_NO_RANGES)
127
128_LIBCPP_END_NAMESPACE_STD
129
130_LIBCPP_POP_MACROS
131
132#endif // _LIBCPP___RANGES_SIZE_H
lib/libcxx/include/__ranges/subrange.h created+267
......@@ -0,0 +1,267 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9#ifndef _LIBCPP___RANGES_SUBRANGE_H
10#define _LIBCPP___RANGES_SUBRANGE_H
11
12#include <__config>
13#include <__iterator/concepts.h>
14#include <__iterator/incrementable_traits.h>
15#include <__iterator/iterator_traits.h>
16#include <__iterator/advance.h>
17#include <__ranges/access.h>
18#include <__ranges/concepts.h>
19#include <__ranges/dangling.h>
20#include <__ranges/enable_borrowed_range.h>
21#include <__ranges/size.h>
22#include <__ranges/view_interface.h>
23#include <concepts>
24#include <type_traits>
25
26#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
27#pragma GCC system_header
28#endif
29
30_LIBCPP_PUSH_MACROS
31#include <__undef_macros>
32
33_LIBCPP_BEGIN_NAMESPACE_STD
34
35#if !defined(_LIBCPP_HAS_NO_RANGES)
36
37// clang-format off
38namespace ranges {
39 template<class _From, class _To>
40 concept __convertible_to_non_slicing =
41 convertible_to<_From, _To> &&
42 // If they're both pointers, they must have the same element type.
43 !(is_pointer_v<decay_t<_From>> &&
44 is_pointer_v<decay_t<_To>> &&
45 __different_from<remove_pointer_t<decay_t<_From>>, remove_pointer_t<decay_t<_To>>>);
46
47 template<class _Tp>
48 concept __pair_like =
49 !is_reference_v<_Tp> && requires(_Tp __t) {
50 typename tuple_size<_Tp>::type; // Ensures `tuple_size<T>` is complete.
51 requires derived_from<tuple_size<_Tp>, integral_constant<size_t, 2>>;
52 typename tuple_element_t<0, remove_const_t<_Tp>>;
53 typename tuple_element_t<1, remove_const_t<_Tp>>;
54 { _VSTD::get<0>(__t) } -> convertible_to<const tuple_element_t<0, _Tp>&>;
55 { _VSTD::get<1>(__t) } -> convertible_to<const tuple_element_t<1, _Tp>&>;
56 };
57
58 template<class _Pair, class _Iter, class _Sent>
59 concept __pair_like_convertible_from =
60 !range<_Pair> && __pair_like<_Pair> &&
61 constructible_from<_Pair, _Iter, _Sent> &&
62 __convertible_to_non_slicing<_Iter, tuple_element_t<0, _Pair>> &&
63 convertible_to<_Sent, tuple_element_t<1, _Pair>>;
64
65 enum class _LIBCPP_ENUM_VIS subrange_kind : bool { unsized, sized };
66
67 template<class _Iter, class _Sent, bool>
68 struct __subrange_base {
69 static constexpr bool __store_size = false;
70 _Iter __begin_ = _Iter();
71 _Sent __end_ = _Sent();
72
73 _LIBCPP_HIDE_FROM_ABI
74 constexpr __subrange_base() = default;
75
76 _LIBCPP_HIDE_FROM_ABI
77 constexpr __subrange_base(_Iter __iter, _Sent __sent, make_unsigned_t<iter_difference_t<_Iter>> = 0)
78 : __begin_(_VSTD::move(__iter)), __end_(__sent) { }
79 };
80
81 template<class _Iter, class _Sent>
82 struct __subrange_base<_Iter, _Sent, true> {
83 static constexpr bool __store_size = true;
84 _Iter __begin_ = _Iter();
85 _Sent __end_ = _Sent();
86 make_unsigned_t<iter_difference_t<_Iter>> __size_ = 0;
87
88 _LIBCPP_HIDE_FROM_ABI
89 constexpr __subrange_base() = default;
90
91 _LIBCPP_HIDE_FROM_ABI
92 constexpr __subrange_base(_Iter __iter, _Sent __sent, decltype(__size_) __size)
93 : __begin_(_VSTD::move(__iter)), __end_(__sent), __size_(__size) { }
94 };
95
96 template<input_or_output_iterator _Iter, sentinel_for<_Iter> _Sent = _Iter,
97 subrange_kind _Kind = sized_sentinel_for<_Sent, _Iter>
98 ? subrange_kind::sized
99 : subrange_kind::unsized>
100 requires (_Kind == subrange_kind::sized || !sized_sentinel_for<_Sent, _Iter>)
101 struct _LIBCPP_TEMPLATE_VIS subrange
102 : public view_interface<subrange<_Iter, _Sent, _Kind>>,
103 private __subrange_base<_Iter, _Sent, _Kind == subrange_kind::sized && !sized_sentinel_for<_Sent, _Iter>> {
104
105 using _Base = __subrange_base<_Iter, _Sent, _Kind == subrange_kind::sized && !sized_sentinel_for<_Sent, _Iter>>;
106
107 _LIBCPP_HIDE_FROM_ABI
108 subrange() requires default_initializable<_Iter> = default;
109
110 _LIBCPP_HIDE_FROM_ABI
111 constexpr subrange(__convertible_to_non_slicing<_Iter> auto __iter, _Sent __sent)
112 requires (!_Base::__store_size)
113 : _Base(_VSTD::move(__iter), __sent) {}
114
115 _LIBCPP_HIDE_FROM_ABI
116 constexpr subrange(__convertible_to_non_slicing<_Iter> auto __iter, _Sent __sent,
117 make_unsigned_t<iter_difference_t<_Iter>> __n)
118 requires (_Kind == subrange_kind::sized)
119 : _Base(_VSTD::move(__iter), __sent, __n) { }
120
121 template<__different_from<subrange> _Range>
122 requires borrowed_range<_Range> &&
123 __convertible_to_non_slicing<iterator_t<_Range>, _Iter> &&
124 convertible_to<sentinel_t<_Range>, _Sent>
125 _LIBCPP_HIDE_FROM_ABI
126 constexpr subrange(_Range&& __range)
127 requires (!_Base::__store_size)
128 : subrange(ranges::begin(__range), ranges::end(__range)) { }
129
130 template<__different_from<subrange> _Range>
131 requires borrowed_range<_Range> &&
132 __convertible_to_non_slicing<iterator_t<_Range>, _Iter> &&
133 convertible_to<sentinel_t<_Range>, _Sent>
134 _LIBCPP_HIDE_FROM_ABI
135 constexpr subrange(_Range&& __range)
136 requires _Base::__store_size && sized_range<_Range>
137 : subrange(__range, ranges::size(__range)) { }
138
139
140 template<borrowed_range _Range>
141 requires __convertible_to_non_slicing<iterator_t<_Range>, _Iter> &&
142 convertible_to<sentinel_t<_Range>, _Sent>
143 _LIBCPP_HIDE_FROM_ABI
144 constexpr subrange(_Range&& __range, make_unsigned_t<iter_difference_t<_Iter>> __n)
145 requires (_Kind == subrange_kind::sized)
146 : subrange(ranges::begin(__range), ranges::end(__range), __n) { }
147
148 template<__different_from<subrange> _Pair>
149 requires __pair_like_convertible_from<_Pair, const _Iter&, const _Sent&>
150 _LIBCPP_HIDE_FROM_ABI
151 constexpr operator _Pair() const { return _Pair(this->__begin_, this->__end_); }
152
153 _LIBCPP_HIDE_FROM_ABI
154 constexpr _Iter begin() const requires copyable<_Iter> {
155 return this->__begin_;
156 }
157
158 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Iter begin() requires (!copyable<_Iter>) {
159 return _VSTD::move(this->__begin_);
160 }
161
162 _LIBCPP_HIDE_FROM_ABI
163 constexpr _Sent end() const { return this->__end_; }
164
165 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty() const { return this->__begin_ == this->__end_; }
166
167 _LIBCPP_HIDE_FROM_ABI
168 constexpr make_unsigned_t<iter_difference_t<_Iter>> size() const
169 requires (_Kind == subrange_kind::sized)
170 {
171 if constexpr (_Base::__store_size)
172 return this->__size_;
173 else
174 return __to_unsigned_like(this->__end_ - this->__begin_);
175 }
176
177 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr subrange next(iter_difference_t<_Iter> __n = 1) const&
178 requires forward_iterator<_Iter> {
179 auto __tmp = *this;
180 __tmp.advance(__n);
181 return __tmp;
182 }
183
184 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr subrange next(iter_difference_t<_Iter> __n = 1) && {
185 advance(__n);
186 return _VSTD::move(*this);
187 }
188
189 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr subrange prev(iter_difference_t<_Iter> __n = 1) const
190 requires bidirectional_iterator<_Iter> {
191 auto __tmp = *this;
192 __tmp.advance(-__n);
193 return __tmp;
194 }
195
196 _LIBCPP_HIDE_FROM_ABI
197 constexpr subrange& advance(iter_difference_t<_Iter> __n) {
198 if constexpr (bidirectional_iterator<_Iter>) {
199 if (__n < 0) {
200 ranges::advance(this->__begin_, __n);
201 if constexpr (_Base::__store_size)
202 this->__size_ += _VSTD::__to_unsigned_like(-__n);
203 return *this;
204 }
205 }
206
207 auto __d = __n - ranges::advance(this->__begin_, __n, this->__end_);
208 if constexpr (_Base::__store_size)
209 this->__size_ -= _VSTD::__to_unsigned_like(__d);
210 return *this;
211 }
212 };
213
214 template<input_or_output_iterator _Iter, sentinel_for<_Iter> _Sent>
215 subrange(_Iter, _Sent) -> subrange<_Iter, _Sent>;
216
217 template<input_or_output_iterator _Iter, sentinel_for<_Iter> _Sent>
218 subrange(_Iter, _Sent, make_unsigned_t<iter_difference_t<_Iter>>)
219 -> subrange<_Iter, _Sent, subrange_kind::sized>;
220
221 template<borrowed_range _Range>
222 subrange(_Range&&) -> subrange<iterator_t<_Range>, sentinel_t<_Range>,
223 (sized_range<_Range> || sized_sentinel_for<sentinel_t<_Range>, iterator_t<_Range>>)
224 ? subrange_kind::sized : subrange_kind::unsized>;
225
226 template<borrowed_range _Range>
227 subrange(_Range&&, make_unsigned_t<range_difference_t<_Range>>)
228 -> subrange<iterator_t<_Range>, sentinel_t<_Range>, subrange_kind::sized>;
229
230 template<size_t _Index, class _Iter, class _Sent, subrange_kind _Kind>
231 requires (_Index < 2)
232 _LIBCPP_HIDE_FROM_ABI
233 constexpr auto get(const subrange<_Iter, _Sent, _Kind>& __subrange) {
234 if constexpr (_Index == 0)
235 return __subrange.begin();
236 else
237 return __subrange.end();
238 }
239
240 template<size_t _Index, class _Iter, class _Sent, subrange_kind _Kind>
241 requires (_Index < 2)
242 _LIBCPP_HIDE_FROM_ABI
243 constexpr auto get(subrange<_Iter, _Sent, _Kind>&& __subrange) {
244 if constexpr (_Index == 0)
245 return __subrange.begin();
246 else
247 return __subrange.end();
248 }
249
250 template<class _Ip, class _Sp, subrange_kind _Kp>
251 inline constexpr bool enable_borrowed_range<subrange<_Ip, _Sp, _Kp>> = true;
252
253 template<range _Rp>
254 using borrowed_subrange_t = _If<borrowed_range<_Rp>, subrange<iterator_t<_Rp> >, dangling>;
255} // namespace ranges
256
257using ranges::get;
258
259// clang-format off
260
261#endif // !defined(_LIBCPP_HAS_NO_RANGES)
262
263_LIBCPP_END_NAMESPACE_STD
264
265_LIBCPP_POP_MACROS
266
267#endif // _LIBCPP___RANGES_SUBRANGE_H
lib/libcxx/include/__ranges/transform_view.h created+408
......@@ -0,0 +1,408 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9#ifndef _LIBCPP___RANGES_TRANSFORM_VIEW_H
10#define _LIBCPP___RANGES_TRANSFORM_VIEW_H
11
12#include <__config>
13#include <__iterator/concepts.h>
14#include <__iterator/iter_swap.h>
15#include <__iterator/iterator_traits.h>
16#include <__ranges/access.h>
17#include <__ranges/all.h>
18#include <__ranges/concepts.h>
19#include <__ranges/copyable_box.h>
20#include <__ranges/empty.h>
21#include <__ranges/size.h>
22#include <__ranges/view_interface.h>
23#include <concepts>
24#include <type_traits>
25
26#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
27#pragma GCC system_header
28#endif
29
30_LIBCPP_PUSH_MACROS
31#include <__undef_macros>
32
33_LIBCPP_BEGIN_NAMESPACE_STD
34
35#if !defined(_LIBCPP_HAS_NO_RANGES)
36
37namespace ranges {
38
39template<class _View, class _Fn>
40concept __transform_view_constraints =
41 view<_View> && is_object_v<_Fn> &&
42 regular_invocable<_Fn&, range_reference_t<_View>> &&
43 __referenceable<invoke_result_t<_Fn&, range_reference_t<_View>>>;
44
45template<input_range _View, copy_constructible _Fn>
46 requires __transform_view_constraints<_View, _Fn>
47class transform_view : public view_interface<transform_view<_View, _Fn>> {
48 template<bool> class __iterator;
49 template<bool> class __sentinel;
50
51 [[no_unique_address]] __copyable_box<_Fn> __func_;
52 [[no_unique_address]] _View __base_ = _View();
53
54public:
55 _LIBCPP_HIDE_FROM_ABI
56 transform_view()
57 requires default_initializable<_View> && default_initializable<_Fn> = default;
58
59 _LIBCPP_HIDE_FROM_ABI
60 constexpr transform_view(_View __base, _Fn __func)
61 : __func_(_VSTD::in_place, _VSTD::move(__func)), __base_(_VSTD::move(__base)) {}
62
63 _LIBCPP_HIDE_FROM_ABI
64 constexpr _View base() const& requires copy_constructible<_View> { return __base_; }
65 _LIBCPP_HIDE_FROM_ABI
66 constexpr _View base() && { return _VSTD::move(__base_); }
67
68 _LIBCPP_HIDE_FROM_ABI
69 constexpr __iterator<false> begin() {
70 return __iterator<false>{*this, ranges::begin(__base_)};
71 }
72 _LIBCPP_HIDE_FROM_ABI
73 constexpr __iterator<true> begin() const
74 requires range<const _View> &&
75 regular_invocable<const _Fn&, range_reference_t<const _View>>
76 {
77 return __iterator<true>(*this, ranges::begin(__base_));
78 }
79
80 _LIBCPP_HIDE_FROM_ABI
81 constexpr __sentinel<false> end() {
82 return __sentinel<false>(ranges::end(__base_));
83 }
84 _LIBCPP_HIDE_FROM_ABI
85 constexpr __iterator<false> end()
86 requires common_range<_View>
87 {
88 return __iterator<false>(*this, ranges::end(__base_));
89 }
90 _LIBCPP_HIDE_FROM_ABI
91 constexpr __sentinel<true> end() const
92 requires range<const _View> &&
93 regular_invocable<const _Fn&, range_reference_t<const _View>>
94 {
95 return __sentinel<true>(ranges::end(__base_));
96 }
97 _LIBCPP_HIDE_FROM_ABI
98 constexpr __iterator<true> end() const
99 requires common_range<const _View> &&
100 regular_invocable<const _Fn&, range_reference_t<const _View>>
101 {
102 return __iterator<true>(*this, ranges::end(__base_));
103 }
104
105 _LIBCPP_HIDE_FROM_ABI
106 constexpr auto size() requires sized_range<_View> { return ranges::size(__base_); }
107 _LIBCPP_HIDE_FROM_ABI
108 constexpr auto size() const requires sized_range<const _View> { return ranges::size(__base_); }
109};
110
111template<class _Range, class _Fn>
112transform_view(_Range&&, _Fn) -> transform_view<views::all_t<_Range>, _Fn>;
113
114template<class _View>
115struct __transform_view_iterator_concept { using type = input_iterator_tag; };
116
117template<random_access_range _View>
118struct __transform_view_iterator_concept<_View> { using type = random_access_iterator_tag; };
119
120template<bidirectional_range _View>
121struct __transform_view_iterator_concept<_View> { using type = bidirectional_iterator_tag; };
122
123template<forward_range _View>
124struct __transform_view_iterator_concept<_View> { using type = forward_iterator_tag; };
125
126template<class, class>
127struct __transform_view_iterator_category_base {};
128
129template<forward_range _View, class _Fn>
130struct __transform_view_iterator_category_base<_View, _Fn> {
131 using _Cat = typename iterator_traits<iterator_t<_View>>::iterator_category;
132
133 using iterator_category = conditional_t<
134 is_lvalue_reference_v<invoke_result_t<_Fn&, range_reference_t<_View>>>,
135 conditional_t<
136 derived_from<_Cat, contiguous_iterator_tag>,
137 random_access_iterator_tag,
138 _Cat
139 >,
140 input_iterator_tag
141 >;
142};
143
144template<input_range _View, copy_constructible _Fn>
145 requires __transform_view_constraints<_View, _Fn>
146template<bool _Const>
147class transform_view<_View, _Fn>::__iterator
148 : public __transform_view_iterator_category_base<_View, _Fn> {
149
150 using _Parent = __maybe_const<_Const, transform_view>;
151 using _Base = __maybe_const<_Const, _View>;
152
153 _Parent *__parent_ = nullptr;
154
155 template<bool>
156 friend class transform_view<_View, _Fn>::__iterator;
157
158 template<bool>
159 friend class transform_view<_View, _Fn>::__sentinel;
160
161public:
162 iterator_t<_Base> __current_ = iterator_t<_Base>();
163
164 using iterator_concept = typename __transform_view_iterator_concept<_View>::type;
165 using value_type = remove_cvref_t<invoke_result_t<_Fn&, range_reference_t<_Base>>>;
166 using difference_type = range_difference_t<_Base>;
167
168 _LIBCPP_HIDE_FROM_ABI
169 __iterator() requires default_initializable<iterator_t<_Base>> = default;
170
171 _LIBCPP_HIDE_FROM_ABI
172 constexpr __iterator(_Parent& __parent, iterator_t<_Base> __current)
173 : __parent_(_VSTD::addressof(__parent)), __current_(_VSTD::move(__current)) {}
174
175 // Note: `__i` should always be `__iterator<false>`, but directly using
176 // `__iterator<false>` is ill-formed when `_Const` is false
177 // (see http://wg21.link/class.copy.ctor#5).
178 _LIBCPP_HIDE_FROM_ABI
179 constexpr __iterator(__iterator<!_Const> __i)
180 requires _Const && convertible_to<iterator_t<_View>, iterator_t<_Base>>
181 : __parent_(__i.__parent_), __current_(_VSTD::move(__i.__current_)) {}
182
183 _LIBCPP_HIDE_FROM_ABI
184 constexpr iterator_t<_Base> base() const&
185 requires copyable<iterator_t<_Base>>
186 {
187 return __current_;
188 }
189
190 _LIBCPP_HIDE_FROM_ABI
191 constexpr iterator_t<_Base> base() && {
192 return _VSTD::move(__current_);
193 }
194
195 _LIBCPP_HIDE_FROM_ABI
196 constexpr decltype(auto) operator*() const
197 noexcept(noexcept(_VSTD::invoke(*__parent_->__func_, *__current_)))
198 {
199 return _VSTD::invoke(*__parent_->__func_, *__current_);
200 }
201
202 _LIBCPP_HIDE_FROM_ABI
203 constexpr __iterator& operator++() {
204 ++__current_;
205 return *this;
206 }
207
208 _LIBCPP_HIDE_FROM_ABI
209 constexpr void operator++(int) { ++__current_; }
210
211 _LIBCPP_HIDE_FROM_ABI
212 constexpr __iterator operator++(int)
213 requires forward_range<_Base>
214 {
215 auto __tmp = *this;
216 ++*this;
217 return __tmp;
218 }
219
220 _LIBCPP_HIDE_FROM_ABI
221 constexpr __iterator& operator--()
222 requires bidirectional_range<_Base>
223 {
224 --__current_;
225 return *this;
226 }
227
228 _LIBCPP_HIDE_FROM_ABI
229 constexpr __iterator operator--(int)
230 requires bidirectional_range<_Base>
231 {
232 auto __tmp = *this;
233 --*this;
234 return __tmp;
235 }
236
237 _LIBCPP_HIDE_FROM_ABI
238 constexpr __iterator& operator+=(difference_type __n)
239 requires random_access_range<_Base>
240 {
241 __current_ += __n;
242 return *this;
243 }
244
245 _LIBCPP_HIDE_FROM_ABI
246 constexpr __iterator& operator-=(difference_type __n)
247 requires random_access_range<_Base>
248 {
249 __current_ -= __n;
250 return *this;
251 }
252
253 _LIBCPP_HIDE_FROM_ABI
254 constexpr decltype(auto) operator[](difference_type __n) const
255 noexcept(noexcept(_VSTD::invoke(*__parent_->__func_, __current_[__n])))
256 requires random_access_range<_Base>
257 {
258 return _VSTD::invoke(*__parent_->__func_, __current_[__n]);
259 }
260
261 _LIBCPP_HIDE_FROM_ABI
262 friend constexpr bool operator==(const __iterator& __x, const __iterator& __y)
263 requires equality_comparable<iterator_t<_Base>>
264 {
265 return __x.__current_ == __y.__current_;
266 }
267
268 _LIBCPP_HIDE_FROM_ABI
269 friend constexpr bool operator<(const __iterator& __x, const __iterator& __y)
270 requires random_access_range<_Base>
271 {
272 return __x.__current_ < __y.__current_;
273 }
274
275 _LIBCPP_HIDE_FROM_ABI
276 friend constexpr bool operator>(const __iterator& __x, const __iterator& __y)
277 requires random_access_range<_Base>
278 {
279 return __x.__current_ > __y.__current_;
280 }
281
282 _LIBCPP_HIDE_FROM_ABI
283 friend constexpr bool operator<=(const __iterator& __x, const __iterator& __y)
284 requires random_access_range<_Base>
285 {
286 return __x.__current_ <= __y.__current_;
287 }
288
289 _LIBCPP_HIDE_FROM_ABI
290 friend constexpr bool operator>=(const __iterator& __x, const __iterator& __y)
291 requires random_access_range<_Base>
292 {
293 return __x.__current_ >= __y.__current_;
294 }
295
296// TODO: Fix this as soon as soon as three_way_comparable is implemented.
297// _LIBCPP_HIDE_FROM_ABI
298// friend constexpr auto operator<=>(const __iterator& __x, const __iterator& __y)
299// requires random_access_range<_Base> && three_way_comparable<iterator_t<_Base>>
300// {
301// return __x.__current_ <=> __y.__current_;
302// }
303
304 _LIBCPP_HIDE_FROM_ABI
305 friend constexpr __iterator operator+(__iterator __i, difference_type __n)
306 requires random_access_range<_Base>
307 {
308 return __iterator{*__i.__parent_, __i.__current_ + __n};
309 }
310
311 _LIBCPP_HIDE_FROM_ABI
312 friend constexpr __iterator operator+(difference_type __n, __iterator __i)
313 requires random_access_range<_Base>
314 {
315 return __iterator{*__i.__parent_, __i.__current_ + __n};
316 }
317
318 _LIBCPP_HIDE_FROM_ABI
319 friend constexpr __iterator operator-(__iterator __i, difference_type __n)
320 requires random_access_range<_Base>
321 {
322 return __iterator{*__i.__parent_, __i.__current_ - __n};
323 }
324
325 _LIBCPP_HIDE_FROM_ABI
326 friend constexpr difference_type operator-(const __iterator& __x, const __iterator& __y)
327 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
328 {
329 return __x.__current_ - __y.__current_;
330 }
331
332 _LIBCPP_HIDE_FROM_ABI
333 friend constexpr decltype(auto) iter_move(const __iterator& __i)
334 noexcept(noexcept(*__i))
335 {
336 if constexpr (is_lvalue_reference_v<decltype(*__i)>)
337 return _VSTD::move(*__i);
338 else
339 return *__i;
340 }
341};
342
343template<input_range _View, copy_constructible _Fn>
344 requires __transform_view_constraints<_View, _Fn>
345template<bool _Const>
346class transform_view<_View, _Fn>::__sentinel {
347 using _Parent = __maybe_const<_Const, transform_view>;
348 using _Base = __maybe_const<_Const, _View>;
349
350 sentinel_t<_Base> __end_ = sentinel_t<_Base>();
351
352 template<bool>
353 friend class transform_view<_View, _Fn>::__iterator;
354
355 template<bool>
356 friend class transform_view<_View, _Fn>::__sentinel;
357
358public:
359 _LIBCPP_HIDE_FROM_ABI
360 __sentinel() = default;
361
362 _LIBCPP_HIDE_FROM_ABI
363 constexpr explicit __sentinel(sentinel_t<_Base> __end) : __end_(__end) {}
364
365 // Note: `__i` should always be `__sentinel<false>`, but directly using
366 // `__sentinel<false>` is ill-formed when `_Const` is false
367 // (see http://wg21.link/class.copy.ctor#5).
368 _LIBCPP_HIDE_FROM_ABI
369 constexpr __sentinel(__sentinel<!_Const> __i)
370 requires _Const && convertible_to<sentinel_t<_View>, sentinel_t<_Base>>
371 : __end_(_VSTD::move(__i.__end_)) {}
372
373 _LIBCPP_HIDE_FROM_ABI
374 constexpr sentinel_t<_Base> base() const { return __end_; }
375
376 template<bool _OtherConst>
377 requires sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>>
378 _LIBCPP_HIDE_FROM_ABI
379 friend constexpr bool operator==(const __iterator<_OtherConst>& __x, const __sentinel& __y) {
380 return __x.__current_ == __y.__end_;
381 }
382
383 template<bool _OtherConst>
384 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>>
385 _LIBCPP_HIDE_FROM_ABI
386 friend constexpr range_difference_t<__maybe_const<_OtherConst, _View>>
387 operator-(const __iterator<_OtherConst>& __x, const __sentinel& __y) {
388 return __x.__current_ - __y.__end_;
389 }
390
391 template<bool _OtherConst>
392 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>>
393 _LIBCPP_HIDE_FROM_ABI
394 friend constexpr range_difference_t<__maybe_const<_OtherConst, _View>>
395 operator-(const __sentinel& __x, const __iterator<_OtherConst>& __y) {
396 return __x.__end_ - __y.__current_;
397 }
398};
399
400} // namespace ranges
401
402#endif // !defined(_LIBCPP_HAS_NO_RANGES)
403
404_LIBCPP_END_NAMESPACE_STD
405
406_LIBCPP_POP_MACROS
407
408#endif // _LIBCPP___RANGES_TRANSFORM_VIEW_H
lib/libcxx/include/__ranges/view_interface.h created+198
......@@ -0,0 +1,198 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9#ifndef _LIBCPP___RANGES_VIEW_INTERFACE_H
10#define _LIBCPP___RANGES_VIEW_INTERFACE_H
11
12#include <__config>
13#include <__iterator/concepts.h>
14#include <__iterator/iterator_traits.h>
15#include <__iterator/prev.h>
16#include <__memory/pointer_traits.h>
17#include <__ranges/access.h>
18#include <__ranges/concepts.h>
19#include <__ranges/empty.h>
20#include <__ranges/enable_view.h>
21#include <concepts>
22#include <type_traits>
23
24#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
25#pragma GCC system_header
26#endif
27
28_LIBCPP_PUSH_MACROS
29#include <__undef_macros>
30
31_LIBCPP_BEGIN_NAMESPACE_STD
32
33#if !defined(_LIBCPP_HAS_NO_RANGES)
34
35namespace ranges {
36
37template<class _Tp>
38concept __can_empty = requires(_Tp __t) { ranges::empty(__t); };
39
40template<class _Tp>
41void __implicitly_convert_to(type_identity_t<_Tp>) noexcept;
42
43template<class _Derived>
44 requires is_class_v<_Derived> && same_as<_Derived, remove_cv_t<_Derived>>
45class view_interface : public view_base {
46 _LIBCPP_HIDE_FROM_ABI
47 constexpr _Derived& __derived() noexcept {
48 return static_cast<_Derived&>(*this);
49 }
50
51 _LIBCPP_HIDE_FROM_ABI
52 constexpr _Derived const& __derived() const noexcept {
53 return static_cast<_Derived const&>(*this);
54 }
55
56public:
57 template<class _D2 = _Derived>
58 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty()
59 noexcept(noexcept(__implicitly_convert_to<bool>(ranges::begin(__derived()) == ranges::end(__derived()))))
60 requires forward_range<_D2>
61 {
62 return ranges::begin(__derived()) == ranges::end(__derived());
63 }
64
65 template<class _D2 = _Derived>
66 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty() const
67 noexcept(noexcept(__implicitly_convert_to<bool>(ranges::begin(__derived()) == ranges::end(__derived()))))
68 requires forward_range<const _D2>
69 {
70 return ranges::begin(__derived()) == ranges::end(__derived());
71 }
72
73 template<class _D2 = _Derived>
74 _LIBCPP_HIDE_FROM_ABI
75 constexpr explicit operator bool()
76 noexcept(noexcept(ranges::empty(declval<_D2>())))
77 requires __can_empty<_D2>
78 {
79 return !ranges::empty(__derived());
80 }
81
82 template<class _D2 = _Derived>
83 _LIBCPP_HIDE_FROM_ABI
84 constexpr explicit operator bool() const
85 noexcept(noexcept(ranges::empty(declval<const _D2>())))
86 requires __can_empty<const _D2>
87 {
88 return !ranges::empty(__derived());
89 }
90
91 template<class _D2 = _Derived>
92 _LIBCPP_HIDE_FROM_ABI
93 constexpr auto data()
94 noexcept(noexcept(_VSTD::to_address(ranges::begin(__derived()))))
95 requires contiguous_iterator<iterator_t<_D2>>
96 {
97 return _VSTD::to_address(ranges::begin(__derived()));
98 }
99
100 template<class _D2 = _Derived>
101 _LIBCPP_HIDE_FROM_ABI
102 constexpr auto data() const
103 noexcept(noexcept(_VSTD::to_address(ranges::begin(__derived()))))
104 requires range<const _D2> && contiguous_iterator<iterator_t<const _D2>>
105 {
106 return _VSTD::to_address(ranges::begin(__derived()));
107 }
108
109 template<class _D2 = _Derived>
110 _LIBCPP_HIDE_FROM_ABI
111 constexpr auto size()
112 noexcept(noexcept(ranges::end(__derived()) - ranges::begin(__derived())))
113 requires forward_range<_D2>
114 && sized_sentinel_for<sentinel_t<_D2>, iterator_t<_D2>>
115 {
116 return ranges::end(__derived()) - ranges::begin(__derived());
117 }
118
119 template<class _D2 = _Derived>
120 _LIBCPP_HIDE_FROM_ABI
121 constexpr auto size() const
122 noexcept(noexcept(ranges::end(__derived()) - ranges::begin(__derived())))
123 requires forward_range<const _D2>
124 && sized_sentinel_for<sentinel_t<const _D2>, iterator_t<const _D2>>
125 {
126 return ranges::end(__derived()) - ranges::begin(__derived());
127 }
128
129 template<class _D2 = _Derived>
130 _LIBCPP_HIDE_FROM_ABI
131 constexpr decltype(auto) front()
132 noexcept(noexcept(*ranges::begin(__derived())))
133 requires forward_range<_D2>
134 {
135 _LIBCPP_ASSERT(!empty(),
136 "Precondition `!empty()` not satisfied. `.front()` called on an empty view.");
137 return *ranges::begin(__derived());
138 }
139
140 template<class _D2 = _Derived>
141 _LIBCPP_HIDE_FROM_ABI
142 constexpr decltype(auto) front() const
143 noexcept(noexcept(*ranges::begin(__derived())))
144 requires forward_range<const _D2>
145 {
146 _LIBCPP_ASSERT(!empty(),
147 "Precondition `!empty()` not satisfied. `.front()` called on an empty view.");
148 return *ranges::begin(__derived());
149 }
150
151 template<class _D2 = _Derived>
152 _LIBCPP_HIDE_FROM_ABI
153 constexpr decltype(auto) back()
154 noexcept(noexcept(*ranges::prev(ranges::end(__derived()))))
155 requires bidirectional_range<_D2> && common_range<_D2>
156 {
157 _LIBCPP_ASSERT(!empty(),
158 "Precondition `!empty()` not satisfied. `.back()` called on an empty view.");
159 return *ranges::prev(ranges::end(__derived()));
160 }
161
162 template<class _D2 = _Derived>
163 _LIBCPP_HIDE_FROM_ABI
164 constexpr decltype(auto) back() const
165 noexcept(noexcept(*ranges::prev(ranges::end(__derived()))))
166 requires bidirectional_range<const _D2> && common_range<const _D2>
167 {
168 _LIBCPP_ASSERT(!empty(),
169 "Precondition `!empty()` not satisfied. `.back()` called on an empty view.");
170 return *ranges::prev(ranges::end(__derived()));
171 }
172
173 template<random_access_range _RARange = _Derived>
174 _LIBCPP_HIDE_FROM_ABI
175 constexpr decltype(auto) operator[](range_difference_t<_RARange> __index)
176 noexcept(noexcept(ranges::begin(__derived())[__index]))
177 {
178 return ranges::begin(__derived())[__index];
179 }
180
181 template<random_access_range _RARange = const _Derived>
182 _LIBCPP_HIDE_FROM_ABI
183 constexpr decltype(auto) operator[](range_difference_t<_RARange> __index) const
184 noexcept(noexcept(ranges::begin(__derived())[__index]))
185 {
186 return ranges::begin(__derived())[__index];
187 }
188};
189
190}
191
192#endif // !defined(_LIBCPP_HAS_NO_RANGES)
193
194_LIBCPP_END_NAMESPACE_STD
195
196_LIBCPP_POP_MACROS
197
198#endif // _LIBCPP___RANGES_VIEW_INTERFACE_H
lib/libcxx/include/__split_buffer+7-6
......@@ -3,8 +3,9 @@
33#define _LIBCPP_SPLIT_BUFFER
44
55#include <__config>
6#include <type_traits>
6#include <__utility/forward.h>
77#include <algorithm>
8#include <type_traits>
89
910#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1011#pragma GCC system_header
......@@ -20,8 +21,8 @@ template <bool>
2021class __split_buffer_common
2122{
2223protected:
23 void __throw_length_error() const;
24 void __throw_out_of_range() const;
24 _LIBCPP_NORETURN void __throw_length_error() const;
25 _LIBCPP_NORETURN void __throw_out_of_range() const;
2526};
2627
2728template <class _Tp, class _Allocator = allocator<_Tp> >
......@@ -444,7 +445,7 @@ __split_buffer<_Tp, _Allocator>::shrink_to_fit() _NOEXCEPT
444445#ifndef _LIBCPP_NO_EXCEPTIONS
445446 try
446447 {
447#endif // _LIBCPP_NO_EXCEPTIONS
448#endif // _LIBCPP_NO_EXCEPTIONS
448449 __split_buffer<value_type, __alloc_rr&> __t(size(), 0, __alloc());
449450 __t.__construct_at_end(move_iterator<pointer>(__begin_),
450451 move_iterator<pointer>(__end_));
......@@ -458,7 +459,7 @@ __split_buffer<_Tp, _Allocator>::shrink_to_fit() _NOEXCEPT
458459 catch (...)
459460 {
460461 }
461#endif // _LIBCPP_NO_EXCEPTIONS
462#endif // _LIBCPP_NO_EXCEPTIONS
462463 }
463464}
464465
......@@ -625,4 +626,4 @@ _LIBCPP_END_NAMESPACE_STD
625626
626627_LIBCPP_POP_MACROS
627628
628#endif // _LIBCPP_SPLIT_BUFFER
629#endif // _LIBCPP_SPLIT_BUFFER
lib/libcxx/include/__sso_allocator deleted-77
......@@ -1,77 +0,0 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___SSO_ALLOCATOR
11#define _LIBCPP___SSO_ALLOCATOR
12
13#include <__config>
14#include <memory>
15#include <new>
16#include <type_traits>
17
18#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
19#pragma GCC system_header
20#endif
21
22_LIBCPP_BEGIN_NAMESPACE_STD
23
24template <class _Tp, size_t _Np> class _LIBCPP_HIDDEN __sso_allocator;
25
26template <size_t _Np>
27class _LIBCPP_HIDDEN __sso_allocator<void, _Np>
28{
29public:
30 typedef const void* const_pointer;
31 typedef void value_type;
32};
33
34template <class _Tp, size_t _Np>
35class _LIBCPP_HIDDEN __sso_allocator
36{
37 typename aligned_storage<sizeof(_Tp) * _Np>::type buf_;
38 bool __allocated_;
39public:
40 typedef size_t size_type;
41 typedef _Tp* pointer;
42 typedef _Tp value_type;
43
44 _LIBCPP_INLINE_VISIBILITY __sso_allocator() throw() : __allocated_(false) {}
45 _LIBCPP_INLINE_VISIBILITY __sso_allocator(const __sso_allocator&) throw() : __allocated_(false) {}
46 template <class _Up> _LIBCPP_INLINE_VISIBILITY __sso_allocator(const __sso_allocator<_Up, _Np>&) throw()
47 : __allocated_(false) {}
48private:
49 __sso_allocator& operator=(const __sso_allocator&);
50public:
51 _LIBCPP_INLINE_VISIBILITY pointer allocate(size_type __n, typename __sso_allocator<void, _Np>::const_pointer = nullptr)
52 {
53 if (!__allocated_ && __n <= _Np)
54 {
55 __allocated_ = true;
56 return (pointer)&buf_;
57 }
58 return allocator<_Tp>().allocate(__n);
59 }
60 _LIBCPP_INLINE_VISIBILITY void deallocate(pointer __p, size_type __n)
61 {
62 if (__p == (pointer)&buf_)
63 __allocated_ = false;
64 else
65 allocator<_Tp>().deallocate(__p, __n);
66 }
67 _LIBCPP_INLINE_VISIBILITY size_type max_size() const throw() {return size_type(~0) / sizeof(_Tp);}
68
69 _LIBCPP_INLINE_VISIBILITY
70 bool operator==(__sso_allocator& __a) const {return &buf_ == &__a.buf_;}
71 _LIBCPP_INLINE_VISIBILITY
72 bool operator!=(__sso_allocator& __a) const {return &buf_ != &__a.buf_;}
73};
74
75_LIBCPP_END_NAMESPACE_STD
76
77#endif // _LIBCPP___SSO_ALLOCATOR
lib/libcxx/include/__std_stream+3-3
......@@ -11,10 +11,10 @@
1111#define _LIBCPP___STD_STREAM
1212
1313#include <__config>
14#include <ostream>
15#include <istream>
1614#include <__locale>
1715#include <cstdio>
16#include <istream>
17#include <ostream>
1818
1919#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2020#pragma GCC system_header
......@@ -358,4 +358,4 @@ _LIBCPP_END_NAMESPACE_STD
358358
359359_LIBCPP_POP_MACROS
360360
361#endif // _LIBCPP___STD_STREAM
361#endif // _LIBCPP___STD_STREAM
lib/libcxx/include/__string+19-53
......@@ -10,55 +10,21 @@
1010#ifndef _LIBCPP___STRING
1111#define _LIBCPP___STRING
1212
13/*
14 string synopsis
15
16namespace std
17{
18
19template <class charT>
20struct char_traits
21{
22 typedef charT char_type;
23 typedef ... int_type;
24 typedef streamoff off_type;
25 typedef streampos pos_type;
26 typedef mbstate_t state_type;
27
28 static constexpr void assign(char_type& c1, const char_type& c2) noexcept;
29 static constexpr bool eq(char_type c1, char_type c2) noexcept;
30 static constexpr bool lt(char_type c1, char_type c2) noexcept;
31
32 static constexpr int compare(const char_type* s1, const char_type* s2, size_t n);
33 static constexpr size_t length(const char_type* s);
34 static constexpr const char_type*
35 find(const char_type* s, size_t n, const char_type& a);
36
37 static constexpr char_type* move(char_type* s1, const char_type* s2, size_t n); // constexpr in C++20
38 static constexpr char_type* copy(char_type* s1, const char_type* s2, size_t n); // constexpr in C++20
39 static constexpr char_type* assign(char_type* s, size_t n, char_type a); // constexpr in C++20
40
41 static constexpr int_type not_eof(int_type c) noexcept;
42 static constexpr char_type to_char_type(int_type c) noexcept;
43 static constexpr int_type to_int_type(char_type c) noexcept;
44 static constexpr bool eq_int_type(int_type c1, int_type c2) noexcept;
45 static constexpr int_type eof() noexcept;
46};
47
48template <> struct char_traits<char>;
49template <> struct char_traits<wchar_t>;
50template <> struct char_traits<char8_t>; // c++20
51
52} // std
53
54*/
55
5613#include <__config>
57#include <algorithm> // for search and min
58#include <cstdio> // for EOF
59#include <cstring> // for memcpy
60#include <cwchar> // for wmemcpy
61#include <memory> // for __murmur2_or_cityhash
14#include <__algorithm/copy.h>
15#include <__algorithm/copy_backward.h>
16#include <__algorithm/copy_n.h>
17#include <__algorithm/fill_n.h>
18#include <__algorithm/find_first_of.h>
19#include <__algorithm/find_end.h>
20#include <__algorithm/min.h>
21#include <__functional/hash.h> // for __murmur2_or_cityhash
22#include <__iterator/iterator_traits.h>
23#include <cstdio> // for EOF
24#include <cstdint> // for uint_least16_t
25#include <cstring> // for memcpy
26#include <cwchar> // for wmemcpy
27#include <type_traits> // for __libcpp_is_constant_evaluated
6228
6329#include <__debug>
6430
......@@ -581,7 +547,7 @@ char_traits<wchar_t>::find(const char_type* __s, size_t __n, const char_type& __
581547}
582548
583549
584#ifndef _LIBCPP_NO_HAS_CHAR8_T
550#ifndef _LIBCPP_HAS_NO_CHAR8_T
585551
586552template <>
587553struct _LIBCPP_TEMPLATE_VIS char_traits<char8_t>
......@@ -688,7 +654,7 @@ char_traits<char8_t>::find(const char_type* __s, size_t __n, const char_type& __
688654 return nullptr;
689655}
690656
691#endif // #_LIBCPP_NO_HAS_CHAR8_T
657#endif // #_LIBCPP_HAS_NO_CHAR8_T
692658
693659#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
694660
......@@ -932,7 +898,7 @@ char_traits<char32_t>::assign(char_type* __s, size_t __n, char_type __a) _NOEXCE
932898 return __r;
933899}
934900
935#endif // _LIBCPP_HAS_NO_UNICODE_CHARS
901#endif // _LIBCPP_HAS_NO_UNICODE_CHARS
936902
937903// helper fns for basic_string and string_view
938904
......@@ -953,7 +919,7 @@ __str_find(const _CharT *__p, _SizeT __sz,
953919template <class _CharT, class _Traits>
954920inline _LIBCPP_CONSTEXPR_AFTER_CXX11 const _CharT *
955921__search_substring(const _CharT *__first1, const _CharT *__last1,
956 const _CharT *__first2, const _CharT *__last2) {
922 const _CharT *__first2, const _CharT *__last2) _NOEXCEPT {
957923 // Take advantage of knowing source and pattern lengths.
958924 // Stop short when source is smaller than pattern.
959925 const ptrdiff_t __len2 = __last2 - __first2;
......@@ -1177,4 +1143,4 @@ _LIBCPP_END_NAMESPACE_STD
11771143
11781144_LIBCPP_POP_MACROS
11791145
1180#endif // _LIBCPP___STRING
1146#endif // _LIBCPP___STRING
lib/libcxx/include/__support/ibm/gettod_zos.h created+53
......@@ -0,0 +1,53 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP_SUPPORT_IBM_GETTOD_ZOS_H
11#define _LIBCPP_SUPPORT_IBM_GETTOD_ZOS_H
12
13#include <time.h>
14
15static inline int gettimeofdayMonotonic(struct timespec64* Output) {
16
17 // The POSIX gettimeofday() function is not available on z/OS. Therefore,
18 // we will call stcke and other hardware instructions in implement equivalent.
19 // Note that nanoseconds alone will overflow when reaching new epoch in 2042.
20
21 struct _t {
22 uint64_t Hi;
23 uint64_t Lo;
24 };
25 struct _t Value = {0, 0};
26 uint64_t CC = 0;
27 asm(" stcke %0\n"
28 " ipm %1\n"
29 " srlg %1,%1,28\n"
30 : "=m"(Value), "+r"(CC)::);
31
32 if (CC != 0) {
33 errno = EMVSTODNOTSET;
34 return CC;
35 }
36 uint64_t us = (Value.Hi >> 4);
37 uint64_t ns = ((Value.Hi & 0x0F) << 8) + (Value.Lo >> 56);
38 ns = (ns * 1000) >> 12;
39 us = us - 2208988800000000;
40
41 register uint64_t DivPair0 asm("r0"); // dividend (upper half), remainder
42 DivPair0 = 0;
43 register uint64_t DivPair1 asm("r1"); // dividend (lower half), quotient
44 DivPair1 = us;
45 uint64_t Divisor = 1000000;
46 asm(" dlgr %0,%2" : "+r"(DivPair0), "+r"(DivPair1) : "r"(Divisor) :);
47
48 Output->tv_sec = DivPair1;
49 Output->tv_nsec = DivPair0 * 1000 + ns;
50 return 0;
51}
52
53#endif // _LIBCPP_SUPPORT_IBM_GETTOD_ZOS_H
lib/libcxx/include/__support/ibm/locale_mgmt_zos.h created+53
......@@ -0,0 +1,53 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP_SUPPORT_IBM_LOCALE_MGMT_ZOS_H
11#define _LIBCPP_SUPPORT_IBM_LOCALE_MGMT_ZOS_H
12
13#if defined(__MVS__)
14#include <locale.h>
15#include <string>
16
17#ifdef __cplusplus
18extern "C" {
19#endif
20
21#define _LC_MAX LC_MESSAGES /* highest real category */
22#define _NCAT (_LC_MAX + 1) /* maximum + 1 */
23
24#define _CATMASK(n) (1 << (n))
25#define LC_COLLATE_MASK _CATMASK(LC_COLLATE)
26#define LC_CTYPE_MASK _CATMASK(LC_CTYPE)
27#define LC_MONETARY_MASK _CATMASK(LC_MONETARY)
28#define LC_NUMERIC_MASK _CATMASK(LC_NUMERIC)
29#define LC_TIME_MASK _CATMASK(LC_TIME)
30#define LC_MESSAGES_MASK _CATMASK(LC_MESSAGES)
31#define LC_ALL_MASK (_CATMASK(_NCAT) - 1)
32
33typedef struct locale_struct {
34 int category_mask;
35 std::string lc_collate;
36 std::string lc_ctype;
37 std::string lc_monetary;
38 std::string lc_numeric;
39 std::string lc_time;
40 std::string lc_messages;
41} * locale_t;
42
43// z/OS does not have newlocale, freelocale and uselocale.
44// The functions below are workarounds in single thread mode.
45locale_t newlocale(int category_mask, const char* locale, locale_t base);
46void freelocale(locale_t locobj);
47locale_t uselocale(locale_t newloc);
48
49#ifdef __cplusplus
50}
51#endif
52#endif // defined(__MVS__)
53#endif // _LIBCPP_SUPPORT_IBM_LOCALE_MGMT_ZOS_H
lib/libcxx/include/__support/ibm/nanosleep.h+39-21
......@@ -12,27 +12,45 @@
1212
1313#include <unistd.h>
1414
15inline int nanosleep(const struct timespec* req, struct timespec* rem)
16{
17 // The nanosleep() function is not available on z/OS. Therefore, we will call
18 // sleep() to sleep for whole seconds and usleep() to sleep for any remaining
19 // fraction of a second. Any remaining nanoseconds will round up to the next
20 // microsecond.
21
22 useconds_t __micro_sec = (rem->tv_nsec + 999) / 1000;
23 if (__micro_sec > 999999)
24 {
25 ++rem->tv_sec;
26 __micro_sec -= 1000000;
27 }
28 while (rem->tv_sec)
29 rem->tv_sec = sleep(rem->tv_sec);
30 if (__micro_sec) {
31 rem->tv_nsec = __micro_sec * 1000;
32 return usleep(__micro_sec);
33 }
34 rem->tv_nsec = 0;
35 return 0;
15inline int nanosleep(const struct timespec* __req, struct timespec* __rem) {
16 // The nanosleep() function is not available on z/OS. Therefore, we will call
17 // sleep() to sleep for whole seconds and usleep() to sleep for any remaining
18 // fraction of a second. Any remaining nanoseconds will round up to the next
19 // microsecond.
20 if (__req->tv_sec < 0 || __req->tv_nsec < 0 || __req->tv_nsec > 999999999) {
21 errno = EINVAL;
22 return -1;
23 }
24 useconds_t __micro_sec =
25 static_cast<useconds_t>((__req->tv_nsec + 999) / 1000);
26 time_t __sec = __req->tv_sec;
27 if (__micro_sec > 999999) {
28 ++__sec;
29 __micro_sec -= 1000000;
30 }
31 __sec = sleep(static_cast<unsigned int>(__sec));
32 if (__sec) {
33 if (__rem) {
34 // Updating the remaining time to sleep in case of unsuccessful call to sleep().
35 __rem->tv_sec = __sec;
36 __rem->tv_nsec = __micro_sec * 1000;
37 }
38 errno = EINTR;
39 return -1;
40 }
41 if (__micro_sec) {
42 int __rt = usleep(__micro_sec);
43 if (__rt != 0 && __rem) {
44 // The usleep() does not provide the amount of remaining time upon its failure,
45 // so the time slept will be ignored.
46 __rem->tv_sec = 0;
47 __rem->tv_nsec = __micro_sec * 1000;
48 // The errno is already set.
49 return -1;
50 }
51 return __rt;
52 }
53 return 0;
3654}
3755
3856#endif // _LIBCPP_SUPPORT_IBM_NANOSLEEP_H
lib/libcxx/include/__support/ibm/xlocale.h+67-9
......@@ -11,6 +11,8 @@
1111#define _LIBCPP_SUPPORT_IBM_XLOCALE_H
1212
1313#include <__support/ibm/locale_mgmt_aix.h>
14#include <__support/ibm/locale_mgmt_zos.h>
15#include <stdarg.h>
1416
1517#include "cstdlib"
1618
......@@ -210,11 +212,13 @@ size_t wcsxfrm_l(wchar_t *__ws1, const wchar_t *__ws2, size_t __n,
210212
211213// strftime_l() is defined by POSIX. However, AIX 7.1 and z/OS do not have it
212214// implemented yet. z/OS retrieves it from the POSIX fallbacks.
215#if !defined(_AIX72)
213216static inline
214217size_t strftime_l(char *__s, size_t __size, const char *__fmt,
215218 const struct tm *__tm, locale_t locale) {
216219 return __xstrftime(locale, __s, __size, __fmt, __tm);
217220}
221#endif
218222
219223#elif defined(__MVS__)
220224#include <wctype.h>
......@@ -222,47 +226,101 @@ size_t strftime_l(char *__s, size_t __size, const char *__fmt,
222226#include <__support/xlocale/__posix_l_fallback.h>
223227#endif // defined(__MVS__)
224228
229namespace {
230
231struct __setAndRestore {
232 explicit __setAndRestore(locale_t locale) {
233 if (locale == (locale_t)0) {
234 __cloc = newlocale(LC_ALL_MASK, "C", /* base */ (locale_t)0);
235 __stored = uselocale(__cloc);
236 } else {
237 __stored = uselocale(locale);
238 }
239 }
240
241 ~__setAndRestore() {
242 uselocale(__stored);
243 if (__cloc)
244 freelocale(__cloc);
245 }
246
247private:
248 locale_t __stored = (locale_t)0;
249 locale_t __cloc = (locale_t)0;
250};
251
252} // namespace
253
225254// The following are not POSIX routines. These are quick-and-dirty hacks
226255// to make things pretend to work
227256static inline
228257long long strtoll_l(const char *__nptr, char **__endptr,
229258 int __base, locale_t locale) {
259 __setAndRestore __newloc(locale);
230260 return strtoll(__nptr, __endptr, __base);
231261}
262
232263static inline
233264long strtol_l(const char *__nptr, char **__endptr,
234265 int __base, locale_t locale) {
266 __setAndRestore __newloc(locale);
235267 return strtol(__nptr, __endptr, __base);
236268}
269
270static inline
271double strtod_l(const char *__nptr, char **__endptr,
272 locale_t locale) {
273 __setAndRestore __newloc(locale);
274 return strtod(__nptr, __endptr);
275}
276
277static inline
278float strtof_l(const char *__nptr, char **__endptr,
279 locale_t locale) {
280 __setAndRestore __newloc(locale);
281 return strtof(__nptr, __endptr);
282}
283
237284static inline
238285long double strtold_l(const char *__nptr, char **__endptr,
239286 locale_t locale) {
287 __setAndRestore __newloc(locale);
240288 return strtold(__nptr, __endptr);
241289}
290
242291static inline
243292unsigned long long strtoull_l(const char *__nptr, char **__endptr,
244293 int __base, locale_t locale) {
294 __setAndRestore __newloc(locale);
245295 return strtoull(__nptr, __endptr, __base);
246296}
297
247298static inline
248299unsigned long strtoul_l(const char *__nptr, char **__endptr,
249300 int __base, locale_t locale) {
301 __setAndRestore __newloc(locale);
250302 return strtoul(__nptr, __endptr, __base);
251303}
252304
253305static inline
254int vasprintf(char **strp, const char *fmt, va_list ap)
255{
306int vasprintf(char **strp, const char *fmt, va_list ap) {
256307 const size_t buff_size = 256;
257 int str_size;
258 if ((*strp = (char *)malloc(buff_size)) == NULL)
259 {
308 if ((*strp = (char *)malloc(buff_size)) == NULL) {
260309 return -1;
261310 }
262 if ((str_size = vsnprintf(*strp, buff_size, fmt, ap)) >= buff_size)
263 {
264 if ((*strp = (char *)realloc(*strp, str_size + 1)) == NULL)
265 {
311
312 va_list ap_copy;
313 // va_copy may not be provided by the C library in C++ 03 mode.
314#if defined(_LIBCPP_CXX03_LANG) && __has_builtin(__builtin_va_copy)
315 __builtin_va_copy(ap_copy, ap);
316#else
317 va_copy(ap_copy, ap);
318#endif
319 int str_size = vsnprintf(*strp, buff_size, fmt, ap_copy);
320 va_end(ap_copy);
321
322 if ((size_t) str_size >= buff_size) {
323 if ((*strp = (char *)realloc(*strp, str_size + 1)) == NULL) {
266324 return -1;
267325 }
268326 str_size = vsnprintf(*strp, str_size + 1, fmt, ap);
lib/libcxx/include/__support/openbsd/xlocale.h+3-3
......@@ -10,10 +10,10 @@
1010#ifndef _LIBCPP_SUPPORT_OPENBSD_XLOCALE_H
1111#define _LIBCPP_SUPPORT_OPENBSD_XLOCALE_H
1212
13#include <cstdlib>
13#include <__support/xlocale/__strtonum_fallback.h>
1414#include <clocale>
15#include <cwctype>
15#include <cstdlib>
1616#include <ctype.h>
17#include <__support/xlocale/__strtonum_fallback.h>
17#include <cwctype>
1818
1919#endif
lib/libcxx/include/__support/win32/limits_msvc_win32.h+1-1
......@@ -17,8 +17,8 @@
1717#error "This header should only be included when using Microsofts C1XX frontend"
1818#endif
1919
20#include <limits.h> // CHAR_BIT
2120#include <float.h> // limit constants
21#include <limits.h> // CHAR_BIT
2222#include <math.h> // HUGE_VAL
2323#include <ymath.h> // internal MSVC header providing the needed functionality
2424
lib/libcxx/include/__support/win32/locale_win32.h+21-2
......@@ -11,9 +11,28 @@
1111#define _LIBCPP_SUPPORT_WIN32_LOCALE_WIN32_H
1212
1313#include <__config>
14#include <stdio.h>
15#include <xlocinfo.h> // _locale_t
1614#include <__nullptr>
15#include <locale.h> // _locale_t
16#include <stdio.h>
17
18#define _X_ALL LC_ALL
19#define _X_COLLATE LC_COLLATE
20#define _X_CTYPE LC_CTYPE
21#define _X_MONETARY LC_MONETARY
22#define _X_NUMERIC LC_NUMERIC
23#define _X_TIME LC_TIME
24#define _X_MAX LC_MAX
25#define _X_MESSAGES 6
26#define _NCAT (_X_MESSAGES + 1)
27
28#define _CATMASK(n) ((1 << (n)) >> 1)
29#define _M_COLLATE _CATMASK(_X_COLLATE)
30#define _M_CTYPE _CATMASK(_X_CTYPE)
31#define _M_MONETARY _CATMASK(_X_MONETARY)
32#define _M_NUMERIC _CATMASK(_X_NUMERIC)
33#define _M_TIME _CATMASK(_X_TIME)
34#define _M_MESSAGES _CATMASK(_X_MESSAGES)
35#define _M_ALL (_CATMASK(_NCAT) - 1)
1736
1837#define LC_COLLATE_MASK _M_COLLATE
1938#define LC_CTYPE_MASK _M_CTYPE
lib/libcxx/include/__threading_support+14-9
......@@ -10,11 +10,12 @@
1010#ifndef _LIBCPP_THREADING_SUPPORT
1111#define _LIBCPP_THREADING_SUPPORT
1212
13#include <__config>
1413#include <__availability>
14#include <__config>
1515#include <chrono>
16#include <iosfwd>
1716#include <errno.h>
17#include <iosfwd>
18#include <limits>
1819
1920#ifdef __MVS__
2021# include <__support/ibm/nanosleep.h>
......@@ -28,14 +29,15 @@
2829# include <__external_threading>
2930#elif !defined(_LIBCPP_HAS_NO_THREADS)
3031
32#if defined(__APPLE__) || defined(__MVS__)
33# define _LIBCPP_NO_NATIVE_SEMAPHORES
34#endif
35
3136#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
3237# include <pthread.h>
3338# include <sched.h>
34# if defined(__APPLE__) || defined(__MVS__)
35# define _LIBCPP_NO_NATIVE_SEMAPHORES
36# endif
3739# ifndef _LIBCPP_NO_NATIVE_SEMAPHORES
38# include <semaphore.h>
40# include <semaphore.h>
3941# endif
4042#elif defined(_LIBCPP_HAS_THREAD_API_C11)
4143# include <threads.h>
......@@ -149,6 +151,9 @@ typedef void* __libcpp_condvar_t;
149151
150152// Semaphore
151153typedef void* __libcpp_semaphore_t;
154#if defined(_LIBCPP_HAS_THREAD_API_WIN32)
155# define _LIBCPP_SEMAPHORE_MAX (::std::numeric_limits<long>::max())
156#endif
152157
153158// Execute Once
154159typedef void* __libcpp_exec_once_flag;
......@@ -390,7 +395,7 @@ bool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m)
390395 return pthread_mutex_trylock(__m) == 0;
391396}
392397
393int __libcpp_recursive_mutex_unlock(__libcpp_mutex_t *__m)
398int __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m)
394399{
395400 return pthread_mutex_unlock(__m);
396401}
......@@ -500,7 +505,7 @@ bool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2)
500505
501506// Thread
502507bool __libcpp_thread_isnull(const __libcpp_thread_t *__t) {
503 return *__t == __libcpp_thread_t();
508 return __libcpp_thread_get_id(__t) == 0;
504509}
505510
506511int __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *),
......@@ -578,7 +583,7 @@ bool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m)
578583 return mtx_trylock(__m) == thrd_success;
579584}
580585
581int __libcpp_recursive_mutex_unlock(__libcpp_mutex_t *__m)
586int __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m)
582587{
583588 return mtx_unlock(__m) == thrd_success ? 0 : EINVAL;
584589}
lib/libcxx/include/__tree+7-5
......@@ -11,10 +11,12 @@
1111#define _LIBCPP___TREE
1212
1313#include <__config>
14#include <__utility/forward.h>
15#include <algorithm>
1416#include <iterator>
17#include <limits>
1518#include <memory>
1619#include <stdexcept>
17#include <algorithm>
1820
1921#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2022#pragma GCC system_header
......@@ -714,7 +716,7 @@ public:
714716};
715717
716718template <class _VoidPtr>
717class __tree_node_base
719class _LIBCPP_STANDALONE_DEBUG __tree_node_base
718720 : public __tree_node_base_types<_VoidPtr>::__end_node_type
719721{
720722 typedef __tree_node_base_types<_VoidPtr> _NodeBaseTypes;
......@@ -742,7 +744,7 @@ private:
742744};
743745
744746template <class _Tp, class _VoidPtr>
745class __tree_node
747class _LIBCPP_STANDALONE_DEBUG __tree_node
746748 : public __tree_node_base<_VoidPtr>
747749{
748750public:
......@@ -2410,7 +2412,7 @@ __tree<_Tp, _Compare, _Allocator>::__node_handle_merge_multi(_Tree& __source)
24102412 }
24112413}
24122414
2413#endif // _LIBCPP_STD_VER > 14
2415#endif // _LIBCPP_STD_VER > 14
24142416
24152417template <class _Tp, class _Compare, class _Allocator>
24162418typename __tree<_Tp, _Compare, _Allocator>::iterator
......@@ -2743,4 +2745,4 @@ _LIBCPP_END_NAMESPACE_STD
27432745
27442746_LIBCPP_POP_MACROS
27452747
2746#endif // _LIBCPP___TREE
2748#endif // _LIBCPP___TREE
lib/libcxx/include/__tuple+2-2
......@@ -134,7 +134,7 @@ template<> struct __parity<7> { template<size_t _Np> struct __pmake : __repeat<t
134134
135135} // namespace detail
136136
137#endif // !__has_builtin(__make_integer_seq) || defined(_LIBCPP_TESTING_FALLBACK_MAKE_INTEGER_SEQUENCE)
137#endif // !__has_builtin(__make_integer_seq) || defined(_LIBCPP_TESTING_FALLBACK_MAKE_INTEGER_SEQUENCE)
138138
139139#if __has_builtin(__make_integer_seq)
140140template <size_t _Ep, size_t _Sp>
......@@ -548,4 +548,4 @@ struct __sfinae_assign_base<false, true> {
548548
549549_LIBCPP_END_NAMESPACE_STD
550550
551#endif // _LIBCPP___TUPLE
551#endif // _LIBCPP___TUPLE
lib/libcxx/include/__utility/__decay_copy.h created+39
......@@ -0,0 +1,39 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___TYPE_TRAITS_DECAY_COPY_H
11#define _LIBCPP___TYPE_TRAITS_DECAY_COPY_H
12
13#include <__config>
14#include <__utility/forward.h>
15#include <type_traits>
16
17#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
18#pragma GCC system_header
19#endif
20
21_LIBCPP_PUSH_MACROS
22#include <__undef_macros>
23
24_LIBCPP_BEGIN_NAMESPACE_STD
25
26template <class _Tp>
27inline _LIBCPP_INLINE_VISIBILITY typename decay<_Tp>::type __decay_copy(_Tp&& __t)
28#if _LIBCPP_STD_VER > 17
29 noexcept(is_nothrow_convertible_v<_Tp, remove_reference_t<_Tp> >)
30#endif
31{
32 return _VSTD::forward<_Tp>(__t);
33}
34
35_LIBCPP_END_NAMESPACE_STD
36
37_LIBCPP_POP_MACROS
38
39#endif // _LIBCPP___TYPE_TRAITS_DECAY_COPY_H
lib/libcxx/include/__utility/as_const.h created+38
......@@ -0,0 +1,38 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___UTILITY_AS_CONST_H
10#define _LIBCPP___UTILITY_AS_CONST_H
11
12#include <__config>
13#include <__utility/forward.h>
14#include <__utility/move.h>
15#include <type_traits>
16
17#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
18#pragma GCC system_header
19#endif
20
21_LIBCPP_PUSH_MACROS
22#include <__undef_macros>
23
24_LIBCPP_BEGIN_NAMESPACE_STD
25
26#if _LIBCPP_STD_VER > 14
27template <class _Tp>
28_LIBCPP_NODISCARD_EXT constexpr add_const_t<_Tp>& as_const(_Tp& __t) noexcept { return __t; }
29
30template <class _Tp>
31void as_const(const _Tp&&) = delete;
32#endif
33
34_LIBCPP_END_NAMESPACE_STD
35
36_LIBCPP_POP_MACROS
37
38#endif // _LIBCPP___UTILITY_AS_CONST_H
lib/libcxx/include/__utility/cmp.h created+107
......@@ -0,0 +1,107 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___UTILITY_CMP_H
10#define _LIBCPP___UTILITY_CMP_H
11
12#include <__config>
13#include <__utility/forward.h>
14#include <__utility/move.h>
15#include <limits>
16#include <type_traits>
17
18#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
19#pragma GCC system_header
20#endif
21
22_LIBCPP_PUSH_MACROS
23#include <__undef_macros>
24
25_LIBCPP_BEGIN_NAMESPACE_STD
26
27#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
28template<class _Tp, class... _Up>
29struct _IsSameAsAny : _Or<_IsSame<_Tp, _Up>...> {};
30
31template<class _Tp>
32concept __is_safe_integral_cmp = is_integral_v<_Tp> &&
33 !_IsSameAsAny<_Tp, bool, char,
34#ifndef _LIBCPP_HAS_NO_CHAR8_T
35 char8_t,
36#endif
37#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
38 char16_t, char32_t,
39#endif
40 wchar_t>::value;
41
42template<__is_safe_integral_cmp _Tp, __is_safe_integral_cmp _Up>
43_LIBCPP_INLINE_VISIBILITY constexpr
44bool cmp_equal(_Tp __t, _Up __u) noexcept
45{
46 if constexpr (is_signed_v<_Tp> == is_signed_v<_Up>)
47 return __t == __u;
48 else if constexpr (is_signed_v<_Tp>)
49 return __t < 0 ? false : make_unsigned_t<_Tp>(__t) == __u;
50 else
51 return __u < 0 ? false : __t == make_unsigned_t<_Up>(__u);
52}
53
54template<__is_safe_integral_cmp _Tp, __is_safe_integral_cmp _Up>
55_LIBCPP_INLINE_VISIBILITY constexpr
56bool cmp_not_equal(_Tp __t, _Up __u) noexcept
57{
58 return !_VSTD::cmp_equal(__t, __u);
59}
60
61template<__is_safe_integral_cmp _Tp, __is_safe_integral_cmp _Up>
62_LIBCPP_INLINE_VISIBILITY constexpr
63bool cmp_less(_Tp __t, _Up __u) noexcept
64{
65 if constexpr (is_signed_v<_Tp> == is_signed_v<_Up>)
66 return __t < __u;
67 else if constexpr (is_signed_v<_Tp>)
68 return __t < 0 ? true : make_unsigned_t<_Tp>(__t) < __u;
69 else
70 return __u < 0 ? false : __t < make_unsigned_t<_Up>(__u);
71}
72
73template<__is_safe_integral_cmp _Tp, __is_safe_integral_cmp _Up>
74_LIBCPP_INLINE_VISIBILITY constexpr
75bool cmp_greater(_Tp __t, _Up __u) noexcept
76{
77 return _VSTD::cmp_less(__u, __t);
78}
79
80template<__is_safe_integral_cmp _Tp, __is_safe_integral_cmp _Up>
81_LIBCPP_INLINE_VISIBILITY constexpr
82bool cmp_less_equal(_Tp __t, _Up __u) noexcept
83{
84 return !_VSTD::cmp_greater(__t, __u);
85}
86
87template<__is_safe_integral_cmp _Tp, __is_safe_integral_cmp _Up>
88_LIBCPP_INLINE_VISIBILITY constexpr
89bool cmp_greater_equal(_Tp __t, _Up __u) noexcept
90{
91 return !_VSTD::cmp_less(__t, __u);
92}
93
94template<__is_safe_integral_cmp _Tp, __is_safe_integral_cmp _Up>
95_LIBCPP_INLINE_VISIBILITY constexpr
96bool in_range(_Up __u) noexcept
97{
98 return _VSTD::cmp_less_equal(__u, numeric_limits<_Tp>::max()) &&
99 _VSTD::cmp_greater_equal(__u, numeric_limits<_Tp>::min());
100}
101#endif
102
103_LIBCPP_END_NAMESPACE_STD
104
105_LIBCPP_POP_MACROS
106
107#endif // _LIBCPP___UTILITY_CMP_H
lib/libcxx/include/__utility/declval.h created+39
......@@ -0,0 +1,39 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___UTILITY_DECLVAL_H
10#define _LIBCPP___UTILITY_DECLVAL_H
11
12#include <__config>
13
14#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
15#pragma GCC system_header
16#endif
17
18_LIBCPP_PUSH_MACROS
19#include <__undef_macros>
20
21_LIBCPP_BEGIN_NAMESPACE_STD
22
23// Suppress deprecation notice for volatile-qualified return type resulting
24// from volatile-qualified types _Tp.
25_LIBCPP_SUPPRESS_DEPRECATED_PUSH
26template <class _Tp>
27_Tp&& __declval(int);
28template <class _Tp>
29_Tp __declval(long);
30_LIBCPP_SUPPRESS_DEPRECATED_POP
31
32template <class _Tp>
33decltype(__declval<_Tp>(0)) declval() _NOEXCEPT;
34
35_LIBCPP_END_NAMESPACE_STD
36
37_LIBCPP_POP_MACROS
38
39#endif // _LIBCPP___UTILITY_DECLVAL_H
lib/libcxx/include/__utility/exchange.h created+40
......@@ -0,0 +1,40 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___UTILITY_EXCHANGE_H
10#define _LIBCPP___UTILITY_EXCHANGE_H
11
12#include <__config>
13#include <__utility/forward.h>
14#include <__utility/move.h>
15
16#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
17#pragma GCC system_header
18#endif
19
20_LIBCPP_PUSH_MACROS
21#include <__undef_macros>
22
23_LIBCPP_BEGIN_NAMESPACE_STD
24
25#if _LIBCPP_STD_VER > 11
26template<class _T1, class _T2 = _T1>
27inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
28_T1 exchange(_T1& __obj, _T2 && __new_value)
29{
30 _T1 __old_value = _VSTD::move(__obj);
31 __obj = _VSTD::forward<_T2>(__new_value);
32 return __old_value;
33}
34#endif // _LIBCPP_STD_VER > 11
35
36_LIBCPP_END_NAMESPACE_STD
37
38_LIBCPP_POP_MACROS
39
40#endif // _LIBCPP___UTILITY_EXCHANGE_H
lib/libcxx/include/__utility/forward.h created+42
......@@ -0,0 +1,42 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___UTILITY_FORWARD_H
11#define _LIBCPP___UTILITY_FORWARD_H
12
13#include <__config>
14#include <type_traits>
15
16#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
17#pragma GCC system_header
18#endif
19
20_LIBCPP_PUSH_MACROS
21#include <__undef_macros>
22
23_LIBCPP_BEGIN_NAMESPACE_STD
24
25template <class _Tp>
26_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR _Tp&&
27forward(typename remove_reference<_Tp>::type& __t) _NOEXCEPT {
28 return static_cast<_Tp&&>(__t);
29}
30
31template <class _Tp>
32_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR _Tp&&
33forward(typename remove_reference<_Tp>::type&& __t) _NOEXCEPT {
34 static_assert(!is_lvalue_reference<_Tp>::value, "cannot forward an rvalue as an lvalue");
35 return static_cast<_Tp&&>(__t);
36}
37
38_LIBCPP_END_NAMESPACE_STD
39
40_LIBCPP_POP_MACROS
41
42#endif // _LIBCPP___UTILITY_FORWARD_H
lib/libcxx/include/__utility/in_place.h created+63
......@@ -0,0 +1,63 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___UTILITY_IN_PLACE_H
10#define _LIBCPP___UTILITY_IN_PLACE_H
11
12#include <__config>
13#include <type_traits>
14
15#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
16#pragma GCC system_header
17#endif
18
19_LIBCPP_PUSH_MACROS
20#include <__undef_macros>
21
22_LIBCPP_BEGIN_NAMESPACE_STD
23
24#if _LIBCPP_STD_VER > 14
25
26struct _LIBCPP_TYPE_VIS in_place_t {
27 explicit in_place_t() = default;
28};
29_LIBCPP_INLINE_VAR constexpr in_place_t in_place{};
30
31template <class _Tp>
32struct _LIBCPP_TEMPLATE_VIS in_place_type_t {
33 explicit in_place_type_t() = default;
34};
35template <class _Tp>
36_LIBCPP_INLINE_VAR constexpr in_place_type_t<_Tp> in_place_type{};
37
38template <size_t _Idx>
39struct _LIBCPP_TEMPLATE_VIS in_place_index_t {
40 explicit in_place_index_t() = default;
41};
42template <size_t _Idx>
43_LIBCPP_INLINE_VAR constexpr in_place_index_t<_Idx> in_place_index{};
44
45template <class _Tp> struct __is_inplace_type_imp : false_type {};
46template <class _Tp> struct __is_inplace_type_imp<in_place_type_t<_Tp>> : true_type {};
47
48template <class _Tp>
49using __is_inplace_type = __is_inplace_type_imp<__uncvref_t<_Tp>>;
50
51template <class _Tp> struct __is_inplace_index_imp : false_type {};
52template <size_t _Idx> struct __is_inplace_index_imp<in_place_index_t<_Idx>> : true_type {};
53
54template <class _Tp>
55using __is_inplace_index = __is_inplace_index_imp<__uncvref_t<_Tp>>;
56
57#endif // _LIBCPP_STD_VER > 14
58
59_LIBCPP_END_NAMESPACE_STD
60
61_LIBCPP_POP_MACROS
62
63#endif // _LIBCPP___UTILITY_IN_PLACE_H
lib/libcxx/include/__utility/integer_sequence.h created+83
......@@ -0,0 +1,83 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___UTILITY_INTEGER_SEQUENCE_H
10#define _LIBCPP___UTILITY_INTEGER_SEQUENCE_H
11
12#include <__config>
13#include <type_traits>
14
15#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
16#pragma GCC system_header
17#endif
18
19_LIBCPP_PUSH_MACROS
20#include <__undef_macros>
21
22_LIBCPP_BEGIN_NAMESPACE_STD
23
24#if _LIBCPP_STD_VER > 11
25
26template<class _Tp, _Tp... _Ip>
27struct _LIBCPP_TEMPLATE_VIS integer_sequence
28{
29 typedef _Tp value_type;
30 static_assert( is_integral<_Tp>::value,
31 "std::integer_sequence can only be instantiated with an integral type" );
32 static
33 _LIBCPP_INLINE_VISIBILITY
34 constexpr
35 size_t
36 size() noexcept { return sizeof...(_Ip); }
37};
38
39template<size_t... _Ip>
40 using index_sequence = integer_sequence<size_t, _Ip...>;
41
42#if __has_builtin(__make_integer_seq) && !defined(_LIBCPP_TESTING_FALLBACK_MAKE_INTEGER_SEQUENCE)
43
44template <class _Tp, _Tp _Ep>
45using __make_integer_sequence _LIBCPP_NODEBUG_TYPE = __make_integer_seq<integer_sequence, _Tp, _Ep>;
46
47#else
48
49template<typename _Tp, _Tp _Np> using __make_integer_sequence_unchecked _LIBCPP_NODEBUG_TYPE =
50 typename __detail::__make<_Np>::type::template __convert<integer_sequence, _Tp>;
51
52template <class _Tp, _Tp _Ep>
53struct __make_integer_sequence_checked
54{
55 static_assert(is_integral<_Tp>::value,
56 "std::make_integer_sequence can only be instantiated with an integral type" );
57 static_assert(0 <= _Ep, "std::make_integer_sequence must have a non-negative sequence length");
58 // Workaround GCC bug by preventing bad installations when 0 <= _Ep
59 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68929
60 typedef _LIBCPP_NODEBUG_TYPE __make_integer_sequence_unchecked<_Tp, 0 <= _Ep ? _Ep : 0> type;
61};
62
63template <class _Tp, _Tp _Ep>
64using __make_integer_sequence _LIBCPP_NODEBUG_TYPE = typename __make_integer_sequence_checked<_Tp, _Ep>::type;
65
66#endif
67
68template<class _Tp, _Tp _Np>
69 using make_integer_sequence = __make_integer_sequence<_Tp, _Np>;
70
71template<size_t _Np>
72 using make_index_sequence = make_integer_sequence<size_t, _Np>;
73
74template<class... _Tp>
75 using index_sequence_for = make_index_sequence<sizeof...(_Tp)>;
76
77#endif // _LIBCPP_STD_VER > 11
78
79_LIBCPP_END_NAMESPACE_STD
80
81_LIBCPP_POP_MACROS
82
83#endif // _LIBCPP___UTILITY_INTEGER_SEQUENCE_H
lib/libcxx/include/__utility/move.h created+52
......@@ -0,0 +1,52 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___UTILITY_MOVE_H
11#define _LIBCPP___UTILITY_MOVE_H
12
13#include <__config>
14#include <type_traits>
15
16#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
17#pragma GCC system_header
18#endif
19
20_LIBCPP_PUSH_MACROS
21#include <__undef_macros>
22
23_LIBCPP_BEGIN_NAMESPACE_STD
24
25template <class _Tp>
26_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR typename remove_reference<_Tp>::type&&
27move(_Tp&& __t) _NOEXCEPT {
28 typedef _LIBCPP_NODEBUG_TYPE typename remove_reference<_Tp>::type _Up;
29 return static_cast<_Up&&>(__t);
30}
31
32#ifndef _LIBCPP_CXX03_LANG
33template <class _Tp>
34using __move_if_noexcept_result_t =
35 typename conditional<!is_nothrow_move_constructible<_Tp>::value && is_copy_constructible<_Tp>::value, const _Tp&,
36 _Tp&&>::type;
37#else // _LIBCPP_CXX03_LANG
38template <class _Tp>
39using __move_if_noexcept_result_t = const _Tp&;
40#endif
41
42template <class _Tp>
43_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 __move_if_noexcept_result_t<_Tp>
44move_if_noexcept(_Tp& __x) _NOEXCEPT {
45 return _VSTD::move(__x);
46}
47
48_LIBCPP_END_NAMESPACE_STD
49
50_LIBCPP_POP_MACROS
51
52#endif // _LIBCPP___UTILITY_MOVE_H
lib/libcxx/include/__utility/pair.h created+585
......@@ -0,0 +1,585 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___UTILITY_PAIR_H
10#define _LIBCPP___UTILITY_PAIR_H
11
12#include <__config>
13#include <__functional/unwrap_ref.h>
14#include <__tuple>
15#include <__utility/forward.h>
16#include <__utility/move.h>
17#include <__utility/piecewise_construct.h>
18#include <cstddef>
19#include <type_traits>
20
21#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
22#pragma GCC system_header
23#endif
24
25_LIBCPP_PUSH_MACROS
26#include <__undef_macros>
27
28_LIBCPP_BEGIN_NAMESPACE_STD
29
30
31#if defined(_LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR)
32template <class, class>
33struct __non_trivially_copyable_base {
34 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
35 __non_trivially_copyable_base() _NOEXCEPT {}
36 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
37 __non_trivially_copyable_base(__non_trivially_copyable_base const&) _NOEXCEPT {}
38};
39#endif
40
41template <class _T1, class _T2>
42struct _LIBCPP_TEMPLATE_VIS pair
43#if defined(_LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR)
44: private __non_trivially_copyable_base<_T1, _T2>
45#endif
46{
47 typedef _T1 first_type;
48 typedef _T2 second_type;
49
50 _T1 first;
51 _T2 second;
52
53#if !defined(_LIBCPP_CXX03_LANG)
54 pair(pair const&) = default;
55 pair(pair&&) = default;
56#else
57 // Use the implicitly declared copy constructor in C++03
58#endif
59
60#ifdef _LIBCPP_CXX03_LANG
61 _LIBCPP_INLINE_VISIBILITY
62 pair() : first(), second() {}
63
64 _LIBCPP_INLINE_VISIBILITY
65 pair(_T1 const& __t1, _T2 const& __t2) : first(__t1), second(__t2) {}
66
67 template <class _U1, class _U2>
68 _LIBCPP_INLINE_VISIBILITY
69 pair(const pair<_U1, _U2>& __p) : first(__p.first), second(__p.second) {}
70
71 _LIBCPP_INLINE_VISIBILITY
72 pair& operator=(pair const& __p) {
73 first = __p.first;
74 second = __p.second;
75 return *this;
76 }
77#else
78 template <bool _Val>
79 using _EnableB _LIBCPP_NODEBUG_TYPE = typename enable_if<_Val, bool>::type;
80
81 struct _CheckArgs {
82 template <int&...>
83 static constexpr bool __enable_explicit_default() {
84 return is_default_constructible<_T1>::value
85 && is_default_constructible<_T2>::value
86 && !__enable_implicit_default<>();
87 }
88
89 template <int&...>
90 static constexpr bool __enable_implicit_default() {
91 return __is_implicitly_default_constructible<_T1>::value
92 && __is_implicitly_default_constructible<_T2>::value;
93 }
94
95 template <class _U1, class _U2>
96 static constexpr bool __enable_explicit() {
97 return is_constructible<first_type, _U1>::value
98 && is_constructible<second_type, _U2>::value
99 && (!is_convertible<_U1, first_type>::value
100 || !is_convertible<_U2, second_type>::value);
101 }
102
103 template <class _U1, class _U2>
104 static constexpr bool __enable_implicit() {
105 return is_constructible<first_type, _U1>::value
106 && is_constructible<second_type, _U2>::value
107 && is_convertible<_U1, first_type>::value
108 && is_convertible<_U2, second_type>::value;
109 }
110 };
111
112 template <bool _MaybeEnable>
113 using _CheckArgsDep _LIBCPP_NODEBUG_TYPE = typename conditional<
114 _MaybeEnable, _CheckArgs, __check_tuple_constructor_fail>::type;
115
116 struct _CheckTupleLikeConstructor {
117 template <class _Tuple>
118 static constexpr bool __enable_implicit() {
119 return __tuple_convertible<_Tuple, pair>::value;
120 }
121
122 template <class _Tuple>
123 static constexpr bool __enable_explicit() {
124 return __tuple_constructible<_Tuple, pair>::value
125 && !__tuple_convertible<_Tuple, pair>::value;
126 }
127
128 template <class _Tuple>
129 static constexpr bool __enable_assign() {
130 return __tuple_assignable<_Tuple, pair>::value;
131 }
132 };
133
134 template <class _Tuple>
135 using _CheckTLC _LIBCPP_NODEBUG_TYPE = typename conditional<
136 __tuple_like_with_size<_Tuple, 2>::value
137 && !is_same<typename decay<_Tuple>::type, pair>::value,
138 _CheckTupleLikeConstructor,
139 __check_tuple_constructor_fail
140 >::type;
141
142 template<bool _Dummy = true, _EnableB<
143 _CheckArgsDep<_Dummy>::__enable_explicit_default()
144 > = false>
145 explicit _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
146 pair() _NOEXCEPT_(is_nothrow_default_constructible<first_type>::value &&
147 is_nothrow_default_constructible<second_type>::value)
148 : first(), second() {}
149
150 template<bool _Dummy = true, _EnableB<
151 _CheckArgsDep<_Dummy>::__enable_implicit_default()
152 > = false>
153 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
154 pair() _NOEXCEPT_(is_nothrow_default_constructible<first_type>::value &&
155 is_nothrow_default_constructible<second_type>::value)
156 : first(), second() {}
157
158 template <bool _Dummy = true, _EnableB<
159 _CheckArgsDep<_Dummy>::template __enable_explicit<_T1 const&, _T2 const&>()
160 > = false>
161 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
162 explicit pair(_T1 const& __t1, _T2 const& __t2)
163 _NOEXCEPT_(is_nothrow_copy_constructible<first_type>::value &&
164 is_nothrow_copy_constructible<second_type>::value)
165 : first(__t1), second(__t2) {}
166
167 template<bool _Dummy = true, _EnableB<
168 _CheckArgsDep<_Dummy>::template __enable_implicit<_T1 const&, _T2 const&>()
169 > = false>
170 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
171 pair(_T1 const& __t1, _T2 const& __t2)
172 _NOEXCEPT_(is_nothrow_copy_constructible<first_type>::value &&
173 is_nothrow_copy_constructible<second_type>::value)
174 : first(__t1), second(__t2) {}
175
176 template<class _U1, class _U2, _EnableB<
177 _CheckArgs::template __enable_explicit<_U1, _U2>()
178 > = false>
179 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
180 explicit pair(_U1&& __u1, _U2&& __u2)
181 _NOEXCEPT_((is_nothrow_constructible<first_type, _U1>::value &&
182 is_nothrow_constructible<second_type, _U2>::value))
183 : first(_VSTD::forward<_U1>(__u1)), second(_VSTD::forward<_U2>(__u2)) {}
184
185 template<class _U1, class _U2, _EnableB<
186 _CheckArgs::template __enable_implicit<_U1, _U2>()
187 > = false>
188 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
189 pair(_U1&& __u1, _U2&& __u2)
190 _NOEXCEPT_((is_nothrow_constructible<first_type, _U1>::value &&
191 is_nothrow_constructible<second_type, _U2>::value))
192 : first(_VSTD::forward<_U1>(__u1)), second(_VSTD::forward<_U2>(__u2)) {}
193
194 template<class _U1, class _U2, _EnableB<
195 _CheckArgs::template __enable_explicit<_U1 const&, _U2 const&>()
196 > = false>
197 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
198 explicit pair(pair<_U1, _U2> const& __p)
199 _NOEXCEPT_((is_nothrow_constructible<first_type, _U1 const&>::value &&
200 is_nothrow_constructible<second_type, _U2 const&>::value))
201 : first(__p.first), second(__p.second) {}
202
203 template<class _U1, class _U2, _EnableB<
204 _CheckArgs::template __enable_implicit<_U1 const&, _U2 const&>()
205 > = false>
206 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
207 pair(pair<_U1, _U2> const& __p)
208 _NOEXCEPT_((is_nothrow_constructible<first_type, _U1 const&>::value &&
209 is_nothrow_constructible<second_type, _U2 const&>::value))
210 : first(__p.first), second(__p.second) {}
211
212 template<class _U1, class _U2, _EnableB<
213 _CheckArgs::template __enable_explicit<_U1, _U2>()
214 > = false>
215 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
216 explicit pair(pair<_U1, _U2>&&__p)
217 _NOEXCEPT_((is_nothrow_constructible<first_type, _U1&&>::value &&
218 is_nothrow_constructible<second_type, _U2&&>::value))
219 : first(_VSTD::forward<_U1>(__p.first)), second(_VSTD::forward<_U2>(__p.second)) {}
220
221 template<class _U1, class _U2, _EnableB<
222 _CheckArgs::template __enable_implicit<_U1, _U2>()
223 > = false>
224 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
225 pair(pair<_U1, _U2>&& __p)
226 _NOEXCEPT_((is_nothrow_constructible<first_type, _U1&&>::value &&
227 is_nothrow_constructible<second_type, _U2&&>::value))
228 : first(_VSTD::forward<_U1>(__p.first)), second(_VSTD::forward<_U2>(__p.second)) {}
229
230 template<class _Tuple, _EnableB<
231 _CheckTLC<_Tuple>::template __enable_explicit<_Tuple>()
232 > = false>
233 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
234 explicit pair(_Tuple&& __p)
235 : first(_VSTD::get<0>(_VSTD::forward<_Tuple>(__p))),
236 second(_VSTD::get<1>(_VSTD::forward<_Tuple>(__p))) {}
237
238 template<class _Tuple, _EnableB<
239 _CheckTLC<_Tuple>::template __enable_implicit<_Tuple>()
240 > = false>
241 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
242 pair(_Tuple&& __p)
243 : first(_VSTD::get<0>(_VSTD::forward<_Tuple>(__p))),
244 second(_VSTD::get<1>(_VSTD::forward<_Tuple>(__p))) {}
245
246 template <class... _Args1, class... _Args2>
247 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
248 pair(piecewise_construct_t __pc,
249 tuple<_Args1...> __first_args, tuple<_Args2...> __second_args)
250 _NOEXCEPT_((is_nothrow_constructible<first_type, _Args1...>::value &&
251 is_nothrow_constructible<second_type, _Args2...>::value))
252 : pair(__pc, __first_args, __second_args,
253 typename __make_tuple_indices<sizeof...(_Args1)>::type(),
254 typename __make_tuple_indices<sizeof...(_Args2) >::type()) {}
255
256 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
257 pair& operator=(typename conditional<
258 is_copy_assignable<first_type>::value &&
259 is_copy_assignable<second_type>::value,
260 pair, __nat>::type const& __p)
261 _NOEXCEPT_(is_nothrow_copy_assignable<first_type>::value &&
262 is_nothrow_copy_assignable<second_type>::value)
263 {
264 first = __p.first;
265 second = __p.second;
266 return *this;
267 }
268
269 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
270 pair& operator=(typename conditional<
271 is_move_assignable<first_type>::value &&
272 is_move_assignable<second_type>::value,
273 pair, __nat>::type&& __p)
274 _NOEXCEPT_(is_nothrow_move_assignable<first_type>::value &&
275 is_nothrow_move_assignable<second_type>::value)
276 {
277 first = _VSTD::forward<first_type>(__p.first);
278 second = _VSTD::forward<second_type>(__p.second);
279 return *this;
280 }
281
282 template <class _Tuple, _EnableB<
283 _CheckTLC<_Tuple>::template __enable_assign<_Tuple>()
284 > = false>
285 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
286 pair& operator=(_Tuple&& __p) {
287 first = _VSTD::get<0>(_VSTD::forward<_Tuple>(__p));
288 second = _VSTD::get<1>(_VSTD::forward<_Tuple>(__p));
289 return *this;
290 }
291#endif
292
293 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
294 void
295 swap(pair& __p) _NOEXCEPT_(__is_nothrow_swappable<first_type>::value &&
296 __is_nothrow_swappable<second_type>::value)
297 {
298 using _VSTD::swap;
299 swap(first, __p.first);
300 swap(second, __p.second);
301 }
302private:
303
304#ifndef _LIBCPP_CXX03_LANG
305 template <class... _Args1, class... _Args2, size_t... _I1, size_t... _I2>
306 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
307 pair(piecewise_construct_t,
308 tuple<_Args1...>& __first_args, tuple<_Args2...>& __second_args,
309 __tuple_indices<_I1...>, __tuple_indices<_I2...>);
310#endif
311};
312
313#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
314template<class _T1, class _T2>
315pair(_T1, _T2) -> pair<_T1, _T2>;
316#endif // _LIBCPP_HAS_NO_DEDUCTION_GUIDES
317
318template <class _T1, class _T2>
319inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
320bool
321operator==(const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y)
322{
323 return __x.first == __y.first && __x.second == __y.second;
324}
325
326template <class _T1, class _T2>
327inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
328bool
329operator!=(const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y)
330{
331 return !(__x == __y);
332}
333
334template <class _T1, class _T2>
335inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
336bool
337operator< (const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y)
338{
339 return __x.first < __y.first || (!(__y.first < __x.first) && __x.second < __y.second);
340}
341
342template <class _T1, class _T2>
343inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
344bool
345operator> (const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y)
346{
347 return __y < __x;
348}
349
350template <class _T1, class _T2>
351inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
352bool
353operator>=(const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y)
354{
355 return !(__x < __y);
356}
357
358template <class _T1, class _T2>
359inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
360bool
361operator<=(const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y)
362{
363 return !(__y < __x);
364}
365
366template <class _T1, class _T2>
367inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
368typename enable_if
369<
370 __is_swappable<_T1>::value &&
371 __is_swappable<_T2>::value,
372 void
373>::type
374swap(pair<_T1, _T2>& __x, pair<_T1, _T2>& __y)
375 _NOEXCEPT_((__is_nothrow_swappable<_T1>::value &&
376 __is_nothrow_swappable<_T2>::value))
377{
378 __x.swap(__y);
379}
380
381#ifndef _LIBCPP_CXX03_LANG
382
383template <class _T1, class _T2>
384inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
385pair<typename __unwrap_ref_decay<_T1>::type, typename __unwrap_ref_decay<_T2>::type>
386make_pair(_T1&& __t1, _T2&& __t2)
387{
388 return pair<typename __unwrap_ref_decay<_T1>::type, typename __unwrap_ref_decay<_T2>::type>
389 (_VSTD::forward<_T1>(__t1), _VSTD::forward<_T2>(__t2));
390}
391
392#else // _LIBCPP_CXX03_LANG
393
394template <class _T1, class _T2>
395inline _LIBCPP_INLINE_VISIBILITY
396pair<_T1,_T2>
397make_pair(_T1 __x, _T2 __y)
398{
399 return pair<_T1, _T2>(__x, __y);
400}
401
402#endif // _LIBCPP_CXX03_LANG
403
404template <class _T1, class _T2>
405 struct _LIBCPP_TEMPLATE_VIS tuple_size<pair<_T1, _T2> >
406 : public integral_constant<size_t, 2> {};
407
408template <size_t _Ip, class _T1, class _T2>
409struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, pair<_T1, _T2> >
410{
411 static_assert(_Ip < 2, "Index out of bounds in std::tuple_element<std::pair<T1, T2>>");
412};
413
414template <class _T1, class _T2>
415struct _LIBCPP_TEMPLATE_VIS tuple_element<0, pair<_T1, _T2> >
416{
417 typedef _LIBCPP_NODEBUG_TYPE _T1 type;
418};
419
420template <class _T1, class _T2>
421struct _LIBCPP_TEMPLATE_VIS tuple_element<1, pair<_T1, _T2> >
422{
423 typedef _LIBCPP_NODEBUG_TYPE _T2 type;
424};
425
426template <size_t _Ip> struct __get_pair;
427
428template <>
429struct __get_pair<0>
430{
431 template <class _T1, class _T2>
432 static
433 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
434 _T1&
435 get(pair<_T1, _T2>& __p) _NOEXCEPT {return __p.first;}
436
437 template <class _T1, class _T2>
438 static
439 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
440 const _T1&
441 get(const pair<_T1, _T2>& __p) _NOEXCEPT {return __p.first;}
442
443#ifndef _LIBCPP_CXX03_LANG
444 template <class _T1, class _T2>
445 static
446 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
447 _T1&&
448 get(pair<_T1, _T2>&& __p) _NOEXCEPT {return _VSTD::forward<_T1>(__p.first);}
449
450 template <class _T1, class _T2>
451 static
452 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
453 const _T1&&
454 get(const pair<_T1, _T2>&& __p) _NOEXCEPT {return _VSTD::forward<const _T1>(__p.first);}
455#endif // _LIBCPP_CXX03_LANG
456};
457
458template <>
459struct __get_pair<1>
460{
461 template <class _T1, class _T2>
462 static
463 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
464 _T2&
465 get(pair<_T1, _T2>& __p) _NOEXCEPT {return __p.second;}
466
467 template <class _T1, class _T2>
468 static
469 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
470 const _T2&
471 get(const pair<_T1, _T2>& __p) _NOEXCEPT {return __p.second;}
472
473#ifndef _LIBCPP_CXX03_LANG
474 template <class _T1, class _T2>
475 static
476 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
477 _T2&&
478 get(pair<_T1, _T2>&& __p) _NOEXCEPT {return _VSTD::forward<_T2>(__p.second);}
479
480 template <class _T1, class _T2>
481 static
482 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
483 const _T2&&
484 get(const pair<_T1, _T2>&& __p) _NOEXCEPT {return _VSTD::forward<const _T2>(__p.second);}
485#endif // _LIBCPP_CXX03_LANG
486};
487
488template <size_t _Ip, class _T1, class _T2>
489inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
490typename tuple_element<_Ip, pair<_T1, _T2> >::type&
491get(pair<_T1, _T2>& __p) _NOEXCEPT
492{
493 return __get_pair<_Ip>::get(__p);
494}
495
496template <size_t _Ip, class _T1, class _T2>
497inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
498const typename tuple_element<_Ip, pair<_T1, _T2> >::type&
499get(const pair<_T1, _T2>& __p) _NOEXCEPT
500{
501 return __get_pair<_Ip>::get(__p);
502}
503
504#ifndef _LIBCPP_CXX03_LANG
505template <size_t _Ip, class _T1, class _T2>
506inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
507typename tuple_element<_Ip, pair<_T1, _T2> >::type&&
508get(pair<_T1, _T2>&& __p) _NOEXCEPT
509{
510 return __get_pair<_Ip>::get(_VSTD::move(__p));
511}
512
513template <size_t _Ip, class _T1, class _T2>
514inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
515const typename tuple_element<_Ip, pair<_T1, _T2> >::type&&
516get(const pair<_T1, _T2>&& __p) _NOEXCEPT
517{
518 return __get_pair<_Ip>::get(_VSTD::move(__p));
519}
520#endif // _LIBCPP_CXX03_LANG
521
522#if _LIBCPP_STD_VER > 11
523template <class _T1, class _T2>
524inline _LIBCPP_INLINE_VISIBILITY
525constexpr _T1 & get(pair<_T1, _T2>& __p) _NOEXCEPT
526{
527 return __get_pair<0>::get(__p);
528}
529
530template <class _T1, class _T2>
531inline _LIBCPP_INLINE_VISIBILITY
532constexpr _T1 const & get(pair<_T1, _T2> const& __p) _NOEXCEPT
533{
534 return __get_pair<0>::get(__p);
535}
536
537template <class _T1, class _T2>
538inline _LIBCPP_INLINE_VISIBILITY
539constexpr _T1 && get(pair<_T1, _T2>&& __p) _NOEXCEPT
540{
541 return __get_pair<0>::get(_VSTD::move(__p));
542}
543
544template <class _T1, class _T2>
545inline _LIBCPP_INLINE_VISIBILITY
546constexpr _T1 const && get(pair<_T1, _T2> const&& __p) _NOEXCEPT
547{
548 return __get_pair<0>::get(_VSTD::move(__p));
549}
550
551template <class _T1, class _T2>
552inline _LIBCPP_INLINE_VISIBILITY
553constexpr _T1 & get(pair<_T2, _T1>& __p) _NOEXCEPT
554{
555 return __get_pair<1>::get(__p);
556}
557
558template <class _T1, class _T2>
559inline _LIBCPP_INLINE_VISIBILITY
560constexpr _T1 const & get(pair<_T2, _T1> const& __p) _NOEXCEPT
561{
562 return __get_pair<1>::get(__p);
563}
564
565template <class _T1, class _T2>
566inline _LIBCPP_INLINE_VISIBILITY
567constexpr _T1 && get(pair<_T2, _T1>&& __p) _NOEXCEPT
568{
569 return __get_pair<1>::get(_VSTD::move(__p));
570}
571
572template <class _T1, class _T2>
573inline _LIBCPP_INLINE_VISIBILITY
574constexpr _T1 const && get(pair<_T2, _T1> const&& __p) _NOEXCEPT
575{
576 return __get_pair<1>::get(_VSTD::move(__p));
577}
578
579#endif
580
581_LIBCPP_END_NAMESPACE_STD
582
583_LIBCPP_POP_MACROS
584
585#endif // _LIBCPP___UTILITY_PAIR_H
lib/libcxx/include/__utility/piecewise_construct.h created+34
......@@ -0,0 +1,34 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___UTILITY_PIECEWISE_CONSTRUCT_H
10#define _LIBCPP___UTILITY_PIECEWISE_CONSTRUCT_H
11
12#include <__config>
13
14#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
15#pragma GCC system_header
16#endif
17
18_LIBCPP_PUSH_MACROS
19#include <__undef_macros>
20
21_LIBCPP_BEGIN_NAMESPACE_STD
22
23struct _LIBCPP_TEMPLATE_VIS piecewise_construct_t { explicit piecewise_construct_t() = default; };
24#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY)
25extern _LIBCPP_EXPORTED_FROM_ABI const piecewise_construct_t piecewise_construct;// = piecewise_construct_t();
26#else
27/* _LIBCPP_INLINE_VAR */ constexpr piecewise_construct_t piecewise_construct = piecewise_construct_t();
28#endif
29
30_LIBCPP_END_NAMESPACE_STD
31
32_LIBCPP_POP_MACROS
33
34#endif // _LIBCPP___UTILITY_PIECEWISE_CONSTRUCT_H
lib/libcxx/include/__utility/rel_ops.h created+67
......@@ -0,0 +1,67 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___UTILITY_REL_OPS_H
10#define _LIBCPP___UTILITY_REL_OPS_H
11
12#include <__config>
13#include <__utility/forward.h>
14#include <__utility/move.h>
15#include <type_traits>
16
17#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
18#pragma GCC system_header
19#endif
20
21_LIBCPP_PUSH_MACROS
22#include <__undef_macros>
23
24_LIBCPP_BEGIN_NAMESPACE_STD
25
26namespace rel_ops
27{
28
29template<class _Tp>
30inline _LIBCPP_INLINE_VISIBILITY
31bool
32operator!=(const _Tp& __x, const _Tp& __y)
33{
34 return !(__x == __y);
35}
36
37template<class _Tp>
38inline _LIBCPP_INLINE_VISIBILITY
39bool
40operator> (const _Tp& __x, const _Tp& __y)
41{
42 return __y < __x;
43}
44
45template<class _Tp>
46inline _LIBCPP_INLINE_VISIBILITY
47bool
48operator<=(const _Tp& __x, const _Tp& __y)
49{
50 return !(__y < __x);
51}
52
53template<class _Tp>
54inline _LIBCPP_INLINE_VISIBILITY
55bool
56operator>=(const _Tp& __x, const _Tp& __y)
57{
58 return !(__x < __y);
59}
60
61} // rel_ops
62
63_LIBCPP_END_NAMESPACE_STD
64
65_LIBCPP_POP_MACROS
66
67#endif // _LIBCPP___UTILITY_REL_OPS_H
lib/libcxx/include/__utility/swap.h created+55
......@@ -0,0 +1,55 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___UTILITY_SWAP_H
10#define _LIBCPP___UTILITY_SWAP_H
11
12#include <__config>
13#include <__utility/declval.h>
14#include <__utility/move.h>
15#include <type_traits>
16#include <cstddef>
17
18#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
19#pragma GCC system_header
20#endif
21
22_LIBCPP_PUSH_MACROS
23#include <__undef_macros>
24
25_LIBCPP_BEGIN_NAMESPACE_STD
26
27#ifndef _LIBCPP_CXX03_LANG
28template <class _Tp>
29using __swap_result_t = typename enable_if<is_move_constructible<_Tp>::value && is_move_assignable<_Tp>::value>::type;
30#else
31template <class>
32using __swap_result_t = void;
33#endif
34
35template <class _Tp>
36inline _LIBCPP_INLINE_VISIBILITY __swap_result_t<_Tp> _LIBCPP_CONSTEXPR_AFTER_CXX17 swap(_Tp& __x, _Tp& __y)
37 _NOEXCEPT_(is_nothrow_move_constructible<_Tp>::value&& is_nothrow_move_assignable<_Tp>::value) {
38 _Tp __t(_VSTD::move(__x));
39 __x = _VSTD::move(__y);
40 __y = _VSTD::move(__t);
41}
42
43template <class _Tp, size_t _Np>
44inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 typename enable_if<__is_swappable<_Tp>::value>::type
45swap(_Tp (&__a)[_Np], _Tp (&__b)[_Np]) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value) {
46 for (size_t __i = 0; __i != _Np; ++__i) {
47 swap(__a[__i], __b[__i]);
48 }
49}
50
51_LIBCPP_END_NAMESPACE_STD
52
53_LIBCPP_POP_MACROS
54
55#endif // _LIBCPP___UTILITY_SWAP_H
lib/libcxx/include/__utility/to_underlying.h created+45
......@@ -0,0 +1,45 @@
1// -*- C++ -*-
2//===----------------- __utility/to_underlying.h --------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___UTILITY_TO_UNDERLYING_H
11#define _LIBCPP___UTILITY_TO_UNDERLYING_H
12
13#include <__config>
14#include <type_traits>
15
16#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
17#pragma GCC system_header
18#endif
19
20_LIBCPP_PUSH_MACROS
21#include <__undef_macros>
22
23_LIBCPP_BEGIN_NAMESPACE_STD
24
25#ifndef _LIBCPP_CXX03_LANG
26template <class _Tp>
27_LIBCPP_INLINE_VISIBILITY constexpr typename underlying_type<_Tp>::type
28__to_underlying(_Tp __val) noexcept {
29 return static_cast<typename underlying_type<_Tp>::type>(__val);
30}
31#endif // !_LIBCPP_CXX03_LANG
32
33#if _LIBCPP_STD_VER > 20
34template <class _Tp>
35_LIBCPP_NODISCARD_EXT _LIBCPP_INLINE_VISIBILITY constexpr underlying_type_t<_Tp>
36to_underlying(_Tp __val) noexcept {
37 return _VSTD::__to_underlying(__val);
38}
39#endif
40
41_LIBCPP_END_NAMESPACE_STD
42
43_LIBCPP_POP_MACROS
44
45#endif // _LIBCPP___UTILITY_TO_UNDERLYING_H
lib/libcxx/include/__variant/monostate.h created+65
......@@ -0,0 +1,65 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___VARIANT_MONOSTATE_H
11#define _LIBCPP___VARIANT_MONOSTATE_H
12
13#include <__config>
14#include <__functional/hash.h>
15#include <cstddef>
16
17#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
18#pragma GCC system_header
19#endif
20
21_LIBCPP_PUSH_MACROS
22#include <__undef_macros>
23
24_LIBCPP_BEGIN_NAMESPACE_STD
25
26#if _LIBCPP_STD_VER > 14
27
28struct _LIBCPP_TEMPLATE_VIS monostate {};
29
30inline _LIBCPP_INLINE_VISIBILITY
31constexpr bool operator<(monostate, monostate) noexcept { return false; }
32
33inline _LIBCPP_INLINE_VISIBILITY
34constexpr bool operator>(monostate, monostate) noexcept { return false; }
35
36inline _LIBCPP_INLINE_VISIBILITY
37constexpr bool operator<=(monostate, monostate) noexcept { return true; }
38
39inline _LIBCPP_INLINE_VISIBILITY
40constexpr bool operator>=(monostate, monostate) noexcept { return true; }
41
42inline _LIBCPP_INLINE_VISIBILITY
43constexpr bool operator==(monostate, monostate) noexcept { return true; }
44
45inline _LIBCPP_INLINE_VISIBILITY
46constexpr bool operator!=(monostate, monostate) noexcept { return false; }
47
48template <>
49struct _LIBCPP_TEMPLATE_VIS hash<monostate> {
50 using argument_type = monostate;
51 using result_type = size_t;
52
53 inline _LIBCPP_INLINE_VISIBILITY
54 result_type operator()(const argument_type&) const _NOEXCEPT {
55 return 66740831; // return a fundamentally attractive random value.
56 }
57};
58
59#endif // _LIBCPP_STD_VER > 14
60
61_LIBCPP_END_NAMESPACE_STD
62
63_LIBCPP_POP_MACROS
64
65#endif // _LIBCPP___VARIANT_MONOSTATE_H
lib/libcxx/include/algorithm+118-5210
......@@ -351,11 +351,11 @@ template <class ForwardIterator, class Compare>
351351 is_sorted_until(ForwardIterator first, ForwardIterator last, Compare comp);
352352
353353template <class RandomAccessIterator>
354 void
354 constexpr void // constexpr in C++20
355355 sort(RandomAccessIterator first, RandomAccessIterator last);
356356
357357template <class RandomAccessIterator, class Compare>
358 void
358 constexpr void // constexpr in C++20
359359 sort(RandomAccessIterator first, RandomAccessIterator last, Compare comp);
360360
361361template <class RandomAccessIterator>
......@@ -367,29 +367,29 @@ template <class RandomAccessIterator, class Compare>
367367 stable_sort(RandomAccessIterator first, RandomAccessIterator last, Compare comp);
368368
369369template <class RandomAccessIterator>
370 void
370 constexpr void // constexpr in C++20
371371 partial_sort(RandomAccessIterator first, RandomAccessIterator middle, RandomAccessIterator last);
372372
373373template <class RandomAccessIterator, class Compare>
374 void
374 constexpr void // constexpr in C++20
375375 partial_sort(RandomAccessIterator first, RandomAccessIterator middle, RandomAccessIterator last, Compare comp);
376376
377377template <class InputIterator, class RandomAccessIterator>
378 RandomAccessIterator
378 constexpr RandomAccessIterator // constexpr in C++20
379379 partial_sort_copy(InputIterator first, InputIterator last,
380380 RandomAccessIterator result_first, RandomAccessIterator result_last);
381381
382382template <class InputIterator, class RandomAccessIterator, class Compare>
383 RandomAccessIterator
383 constexpr RandomAccessIterator // constexpr in C++20
384384 partial_sort_copy(InputIterator first, InputIterator last,
385385 RandomAccessIterator result_first, RandomAccessIterator result_last, Compare comp);
386386
387387template <class RandomAccessIterator>
388 void
388 constexpr void // constexpr in C++20
389389 nth_element(RandomAccessIterator first, RandomAccessIterator nth, RandomAccessIterator last);
390390
391391template <class RandomAccessIterator, class Compare>
392 void
392 constexpr void // constexpr in C++20
393393 nth_element(RandomAccessIterator first, RandomAccessIterator nth, RandomAccessIterator last, Compare comp);
394394
395395template <class ForwardIterator, class T>
......@@ -491,35 +491,35 @@ template <class InputIterator1, class InputIterator2, class OutputIterator, clas
491491 InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp);
492492
493493template <class RandomAccessIterator>
494 void
494 constexpr void // constexpr in C++20
495495 push_heap(RandomAccessIterator first, RandomAccessIterator last);
496496
497497template <class RandomAccessIterator, class Compare>
498 void
498 constexpr void // constexpr in C++20
499499 push_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp);
500500
501501template <class RandomAccessIterator>
502 void
502 constexpr void // constexpr in C++20
503503 pop_heap(RandomAccessIterator first, RandomAccessIterator last);
504504
505505template <class RandomAccessIterator, class Compare>
506 void
506 constexpr void // constexpr in C++20
507507 pop_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp);
508508
509509template <class RandomAccessIterator>
510 void
510 constexpr void // constexpr in C++20
511511 make_heap(RandomAccessIterator first, RandomAccessIterator last);
512512
513513template <class RandomAccessIterator, class Compare>
514 void
514 constexpr void // constexpr in C++20
515515 make_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp);
516516
517517template <class RandomAccessIterator>
518 void
518 constexpr void // constexpr in C++20
519519 sort_heap(RandomAccessIterator first, RandomAccessIterator last);
520520
521521template <class RandomAccessIterator, class Compare>
522 void
522 constexpr void // constexpr in C++20
523523 sort_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp);
524524
525525template <class RandomAccessIterator>
......@@ -646,18 +646,113 @@ template <class BidirectionalIterator, class Compare>
646646*/
647647
648648#include <__config>
649#include <initializer_list>
650#include <type_traits>
649#include <__debug>
650#include <__bits> // __libcpp_clz
651#include <cstddef>
651652#include <cstring>
653#include <functional>
654#include <initializer_list>
652655#include <utility> // needed to provide swap_ranges.
653656#include <memory>
654#include <functional>
655657#include <iterator>
656#include <cstddef>
657#include <bit>
658#include <memory>
659#include <type_traits>
660#include <utility> // swap_ranges
658661#include <version>
659662
660#include <__debug>
663#include <__algorithm/adjacent_find.h>
664#include <__algorithm/all_of.h>
665#include <__algorithm/any_of.h>
666#include <__algorithm/binary_search.h>
667#include <__algorithm/clamp.h>
668#include <__algorithm/comp.h>
669#include <__algorithm/comp_ref_type.h>
670#include <__algorithm/copy.h>
671#include <__algorithm/copy_backward.h>
672#include <__algorithm/copy_if.h>
673#include <__algorithm/copy_n.h>
674#include <__algorithm/count.h>
675#include <__algorithm/count_if.h>
676#include <__algorithm/equal.h>
677#include <__algorithm/equal_range.h>
678#include <__algorithm/fill_n.h>
679#include <__algorithm/fill.h>
680#include <__algorithm/find.h>
681#include <__algorithm/find_end.h>
682#include <__algorithm/find_first_of.h>
683#include <__algorithm/find_if.h>
684#include <__algorithm/find_if_not.h>
685#include <__algorithm/for_each.h>
686#include <__algorithm/for_each_n.h>
687#include <__algorithm/generate_n.h>
688#include <__algorithm/generate.h>
689#include <__algorithm/half_positive.h>
690#include <__algorithm/includes.h>
691#include <__algorithm/inplace_merge.h>
692#include <__algorithm/is_heap.h>
693#include <__algorithm/is_heap_until.h>
694#include <__algorithm/is_partitioned.h>
695#include <__algorithm/is_permutation.h>
696#include <__algorithm/is_sorted.h>
697#include <__algorithm/is_sorted_until.h>
698#include <__algorithm/iter_swap.h>
699#include <__algorithm/lexicographical_compare.h>
700#include <__algorithm/lower_bound.h>
701#include <__algorithm/make_heap.h>
702#include <__algorithm/max.h>
703#include <__algorithm/max_element.h>
704#include <__algorithm/merge.h>
705#include <__algorithm/min.h>
706#include <__algorithm/min_element.h>
707#include <__algorithm/minmax.h>
708#include <__algorithm/minmax_element.h>
709#include <__algorithm/mismatch.h>
710#include <__algorithm/move.h>
711#include <__algorithm/move_backward.h>
712#include <__algorithm/next_permutation.h>
713#include <__algorithm/none_of.h>
714#include <__algorithm/nth_element.h>
715#include <__algorithm/partial_sort.h>
716#include <__algorithm/partial_sort_copy.h>
717#include <__algorithm/partition.h>
718#include <__algorithm/partition_copy.h>
719#include <__algorithm/partition_point.h>
720#include <__algorithm/pop_heap.h>
721#include <__algorithm/prev_permutation.h>
722#include <__algorithm/push_heap.h>
723#include <__algorithm/remove.h>
724#include <__algorithm/remove_copy.h>
725#include <__algorithm/remove_copy_if.h>
726#include <__algorithm/remove_if.h>
727#include <__algorithm/replace.h>
728#include <__algorithm/replace_copy.h>
729#include <__algorithm/replace_copy_if.h>
730#include <__algorithm/replace_if.h>
731#include <__algorithm/reverse.h>
732#include <__algorithm/reverse_copy.h>
733#include <__algorithm/rotate.h>
734#include <__algorithm/rotate_copy.h>
735#include <__algorithm/sample.h>
736#include <__algorithm/search.h>
737#include <__algorithm/search_n.h>
738#include <__algorithm/set_difference.h>
739#include <__algorithm/set_intersection.h>
740#include <__algorithm/set_symmetric_difference.h>
741#include <__algorithm/set_union.h>
742#include <__algorithm/shift_left.h>
743#include <__algorithm/shift_right.h>
744#include <__algorithm/shuffle.h>
745#include <__algorithm/sift_down.h>
746#include <__algorithm/sort.h>
747#include <__algorithm/sort_heap.h>
748#include <__algorithm/stable_partition.h>
749#include <__algorithm/stable_sort.h>
750#include <__algorithm/swap_ranges.h>
751#include <__algorithm/transform.h>
752#include <__algorithm/unique_copy.h>
753#include <__algorithm/unique.h>
754#include <__algorithm/unwrap_iter.h>
755#include <__algorithm/upper_bound.h>
661756
662757#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
663758#pragma GCC system_header
......@@ -666,5197 +761,10 @@ template <class BidirectionalIterator, class Compare>
666761_LIBCPP_PUSH_MACROS
667762#include <__undef_macros>
668763
669
670_LIBCPP_BEGIN_NAMESPACE_STD
671
672// I'd like to replace these with _VSTD::equal_to<void>, but can't because:
673// * That only works with C++14 and later, and
674// * We haven't included <functional> here.
675template <class _T1, class _T2 = _T1>
676struct __equal_to
677{
678 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 bool operator()(const _T1& __x, const _T1& __y) const {return __x == __y;}
679 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 bool operator()(const _T1& __x, const _T2& __y) const {return __x == __y;}
680 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 bool operator()(const _T2& __x, const _T1& __y) const {return __x == __y;}
681 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 bool operator()(const _T2& __x, const _T2& __y) const {return __x == __y;}
682};
683
684template <class _T1>
685struct __equal_to<_T1, _T1>
686{
687 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
688 bool operator()(const _T1& __x, const _T1& __y) const {return __x == __y;}
689};
690
691template <class _T1>
692struct __equal_to<const _T1, _T1>
693{
694 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
695 bool operator()(const _T1& __x, const _T1& __y) const {return __x == __y;}
696};
697
698template <class _T1>
699struct __equal_to<_T1, const _T1>
700{
701 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
702 bool operator()(const _T1& __x, const _T1& __y) const {return __x == __y;}
703};
704
705template <class _T1, class _T2 = _T1>
706struct __less
707{
708 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
709 bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;}
710
711 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
712 bool operator()(const _T1& __x, const _T2& __y) const {return __x < __y;}
713
714 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
715 bool operator()(const _T2& __x, const _T1& __y) const {return __x < __y;}
716
717 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
718 bool operator()(const _T2& __x, const _T2& __y) const {return __x < __y;}
719};
720
721template <class _T1>
722struct __less<_T1, _T1>
723{
724 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
725 bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;}
726};
727
728template <class _T1>
729struct __less<const _T1, _T1>
730{
731 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
732 bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;}
733};
734
735template <class _T1>
736struct __less<_T1, const _T1>
737{
738 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
739 bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;}
740};
741
742template <class _Predicate>
743class __invert // invert the sense of a comparison
744{
745private:
746 _Predicate __p_;
747public:
748 _LIBCPP_INLINE_VISIBILITY __invert() {}
749
750 _LIBCPP_INLINE_VISIBILITY
751 explicit __invert(_Predicate __p) : __p_(__p) {}
752
753 template <class _T1>
754 _LIBCPP_INLINE_VISIBILITY
755 bool operator()(const _T1& __x) {return !__p_(__x);}
756
757 template <class _T1, class _T2>
758 _LIBCPP_INLINE_VISIBILITY
759 bool operator()(const _T1& __x, const _T2& __y) {return __p_(__y, __x);}
760};
761
762// Perform division by two quickly for positive integers (llvm.org/PR39129)
763
764template <typename _Integral>
765_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
766typename enable_if
767<
768 is_integral<_Integral>::value,
769 _Integral
770>::type
771__half_positive(_Integral __value)
772{
773 return static_cast<_Integral>(static_cast<typename make_unsigned<_Integral>::type>(__value) / 2);
774}
775
776template <typename _Tp>
777_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
778typename enable_if
779<
780 !is_integral<_Tp>::value,
781 _Tp
782>::type
783__half_positive(_Tp __value)
784{
785 return __value / 2;
786}
787
788#ifdef _LIBCPP_DEBUG
789
790template <class _Compare>
791struct __debug_less
792{
793 _Compare &__comp_;
794 _LIBCPP_CONSTEXPR_AFTER_CXX17
795 __debug_less(_Compare& __c) : __comp_(__c) {}
796
797 template <class _Tp, class _Up>
798 _LIBCPP_CONSTEXPR_AFTER_CXX17
799 bool operator()(const _Tp& __x, const _Up& __y)
800 {
801 bool __r = __comp_(__x, __y);
802 if (__r)
803 __do_compare_assert(0, __y, __x);
804 return __r;
805 }
806
807 template <class _Tp, class _Up>
808 _LIBCPP_CONSTEXPR_AFTER_CXX17
809 bool operator()(_Tp& __x, _Up& __y)
810 {
811 bool __r = __comp_(__x, __y);
812 if (__r)
813 __do_compare_assert(0, __y, __x);
814 return __r;
815 }
816
817 template <class _LHS, class _RHS>
818 _LIBCPP_CONSTEXPR_AFTER_CXX17
819 inline _LIBCPP_INLINE_VISIBILITY
820 decltype((void)_VSTD::declval<_Compare&>()(
821 _VSTD::declval<_LHS &>(), _VSTD::declval<_RHS &>()))
822 __do_compare_assert(int, _LHS & __l, _RHS & __r) {
823 _LIBCPP_ASSERT(!__comp_(__l, __r),
824 "Comparator does not induce a strict weak ordering");
825 }
826
827 template <class _LHS, class _RHS>
828 _LIBCPP_CONSTEXPR_AFTER_CXX17
829 inline _LIBCPP_INLINE_VISIBILITY
830 void __do_compare_assert(long, _LHS &, _RHS &) {}
831};
832
833#endif // _LIBCPP_DEBUG
834
835template <class _Comp>
836struct __comp_ref_type {
837 // Pass the comparator by lvalue reference. Or in debug mode, using a
838 // debugging wrapper that stores a reference.
839#ifndef _LIBCPP_DEBUG
840 typedef typename add_lvalue_reference<_Comp>::type type;
841#else
842 typedef __debug_less<_Comp> type;
843#endif
844};
845
846// all_of
847
848template <class _InputIterator, class _Predicate>
849_LIBCPP_NODISCARD_EXT inline
850_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
851bool
852all_of(_InputIterator __first, _InputIterator __last, _Predicate __pred)
853{
854 for (; __first != __last; ++__first)
855 if (!__pred(*__first))
856 return false;
857 return true;
858}
859
860// any_of
861
862template <class _InputIterator, class _Predicate>
863_LIBCPP_NODISCARD_EXT inline
864_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
865bool
866any_of(_InputIterator __first, _InputIterator __last, _Predicate __pred)
867{
868 for (; __first != __last; ++__first)
869 if (__pred(*__first))
870 return true;
871 return false;
872}
873
874// none_of
875
876template <class _InputIterator, class _Predicate>
877_LIBCPP_NODISCARD_EXT inline
878_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
879bool
880none_of(_InputIterator __first, _InputIterator __last, _Predicate __pred)
881{
882 for (; __first != __last; ++__first)
883 if (__pred(*__first))
884 return false;
885 return true;
886}
887
888// for_each
889
890template <class _InputIterator, class _Function>
891inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
892_Function
893for_each(_InputIterator __first, _InputIterator __last, _Function __f)
894{
895 for (; __first != __last; ++__first)
896 __f(*__first);
897 return __f;
898}
899
900#if _LIBCPP_STD_VER > 14
901// for_each_n
902
903template <class _InputIterator, class _Size, class _Function>
904inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
905_InputIterator
906for_each_n(_InputIterator __first, _Size __orig_n, _Function __f)
907{
908 typedef decltype(_VSTD::__convert_to_integral(__orig_n)) _IntegralSize;
909 _IntegralSize __n = __orig_n;
910 while (__n > 0)
911 {
912 __f(*__first);
913 ++__first;
914 --__n;
915 }
916 return __first;
917}
918#endif
919
920// find
921
922template <class _InputIterator, class _Tp>
923_LIBCPP_NODISCARD_EXT inline
924_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
925_InputIterator
926find(_InputIterator __first, _InputIterator __last, const _Tp& __value_)
927{
928 for (; __first != __last; ++__first)
929 if (*__first == __value_)
930 break;
931 return __first;
932}
933
934// find_if
935
936template <class _InputIterator, class _Predicate>
937_LIBCPP_NODISCARD_EXT inline
938_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
939_InputIterator
940find_if(_InputIterator __first, _InputIterator __last, _Predicate __pred)
941{
942 for (; __first != __last; ++__first)
943 if (__pred(*__first))
944 break;
945 return __first;
946}
947
948// find_if_not
949
950template<class _InputIterator, class _Predicate>
951_LIBCPP_NODISCARD_EXT inline
952_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
953_InputIterator
954find_if_not(_InputIterator __first, _InputIterator __last, _Predicate __pred)
955{
956 for (; __first != __last; ++__first)
957 if (!__pred(*__first))
958 break;
959 return __first;
960}
961
962// find_end
963
964template <class _BinaryPredicate, class _ForwardIterator1, class _ForwardIterator2>
965_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator1
966__find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
967 _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred,
968 forward_iterator_tag, forward_iterator_tag)
969{
970 // modeled after search algorithm
971 _ForwardIterator1 __r = __last1; // __last1 is the "default" answer
972 if (__first2 == __last2)
973 return __r;
974 while (true)
975 {
976 while (true)
977 {
978 if (__first1 == __last1) // if source exhausted return last correct answer
979 return __r; // (or __last1 if never found)
980 if (__pred(*__first1, *__first2))
981 break;
982 ++__first1;
983 }
984 // *__first1 matches *__first2, now match elements after here
985 _ForwardIterator1 __m1 = __first1;
986 _ForwardIterator2 __m2 = __first2;
987 while (true)
988 {
989 if (++__m2 == __last2)
990 { // Pattern exhaused, record answer and search for another one
991 __r = __first1;
992 ++__first1;
993 break;
994 }
995 if (++__m1 == __last1) // Source exhausted, return last answer
996 return __r;
997 if (!__pred(*__m1, *__m2)) // mismatch, restart with a new __first
998 {
999 ++__first1;
1000 break;
1001 } // else there is a match, check next elements
1002 }
1003 }
1004}
1005
1006template <class _BinaryPredicate, class _BidirectionalIterator1, class _BidirectionalIterator2>
1007_LIBCPP_CONSTEXPR_AFTER_CXX17 _BidirectionalIterator1
1008__find_end(_BidirectionalIterator1 __first1, _BidirectionalIterator1 __last1,
1009 _BidirectionalIterator2 __first2, _BidirectionalIterator2 __last2, _BinaryPredicate __pred,
1010 bidirectional_iterator_tag, bidirectional_iterator_tag)
1011{
1012 // modeled after search algorithm (in reverse)
1013 if (__first2 == __last2)
1014 return __last1; // Everything matches an empty sequence
1015 _BidirectionalIterator1 __l1 = __last1;
1016 _BidirectionalIterator2 __l2 = __last2;
1017 --__l2;
1018 while (true)
1019 {
1020 // Find last element in sequence 1 that matchs *(__last2-1), with a mininum of loop checks
1021 while (true)
1022 {
1023 if (__first1 == __l1) // return __last1 if no element matches *__first2
1024 return __last1;
1025 if (__pred(*--__l1, *__l2))
1026 break;
1027 }
1028 // *__l1 matches *__l2, now match elements before here
1029 _BidirectionalIterator1 __m1 = __l1;
1030 _BidirectionalIterator2 __m2 = __l2;
1031 while (true)
1032 {
1033 if (__m2 == __first2) // If pattern exhausted, __m1 is the answer (works for 1 element pattern)
1034 return __m1;
1035 if (__m1 == __first1) // Otherwise if source exhaused, pattern not found
1036 return __last1;
1037 if (!__pred(*--__m1, *--__m2)) // if there is a mismatch, restart with a new __l1
1038 {
1039 break;
1040 } // else there is a match, check next elements
1041 }
1042 }
1043}
1044
1045template <class _BinaryPredicate, class _RandomAccessIterator1, class _RandomAccessIterator2>
1046_LIBCPP_CONSTEXPR_AFTER_CXX11 _RandomAccessIterator1
1047__find_end(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1,
1048 _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, _BinaryPredicate __pred,
1049 random_access_iterator_tag, random_access_iterator_tag)
1050{
1051 // Take advantage of knowing source and pattern lengths. Stop short when source is smaller than pattern
1052 typename iterator_traits<_RandomAccessIterator2>::difference_type __len2 = __last2 - __first2;
1053 if (__len2 == 0)
1054 return __last1;
1055 typename iterator_traits<_RandomAccessIterator1>::difference_type __len1 = __last1 - __first1;
1056 if (__len1 < __len2)
1057 return __last1;
1058 const _RandomAccessIterator1 __s = __first1 + (__len2 - 1); // End of pattern match can't go before here
1059 _RandomAccessIterator1 __l1 = __last1;
1060 _RandomAccessIterator2 __l2 = __last2;
1061 --__l2;
1062 while (true)
1063 {
1064 while (true)
1065 {
1066 if (__s == __l1)
1067 return __last1;
1068 if (__pred(*--__l1, *__l2))
1069 break;
1070 }
1071 _RandomAccessIterator1 __m1 = __l1;
1072 _RandomAccessIterator2 __m2 = __l2;
1073 while (true)
1074 {
1075 if (__m2 == __first2)
1076 return __m1;
1077 // no need to check range on __m1 because __s guarantees we have enough source
1078 if (!__pred(*--__m1, *--__m2))
1079 {
1080 break;
1081 }
1082 }
1083 }
1084}
1085
1086template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
1087_LIBCPP_NODISCARD_EXT inline
1088_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1089_ForwardIterator1
1090find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
1091 _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred)
1092{
1093 return _VSTD::__find_end<typename add_lvalue_reference<_BinaryPredicate>::type>
1094 (__first1, __last1, __first2, __last2, __pred,
1095 typename iterator_traits<_ForwardIterator1>::iterator_category(),
1096 typename iterator_traits<_ForwardIterator2>::iterator_category());
1097}
1098
1099template <class _ForwardIterator1, class _ForwardIterator2>
1100_LIBCPP_NODISCARD_EXT inline
1101_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1102_ForwardIterator1
1103find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
1104 _ForwardIterator2 __first2, _ForwardIterator2 __last2)
1105{
1106 typedef typename iterator_traits<_ForwardIterator1>::value_type __v1;
1107 typedef typename iterator_traits<_ForwardIterator2>::value_type __v2;
1108 return _VSTD::find_end(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>());
1109}
1110
1111// find_first_of
1112
1113template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
1114_LIBCPP_CONSTEXPR_AFTER_CXX11 _ForwardIterator1
1115__find_first_of_ce(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
1116 _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred)
1117{
1118 for (; __first1 != __last1; ++__first1)
1119 for (_ForwardIterator2 __j = __first2; __j != __last2; ++__j)
1120 if (__pred(*__first1, *__j))
1121 return __first1;
1122 return __last1;
1123}
1124
1125
1126template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
1127_LIBCPP_NODISCARD_EXT inline
1128_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1129_ForwardIterator1
1130find_first_of(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
1131 _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred)
1132{
1133 return _VSTD::__find_first_of_ce(__first1, __last1, __first2, __last2, __pred);
1134}
1135
1136template <class _ForwardIterator1, class _ForwardIterator2>
1137_LIBCPP_NODISCARD_EXT inline
1138_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1139_ForwardIterator1
1140find_first_of(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
1141 _ForwardIterator2 __first2, _ForwardIterator2 __last2)
1142{
1143 typedef typename iterator_traits<_ForwardIterator1>::value_type __v1;
1144 typedef typename iterator_traits<_ForwardIterator2>::value_type __v2;
1145 return _VSTD::__find_first_of_ce(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>());
1146}
1147
1148// adjacent_find
1149
1150template <class _ForwardIterator, class _BinaryPredicate>
1151_LIBCPP_NODISCARD_EXT inline
1152_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1153_ForwardIterator
1154adjacent_find(_ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred)
1155{
1156 if (__first != __last)
1157 {
1158 _ForwardIterator __i = __first;
1159 while (++__i != __last)
1160 {
1161 if (__pred(*__first, *__i))
1162 return __first;
1163 __first = __i;
1164 }
1165 }
1166 return __last;
1167}
1168
1169template <class _ForwardIterator>
1170_LIBCPP_NODISCARD_EXT inline
1171_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1172_ForwardIterator
1173adjacent_find(_ForwardIterator __first, _ForwardIterator __last)
1174{
1175 typedef typename iterator_traits<_ForwardIterator>::value_type __v;
1176 return _VSTD::adjacent_find(__first, __last, __equal_to<__v>());
1177}
1178
1179// count
1180
1181template <class _InputIterator, class _Tp>
1182_LIBCPP_NODISCARD_EXT inline
1183_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1184typename iterator_traits<_InputIterator>::difference_type
1185count(_InputIterator __first, _InputIterator __last, const _Tp& __value_)
1186{
1187 typename iterator_traits<_InputIterator>::difference_type __r(0);
1188 for (; __first != __last; ++__first)
1189 if (*__first == __value_)
1190 ++__r;
1191 return __r;
1192}
1193
1194// count_if
1195
1196template <class _InputIterator, class _Predicate>
1197_LIBCPP_NODISCARD_EXT inline
1198_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1199typename iterator_traits<_InputIterator>::difference_type
1200count_if(_InputIterator __first, _InputIterator __last, _Predicate __pred)
1201{
1202 typename iterator_traits<_InputIterator>::difference_type __r(0);
1203 for (; __first != __last; ++__first)
1204 if (__pred(*__first))
1205 ++__r;
1206 return __r;
1207}
1208
1209// mismatch
1210
1211template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate>
1212_LIBCPP_NODISCARD_EXT inline
1213_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1214pair<_InputIterator1, _InputIterator2>
1215mismatch(_InputIterator1 __first1, _InputIterator1 __last1,
1216 _InputIterator2 __first2, _BinaryPredicate __pred)
1217{
1218 for (; __first1 != __last1; ++__first1, (void) ++__first2)
1219 if (!__pred(*__first1, *__first2))
1220 break;
1221 return pair<_InputIterator1, _InputIterator2>(__first1, __first2);
1222}
1223
1224template <class _InputIterator1, class _InputIterator2>
1225_LIBCPP_NODISCARD_EXT inline
1226_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1227pair<_InputIterator1, _InputIterator2>
1228mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2)
1229{
1230 typedef typename iterator_traits<_InputIterator1>::value_type __v1;
1231 typedef typename iterator_traits<_InputIterator2>::value_type __v2;
1232 return _VSTD::mismatch(__first1, __last1, __first2, __equal_to<__v1, __v2>());
1233}
1234
1235#if _LIBCPP_STD_VER > 11
1236template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate>
1237_LIBCPP_NODISCARD_EXT inline
1238_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1239pair<_InputIterator1, _InputIterator2>
1240mismatch(_InputIterator1 __first1, _InputIterator1 __last1,
1241 _InputIterator2 __first2, _InputIterator2 __last2,
1242 _BinaryPredicate __pred)
1243{
1244 for (; __first1 != __last1 && __first2 != __last2; ++__first1, (void) ++__first2)
1245 if (!__pred(*__first1, *__first2))
1246 break;
1247 return pair<_InputIterator1, _InputIterator2>(__first1, __first2);
1248}
1249
1250template <class _InputIterator1, class _InputIterator2>
1251_LIBCPP_NODISCARD_EXT inline
1252_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1253pair<_InputIterator1, _InputIterator2>
1254mismatch(_InputIterator1 __first1, _InputIterator1 __last1,
1255 _InputIterator2 __first2, _InputIterator2 __last2)
1256{
1257 typedef typename iterator_traits<_InputIterator1>::value_type __v1;
1258 typedef typename iterator_traits<_InputIterator2>::value_type __v2;
1259 return _VSTD::mismatch(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>());
1260}
1261#endif
1262
1263// equal
1264
1265template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate>
1266_LIBCPP_NODISCARD_EXT inline
1267_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1268bool
1269equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _BinaryPredicate __pred)
1270{
1271 for (; __first1 != __last1; ++__first1, (void) ++__first2)
1272 if (!__pred(*__first1, *__first2))
1273 return false;
1274 return true;
1275}
1276
1277template <class _InputIterator1, class _InputIterator2>
1278_LIBCPP_NODISCARD_EXT inline
1279_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1280bool
1281equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2)
1282{
1283 typedef typename iterator_traits<_InputIterator1>::value_type __v1;
1284 typedef typename iterator_traits<_InputIterator2>::value_type __v2;
1285 return _VSTD::equal(__first1, __last1, __first2, __equal_to<__v1, __v2>());
1286}
1287
1288#if _LIBCPP_STD_VER > 11
1289template <class _BinaryPredicate, class _InputIterator1, class _InputIterator2>
1290inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1291bool
1292__equal(_InputIterator1 __first1, _InputIterator1 __last1,
1293 _InputIterator2 __first2, _InputIterator2 __last2, _BinaryPredicate __pred,
1294 input_iterator_tag, input_iterator_tag )
1295{
1296 for (; __first1 != __last1 && __first2 != __last2; ++__first1, (void) ++__first2)
1297 if (!__pred(*__first1, *__first2))
1298 return false;
1299 return __first1 == __last1 && __first2 == __last2;
1300}
1301
1302template <class _BinaryPredicate, class _RandomAccessIterator1, class _RandomAccessIterator2>
1303inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1304bool
1305__equal(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1,
1306 _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, _BinaryPredicate __pred,
1307 random_access_iterator_tag, random_access_iterator_tag )
1308{
1309 if ( _VSTD::distance(__first1, __last1) != _VSTD::distance(__first2, __last2))
1310 return false;
1311 return _VSTD::equal<_RandomAccessIterator1, _RandomAccessIterator2,
1312 typename add_lvalue_reference<_BinaryPredicate>::type>
1313 (__first1, __last1, __first2, __pred );
1314}
1315
1316template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate>
1317_LIBCPP_NODISCARD_EXT inline
1318_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1319bool
1320equal(_InputIterator1 __first1, _InputIterator1 __last1,
1321 _InputIterator2 __first2, _InputIterator2 __last2, _BinaryPredicate __pred )
1322{
1323 return _VSTD::__equal<typename add_lvalue_reference<_BinaryPredicate>::type>
1324 (__first1, __last1, __first2, __last2, __pred,
1325 typename iterator_traits<_InputIterator1>::iterator_category(),
1326 typename iterator_traits<_InputIterator2>::iterator_category());
1327}
1328
1329template <class _InputIterator1, class _InputIterator2>
1330_LIBCPP_NODISCARD_EXT inline
1331_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1332bool
1333equal(_InputIterator1 __first1, _InputIterator1 __last1,
1334 _InputIterator2 __first2, _InputIterator2 __last2)
1335{
1336 typedef typename iterator_traits<_InputIterator1>::value_type __v1;
1337 typedef typename iterator_traits<_InputIterator2>::value_type __v2;
1338 return _VSTD::__equal(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>(),
1339 typename iterator_traits<_InputIterator1>::iterator_category(),
1340 typename iterator_traits<_InputIterator2>::iterator_category());
1341}
1342#endif
1343
1344// is_permutation
1345
1346template<class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
1347_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_AFTER_CXX17 bool
1348is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
1349 _ForwardIterator2 __first2, _BinaryPredicate __pred)
1350{
1351// shorten sequences as much as possible by lopping of any equal prefix
1352 for (; __first1 != __last1; ++__first1, (void) ++__first2)
1353 if (!__pred(*__first1, *__first2))
1354 break;
1355 if (__first1 == __last1)
1356 return true;
1357
1358// __first1 != __last1 && *__first1 != *__first2
1359 typedef typename iterator_traits<_ForwardIterator1>::difference_type _D1;
1360 _D1 __l1 = _VSTD::distance(__first1, __last1);
1361 if (__l1 == _D1(1))
1362 return false;
1363 _ForwardIterator2 __last2 = _VSTD::next(__first2, __l1);
1364 // For each element in [f1, l1) see if there are the same number of
1365 // equal elements in [f2, l2)
1366 for (_ForwardIterator1 __i = __first1; __i != __last1; ++__i)
1367 {
1368 // Have we already counted the number of *__i in [f1, l1)?
1369 _ForwardIterator1 __match = __first1;
1370 for (; __match != __i; ++__match)
1371 if (__pred(*__match, *__i))
1372 break;
1373 if (__match == __i) {
1374 // Count number of *__i in [f2, l2)
1375 _D1 __c2 = 0;
1376 for (_ForwardIterator2 __j = __first2; __j != __last2; ++__j)
1377 if (__pred(*__i, *__j))
1378 ++__c2;
1379 if (__c2 == 0)
1380 return false;
1381 // Count number of *__i in [__i, l1) (we can start with 1)
1382 _D1 __c1 = 1;
1383 for (_ForwardIterator1 __j = _VSTD::next(__i); __j != __last1; ++__j)
1384 if (__pred(*__i, *__j))
1385 ++__c1;
1386 if (__c1 != __c2)
1387 return false;
1388 }
1389 }
1390 return true;
1391}
1392
1393template<class _ForwardIterator1, class _ForwardIterator2>
1394_LIBCPP_NODISCARD_EXT inline
1395_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1396bool
1397is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
1398 _ForwardIterator2 __first2)
1399{
1400 typedef typename iterator_traits<_ForwardIterator1>::value_type __v1;
1401 typedef typename iterator_traits<_ForwardIterator2>::value_type __v2;
1402 return _VSTD::is_permutation(__first1, __last1, __first2, __equal_to<__v1, __v2>());
1403}
1404
1405#if _LIBCPP_STD_VER > 11
1406template<class _BinaryPredicate, class _ForwardIterator1, class _ForwardIterator2>
1407_LIBCPP_CONSTEXPR_AFTER_CXX17 bool
1408__is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
1409 _ForwardIterator2 __first2, _ForwardIterator2 __last2,
1410 _BinaryPredicate __pred,
1411 forward_iterator_tag, forward_iterator_tag )
1412{
1413// shorten sequences as much as possible by lopping of any equal prefix
1414 for (; __first1 != __last1 && __first2 != __last2; ++__first1, (void) ++__first2)
1415 if (!__pred(*__first1, *__first2))
1416 break;
1417 if (__first1 == __last1)
1418 return __first2 == __last2;
1419 else if (__first2 == __last2)
1420 return false;
1421
1422 typedef typename iterator_traits<_ForwardIterator1>::difference_type _D1;
1423 _D1 __l1 = _VSTD::distance(__first1, __last1);
1424
1425 typedef typename iterator_traits<_ForwardIterator2>::difference_type _D2;
1426 _D2 __l2 = _VSTD::distance(__first2, __last2);
1427 if (__l1 != __l2)
1428 return false;
1429
1430 // For each element in [f1, l1) see if there are the same number of
1431 // equal elements in [f2, l2)
1432 for (_ForwardIterator1 __i = __first1; __i != __last1; ++__i)
1433 {
1434 // Have we already counted the number of *__i in [f1, l1)?
1435 _ForwardIterator1 __match = __first1;
1436 for (; __match != __i; ++__match)
1437 if (__pred(*__match, *__i))
1438 break;
1439 if (__match == __i) {
1440 // Count number of *__i in [f2, l2)
1441 _D1 __c2 = 0;
1442 for (_ForwardIterator2 __j = __first2; __j != __last2; ++__j)
1443 if (__pred(*__i, *__j))
1444 ++__c2;
1445 if (__c2 == 0)
1446 return false;
1447 // Count number of *__i in [__i, l1) (we can start with 1)
1448 _D1 __c1 = 1;
1449 for (_ForwardIterator1 __j = _VSTD::next(__i); __j != __last1; ++__j)
1450 if (__pred(*__i, *__j))
1451 ++__c1;
1452 if (__c1 != __c2)
1453 return false;
1454 }
1455 }
1456 return true;
1457}
1458
1459template<class _BinaryPredicate, class _RandomAccessIterator1, class _RandomAccessIterator2>
1460_LIBCPP_CONSTEXPR_AFTER_CXX17 bool
1461__is_permutation(_RandomAccessIterator1 __first1, _RandomAccessIterator2 __last1,
1462 _RandomAccessIterator1 __first2, _RandomAccessIterator2 __last2,
1463 _BinaryPredicate __pred,
1464 random_access_iterator_tag, random_access_iterator_tag )
1465{
1466 if ( _VSTD::distance(__first1, __last1) != _VSTD::distance(__first2, __last2))
1467 return false;
1468 return _VSTD::is_permutation<_RandomAccessIterator1, _RandomAccessIterator2,
1469 typename add_lvalue_reference<_BinaryPredicate>::type>
1470 (__first1, __last1, __first2, __pred );
1471}
1472
1473template<class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
1474_LIBCPP_NODISCARD_EXT inline
1475_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1476bool
1477is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
1478 _ForwardIterator2 __first2, _ForwardIterator2 __last2,
1479 _BinaryPredicate __pred )
1480{
1481 return _VSTD::__is_permutation<typename add_lvalue_reference<_BinaryPredicate>::type>
1482 (__first1, __last1, __first2, __last2, __pred,
1483 typename iterator_traits<_ForwardIterator1>::iterator_category(),
1484 typename iterator_traits<_ForwardIterator2>::iterator_category());
1485}
1486
1487template<class _ForwardIterator1, class _ForwardIterator2>
1488_LIBCPP_NODISCARD_EXT inline
1489_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1490bool
1491is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
1492 _ForwardIterator2 __first2, _ForwardIterator2 __last2)
1493{
1494 typedef typename iterator_traits<_ForwardIterator1>::value_type __v1;
1495 typedef typename iterator_traits<_ForwardIterator2>::value_type __v2;
1496 return _VSTD::__is_permutation(__first1, __last1, __first2, __last2,
1497 __equal_to<__v1, __v2>(),
1498 typename iterator_traits<_ForwardIterator1>::iterator_category(),
1499 typename iterator_traits<_ForwardIterator2>::iterator_category());
1500}
1501#endif
1502
1503// search
1504// __search is in <functional>
1505
1506template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
1507_LIBCPP_NODISCARD_EXT inline
1508_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1509_ForwardIterator1
1510search(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
1511 _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred)
1512{
1513 return _VSTD::__search<typename add_lvalue_reference<_BinaryPredicate>::type>
1514 (__first1, __last1, __first2, __last2, __pred,
1515 typename iterator_traits<_ForwardIterator1>::iterator_category(),
1516 typename iterator_traits<_ForwardIterator2>::iterator_category())
1517 .first;
1518}
1519
1520template <class _ForwardIterator1, class _ForwardIterator2>
1521_LIBCPP_NODISCARD_EXT inline
1522_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1523_ForwardIterator1
1524search(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
1525 _ForwardIterator2 __first2, _ForwardIterator2 __last2)
1526{
1527 typedef typename iterator_traits<_ForwardIterator1>::value_type __v1;
1528 typedef typename iterator_traits<_ForwardIterator2>::value_type __v2;
1529 return _VSTD::search(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>());
1530}
1531
1532
1533#if _LIBCPP_STD_VER > 14
1534template <class _ForwardIterator, class _Searcher>
1535_LIBCPP_NODISCARD_EXT _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1536_ForwardIterator search(_ForwardIterator __f, _ForwardIterator __l, const _Searcher &__s)
1537{ return __s(__f, __l).first; }
1538#endif
1539
1540// search_n
1541
1542template <class _BinaryPredicate, class _ForwardIterator, class _Size, class _Tp>
1543_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator
1544__search_n(_ForwardIterator __first, _ForwardIterator __last,
1545 _Size __count, const _Tp& __value_, _BinaryPredicate __pred, forward_iterator_tag)
1546{
1547 if (__count <= 0)
1548 return __first;
1549 while (true)
1550 {
1551 // Find first element in sequence that matchs __value_, with a mininum of loop checks
1552 while (true)
1553 {
1554 if (__first == __last) // return __last if no element matches __value_
1555 return __last;
1556 if (__pred(*__first, __value_))
1557 break;
1558 ++__first;
1559 }
1560 // *__first matches __value_, now match elements after here
1561 _ForwardIterator __m = __first;
1562 _Size __c(0);
1563 while (true)
1564 {
1565 if (++__c == __count) // If pattern exhausted, __first is the answer (works for 1 element pattern)
1566 return __first;
1567 if (++__m == __last) // Otherwise if source exhaused, pattern not found
1568 return __last;
1569 if (!__pred(*__m, __value_)) // if there is a mismatch, restart with a new __first
1570 {
1571 __first = __m;
1572 ++__first;
1573 break;
1574 } // else there is a match, check next elements
1575 }
1576 }
1577}
1578
1579template <class _BinaryPredicate, class _RandomAccessIterator, class _Size, class _Tp>
1580_LIBCPP_CONSTEXPR_AFTER_CXX17 _RandomAccessIterator
1581__search_n(_RandomAccessIterator __first, _RandomAccessIterator __last,
1582 _Size __count, const _Tp& __value_, _BinaryPredicate __pred, random_access_iterator_tag)
1583{
1584 if (__count <= 0)
1585 return __first;
1586 _Size __len = static_cast<_Size>(__last - __first);
1587 if (__len < __count)
1588 return __last;
1589 const _RandomAccessIterator __s = __last - (__count - 1); // Start of pattern match can't go beyond here
1590 while (true)
1591 {
1592 // Find first element in sequence that matchs __value_, with a mininum of loop checks
1593 while (true)
1594 {
1595 if (__first >= __s) // return __last if no element matches __value_
1596 return __last;
1597 if (__pred(*__first, __value_))
1598 break;
1599 ++__first;
1600 }
1601 // *__first matches __value_, now match elements after here
1602 _RandomAccessIterator __m = __first;
1603 _Size __c(0);
1604 while (true)
1605 {
1606 if (++__c == __count) // If pattern exhausted, __first is the answer (works for 1 element pattern)
1607 return __first;
1608 ++__m; // no need to check range on __m because __s guarantees we have enough source
1609 if (!__pred(*__m, __value_)) // if there is a mismatch, restart with a new __first
1610 {
1611 __first = __m;
1612 ++__first;
1613 break;
1614 } // else there is a match, check next elements
1615 }
1616 }
1617}
1618
1619template <class _ForwardIterator, class _Size, class _Tp, class _BinaryPredicate>
1620_LIBCPP_NODISCARD_EXT inline
1621_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1622_ForwardIterator
1623search_n(_ForwardIterator __first, _ForwardIterator __last,
1624 _Size __count, const _Tp& __value_, _BinaryPredicate __pred)
1625{
1626 return _VSTD::__search_n<typename add_lvalue_reference<_BinaryPredicate>::type>
1627 (__first, __last, _VSTD::__convert_to_integral(__count), __value_, __pred,
1628 typename iterator_traits<_ForwardIterator>::iterator_category());
1629}
1630
1631template <class _ForwardIterator, class _Size, class _Tp>
1632_LIBCPP_NODISCARD_EXT inline
1633_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1634_ForwardIterator
1635search_n(_ForwardIterator __first, _ForwardIterator __last, _Size __count, const _Tp& __value_)
1636{
1637 typedef typename iterator_traits<_ForwardIterator>::value_type __v;
1638 return _VSTD::search_n(__first, __last, _VSTD::__convert_to_integral(__count),
1639 __value_, __equal_to<__v, _Tp>());
1640}
1641
1642// copy
1643template <class _Iter>
1644inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
1645_Iter
1646__unwrap_iter(_Iter __i)
1647{
1648 return __i;
1649}
1650
1651template <class _Tp>
1652inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
1653typename enable_if
1654<
1655 is_trivially_copy_assignable<_Tp>::value,
1656 _Tp*
1657>::type
1658__unwrap_iter(move_iterator<_Tp*> __i)
1659{
1660 return __i.base();
1661}
1662
1663#if _LIBCPP_DEBUG_LEVEL < 2
1664
1665template <class _Tp>
1666inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
1667typename enable_if
1668<
1669 is_trivially_copy_assignable<_Tp>::value,
1670 _Tp*
1671>::type
1672__unwrap_iter(__wrap_iter<_Tp*> __i)
1673{
1674 return __i.base();
1675}
1676
1677template <class _Tp>
1678inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
1679typename enable_if
1680<
1681 is_trivially_copy_assignable<_Tp>::value,
1682 const _Tp*
1683>::type
1684__unwrap_iter(__wrap_iter<const _Tp*> __i)
1685{
1686 return __i.base();
1687}
1688
1689#else
1690
1691template <class _Tp>
1692inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
1693typename enable_if
1694<
1695 is_trivially_copy_assignable<_Tp>::value,
1696 __wrap_iter<_Tp*>
1697>::type
1698__unwrap_iter(__wrap_iter<_Tp*> __i)
1699{
1700 return __i;
1701}
1702
1703#endif // _LIBCPP_DEBUG_LEVEL < 2
1704
1705template <class _InputIterator, class _OutputIterator>
1706inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1707_OutputIterator
1708__copy_constexpr(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
1709{
1710 for (; __first != __last; ++__first, (void) ++__result)
1711 *__result = *__first;
1712 return __result;
1713}
1714
1715template <class _InputIterator, class _OutputIterator>
1716inline _LIBCPP_INLINE_VISIBILITY
1717_OutputIterator
1718__copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
1719{
1720 return _VSTD::__copy_constexpr(__first, __last, __result);
1721}
1722
1723template <class _Tp, class _Up>
1724inline _LIBCPP_INLINE_VISIBILITY
1725typename enable_if
1726<
1727 is_same<typename remove_const<_Tp>::type, _Up>::value &&
1728 is_trivially_copy_assignable<_Up>::value,
1729 _Up*
1730>::type
1731__copy(_Tp* __first, _Tp* __last, _Up* __result)
1732{
1733 const size_t __n = static_cast<size_t>(__last - __first);
1734 if (__n > 0)
1735 _VSTD::memmove(__result, __first, __n * sizeof(_Up));
1736 return __result + __n;
1737}
1738
1739template <class _InputIterator, class _OutputIterator>
1740inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1741_OutputIterator
1742copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
1743{
1744 if (__libcpp_is_constant_evaluated()) {
1745 return _VSTD::__copy_constexpr(
1746 _VSTD::__unwrap_iter(__first), _VSTD::__unwrap_iter(__last), _VSTD::__unwrap_iter(__result));
1747 } else {
1748 return _VSTD::__copy(
1749 _VSTD::__unwrap_iter(__first), _VSTD::__unwrap_iter(__last), _VSTD::__unwrap_iter(__result));
1750 }
1751}
1752
1753// copy_backward
1754
1755template <class _BidirectionalIterator, class _OutputIterator>
1756inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1757_OutputIterator
1758__copy_backward_constexpr(_BidirectionalIterator __first, _BidirectionalIterator __last, _OutputIterator __result)
1759{
1760 while (__first != __last)
1761 *--__result = *--__last;
1762 return __result;
1763}
1764
1765template <class _BidirectionalIterator, class _OutputIterator>
1766inline _LIBCPP_INLINE_VISIBILITY
1767_OutputIterator
1768__copy_backward(_BidirectionalIterator __first, _BidirectionalIterator __last, _OutputIterator __result)
1769{
1770 return _VSTD::__copy_backward_constexpr(__first, __last, __result);
1771}
1772
1773template <class _Tp, class _Up>
1774inline _LIBCPP_INLINE_VISIBILITY
1775typename enable_if
1776<
1777 is_same<typename remove_const<_Tp>::type, _Up>::value &&
1778 is_trivially_copy_assignable<_Up>::value,
1779 _Up*
1780>::type
1781__copy_backward(_Tp* __first, _Tp* __last, _Up* __result)
1782{
1783 const size_t __n = static_cast<size_t>(__last - __first);
1784 if (__n > 0)
1785 {
1786 __result -= __n;
1787 _VSTD::memmove(__result, __first, __n * sizeof(_Up));
1788 }
1789 return __result;
1790}
1791
1792template <class _BidirectionalIterator1, class _BidirectionalIterator2>
1793inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1794_BidirectionalIterator2
1795copy_backward(_BidirectionalIterator1 __first, _BidirectionalIterator1 __last,
1796 _BidirectionalIterator2 __result)
1797{
1798 if (__libcpp_is_constant_evaluated()) {
1799 return _VSTD::__copy_backward_constexpr(_VSTD::__unwrap_iter(__first),
1800 _VSTD::__unwrap_iter(__last),
1801 _VSTD::__unwrap_iter(__result));
1802 } else {
1803 return _VSTD::__copy_backward(_VSTD::__unwrap_iter(__first),
1804 _VSTD::__unwrap_iter(__last),
1805 _VSTD::__unwrap_iter(__result));
1806 }
1807}
1808
1809// copy_if
1810
1811template<class _InputIterator, class _OutputIterator, class _Predicate>
1812inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1813_OutputIterator
1814copy_if(_InputIterator __first, _InputIterator __last,
1815 _OutputIterator __result, _Predicate __pred)
1816{
1817 for (; __first != __last; ++__first)
1818 {
1819 if (__pred(*__first))
1820 {
1821 *__result = *__first;
1822 ++__result;
1823 }
1824 }
1825 return __result;
1826}
1827
1828// copy_n
1829
1830template<class _InputIterator, class _Size, class _OutputIterator>
1831inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1832typename enable_if
1833<
1834 __is_cpp17_input_iterator<_InputIterator>::value &&
1835 !__is_cpp17_random_access_iterator<_InputIterator>::value,
1836 _OutputIterator
1837>::type
1838copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result)
1839{
1840 typedef decltype(_VSTD::__convert_to_integral(__orig_n)) _IntegralSize;
1841 _IntegralSize __n = __orig_n;
1842 if (__n > 0)
1843 {
1844 *__result = *__first;
1845 ++__result;
1846 for (--__n; __n > 0; --__n)
1847 {
1848 ++__first;
1849 *__result = *__first;
1850 ++__result;
1851 }
1852 }
1853 return __result;
1854}
1855
1856template<class _InputIterator, class _Size, class _OutputIterator>
1857inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1858typename enable_if
1859<
1860 __is_cpp17_random_access_iterator<_InputIterator>::value,
1861 _OutputIterator
1862>::type
1863copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result)
1864{
1865 typedef decltype(_VSTD::__convert_to_integral(__orig_n)) _IntegralSize;
1866 _IntegralSize __n = __orig_n;
1867 return _VSTD::copy(__first, __first + __n, __result);
1868}
1869
1870// move
1871
1872// __move_constexpr exists so that __move doesn't call itself when delegating to the constexpr
1873// version of __move.
1874template <class _InputIterator, class _OutputIterator>
1875inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1876_OutputIterator
1877__move_constexpr(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
1878{
1879 for (; __first != __last; ++__first, (void) ++__result)
1880 *__result = _VSTD::move(*__first);
1881 return __result;
1882}
1883
1884template <class _InputIterator, class _OutputIterator>
1885inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1886_OutputIterator
1887__move(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
1888{
1889 return _VSTD::__move_constexpr(__first, __last, __result);
1890}
1891
1892template <class _Tp, class _Up>
1893inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1894typename enable_if
1895<
1896 is_same<typename remove_const<_Tp>::type, _Up>::value &&
1897 is_trivially_copy_assignable<_Up>::value,
1898 _Up*
1899>::type
1900__move(_Tp* __first, _Tp* __last, _Up* __result)
1901{
1902 if (__libcpp_is_constant_evaluated())
1903 return _VSTD::__move_constexpr(__first, __last, __result);
1904 const size_t __n = static_cast<size_t>(__last - __first);
1905 if (__n > 0)
1906 _VSTD::memmove(__result, __first, __n * sizeof(_Up));
1907 return __result + __n;
1908}
1909
1910template <class _InputIterator, class _OutputIterator>
1911inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1912_OutputIterator
1913move(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
1914{
1915 return _VSTD::__move(_VSTD::__unwrap_iter(__first), _VSTD::__unwrap_iter(__last), _VSTD::__unwrap_iter(__result));
1916}
1917
1918// move_backward
1919
1920// __move_backward_constexpr exists so that __move_backward doesn't call itself when delegating to
1921// the constexpr version of __move_backward.
1922template <class _InputIterator, class _OutputIterator>
1923inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1924_OutputIterator
1925__move_backward_constexpr(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
1926{
1927 while (__first != __last)
1928 *--__result = _VSTD::move(*--__last);
1929 return __result;
1930}
1931
1932template <class _InputIterator, class _OutputIterator>
1933inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1934_OutputIterator
1935__move_backward(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
1936{
1937 return _VSTD::__move_backward_constexpr(__first, __last, __result);
1938}
1939
1940template <class _Tp, class _Up>
1941inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1942typename enable_if
1943<
1944 is_same<typename remove_const<_Tp>::type, _Up>::value &&
1945 is_trivially_copy_assignable<_Up>::value,
1946 _Up*
1947>::type
1948__move_backward(_Tp* __first, _Tp* __last, _Up* __result)
1949{
1950 if (__libcpp_is_constant_evaluated())
1951 return _VSTD::__move_backward_constexpr(__first, __last, __result);
1952 const size_t __n = static_cast<size_t>(__last - __first);
1953 if (__n > 0)
1954 {
1955 __result -= __n;
1956 _VSTD::memmove(__result, __first, __n * sizeof(_Up));
1957 }
1958 return __result;
1959}
1960
1961template <class _BidirectionalIterator1, class _BidirectionalIterator2>
1962inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1963_BidirectionalIterator2
1964move_backward(_BidirectionalIterator1 __first, _BidirectionalIterator1 __last,
1965 _BidirectionalIterator2 __result)
1966{
1967 return _VSTD::__move_backward(_VSTD::__unwrap_iter(__first), _VSTD::__unwrap_iter(__last), _VSTD::__unwrap_iter(__result));
1968}
1969
1970// iter_swap
1971
1972// moved to <type_traits> for better swap / noexcept support
1973
1974// transform
1975
1976template <class _InputIterator, class _OutputIterator, class _UnaryOperation>
1977inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1978_OutputIterator
1979transform(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _UnaryOperation __op)
1980{
1981 for (; __first != __last; ++__first, (void) ++__result)
1982 *__result = __op(*__first);
1983 return __result;
1984}
1985
1986template <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _BinaryOperation>
1987inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1988_OutputIterator
1989transform(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2,
1990 _OutputIterator __result, _BinaryOperation __binary_op)
1991{
1992 for (; __first1 != __last1; ++__first1, (void) ++__first2, ++__result)
1993 *__result = __binary_op(*__first1, *__first2);
1994 return __result;
1995}
1996
1997// replace
1998
1999template <class _ForwardIterator, class _Tp>
2000inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
2001void
2002replace(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __old_value, const _Tp& __new_value)
2003{
2004 for (; __first != __last; ++__first)
2005 if (*__first == __old_value)
2006 *__first = __new_value;
2007}
2008
2009// replace_if
2010
2011template <class _ForwardIterator, class _Predicate, class _Tp>
2012inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
2013void
2014replace_if(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, const _Tp& __new_value)
2015{
2016 for (; __first != __last; ++__first)
2017 if (__pred(*__first))
2018 *__first = __new_value;
2019}
2020
2021// replace_copy
2022
2023template <class _InputIterator, class _OutputIterator, class _Tp>
2024inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
2025_OutputIterator
2026replace_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result,
2027 const _Tp& __old_value, const _Tp& __new_value)
2028{
2029 for (; __first != __last; ++__first, (void) ++__result)
2030 if (*__first == __old_value)
2031 *__result = __new_value;
2032 else
2033 *__result = *__first;
2034 return __result;
2035}
2036
2037// replace_copy_if
2038
2039template <class _InputIterator, class _OutputIterator, class _Predicate, class _Tp>
2040inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
2041_OutputIterator
2042replace_copy_if(_InputIterator __first, _InputIterator __last, _OutputIterator __result,
2043 _Predicate __pred, const _Tp& __new_value)
2044{
2045 for (; __first != __last; ++__first, (void) ++__result)
2046 if (__pred(*__first))
2047 *__result = __new_value;
2048 else
2049 *__result = *__first;
2050 return __result;
2051}
2052
2053// fill_n
2054
2055template <class _OutputIterator, class _Size, class _Tp>
2056inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
2057_OutputIterator
2058__fill_n(_OutputIterator __first, _Size __n, const _Tp& __value_)
2059{
2060 for (; __n > 0; ++__first, (void) --__n)
2061 *__first = __value_;
2062 return __first;
2063}
2064
2065template <class _OutputIterator, class _Size, class _Tp>
2066inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
2067_OutputIterator
2068fill_n(_OutputIterator __first, _Size __n, const _Tp& __value_)
2069{
2070 return _VSTD::__fill_n(__first, _VSTD::__convert_to_integral(__n), __value_);
2071}
2072
2073// fill
2074
2075template <class _ForwardIterator, class _Tp>
2076inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
2077void
2078__fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, forward_iterator_tag)
2079{
2080 for (; __first != __last; ++__first)
2081 *__first = __value_;
2082}
2083
2084template <class _RandomAccessIterator, class _Tp>
2085inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
2086void
2087__fill(_RandomAccessIterator __first, _RandomAccessIterator __last, const _Tp& __value_, random_access_iterator_tag)
2088{
2089 _VSTD::fill_n(__first, __last - __first, __value_);
2090}
2091
2092template <class _ForwardIterator, class _Tp>
2093inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
2094void
2095fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_)
2096{
2097 _VSTD::__fill(__first, __last, __value_, typename iterator_traits<_ForwardIterator>::iterator_category());
2098}
2099
2100// generate
2101
2102template <class _ForwardIterator, class _Generator>
2103inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
2104void
2105generate(_ForwardIterator __first, _ForwardIterator __last, _Generator __gen)
2106{
2107 for (; __first != __last; ++__first)
2108 *__first = __gen();
2109}
2110
2111// generate_n
2112
2113template <class _OutputIterator, class _Size, class _Generator>
2114inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
2115_OutputIterator
2116generate_n(_OutputIterator __first, _Size __orig_n, _Generator __gen)
2117{
2118 typedef decltype(_VSTD::__convert_to_integral(__orig_n)) _IntegralSize;
2119 _IntegralSize __n = __orig_n;
2120 for (; __n > 0; ++__first, (void) --__n)
2121 *__first = __gen();
2122 return __first;
2123}
2124
2125// remove
2126
2127template <class _ForwardIterator, class _Tp>
2128_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator
2129remove(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_)
2130{
2131 __first = _VSTD::find(__first, __last, __value_);
2132 if (__first != __last)
2133 {
2134 _ForwardIterator __i = __first;
2135 while (++__i != __last)
2136 {
2137 if (!(*__i == __value_))
2138 {
2139 *__first = _VSTD::move(*__i);
2140 ++__first;
2141 }
2142 }
2143 }
2144 return __first;
2145}
2146
2147// remove_if
2148
2149template <class _ForwardIterator, class _Predicate>
2150_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator
2151remove_if(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred)
2152{
2153 __first = _VSTD::find_if<_ForwardIterator, typename add_lvalue_reference<_Predicate>::type>
2154 (__first, __last, __pred);
2155 if (__first != __last)
2156 {
2157 _ForwardIterator __i = __first;
2158 while (++__i != __last)
2159 {
2160 if (!__pred(*__i))
2161 {
2162 *__first = _VSTD::move(*__i);
2163 ++__first;
2164 }
2165 }
2166 }
2167 return __first;
2168}
2169
2170// remove_copy
2171
2172template <class _InputIterator, class _OutputIterator, class _Tp>
2173inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
2174_OutputIterator
2175remove_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, const _Tp& __value_)
2176{
2177 for (; __first != __last; ++__first)
2178 {
2179 if (!(*__first == __value_))
2180 {
2181 *__result = *__first;
2182 ++__result;
2183 }
2184 }
2185 return __result;
2186}
2187
2188// remove_copy_if
2189
2190template <class _InputIterator, class _OutputIterator, class _Predicate>
2191inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
2192_OutputIterator
2193remove_copy_if(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _Predicate __pred)
2194{
2195 for (; __first != __last; ++__first)
2196 {
2197 if (!__pred(*__first))
2198 {
2199 *__result = *__first;
2200 ++__result;
2201 }
2202 }
2203 return __result;
2204}
2205
2206// unique
2207
2208template <class _ForwardIterator, class _BinaryPredicate>
2209_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator
2210unique(_ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred)
2211{
2212 __first = _VSTD::adjacent_find<_ForwardIterator, typename add_lvalue_reference<_BinaryPredicate>::type>
2213 (__first, __last, __pred);
2214 if (__first != __last)
2215 {
2216 // ... a a ? ...
2217 // f i
2218 _ForwardIterator __i = __first;
2219 for (++__i; ++__i != __last;)
2220 if (!__pred(*__first, *__i))
2221 *++__first = _VSTD::move(*__i);
2222 ++__first;
2223 }
2224 return __first;
2225}
2226
2227template <class _ForwardIterator>
2228_LIBCPP_NODISCARD_EXT inline
2229_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
2230_ForwardIterator
2231unique(_ForwardIterator __first, _ForwardIterator __last)
2232{
2233 typedef typename iterator_traits<_ForwardIterator>::value_type __v;
2234 return _VSTD::unique(__first, __last, __equal_to<__v>());
2235}
2236
2237// unique_copy
2238
2239template <class _BinaryPredicate, class _InputIterator, class _OutputIterator>
2240_LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator
2241__unique_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _BinaryPredicate __pred,
2242 input_iterator_tag, output_iterator_tag)
2243{
2244 if (__first != __last)
2245 {
2246 typename iterator_traits<_InputIterator>::value_type __t(*__first);
2247 *__result = __t;
2248 ++__result;
2249 while (++__first != __last)
2250 {
2251 if (!__pred(__t, *__first))
2252 {
2253 __t = *__first;
2254 *__result = __t;
2255 ++__result;
2256 }
2257 }
2258 }
2259 return __result;
2260}
2261
2262template <class _BinaryPredicate, class _ForwardIterator, class _OutputIterator>
2263_LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator
2264__unique_copy(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result, _BinaryPredicate __pred,
2265 forward_iterator_tag, output_iterator_tag)
2266{
2267 if (__first != __last)
2268 {
2269 _ForwardIterator __i = __first;
2270 *__result = *__i;
2271 ++__result;
2272 while (++__first != __last)
2273 {
2274 if (!__pred(*__i, *__first))
2275 {
2276 *__result = *__first;
2277 ++__result;
2278 __i = __first;
2279 }
2280 }
2281 }
2282 return __result;
2283}
2284
2285template <class _BinaryPredicate, class _InputIterator, class _ForwardIterator>
2286_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator
2287__unique_copy(_InputIterator __first, _InputIterator __last, _ForwardIterator __result, _BinaryPredicate __pred,
2288 input_iterator_tag, forward_iterator_tag)
2289{
2290 if (__first != __last)
2291 {
2292 *__result = *__first;
2293 while (++__first != __last)
2294 if (!__pred(*__result, *__first))
2295 *++__result = *__first;
2296 ++__result;
2297 }
2298 return __result;
2299}
2300
2301template <class _InputIterator, class _OutputIterator, class _BinaryPredicate>
2302inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
2303_OutputIterator
2304unique_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _BinaryPredicate __pred)
2305{
2306 return _VSTD::__unique_copy<typename add_lvalue_reference<_BinaryPredicate>::type>
2307 (__first, __last, __result, __pred,
2308 typename iterator_traits<_InputIterator>::iterator_category(),
2309 typename iterator_traits<_OutputIterator>::iterator_category());
2310}
2311
2312template <class _InputIterator, class _OutputIterator>
2313inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
2314_OutputIterator
2315unique_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
2316{
2317 typedef typename iterator_traits<_InputIterator>::value_type __v;
2318 return _VSTD::unique_copy(__first, __last, __result, __equal_to<__v>());
2319}
2320
2321// reverse
2322
2323template <class _BidirectionalIterator>
2324inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
2325void
2326__reverse(_BidirectionalIterator __first, _BidirectionalIterator __last, bidirectional_iterator_tag)
2327{
2328 while (__first != __last)
2329 {
2330 if (__first == --__last)
2331 break;
2332 _VSTD::iter_swap(__first, __last);
2333 ++__first;
2334 }
2335}
2336
2337template <class _RandomAccessIterator>
2338inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
2339void
2340__reverse(_RandomAccessIterator __first, _RandomAccessIterator __last, random_access_iterator_tag)
2341{
2342 if (__first != __last)
2343 for (; __first < --__last; ++__first)
2344 _VSTD::iter_swap(__first, __last);
2345}
2346
2347template <class _BidirectionalIterator>
2348inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
2349void
2350reverse(_BidirectionalIterator __first, _BidirectionalIterator __last)
2351{
2352 _VSTD::__reverse(__first, __last, typename iterator_traits<_BidirectionalIterator>::iterator_category());
2353}
2354
2355// reverse_copy
2356
2357template <class _BidirectionalIterator, class _OutputIterator>
2358inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
2359_OutputIterator
2360reverse_copy(_BidirectionalIterator __first, _BidirectionalIterator __last, _OutputIterator __result)
2361{
2362 for (; __first != __last; ++__result)
2363 *__result = *--__last;
2364 return __result;
2365}
2366
2367// rotate
2368
2369template <class _ForwardIterator>
2370_LIBCPP_CONSTEXPR_AFTER_CXX11 _ForwardIterator
2371__rotate_left(_ForwardIterator __first, _ForwardIterator __last)
2372{
2373 typedef typename iterator_traits<_ForwardIterator>::value_type value_type;
2374 value_type __tmp = _VSTD::move(*__first);
2375 _ForwardIterator __lm1 = _VSTD::move(_VSTD::next(__first), __last, __first);
2376 *__lm1 = _VSTD::move(__tmp);
2377 return __lm1;
2378}
2379
2380template <class _BidirectionalIterator>
2381_LIBCPP_CONSTEXPR_AFTER_CXX11 _BidirectionalIterator
2382__rotate_right(_BidirectionalIterator __first, _BidirectionalIterator __last)
2383{
2384 typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;
2385 _BidirectionalIterator __lm1 = _VSTD::prev(__last);
2386 value_type __tmp = _VSTD::move(*__lm1);
2387 _BidirectionalIterator __fp1 = _VSTD::move_backward(__first, __lm1, __last);
2388 *__first = _VSTD::move(__tmp);
2389 return __fp1;
2390}
2391
2392template <class _ForwardIterator>
2393_LIBCPP_CONSTEXPR_AFTER_CXX14 _ForwardIterator
2394__rotate_forward(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last)
2395{
2396 _ForwardIterator __i = __middle;
2397 while (true)
2398 {
2399 swap(*__first, *__i);
2400 ++__first;
2401 if (++__i == __last)
2402 break;
2403 if (__first == __middle)
2404 __middle = __i;
2405 }
2406 _ForwardIterator __r = __first;
2407 if (__first != __middle)
2408 {
2409 __i = __middle;
2410 while (true)
2411 {
2412 swap(*__first, *__i);
2413 ++__first;
2414 if (++__i == __last)
2415 {
2416 if (__first == __middle)
2417 break;
2418 __i = __middle;
2419 }
2420 else if (__first == __middle)
2421 __middle = __i;
2422 }
2423 }
2424 return __r;
2425}
2426
2427template<typename _Integral>
2428inline _LIBCPP_INLINE_VISIBILITY
2429_LIBCPP_CONSTEXPR_AFTER_CXX14 _Integral
2430__algo_gcd(_Integral __x, _Integral __y)
2431{
2432 do
2433 {
2434 _Integral __t = __x % __y;
2435 __x = __y;
2436 __y = __t;
2437 } while (__y);
2438 return __x;
2439}
2440
2441template<typename _RandomAccessIterator>
2442_LIBCPP_CONSTEXPR_AFTER_CXX14 _RandomAccessIterator
2443__rotate_gcd(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last)
2444{
2445 typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
2446 typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
2447
2448 const difference_type __m1 = __middle - __first;
2449 const difference_type __m2 = __last - __middle;
2450 if (__m1 == __m2)
2451 {
2452 _VSTD::swap_ranges(__first, __middle, __middle);
2453 return __middle;
2454 }
2455 const difference_type __g = _VSTD::__algo_gcd(__m1, __m2);
2456 for (_RandomAccessIterator __p = __first + __g; __p != __first;)
2457 {
2458 value_type __t(_VSTD::move(*--__p));
2459 _RandomAccessIterator __p1 = __p;
2460 _RandomAccessIterator __p2 = __p1 + __m1;
2461 do
2462 {
2463 *__p1 = _VSTD::move(*__p2);
2464 __p1 = __p2;
2465 const difference_type __d = __last - __p2;
2466 if (__m1 < __d)
2467 __p2 += __m1;
2468 else
2469 __p2 = __first + (__m1 - __d);
2470 } while (__p2 != __p);
2471 *__p1 = _VSTD::move(__t);
2472 }
2473 return __first + __m2;
2474}
2475
2476template <class _ForwardIterator>
2477inline _LIBCPP_INLINE_VISIBILITY
2478_LIBCPP_CONSTEXPR_AFTER_CXX11 _ForwardIterator
2479__rotate(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last,
2480 _VSTD::forward_iterator_tag)
2481{
2482 typedef typename _VSTD::iterator_traits<_ForwardIterator>::value_type value_type;
2483 if (_VSTD::is_trivially_move_assignable<value_type>::value)
2484 {
2485 if (_VSTD::next(__first) == __middle)
2486 return _VSTD::__rotate_left(__first, __last);
2487 }
2488 return _VSTD::__rotate_forward(__first, __middle, __last);
2489}
2490
2491template <class _BidirectionalIterator>
2492inline _LIBCPP_INLINE_VISIBILITY
2493_LIBCPP_CONSTEXPR_AFTER_CXX11 _BidirectionalIterator
2494__rotate(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last,
2495 _VSTD::bidirectional_iterator_tag)
2496{
2497 typedef typename _VSTD::iterator_traits<_BidirectionalIterator>::value_type value_type;
2498 if (_VSTD::is_trivially_move_assignable<value_type>::value)
2499 {
2500 if (_VSTD::next(__first) == __middle)
2501 return _VSTD::__rotate_left(__first, __last);
2502 if (_VSTD::next(__middle) == __last)
2503 return _VSTD::__rotate_right(__first, __last);
2504 }
2505 return _VSTD::__rotate_forward(__first, __middle, __last);
2506}
2507
2508template <class _RandomAccessIterator>
2509inline _LIBCPP_INLINE_VISIBILITY
2510_LIBCPP_CONSTEXPR_AFTER_CXX11 _RandomAccessIterator
2511__rotate(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last,
2512 _VSTD::random_access_iterator_tag)
2513{
2514 typedef typename _VSTD::iterator_traits<_RandomAccessIterator>::value_type value_type;
2515 if (_VSTD::is_trivially_move_assignable<value_type>::value)
2516 {
2517 if (_VSTD::next(__first) == __middle)
2518 return _VSTD::__rotate_left(__first, __last);
2519 if (_VSTD::next(__middle) == __last)
2520 return _VSTD::__rotate_right(__first, __last);
2521 return _VSTD::__rotate_gcd(__first, __middle, __last);
2522 }
2523 return _VSTD::__rotate_forward(__first, __middle, __last);
2524}
2525
2526template <class _ForwardIterator>
2527inline _LIBCPP_INLINE_VISIBILITY
2528_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator
2529rotate(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last)
2530{
2531 if (__first == __middle)
2532 return __last;
2533 if (__middle == __last)
2534 return __first;
2535 return _VSTD::__rotate(__first, __middle, __last,
2536 typename _VSTD::iterator_traits<_ForwardIterator>::iterator_category());
2537}
2538
2539// rotate_copy
2540
2541template <class _ForwardIterator, class _OutputIterator>
2542inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
2543_OutputIterator
2544rotate_copy(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last, _OutputIterator __result)
2545{
2546 return _VSTD::copy(__first, __middle, _VSTD::copy(__middle, __last, __result));
2547}
2548
2549// min_element
2550
2551template <class _ForwardIterator, class _Compare>
2552_LIBCPP_NODISCARD_EXT inline
2553_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
2554_ForwardIterator
2555min_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
2556{
2557 static_assert(__is_cpp17_forward_iterator<_ForwardIterator>::value,
2558 "std::min_element requires a ForwardIterator");
2559 if (__first != __last)
2560 {
2561 _ForwardIterator __i = __first;
2562 while (++__i != __last)
2563 if (__comp(*__i, *__first))
2564 __first = __i;
2565 }
2566 return __first;
2567}
2568
2569template <class _ForwardIterator>
2570_LIBCPP_NODISCARD_EXT inline
2571_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
2572_ForwardIterator
2573min_element(_ForwardIterator __first, _ForwardIterator __last)
2574{
2575 return _VSTD::min_element(__first, __last,
2576 __less<typename iterator_traits<_ForwardIterator>::value_type>());
2577}
2578
2579// min
2580
2581template <class _Tp, class _Compare>
2582_LIBCPP_NODISCARD_EXT inline
2583_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
2584const _Tp&
2585min(const _Tp& __a, const _Tp& __b, _Compare __comp)
2586{
2587 return __comp(__b, __a) ? __b : __a;
2588}
2589
2590template <class _Tp>
2591_LIBCPP_NODISCARD_EXT inline
2592_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
2593const _Tp&
2594min(const _Tp& __a, const _Tp& __b)
2595{
2596 return _VSTD::min(__a, __b, __less<_Tp>());
2597}
2598
2599#ifndef _LIBCPP_CXX03_LANG
2600
2601template<class _Tp, class _Compare>
2602_LIBCPP_NODISCARD_EXT inline
2603_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
2604_Tp
2605min(initializer_list<_Tp> __t, _Compare __comp)
2606{
2607 return *_VSTD::min_element(__t.begin(), __t.end(), __comp);
2608}
2609
2610template<class _Tp>
2611_LIBCPP_NODISCARD_EXT inline
2612_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
2613_Tp
2614min(initializer_list<_Tp> __t)
2615{
2616 return *_VSTD::min_element(__t.begin(), __t.end(), __less<_Tp>());
2617}
2618
2619#endif // _LIBCPP_CXX03_LANG
2620
2621// max_element
2622
2623template <class _ForwardIterator, class _Compare>
2624_LIBCPP_NODISCARD_EXT inline
2625_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
2626_ForwardIterator
2627max_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
2628{
2629 static_assert(__is_cpp17_forward_iterator<_ForwardIterator>::value,
2630 "std::max_element requires a ForwardIterator");
2631 if (__first != __last)
2632 {
2633 _ForwardIterator __i = __first;
2634 while (++__i != __last)
2635 if (__comp(*__first, *__i))
2636 __first = __i;
2637 }
2638 return __first;
2639}
2640
2641
2642template <class _ForwardIterator>
2643_LIBCPP_NODISCARD_EXT inline
2644_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
2645_ForwardIterator
2646max_element(_ForwardIterator __first, _ForwardIterator __last)
2647{
2648 return _VSTD::max_element(__first, __last,
2649 __less<typename iterator_traits<_ForwardIterator>::value_type>());
2650}
2651
2652// max
2653
2654template <class _Tp, class _Compare>
2655_LIBCPP_NODISCARD_EXT inline
2656_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
2657const _Tp&
2658max(const _Tp& __a, const _Tp& __b, _Compare __comp)
2659{
2660 return __comp(__a, __b) ? __b : __a;
2661}
2662
2663template <class _Tp>
2664_LIBCPP_NODISCARD_EXT inline
2665_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
2666const _Tp&
2667max(const _Tp& __a, const _Tp& __b)
2668{
2669 return _VSTD::max(__a, __b, __less<_Tp>());
2670}
2671
2672#ifndef _LIBCPP_CXX03_LANG
2673
2674template<class _Tp, class _Compare>
2675_LIBCPP_NODISCARD_EXT inline
2676_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
2677_Tp
2678max(initializer_list<_Tp> __t, _Compare __comp)
2679{
2680 return *_VSTD::max_element(__t.begin(), __t.end(), __comp);
2681}
2682
2683template<class _Tp>
2684_LIBCPP_NODISCARD_EXT inline
2685_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
2686_Tp
2687max(initializer_list<_Tp> __t)
2688{
2689 return *_VSTD::max_element(__t.begin(), __t.end(), __less<_Tp>());
2690}
2691
2692#endif // _LIBCPP_CXX03_LANG
2693
2694#if _LIBCPP_STD_VER > 14
2695// clamp
2696template<class _Tp, class _Compare>
2697_LIBCPP_NODISCARD_EXT inline
2698_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
2699const _Tp&
2700clamp(const _Tp& __v, const _Tp& __lo, const _Tp& __hi, _Compare __comp)
2701{
2702 _LIBCPP_ASSERT(!__comp(__hi, __lo), "Bad bounds passed to std::clamp");
2703 return __comp(__v, __lo) ? __lo : __comp(__hi, __v) ? __hi : __v;
2704
2705}
2706
2707template<class _Tp>
2708_LIBCPP_NODISCARD_EXT inline
2709_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
2710const _Tp&
2711clamp(const _Tp& __v, const _Tp& __lo, const _Tp& __hi)
2712{
2713 return _VSTD::clamp(__v, __lo, __hi, __less<_Tp>());
2714}
2715#endif
2716
2717// minmax_element
2718
2719template <class _ForwardIterator, class _Compare>
2720_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_AFTER_CXX11
2721pair<_ForwardIterator, _ForwardIterator>
2722minmax_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
2723{
2724 static_assert(__is_cpp17_forward_iterator<_ForwardIterator>::value,
2725 "std::minmax_element requires a ForwardIterator");
2726 pair<_ForwardIterator, _ForwardIterator> __result(__first, __first);
2727 if (__first != __last)
2728 {
2729 if (++__first != __last)
2730 {
2731 if (__comp(*__first, *__result.first))
2732 __result.first = __first;
2733 else
2734 __result.second = __first;
2735 while (++__first != __last)
2736 {
2737 _ForwardIterator __i = __first;
2738 if (++__first == __last)
2739 {
2740 if (__comp(*__i, *__result.first))
2741 __result.first = __i;
2742 else if (!__comp(*__i, *__result.second))
2743 __result.second = __i;
2744 break;
2745 }
2746 else
2747 {
2748 if (__comp(*__first, *__i))
2749 {
2750 if (__comp(*__first, *__result.first))
2751 __result.first = __first;
2752 if (!__comp(*__i, *__result.second))
2753 __result.second = __i;
2754 }
2755 else
2756 {
2757 if (__comp(*__i, *__result.first))
2758 __result.first = __i;
2759 if (!__comp(*__first, *__result.second))
2760 __result.second = __first;
2761 }
2762 }
2763 }
2764 }
2765 }
2766 return __result;
2767}
2768
2769template <class _ForwardIterator>
2770_LIBCPP_NODISCARD_EXT inline
2771_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
2772pair<_ForwardIterator, _ForwardIterator>
2773minmax_element(_ForwardIterator __first, _ForwardIterator __last)
2774{
2775 return _VSTD::minmax_element(__first, __last,
2776 __less<typename iterator_traits<_ForwardIterator>::value_type>());
2777}
2778
2779// minmax
2780
2781template<class _Tp, class _Compare>
2782_LIBCPP_NODISCARD_EXT inline
2783_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
2784pair<const _Tp&, const _Tp&>
2785minmax(const _Tp& __a, const _Tp& __b, _Compare __comp)
2786{
2787 return __comp(__b, __a) ? pair<const _Tp&, const _Tp&>(__b, __a) :
2788 pair<const _Tp&, const _Tp&>(__a, __b);
2789}
2790
2791template<class _Tp>
2792_LIBCPP_NODISCARD_EXT inline
2793_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
2794pair<const _Tp&, const _Tp&>
2795minmax(const _Tp& __a, const _Tp& __b)
2796{
2797 return _VSTD::minmax(__a, __b, __less<_Tp>());
2798}
2799
2800#ifndef _LIBCPP_CXX03_LANG
2801
2802template<class _Tp, class _Compare>
2803_LIBCPP_NODISCARD_EXT inline
2804_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
2805pair<_Tp, _Tp>
2806minmax(initializer_list<_Tp> __t, _Compare __comp)
2807{
2808 typedef typename initializer_list<_Tp>::const_iterator _Iter;
2809 _Iter __first = __t.begin();
2810 _Iter __last = __t.end();
2811 pair<_Tp, _Tp> __result(*__first, *__first);
2812
2813 ++__first;
2814 if (__t.size() % 2 == 0)
2815 {
2816 if (__comp(*__first, __result.first))
2817 __result.first = *__first;
2818 else
2819 __result.second = *__first;
2820 ++__first;
2821 }
2822
2823 while (__first != __last)
2824 {
2825 _Tp __prev = *__first++;
2826 if (__comp(*__first, __prev)) {
2827 if ( __comp(*__first, __result.first)) __result.first = *__first;
2828 if (!__comp(__prev, __result.second)) __result.second = __prev;
2829 }
2830 else {
2831 if ( __comp(__prev, __result.first)) __result.first = __prev;
2832 if (!__comp(*__first, __result.second)) __result.second = *__first;
2833 }
2834
2835 __first++;
2836 }
2837 return __result;
2838}
2839
2840template<class _Tp>
2841_LIBCPP_NODISCARD_EXT inline
2842_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
2843pair<_Tp, _Tp>
2844minmax(initializer_list<_Tp> __t)
2845{
2846 return _VSTD::minmax(__t, __less<_Tp>());
2847}
2848
2849#endif // _LIBCPP_CXX03_LANG
2850
2851// random_shuffle
2852
2853// __independent_bits_engine
2854
2855template <unsigned long long _Xp, size_t _Rp>
2856struct __log2_imp
2857{
2858 static const size_t value = _Xp & ((unsigned long long)(1) << _Rp) ? _Rp
2859 : __log2_imp<_Xp, _Rp - 1>::value;
2860};
2861
2862template <unsigned long long _Xp>
2863struct __log2_imp<_Xp, 0>
2864{
2865 static const size_t value = 0;
2866};
2867
2868template <size_t _Rp>
2869struct __log2_imp<0, _Rp>
2870{
2871 static const size_t value = _Rp + 1;
2872};
2873
2874template <class _UIntType, _UIntType _Xp>
2875struct __log2
2876{
2877 static const size_t value = __log2_imp<_Xp,
2878 sizeof(_UIntType) * __CHAR_BIT__ - 1>::value;
2879};
2880
2881template<class _Engine, class _UIntType>
2882class __independent_bits_engine
2883{
2884public:
2885 // types
2886 typedef _UIntType result_type;
2887
2888private:
2889 typedef typename _Engine::result_type _Engine_result_type;
2890 typedef typename conditional
2891 <
2892 sizeof(_Engine_result_type) <= sizeof(result_type),
2893 result_type,
2894 _Engine_result_type
2895 >::type _Working_result_type;
2896
2897 _Engine& __e_;
2898 size_t __w_;
2899 size_t __w0_;
2900 size_t __n_;
2901 size_t __n0_;
2902 _Working_result_type __y0_;
2903 _Working_result_type __y1_;
2904 _Engine_result_type __mask0_;
2905 _Engine_result_type __mask1_;
2906
2907#ifdef _LIBCPP_CXX03_LANG
2908 static const _Working_result_type _Rp = _Engine::_Max - _Engine::_Min
2909 + _Working_result_type(1);
2910#else
2911 static _LIBCPP_CONSTEXPR const _Working_result_type _Rp = _Engine::max() - _Engine::min()
2912 + _Working_result_type(1);
2913#endif
2914 static _LIBCPP_CONSTEXPR const size_t __m = __log2<_Working_result_type, _Rp>::value;
2915 static _LIBCPP_CONSTEXPR const size_t _WDt = numeric_limits<_Working_result_type>::digits;
2916 static _LIBCPP_CONSTEXPR const size_t _EDt = numeric_limits<_Engine_result_type>::digits;
2917
2918public:
2919 // constructors and seeding functions
2920 __independent_bits_engine(_Engine& __e, size_t __w);
2921
2922 // generating functions
2923 result_type operator()() {return __eval(integral_constant<bool, _Rp != 0>());}
2924
2925private:
2926 result_type __eval(false_type);
2927 result_type __eval(true_type);
2928};
2929
2930template<class _Engine, class _UIntType>
2931__independent_bits_engine<_Engine, _UIntType>
2932 ::__independent_bits_engine(_Engine& __e, size_t __w)
2933 : __e_(__e),
2934 __w_(__w)
2935{
2936 __n_ = __w_ / __m + (__w_ % __m != 0);
2937 __w0_ = __w_ / __n_;
2938 if (_Rp == 0)
2939 __y0_ = _Rp;
2940 else if (__w0_ < _WDt)
2941 __y0_ = (_Rp >> __w0_) << __w0_;
2942 else
2943 __y0_ = 0;
2944 if (_Rp - __y0_ > __y0_ / __n_)
2945 {
2946 ++__n_;
2947 __w0_ = __w_ / __n_;
2948 if (__w0_ < _WDt)
2949 __y0_ = (_Rp >> __w0_) << __w0_;
2950 else
2951 __y0_ = 0;
2952 }
2953 __n0_ = __n_ - __w_ % __n_;
2954 if (__w0_ < _WDt - 1)
2955 __y1_ = (_Rp >> (__w0_ + 1)) << (__w0_ + 1);
2956 else
2957 __y1_ = 0;
2958 __mask0_ = __w0_ > 0 ? _Engine_result_type(~0) >> (_EDt - __w0_) :
2959 _Engine_result_type(0);
2960 __mask1_ = __w0_ < _EDt - 1 ?
2961 _Engine_result_type(~0) >> (_EDt - (__w0_ + 1)) :
2962 _Engine_result_type(~0);
2963}
2964
2965template<class _Engine, class _UIntType>
2966inline
2967_UIntType
2968__independent_bits_engine<_Engine, _UIntType>::__eval(false_type)
2969{
2970 return static_cast<result_type>(__e_() & __mask0_);
2971}
2972
2973template<class _Engine, class _UIntType>
2974_UIntType
2975__independent_bits_engine<_Engine, _UIntType>::__eval(true_type)
2976{
2977 const size_t _WRt = numeric_limits<result_type>::digits;
2978 result_type _Sp = 0;
2979 for (size_t __k = 0; __k < __n0_; ++__k)
2980 {
2981 _Engine_result_type __u;
2982 do
2983 {
2984 __u = __e_() - _Engine::min();
2985 } while (__u >= __y0_);
2986 if (__w0_ < _WRt)
2987 _Sp <<= __w0_;
2988 else
2989 _Sp = 0;
2990 _Sp += __u & __mask0_;
2991 }
2992 for (size_t __k = __n0_; __k < __n_; ++__k)
2993 {
2994 _Engine_result_type __u;
2995 do
2996 {
2997 __u = __e_() - _Engine::min();
2998 } while (__u >= __y1_);
2999 if (__w0_ < _WRt - 1)
3000 _Sp <<= __w0_ + 1;
3001 else
3002 _Sp = 0;
3003 _Sp += __u & __mask1_;
3004 }
3005 return _Sp;
3006}
3007
3008// uniform_int_distribution
3009
3010template<class _IntType = int>
3011class uniform_int_distribution
3012{
3013public:
3014 // types
3015 typedef _IntType result_type;
3016
3017 class param_type
3018 {
3019 result_type __a_;
3020 result_type __b_;
3021 public:
3022 typedef uniform_int_distribution distribution_type;
3023
3024 explicit param_type(result_type __a = 0,
3025 result_type __b = numeric_limits<result_type>::max())
3026 : __a_(__a), __b_(__b) {}
3027
3028 result_type a() const {return __a_;}
3029 result_type b() const {return __b_;}
3030
3031 friend bool operator==(const param_type& __x, const param_type& __y)
3032 {return __x.__a_ == __y.__a_ && __x.__b_ == __y.__b_;}
3033 friend bool operator!=(const param_type& __x, const param_type& __y)
3034 {return !(__x == __y);}
3035 };
3036
3037private:
3038 param_type __p_;
3039
3040public:
3041 // constructors and reset functions
3042#ifndef _LIBCPP_CXX03_LANG
3043 uniform_int_distribution() : uniform_int_distribution(0) {}
3044 explicit uniform_int_distribution(
3045 result_type __a, result_type __b = numeric_limits<result_type>::max())
3046 : __p_(param_type(__a, __b)) {}
3047#else
3048 explicit uniform_int_distribution(
3049 result_type __a = 0,
3050 result_type __b = numeric_limits<result_type>::max())
3051 : __p_(param_type(__a, __b)) {}
3052#endif
3053 explicit uniform_int_distribution(const param_type& __p) : __p_(__p) {}
3054 void reset() {}
3055
3056 // generating functions
3057 template<class _URNG> result_type operator()(_URNG& __g)
3058 {return (*this)(__g, __p_);}
3059 template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);
3060
3061 // property functions
3062 result_type a() const {return __p_.a();}
3063 result_type b() const {return __p_.b();}
3064
3065 param_type param() const {return __p_;}
3066 void param(const param_type& __p) {__p_ = __p;}
3067
3068 result_type min() const {return a();}
3069 result_type max() const {return b();}
3070
3071 friend bool operator==(const uniform_int_distribution& __x,
3072 const uniform_int_distribution& __y)
3073 {return __x.__p_ == __y.__p_;}
3074 friend bool operator!=(const uniform_int_distribution& __x,
3075 const uniform_int_distribution& __y)
3076 {return !(__x == __y);}
3077};
3078
3079template<class _IntType>
3080template<class _URNG>
3081typename uniform_int_distribution<_IntType>::result_type
3082uniform_int_distribution<_IntType>::operator()(_URNG& __g, const param_type& __p)
3083_LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
3084{
3085 typedef typename conditional<sizeof(result_type) <= sizeof(uint32_t),
3086 uint32_t, uint64_t>::type _UIntType;
3087 const _UIntType _Rp = _UIntType(__p.b()) - _UIntType(__p.a()) + _UIntType(1);
3088 if (_Rp == 1)
3089 return __p.a();
3090 const size_t _Dt = numeric_limits<_UIntType>::digits;
3091 typedef __independent_bits_engine<_URNG, _UIntType> _Eng;
3092 if (_Rp == 0)
3093 return static_cast<result_type>(_Eng(__g, _Dt)());
3094 size_t __w = _Dt - __libcpp_clz(_Rp) - 1;
3095 if ((_Rp & (numeric_limits<_UIntType>::max() >> (_Dt - __w))) != 0)
3096 ++__w;
3097 _Eng __e(__g, __w);
3098 _UIntType __u;
3099 do
3100 {
3101 __u = __e();
3102 } while (__u >= _Rp);
3103 return static_cast<result_type>(__u + __p.a());
3104}
3105
3106#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_RANDOM_SHUFFLE) \
3107 || defined(_LIBCPP_BUILDING_LIBRARY)
3108class _LIBCPP_TYPE_VIS __rs_default;
3109
3110_LIBCPP_FUNC_VIS __rs_default __rs_get();
3111
3112class _LIBCPP_TYPE_VIS __rs_default
3113{
3114 static unsigned __c_;
3115
3116 __rs_default();
3117public:
3118 typedef uint_fast32_t result_type;
3119
3120 static const result_type _Min = 0;
3121 static const result_type _Max = 0xFFFFFFFF;
3122
3123 __rs_default(const __rs_default&);
3124 ~__rs_default();
3125
3126 result_type operator()();
3127
3128 static _LIBCPP_CONSTEXPR result_type min() {return _Min;}
3129 static _LIBCPP_CONSTEXPR result_type max() {return _Max;}
3130
3131 friend _LIBCPP_FUNC_VIS __rs_default __rs_get();
3132};
3133
3134_LIBCPP_FUNC_VIS __rs_default __rs_get();
3135
3136template <class _RandomAccessIterator>
3137_LIBCPP_DEPRECATED_IN_CXX14 void
3138random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last)
3139{
3140 typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
3141 typedef uniform_int_distribution<ptrdiff_t> _Dp;
3142 typedef typename _Dp::param_type _Pp;
3143 difference_type __d = __last - __first;
3144 if (__d > 1)
3145 {
3146 _Dp __uid;
3147 __rs_default __g = __rs_get();
3148 for (--__last, (void) --__d; __first < __last; ++__first, (void) --__d)
3149 {
3150 difference_type __i = __uid(__g, _Pp(0, __d));
3151 if (__i != difference_type(0))
3152 swap(*__first, *(__first + __i));
3153 }
3154 }
3155}
3156
3157template <class _RandomAccessIterator, class _RandomNumberGenerator>
3158_LIBCPP_DEPRECATED_IN_CXX14 void
3159random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last,
3160#ifndef _LIBCPP_CXX03_LANG
3161 _RandomNumberGenerator&& __rand)
3162#else
3163 _RandomNumberGenerator& __rand)
3164#endif
3165{
3166 typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
3167 difference_type __d = __last - __first;
3168 if (__d > 1)
3169 {
3170 for (--__last; __first < __last; ++__first, (void) --__d)
3171 {
3172 difference_type __i = __rand(__d);
3173 if (__i != difference_type(0))
3174 swap(*__first, *(__first + __i));
3175 }
3176 }
3177}
3178#endif
3179
3180template <class _PopulationIterator, class _SampleIterator, class _Distance,
3181 class _UniformRandomNumberGenerator>
3182_LIBCPP_INLINE_VISIBILITY
3183_SampleIterator __sample(_PopulationIterator __first,
3184 _PopulationIterator __last, _SampleIterator __output_iter,
3185 _Distance __n,
3186 _UniformRandomNumberGenerator & __g,
3187 input_iterator_tag) {
3188
3189 _Distance __k = 0;
3190 for (; __first != __last && __k < __n; ++__first, (void) ++__k)
3191 __output_iter[__k] = *__first;
3192 _Distance __sz = __k;
3193 for (; __first != __last; ++__first, (void) ++__k) {
3194 _Distance __r = _VSTD::uniform_int_distribution<_Distance>(0, __k)(__g);
3195 if (__r < __sz)
3196 __output_iter[__r] = *__first;
3197 }
3198 return __output_iter + _VSTD::min(__n, __k);
3199}
3200
3201template <class _PopulationIterator, class _SampleIterator, class _Distance,
3202 class _UniformRandomNumberGenerator>
3203_LIBCPP_INLINE_VISIBILITY
3204_SampleIterator __sample(_PopulationIterator __first,
3205 _PopulationIterator __last, _SampleIterator __output_iter,
3206 _Distance __n,
3207 _UniformRandomNumberGenerator& __g,
3208 forward_iterator_tag) {
3209 _Distance __unsampled_sz = _VSTD::distance(__first, __last);
3210 for (__n = _VSTD::min(__n, __unsampled_sz); __n != 0; ++__first) {
3211 _Distance __r =
3212 _VSTD::uniform_int_distribution<_Distance>(0, --__unsampled_sz)(__g);
3213 if (__r < __n) {
3214 *__output_iter++ = *__first;
3215 --__n;
3216 }
3217 }
3218 return __output_iter;
3219}
3220
3221template <class _PopulationIterator, class _SampleIterator, class _Distance,
3222 class _UniformRandomNumberGenerator>
3223_LIBCPP_INLINE_VISIBILITY
3224_SampleIterator __sample(_PopulationIterator __first,
3225 _PopulationIterator __last, _SampleIterator __output_iter,
3226 _Distance __n, _UniformRandomNumberGenerator& __g) {
3227 typedef typename iterator_traits<_PopulationIterator>::iterator_category
3228 _PopCategory;
3229 typedef typename iterator_traits<_PopulationIterator>::difference_type
3230 _Difference;
3231 static_assert(__is_cpp17_forward_iterator<_PopulationIterator>::value ||
3232 __is_cpp17_random_access_iterator<_SampleIterator>::value,
3233 "SampleIterator must meet the requirements of RandomAccessIterator");
3234 typedef typename common_type<_Distance, _Difference>::type _CommonType;
3235 _LIBCPP_ASSERT(__n >= 0, "N must be a positive number.");
3236 return _VSTD::__sample(
3237 __first, __last, __output_iter, _CommonType(__n),
3238 __g, _PopCategory());
3239}
3240
3241#if _LIBCPP_STD_VER > 14
3242template <class _PopulationIterator, class _SampleIterator, class _Distance,
3243 class _UniformRandomNumberGenerator>
3244inline _LIBCPP_INLINE_VISIBILITY
3245_SampleIterator sample(_PopulationIterator __first,
3246 _PopulationIterator __last, _SampleIterator __output_iter,
3247 _Distance __n, _UniformRandomNumberGenerator&& __g) {
3248 return _VSTD::__sample(__first, __last, __output_iter, __n, __g);
3249}
3250#endif // _LIBCPP_STD_VER > 14
3251
3252template<class _RandomAccessIterator, class _UniformRandomNumberGenerator>
3253 void shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last,
3254 _UniformRandomNumberGenerator&& __g)
3255{
3256 typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
3257 typedef uniform_int_distribution<ptrdiff_t> _Dp;
3258 typedef typename _Dp::param_type _Pp;
3259 difference_type __d = __last - __first;
3260 if (__d > 1)
3261 {
3262 _Dp __uid;
3263 for (--__last, (void) --__d; __first < __last; ++__first, (void) --__d)
3264 {
3265 difference_type __i = __uid(__g, _Pp(0, __d));
3266 if (__i != difference_type(0))
3267 swap(*__first, *(__first + __i));
3268 }
3269 }
3270}
3271
3272#if _LIBCPP_STD_VER > 17
3273
3274// shift_left, shift_right
3275
3276template <class _ForwardIterator>
3277inline _LIBCPP_INLINE_VISIBILITY constexpr
3278_ForwardIterator
3279shift_left(_ForwardIterator __first, _ForwardIterator __last,
3280 typename iterator_traits<_ForwardIterator>::difference_type __n)
3281{
3282 if (__n == 0) {
3283 return __last;
3284 }
3285
3286 _ForwardIterator __m = __first;
3287 if constexpr (__is_cpp17_random_access_iterator<_ForwardIterator>::value) {
3288 if (__n >= __last - __first) {
3289 return __first;
3290 }
3291 __m += __n;
3292 } else {
3293 for (; __n > 0; --__n) {
3294 if (__m == __last) {
3295 return __first;
3296 }
3297 ++__m;
3298 }
3299 }
3300 return _VSTD::move(__m, __last, __first);
3301}
3302
3303template <class _ForwardIterator>
3304inline _LIBCPP_INLINE_VISIBILITY constexpr
3305_ForwardIterator
3306shift_right(_ForwardIterator __first, _ForwardIterator __last,
3307 typename iterator_traits<_ForwardIterator>::difference_type __n)
3308{
3309 if (__n == 0) {
3310 return __first;
3311 }
3312
3313 if constexpr (__is_cpp17_random_access_iterator<_ForwardIterator>::value) {
3314 decltype(__n) __d = __last - __first;
3315 if (__n >= __d) {
3316 return __last;
3317 }
3318 _ForwardIterator __m = __first + (__d - __n);
3319 return _VSTD::move_backward(__first, __m, __last);
3320 } else if constexpr (__is_cpp17_bidirectional_iterator<_ForwardIterator>::value) {
3321 _ForwardIterator __m = __last;
3322 for (; __n > 0; --__n) {
3323 if (__m == __first) {
3324 return __last;
3325 }
3326 --__m;
3327 }
3328 return _VSTD::move_backward(__first, __m, __last);
3329 } else {
3330 _ForwardIterator __ret = __first;
3331 for (; __n > 0; --__n) {
3332 if (__ret == __last) {
3333 return __last;
3334 }
3335 ++__ret;
3336 }
3337
3338 // We have an __n-element scratch space from __first to __ret.
3339 // Slide an __n-element window [__trail, __lead) from left to right.
3340 // We're essentially doing swap_ranges(__first, __ret, __trail, __lead)
3341 // over and over; but once __lead reaches __last we needn't bother
3342 // to save the values of elements [__trail, __last).
3343
3344 auto __trail = __first;
3345 auto __lead = __ret;
3346 while (__trail != __ret) {
3347 if (__lead == __last) {
3348 _VSTD::move(__first, __trail, __ret);
3349 return __ret;
3350 }
3351 ++__trail;
3352 ++__lead;
3353 }
3354
3355 _ForwardIterator __mid = __first;
3356 while (true) {
3357 if (__lead == __last) {
3358 __trail = _VSTD::move(__mid, __ret, __trail);
3359 _VSTD::move(__first, __mid, __trail);
3360 return __ret;
3361 }
3362 swap(*__mid, *__trail);
3363 ++__mid;
3364 ++__trail;
3365 ++__lead;
3366 if (__mid == __ret) {
3367 __mid = __first;
3368 }
3369 }
3370 }
3371}
3372
3373#endif // _LIBCPP_STD_VER > 17
3374
3375// is_partitioned
3376
3377template <class _InputIterator, class _Predicate>
3378_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_AFTER_CXX17 bool
3379is_partitioned(_InputIterator __first, _InputIterator __last, _Predicate __pred)
3380{
3381 for (; __first != __last; ++__first)
3382 if (!__pred(*__first))
3383 break;
3384 if ( __first == __last )
3385 return true;
3386 ++__first;
3387 for (; __first != __last; ++__first)
3388 if (__pred(*__first))
3389 return false;
3390 return true;
3391}
3392
3393// partition
3394
3395template <class _Predicate, class _ForwardIterator>
3396_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator
3397__partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, forward_iterator_tag)
3398{
3399 while (true)
3400 {
3401 if (__first == __last)
3402 return __first;
3403 if (!__pred(*__first))
3404 break;
3405 ++__first;
3406 }
3407 for (_ForwardIterator __p = __first; ++__p != __last;)
3408 {
3409 if (__pred(*__p))
3410 {
3411 swap(*__first, *__p);
3412 ++__first;
3413 }
3414 }
3415 return __first;
3416}
3417
3418template <class _Predicate, class _BidirectionalIterator>
3419_LIBCPP_CONSTEXPR_AFTER_CXX17 _BidirectionalIterator
3420__partition(_BidirectionalIterator __first, _BidirectionalIterator __last, _Predicate __pred,
3421 bidirectional_iterator_tag)
3422{
3423 while (true)
3424 {
3425 while (true)
3426 {
3427 if (__first == __last)
3428 return __first;
3429 if (!__pred(*__first))
3430 break;
3431 ++__first;
3432 }
3433 do
3434 {
3435 if (__first == --__last)
3436 return __first;
3437 } while (!__pred(*__last));
3438 swap(*__first, *__last);
3439 ++__first;
3440 }
3441}
3442
3443template <class _ForwardIterator, class _Predicate>
3444inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
3445_ForwardIterator
3446partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred)
3447{
3448 return _VSTD::__partition<typename add_lvalue_reference<_Predicate>::type>
3449 (__first, __last, __pred, typename iterator_traits<_ForwardIterator>::iterator_category());
3450}
3451
3452// partition_copy
3453
3454template <class _InputIterator, class _OutputIterator1,
3455 class _OutputIterator2, class _Predicate>
3456_LIBCPP_CONSTEXPR_AFTER_CXX17 pair<_OutputIterator1, _OutputIterator2>
3457partition_copy(_InputIterator __first, _InputIterator __last,
3458 _OutputIterator1 __out_true, _OutputIterator2 __out_false,
3459 _Predicate __pred)
3460{
3461 for (; __first != __last; ++__first)
3462 {
3463 if (__pred(*__first))
3464 {
3465 *__out_true = *__first;
3466 ++__out_true;
3467 }
3468 else
3469 {
3470 *__out_false = *__first;
3471 ++__out_false;
3472 }
3473 }
3474 return pair<_OutputIterator1, _OutputIterator2>(__out_true, __out_false);
3475}
3476
3477// partition_point
3478
3479template<class _ForwardIterator, class _Predicate>
3480_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator
3481partition_point(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred)
3482{
3483 typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type;
3484 difference_type __len = _VSTD::distance(__first, __last);
3485 while (__len != 0)
3486 {
3487 difference_type __l2 = _VSTD::__half_positive(__len);
3488 _ForwardIterator __m = __first;
3489 _VSTD::advance(__m, __l2);
3490 if (__pred(*__m))
3491 {
3492 __first = ++__m;
3493 __len -= __l2 + 1;
3494 }
3495 else
3496 __len = __l2;
3497 }
3498 return __first;
3499}
3500
3501// stable_partition
3502
3503template <class _Predicate, class _ForwardIterator, class _Distance, class _Pair>
3504_ForwardIterator
3505__stable_partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred,
3506 _Distance __len, _Pair __p, forward_iterator_tag __fit)
3507{
3508 // *__first is known to be false
3509 // __len >= 1
3510 if (__len == 1)
3511 return __first;
3512 if (__len == 2)
3513 {
3514 _ForwardIterator __m = __first;
3515 if (__pred(*++__m))
3516 {
3517 swap(*__first, *__m);
3518 return __m;
3519 }
3520 return __first;
3521 }
3522 if (__len <= __p.second)
3523 { // The buffer is big enough to use
3524 typedef typename iterator_traits<_ForwardIterator>::value_type value_type;
3525 __destruct_n __d(0);
3526 unique_ptr<value_type, __destruct_n&> __h(__p.first, __d);
3527 // Move the falses into the temporary buffer, and the trues to the front of the line
3528 // Update __first to always point to the end of the trues
3529 value_type* __t = __p.first;
3530 ::new ((void*)__t) value_type(_VSTD::move(*__first));
3531 __d.template __incr<value_type>();
3532 ++__t;
3533 _ForwardIterator __i = __first;
3534 while (++__i != __last)
3535 {
3536 if (__pred(*__i))
3537 {
3538 *__first = _VSTD::move(*__i);
3539 ++__first;
3540 }
3541 else
3542 {
3543 ::new ((void*)__t) value_type(_VSTD::move(*__i));
3544 __d.template __incr<value_type>();
3545 ++__t;
3546 }
3547 }
3548 // All trues now at start of range, all falses in buffer
3549 // Move falses back into range, but don't mess up __first which points to first false
3550 __i = __first;
3551 for (value_type* __t2 = __p.first; __t2 < __t; ++__t2, (void) ++__i)
3552 *__i = _VSTD::move(*__t2);
3553 // __h destructs moved-from values out of the temp buffer, but doesn't deallocate buffer
3554 return __first;
3555 }
3556 // Else not enough buffer, do in place
3557 // __len >= 3
3558 _ForwardIterator __m = __first;
3559 _Distance __len2 = __len / 2; // __len2 >= 2
3560 _VSTD::advance(__m, __len2);
3561 // recurse on [__first, __m), *__first know to be false
3562 // F?????????????????
3563 // f m l
3564 typedef typename add_lvalue_reference<_Predicate>::type _PredRef;
3565 _ForwardIterator __first_false = _VSTD::__stable_partition<_PredRef>(__first, __m, __pred, __len2, __p, __fit);
3566 // TTTFFFFF??????????
3567 // f ff m l
3568 // recurse on [__m, __last], except increase __m until *(__m) is false, *__last know to be true
3569 _ForwardIterator __m1 = __m;
3570 _ForwardIterator __second_false = __last;
3571 _Distance __len_half = __len - __len2;
3572 while (__pred(*__m1))
3573 {
3574 if (++__m1 == __last)
3575 goto __second_half_done;
3576 --__len_half;
3577 }
3578 // TTTFFFFFTTTF??????
3579 // f ff m m1 l
3580 __second_false = _VSTD::__stable_partition<_PredRef>(__m1, __last, __pred, __len_half, __p, __fit);
3581__second_half_done:
3582 // TTTFFFFFTTTTTFFFFF
3583 // f ff m sf l
3584 return _VSTD::rotate(__first_false, __m, __second_false);
3585 // TTTTTTTTFFFFFFFFFF
3586 // |
3587}
3588
3589struct __return_temporary_buffer
3590{
3591 template <class _Tp>
3592 _LIBCPP_INLINE_VISIBILITY void operator()(_Tp* __p) const {_VSTD::return_temporary_buffer(__p);}
3593};
3594
3595template <class _Predicate, class _ForwardIterator>
3596_ForwardIterator
3597__stable_partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred,
3598 forward_iterator_tag)
3599{
3600 const unsigned __alloc_limit = 3; // might want to make this a function of trivial assignment
3601 // Either prove all true and return __first or point to first false
3602 while (true)
3603 {
3604 if (__first == __last)
3605 return __first;
3606 if (!__pred(*__first))
3607 break;
3608 ++__first;
3609 }
3610 // We now have a reduced range [__first, __last)
3611 // *__first is known to be false
3612 typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type;
3613 typedef typename iterator_traits<_ForwardIterator>::value_type value_type;
3614 difference_type __len = _VSTD::distance(__first, __last);
3615 pair<value_type*, ptrdiff_t> __p(0, 0);
3616 unique_ptr<value_type, __return_temporary_buffer> __h;
3617 if (__len >= __alloc_limit)
3618 {
3619 __p = _VSTD::get_temporary_buffer<value_type>(__len);
3620 __h.reset(__p.first);
3621 }
3622 return _VSTD::__stable_partition<typename add_lvalue_reference<_Predicate>::type>
3623 (__first, __last, __pred, __len, __p, forward_iterator_tag());
3624}
3625
3626template <class _Predicate, class _BidirectionalIterator, class _Distance, class _Pair>
3627_BidirectionalIterator
3628__stable_partition(_BidirectionalIterator __first, _BidirectionalIterator __last, _Predicate __pred,
3629 _Distance __len, _Pair __p, bidirectional_iterator_tag __bit)
3630{
3631 // *__first is known to be false
3632 // *__last is known to be true
3633 // __len >= 2
3634 if (__len == 2)
3635 {
3636 swap(*__first, *__last);
3637 return __last;
3638 }
3639 if (__len == 3)
3640 {
3641 _BidirectionalIterator __m = __first;
3642 if (__pred(*++__m))
3643 {
3644 swap(*__first, *__m);
3645 swap(*__m, *__last);
3646 return __last;
3647 }
3648 swap(*__m, *__last);
3649 swap(*__first, *__m);
3650 return __m;
3651 }
3652 if (__len <= __p.second)
3653 { // The buffer is big enough to use
3654 typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;
3655 __destruct_n __d(0);
3656 unique_ptr<value_type, __destruct_n&> __h(__p.first, __d);
3657 // Move the falses into the temporary buffer, and the trues to the front of the line
3658 // Update __first to always point to the end of the trues
3659 value_type* __t = __p.first;
3660 ::new ((void*)__t) value_type(_VSTD::move(*__first));
3661 __d.template __incr<value_type>();
3662 ++__t;
3663 _BidirectionalIterator __i = __first;
3664 while (++__i != __last)
3665 {
3666 if (__pred(*__i))
3667 {
3668 *__first = _VSTD::move(*__i);
3669 ++__first;
3670 }
3671 else
3672 {
3673 ::new ((void*)__t) value_type(_VSTD::move(*__i));
3674 __d.template __incr<value_type>();
3675 ++__t;
3676 }
3677 }
3678 // move *__last, known to be true
3679 *__first = _VSTD::move(*__i);
3680 __i = ++__first;
3681 // All trues now at start of range, all falses in buffer
3682 // Move falses back into range, but don't mess up __first which points to first false
3683 for (value_type* __t2 = __p.first; __t2 < __t; ++__t2, (void) ++__i)
3684 *__i = _VSTD::move(*__t2);
3685 // __h destructs moved-from values out of the temp buffer, but doesn't deallocate buffer
3686 return __first;
3687 }
3688 // Else not enough buffer, do in place
3689 // __len >= 4
3690 _BidirectionalIterator __m = __first;
3691 _Distance __len2 = __len / 2; // __len2 >= 2
3692 _VSTD::advance(__m, __len2);
3693 // recurse on [__first, __m-1], except reduce __m-1 until *(__m-1) is true, *__first know to be false
3694 // F????????????????T
3695 // f m l
3696 _BidirectionalIterator __m1 = __m;
3697 _BidirectionalIterator __first_false = __first;
3698 _Distance __len_half = __len2;
3699 while (!__pred(*--__m1))
3700 {
3701 if (__m1 == __first)
3702 goto __first_half_done;
3703 --__len_half;
3704 }
3705 // F???TFFF?????????T
3706 // f m1 m l
3707 typedef typename add_lvalue_reference<_Predicate>::type _PredRef;
3708 __first_false = _VSTD::__stable_partition<_PredRef>(__first, __m1, __pred, __len_half, __p, __bit);
3709__first_half_done:
3710 // TTTFFFFF?????????T
3711 // f ff m l
3712 // recurse on [__m, __last], except increase __m until *(__m) is false, *__last know to be true
3713 __m1 = __m;
3714 _BidirectionalIterator __second_false = __last;
3715 ++__second_false;
3716 __len_half = __len - __len2;
3717 while (__pred(*__m1))
3718 {
3719 if (++__m1 == __last)
3720 goto __second_half_done;
3721 --__len_half;
3722 }
3723 // TTTFFFFFTTTF?????T
3724 // f ff m m1 l
3725 __second_false = _VSTD::__stable_partition<_PredRef>(__m1, __last, __pred, __len_half, __p, __bit);
3726__second_half_done:
3727 // TTTFFFFFTTTTTFFFFF
3728 // f ff m sf l
3729 return _VSTD::rotate(__first_false, __m, __second_false);
3730 // TTTTTTTTFFFFFFFFFF
3731 // |
3732}
3733
3734template <class _Predicate, class _BidirectionalIterator>
3735_BidirectionalIterator
3736__stable_partition(_BidirectionalIterator __first, _BidirectionalIterator __last, _Predicate __pred,
3737 bidirectional_iterator_tag)
3738{
3739 typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type;
3740 typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;
3741 const difference_type __alloc_limit = 4; // might want to make this a function of trivial assignment
3742 // Either prove all true and return __first or point to first false
3743 while (true)
3744 {
3745 if (__first == __last)
3746 return __first;
3747 if (!__pred(*__first))
3748 break;
3749 ++__first;
3750 }
3751 // __first points to first false, everything prior to __first is already set.
3752 // Either prove [__first, __last) is all false and return __first, or point __last to last true
3753 do
3754 {
3755 if (__first == --__last)
3756 return __first;
3757 } while (!__pred(*__last));
3758 // We now have a reduced range [__first, __last]
3759 // *__first is known to be false
3760 // *__last is known to be true
3761 // __len >= 2
3762 difference_type __len = _VSTD::distance(__first, __last) + 1;
3763 pair<value_type*, ptrdiff_t> __p(0, 0);
3764 unique_ptr<value_type, __return_temporary_buffer> __h;
3765 if (__len >= __alloc_limit)
3766 {
3767 __p = _VSTD::get_temporary_buffer<value_type>(__len);
3768 __h.reset(__p.first);
3769 }
3770 return _VSTD::__stable_partition<typename add_lvalue_reference<_Predicate>::type>
3771 (__first, __last, __pred, __len, __p, bidirectional_iterator_tag());
3772}
3773
3774template <class _ForwardIterator, class _Predicate>
3775inline _LIBCPP_INLINE_VISIBILITY
3776_ForwardIterator
3777stable_partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred)
3778{
3779 return _VSTD::__stable_partition<typename add_lvalue_reference<_Predicate>::type>
3780 (__first, __last, __pred, typename iterator_traits<_ForwardIterator>::iterator_category());
3781}
3782
3783// is_sorted_until
3784
3785template <class _ForwardIterator, class _Compare>
3786_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator
3787is_sorted_until(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
3788{
3789 if (__first != __last)
3790 {
3791 _ForwardIterator __i = __first;
3792 while (++__i != __last)
3793 {
3794 if (__comp(*__i, *__first))
3795 return __i;
3796 __first = __i;
3797 }
3798 }
3799 return __last;
3800}
3801
3802template<class _ForwardIterator>
3803_LIBCPP_NODISCARD_EXT inline
3804_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
3805_ForwardIterator
3806is_sorted_until(_ForwardIterator __first, _ForwardIterator __last)
3807{
3808 return _VSTD::is_sorted_until(__first, __last, __less<typename iterator_traits<_ForwardIterator>::value_type>());
3809}
3810
3811// is_sorted
3812
3813template <class _ForwardIterator, class _Compare>
3814_LIBCPP_NODISCARD_EXT inline
3815_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
3816bool
3817is_sorted(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
3818{
3819 return _VSTD::is_sorted_until(__first, __last, __comp) == __last;
3820}
3821
3822template<class _ForwardIterator>
3823_LIBCPP_NODISCARD_EXT inline
3824_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
3825bool
3826is_sorted(_ForwardIterator __first, _ForwardIterator __last)
3827{
3828 return _VSTD::is_sorted(__first, __last, __less<typename iterator_traits<_ForwardIterator>::value_type>());
3829}
3830
3831// sort
3832
3833// stable, 2-3 compares, 0-2 swaps
3834
3835template <class _Compare, class _ForwardIterator>
3836unsigned
3837__sort3(_ForwardIterator __x, _ForwardIterator __y, _ForwardIterator __z, _Compare __c)
3838{
3839 unsigned __r = 0;
3840 if (!__c(*__y, *__x)) // if x <= y
3841 {
3842 if (!__c(*__z, *__y)) // if y <= z
3843 return __r; // x <= y && y <= z
3844 // x <= y && y > z
3845 swap(*__y, *__z); // x <= z && y < z
3846 __r = 1;
3847 if (__c(*__y, *__x)) // if x > y
3848 {
3849 swap(*__x, *__y); // x < y && y <= z
3850 __r = 2;
3851 }
3852 return __r; // x <= y && y < z
3853 }
3854 if (__c(*__z, *__y)) // x > y, if y > z
3855 {
3856 swap(*__x, *__z); // x < y && y < z
3857 __r = 1;
3858 return __r;
3859 }
3860 swap(*__x, *__y); // x > y && y <= z
3861 __r = 1; // x < y && x <= z
3862 if (__c(*__z, *__y)) // if y > z
3863 {
3864 swap(*__y, *__z); // x <= y && y < z
3865 __r = 2;
3866 }
3867 return __r;
3868} // x <= y && y <= z
3869
3870// stable, 3-6 compares, 0-5 swaps
3871
3872template <class _Compare, class _ForwardIterator>
3873unsigned
3874__sort4(_ForwardIterator __x1, _ForwardIterator __x2, _ForwardIterator __x3,
3875 _ForwardIterator __x4, _Compare __c)
3876{
3877 unsigned __r = _VSTD::__sort3<_Compare>(__x1, __x2, __x3, __c);
3878 if (__c(*__x4, *__x3))
3879 {
3880 swap(*__x3, *__x4);
3881 ++__r;
3882 if (__c(*__x3, *__x2))
3883 {
3884 swap(*__x2, *__x3);
3885 ++__r;
3886 if (__c(*__x2, *__x1))
3887 {
3888 swap(*__x1, *__x2);
3889 ++__r;
3890 }
3891 }
3892 }
3893 return __r;
3894}
3895
3896// stable, 4-10 compares, 0-9 swaps
3897
3898template <class _Compare, class _ForwardIterator>
3899_LIBCPP_HIDDEN
3900unsigned
3901__sort5(_ForwardIterator __x1, _ForwardIterator __x2, _ForwardIterator __x3,
3902 _ForwardIterator __x4, _ForwardIterator __x5, _Compare __c)
3903{
3904 unsigned __r = _VSTD::__sort4<_Compare>(__x1, __x2, __x3, __x4, __c);
3905 if (__c(*__x5, *__x4))
3906 {
3907 swap(*__x4, *__x5);
3908 ++__r;
3909 if (__c(*__x4, *__x3))
3910 {
3911 swap(*__x3, *__x4);
3912 ++__r;
3913 if (__c(*__x3, *__x2))
3914 {
3915 swap(*__x2, *__x3);
3916 ++__r;
3917 if (__c(*__x2, *__x1))
3918 {
3919 swap(*__x1, *__x2);
3920 ++__r;
3921 }
3922 }
3923 }
3924 }
3925 return __r;
3926}
3927
3928// Assumes size > 0
3929template <class _Compare, class _BidirectionalIterator>
3930void
3931__selection_sort(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp)
3932{
3933 _BidirectionalIterator __lm1 = __last;
3934 for (--__lm1; __first != __lm1; ++__first)
3935 {
3936 _BidirectionalIterator __i = _VSTD::min_element<_BidirectionalIterator,
3937 typename add_lvalue_reference<_Compare>::type>
3938 (__first, __last, __comp);
3939 if (__i != __first)
3940 swap(*__first, *__i);
3941 }
3942}
3943
3944template <class _Compare, class _BidirectionalIterator>
3945void
3946__insertion_sort(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp)
3947{
3948 typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;
3949 if (__first != __last)
3950 {
3951 _BidirectionalIterator __i = __first;
3952 for (++__i; __i != __last; ++__i)
3953 {
3954 _BidirectionalIterator __j = __i;
3955 value_type __t(_VSTD::move(*__j));
3956 for (_BidirectionalIterator __k = __i; __k != __first && __comp(__t, *--__k); --__j)
3957 *__j = _VSTD::move(*__k);
3958 *__j = _VSTD::move(__t);
3959 }
3960 }
3961}
3962
3963template <class _Compare, class _RandomAccessIterator>
3964void
3965__insertion_sort_3(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
3966{
3967 typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
3968 _RandomAccessIterator __j = __first+2;
3969 _VSTD::__sort3<_Compare>(__first, __first+1, __j, __comp);
3970 for (_RandomAccessIterator __i = __j+1; __i != __last; ++__i)
3971 {
3972 if (__comp(*__i, *__j))
3973 {
3974 value_type __t(_VSTD::move(*__i));
3975 _RandomAccessIterator __k = __j;
3976 __j = __i;
3977 do
3978 {
3979 *__j = _VSTD::move(*__k);
3980 __j = __k;
3981 } while (__j != __first && __comp(__t, *--__k));
3982 *__j = _VSTD::move(__t);
3983 }
3984 __j = __i;
3985 }
3986}
3987
3988template <class _Compare, class _RandomAccessIterator>
3989bool
3990__insertion_sort_incomplete(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
3991{
3992 switch (__last - __first)
3993 {
3994 case 0:
3995 case 1:
3996 return true;
3997 case 2:
3998 if (__comp(*--__last, *__first))
3999 swap(*__first, *__last);
4000 return true;
4001 case 3:
4002 _VSTD::__sort3<_Compare>(__first, __first+1, --__last, __comp);
4003 return true;
4004 case 4:
4005 _VSTD::__sort4<_Compare>(__first, __first+1, __first+2, --__last, __comp);
4006 return true;
4007 case 5:
4008 _VSTD::__sort5<_Compare>(__first, __first+1, __first+2, __first+3, --__last, __comp);
4009 return true;
4010 }
4011 typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
4012 _RandomAccessIterator __j = __first+2;
4013 _VSTD::__sort3<_Compare>(__first, __first+1, __j, __comp);
4014 const unsigned __limit = 8;
4015 unsigned __count = 0;
4016 for (_RandomAccessIterator __i = __j+1; __i != __last; ++__i)
4017 {
4018 if (__comp(*__i, *__j))
4019 {
4020 value_type __t(_VSTD::move(*__i));
4021 _RandomAccessIterator __k = __j;
4022 __j = __i;
4023 do
4024 {
4025 *__j = _VSTD::move(*__k);
4026 __j = __k;
4027 } while (__j != __first && __comp(__t, *--__k));
4028 *__j = _VSTD::move(__t);
4029 if (++__count == __limit)
4030 return ++__i == __last;
4031 }
4032 __j = __i;
4033 }
4034 return true;
4035}
4036
4037template <class _Compare, class _BidirectionalIterator>
4038void
4039__insertion_sort_move(_BidirectionalIterator __first1, _BidirectionalIterator __last1,
4040 typename iterator_traits<_BidirectionalIterator>::value_type* __first2, _Compare __comp)
4041{
4042 typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;
4043 if (__first1 != __last1)
4044 {
4045 __destruct_n __d(0);
4046 unique_ptr<value_type, __destruct_n&> __h(__first2, __d);
4047 value_type* __last2 = __first2;
4048 ::new ((void*)__last2) value_type(_VSTD::move(*__first1));
4049 __d.template __incr<value_type>();
4050 for (++__last2; ++__first1 != __last1; ++__last2)
4051 {
4052 value_type* __j2 = __last2;
4053 value_type* __i2 = __j2;
4054 if (__comp(*__first1, *--__i2))
4055 {
4056 ::new ((void*)__j2) value_type(_VSTD::move(*__i2));
4057 __d.template __incr<value_type>();
4058 for (--__j2; __i2 != __first2 && __comp(*__first1, *--__i2); --__j2)
4059 *__j2 = _VSTD::move(*__i2);
4060 *__j2 = _VSTD::move(*__first1);
4061 }
4062 else
4063 {
4064 ::new ((void*)__j2) value_type(_VSTD::move(*__first1));
4065 __d.template __incr<value_type>();
4066 }
4067 }
4068 __h.release();
4069 }
4070}
4071
4072template <class _Compare, class _RandomAccessIterator>
4073void
4074__sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
4075{
4076 // _Compare is known to be a reference type
4077 typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
4078 typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
4079 const difference_type __limit = is_trivially_copy_constructible<value_type>::value &&
4080 is_trivially_copy_assignable<value_type>::value ? 30 : 6;
4081 while (true)
4082 {
4083 __restart:
4084 difference_type __len = __last - __first;
4085 switch (__len)
4086 {
4087 case 0:
4088 case 1:
4089 return;
4090 case 2:
4091 if (__comp(*--__last, *__first))
4092 swap(*__first, *__last);
4093 return;
4094 case 3:
4095 _VSTD::__sort3<_Compare>(__first, __first+1, --__last, __comp);
4096 return;
4097 case 4:
4098 _VSTD::__sort4<_Compare>(__first, __first+1, __first+2, --__last, __comp);
4099 return;
4100 case 5:
4101 _VSTD::__sort5<_Compare>(__first, __first+1, __first+2, __first+3, --__last, __comp);
4102 return;
4103 }
4104 if (__len <= __limit)
4105 {
4106 _VSTD::__insertion_sort_3<_Compare>(__first, __last, __comp);
4107 return;
4108 }
4109 // __len > 5
4110 _RandomAccessIterator __m = __first;
4111 _RandomAccessIterator __lm1 = __last;
4112 --__lm1;
4113 unsigned __n_swaps;
4114 {
4115 difference_type __delta;
4116 if (__len >= 1000)
4117 {
4118 __delta = __len/2;
4119 __m += __delta;
4120 __delta /= 2;
4121 __n_swaps = _VSTD::__sort5<_Compare>(__first, __first + __delta, __m, __m+__delta, __lm1, __comp);
4122 }
4123 else
4124 {
4125 __delta = __len/2;
4126 __m += __delta;
4127 __n_swaps = _VSTD::__sort3<_Compare>(__first, __m, __lm1, __comp);
4128 }
4129 }
4130 // *__m is median
4131 // partition [__first, __m) < *__m and *__m <= [__m, __last)
4132 // (this inhibits tossing elements equivalent to __m around unnecessarily)
4133 _RandomAccessIterator __i = __first;
4134 _RandomAccessIterator __j = __lm1;
4135 // j points beyond range to be tested, *__m is known to be <= *__lm1
4136 // The search going up is known to be guarded but the search coming down isn't.
4137 // Prime the downward search with a guard.
4138 if (!__comp(*__i, *__m)) // if *__first == *__m
4139 {
4140 // *__first == *__m, *__first doesn't go in first part
4141 // manually guard downward moving __j against __i
4142 while (true)
4143 {
4144 if (__i == --__j)
4145 {
4146 // *__first == *__m, *__m <= all other elements
4147 // Parition instead into [__first, __i) == *__first and *__first < [__i, __last)
4148 ++__i; // __first + 1
4149 __j = __last;
4150 if (!__comp(*__first, *--__j)) // we need a guard if *__first == *(__last-1)
4151 {
4152 while (true)
4153 {
4154 if (__i == __j)
4155 return; // [__first, __last) all equivalent elements
4156 if (__comp(*__first, *__i))
4157 {
4158 swap(*__i, *__j);
4159 ++__n_swaps;
4160 ++__i;
4161 break;
4162 }
4163 ++__i;
4164 }
4165 }
4166 // [__first, __i) == *__first and *__first < [__j, __last) and __j == __last - 1
4167 if (__i == __j)
4168 return;
4169 while (true)
4170 {
4171 while (!__comp(*__first, *__i))
4172 ++__i;
4173 while (__comp(*__first, *--__j))
4174 ;
4175 if (__i >= __j)
4176 break;
4177 swap(*__i, *__j);
4178 ++__n_swaps;
4179 ++__i;
4180 }
4181 // [__first, __i) == *__first and *__first < [__i, __last)
4182 // The first part is sorted, sort the second part
4183 // _VSTD::__sort<_Compare>(__i, __last, __comp);
4184 __first = __i;
4185 goto __restart;
4186 }
4187 if (__comp(*__j, *__m))
4188 {
4189 swap(*__i, *__j);
4190 ++__n_swaps;
4191 break; // found guard for downward moving __j, now use unguarded partition
4192 }
4193 }
4194 }
4195 // It is known that *__i < *__m
4196 ++__i;
4197 // j points beyond range to be tested, *__m is known to be <= *__lm1
4198 // if not yet partitioned...
4199 if (__i < __j)
4200 {
4201 // known that *(__i - 1) < *__m
4202 // known that __i <= __m
4203 while (true)
4204 {
4205 // __m still guards upward moving __i
4206 while (__comp(*__i, *__m))
4207 ++__i;
4208 // It is now known that a guard exists for downward moving __j
4209 while (!__comp(*--__j, *__m))
4210 ;
4211 if (__i > __j)
4212 break;
4213 swap(*__i, *__j);
4214 ++__n_swaps;
4215 // It is known that __m != __j
4216 // If __m just moved, follow it
4217 if (__m == __i)
4218 __m = __j;
4219 ++__i;
4220 }
4221 }
4222 // [__first, __i) < *__m and *__m <= [__i, __last)
4223 if (__i != __m && __comp(*__m, *__i))
4224 {
4225 swap(*__i, *__m);
4226 ++__n_swaps;
4227 }
4228 // [__first, __i) < *__i and *__i <= [__i+1, __last)
4229 // If we were given a perfect partition, see if insertion sort is quick...
4230 if (__n_swaps == 0)
4231 {
4232 bool __fs = _VSTD::__insertion_sort_incomplete<_Compare>(__first, __i, __comp);
4233 if (_VSTD::__insertion_sort_incomplete<_Compare>(__i+1, __last, __comp))
4234 {
4235 if (__fs)
4236 return;
4237 __last = __i;
4238 continue;
4239 }
4240 else
4241 {
4242 if (__fs)
4243 {
4244 __first = ++__i;
4245 continue;
4246 }
4247 }
4248 }
4249 // sort smaller range with recursive call and larger with tail recursion elimination
4250 if (__i - __first < __last - __i)
4251 {
4252 _VSTD::__sort<_Compare>(__first, __i, __comp);
4253 // _VSTD::__sort<_Compare>(__i+1, __last, __comp);
4254 __first = ++__i;
4255 }
4256 else
4257 {
4258 _VSTD::__sort<_Compare>(__i+1, __last, __comp);
4259 // _VSTD::__sort<_Compare>(__first, __i, __comp);
4260 __last = __i;
4261 }
4262 }
4263}
4264
4265// This forwarder keeps the top call and the recursive calls using the same instantiation, forcing a reference _Compare
4266template <class _RandomAccessIterator, class _Compare>
4267inline _LIBCPP_INLINE_VISIBILITY
4268void
4269sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
4270{
4271 typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
4272 _VSTD::__sort<_Comp_ref>(__first, __last, _Comp_ref(__comp));
4273}
4274
4275template <class _RandomAccessIterator>
4276inline _LIBCPP_INLINE_VISIBILITY
4277void
4278sort(_RandomAccessIterator __first, _RandomAccessIterator __last)
4279{
4280 _VSTD::sort(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
4281}
4282
4283template <class _Tp>
4284inline _LIBCPP_INLINE_VISIBILITY
4285void
4286sort(_Tp** __first, _Tp** __last)
4287{
4288 _VSTD::sort((uintptr_t*)__first, (uintptr_t*)__last, __less<uintptr_t>());
4289}
4290
4291template <class _Tp>
4292inline _LIBCPP_INLINE_VISIBILITY
4293void
4294sort(__wrap_iter<_Tp*> __first, __wrap_iter<_Tp*> __last)
4295{
4296 _VSTD::sort(__first.base(), __last.base());
4297}
4298
4299template <class _Tp, class _Compare>
4300inline _LIBCPP_INLINE_VISIBILITY
4301void
4302sort(__wrap_iter<_Tp*> __first, __wrap_iter<_Tp*> __last, _Compare __comp)
4303{
4304 typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
4305 _VSTD::sort<_Tp*, _Comp_ref>(__first.base(), __last.base(), __comp);
4306}
4307
4308_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<char>&, char*>(char*, char*, __less<char>&))
4309_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<wchar_t>&, wchar_t*>(wchar_t*, wchar_t*, __less<wchar_t>&))
4310_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<signed char>&, signed char*>(signed char*, signed char*, __less<signed char>&))
4311_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<unsigned char>&, unsigned char*>(unsigned char*, unsigned char*, __less<unsigned char>&))
4312_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<short>&, short*>(short*, short*, __less<short>&))
4313_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<unsigned short>&, unsigned short*>(unsigned short*, unsigned short*, __less<unsigned short>&))
4314_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<int>&, int*>(int*, int*, __less<int>&))
4315_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<unsigned>&, unsigned*>(unsigned*, unsigned*, __less<unsigned>&))
4316_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<long>&, long*>(long*, long*, __less<long>&))
4317_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<unsigned long>&, unsigned long*>(unsigned long*, unsigned long*, __less<unsigned long>&))
4318_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<long long>&, long long*>(long long*, long long*, __less<long long>&))
4319_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<unsigned long long>&, unsigned long long*>(unsigned long long*, unsigned long long*, __less<unsigned long long>&))
4320_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<float>&, float*>(float*, float*, __less<float>&))
4321_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<double>&, double*>(double*, double*, __less<double>&))
4322_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<long double>&, long double*>(long double*, long double*, __less<long double>&))
4323
4324_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<char>&, char*>(char*, char*, __less<char>&))
4325_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<wchar_t>&, wchar_t*>(wchar_t*, wchar_t*, __less<wchar_t>&))
4326_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<signed char>&, signed char*>(signed char*, signed char*, __less<signed char>&))
4327_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned char>&, unsigned char*>(unsigned char*, unsigned char*, __less<unsigned char>&))
4328_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<short>&, short*>(short*, short*, __less<short>&))
4329_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned short>&, unsigned short*>(unsigned short*, unsigned short*, __less<unsigned short>&))
4330_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<int>&, int*>(int*, int*, __less<int>&))
4331_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned>&, unsigned*>(unsigned*, unsigned*, __less<unsigned>&))
4332_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<long>&, long*>(long*, long*, __less<long>&))
4333_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned long>&, unsigned long*>(unsigned long*, unsigned long*, __less<unsigned long>&))
4334_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<long long>&, long long*>(long long*, long long*, __less<long long>&))
4335_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned long long>&, unsigned long long*>(unsigned long long*, unsigned long long*, __less<unsigned long long>&))
4336_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<float>&, float*>(float*, float*, __less<float>&))
4337_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<double>&, double*>(double*, double*, __less<double>&))
4338_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<long double>&, long double*>(long double*, long double*, __less<long double>&))
4339
4340_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS unsigned __sort5<__less<long double>&, long double*>(long double*, long double*, long double*, long double*, long double*, __less<long double>&))
4341
4342// lower_bound
4343
4344template <class _Compare, class _ForwardIterator, class _Tp>
4345_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator
4346__lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp)
4347{
4348 typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type;
4349 difference_type __len = _VSTD::distance(__first, __last);
4350 while (__len != 0)
4351 {
4352 difference_type __l2 = _VSTD::__half_positive(__len);
4353 _ForwardIterator __m = __first;
4354 _VSTD::advance(__m, __l2);
4355 if (__comp(*__m, __value_))
4356 {
4357 __first = ++__m;
4358 __len -= __l2 + 1;
4359 }
4360 else
4361 __len = __l2;
4362 }
4363 return __first;
4364}
4365
4366template <class _ForwardIterator, class _Tp, class _Compare>
4367_LIBCPP_NODISCARD_EXT inline
4368_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
4369_ForwardIterator
4370lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp)
4371{
4372 typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
4373 return _VSTD::__lower_bound<_Comp_ref>(__first, __last, __value_, __comp);
4374}
4375
4376template <class _ForwardIterator, class _Tp>
4377_LIBCPP_NODISCARD_EXT inline
4378_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
4379_ForwardIterator
4380lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_)
4381{
4382 return _VSTD::lower_bound(__first, __last, __value_,
4383 __less<typename iterator_traits<_ForwardIterator>::value_type, _Tp>());
4384}
4385
4386// upper_bound
4387
4388template <class _Compare, class _ForwardIterator, class _Tp>
4389_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator
4390__upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp)
4391{
4392 typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type;
4393 difference_type __len = _VSTD::distance(__first, __last);
4394 while (__len != 0)
4395 {
4396 difference_type __l2 = _VSTD::__half_positive(__len);
4397 _ForwardIterator __m = __first;
4398 _VSTD::advance(__m, __l2);
4399 if (__comp(__value_, *__m))
4400 __len = __l2;
4401 else
4402 {
4403 __first = ++__m;
4404 __len -= __l2 + 1;
4405 }
4406 }
4407 return __first;
4408}
4409
4410template <class _ForwardIterator, class _Tp, class _Compare>
4411_LIBCPP_NODISCARD_EXT inline
4412_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
4413_ForwardIterator
4414upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp)
4415{
4416 typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
4417 return _VSTD::__upper_bound<_Comp_ref>(__first, __last, __value_, __comp);
4418}
4419
4420template <class _ForwardIterator, class _Tp>
4421_LIBCPP_NODISCARD_EXT inline
4422_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
4423_ForwardIterator
4424upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_)
4425{
4426 return _VSTD::upper_bound(__first, __last, __value_,
4427 __less<_Tp, typename iterator_traits<_ForwardIterator>::value_type>());
4428}
4429
4430// equal_range
4431
4432template <class _Compare, class _ForwardIterator, class _Tp>
4433_LIBCPP_CONSTEXPR_AFTER_CXX17 pair<_ForwardIterator, _ForwardIterator>
4434__equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp)
4435{
4436 typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type;
4437 difference_type __len = _VSTD::distance(__first, __last);
4438 while (__len != 0)
4439 {
4440 difference_type __l2 = _VSTD::__half_positive(__len);
4441 _ForwardIterator __m = __first;
4442 _VSTD::advance(__m, __l2);
4443 if (__comp(*__m, __value_))
4444 {
4445 __first = ++__m;
4446 __len -= __l2 + 1;
4447 }
4448 else if (__comp(__value_, *__m))
4449 {
4450 __last = __m;
4451 __len = __l2;
4452 }
4453 else
4454 {
4455 _ForwardIterator __mp1 = __m;
4456 return pair<_ForwardIterator, _ForwardIterator>
4457 (
4458 _VSTD::__lower_bound<_Compare>(__first, __m, __value_, __comp),
4459 _VSTD::__upper_bound<_Compare>(++__mp1, __last, __value_, __comp)
4460 );
4461 }
4462 }
4463 return pair<_ForwardIterator, _ForwardIterator>(__first, __first);
4464}
4465
4466template <class _ForwardIterator, class _Tp, class _Compare>
4467_LIBCPP_NODISCARD_EXT inline
4468_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
4469pair<_ForwardIterator, _ForwardIterator>
4470equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp)
4471{
4472 typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
4473 return _VSTD::__equal_range<_Comp_ref>(__first, __last, __value_, __comp);
4474}
4475
4476template <class _ForwardIterator, class _Tp>
4477_LIBCPP_NODISCARD_EXT inline
4478_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
4479pair<_ForwardIterator, _ForwardIterator>
4480equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_)
4481{
4482 return _VSTD::equal_range(__first, __last, __value_,
4483 __less<typename iterator_traits<_ForwardIterator>::value_type, _Tp>());
4484}
4485
4486// binary_search
4487
4488template <class _Compare, class _ForwardIterator, class _Tp>
4489inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
4490bool
4491__binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp)
4492{
4493 __first = _VSTD::__lower_bound<_Compare>(__first, __last, __value_, __comp);
4494 return __first != __last && !__comp(__value_, *__first);
4495}
4496
4497template <class _ForwardIterator, class _Tp, class _Compare>
4498_LIBCPP_NODISCARD_EXT inline
4499_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
4500bool
4501binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp)
4502{
4503 typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
4504 return _VSTD::__binary_search<_Comp_ref>(__first, __last, __value_, __comp);
4505}
4506
4507template <class _ForwardIterator, class _Tp>
4508_LIBCPP_NODISCARD_EXT inline
4509_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
4510bool
4511binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_)
4512{
4513 return _VSTD::binary_search(__first, __last, __value_,
4514 __less<typename iterator_traits<_ForwardIterator>::value_type, _Tp>());
4515}
4516
4517// merge
4518
4519template <class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator>
4520_LIBCPP_CONSTEXPR_AFTER_CXX17
4521_OutputIterator
4522__merge(_InputIterator1 __first1, _InputIterator1 __last1,
4523 _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)
4524{
4525 for (; __first1 != __last1; ++__result)
4526 {
4527 if (__first2 == __last2)
4528 return _VSTD::copy(__first1, __last1, __result);
4529 if (__comp(*__first2, *__first1))
4530 {
4531 *__result = *__first2;
4532 ++__first2;
4533 }
4534 else
4535 {
4536 *__result = *__first1;
4537 ++__first1;
4538 }
4539 }
4540 return _VSTD::copy(__first2, __last2, __result);
4541}
4542
4543template <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _Compare>
4544inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
4545_OutputIterator
4546merge(_InputIterator1 __first1, _InputIterator1 __last1,
4547 _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)
4548{
4549 typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
4550 return _VSTD::__merge<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp);
4551}
4552
4553template <class _InputIterator1, class _InputIterator2, class _OutputIterator>
4554inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
4555_OutputIterator
4556merge(_InputIterator1 __first1, _InputIterator1 __last1,
4557 _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result)
4558{
4559 typedef typename iterator_traits<_InputIterator1>::value_type __v1;
4560 typedef typename iterator_traits<_InputIterator2>::value_type __v2;
4561 return _VSTD::merge(__first1, __last1, __first2, __last2, __result, __less<__v1, __v2>());
4562}
4563
4564// inplace_merge
4565
4566template <class _Compare, class _InputIterator1, class _InputIterator2,
4567 class _OutputIterator>
4568void __half_inplace_merge(_InputIterator1 __first1, _InputIterator1 __last1,
4569 _InputIterator2 __first2, _InputIterator2 __last2,
4570 _OutputIterator __result, _Compare __comp)
4571{
4572 for (; __first1 != __last1; ++__result)
4573 {
4574 if (__first2 == __last2)
4575 {
4576 _VSTD::move(__first1, __last1, __result);
4577 return;
4578 }
4579
4580 if (__comp(*__first2, *__first1))
4581 {
4582 *__result = _VSTD::move(*__first2);
4583 ++__first2;
4584 }
4585 else
4586 {
4587 *__result = _VSTD::move(*__first1);
4588 ++__first1;
4589 }
4590 }
4591 // __first2 through __last2 are already in the right spot.
4592}
4593
4594template <class _Compare, class _BidirectionalIterator>
4595void
4596__buffered_inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last,
4597 _Compare __comp, typename iterator_traits<_BidirectionalIterator>::difference_type __len1,
4598 typename iterator_traits<_BidirectionalIterator>::difference_type __len2,
4599 typename iterator_traits<_BidirectionalIterator>::value_type* __buff)
4600{
4601 typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;
4602 __destruct_n __d(0);
4603 unique_ptr<value_type, __destruct_n&> __h2(__buff, __d);
4604 if (__len1 <= __len2)
4605 {
4606 value_type* __p = __buff;
4607 for (_BidirectionalIterator __i = __first; __i != __middle; __d.template __incr<value_type>(), (void) ++__i, (void) ++__p)
4608 ::new ((void*)__p) value_type(_VSTD::move(*__i));
4609 _VSTD::__half_inplace_merge<_Compare>(__buff, __p, __middle, __last, __first, __comp);
4610 }
4611 else
4612 {
4613 value_type* __p = __buff;
4614 for (_BidirectionalIterator __i = __middle; __i != __last; __d.template __incr<value_type>(), (void) ++__i, (void) ++__p)
4615 ::new ((void*)__p) value_type(_VSTD::move(*__i));
4616 typedef reverse_iterator<_BidirectionalIterator> _RBi;
4617 typedef reverse_iterator<value_type*> _Rv;
4618 typedef __invert<_Compare> _Inverted;
4619 _VSTD::__half_inplace_merge<_Inverted>(_Rv(__p), _Rv(__buff),
4620 _RBi(__middle), _RBi(__first),
4621 _RBi(__last), _Inverted(__comp));
4622 }
4623}
4624
4625template <class _Compare, class _BidirectionalIterator>
4626void
4627__inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last,
4628 _Compare __comp, typename iterator_traits<_BidirectionalIterator>::difference_type __len1,
4629 typename iterator_traits<_BidirectionalIterator>::difference_type __len2,
4630 typename iterator_traits<_BidirectionalIterator>::value_type* __buff, ptrdiff_t __buff_size)
4631{
4632 typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type;
4633 while (true)
4634 {
4635 // if __middle == __last, we're done
4636 if (__len2 == 0)
4637 return;
4638 if (__len1 <= __buff_size || __len2 <= __buff_size)
4639 return _VSTD::__buffered_inplace_merge<_Compare>
4640 (__first, __middle, __last, __comp, __len1, __len2, __buff);
4641 // shrink [__first, __middle) as much as possible (with no moves), returning if it shrinks to 0
4642 for (; true; ++__first, (void) --__len1)
4643 {
4644 if (__len1 == 0)
4645 return;
4646 if (__comp(*__middle, *__first))
4647 break;
4648 }
4649 // __first < __middle < __last
4650 // *__first > *__middle
4651 // partition [__first, __m1) [__m1, __middle) [__middle, __m2) [__m2, __last) such that
4652 // all elements in:
4653 // [__first, __m1) <= [__middle, __m2)
4654 // [__middle, __m2) < [__m1, __middle)
4655 // [__m1, __middle) <= [__m2, __last)
4656 // and __m1 or __m2 is in the middle of its range
4657 _BidirectionalIterator __m1; // "median" of [__first, __middle)
4658 _BidirectionalIterator __m2; // "median" of [__middle, __last)
4659 difference_type __len11; // distance(__first, __m1)
4660 difference_type __len21; // distance(__middle, __m2)
4661 // binary search smaller range
4662 if (__len1 < __len2)
4663 { // __len >= 1, __len2 >= 2
4664 __len21 = __len2 / 2;
4665 __m2 = __middle;
4666 _VSTD::advance(__m2, __len21);
4667 __m1 = _VSTD::__upper_bound<_Compare>(__first, __middle, *__m2, __comp);
4668 __len11 = _VSTD::distance(__first, __m1);
4669 }
4670 else
4671 {
4672 if (__len1 == 1)
4673 { // __len1 >= __len2 && __len2 > 0, therefore __len2 == 1
4674 // It is known *__first > *__middle
4675 swap(*__first, *__middle);
4676 return;
4677 }
4678 // __len1 >= 2, __len2 >= 1
4679 __len11 = __len1 / 2;
4680 __m1 = __first;
4681 _VSTD::advance(__m1, __len11);
4682 __m2 = _VSTD::__lower_bound<_Compare>(__middle, __last, *__m1, __comp);
4683 __len21 = _VSTD::distance(__middle, __m2);
4684 }
4685 difference_type __len12 = __len1 - __len11; // distance(__m1, __middle)
4686 difference_type __len22 = __len2 - __len21; // distance(__m2, __last)
4687 // [__first, __m1) [__m1, __middle) [__middle, __m2) [__m2, __last)
4688 // swap middle two partitions
4689 __middle = _VSTD::rotate(__m1, __middle, __m2);
4690 // __len12 and __len21 now have swapped meanings
4691 // merge smaller range with recursive call and larger with tail recursion elimination
4692 if (__len11 + __len21 < __len12 + __len22)
4693 {
4694 _VSTD::__inplace_merge<_Compare>(__first, __m1, __middle, __comp, __len11, __len21, __buff, __buff_size);
4695// _VSTD::__inplace_merge<_Compare>(__middle, __m2, __last, __comp, __len12, __len22, __buff, __buff_size);
4696 __first = __middle;
4697 __middle = __m2;
4698 __len1 = __len12;
4699 __len2 = __len22;
4700 }
4701 else
4702 {
4703 _VSTD::__inplace_merge<_Compare>(__middle, __m2, __last, __comp, __len12, __len22, __buff, __buff_size);
4704// _VSTD::__inplace_merge<_Compare>(__first, __m1, __middle, __comp, __len11, __len21, __buff, __buff_size);
4705 __last = __middle;
4706 __middle = __m1;
4707 __len1 = __len11;
4708 __len2 = __len21;
4709 }
4710 }
4711}
4712
4713template <class _BidirectionalIterator, class _Compare>
4714inline _LIBCPP_INLINE_VISIBILITY
4715void
4716inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last,
4717 _Compare __comp)
4718{
4719 typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;
4720 typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type;
4721 difference_type __len1 = _VSTD::distance(__first, __middle);
4722 difference_type __len2 = _VSTD::distance(__middle, __last);
4723 difference_type __buf_size = _VSTD::min(__len1, __len2);
4724 pair<value_type*, ptrdiff_t> __buf = _VSTD::get_temporary_buffer<value_type>(__buf_size);
4725 unique_ptr<value_type, __return_temporary_buffer> __h(__buf.first);
4726 typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
4727 return _VSTD::__inplace_merge<_Comp_ref>(__first, __middle, __last, __comp, __len1, __len2,
4728 __buf.first, __buf.second);
4729}
4730
4731template <class _BidirectionalIterator>
4732inline _LIBCPP_INLINE_VISIBILITY
4733void
4734inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last)
4735{
4736 _VSTD::inplace_merge(__first, __middle, __last,
4737 __less<typename iterator_traits<_BidirectionalIterator>::value_type>());
4738}
4739
4740// stable_sort
4741
4742template <class _Compare, class _InputIterator1, class _InputIterator2>
4743void
4744__merge_move_construct(_InputIterator1 __first1, _InputIterator1 __last1,
4745 _InputIterator2 __first2, _InputIterator2 __last2,
4746 typename iterator_traits<_InputIterator1>::value_type* __result, _Compare __comp)
4747{
4748 typedef typename iterator_traits<_InputIterator1>::value_type value_type;
4749 __destruct_n __d(0);
4750 unique_ptr<value_type, __destruct_n&> __h(__result, __d);
4751 for (; true; ++__result)
4752 {
4753 if (__first1 == __last1)
4754 {
4755 for (; __first2 != __last2; ++__first2, ++__result, (void)__d.template __incr<value_type>())
4756 ::new ((void*)__result) value_type(_VSTD::move(*__first2));
4757 __h.release();
4758 return;
4759 }
4760 if (__first2 == __last2)
4761 {
4762 for (; __first1 != __last1; ++__first1, ++__result, (void)__d.template __incr<value_type>())
4763 ::new ((void*)__result) value_type(_VSTD::move(*__first1));
4764 __h.release();
4765 return;
4766 }
4767 if (__comp(*__first2, *__first1))
4768 {
4769 ::new ((void*)__result) value_type(_VSTD::move(*__first2));
4770 __d.template __incr<value_type>();
4771 ++__first2;
4772 }
4773 else
4774 {
4775 ::new ((void*)__result) value_type(_VSTD::move(*__first1));
4776 __d.template __incr<value_type>();
4777 ++__first1;
4778 }
4779 }
4780}
4781
4782template <class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator>
4783void
4784__merge_move_assign(_InputIterator1 __first1, _InputIterator1 __last1,
4785 _InputIterator2 __first2, _InputIterator2 __last2,
4786 _OutputIterator __result, _Compare __comp)
4787{
4788 for (; __first1 != __last1; ++__result)
4789 {
4790 if (__first2 == __last2)
4791 {
4792 for (; __first1 != __last1; ++__first1, (void) ++__result)
4793 *__result = _VSTD::move(*__first1);
4794 return;
4795 }
4796 if (__comp(*__first2, *__first1))
4797 {
4798 *__result = _VSTD::move(*__first2);
4799 ++__first2;
4800 }
4801 else
4802 {
4803 *__result = _VSTD::move(*__first1);
4804 ++__first1;
4805 }
4806 }
4807 for (; __first2 != __last2; ++__first2, (void) ++__result)
4808 *__result = _VSTD::move(*__first2);
4809}
4810
4811template <class _Compare, class _RandomAccessIterator>
4812void
4813__stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp,
4814 typename iterator_traits<_RandomAccessIterator>::difference_type __len,
4815 typename iterator_traits<_RandomAccessIterator>::value_type* __buff, ptrdiff_t __buff_size);
4816
4817template <class _Compare, class _RandomAccessIterator>
4818void
4819__stable_sort_move(_RandomAccessIterator __first1, _RandomAccessIterator __last1, _Compare __comp,
4820 typename iterator_traits<_RandomAccessIterator>::difference_type __len,
4821 typename iterator_traits<_RandomAccessIterator>::value_type* __first2)
4822{
4823 typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
4824 switch (__len)
4825 {
4826 case 0:
4827 return;
4828 case 1:
4829 ::new ((void*)__first2) value_type(_VSTD::move(*__first1));
4830 return;
4831 case 2:
4832 __destruct_n __d(0);
4833 unique_ptr<value_type, __destruct_n&> __h2(__first2, __d);
4834 if (__comp(*--__last1, *__first1))
4835 {
4836 ::new ((void*)__first2) value_type(_VSTD::move(*__last1));
4837 __d.template __incr<value_type>();
4838 ++__first2;
4839 ::new ((void*)__first2) value_type(_VSTD::move(*__first1));
4840 }
4841 else
4842 {
4843 ::new ((void*)__first2) value_type(_VSTD::move(*__first1));
4844 __d.template __incr<value_type>();
4845 ++__first2;
4846 ::new ((void*)__first2) value_type(_VSTD::move(*__last1));
4847 }
4848 __h2.release();
4849 return;
4850 }
4851 if (__len <= 8)
4852 {
4853 _VSTD::__insertion_sort_move<_Compare>(__first1, __last1, __first2, __comp);
4854 return;
4855 }
4856 typename iterator_traits<_RandomAccessIterator>::difference_type __l2 = __len / 2;
4857 _RandomAccessIterator __m = __first1 + __l2;
4858 _VSTD::__stable_sort<_Compare>(__first1, __m, __comp, __l2, __first2, __l2);
4859 _VSTD::__stable_sort<_Compare>(__m, __last1, __comp, __len - __l2, __first2 + __l2, __len - __l2);
4860 _VSTD::__merge_move_construct<_Compare>(__first1, __m, __m, __last1, __first2, __comp);
4861}
4862
4863template <class _Tp>
4864struct __stable_sort_switch
4865{
4866 static const unsigned value = 128*is_trivially_copy_assignable<_Tp>::value;
4867};
4868
4869template <class _Compare, class _RandomAccessIterator>
4870void
4871__stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp,
4872 typename iterator_traits<_RandomAccessIterator>::difference_type __len,
4873 typename iterator_traits<_RandomAccessIterator>::value_type* __buff, ptrdiff_t __buff_size)
4874{
4875 typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
4876 typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
4877 switch (__len)
4878 {
4879 case 0:
4880 case 1:
4881 return;
4882 case 2:
4883 if (__comp(*--__last, *__first))
4884 swap(*__first, *__last);
4885 return;
4886 }
4887 if (__len <= static_cast<difference_type>(__stable_sort_switch<value_type>::value))
4888 {
4889 _VSTD::__insertion_sort<_Compare>(__first, __last, __comp);
4890 return;
4891 }
4892 typename iterator_traits<_RandomAccessIterator>::difference_type __l2 = __len / 2;
4893 _RandomAccessIterator __m = __first + __l2;
4894 if (__len <= __buff_size)
4895 {
4896 __destruct_n __d(0);
4897 unique_ptr<value_type, __destruct_n&> __h2(__buff, __d);
4898 _VSTD::__stable_sort_move<_Compare>(__first, __m, __comp, __l2, __buff);
4899 __d.__set(__l2, (value_type*)nullptr);
4900 _VSTD::__stable_sort_move<_Compare>(__m, __last, __comp, __len - __l2, __buff + __l2);
4901 __d.__set(__len, (value_type*)nullptr);
4902 _VSTD::__merge_move_assign<_Compare>(__buff, __buff + __l2, __buff + __l2, __buff + __len, __first, __comp);
4903// _VSTD::__merge<_Compare>(move_iterator<value_type*>(__buff),
4904// move_iterator<value_type*>(__buff + __l2),
4905// move_iterator<_RandomAccessIterator>(__buff + __l2),
4906// move_iterator<_RandomAccessIterator>(__buff + __len),
4907// __first, __comp);
4908 return;
4909 }
4910 _VSTD::__stable_sort<_Compare>(__first, __m, __comp, __l2, __buff, __buff_size);
4911 _VSTD::__stable_sort<_Compare>(__m, __last, __comp, __len - __l2, __buff, __buff_size);
4912 _VSTD::__inplace_merge<_Compare>(__first, __m, __last, __comp, __l2, __len - __l2, __buff, __buff_size);
4913}
4914
4915template <class _RandomAccessIterator, class _Compare>
4916inline _LIBCPP_INLINE_VISIBILITY
4917void
4918stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
4919{
4920 typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
4921 typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
4922 difference_type __len = __last - __first;
4923 pair<value_type*, ptrdiff_t> __buf(0, 0);
4924 unique_ptr<value_type, __return_temporary_buffer> __h;
4925 if (__len > static_cast<difference_type>(__stable_sort_switch<value_type>::value))
4926 {
4927 __buf = _VSTD::get_temporary_buffer<value_type>(__len);
4928 __h.reset(__buf.first);
4929 }
4930 typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
4931 _VSTD::__stable_sort<_Comp_ref>(__first, __last, __comp, __len, __buf.first, __buf.second);
4932}
4933
4934template <class _RandomAccessIterator>
4935inline _LIBCPP_INLINE_VISIBILITY
4936void
4937stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last)
4938{
4939 _VSTD::stable_sort(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
4940}
4941
4942// is_heap_until
4943
4944template <class _RandomAccessIterator, class _Compare>
4945_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_AFTER_CXX17 _RandomAccessIterator
4946is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
4947{
4948 typedef typename _VSTD::iterator_traits<_RandomAccessIterator>::difference_type difference_type;
4949 difference_type __len = __last - __first;
4950 difference_type __p = 0;
4951 difference_type __c = 1;
4952 _RandomAccessIterator __pp = __first;
4953 while (__c < __len)
4954 {
4955 _RandomAccessIterator __cp = __first + __c;
4956 if (__comp(*__pp, *__cp))
4957 return __cp;
4958 ++__c;
4959 ++__cp;
4960 if (__c == __len)
4961 return __last;
4962 if (__comp(*__pp, *__cp))
4963 return __cp;
4964 ++__p;
4965 ++__pp;
4966 __c = 2 * __p + 1;
4967 }
4968 return __last;
4969}
4970
4971template<class _RandomAccessIterator>
4972_LIBCPP_NODISCARD_EXT inline
4973_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
4974_RandomAccessIterator
4975is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last)
4976{
4977 return _VSTD::is_heap_until(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
4978}
4979
4980// is_heap
4981
4982template <class _RandomAccessIterator, class _Compare>
4983_LIBCPP_NODISCARD_EXT inline
4984_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
4985bool
4986is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
4987{
4988 return _VSTD::is_heap_until(__first, __last, __comp) == __last;
4989}
4990
4991template<class _RandomAccessIterator>
4992_LIBCPP_NODISCARD_EXT inline
4993_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
4994bool
4995is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
4996{
4997 return _VSTD::is_heap(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
4998}
4999
5000// push_heap
5001
5002template <class _Compare, class _RandomAccessIterator>
5003void
5004__sift_up(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp,
5005 typename iterator_traits<_RandomAccessIterator>::difference_type __len)
5006{
5007 typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
5008 if (__len > 1)
5009 {
5010 __len = (__len - 2) / 2;
5011 _RandomAccessIterator __ptr = __first + __len;
5012 if (__comp(*__ptr, *--__last))
5013 {
5014 value_type __t(_VSTD::move(*__last));
5015 do
5016 {
5017 *__last = _VSTD::move(*__ptr);
5018 __last = __ptr;
5019 if (__len == 0)
5020 break;
5021 __len = (__len - 1) / 2;
5022 __ptr = __first + __len;
5023 } while (__comp(*__ptr, __t));
5024 *__last = _VSTD::move(__t);
5025 }
5026 }
5027}
5028
5029template <class _RandomAccessIterator, class _Compare>
5030inline _LIBCPP_INLINE_VISIBILITY
5031void
5032push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
5033{
5034 typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
5035 _VSTD::__sift_up<_Comp_ref>(__first, __last, __comp, __last - __first);
5036}
5037
5038template <class _RandomAccessIterator>
5039inline _LIBCPP_INLINE_VISIBILITY
5040void
5041push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
5042{
5043 _VSTD::push_heap(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
5044}
5045
5046// pop_heap
5047
5048template <class _Compare, class _RandomAccessIterator>
5049void
5050__sift_down(_RandomAccessIterator __first, _RandomAccessIterator /*__last*/,
5051 _Compare __comp,
5052 typename iterator_traits<_RandomAccessIterator>::difference_type __len,
5053 _RandomAccessIterator __start)
5054{
5055 typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
5056 typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
5057 // left-child of __start is at 2 * __start + 1
5058 // right-child of __start is at 2 * __start + 2
5059 difference_type __child = __start - __first;
5060
5061 if (__len < 2 || (__len - 2) / 2 < __child)
5062 return;
5063
5064 __child = 2 * __child + 1;
5065 _RandomAccessIterator __child_i = __first + __child;
5066
5067 if ((__child + 1) < __len && __comp(*__child_i, *(__child_i + 1))) {
5068 // right-child exists and is greater than left-child
5069 ++__child_i;
5070 ++__child;
5071 }
5072
5073 // check if we are in heap-order
5074 if (__comp(*__child_i, *__start))
5075 // we are, __start is larger than it's largest child
5076 return;
5077
5078 value_type __top(_VSTD::move(*__start));
5079 do
5080 {
5081 // we are not in heap-order, swap the parent with it's largest child
5082 *__start = _VSTD::move(*__child_i);
5083 __start = __child_i;
5084
5085 if ((__len - 2) / 2 < __child)
5086 break;
5087
5088 // recompute the child based off of the updated parent
5089 __child = 2 * __child + 1;
5090 __child_i = __first + __child;
5091
5092 if ((__child + 1) < __len && __comp(*__child_i, *(__child_i + 1))) {
5093 // right-child exists and is greater than left-child
5094 ++__child_i;
5095 ++__child;
5096 }
5097
5098 // check if we are in heap-order
5099 } while (!__comp(*__child_i, __top));
5100 *__start = _VSTD::move(__top);
5101}
5102
5103template <class _Compare, class _RandomAccessIterator>
5104inline _LIBCPP_INLINE_VISIBILITY
5105void
5106__pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp,
5107 typename iterator_traits<_RandomAccessIterator>::difference_type __len)
5108{
5109 if (__len > 1)
5110 {
5111 swap(*__first, *--__last);
5112 _VSTD::__sift_down<_Compare>(__first, __last, __comp, __len - 1, __first);
5113 }
5114}
5115
5116template <class _RandomAccessIterator, class _Compare>
5117inline _LIBCPP_INLINE_VISIBILITY
5118void
5119pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
5120{
5121 typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
5122 _VSTD::__pop_heap<_Comp_ref>(__first, __last, __comp, __last - __first);
5123}
5124
5125template <class _RandomAccessIterator>
5126inline _LIBCPP_INLINE_VISIBILITY
5127void
5128pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
5129{
5130 _VSTD::pop_heap(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
5131}
5132
5133// make_heap
5134
5135template <class _Compare, class _RandomAccessIterator>
5136void
5137__make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
5138{
5139 typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
5140 difference_type __n = __last - __first;
5141 if (__n > 1)
5142 {
5143 // start from the first parent, there is no need to consider children
5144 for (difference_type __start = (__n - 2) / 2; __start >= 0; --__start)
5145 {
5146 _VSTD::__sift_down<_Compare>(__first, __last, __comp, __n, __first + __start);
5147 }
5148 }
5149}
5150
5151template <class _RandomAccessIterator, class _Compare>
5152inline _LIBCPP_INLINE_VISIBILITY
5153void
5154make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
5155{
5156 typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
5157 _VSTD::__make_heap<_Comp_ref>(__first, __last, __comp);
5158}
5159
5160template <class _RandomAccessIterator>
5161inline _LIBCPP_INLINE_VISIBILITY
5162void
5163make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
5164{
5165 _VSTD::make_heap(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
5166}
5167
5168// sort_heap
5169
5170template <class _Compare, class _RandomAccessIterator>
5171void
5172__sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
5173{
5174 typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
5175 for (difference_type __n = __last - __first; __n > 1; --__last, (void) --__n)
5176 _VSTD::__pop_heap<_Compare>(__first, __last, __comp, __n);
5177}
5178
5179template <class _RandomAccessIterator, class _Compare>
5180inline _LIBCPP_INLINE_VISIBILITY
5181void
5182sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
5183{
5184 typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
5185 _VSTD::__sort_heap<_Comp_ref>(__first, __last, __comp);
5186}
5187
5188template <class _RandomAccessIterator>
5189inline _LIBCPP_INLINE_VISIBILITY
5190void
5191sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
5192{
5193 _VSTD::sort_heap(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
5194}
5195
5196// partial_sort
5197
5198template <class _Compare, class _RandomAccessIterator>
5199void
5200__partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last,
5201 _Compare __comp)
5202{
5203 _VSTD::__make_heap<_Compare>(__first, __middle, __comp);
5204 typename iterator_traits<_RandomAccessIterator>::difference_type __len = __middle - __first;
5205 for (_RandomAccessIterator __i = __middle; __i != __last; ++__i)
5206 {
5207 if (__comp(*__i, *__first))
5208 {
5209 swap(*__i, *__first);
5210 _VSTD::__sift_down<_Compare>(__first, __middle, __comp, __len, __first);
5211 }
5212 }
5213 _VSTD::__sort_heap<_Compare>(__first, __middle, __comp);
5214}
5215
5216template <class _RandomAccessIterator, class _Compare>
5217inline _LIBCPP_INLINE_VISIBILITY
5218void
5219partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last,
5220 _Compare __comp)
5221{
5222 typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
5223 _VSTD::__partial_sort<_Comp_ref>(__first, __middle, __last, __comp);
5224}
5225
5226template <class _RandomAccessIterator>
5227inline _LIBCPP_INLINE_VISIBILITY
5228void
5229partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last)
5230{
5231 _VSTD::partial_sort(__first, __middle, __last,
5232 __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
5233}
5234
5235// partial_sort_copy
5236
5237template <class _Compare, class _InputIterator, class _RandomAccessIterator>
5238_RandomAccessIterator
5239__partial_sort_copy(_InputIterator __first, _InputIterator __last,
5240 _RandomAccessIterator __result_first, _RandomAccessIterator __result_last, _Compare __comp)
5241{
5242 _RandomAccessIterator __r = __result_first;
5243 if (__r != __result_last)
5244 {
5245 for (; __first != __last && __r != __result_last; ++__first, (void) ++__r)
5246 *__r = *__first;
5247 _VSTD::__make_heap<_Compare>(__result_first, __r, __comp);
5248 typename iterator_traits<_RandomAccessIterator>::difference_type __len = __r - __result_first;
5249 for (; __first != __last; ++__first)
5250 if (__comp(*__first, *__result_first))
5251 {
5252 *__result_first = *__first;
5253 _VSTD::__sift_down<_Compare>(__result_first, __r, __comp, __len, __result_first);
5254 }
5255 _VSTD::__sort_heap<_Compare>(__result_first, __r, __comp);
5256 }
5257 return __r;
5258}
5259
5260template <class _InputIterator, class _RandomAccessIterator, class _Compare>
5261inline _LIBCPP_INLINE_VISIBILITY
5262_RandomAccessIterator
5263partial_sort_copy(_InputIterator __first, _InputIterator __last,
5264 _RandomAccessIterator __result_first, _RandomAccessIterator __result_last, _Compare __comp)
5265{
5266 typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
5267 return _VSTD::__partial_sort_copy<_Comp_ref>(__first, __last, __result_first, __result_last, __comp);
5268}
5269
5270template <class _InputIterator, class _RandomAccessIterator>
5271inline _LIBCPP_INLINE_VISIBILITY
5272_RandomAccessIterator
5273partial_sort_copy(_InputIterator __first, _InputIterator __last,
5274 _RandomAccessIterator __result_first, _RandomAccessIterator __result_last)
5275{
5276 return _VSTD::partial_sort_copy(__first, __last, __result_first, __result_last,
5277 __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
5278}
5279
5280// nth_element
5281
5282template <class _Compare, class _RandomAccessIterator>
5283void
5284__nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last, _Compare __comp)
5285{
5286 // _Compare is known to be a reference type
5287 typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
5288 const difference_type __limit = 7;
5289 while (true)
5290 {
5291 __restart:
5292 if (__nth == __last)
5293 return;
5294 difference_type __len = __last - __first;
5295 switch (__len)
5296 {
5297 case 0:
5298 case 1:
5299 return;
5300 case 2:
5301 if (__comp(*--__last, *__first))
5302 swap(*__first, *__last);
5303 return;
5304 case 3:
5305 {
5306 _RandomAccessIterator __m = __first;
5307 _VSTD::__sort3<_Compare>(__first, ++__m, --__last, __comp);
5308 return;
5309 }
5310 }
5311 if (__len <= __limit)
5312 {
5313 _VSTD::__selection_sort<_Compare>(__first, __last, __comp);
5314 return;
5315 }
5316 // __len > __limit >= 3
5317 _RandomAccessIterator __m = __first + __len/2;
5318 _RandomAccessIterator __lm1 = __last;
5319 unsigned __n_swaps = _VSTD::__sort3<_Compare>(__first, __m, --__lm1, __comp);
5320 // *__m is median
5321 // partition [__first, __m) < *__m and *__m <= [__m, __last)
5322 // (this inhibits tossing elements equivalent to __m around unnecessarily)
5323 _RandomAccessIterator __i = __first;
5324 _RandomAccessIterator __j = __lm1;
5325 // j points beyond range to be tested, *__lm1 is known to be <= *__m
5326 // The search going up is known to be guarded but the search coming down isn't.
5327 // Prime the downward search with a guard.
5328 if (!__comp(*__i, *__m)) // if *__first == *__m
5329 {
5330 // *__first == *__m, *__first doesn't go in first part
5331 // manually guard downward moving __j against __i
5332 while (true)
5333 {
5334 if (__i == --__j)
5335 {
5336 // *__first == *__m, *__m <= all other elements
5337 // Partition instead into [__first, __i) == *__first and *__first < [__i, __last)
5338 ++__i; // __first + 1
5339 __j = __last;
5340 if (!__comp(*__first, *--__j)) // we need a guard if *__first == *(__last-1)
5341 {
5342 while (true)
5343 {
5344 if (__i == __j)
5345 return; // [__first, __last) all equivalent elements
5346 if (__comp(*__first, *__i))
5347 {
5348 swap(*__i, *__j);
5349 ++__n_swaps;
5350 ++__i;
5351 break;
5352 }
5353 ++__i;
5354 }
5355 }
5356 // [__first, __i) == *__first and *__first < [__j, __last) and __j == __last - 1
5357 if (__i == __j)
5358 return;
5359 while (true)
5360 {
5361 while (!__comp(*__first, *__i))
5362 ++__i;
5363 while (__comp(*__first, *--__j))
5364 ;
5365 if (__i >= __j)
5366 break;
5367 swap(*__i, *__j);
5368 ++__n_swaps;
5369 ++__i;
5370 }
5371 // [__first, __i) == *__first and *__first < [__i, __last)
5372 // The first part is sorted,
5373 if (__nth < __i)
5374 return;
5375 // __nth_element the second part
5376 // _VSTD::__nth_element<_Compare>(__i, __nth, __last, __comp);
5377 __first = __i;
5378 goto __restart;
5379 }
5380 if (__comp(*__j, *__m))
5381 {
5382 swap(*__i, *__j);
5383 ++__n_swaps;
5384 break; // found guard for downward moving __j, now use unguarded partition
5385 }
5386 }
5387 }
5388 ++__i;
5389 // j points beyond range to be tested, *__lm1 is known to be <= *__m
5390 // if not yet partitioned...
5391 if (__i < __j)
5392 {
5393 // known that *(__i - 1) < *__m
5394 while (true)
5395 {
5396 // __m still guards upward moving __i
5397 while (__comp(*__i, *__m))
5398 ++__i;
5399 // It is now known that a guard exists for downward moving __j
5400 while (!__comp(*--__j, *__m))
5401 ;
5402 if (__i >= __j)
5403 break;
5404 swap(*__i, *__j);
5405 ++__n_swaps;
5406 // It is known that __m != __j
5407 // If __m just moved, follow it
5408 if (__m == __i)
5409 __m = __j;
5410 ++__i;
5411 }
5412 }
5413 // [__first, __i) < *__m and *__m <= [__i, __last)
5414 if (__i != __m && __comp(*__m, *__i))
5415 {
5416 swap(*__i, *__m);
5417 ++__n_swaps;
5418 }
5419 // [__first, __i) < *__i and *__i <= [__i+1, __last)
5420 if (__nth == __i)
5421 return;
5422 if (__n_swaps == 0)
5423 {
5424 // We were given a perfectly partitioned sequence. Coincidence?
5425 if (__nth < __i)
5426 {
5427 // Check for [__first, __i) already sorted
5428 __j = __m = __first;
5429 while (++__j != __i)
5430 {
5431 if (__comp(*__j, *__m))
5432 // not yet sorted, so sort
5433 goto not_sorted;
5434 __m = __j;
5435 }
5436 // [__first, __i) sorted
5437 return;
5438 }
5439 else
5440 {
5441 // Check for [__i, __last) already sorted
5442 __j = __m = __i;
5443 while (++__j != __last)
5444 {
5445 if (__comp(*__j, *__m))
5446 // not yet sorted, so sort
5447 goto not_sorted;
5448 __m = __j;
5449 }
5450 // [__i, __last) sorted
5451 return;
5452 }
5453 }
5454not_sorted:
5455 // __nth_element on range containing __nth
5456 if (__nth < __i)
5457 {
5458 // _VSTD::__nth_element<_Compare>(__first, __nth, __i, __comp);
5459 __last = __i;
5460 }
5461 else
5462 {
5463 // _VSTD::__nth_element<_Compare>(__i+1, __nth, __last, __comp);
5464 __first = ++__i;
5465 }
5466 }
5467}
5468
5469template <class _RandomAccessIterator, class _Compare>
5470inline _LIBCPP_INLINE_VISIBILITY
5471void
5472nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last, _Compare __comp)
5473{
5474 typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
5475 _VSTD::__nth_element<_Comp_ref>(__first, __nth, __last, __comp);
5476}
5477
5478template <class _RandomAccessIterator>
5479inline _LIBCPP_INLINE_VISIBILITY
5480void
5481nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last)
5482{
5483 _VSTD::nth_element(__first, __nth, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
5484}
5485
5486// includes
5487
5488template <class _Compare, class _InputIterator1, class _InputIterator2>
5489_LIBCPP_CONSTEXPR_AFTER_CXX17 bool
5490__includes(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2,
5491 _Compare __comp)
5492{
5493 for (; __first2 != __last2; ++__first1)
5494 {
5495 if (__first1 == __last1 || __comp(*__first2, *__first1))
5496 return false;
5497 if (!__comp(*__first1, *__first2))
5498 ++__first2;
5499 }
5500 return true;
5501}
5502
5503template <class _InputIterator1, class _InputIterator2, class _Compare>
5504_LIBCPP_NODISCARD_EXT inline
5505_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
5506bool
5507includes(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2,
5508 _Compare __comp)
5509{
5510 typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
5511 return _VSTD::__includes<_Comp_ref>(__first1, __last1, __first2, __last2, __comp);
5512}
5513
5514template <class _InputIterator1, class _InputIterator2>
5515_LIBCPP_NODISCARD_EXT inline
5516_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
5517bool
5518includes(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2)
5519{
5520 return _VSTD::includes(__first1, __last1, __first2, __last2,
5521 __less<typename iterator_traits<_InputIterator1>::value_type,
5522 typename iterator_traits<_InputIterator2>::value_type>());
5523}
5524
5525// set_union
5526
5527template <class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator>
5528_LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator
5529__set_union(_InputIterator1 __first1, _InputIterator1 __last1,
5530 _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)
5531{
5532 for (; __first1 != __last1; ++__result)
5533 {
5534 if (__first2 == __last2)
5535 return _VSTD::copy(__first1, __last1, __result);
5536 if (__comp(*__first2, *__first1))
5537 {
5538 *__result = *__first2;
5539 ++__first2;
5540 }
5541 else
5542 {
5543 if (!__comp(*__first1, *__first2))
5544 ++__first2;
5545 *__result = *__first1;
5546 ++__first1;
5547 }
5548 }
5549 return _VSTD::copy(__first2, __last2, __result);
5550}
5551
5552template <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _Compare>
5553inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
5554_OutputIterator
5555set_union(_InputIterator1 __first1, _InputIterator1 __last1,
5556 _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)
5557{
5558 typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
5559 return _VSTD::__set_union<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp);
5560}
5561
5562template <class _InputIterator1, class _InputIterator2, class _OutputIterator>
5563inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
5564_OutputIterator
5565set_union(_InputIterator1 __first1, _InputIterator1 __last1,
5566 _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result)
5567{
5568 return _VSTD::set_union(__first1, __last1, __first2, __last2, __result,
5569 __less<typename iterator_traits<_InputIterator1>::value_type,
5570 typename iterator_traits<_InputIterator2>::value_type>());
5571}
5572
5573// set_intersection
5574
5575template <class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator>
5576_LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator
5577__set_intersection(_InputIterator1 __first1, _InputIterator1 __last1,
5578 _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)
5579{
5580 while (__first1 != __last1 && __first2 != __last2)
5581 {
5582 if (__comp(*__first1, *__first2))
5583 ++__first1;
5584 else
5585 {
5586 if (!__comp(*__first2, *__first1))
5587 {
5588 *__result = *__first1;
5589 ++__result;
5590 ++__first1;
5591 }
5592 ++__first2;
5593 }
5594 }
5595 return __result;
5596}
5597
5598template <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _Compare>
5599inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
5600_OutputIterator
5601set_intersection(_InputIterator1 __first1, _InputIterator1 __last1,
5602 _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)
5603{
5604 typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
5605 return _VSTD::__set_intersection<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp);
5606}
5607
5608template <class _InputIterator1, class _InputIterator2, class _OutputIterator>
5609inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
5610_OutputIterator
5611set_intersection(_InputIterator1 __first1, _InputIterator1 __last1,
5612 _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result)
5613{
5614 return _VSTD::set_intersection(__first1, __last1, __first2, __last2, __result,
5615 __less<typename iterator_traits<_InputIterator1>::value_type,
5616 typename iterator_traits<_InputIterator2>::value_type>());
5617}
5618
5619// set_difference
5620
5621template <class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator>
5622_LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator
5623__set_difference(_InputIterator1 __first1, _InputIterator1 __last1,
5624 _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)
5625{
5626 while (__first1 != __last1)
5627 {
5628 if (__first2 == __last2)
5629 return _VSTD::copy(__first1, __last1, __result);
5630 if (__comp(*__first1, *__first2))
5631 {
5632 *__result = *__first1;
5633 ++__result;
5634 ++__first1;
5635 }
5636 else
5637 {
5638 if (!__comp(*__first2, *__first1))
5639 ++__first1;
5640 ++__first2;
5641 }
5642 }
5643 return __result;
5644}
5645
5646template <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _Compare>
5647inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
5648_OutputIterator
5649set_difference(_InputIterator1 __first1, _InputIterator1 __last1,
5650 _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)
5651{
5652 typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
5653 return _VSTD::__set_difference<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp);
5654}
5655
5656template <class _InputIterator1, class _InputIterator2, class _OutputIterator>
5657inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
5658_OutputIterator
5659set_difference(_InputIterator1 __first1, _InputIterator1 __last1,
5660 _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result)
5661{
5662 return _VSTD::set_difference(__first1, __last1, __first2, __last2, __result,
5663 __less<typename iterator_traits<_InputIterator1>::value_type,
5664 typename iterator_traits<_InputIterator2>::value_type>());
5665}
5666
5667// set_symmetric_difference
5668
5669template <class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator>
5670_LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator
5671__set_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1,
5672 _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)
5673{
5674 while (__first1 != __last1)
5675 {
5676 if (__first2 == __last2)
5677 return _VSTD::copy(__first1, __last1, __result);
5678 if (__comp(*__first1, *__first2))
5679 {
5680 *__result = *__first1;
5681 ++__result;
5682 ++__first1;
5683 }
5684 else
5685 {
5686 if (__comp(*__first2, *__first1))
5687 {
5688 *__result = *__first2;
5689 ++__result;
5690 }
5691 else
5692 ++__first1;
5693 ++__first2;
5694 }
5695 }
5696 return _VSTD::copy(__first2, __last2, __result);
5697}
5698
5699template <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _Compare>
5700inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
5701_OutputIterator
5702set_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1,
5703 _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)
5704{
5705 typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
5706 return _VSTD::__set_symmetric_difference<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp);
5707}
5708
5709template <class _InputIterator1, class _InputIterator2, class _OutputIterator>
5710inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
5711_OutputIterator
5712set_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1,
5713 _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result)
5714{
5715 return _VSTD::set_symmetric_difference(__first1, __last1, __first2, __last2, __result,
5716 __less<typename iterator_traits<_InputIterator1>::value_type,
5717 typename iterator_traits<_InputIterator2>::value_type>());
5718}
5719
5720// lexicographical_compare
5721
5722template <class _Compare, class _InputIterator1, class _InputIterator2>
5723_LIBCPP_CONSTEXPR_AFTER_CXX17 bool
5724__lexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1,
5725 _InputIterator2 __first2, _InputIterator2 __last2, _Compare __comp)
5726{
5727 for (; __first2 != __last2; ++__first1, (void) ++__first2)
5728 {
5729 if (__first1 == __last1 || __comp(*__first1, *__first2))
5730 return true;
5731 if (__comp(*__first2, *__first1))
5732 return false;
5733 }
5734 return false;
5735}
5736
5737template <class _InputIterator1, class _InputIterator2, class _Compare>
5738_LIBCPP_NODISCARD_EXT inline
5739_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
5740bool
5741lexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1,
5742 _InputIterator2 __first2, _InputIterator2 __last2, _Compare __comp)
5743{
5744 typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
5745 return _VSTD::__lexicographical_compare<_Comp_ref>(__first1, __last1, __first2, __last2, __comp);
5746}
5747
5748template <class _InputIterator1, class _InputIterator2>
5749_LIBCPP_NODISCARD_EXT inline
5750_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
5751bool
5752lexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1,
5753 _InputIterator2 __first2, _InputIterator2 __last2)
5754{
5755 return _VSTD::lexicographical_compare(__first1, __last1, __first2, __last2,
5756 __less<typename iterator_traits<_InputIterator1>::value_type,
5757 typename iterator_traits<_InputIterator2>::value_type>());
5758}
5759
5760// next_permutation
5761
5762template <class _Compare, class _BidirectionalIterator>
5763_LIBCPP_CONSTEXPR_AFTER_CXX17 bool
5764__next_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp)
5765{
5766 _BidirectionalIterator __i = __last;
5767 if (__first == __last || __first == --__i)
5768 return false;
5769 while (true)
5770 {
5771 _BidirectionalIterator __ip1 = __i;
5772 if (__comp(*--__i, *__ip1))
5773 {
5774 _BidirectionalIterator __j = __last;
5775 while (!__comp(*__i, *--__j))
5776 ;
5777 swap(*__i, *__j);
5778 _VSTD::reverse(__ip1, __last);
5779 return true;
5780 }
5781 if (__i == __first)
5782 {
5783 _VSTD::reverse(__first, __last);
5784 return false;
5785 }
5786 }
5787}
5788
5789template <class _BidirectionalIterator, class _Compare>
5790inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
5791bool
5792next_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp)
5793{
5794 typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
5795 return _VSTD::__next_permutation<_Comp_ref>(__first, __last, __comp);
5796}
5797
5798template <class _BidirectionalIterator>
5799inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
5800bool
5801next_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last)
5802{
5803 return _VSTD::next_permutation(__first, __last,
5804 __less<typename iterator_traits<_BidirectionalIterator>::value_type>());
5805}
5806
5807// prev_permutation
5808
5809template <class _Compare, class _BidirectionalIterator>
5810_LIBCPP_CONSTEXPR_AFTER_CXX17 bool
5811__prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp)
5812{
5813 _BidirectionalIterator __i = __last;
5814 if (__first == __last || __first == --__i)
5815 return false;
5816 while (true)
5817 {
5818 _BidirectionalIterator __ip1 = __i;
5819 if (__comp(*__ip1, *--__i))
5820 {
5821 _BidirectionalIterator __j = __last;
5822 while (!__comp(*--__j, *__i))
5823 ;
5824 swap(*__i, *__j);
5825 _VSTD::reverse(__ip1, __last);
5826 return true;
5827 }
5828 if (__i == __first)
5829 {
5830 _VSTD::reverse(__first, __last);
5831 return false;
5832 }
5833 }
5834}
5835
5836template <class _BidirectionalIterator, class _Compare>
5837inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
5838bool
5839prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp)
5840{
5841 typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
5842 return _VSTD::__prev_permutation<_Comp_ref>(__first, __last, __comp);
5843}
5844
5845template <class _BidirectionalIterator>
5846inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
5847bool
5848prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last)
5849{
5850 return _VSTD::prev_permutation(__first, __last,
5851 __less<typename iterator_traits<_BidirectionalIterator>::value_type>());
5852}
5853
5854_LIBCPP_END_NAMESPACE_STD
5855
5856764_LIBCPP_POP_MACROS
5857765
5858766#if defined(_LIBCPP_HAS_PARALLEL_ALGORITHMS) && _LIBCPP_STD_VER >= 17
5859767# include <__pstl_algorithm>
5860768#endif
5861769
5862#endif // _LIBCPP_ALGORITHM
770#endif // _LIBCPP_ALGORITHM
lib/libcxx/include/any+4-3
......@@ -80,12 +80,13 @@ namespace std {
8080
8181*/
8282
83#include <experimental/__config>
8483#include <__availability>
84#include <__config>
85#include <__utility/forward.h>
86#include <cstdlib>
8587#include <memory>
86#include <typeinfo>
8788#include <type_traits>
88#include <cstdlib>
89#include <typeinfo>
8990#include <version>
9091
9192#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
lib/libcxx/include/array+6-9
......@@ -109,25 +109,22 @@ template <size_t I, class T, size_t N> const T&& get(const array<T, N>&&) noexce
109109*/
110110
111111#include <__config>
112#include <__debug>
112113#include <__tuple>
113#include <type_traits>
114#include <utility>
115#include <iterator>
116114#include <algorithm>
117#include <stdexcept>
118115#include <cstdlib> // for _LIBCPP_UNREACHABLE
116#include <iterator>
117#include <stdexcept>
118#include <type_traits>
119#include <utility>
119120#include <version>
120#include <__debug>
121121
122122#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
123123#pragma GCC system_header
124124#endif
125125
126
127
128126_LIBCPP_BEGIN_NAMESPACE_STD
129127
130
131128template <class _Tp, size_t _Size>
132129struct _LIBCPP_TEMPLATE_VIS array
133130{
......@@ -520,4 +517,4 @@ to_array(_Tp(&&__arr)[_Size]) noexcept(is_nothrow_move_constructible_v<_Tp>) {
520517
521518_LIBCPP_END_NAMESPACE_STD
522519
523#endif // _LIBCPP_ARRAY
520#endif // _LIBCPP_ARRAY
lib/libcxx/include/atomic+54-23
......@@ -67,7 +67,8 @@ struct atomic
6767 bool is_lock_free() const volatile noexcept;
6868 bool is_lock_free() const noexcept;
6969
70 atomic() noexcept = default;
70 atomic() noexcept = default; // until C++20
71 constexpr atomic() noexcept(is_nothrow_default_constructible_v<T>); // since C++20
7172 constexpr atomic(T desr) noexcept;
7273 atomic(const atomic&) = delete;
7374 atomic& operator=(const atomic&) = delete;
......@@ -201,7 +202,8 @@ struct atomic<T*>
201202 bool is_lock_free() const volatile noexcept;
202203 bool is_lock_free() const noexcept;
203204
204 atomic() noexcept = default;
205 atomic() noexcept = default; // until C++20
206 constexpr atomic() noexcept; // since C++20
205207 constexpr atomic(T* desr) noexcept;
206208 atomic(const atomic&) = delete;
207209 atomic& operator=(const atomic&) = delete;
......@@ -509,7 +511,8 @@ typedef atomic<uintmax_t> atomic_uintmax_t;
509511
510512typedef struct atomic_flag
511513{
512 atomic_flag() noexcept = default;
514 atomic_flag() noexcept = default; // until C++20
515 constexpr atomic_flag() noexcept; // since C++20
513516 atomic_flag(const atomic_flag&) = delete;
514517 atomic_flag& operator=(const atomic_flag&) = delete;
515518 atomic_flag& operator=(const atomic_flag&) volatile = delete;
......@@ -574,8 +577,8 @@ template <class T>
574577
575578*/
576579
577#include <__config>
578580#include <__availability>
581#include <__config>
579582#include <__threading_support>
580583#include <cstddef>
581584#include <cstdint>
......@@ -669,7 +672,7 @@ static_assert((is_same<underlying_type<memory_order>::type, __memory_order_under
669672 "unexpected underlying type for std::memory_order");
670673
671674#if defined(_LIBCPP_HAS_GCC_ATOMIC_IMP) || \
672 defined(_LIBCPP_ATOMIC_ONLY_USE_BUILTINS)
675 defined(_LIBCPP_ATOMIC_ONLY_USE_BUILTINS)
673676
674677// [atomics.types.generic]p1 guarantees _Tp is trivially copyable. Because
675678// the default operator= in an object is not volatile, a byte-by-byte copy
......@@ -1017,26 +1020,33 @@ _Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp> * __a, _Tp __value, memory
10171020 return __c11_atomic_exchange(&__a->__a_value, __value, static_cast<__memory_order_underlying_t>(__order));
10181021}
10191022
1023_LIBCPP_INLINE_VISIBILITY inline _LIBCPP_CONSTEXPR memory_order __to_failure_order(memory_order __order) {
1024 // Avoid switch statement to make this a constexpr.
1025 return __order == memory_order_release ? memory_order_relaxed:
1026 (__order == memory_order_acq_rel ? memory_order_acquire:
1027 __order);
1028}
1029
10201030template<class _Tp>
10211031_LIBCPP_INLINE_VISIBILITY
10221032bool __cxx_atomic_compare_exchange_strong(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
1023 return __c11_atomic_compare_exchange_strong(&__a->__a_value, __expected, __value, static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__failure));
1033 return __c11_atomic_compare_exchange_strong(&__a->__a_value, __expected, __value, static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__to_failure_order(__failure)));
10241034}
10251035template<class _Tp>
10261036_LIBCPP_INLINE_VISIBILITY
10271037bool __cxx_atomic_compare_exchange_strong(__cxx_atomic_base_impl<_Tp> * __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
1028 return __c11_atomic_compare_exchange_strong(&__a->__a_value, __expected, __value, static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__failure));
1038 return __c11_atomic_compare_exchange_strong(&__a->__a_value, __expected, __value, static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__to_failure_order(__failure)));
10291039}
10301040
10311041template<class _Tp>
10321042_LIBCPP_INLINE_VISIBILITY
10331043bool __cxx_atomic_compare_exchange_weak(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
1034 return __c11_atomic_compare_exchange_weak(&__a->__a_value, __expected, __value, static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__failure));
1044 return __c11_atomic_compare_exchange_weak(&__a->__a_value, __expected, __value, static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__to_failure_order(__failure)));
10351045}
10361046template<class _Tp>
10371047_LIBCPP_INLINE_VISIBILITY
10381048bool __cxx_atomic_compare_exchange_weak(__cxx_atomic_base_impl<_Tp> * __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
1039 return __c11_atomic_compare_exchange_weak(&__a->__a_value, __expected, __value, static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__failure));
1049 return __c11_atomic_compare_exchange_weak(&__a->__a_value, __expected, __value, static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__to_failure_order(__failure)));
10401050}
10411051
10421052template<class _Tp>
......@@ -1127,7 +1137,7 @@ _Tp kill_dependency(_Tp __y) _NOEXCEPT
11271137#if defined(__CLANG_ATOMIC_BOOL_LOCK_FREE)
11281138# define ATOMIC_BOOL_LOCK_FREE __CLANG_ATOMIC_BOOL_LOCK_FREE
11291139# define ATOMIC_CHAR_LOCK_FREE __CLANG_ATOMIC_CHAR_LOCK_FREE
1130#ifndef _LIBCPP_NO_HAS_CHAR8_T
1140#ifndef _LIBCPP_HAS_NO_CHAR8_T
11311141# define ATOMIC_CHAR8_T_LOCK_FREE __CLANG_ATOMIC_CHAR8_T_LOCK_FREE
11321142#endif
11331143# define ATOMIC_CHAR16_T_LOCK_FREE __CLANG_ATOMIC_CHAR16_T_LOCK_FREE
......@@ -1141,7 +1151,7 @@ _Tp kill_dependency(_Tp __y) _NOEXCEPT
11411151#elif defined(__GCC_ATOMIC_BOOL_LOCK_FREE)
11421152# define ATOMIC_BOOL_LOCK_FREE __GCC_ATOMIC_BOOL_LOCK_FREE
11431153# define ATOMIC_CHAR_LOCK_FREE __GCC_ATOMIC_CHAR_LOCK_FREE
1144#ifndef _LIBCPP_NO_HAS_CHAR8_T
1154#ifndef _LIBCPP_HAS_NO_CHAR8_T
11451155# define ATOMIC_CHAR8_T_LOCK_FREE __GCC_ATOMIC_CHAR8_T_LOCK_FREE
11461156#endif
11471157# define ATOMIC_CHAR16_T_LOCK_FREE __GCC_ATOMIC_CHAR16_T_LOCK_FREE
......@@ -1458,7 +1468,7 @@ template<> struct __cxx_is_always_lock_free<bool> { enum { __value = 2 == ATOMIC
14581468template<> struct __cxx_is_always_lock_free<char> { enum { __value = 2 == ATOMIC_CHAR_LOCK_FREE }; };
14591469template<> struct __cxx_is_always_lock_free<signed char> { enum { __value = 2 == ATOMIC_CHAR_LOCK_FREE }; };
14601470template<> struct __cxx_is_always_lock_free<unsigned char> { enum { __value = 2 == ATOMIC_CHAR_LOCK_FREE }; };
1461#ifndef _LIBCPP_NO_HAS_CHAR8_T
1471#ifndef _LIBCPP_HAS_NO_CHAR8_T
14621472template<> struct __cxx_is_always_lock_free<char8_t> { enum { __value = 2 == ATOMIC_CHAR8_T_LOCK_FREE }; };
14631473#endif
14641474template<> struct __cxx_is_always_lock_free<char16_t> { enum { __value = 2 == ATOMIC_CHAR16_T_LOCK_FREE }; };
......@@ -1673,24 +1683,23 @@ struct __atomic_base // false
16731683 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_all() _NOEXCEPT
16741684 {__cxx_atomic_notify_all(&__a_);}
16751685
1686#if _LIBCPP_STD_VER > 17
1687 _LIBCPP_INLINE_VISIBILITY constexpr
1688 __atomic_base() noexcept(is_nothrow_default_constructible_v<_Tp>) : __a_(_Tp()) {}
1689#else
16761690 _LIBCPP_INLINE_VISIBILITY
16771691 __atomic_base() _NOEXCEPT _LIBCPP_DEFAULT
1692#endif
16781693
16791694 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
16801695 __atomic_base(_Tp __d) _NOEXCEPT : __a_(__d) {}
16811696
16821697#ifndef _LIBCPP_CXX03_LANG
16831698 __atomic_base(const __atomic_base&) = delete;
1684 __atomic_base& operator=(const __atomic_base&) = delete;
1685 __atomic_base& operator=(const __atomic_base&) volatile = delete;
16861699#else
16871700private:
16881701 _LIBCPP_INLINE_VISIBILITY
16891702 __atomic_base(const __atomic_base&);
1690 _LIBCPP_INLINE_VISIBILITY
1691 __atomic_base& operator=(const __atomic_base&);
1692 _LIBCPP_INLINE_VISIBILITY
1693 __atomic_base& operator=(const __atomic_base&) volatile;
16941703#endif
16951704};
16961705
......@@ -1706,8 +1715,10 @@ struct __atomic_base<_Tp, true>
17061715 : public __atomic_base<_Tp, false>
17071716{
17081717 typedef __atomic_base<_Tp, false> __base;
1709 _LIBCPP_INLINE_VISIBILITY
1718
1719 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
17101720 __atomic_base() _NOEXCEPT _LIBCPP_DEFAULT
1721
17111722 _LIBCPP_INLINE_VISIBILITY
17121723 _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __base(__d) {}
17131724
......@@ -1789,8 +1800,15 @@ struct atomic
17891800 typedef __atomic_base<_Tp> __base;
17901801 typedef _Tp value_type;
17911802 typedef value_type difference_type;
1803
1804#if _LIBCPP_STD_VER > 17
1805 _LIBCPP_INLINE_VISIBILITY
1806 atomic() = default;
1807#else
17921808 _LIBCPP_INLINE_VISIBILITY
17931809 atomic() _NOEXCEPT _LIBCPP_DEFAULT
1810#endif
1811
17941812 _LIBCPP_INLINE_VISIBILITY
17951813 _LIBCPP_CONSTEXPR atomic(_Tp __d) _NOEXCEPT : __base(__d) {}
17961814
......@@ -1800,6 +1818,9 @@ struct atomic
18001818 _LIBCPP_INLINE_VISIBILITY
18011819 _Tp operator=(_Tp __d) _NOEXCEPT
18021820 {__base::store(__d); return __d;}
1821
1822 atomic& operator=(const atomic&) = delete;
1823 atomic& operator=(const atomic&) volatile = delete;
18031824};
18041825
18051826// atomic<T*>
......@@ -1811,8 +1832,10 @@ struct atomic<_Tp*>
18111832 typedef __atomic_base<_Tp*> __base;
18121833 typedef _Tp* value_type;
18131834 typedef ptrdiff_t difference_type;
1835
18141836 _LIBCPP_INLINE_VISIBILITY
18151837 atomic() _NOEXCEPT _LIBCPP_DEFAULT
1838
18161839 _LIBCPP_INLINE_VISIBILITY
18171840 _LIBCPP_CONSTEXPR atomic(_Tp* __d) _NOEXCEPT : __base(__d) {}
18181841
......@@ -1862,6 +1885,9 @@ struct atomic<_Tp*>
18621885 _Tp* operator-=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;}
18631886 _LIBCPP_INLINE_VISIBILITY
18641887 _Tp* operator-=(ptrdiff_t __op) _NOEXCEPT {return fetch_sub(__op) - __op;}
1888
1889 atomic& operator=(const atomic&) = delete;
1890 atomic& operator=(const atomic&) volatile = delete;
18651891};
18661892
18671893// atomic_is_lock_free
......@@ -1885,7 +1911,7 @@ atomic_is_lock_free(const atomic<_Tp>* __o) _NOEXCEPT
18851911// atomic_init
18861912
18871913template <class _Tp>
1888_LIBCPP_INLINE_VISIBILITY
1914_LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_INLINE_VISIBILITY
18891915void
18901916atomic_init(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
18911917{
......@@ -1893,7 +1919,7 @@ atomic_init(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NO
18931919}
18941920
18951921template <class _Tp>
1896_LIBCPP_INLINE_VISIBILITY
1922_LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_INLINE_VISIBILITY
18971923void
18981924atomic_init(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
18991925{
......@@ -2534,8 +2560,13 @@ typedef struct atomic_flag
25342560 void notify_all() _NOEXCEPT
25352561 {__cxx_atomic_notify_all(&__a_);}
25362562
2563#if _LIBCPP_STD_VER > 17
2564 _LIBCPP_INLINE_VISIBILITY constexpr
2565 atomic_flag() _NOEXCEPT : __a_(false) {}
2566#else
25372567 _LIBCPP_INLINE_VISIBILITY
25382568 atomic_flag() _NOEXCEPT _LIBCPP_DEFAULT
2569#endif
25392570
25402571 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
25412572 atomic_flag(bool __b) _NOEXCEPT : __a_(__b) {} // EXTENSION
......@@ -2728,7 +2759,7 @@ typedef atomic<long> atomic_long;
27282759typedef atomic<unsigned long> atomic_ulong;
27292760typedef atomic<long long> atomic_llong;
27302761typedef atomic<unsigned long long> atomic_ullong;
2731#ifndef _LIBCPP_NO_HAS_CHAR8_T
2762#ifndef _LIBCPP_HAS_NO_CHAR8_T
27322763typedef atomic<char8_t> atomic_char8_t;
27332764#endif
27342765typedef atomic<char16_t> atomic_char16_t;
......@@ -2801,4 +2832,4 @@ typedef atomic<__libcpp_unsigned_lock_free> atomic_unsigned_lock_free;
28012832
28022833_LIBCPP_END_NAMESPACE_STD
28032834
2804#endif // _LIBCPP_ATOMIC
2835#endif // _LIBCPP_ATOMIC
lib/libcxx/include/barrier+4-5
......@@ -45,8 +45,8 @@ namespace std
4545
4646*/
4747
48#include <__config>
4948#include <__availability>
49#include <__config>
5050#include <atomic>
5151#ifndef _LIBCPP_HAS_NO_TREE_BARRIER
5252# include <memory>
......@@ -107,7 +107,6 @@ void __destroy_barrier_algorithm_base(__barrier_algorithm_base* __barrier);
107107
108108template<class _CompletionF>
109109class __barrier_base {
110
111110 ptrdiff_t __expected;
112111 unique_ptr<__barrier_algorithm_base,
113112 void (*)(__barrier_algorithm_base*)> __base;
......@@ -146,7 +145,7 @@ public:
146145 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
147146 void wait(arrival_token&& __old_phase) const
148147 {
149 auto const __test_fn = [=]() -> bool {
148 auto const __test_fn = [this, __old_phase]() -> bool {
150149 return __phase.load(memory_order_acquire) != __old_phase;
151150 };
152151 __libcpp_thread_poll_with_backoff(__test_fn, __libcpp_timed_backoff_policy());
......@@ -309,11 +308,11 @@ public:
309308 {
310309 __b.wait(_VSTD::move(__phase));
311310 }
312 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
311 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
313312 void arrive_and_wait()
314313 {
315314 wait(arrive());
316 }
315 }
317316 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
318317 void arrive_and_drop()
319318 {
lib/libcxx/include/bit+26-56
......@@ -55,11 +55,11 @@ namespace std {
5555*/
5656
5757#include <__config>
58#include <__bits>
58#include <__bits> // __libcpp_clz
59#include <__debug>
5960#include <limits>
6061#include <type_traits>
6162#include <version>
62#include <__debug>
6363
6464#if defined(__IBMCPP__)
6565#include "__support/ibm/support.h"
......@@ -77,49 +77,33 @@ _LIBCPP_PUSH_MACROS
7777
7878_LIBCPP_BEGIN_NAMESPACE_STD
7979
80
81template <class _Tp>
82using __bitop_unsigned_integer _LIBCPP_NODEBUG_TYPE = integral_constant<bool,
83 is_integral<_Tp>::value &&
84 is_unsigned<_Tp>::value &&
85 _IsNotSame<typename remove_cv<_Tp>::type, bool>::value &&
86 _IsNotSame<typename remove_cv<_Tp>::type, signed char>::value &&
87 _IsNotSame<typename remove_cv<_Tp>::type, wchar_t>::value &&
88 _IsNotSame<typename remove_cv<_Tp>::type, char16_t>::value &&
89 _IsNotSame<typename remove_cv<_Tp>::type, char32_t>::value
90 >;
91
92
9380template<class _Tp>
9481_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
9582_Tp __rotl(_Tp __t, unsigned int __cnt) _NOEXCEPT
9683{
97 static_assert(__bitop_unsigned_integer<_Tp>::value, "__rotl requires unsigned");
84 static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__rotl requires an unsigned integer type");
9885 const unsigned int __dig = numeric_limits<_Tp>::digits;
9986 if ((__cnt % __dig) == 0)
10087 return __t;
10188 return (__t << (__cnt % __dig)) | (__t >> (__dig - (__cnt % __dig)));
10289}
10390
104
10591template<class _Tp>
10692_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
10793_Tp __rotr(_Tp __t, unsigned int __cnt) _NOEXCEPT
10894{
109 static_assert(__bitop_unsigned_integer<_Tp>::value, "__rotr requires unsigned");
95 static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__rotr requires an unsigned integer type");
11096 const unsigned int __dig = numeric_limits<_Tp>::digits;
11197 if ((__cnt % __dig) == 0)
11298 return __t;
11399 return (__t >> (__cnt % __dig)) | (__t << (__dig - (__cnt % __dig)));
114100}
115101
116
117
118102template<class _Tp>
119103_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
120104int __countr_zero(_Tp __t) _NOEXCEPT
121105{
122 static_assert(__bitop_unsigned_integer<_Tp>::value, "__countr_zero requires unsigned");
106 static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__countr_zero requires an unsigned integer type");
123107 if (__t == 0)
124108 return numeric_limits<_Tp>::digits;
125109
......@@ -132,14 +116,13 @@ int __countr_zero(_Tp __t) _NOEXCEPT
132116 else
133117 {
134118 int __ret = 0;
135 int __iter = 0;
136119 const unsigned int __ulldigits = numeric_limits<unsigned long long>::digits;
137 while ((__iter = __libcpp_ctz(static_cast<unsigned long long>(__t))) == __ulldigits)
120 while (static_cast<unsigned long long>(__t) == 0uLL)
138121 {
139 __ret += __iter;
122 __ret += __ulldigits;
140123 __t >>= __ulldigits;
141124 }
142 return __ret + __iter;
125 return __ret + __libcpp_ctz(static_cast<unsigned long long>(__t));
143126 }
144127}
145128
......@@ -147,7 +130,7 @@ template<class _Tp>
147130_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
148131int __countl_zero(_Tp __t) _NOEXCEPT
149132{
150 static_assert(__bitop_unsigned_integer<_Tp>::value, "__countl_zero requires unsigned");
133 static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__countl_zero requires an unsigned integer type");
151134 if (__t == 0)
152135 return numeric_limits<_Tp>::digits;
153136
......@@ -179,30 +162,27 @@ template<class _Tp>
179162_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
180163int __countl_one(_Tp __t) _NOEXCEPT
181164{
182 static_assert(__bitop_unsigned_integer<_Tp>::value, "__countl_one requires unsigned");
165 static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__countl_one requires an unsigned integer type");
183166 return __t != numeric_limits<_Tp>::max()
184167 ? __countl_zero(static_cast<_Tp>(~__t))
185168 : numeric_limits<_Tp>::digits;
186169}
187170
188
189171template<class _Tp>
190172_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
191173int __countr_one(_Tp __t) _NOEXCEPT
192174{
193 static_assert(__bitop_unsigned_integer<_Tp>::value, "__countr_one requires unsigned");
175 static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__countr_one requires an unsigned integer type");
194176 return __t != numeric_limits<_Tp>::max()
195177 ? __countr_zero(static_cast<_Tp>(~__t))
196178 : numeric_limits<_Tp>::digits;
197179}
198180
199
200181template<class _Tp>
201182_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
202int
203__popcount(_Tp __t) _NOEXCEPT
183int __popcount(_Tp __t) _NOEXCEPT
204184{
205 static_assert(__bitop_unsigned_integer<_Tp>::value, "__libcpp_popcount requires unsigned");
185 static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__popcount requires an unsigned integer type");
206186 if (sizeof(_Tp) <= sizeof(unsigned int))
207187 return __libcpp_popcount(static_cast<unsigned int>(__t));
208188 else if (sizeof(_Tp) <= sizeof(unsigned long))
......@@ -221,13 +201,12 @@ __popcount(_Tp __t) _NOEXCEPT
221201 }
222202}
223203
224
225204// integral log base 2
226205template<class _Tp>
227206_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
228207unsigned __bit_log2(_Tp __t) _NOEXCEPT
229208{
230 static_assert(__bitop_unsigned_integer<_Tp>::value, "__bit_log2 requires unsigned");
209 static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__bit_log2 requires an unsigned integer type");
231210 return numeric_limits<_Tp>::digits - 1 - __countl_zero(__t);
232211}
233212
......@@ -235,80 +214,71 @@ template <class _Tp>
235214_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
236215bool __has_single_bit(_Tp __t) _NOEXCEPT
237216{
238 static_assert(__bitop_unsigned_integer<_Tp>::value, "__has_single_bit requires unsigned");
217 static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__has_single_bit requires an unsigned integer type");
239218 return __t != 0 && (((__t & (__t - 1)) == 0));
240219}
241220
242
243221#if _LIBCPP_STD_VER > 17
244222
245223template<class _Tp>
246224_LIBCPP_INLINE_VISIBILITY constexpr
247enable_if_t<__bitop_unsigned_integer<_Tp>::value, _Tp>
225_EnableIf<__libcpp_is_unsigned_integer<_Tp>::value, _Tp>
248226rotl(_Tp __t, unsigned int __cnt) noexcept
249227{
250228 return __rotl(__t, __cnt);
251229}
252230
253
254// rotr
255231template<class _Tp>
256232_LIBCPP_INLINE_VISIBILITY constexpr
257enable_if_t<__bitop_unsigned_integer<_Tp>::value, _Tp>
233_EnableIf<__libcpp_is_unsigned_integer<_Tp>::value, _Tp>
258234rotr(_Tp __t, unsigned int __cnt) noexcept
259235{
260236 return __rotr(__t, __cnt);
261237}
262238
263
264239template<class _Tp>
265240_LIBCPP_INLINE_VISIBILITY constexpr
266enable_if_t<__bitop_unsigned_integer<_Tp>::value, int>
241_EnableIf<__libcpp_is_unsigned_integer<_Tp>::value, int>
267242countl_zero(_Tp __t) noexcept
268243{
269244 return __countl_zero(__t);
270245}
271246
272
273247template<class _Tp>
274248_LIBCPP_INLINE_VISIBILITY constexpr
275enable_if_t<__bitop_unsigned_integer<_Tp>::value, int>
249_EnableIf<__libcpp_is_unsigned_integer<_Tp>::value, int>
276250countl_one(_Tp __t) noexcept
277251{
278252 return __countl_one(__t);
279253}
280254
281
282255template<class _Tp>
283256_LIBCPP_INLINE_VISIBILITY constexpr
284enable_if_t<__bitop_unsigned_integer<_Tp>::value, int>
257_EnableIf<__libcpp_is_unsigned_integer<_Tp>::value, int>
285258countr_zero(_Tp __t) noexcept
286259{
287260 return __countr_zero(__t);
288261}
289262
290
291263template<class _Tp>
292264_LIBCPP_INLINE_VISIBILITY constexpr
293enable_if_t<__bitop_unsigned_integer<_Tp>::value, int>
265_EnableIf<__libcpp_is_unsigned_integer<_Tp>::value, int>
294266countr_one(_Tp __t) noexcept
295267{
296268 return __countr_one(__t);
297269}
298270
299
300271template<class _Tp>
301272_LIBCPP_INLINE_VISIBILITY constexpr
302enable_if_t<__bitop_unsigned_integer<_Tp>::value, int>
273_EnableIf<__libcpp_is_unsigned_integer<_Tp>::value, int>
303274popcount(_Tp __t) noexcept
304275{
305276 return __popcount(__t);
306277}
307278
308
309279template <class _Tp>
310280_LIBCPP_INLINE_VISIBILITY constexpr
311enable_if_t<__bitop_unsigned_integer<_Tp>::value, bool>
281_EnableIf<__libcpp_is_unsigned_integer<_Tp>::value, bool>
312282has_single_bit(_Tp __t) noexcept
313283{
314284 return __has_single_bit(__t);
......@@ -316,7 +286,7 @@ has_single_bit(_Tp __t) noexcept
316286
317287template <class _Tp>
318288_LIBCPP_INLINE_VISIBILITY constexpr
319enable_if_t<__bitop_unsigned_integer<_Tp>::value, _Tp>
289_EnableIf<__libcpp_is_unsigned_integer<_Tp>::value, _Tp>
320290bit_floor(_Tp __t) noexcept
321291{
322292 return __t == 0 ? 0 : _Tp{1} << __bit_log2(__t);
......@@ -324,7 +294,7 @@ bit_floor(_Tp __t) noexcept
324294
325295template <class _Tp>
326296_LIBCPP_INLINE_VISIBILITY constexpr
327enable_if_t<__bitop_unsigned_integer<_Tp>::value, _Tp>
297_EnableIf<__libcpp_is_unsigned_integer<_Tp>::value, _Tp>
328298bit_ceil(_Tp __t) noexcept
329299{
330300 if (__t < 2) return 1;
......@@ -343,7 +313,7 @@ bit_ceil(_Tp __t) noexcept
343313
344314template <class _Tp>
345315_LIBCPP_INLINE_VISIBILITY constexpr
346enable_if_t<__bitop_unsigned_integer<_Tp>::value, _Tp>
316_EnableIf<__libcpp_is_unsigned_integer<_Tp>::value, _Tp>
347317bit_width(_Tp __t) noexcept
348318{
349319 return __t == 0 ? 0 : __bit_log2(__t) + 1;
lib/libcxx/include/bitset+9-15
......@@ -114,12 +114,12 @@ template <size_t N> struct hash<std::bitset<N>>;
114114
115115#include <__config>
116116#include <__bit_reference>
117#include <cstddef>
117#include <__functional_base>
118118#include <climits>
119#include <string>
120#include <stdexcept>
119#include <cstddef>
121120#include <iosfwd>
122#include <__functional_base>
121#include <stdexcept>
122#include <string>
123123
124124#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
125125#pragma GCC system_header
......@@ -202,7 +202,7 @@ private:
202202 void __init(unsigned long long __v, false_type) _NOEXCEPT;
203203 _LIBCPP_INLINE_VISIBILITY
204204 void __init(unsigned long long __v, true_type) _NOEXCEPT;
205#endif // _LIBCPP_CXX03_LANG
205#endif // _LIBCPP_CXX03_LANG
206206 unsigned long to_ulong(false_type) const;
207207 _LIBCPP_INLINE_VISIBILITY
208208 unsigned long to_ulong(true_type) const;
......@@ -258,7 +258,7 @@ __bitset<_N_words, _Size>::__init(unsigned long long __v, true_type) _NOEXCEPT
258258 _VSTD::fill(__first_ + 1, __first_ + sizeof(__first_)/sizeof(__first_[0]), __storage_type(0));
259259}
260260
261#endif // _LIBCPP_CXX03_LANG
261#endif // _LIBCPP_CXX03_LANG
262262
263263template <size_t _N_words, size_t _Size>
264264inline
......@@ -775,10 +775,7 @@ bitset<_Size>::bitset(const _CharT* __str,
775775 for (; __i < _Mp; ++__i)
776776 {
777777 _CharT __c = __str[_Mp - 1 - __i];
778 if (__c == __zero)
779 (*this)[__i] = false;
780 else
781 (*this)[__i] = true;
778 (*this)[__i] = (__c == __one);
782779 }
783780 _VSTD::fill(base::__make_iter(__i), base::__make_iter(_Size), false);
784781}
......@@ -803,10 +800,7 @@ bitset<_Size>::bitset(const basic_string<_CharT,_Traits,_Allocator>& __str,
803800 for (; __i < _Mp; ++__i)
804801 {
805802 _CharT __c = __str[__pos + _Mp - 1 - __i];
806 if (_Traits::eq(__c, __zero))
807 (*this)[__i] = false;
808 else
809 (*this)[__i] = true;
803 (*this)[__i] = _Traits::eq(__c, __one);
810804 }
811805 _VSTD::fill(base::__make_iter(__i), base::__make_iter(_Size), false);
812806}
......@@ -1106,4 +1100,4 @@ _LIBCPP_END_NAMESPACE_STD
11061100
11071101_LIBCPP_POP_MACROS
11081102
1109#endif // _LIBCPP_BITSET
1103#endif // _LIBCPP_BITSET
lib/libcxx/include/ccomplex+1-1
......@@ -25,4 +25,4 @@
2525
2626// hh 080623 Created
2727
28#endif // _LIBCPP_CCOMPLEX
28#endif // _LIBCPP_CCOMPLEX
lib/libcxx/include/cctype+15-15
......@@ -100,21 +100,21 @@ _LIBCPP_BEGIN_NAMESPACE_STD
100100#endif
101101
102102
103using ::isalnum;
104using ::isalpha;
105using ::isblank;
106using ::iscntrl;
107using ::isdigit;
108using ::isgraph;
109using ::islower;
110using ::isprint;
111using ::ispunct;
112using ::isspace;
113using ::isupper;
114using ::isxdigit;
115using ::tolower;
116using ::toupper;
103using ::isalnum _LIBCPP_USING_IF_EXISTS;
104using ::isalpha _LIBCPP_USING_IF_EXISTS;
105using ::isblank _LIBCPP_USING_IF_EXISTS;
106using ::iscntrl _LIBCPP_USING_IF_EXISTS;
107using ::isdigit _LIBCPP_USING_IF_EXISTS;
108using ::isgraph _LIBCPP_USING_IF_EXISTS;
109using ::islower _LIBCPP_USING_IF_EXISTS;
110using ::isprint _LIBCPP_USING_IF_EXISTS;
111using ::ispunct _LIBCPP_USING_IF_EXISTS;
112using ::isspace _LIBCPP_USING_IF_EXISTS;
113using ::isupper _LIBCPP_USING_IF_EXISTS;
114using ::isxdigit _LIBCPP_USING_IF_EXISTS;
115using ::tolower _LIBCPP_USING_IF_EXISTS;
116using ::toupper _LIBCPP_USING_IF_EXISTS;
117117
118118_LIBCPP_END_NAMESPACE_STD
119119
120#endif // _LIBCPP_CCTYPE
120#endif // _LIBCPP_CCTYPE
lib/libcxx/include/cerrno+1-1
......@@ -29,4 +29,4 @@ Macros:
2929#pragma GCC system_header
3030#endif
3131
32#endif // _LIBCPP_CERRNO
32#endif // _LIBCPP_CERRNO
lib/libcxx/include/cfenv+15-15
......@@ -61,21 +61,21 @@ int feupdateenv(const fenv_t* envp);
6161
6262_LIBCPP_BEGIN_NAMESPACE_STD
6363
64using ::fenv_t;
65using ::fexcept_t;
66
67using ::feclearexcept;
68using ::fegetexceptflag;
69using ::feraiseexcept;
70using ::fesetexceptflag;
71using ::fetestexcept;
72using ::fegetround;
73using ::fesetround;
74using ::fegetenv;
75using ::feholdexcept;
76using ::fesetenv;
77using ::feupdateenv;
64using ::fenv_t _LIBCPP_USING_IF_EXISTS;
65using ::fexcept_t _LIBCPP_USING_IF_EXISTS;
66
67using ::feclearexcept _LIBCPP_USING_IF_EXISTS;
68using ::fegetexceptflag _LIBCPP_USING_IF_EXISTS;
69using ::feraiseexcept _LIBCPP_USING_IF_EXISTS;
70using ::fesetexceptflag _LIBCPP_USING_IF_EXISTS;
71using ::fetestexcept _LIBCPP_USING_IF_EXISTS;
72using ::fegetround _LIBCPP_USING_IF_EXISTS;
73using ::fesetround _LIBCPP_USING_IF_EXISTS;
74using ::fegetenv _LIBCPP_USING_IF_EXISTS;
75using ::feholdexcept _LIBCPP_USING_IF_EXISTS;
76using ::fesetenv _LIBCPP_USING_IF_EXISTS;
77using ::feupdateenv _LIBCPP_USING_IF_EXISTS;
7878
7979_LIBCPP_END_NAMESPACE_STD
8080
81#endif // _LIBCPP_CFENV
81#endif // _LIBCPP_CFENV
lib/libcxx/include/cfloat+1-1
......@@ -76,4 +76,4 @@ Macros:
7676#pragma GCC system_header
7777#endif
7878
79#endif // _LIBCPP_CFLOAT
79#endif // _LIBCPP_CFLOAT
lib/libcxx/include/charconv+97-40
......@@ -73,11 +73,13 @@ namespace std {
7373
7474*/
7575
76#include <__config>
7776#include <__availability>
77#include <__config>
7878#include <__errc>
79#include <__utility/to_underlying.h>
7980#include <cmath> // for log2f
8081#include <cstdint>
82#include <cstdlib> // for _LIBCPP_UNREACHABLE
8183#include <cstring>
8284#include <limits>
8385#include <type_traits>
......@@ -108,6 +110,47 @@ enum class _LIBCPP_ENUM_VIS chars_format
108110 general = fixed | scientific
109111};
110112
113inline _LIBCPP_INLINE_VISIBILITY constexpr chars_format
114operator~(chars_format __x) {
115 return chars_format(~_VSTD::__to_underlying(__x));
116}
117
118inline _LIBCPP_INLINE_VISIBILITY constexpr chars_format
119operator&(chars_format __x, chars_format __y) {
120 return chars_format(_VSTD::__to_underlying(__x) &
121 _VSTD::__to_underlying(__y));
122}
123
124inline _LIBCPP_INLINE_VISIBILITY constexpr chars_format
125operator|(chars_format __x, chars_format __y) {
126 return chars_format(_VSTD::__to_underlying(__x) |
127 _VSTD::__to_underlying(__y));
128}
129
130inline _LIBCPP_INLINE_VISIBILITY constexpr chars_format
131operator^(chars_format __x, chars_format __y) {
132 return chars_format(_VSTD::__to_underlying(__x) ^
133 _VSTD::__to_underlying(__y));
134}
135
136inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 chars_format&
137operator&=(chars_format& __x, chars_format __y) {
138 __x = __x & __y;
139 return __x;
140}
141
142inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 chars_format&
143operator|=(chars_format& __x, chars_format __y) {
144 __x = __x | __y;
145 return __x;
146}
147
148inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 chars_format&
149operator^=(chars_format& __x, chars_format __y) {
150 __x = __x ^ __y;
151 return __x;
152}
153
111154struct _LIBCPP_TYPE_VIS to_chars_result
112155{
113156 char* ptr;
......@@ -288,19 +331,12 @@ __complement(_Tp __x)
288331 return _Tp(~__x + 1);
289332}
290333
291template <typename _Tp>
292inline _LIBCPP_INLINE_VISIBILITY typename make_unsigned<_Tp>::type
293__to_unsigned(_Tp __x)
294{
295 return static_cast<typename make_unsigned<_Tp>::type>(__x);
296}
297
298334template <typename _Tp>
299335_LIBCPP_AVAILABILITY_TO_CHARS
300336inline _LIBCPP_INLINE_VISIBILITY to_chars_result
301337__to_chars_itoa(char* __first, char* __last, _Tp __value, true_type)
302338{
303 auto __x = __to_unsigned(__value);
339 auto __x = __to_unsigned_like(__value);
304340 if (__value < 0 && __first != __last)
305341 {
306342 *__first++ = '-';
......@@ -348,7 +384,7 @@ inline _LIBCPP_INLINE_VISIBILITY to_chars_result
348384__to_chars_integral(char* __first, char* __last, _Tp __value, int __base,
349385 true_type)
350386{
351 auto __x = __to_unsigned(__value);
387 auto __x = __to_unsigned_like(__value);
352388 if (__value < 0 && __first != __last)
353389 {
354390 *__first++ = '-';
......@@ -358,33 +394,54 @@ __to_chars_integral(char* __first, char* __last, _Tp __value, int __base,
358394 return __to_chars_integral(__first, __last, __x, __base, false_type());
359395}
360396
397template <typename _Tp>
398_LIBCPP_AVAILABILITY_TO_CHARS _LIBCPP_INLINE_VISIBILITY int __to_chars_integral_width(_Tp __value, unsigned __base) {
399 _LIBCPP_ASSERT(__value >= 0, "The function requires a non-negative value.");
400
401 unsigned __base_2 = __base * __base;
402 unsigned __base_3 = __base_2 * __base;
403 unsigned __base_4 = __base_2 * __base_2;
404
405 int __r = 0;
406 while (true) {
407 if (__value < __base)
408 return __r + 1;
409 if (__value < __base_2)
410 return __r + 2;
411 if (__value < __base_3)
412 return __r + 3;
413 if (__value < __base_4)
414 return __r + 4;
415
416 __value /= __base_4;
417 __r += 4;
418 }
419
420 _LIBCPP_UNREACHABLE();
421}
422
361423template <typename _Tp>
362424_LIBCPP_AVAILABILITY_TO_CHARS
363425inline _LIBCPP_INLINE_VISIBILITY to_chars_result
364426__to_chars_integral(char* __first, char* __last, _Tp __value, int __base,
365427 false_type)
366428{
367 if (__base == 10)
368 return __to_chars_itoa(__first, __last, __value, false_type());
369
370 auto __p = __last;
371 while (__p != __first)
372 {
373 auto __c = __value % __base;
374 __value /= __base;
375 *--__p = "0123456789abcdefghijklmnopqrstuvwxyz"[__c];
376 if (__value == 0)
377 break;
378 }
379
380 auto __len = __last - __p;
381 if (__value != 0 || !__len)
382 return {__last, errc::value_too_large};
383 else
384 {
385 _VSTD::memmove(__first, __p, __len);
386 return {__first + __len, {}};
387 }
429 if (__base == 10)
430 return __to_chars_itoa(__first, __last, __value, false_type());
431
432 ptrdiff_t __cap = __last - __first;
433 int __n = __to_chars_integral_width(__value, __base);
434 if (__n > __cap)
435 return {__last, errc::value_too_large};
436
437 __last = __first + __n;
438 char* __p = __last;
439 do {
440 unsigned __c = __value % __base;
441 __value /= __base;
442 *--__p = "0123456789abcdefghijklmnopqrstuvwxyz"[__c];
443 } while (__value != 0);
444 return {__last, errc(0)};
388445}
389446
390447template <typename _Tp, typename enable_if<is_integral<_Tp>::value, int>::type = 0>
......@@ -410,7 +467,7 @@ inline _LIBCPP_INLINE_VISIBILITY from_chars_result
410467__sign_combinator(_It __first, _It __last, _Tp& __value, _Fn __f, _Ts... __args)
411468{
412469 using __tl = numeric_limits<_Tp>;
413 decltype(__to_unsigned(__value)) __x;
470 decltype(__to_unsigned_like(__value)) __x;
414471
415472 bool __neg = (__first != __last && *__first == '-');
416473 auto __r = __f(__neg ? __first + 1 : __first, __last, __x, __args...);
......@@ -426,7 +483,7 @@ __sign_combinator(_It __first, _It __last, _Tp& __value, _Fn __f, _Ts... __args)
426483
427484 if (__neg)
428485 {
429 if (__x <= __complement(__to_unsigned(__tl::min())))
486 if (__x <= __complement(__to_unsigned_like(__tl::min())))
430487 {
431488 __x = __complement(__x);
432489 _VSTD::memcpy(&__value, &__x, sizeof(__x));
......@@ -541,7 +598,7 @@ template <typename _Tp, typename enable_if<is_signed<_Tp>::value, int>::type = 0
541598inline _LIBCPP_INLINE_VISIBILITY from_chars_result
542599__from_chars_atoi(const char* __first, const char* __last, _Tp& __value)
543600{
544 using __t = decltype(__to_unsigned(__value));
601 using __t = decltype(__to_unsigned_like(__value));
545602 return __sign_combinator(__first, __last, __value, __from_chars_atoi<__t>);
546603}
547604
......@@ -555,13 +612,13 @@ __from_chars_integral(const char* __first, const char* __last, _Tp& __value,
555612
556613 return __subject_seq_combinator(
557614 __first, __last, __value,
558 [](const char* __p, const char* __last, _Tp& __value,
615 [](const char* __p, const char* __lastx, _Tp& __value,
559616 int __base) -> from_chars_result {
560617 using __tl = numeric_limits<_Tp>;
561618 auto __digits = __tl::digits / log2f(float(__base));
562619 _Tp __a = __in_pattern(*__p++, __base).__val, __b = 0;
563620
564 for (int __i = 1; __p != __last; ++__i, ++__p)
621 for (int __i = 1; __p != __lastx; ++__i, ++__p)
565622 {
566623 if (auto __c = __in_pattern(*__p, __base))
567624 {
......@@ -579,7 +636,7 @@ __from_chars_integral(const char* __first, const char* __last, _Tp& __value,
579636 break;
580637 }
581638
582 if (__p == __last || !__in_pattern(*__p, __base))
639 if (__p == __lastx || !__in_pattern(*__p, __base))
583640 {
584641 if (__tl::max() - __a >= __b)
585642 {
......@@ -597,7 +654,7 @@ inline _LIBCPP_INLINE_VISIBILITY from_chars_result
597654__from_chars_integral(const char* __first, const char* __last, _Tp& __value,
598655 int __base)
599656{
600 using __t = decltype(__to_unsigned(__value));
657 using __t = decltype(__to_unsigned_like(__value));
601658 return __sign_combinator(__first, __last, __value,
602659 __from_chars_integral<__t>, __base);
603660}
......@@ -617,10 +674,10 @@ from_chars(const char* __first, const char* __last, _Tp& __value, int __base)
617674 return __from_chars_integral(__first, __last, __value, __base);
618675}
619676
620#endif // _LIBCPP_CXX03_LANG
677#endif // _LIBCPP_CXX03_LANG
621678
622679_LIBCPP_END_NAMESPACE_STD
623680
624681_LIBCPP_POP_MACROS
625682
626#endif // _LIBCPP_CHARCONV
683#endif // _LIBCPP_CHARCONV
lib/libcxx/include/chrono+17-16
......@@ -823,12 +823,13 @@ constexpr chrono::year operator ""y(unsigned lo
823823} // std
824824*/
825825
826#include <__config>
827826#include <__availability>
827#include <__config>
828#include <compare>
828829#include <ctime>
829#include <type_traits>
830#include <ratio>
831830#include <limits>
831#include <ratio>
832#include <type_traits>
832833#include <version>
833834
834835#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
......@@ -1091,7 +1092,7 @@ public:
10911092 (__no_overflow<_Period2, period>::type::den == 1 &&
10921093 !treat_as_floating_point<_Rep2>::value))
10931094 >::type* = nullptr)
1094 : __rep_(_VSTD::chrono::duration_cast<duration>(__d).count()) {}
1095 : __rep_(chrono::duration_cast<duration>(__d).count()) {}
10951096
10961097 // observer
10971098
......@@ -1410,7 +1411,7 @@ inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
14101411time_point<_Clock, _ToDuration>
14111412time_point_cast(const time_point<_Clock, _Duration>& __t)
14121413{
1413 return time_point<_Clock, _ToDuration>(_VSTD::chrono::duration_cast<_ToDuration>(__t.time_since_epoch()));
1414 return time_point<_Clock, _ToDuration>(chrono::duration_cast<_ToDuration>(__t.time_since_epoch()));
14141415}
14151416
14161417#if _LIBCPP_STD_VER > 14
......@@ -1926,13 +1927,13 @@ inline constexpr weekday& weekday::operator-=(const days& __dd) noexcept
19261927
19271928class weekday_indexed {
19281929private:
1929 _VSTD::chrono::weekday __wd;
1930 chrono::weekday __wd;
19301931 unsigned char __idx;
19311932public:
19321933 weekday_indexed() = default;
1933 inline constexpr weekday_indexed(const _VSTD::chrono::weekday& __wdval, unsigned __idxval) noexcept
1934 inline constexpr weekday_indexed(const chrono::weekday& __wdval, unsigned __idxval) noexcept
19341935 : __wd{__wdval}, __idx(__idxval) {}
1935 inline constexpr _VSTD::chrono::weekday weekday() const noexcept { return __wd; }
1936 inline constexpr chrono::weekday weekday() const noexcept { return __wd; }
19361937 inline constexpr unsigned index() const noexcept { return __idx; }
19371938 inline constexpr bool ok() const noexcept { return __wd.ok() && __idx >= 1 && __idx <= 5; }
19381939};
......@@ -1948,11 +1949,11 @@ bool operator!=(const weekday_indexed& __lhs, const weekday_indexed& __rhs) noex
19481949
19491950class weekday_last {
19501951private:
1951 _VSTD::chrono::weekday __wd;
1952 chrono::weekday __wd;
19521953public:
1953 explicit constexpr weekday_last(const _VSTD::chrono::weekday& __val) noexcept
1954 explicit constexpr weekday_last(const chrono::weekday& __val) noexcept
19541955 : __wd{__val} {}
1955 constexpr _VSTD::chrono::weekday weekday() const noexcept { return __wd; }
1956 constexpr chrono::weekday weekday() const noexcept { return __wd; }
19561957 constexpr bool ok() const noexcept { return __wd.ok(); }
19571958};
19581959
......@@ -2308,8 +2309,8 @@ inline constexpr
23082309year_month_day
23092310year_month_day::__from_days(days __d) noexcept
23102311{
2311 static_assert(std::numeric_limits<unsigned>::digits >= 18, "");
2312 static_assert(std::numeric_limits<int>::digits >= 20 , "");
2312 static_assert(numeric_limits<unsigned>::digits >= 18, "");
2313 static_assert(numeric_limits<int>::digits >= 20 , "");
23132314 const int __z = __d.count() + 719468;
23142315 const int __era = (__z >= 0 ? __z : __z - 146096) / 146097;
23152316 const unsigned __doe = static_cast<unsigned>(__z - __era * 146097); // [0, 146096]
......@@ -2325,8 +2326,8 @@ year_month_day::__from_days(days __d) noexcept
23252326// https://howardhinnant.github.io/date_algorithms.html#days_from_civil
23262327inline constexpr days year_month_day::__to_days() const noexcept
23272328{
2328 static_assert(std::numeric_limits<unsigned>::digits >= 18, "");
2329 static_assert(std::numeric_limits<int>::digits >= 20 , "");
2329 static_assert(numeric_limits<unsigned>::digits >= 18, "");
2330 static_assert(numeric_limits<int>::digits >= 20 , "");
23302331
23312332 const int __yr = static_cast<int>(__y) - (__m <= February);
23322333 const unsigned __mth = static_cast<unsigned>(__m);
......@@ -2964,4 +2965,4 @@ _LIBCPP_END_NAMESPACE_FILESYSTEM
29642965
29652966_LIBCPP_POP_MACROS
29662967
2967#endif // _LIBCPP_CHRONO
2968#endif // _LIBCPP_CHRONO
lib/libcxx/include/cinttypes+8-8
......@@ -244,14 +244,14 @@ uintmax_t wcstoumax(const wchar_t* restrict nptr, wchar_t** restrict endptr, int
244244
245245_LIBCPP_BEGIN_NAMESPACE_STD
246246
247using::imaxdiv_t;
248using::imaxabs;
249using::imaxdiv;
250using::strtoimax;
251using::strtoumax;
252using::wcstoimax;
253using::wcstoumax;
247using ::imaxdiv_t _LIBCPP_USING_IF_EXISTS;
248using ::imaxabs _LIBCPP_USING_IF_EXISTS;
249using ::imaxdiv _LIBCPP_USING_IF_EXISTS;
250using ::strtoimax _LIBCPP_USING_IF_EXISTS;
251using ::strtoumax _LIBCPP_USING_IF_EXISTS;
252using ::wcstoimax _LIBCPP_USING_IF_EXISTS;
253using ::wcstoumax _LIBCPP_USING_IF_EXISTS;
254254
255255_LIBCPP_END_NAMESPACE_STD
256256
257#endif // _LIBCPP_CINTTYPES
257#endif // _LIBCPP_CINTTYPES
lib/libcxx/include/ciso646+1-1
......@@ -21,4 +21,4 @@
2121#pragma GCC system_header
2222#endif
2323
24#endif // _LIBCPP_CISO646
24#endif // _LIBCPP_CISO646
lib/libcxx/include/climits+1-1
......@@ -44,4 +44,4 @@ Macros:
4444#pragma GCC system_header
4545#endif
4646
47#endif // _LIBCPP_CLIMITS
47#endif // _LIBCPP_CLIMITS
lib/libcxx/include/clocale+4-4
......@@ -43,12 +43,12 @@ lconv* localeconv();
4343
4444_LIBCPP_BEGIN_NAMESPACE_STD
4545
46using ::lconv;
46using ::lconv _LIBCPP_USING_IF_EXISTS;
4747#ifndef _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS
48using ::setlocale;
48using ::setlocale _LIBCPP_USING_IF_EXISTS;
4949#endif
50using ::localeconv;
50using ::localeconv _LIBCPP_USING_IF_EXISTS;
5151
5252_LIBCPP_END_NAMESPACE_STD
5353
54#endif // _LIBCPP_CLOCALE
54#endif // _LIBCPP_CLOCALE
lib/libcxx/include/cmath+213-215
......@@ -318,217 +318,215 @@ _LIBCPP_PUSH_MACROS
318318
319319_LIBCPP_BEGIN_NAMESPACE_STD
320320
321using ::signbit;
322using ::fpclassify;
323using ::isfinite;
324using ::isinf;
325using ::isnan;
326using ::isnormal;
327using ::isgreater;
328using ::isgreaterequal;
329using ::isless;
330using ::islessequal;
331using ::islessgreater;
332using ::isunordered;
333using ::isunordered;
334
335using ::float_t;
336using ::double_t;
337
338#ifndef _AIX
339using ::abs;
340#endif
341
342using ::acos;
343using ::acosf;
344using ::asin;
345using ::asinf;
346using ::atan;
347using ::atanf;
348using ::atan2;
349using ::atan2f;
350using ::ceil;
351using ::ceilf;
352using ::cos;
353using ::cosf;
354using ::cosh;
355using ::coshf;
356
357using ::exp;
358using ::expf;
359
360using ::fabs;
361using ::fabsf;
362using ::floor;
363using ::floorf;
364
365using ::fmod;
366using ::fmodf;
367
368using ::frexp;
369using ::frexpf;
370using ::ldexp;
371using ::ldexpf;
372
373using ::log;
374using ::logf;
375
376using ::log10;
377using ::log10f;
378using ::modf;
379using ::modff;
380
381using ::pow;
382using ::powf;
383
384using ::sin;
385using ::sinf;
386using ::sinh;
387using ::sinhf;
388
389using ::sqrt;
390using ::sqrtf;
391using ::tan;
392using ::tanf;
393
394using ::tanh;
395using ::tanhf;
396
397using ::acosh;
398using ::acoshf;
399using ::asinh;
400using ::asinhf;
401using ::atanh;
402using ::atanhf;
403using ::cbrt;
404using ::cbrtf;
405
406using ::copysign;
407using ::copysignf;
408
409using ::erf;
410using ::erff;
411using ::erfc;
412using ::erfcf;
413using ::exp2;
414using ::exp2f;
415using ::expm1;
416using ::expm1f;
417using ::fdim;
418using ::fdimf;
419using ::fmaf;
420using ::fma;
421using ::fmax;
422using ::fmaxf;
423using ::fmin;
424using ::fminf;
425using ::hypot;
426using ::hypotf;
427using ::ilogb;
428using ::ilogbf;
429using ::lgamma;
430using ::lgammaf;
431using ::llrint;
432using ::llrintf;
433using ::llround;
434using ::llroundf;
435using ::log1p;
436using ::log1pf;
437using ::log2;
438using ::log2f;
439using ::logb;
440using ::logbf;
441using ::lrint;
442using ::lrintf;
443using ::lround;
444using ::lroundf;
445
446using ::nan;
447using ::nanf;
448
449using ::nearbyint;
450using ::nearbyintf;
451using ::nextafter;
452using ::nextafterf;
453using ::nexttoward;
454using ::nexttowardf;
455using ::remainder;
456using ::remainderf;
457using ::remquo;
458using ::remquof;
459using ::rint;
460using ::rintf;
461using ::round;
462using ::roundf;
463using ::scalbln;
464using ::scalblnf;
465using ::scalbn;
466using ::scalbnf;
467using ::tgamma;
468using ::tgammaf;
469using ::trunc;
470using ::truncf;
471
472using ::acosl;
473using ::asinl;
474using ::atanl;
475using ::atan2l;
476using ::ceill;
477using ::cosl;
478using ::coshl;
479using ::expl;
480using ::fabsl;
481using ::floorl;
482using ::fmodl;
483using ::frexpl;
484using ::ldexpl;
485using ::logl;
486using ::log10l;
487using ::modfl;
488using ::powl;
489using ::sinl;
490using ::sinhl;
491using ::sqrtl;
492using ::tanl;
493
494using ::tanhl;
495using ::acoshl;
496using ::asinhl;
497using ::atanhl;
498using ::cbrtl;
499
500using ::copysignl;
501
502using ::erfl;
503using ::erfcl;
504using ::exp2l;
505using ::expm1l;
506using ::fdiml;
507using ::fmal;
508using ::fmaxl;
509using ::fminl;
510using ::hypotl;
511using ::ilogbl;
512using ::lgammal;
513using ::llrintl;
514using ::llroundl;
515using ::log1pl;
516using ::log2l;
517using ::logbl;
518using ::lrintl;
519using ::lroundl;
520using ::nanl;
521using ::nearbyintl;
522using ::nextafterl;
523using ::nexttowardl;
524using ::remainderl;
525using ::remquol;
526using ::rintl;
527using ::roundl;
528using ::scalblnl;
529using ::scalbnl;
530using ::tgammal;
531using ::truncl;
321using ::signbit _LIBCPP_USING_IF_EXISTS;
322using ::fpclassify _LIBCPP_USING_IF_EXISTS;
323using ::isfinite _LIBCPP_USING_IF_EXISTS;
324using ::isinf _LIBCPP_USING_IF_EXISTS;
325using ::isnan _LIBCPP_USING_IF_EXISTS;
326using ::isnormal _LIBCPP_USING_IF_EXISTS;
327using ::isgreater _LIBCPP_USING_IF_EXISTS;
328using ::isgreaterequal _LIBCPP_USING_IF_EXISTS;
329using ::isless _LIBCPP_USING_IF_EXISTS;
330using ::islessequal _LIBCPP_USING_IF_EXISTS;
331using ::islessgreater _LIBCPP_USING_IF_EXISTS;
332using ::isunordered _LIBCPP_USING_IF_EXISTS;
333using ::isunordered _LIBCPP_USING_IF_EXISTS;
334
335using ::float_t _LIBCPP_USING_IF_EXISTS;
336using ::double_t _LIBCPP_USING_IF_EXISTS;
337
338using ::abs _LIBCPP_USING_IF_EXISTS;
339
340using ::acos _LIBCPP_USING_IF_EXISTS;
341using ::acosf _LIBCPP_USING_IF_EXISTS;
342using ::asin _LIBCPP_USING_IF_EXISTS;
343using ::asinf _LIBCPP_USING_IF_EXISTS;
344using ::atan _LIBCPP_USING_IF_EXISTS;
345using ::atanf _LIBCPP_USING_IF_EXISTS;
346using ::atan2 _LIBCPP_USING_IF_EXISTS;
347using ::atan2f _LIBCPP_USING_IF_EXISTS;
348using ::ceil _LIBCPP_USING_IF_EXISTS;
349using ::ceilf _LIBCPP_USING_IF_EXISTS;
350using ::cos _LIBCPP_USING_IF_EXISTS;
351using ::cosf _LIBCPP_USING_IF_EXISTS;
352using ::cosh _LIBCPP_USING_IF_EXISTS;
353using ::coshf _LIBCPP_USING_IF_EXISTS;
354
355using ::exp _LIBCPP_USING_IF_EXISTS;
356using ::expf _LIBCPP_USING_IF_EXISTS;
357
358using ::fabs _LIBCPP_USING_IF_EXISTS;
359using ::fabsf _LIBCPP_USING_IF_EXISTS;
360using ::floor _LIBCPP_USING_IF_EXISTS;
361using ::floorf _LIBCPP_USING_IF_EXISTS;
362
363using ::fmod _LIBCPP_USING_IF_EXISTS;
364using ::fmodf _LIBCPP_USING_IF_EXISTS;
365
366using ::frexp _LIBCPP_USING_IF_EXISTS;
367using ::frexpf _LIBCPP_USING_IF_EXISTS;
368using ::ldexp _LIBCPP_USING_IF_EXISTS;
369using ::ldexpf _LIBCPP_USING_IF_EXISTS;
370
371using ::log _LIBCPP_USING_IF_EXISTS;
372using ::logf _LIBCPP_USING_IF_EXISTS;
373
374using ::log10 _LIBCPP_USING_IF_EXISTS;
375using ::log10f _LIBCPP_USING_IF_EXISTS;
376using ::modf _LIBCPP_USING_IF_EXISTS;
377using ::modff _LIBCPP_USING_IF_EXISTS;
378
379using ::pow _LIBCPP_USING_IF_EXISTS;
380using ::powf _LIBCPP_USING_IF_EXISTS;
381
382using ::sin _LIBCPP_USING_IF_EXISTS;
383using ::sinf _LIBCPP_USING_IF_EXISTS;
384using ::sinh _LIBCPP_USING_IF_EXISTS;
385using ::sinhf _LIBCPP_USING_IF_EXISTS;
386
387using ::sqrt _LIBCPP_USING_IF_EXISTS;
388using ::sqrtf _LIBCPP_USING_IF_EXISTS;
389using ::tan _LIBCPP_USING_IF_EXISTS;
390using ::tanf _LIBCPP_USING_IF_EXISTS;
391
392using ::tanh _LIBCPP_USING_IF_EXISTS;
393using ::tanhf _LIBCPP_USING_IF_EXISTS;
394
395using ::acosh _LIBCPP_USING_IF_EXISTS;
396using ::acoshf _LIBCPP_USING_IF_EXISTS;
397using ::asinh _LIBCPP_USING_IF_EXISTS;
398using ::asinhf _LIBCPP_USING_IF_EXISTS;
399using ::atanh _LIBCPP_USING_IF_EXISTS;
400using ::atanhf _LIBCPP_USING_IF_EXISTS;
401using ::cbrt _LIBCPP_USING_IF_EXISTS;
402using ::cbrtf _LIBCPP_USING_IF_EXISTS;
403
404using ::copysign _LIBCPP_USING_IF_EXISTS;
405using ::copysignf _LIBCPP_USING_IF_EXISTS;
406
407using ::erf _LIBCPP_USING_IF_EXISTS;
408using ::erff _LIBCPP_USING_IF_EXISTS;
409using ::erfc _LIBCPP_USING_IF_EXISTS;
410using ::erfcf _LIBCPP_USING_IF_EXISTS;
411using ::exp2 _LIBCPP_USING_IF_EXISTS;
412using ::exp2f _LIBCPP_USING_IF_EXISTS;
413using ::expm1 _LIBCPP_USING_IF_EXISTS;
414using ::expm1f _LIBCPP_USING_IF_EXISTS;
415using ::fdim _LIBCPP_USING_IF_EXISTS;
416using ::fdimf _LIBCPP_USING_IF_EXISTS;
417using ::fmaf _LIBCPP_USING_IF_EXISTS;
418using ::fma _LIBCPP_USING_IF_EXISTS;
419using ::fmax _LIBCPP_USING_IF_EXISTS;
420using ::fmaxf _LIBCPP_USING_IF_EXISTS;
421using ::fmin _LIBCPP_USING_IF_EXISTS;
422using ::fminf _LIBCPP_USING_IF_EXISTS;
423using ::hypot _LIBCPP_USING_IF_EXISTS;
424using ::hypotf _LIBCPP_USING_IF_EXISTS;
425using ::ilogb _LIBCPP_USING_IF_EXISTS;
426using ::ilogbf _LIBCPP_USING_IF_EXISTS;
427using ::lgamma _LIBCPP_USING_IF_EXISTS;
428using ::lgammaf _LIBCPP_USING_IF_EXISTS;
429using ::llrint _LIBCPP_USING_IF_EXISTS;
430using ::llrintf _LIBCPP_USING_IF_EXISTS;
431using ::llround _LIBCPP_USING_IF_EXISTS;
432using ::llroundf _LIBCPP_USING_IF_EXISTS;
433using ::log1p _LIBCPP_USING_IF_EXISTS;
434using ::log1pf _LIBCPP_USING_IF_EXISTS;
435using ::log2 _LIBCPP_USING_IF_EXISTS;
436using ::log2f _LIBCPP_USING_IF_EXISTS;
437using ::logb _LIBCPP_USING_IF_EXISTS;
438using ::logbf _LIBCPP_USING_IF_EXISTS;
439using ::lrint _LIBCPP_USING_IF_EXISTS;
440using ::lrintf _LIBCPP_USING_IF_EXISTS;
441using ::lround _LIBCPP_USING_IF_EXISTS;
442using ::lroundf _LIBCPP_USING_IF_EXISTS;
443
444using ::nan _LIBCPP_USING_IF_EXISTS;
445using ::nanf _LIBCPP_USING_IF_EXISTS;
446
447using ::nearbyint _LIBCPP_USING_IF_EXISTS;
448using ::nearbyintf _LIBCPP_USING_IF_EXISTS;
449using ::nextafter _LIBCPP_USING_IF_EXISTS;
450using ::nextafterf _LIBCPP_USING_IF_EXISTS;
451using ::nexttoward _LIBCPP_USING_IF_EXISTS;
452using ::nexttowardf _LIBCPP_USING_IF_EXISTS;
453using ::remainder _LIBCPP_USING_IF_EXISTS;
454using ::remainderf _LIBCPP_USING_IF_EXISTS;
455using ::remquo _LIBCPP_USING_IF_EXISTS;
456using ::remquof _LIBCPP_USING_IF_EXISTS;
457using ::rint _LIBCPP_USING_IF_EXISTS;
458using ::rintf _LIBCPP_USING_IF_EXISTS;
459using ::round _LIBCPP_USING_IF_EXISTS;
460using ::roundf _LIBCPP_USING_IF_EXISTS;
461using ::scalbln _LIBCPP_USING_IF_EXISTS;
462using ::scalblnf _LIBCPP_USING_IF_EXISTS;
463using ::scalbn _LIBCPP_USING_IF_EXISTS;
464using ::scalbnf _LIBCPP_USING_IF_EXISTS;
465using ::tgamma _LIBCPP_USING_IF_EXISTS;
466using ::tgammaf _LIBCPP_USING_IF_EXISTS;
467using ::trunc _LIBCPP_USING_IF_EXISTS;
468using ::truncf _LIBCPP_USING_IF_EXISTS;
469
470using ::acosl _LIBCPP_USING_IF_EXISTS;
471using ::asinl _LIBCPP_USING_IF_EXISTS;
472using ::atanl _LIBCPP_USING_IF_EXISTS;
473using ::atan2l _LIBCPP_USING_IF_EXISTS;
474using ::ceill _LIBCPP_USING_IF_EXISTS;
475using ::cosl _LIBCPP_USING_IF_EXISTS;
476using ::coshl _LIBCPP_USING_IF_EXISTS;
477using ::expl _LIBCPP_USING_IF_EXISTS;
478using ::fabsl _LIBCPP_USING_IF_EXISTS;
479using ::floorl _LIBCPP_USING_IF_EXISTS;
480using ::fmodl _LIBCPP_USING_IF_EXISTS;
481using ::frexpl _LIBCPP_USING_IF_EXISTS;
482using ::ldexpl _LIBCPP_USING_IF_EXISTS;
483using ::logl _LIBCPP_USING_IF_EXISTS;
484using ::log10l _LIBCPP_USING_IF_EXISTS;
485using ::modfl _LIBCPP_USING_IF_EXISTS;
486using ::powl _LIBCPP_USING_IF_EXISTS;
487using ::sinl _LIBCPP_USING_IF_EXISTS;
488using ::sinhl _LIBCPP_USING_IF_EXISTS;
489using ::sqrtl _LIBCPP_USING_IF_EXISTS;
490using ::tanl _LIBCPP_USING_IF_EXISTS;
491
492using ::tanhl _LIBCPP_USING_IF_EXISTS;
493using ::acoshl _LIBCPP_USING_IF_EXISTS;
494using ::asinhl _LIBCPP_USING_IF_EXISTS;
495using ::atanhl _LIBCPP_USING_IF_EXISTS;
496using ::cbrtl _LIBCPP_USING_IF_EXISTS;
497
498using ::copysignl _LIBCPP_USING_IF_EXISTS;
499
500using ::erfl _LIBCPP_USING_IF_EXISTS;
501using ::erfcl _LIBCPP_USING_IF_EXISTS;
502using ::exp2l _LIBCPP_USING_IF_EXISTS;
503using ::expm1l _LIBCPP_USING_IF_EXISTS;
504using ::fdiml _LIBCPP_USING_IF_EXISTS;
505using ::fmal _LIBCPP_USING_IF_EXISTS;
506using ::fmaxl _LIBCPP_USING_IF_EXISTS;
507using ::fminl _LIBCPP_USING_IF_EXISTS;
508using ::hypotl _LIBCPP_USING_IF_EXISTS;
509using ::ilogbl _LIBCPP_USING_IF_EXISTS;
510using ::lgammal _LIBCPP_USING_IF_EXISTS;
511using ::llrintl _LIBCPP_USING_IF_EXISTS;
512using ::llroundl _LIBCPP_USING_IF_EXISTS;
513using ::log1pl _LIBCPP_USING_IF_EXISTS;
514using ::log2l _LIBCPP_USING_IF_EXISTS;
515using ::logbl _LIBCPP_USING_IF_EXISTS;
516using ::lrintl _LIBCPP_USING_IF_EXISTS;
517using ::lroundl _LIBCPP_USING_IF_EXISTS;
518using ::nanl _LIBCPP_USING_IF_EXISTS;
519using ::nearbyintl _LIBCPP_USING_IF_EXISTS;
520using ::nextafterl _LIBCPP_USING_IF_EXISTS;
521using ::nexttowardl _LIBCPP_USING_IF_EXISTS;
522using ::remainderl _LIBCPP_USING_IF_EXISTS;
523using ::remquol _LIBCPP_USING_IF_EXISTS;
524using ::rintl _LIBCPP_USING_IF_EXISTS;
525using ::roundl _LIBCPP_USING_IF_EXISTS;
526using ::scalblnl _LIBCPP_USING_IF_EXISTS;
527using ::scalbnl _LIBCPP_USING_IF_EXISTS;
528using ::tgammal _LIBCPP_USING_IF_EXISTS;
529using ::truncl _LIBCPP_USING_IF_EXISTS;
532530
533531#if _LIBCPP_STD_VER > 14
534532inline _LIBCPP_INLINE_VISIBILITY float hypot( float x, float y, float z ) { return sqrt(x*x + y*y + z*z); }
......@@ -623,10 +621,10 @@ _Fp __lerp(_Fp __a, _Fp __b, _Fp __t) noexcept {
623621
624622 if (__t == 1) return __b;
625623 const _Fp __x = __a + __t * (__b - __a);
626 if (__t > 1 == __b > __a)
627 return __b < __x ? __x : __b;
624 if ((__t > 1) == (__b > __a))
625 return __b < __x ? __x : __b;
628626 else
629 return __x < __b ? __x : __b;
627 return __x < __b ? __x : __b;
630628}
631629
632630constexpr float
......@@ -674,4 +672,4 @@ _LIBCPP_END_NAMESPACE_STD
674672
675673_LIBCPP_POP_MACROS
676674
677#endif // _LIBCPP_CMATH
675#endif // _LIBCPP_CMATH
lib/libcxx/include/codecvt+1-1
......@@ -570,4 +570,4 @@ public:
570570
571571_LIBCPP_END_NAMESPACE_STD
572572
573#endif // _LIBCPP_CODECVT
573#endif // _LIBCPP_CODECVT
lib/libcxx/include/compare+146-424
......@@ -15,15 +15,13 @@
1515
1616namespace std {
1717 // [cmp.categories], comparison category types
18 class weak_equality;
19 class strong_equality;
2018 class partial_ordering;
2119 class weak_ordering;
2220 class strong_ordering;
2321
2422 // named comparison functions
25 constexpr bool is_eq (weak_equality cmp) noexcept { return cmp == 0; }
26 constexpr bool is_neq (weak_equality cmp) noexcept { return cmp != 0; }
23 constexpr bool is_eq (partial_ordering cmp) noexcept { return cmp == 0; }
24 constexpr bool is_neq (partial_ordering cmp) noexcept { return cmp != 0; }
2725 constexpr bool is_lt (partial_ordering cmp) noexcept { return cmp < 0; }
2826 constexpr bool is_lteq(partial_ordering cmp) noexcept { return cmp <= 0; }
2927 constexpr bool is_gt (partial_ordering cmp) noexcept { return cmp > 0; }
......@@ -41,8 +39,6 @@ namespace std {
4139 template<class T> constexpr strong_ordering strong_order(const T& a, const T& b);
4240 template<class T> constexpr weak_ordering weak_order(const T& a, const T& b);
4341 template<class T> constexpr partial_ordering partial_order(const T& a, const T& b);
44 template<class T> constexpr strong_equality strong_equal(const T& a, const T& b);
45 template<class T> constexpr weak_equality weak_equal(const T& a, const T& b);
4642
4743 // [cmp.partialord], Class partial_ordering
4844 class partial_ordering {
......@@ -126,7 +122,6 @@ namespace std {
126122
127123#include <__config>
128124#include <type_traits>
129#include <array>
130125
131126#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
132127#pragma GCC system_header
......@@ -134,8 +129,7 @@ namespace std {
134129
135130_LIBCPP_BEGIN_NAMESPACE_STD
136131
137#if _LIBCPP_STD_VER > 17
138
132#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_SPACESHIP_OPERATOR)
139133// exposition only
140134enum class _LIBCPP_ENUM_VIS _EqResult : unsigned char {
141135 __zero = 0,
......@@ -154,138 +148,21 @@ enum class _LIBCPP_ENUM_VIS _NCmpResult : signed char {
154148 __unordered = -127
155149};
156150
151class partial_ordering;
152class weak_ordering;
153class strong_ordering;
154
155template<class _Tp, class... _Args>
156inline constexpr bool __one_of_v = (is_same_v<_Tp, _Args> || ...);
157
157158struct _CmpUnspecifiedParam {
158159 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEVAL
159160 _CmpUnspecifiedParam(int _CmpUnspecifiedParam::*) noexcept {}
160161
161 template<typename _Tp, typename = _VSTD::enable_if_t<!_VSTD::is_same_v<_Tp, int>>>
162 template<class _Tp, class = enable_if_t<!__one_of_v<_Tp, int, partial_ordering, weak_ordering, strong_ordering>>>
162163 _CmpUnspecifiedParam(_Tp) = delete;
163164};
164165
165class weak_equality {
166 _LIBCPP_INLINE_VISIBILITY
167 constexpr explicit weak_equality(_EqResult __val) noexcept : __value_(__val) {}
168
169public:
170 static const weak_equality equivalent;
171 static const weak_equality nonequivalent;
172
173 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(weak_equality __v, _CmpUnspecifiedParam) noexcept;
174 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(_CmpUnspecifiedParam, weak_equality __v) noexcept;
175 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(weak_equality __v, _CmpUnspecifiedParam) noexcept;
176 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(_CmpUnspecifiedParam, weak_equality __v) noexcept;
177
178#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
179 _LIBCPP_INLINE_VISIBILITY friend constexpr weak_equality operator<=>(weak_equality __v, _CmpUnspecifiedParam) noexcept;
180 _LIBCPP_INLINE_VISIBILITY friend constexpr weak_equality operator<=>(_CmpUnspecifiedParam, weak_equality __v) noexcept;
181#endif
182
183private:
184 _EqResult __value_;
185};
186
187_LIBCPP_INLINE_VAR constexpr weak_equality weak_equality::equivalent(_EqResult::__equiv);
188_LIBCPP_INLINE_VAR constexpr weak_equality weak_equality::nonequivalent(_EqResult::__nonequiv);
189
190_LIBCPP_INLINE_VISIBILITY
191inline constexpr bool operator==(weak_equality __v, _CmpUnspecifiedParam) noexcept {
192 return __v.__value_ == _EqResult::__zero;
193}
194
195_LIBCPP_INLINE_VISIBILITY
196inline constexpr bool operator==(_CmpUnspecifiedParam, weak_equality __v) noexcept {
197 return __v.__value_ == _EqResult::__zero;
198}
199
200_LIBCPP_INLINE_VISIBILITY
201inline constexpr bool operator!=(weak_equality __v, _CmpUnspecifiedParam) noexcept {
202 return __v.__value_ != _EqResult::__zero;
203}
204
205_LIBCPP_INLINE_VISIBILITY
206inline constexpr bool operator!=(_CmpUnspecifiedParam, weak_equality __v) noexcept {
207 return __v.__value_ != _EqResult::__zero;
208}
209
210#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
211_LIBCPP_INLINE_VISIBILITY
212inline constexpr weak_equality operator<=>(weak_equality __v, _CmpUnspecifiedParam) noexcept {
213 return __v;
214}
215
216_LIBCPP_INLINE_VISIBILITY
217inline constexpr weak_equality operator<=>(_CmpUnspecifiedParam, weak_equality __v) noexcept {
218 return __v;
219}
220#endif
221
222class strong_equality {
223 _LIBCPP_INLINE_VISIBILITY
224 explicit constexpr strong_equality(_EqResult __val) noexcept : __value_(__val) {}
225
226public:
227 static const strong_equality equal;
228 static const strong_equality nonequal;
229 static const strong_equality equivalent;
230 static const strong_equality nonequivalent;
231
232 // conversion
233 _LIBCPP_INLINE_VISIBILITY constexpr operator weak_equality() const noexcept {
234 return __value_ == _EqResult::__zero ? weak_equality::equivalent
235 : weak_equality::nonequivalent;
236 }
237
238 // comparisons
239 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(strong_equality __v, _CmpUnspecifiedParam) noexcept;
240 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(strong_equality __v, _CmpUnspecifiedParam) noexcept;
241 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(_CmpUnspecifiedParam, strong_equality __v) noexcept;
242 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(_CmpUnspecifiedParam, strong_equality __v) noexcept;
243
244#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
245 _LIBCPP_INLINE_VISIBILITY friend constexpr strong_equality operator<=>(strong_equality __v, _CmpUnspecifiedParam) noexcept;
246 _LIBCPP_INLINE_VISIBILITY friend constexpr strong_equality operator<=>(_CmpUnspecifiedParam, strong_equality __v) noexcept;
247#endif
248private:
249 _EqResult __value_;
250};
251
252_LIBCPP_INLINE_VAR constexpr strong_equality strong_equality::equal(_EqResult::__equal);
253_LIBCPP_INLINE_VAR constexpr strong_equality strong_equality::nonequal(_EqResult::__nonequal);
254_LIBCPP_INLINE_VAR constexpr strong_equality strong_equality::equivalent(_EqResult::__equiv);
255_LIBCPP_INLINE_VAR constexpr strong_equality strong_equality::nonequivalent(_EqResult::__nonequiv);
256
257_LIBCPP_INLINE_VISIBILITY
258constexpr bool operator==(strong_equality __v, _CmpUnspecifiedParam) noexcept {
259 return __v.__value_ == _EqResult::__zero;
260}
261
262_LIBCPP_INLINE_VISIBILITY
263constexpr bool operator==(_CmpUnspecifiedParam, strong_equality __v) noexcept {
264 return __v.__value_ == _EqResult::__zero;
265}
266
267_LIBCPP_INLINE_VISIBILITY
268constexpr bool operator!=(strong_equality __v, _CmpUnspecifiedParam) noexcept {
269 return __v.__value_ != _EqResult::__zero;
270}
271
272_LIBCPP_INLINE_VISIBILITY
273constexpr bool operator!=(_CmpUnspecifiedParam, strong_equality __v) noexcept {
274 return __v.__value_ != _EqResult::__zero;
275}
276
277#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
278_LIBCPP_INLINE_VISIBILITY
279constexpr strong_equality operator<=>(strong_equality __v, _CmpUnspecifiedParam) noexcept {
280 return __v;
281}
282
283_LIBCPP_INLINE_VISIBILITY
284constexpr strong_equality operator<=>(_CmpUnspecifiedParam, strong_equality __v) noexcept {
285 return __v;
286}
287#endif // _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
288
289166class partial_ordering {
290167 using _ValueT = signed char;
291168
......@@ -311,32 +188,52 @@ public:
311188 static const partial_ordering greater;
312189 static const partial_ordering unordered;
313190
314 // conversion
315 constexpr operator weak_equality() const noexcept {
316 return __value_ == 0 ? weak_equality::equivalent : weak_equality::nonequivalent;
317 }
318
319191 // comparisons
320 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
321 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
322 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (partial_ordering __v, _CmpUnspecifiedParam) noexcept;
323 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
324 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (partial_ordering __v, _CmpUnspecifiedParam) noexcept;
325 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
326 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
327 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
328 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (_CmpUnspecifiedParam, partial_ordering __v) noexcept;
329 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
330 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (_CmpUnspecifiedParam, partial_ordering __v) noexcept;
331 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
332
333#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
334192 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(partial_ordering, partial_ordering) noexcept = default;
335193
336 _LIBCPP_INLINE_VISIBILITY friend constexpr partial_ordering operator<=>(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
337 _LIBCPP_INLINE_VISIBILITY friend constexpr partial_ordering operator<=>(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
338#endif
194 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
195 return __v.__is_ordered() && __v.__value_ == 0;
196 }
197
198 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (partial_ordering __v, _CmpUnspecifiedParam) noexcept {
199 return __v.__is_ordered() && __v.__value_ < 0;
200 }
201
202 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
203 return __v.__is_ordered() && __v.__value_ <= 0;
204 }
205
206 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (partial_ordering __v, _CmpUnspecifiedParam) noexcept {
207 return __v.__is_ordered() && __v.__value_ > 0;
208 }
209
210 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
211 return __v.__is_ordered() && __v.__value_ >= 0;
212 }
339213
214 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (_CmpUnspecifiedParam, partial_ordering __v) noexcept {
215 return __v.__is_ordered() && 0 < __v.__value_;
216 }
217
218 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
219 return __v.__is_ordered() && 0 <= __v.__value_;
220 }
221
222 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (_CmpUnspecifiedParam, partial_ordering __v) noexcept {
223 return __v.__is_ordered() && 0 > __v.__value_;
224 }
225
226 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
227 return __v.__is_ordered() && 0 >= __v.__value_;
228 }
229
230 _LIBCPP_INLINE_VISIBILITY friend constexpr partial_ordering operator<=>(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
231 return __v;
232 }
233
234 _LIBCPP_INLINE_VISIBILITY friend constexpr partial_ordering operator<=>(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
235 return __v < 0 ? partial_ordering::greater : (__v > 0 ? partial_ordering::less : __v);
236 }
340237private:
341238 _ValueT __value_;
342239};
......@@ -346,68 +243,6 @@ _LIBCPP_INLINE_VAR constexpr partial_ordering partial_ordering::equivalent(_EqRe
346243_LIBCPP_INLINE_VAR constexpr partial_ordering partial_ordering::greater(_OrdResult::__greater);
347244_LIBCPP_INLINE_VAR constexpr partial_ordering partial_ordering::unordered(_NCmpResult ::__unordered);
348245
349_LIBCPP_INLINE_VISIBILITY
350constexpr bool operator==(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
351 return __v.__is_ordered() && __v.__value_ == 0;
352}
353_LIBCPP_INLINE_VISIBILITY
354constexpr bool operator< (partial_ordering __v, _CmpUnspecifiedParam) noexcept {
355 return __v.__is_ordered() && __v.__value_ < 0;
356}
357_LIBCPP_INLINE_VISIBILITY
358constexpr bool operator<=(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
359 return __v.__is_ordered() && __v.__value_ <= 0;
360}
361_LIBCPP_INLINE_VISIBILITY
362constexpr bool operator> (partial_ordering __v, _CmpUnspecifiedParam) noexcept {
363 return __v.__is_ordered() && __v.__value_ > 0;
364}
365_LIBCPP_INLINE_VISIBILITY
366constexpr bool operator>=(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
367 return __v.__is_ordered() && __v.__value_ >= 0;
368}
369
370_LIBCPP_INLINE_VISIBILITY
371constexpr bool operator==(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
372 return __v.__is_ordered() && 0 == __v.__value_;
373}
374_LIBCPP_INLINE_VISIBILITY
375constexpr bool operator< (_CmpUnspecifiedParam, partial_ordering __v) noexcept {
376 return __v.__is_ordered() && 0 < __v.__value_;
377}
378_LIBCPP_INLINE_VISIBILITY
379constexpr bool operator<=(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
380 return __v.__is_ordered() && 0 <= __v.__value_;
381}
382_LIBCPP_INLINE_VISIBILITY
383constexpr bool operator> (_CmpUnspecifiedParam, partial_ordering __v) noexcept {
384 return __v.__is_ordered() && 0 > __v.__value_;
385}
386_LIBCPP_INLINE_VISIBILITY
387constexpr bool operator>=(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
388 return __v.__is_ordered() && 0 >= __v.__value_;
389}
390
391_LIBCPP_INLINE_VISIBILITY
392constexpr bool operator!=(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
393 return !__v.__is_ordered() || __v.__value_ != 0;
394}
395_LIBCPP_INLINE_VISIBILITY
396constexpr bool operator!=(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
397 return !__v.__is_ordered() || __v.__value_ != 0;
398}
399
400#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
401_LIBCPP_INLINE_VISIBILITY
402constexpr partial_ordering operator<=>(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
403 return __v;
404}
405_LIBCPP_INLINE_VISIBILITY
406constexpr partial_ordering operator<=>(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
407 return __v < 0 ? partial_ordering::greater : (__v > 0 ? partial_ordering::less : __v);
408}
409#endif // _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
410
411246class weak_ordering {
412247 using _ValueT = signed char;
413248
......@@ -421,13 +256,6 @@ public:
421256 static const weak_ordering equivalent;
422257 static const weak_ordering greater;
423258
424 // conversions
425 _LIBCPP_INLINE_VISIBILITY
426 constexpr operator weak_equality() const noexcept {
427 return __value_ == 0 ? weak_equality::equivalent
428 : weak_equality::nonequivalent;
429 }
430
431259 _LIBCPP_INLINE_VISIBILITY
432260 constexpr operator partial_ordering() const noexcept {
433261 return __value_ == 0 ? partial_ordering::equivalent
......@@ -435,25 +263,51 @@ public:
435263 }
436264
437265 // comparisons
438 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(weak_ordering __v, _CmpUnspecifiedParam) noexcept;
439 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(weak_ordering __v, _CmpUnspecifiedParam) noexcept;
440 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (weak_ordering __v, _CmpUnspecifiedParam) noexcept;
441 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(weak_ordering __v, _CmpUnspecifiedParam) noexcept;
442 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (weak_ordering __v, _CmpUnspecifiedParam) noexcept;
443 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(weak_ordering __v, _CmpUnspecifiedParam) noexcept;
444 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(_CmpUnspecifiedParam, weak_ordering __v) noexcept;
445 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(_CmpUnspecifiedParam, weak_ordering __v) noexcept;
446 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (_CmpUnspecifiedParam, weak_ordering __v) noexcept;
447 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(_CmpUnspecifiedParam, weak_ordering __v) noexcept;
448 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (_CmpUnspecifiedParam, weak_ordering __v) noexcept;
449 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(_CmpUnspecifiedParam, weak_ordering __v) noexcept;
450
451#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
452266 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(weak_ordering, weak_ordering) noexcept = default;
453267
454 _LIBCPP_INLINE_VISIBILITY friend constexpr weak_ordering operator<=>(weak_ordering __v, _CmpUnspecifiedParam) noexcept;
455 _LIBCPP_INLINE_VISIBILITY friend constexpr weak_ordering operator<=>(_CmpUnspecifiedParam, weak_ordering __v) noexcept;
456#endif
268 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
269 return __v.__value_ == 0;
270 }
271
272 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (weak_ordering __v, _CmpUnspecifiedParam) noexcept {
273 return __v.__value_ < 0;
274 }
275
276 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
277 return __v.__value_ <= 0;
278 }
279
280 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (weak_ordering __v, _CmpUnspecifiedParam) noexcept {
281 return __v.__value_ > 0;
282 }
283
284 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
285 return __v.__value_ >= 0;
286 }
287
288 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (_CmpUnspecifiedParam, weak_ordering __v) noexcept {
289 return 0 < __v.__value_;
290 }
291
292 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
293 return 0 <= __v.__value_;
294 }
295
296 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (_CmpUnspecifiedParam, weak_ordering __v) noexcept {
297 return 0 > __v.__value_;
298 }
299
300 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
301 return 0 >= __v.__value_;
302 }
303
304 _LIBCPP_INLINE_VISIBILITY friend constexpr weak_ordering operator<=>(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
305 return __v;
306 }
307
308 _LIBCPP_INLINE_VISIBILITY friend constexpr weak_ordering operator<=>(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
309 return __v < 0 ? weak_ordering::greater : (__v > 0 ? weak_ordering::less : __v);
310 }
457311
458312private:
459313 _ValueT __value_;
......@@ -462,67 +316,6 @@ private:
462316_LIBCPP_INLINE_VAR constexpr weak_ordering weak_ordering::less(_OrdResult::__less);
463317_LIBCPP_INLINE_VAR constexpr weak_ordering weak_ordering::equivalent(_EqResult::__equiv);
464318_LIBCPP_INLINE_VAR constexpr weak_ordering weak_ordering::greater(_OrdResult::__greater);
465
466_LIBCPP_INLINE_VISIBILITY
467constexpr bool operator==(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
468 return __v.__value_ == 0;
469}
470_LIBCPP_INLINE_VISIBILITY
471constexpr bool operator!=(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
472 return __v.__value_ != 0;
473}
474_LIBCPP_INLINE_VISIBILITY
475constexpr bool operator< (weak_ordering __v, _CmpUnspecifiedParam) noexcept {
476 return __v.__value_ < 0;
477}
478_LIBCPP_INLINE_VISIBILITY
479constexpr bool operator<=(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
480 return __v.__value_ <= 0;
481}
482_LIBCPP_INLINE_VISIBILITY
483constexpr bool operator> (weak_ordering __v, _CmpUnspecifiedParam) noexcept {
484 return __v.__value_ > 0;
485}
486_LIBCPP_INLINE_VISIBILITY
487constexpr bool operator>=(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
488 return __v.__value_ >= 0;
489}
490_LIBCPP_INLINE_VISIBILITY
491constexpr bool operator==(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
492 return 0 == __v.__value_;
493}
494_LIBCPP_INLINE_VISIBILITY
495constexpr bool operator!=(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
496 return 0 != __v.__value_;
497}
498_LIBCPP_INLINE_VISIBILITY
499constexpr bool operator< (_CmpUnspecifiedParam, weak_ordering __v) noexcept {
500 return 0 < __v.__value_;
501}
502_LIBCPP_INLINE_VISIBILITY
503constexpr bool operator<=(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
504 return 0 <= __v.__value_;
505}
506_LIBCPP_INLINE_VISIBILITY
507constexpr bool operator> (_CmpUnspecifiedParam, weak_ordering __v) noexcept {
508 return 0 > __v.__value_;
509}
510_LIBCPP_INLINE_VISIBILITY
511constexpr bool operator>=(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
512 return 0 >= __v.__value_;
513}
514
515#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
516_LIBCPP_INLINE_VISIBILITY
517constexpr weak_ordering operator<=>(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
518 return __v;
519}
520_LIBCPP_INLINE_VISIBILITY
521constexpr weak_ordering operator<=>(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
522 return __v < 0 ? weak_ordering::greater : (__v > 0 ? weak_ordering::less : __v);
523}
524#endif // _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
525
526319class strong_ordering {
527320 using _ValueT = signed char;
528321
......@@ -538,18 +331,6 @@ public:
538331 static const strong_ordering greater;
539332
540333 // conversions
541 _LIBCPP_INLINE_VISIBILITY
542 constexpr operator weak_equality() const noexcept {
543 return __value_ == 0 ? weak_equality::equivalent
544 : weak_equality::nonequivalent;
545 }
546
547 _LIBCPP_INLINE_VISIBILITY
548 constexpr operator strong_equality() const noexcept {
549 return __value_ == 0 ? strong_equality::equal
550 : strong_equality::nonequal;
551 }
552
553334 _LIBCPP_INLINE_VISIBILITY
554335 constexpr operator partial_ordering() const noexcept {
555336 return __value_ == 0 ? partial_ordering::equivalent
......@@ -563,25 +344,51 @@ public:
563344 }
564345
565346 // comparisons
566 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(strong_ordering __v, _CmpUnspecifiedParam) noexcept;
567 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(strong_ordering __v, _CmpUnspecifiedParam) noexcept;
568 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (strong_ordering __v, _CmpUnspecifiedParam) noexcept;
569 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(strong_ordering __v, _CmpUnspecifiedParam) noexcept;
570 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (strong_ordering __v, _CmpUnspecifiedParam) noexcept;
571 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(strong_ordering __v, _CmpUnspecifiedParam) noexcept;
572 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(_CmpUnspecifiedParam, strong_ordering __v) noexcept;
573 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(_CmpUnspecifiedParam, strong_ordering __v) noexcept;
574 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (_CmpUnspecifiedParam, strong_ordering __v) noexcept;
575 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(_CmpUnspecifiedParam, strong_ordering __v) noexcept;
576 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (_CmpUnspecifiedParam, strong_ordering __v) noexcept;
577 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(_CmpUnspecifiedParam, strong_ordering __v) noexcept;
578
579#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
580347 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(strong_ordering, strong_ordering) noexcept = default;
581348
582 _LIBCPP_INLINE_VISIBILITY friend constexpr strong_ordering operator<=>(strong_ordering __v, _CmpUnspecifiedParam) noexcept;
583 _LIBCPP_INLINE_VISIBILITY friend constexpr strong_ordering operator<=>(_CmpUnspecifiedParam, strong_ordering __v) noexcept;
584#endif
349 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
350 return __v.__value_ == 0;
351 }
352
353 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (strong_ordering __v, _CmpUnspecifiedParam) noexcept {
354 return __v.__value_ < 0;
355 }
356
357 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
358 return __v.__value_ <= 0;
359 }
360
361 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (strong_ordering __v, _CmpUnspecifiedParam) noexcept {
362 return __v.__value_ > 0;
363 }
364
365 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
366 return __v.__value_ >= 0;
367 }
368
369 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (_CmpUnspecifiedParam, strong_ordering __v) noexcept {
370 return 0 < __v.__value_;
371 }
372
373 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
374 return 0 <= __v.__value_;
375 }
376
377 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (_CmpUnspecifiedParam, strong_ordering __v) noexcept {
378 return 0 > __v.__value_;
379 }
380
381 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
382 return 0 >= __v.__value_;
383 }
384
385 _LIBCPP_INLINE_VISIBILITY friend constexpr strong_ordering operator<=>(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
386 return __v;
387 }
388
389 _LIBCPP_INLINE_VISIBILITY friend constexpr strong_ordering operator<=>(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
390 return __v < 0 ? strong_ordering::greater : (__v > 0 ? strong_ordering::less : __v);
391 }
585392
586393private:
587394 _ValueT __value_;
......@@ -592,73 +399,7 @@ _LIBCPP_INLINE_VAR constexpr strong_ordering strong_ordering::equal(_EqResult::_
592399_LIBCPP_INLINE_VAR constexpr strong_ordering strong_ordering::equivalent(_EqResult::__equiv);
593400_LIBCPP_INLINE_VAR constexpr strong_ordering strong_ordering::greater(_OrdResult::__greater);
594401
595_LIBCPP_INLINE_VISIBILITY
596constexpr bool operator==(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
597 return __v.__value_ == 0;
598}
599_LIBCPP_INLINE_VISIBILITY
600constexpr bool operator!=(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
601 return __v.__value_ != 0;
602}
603_LIBCPP_INLINE_VISIBILITY
604constexpr bool operator< (strong_ordering __v, _CmpUnspecifiedParam) noexcept {
605 return __v.__value_ < 0;
606}
607_LIBCPP_INLINE_VISIBILITY
608constexpr bool operator<=(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
609 return __v.__value_ <= 0;
610}
611_LIBCPP_INLINE_VISIBILITY
612constexpr bool operator> (strong_ordering __v, _CmpUnspecifiedParam) noexcept {
613 return __v.__value_ > 0;
614}
615_LIBCPP_INLINE_VISIBILITY
616constexpr bool operator>=(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
617 return __v.__value_ >= 0;
618}
619_LIBCPP_INLINE_VISIBILITY
620constexpr bool operator==(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
621 return 0 == __v.__value_;
622}
623_LIBCPP_INLINE_VISIBILITY
624constexpr bool operator!=(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
625 return 0 != __v.__value_;
626}
627_LIBCPP_INLINE_VISIBILITY
628constexpr bool operator< (_CmpUnspecifiedParam, strong_ordering __v) noexcept {
629 return 0 < __v.__value_;
630}
631_LIBCPP_INLINE_VISIBILITY
632constexpr bool operator<=(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
633 return 0 <= __v.__value_;
634}
635_LIBCPP_INLINE_VISIBILITY
636constexpr bool operator> (_CmpUnspecifiedParam, strong_ordering __v) noexcept {
637 return 0 > __v.__value_;
638}
639_LIBCPP_INLINE_VISIBILITY
640constexpr bool operator>=(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
641 return 0 >= __v.__value_;
642}
643
644#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
645_LIBCPP_INLINE_VISIBILITY
646constexpr strong_ordering operator<=>(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
647 return __v;
648}
649_LIBCPP_INLINE_VISIBILITY
650constexpr strong_ordering operator<=>(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
651 return __v < 0 ? strong_ordering::greater : (__v > 0 ? strong_ordering::less : __v);
652}
653#endif // _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
654
655402// named comparison functions
656_LIBCPP_INLINE_VISIBILITY
657constexpr bool is_eq(weak_equality __cmp) noexcept { return __cmp == 0; }
658
659_LIBCPP_INLINE_VISIBILITY
660constexpr bool is_neq(weak_equality __cmp) noexcept { return __cmp != 0; }
661
662403_LIBCPP_INLINE_VISIBILITY
663404constexpr bool is_lt(partial_ordering __cmp) noexcept { return __cmp < 0; }
664405
......@@ -675,8 +416,6 @@ namespace __comp_detail {
675416
676417enum _ClassifyCompCategory : unsigned{
677418 _None,
678 _WeakEq,
679 _StrongEq,
680419 _PartialOrd,
681420 _WeakOrd,
682421 _StrongOrd,
......@@ -686,10 +425,6 @@ enum _ClassifyCompCategory : unsigned{
686425template <class _Tp>
687426_LIBCPP_INLINE_VISIBILITY
688427constexpr _ClassifyCompCategory __type_to_enum() noexcept {
689 if (is_same_v<_Tp, weak_equality>)
690 return _WeakEq;
691 if (is_same_v<_Tp, strong_equality>)
692 return _StrongEq;
693428 if (is_same_v<_Tp, partial_ordering>)
694429 return _PartialOrd;
695430 if (is_same_v<_Tp, weak_ordering>)
......@@ -701,18 +436,12 @@ constexpr _ClassifyCompCategory __type_to_enum() noexcept {
701436
702437template <size_t _Size>
703438constexpr _ClassifyCompCategory
704__compute_comp_type(array<_ClassifyCompCategory, _Size> __types) {
705 array<int, _CCC_Size> __seen = {};
439__compute_comp_type(const _ClassifyCompCategory (&__types)[_Size]) {
440 int __seen[_CCC_Size] = {};
706441 for (auto __type : __types)
707442 ++__seen[__type];
708443 if (__seen[_None])
709444 return _None;
710 if (__seen[_WeakEq])
711 return _WeakEq;
712 if (__seen[_StrongEq] && (__seen[_PartialOrd] || __seen[_WeakOrd]))
713 return _WeakEq;
714 if (__seen[_StrongEq])
715 return _StrongEq;
716445 if (__seen[_PartialOrd])
717446 return _PartialOrd;
718447 if (__seen[_WeakOrd])
......@@ -720,18 +449,13 @@ __compute_comp_type(array<_ClassifyCompCategory, _Size> __types) {
720449 return _StrongOrd;
721450}
722451
723template <class ..._Ts>
452template <class ..._Ts, bool _False = false>
724453constexpr auto __get_comp_type() {
725454 using _CCC = _ClassifyCompCategory;
726 constexpr array<_CCC, sizeof...(_Ts)> __type_kinds{{__comp_detail::__type_to_enum<_Ts>()...}};
727 constexpr _CCC _Cat = sizeof...(_Ts) == 0 ? _StrongOrd
728 : __compute_comp_type(__type_kinds);
455 constexpr _CCC __type_kinds[] = {_StrongOrd, __type_to_enum<_Ts>()...};
456 constexpr _CCC _Cat = __compute_comp_type(__type_kinds);
729457 if constexpr (_Cat == _None)
730458 return void();
731 else if constexpr (_Cat == _WeakEq)
732 return weak_equality::equivalent;
733 else if constexpr (_Cat == _StrongEq)
734 return strong_equality::equivalent;
735459 else if constexpr (_Cat == _PartialOrd)
736460 return partial_ordering::equivalent;
737461 else if constexpr (_Cat == _WeakOrd)
......@@ -739,7 +463,7 @@ constexpr auto __get_comp_type() {
739463 else if constexpr (_Cat == _StrongOrd)
740464 return strong_ordering::equivalent;
741465 else
742 static_assert(_Cat != _Cat, "unhandled case");
466 static_assert(_False, "unhandled case");
743467}
744468} // namespace __comp_detail
745469
......@@ -757,10 +481,8 @@ using common_comparison_category_t = typename common_comparison_category<_Ts...>
757481template<class _Tp> constexpr strong_ordering strong_order(const _Tp& __lhs, const _Tp& __rhs);
758482template<class _Tp> constexpr weak_ordering weak_order(const _Tp& __lhs, const _Tp& __rhs);
759483template<class _Tp> constexpr partial_ordering partial_order(const _Tp& __lhs, const _Tp& __rhs);
760template<class _Tp> constexpr strong_equality strong_equal(const _Tp& __lhs, const _Tp& __rhs);
761template<class _Tp> constexpr weak_equality weak_equal(const _Tp& __lhs, const _Tp& __rhs);
762484
763#endif // _LIBCPP_STD_VER > 17
485#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_SPACESHIP_OPERATOR)
764486
765487_LIBCPP_END_NAMESPACE_STD
766488
lib/libcxx/include/complex+3-3
......@@ -232,10 +232,10 @@ template<class T> complex<T> tanh (const complex<T>&);
232232*/
233233
234234#include <__config>
235#include <type_traits>
236#include <stdexcept>
237235#include <cmath>
238236#include <iosfwd>
237#include <stdexcept>
238#include <type_traits>
239239#include <version>
240240
241241#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
......@@ -1490,4 +1490,4 @@ inline namespace literals
14901490
14911491_LIBCPP_END_NAMESPACE_STD
14921492
1493#endif // _LIBCPP_COMPLEX
1493#endif // _LIBCPP_COMPLEX
lib/libcxx/include/complex.h+2-2
......@@ -31,6 +31,6 @@
3131
3232#include_next <complex.h>
3333
34#endif // __cplusplus
34#endif // __cplusplus
3535
36#endif // _LIBCPP_COMPLEX_H
36#endif // _LIBCPP_COMPLEX_H
lib/libcxx/include/concepts+294-10
......@@ -67,9 +67,9 @@ namespace std {
6767 template<class T, class... Args>
6868 concept constructible_from = see below;
6969
70 // [concept.defaultconstructible], concept default_constructible
70 // [concept.default.init], concept default_initializable
7171 template<class T>
72 concept default_constructible = see below;
72 concept default_initializable = see below;
7373
7474 // [concept.moveconstructible], concept move_constructible
7575 template<class T>
......@@ -79,11 +79,6 @@ namespace std {
7979 template<class T>
8080 concept copy_constructible = see below;
8181
82 // [concepts.compare], comparison concepts
83 // [concept.boolean], concept boolean
84 template<class B>
85 concept boolean = see below;
86
8782 // [concept.equalitycomparable], concept equality_comparable
8883 template<class T>
8984 concept equality_comparable = see below;
......@@ -135,7 +130,10 @@ namespace std {
135130*/
136131
137132#include <__config>
133#include <__functional/invoke.h>
134#include <__functional_base>
138135#include <type_traits>
136#include <utility>
139137#include <version>
140138
141139#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
......@@ -147,7 +145,7 @@ _LIBCPP_PUSH_MACROS
147145
148146_LIBCPP_BEGIN_NAMESPACE_STD
149147
150#if _LIBCPP_STD_VER > 17 && defined(__cpp_concepts) && __cpp_concepts >= 201811L
148#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
151149
152150// [concept.same]
153151
......@@ -157,12 +155,298 @@ concept __same_as_impl = _VSTD::_IsSame<_Tp, _Up>::value;
157155template<class _Tp, class _Up>
158156concept same_as = __same_as_impl<_Tp, _Up> && __same_as_impl<_Up, _Tp>;
159157
158// [concept.derived]
159template<class _Dp, class _Bp>
160concept derived_from =
161 is_base_of_v<_Bp, _Dp> &&
162 is_convertible_v<const volatile _Dp*, const volatile _Bp*>;
163
164// [concept.convertible]
165template<class _From, class _To>
166concept convertible_to =
167 is_convertible_v<_From, _To> &&
168 requires(add_rvalue_reference_t<_From> (&__f)()) {
169 static_cast<_To>(__f());
170 };
171
172// [concept.commonref]
173template<class _Tp, class _Up>
174concept common_reference_with =
175 same_as<common_reference_t<_Tp, _Up>, common_reference_t<_Up, _Tp>> &&
176 convertible_to<_Tp, common_reference_t<_Tp, _Up>> &&
177 convertible_to<_Up, common_reference_t<_Tp, _Up>>;
178
179// [concept.common]
180template<class _Tp, class _Up>
181concept common_with =
182 same_as<common_type_t<_Tp, _Up>, common_type_t<_Up, _Tp>> &&
183 requires {
184 static_cast<common_type_t<_Tp, _Up>>(declval<_Tp>());
185 static_cast<common_type_t<_Tp, _Up>>(declval<_Up>());
186 } &&
187 common_reference_with<
188 add_lvalue_reference_t<const _Tp>,
189 add_lvalue_reference_t<const _Up>> &&
190 common_reference_with<
191 add_lvalue_reference_t<common_type_t<_Tp, _Up>>,
192 common_reference_t<
193 add_lvalue_reference_t<const _Tp>,
194 add_lvalue_reference_t<const _Up>>>;
195
196// [concepts.arithmetic], arithmetic concepts
197template<class _Tp>
198concept integral = is_integral_v<_Tp>;
199
200template<class _Tp>
201concept signed_integral = integral<_Tp> && is_signed_v<_Tp>;
202
203template<class _Tp>
204concept unsigned_integral = integral<_Tp> && !signed_integral<_Tp>;
205
206template<class _Tp>
207concept floating_point = is_floating_point_v<_Tp>;
208
209// [concept.assignable]
210template<class _Lhs, class _Rhs>
211concept assignable_from =
212 is_lvalue_reference_v<_Lhs> &&
213 common_reference_with<__make_const_lvalue_ref<_Lhs>, __make_const_lvalue_ref<_Rhs>> &&
214 requires (_Lhs __lhs, _Rhs&& __rhs) {
215 { __lhs = _VSTD::forward<_Rhs>(__rhs) } -> same_as<_Lhs>;
216 };
217
160218// [concept.destructible]
161219
162220template<class _Tp>
163concept destructible = _VSTD::is_nothrow_destructible_v<_Tp>;
221concept destructible = is_nothrow_destructible_v<_Tp>;
222
223// [concept.constructible]
224template<class _Tp, class... _Args>
225concept constructible_from =
226 destructible<_Tp> && is_constructible_v<_Tp, _Args...>;
227
228// [concept.default.init]
229
230template<class _Tp>
231concept __default_initializable = requires { ::new _Tp; };
232
233template<class _Tp>
234concept default_initializable = constructible_from<_Tp> &&
235 requires { _Tp{}; } && __default_initializable<_Tp>;
236
237// [concept.moveconstructible]
238template<class _Tp>
239concept move_constructible =
240 constructible_from<_Tp, _Tp> && convertible_to<_Tp, _Tp>;
241
242// [concept.copyconstructible]
243template<class _Tp>
244concept copy_constructible =
245 move_constructible<_Tp> &&
246 constructible_from<_Tp, _Tp&> && convertible_to<_Tp&, _Tp> &&
247 constructible_from<_Tp, const _Tp&> && convertible_to<const _Tp&, _Tp> &&
248 constructible_from<_Tp, const _Tp> && convertible_to<const _Tp, _Tp>;
249
250// Whether a type is a class type or enumeration type according to the Core wording.
251template<class _Tp>
252concept __class_or_enum = is_class_v<_Tp> || is_union_v<_Tp> || is_enum_v<_Tp>;
253
254// [concept.swappable]
255namespace ranges::__swap {
256 // Deleted to inhibit ADL
257 template<class _Tp>
258 void swap(_Tp&, _Tp&) = delete;
259
260
261 // [1]
262 template<class _Tp, class _Up>
263 concept __unqualified_swappable_with =
264 (__class_or_enum<remove_cvref_t<_Tp>> || __class_or_enum<remove_cvref_t<_Up>>) &&
265 requires(_Tp&& __t, _Up&& __u) {
266 swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u));
267 };
268
269 struct __fn;
270
271 template<class _Tp, class _Up, size_t _Size>
272 concept __swappable_arrays =
273 !__unqualified_swappable_with<_Tp(&)[_Size], _Up(&)[_Size]> &&
274 extent_v<_Tp> == extent_v<_Up> &&
275 requires(_Tp(& __t)[_Size], _Up(& __u)[_Size], const __fn& __swap) {
276 __swap(__t[0], __u[0]);
277 };
278
279 template<class _Tp>
280 concept __exchangeable =
281 !__unqualified_swappable_with<_Tp&, _Tp&> &&
282 move_constructible<_Tp> &&
283 assignable_from<_Tp&, _Tp>;
284
285 struct __fn {
286 // 2.1 `S` is `(void)swap(E1, E2)`* if `E1` or `E2` has class or enumeration type and...
287 // *The name `swap` is used here unqualified.
288 template<class _Tp, class _Up>
289 requires __unqualified_swappable_with<_Tp, _Up>
290 constexpr void operator()(_Tp&& __t, _Up&& __u) const
291 noexcept(noexcept(swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))))
292 {
293 swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u));
294 }
295
296 // 2.2 Otherwise, if `E1` and `E2` are lvalues of array types with equal extent and...
297 template<class _Tp, class _Up, size_t _Size>
298 requires __swappable_arrays<_Tp, _Up, _Size>
299 constexpr void operator()(_Tp(& __t)[_Size], _Up(& __u)[_Size]) const
300 noexcept(noexcept((*this)(*__t, *__u)))
301 {
302 // TODO(cjdb): replace with `ranges::swap_ranges`.
303 for (size_t __i = 0; __i < _Size; ++__i) {
304 (*this)(__t[__i], __u[__i]);
305 }
306 }
307
308 // 2.3 Otherwise, if `E1` and `E2` are lvalues of the same type `T` that models...
309 template<__exchangeable _Tp>
310 constexpr void operator()(_Tp& __x, _Tp& __y) const
311 noexcept(is_nothrow_move_constructible_v<_Tp> && is_nothrow_move_assignable_v<_Tp>)
312 {
313 __y = _VSTD::exchange(__x, _VSTD::move(__y));
314 }
315 };
316} // namespace ranges::__swap
317
318namespace ranges::inline __cpo {
319 inline constexpr auto swap = __swap::__fn{};
320} // namespace ranges::__cpo
321
322template<class _Tp>
323concept swappable = requires(_Tp& __a, _Tp& __b) { ranges::swap(__a, __b); };
324
325template<class _Tp, class _Up>
326concept swappable_with =
327 common_reference_with<_Tp, _Up> &&
328 requires(_Tp&& __t, _Up&& __u) {
329 ranges::swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Tp>(__t));
330 ranges::swap(_VSTD::forward<_Up>(__u), _VSTD::forward<_Up>(__u));
331 ranges::swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u));
332 ranges::swap(_VSTD::forward<_Up>(__u), _VSTD::forward<_Tp>(__t));
333 };
334
335// [concept.booleantestable]
336template<class _Tp>
337concept __boolean_testable_impl = convertible_to<_Tp, bool>;
338
339template<class _Tp>
340concept __boolean_testable = __boolean_testable_impl<_Tp> && requires(_Tp&& __t) {
341 { !std::forward<_Tp>(__t) } -> __boolean_testable_impl;
342};
343
344// [concept.equalitycomparable]
345template<class _Tp, class _Up>
346concept __weakly_equality_comparable_with =
347 requires(__make_const_lvalue_ref<_Tp> __t, __make_const_lvalue_ref<_Up> __u) {
348 { __t == __u } -> __boolean_testable;
349 { __t != __u } -> __boolean_testable;
350 { __u == __t } -> __boolean_testable;
351 { __u != __t } -> __boolean_testable;
352 };
353
354template<class _Tp>
355concept equality_comparable = __weakly_equality_comparable_with<_Tp, _Tp>;
356
357template<class _Tp, class _Up>
358concept equality_comparable_with =
359 equality_comparable<_Tp> && equality_comparable<_Up> &&
360 common_reference_with<__make_const_lvalue_ref<_Tp>, __make_const_lvalue_ref<_Up>> &&
361 equality_comparable<
362 common_reference_t<
363 __make_const_lvalue_ref<_Tp>,
364 __make_const_lvalue_ref<_Up>>> &&
365 __weakly_equality_comparable_with<_Tp, _Up>;
366
367// [concept.totallyordered]
368
369template<class _Tp, class _Up>
370concept __partially_ordered_with =
371 requires(__make_const_lvalue_ref<_Tp> __t, __make_const_lvalue_ref<_Up> __u) {
372 { __t < __u } -> __boolean_testable;
373 { __t > __u } -> __boolean_testable;
374 { __t <= __u } -> __boolean_testable;
375 { __t >= __u } -> __boolean_testable;
376 { __u < __t } -> __boolean_testable;
377 { __u > __t } -> __boolean_testable;
378 { __u <= __t } -> __boolean_testable;
379 { __u >= __t } -> __boolean_testable;
380 };
381
382template<class _Tp>
383concept totally_ordered = equality_comparable<_Tp> && __partially_ordered_with<_Tp, _Tp>;
384
385template<class _Tp, class _Up>
386concept totally_ordered_with =
387 totally_ordered<_Tp> && totally_ordered<_Up> &&
388 equality_comparable_with<_Tp, _Up> &&
389 totally_ordered<
390 common_reference_t<
391 __make_const_lvalue_ref<_Tp>,
392 __make_const_lvalue_ref<_Up>>> &&
393 __partially_ordered_with<_Tp, _Up>;
394
395// [concepts.object]
396template<class _Tp>
397concept movable =
398 is_object_v<_Tp> &&
399 move_constructible<_Tp> &&
400 assignable_from<_Tp&, _Tp> &&
401 swappable<_Tp>;
402
403template<class _Tp>
404concept copyable =
405 copy_constructible<_Tp> &&
406 movable<_Tp> &&
407 assignable_from<_Tp&, _Tp&> &&
408 assignable_from<_Tp&, const _Tp&> &&
409 assignable_from<_Tp&, const _Tp>;
410
411template<class _Tp>
412concept semiregular = copyable<_Tp> && default_initializable<_Tp>;
413
414template<class _Tp>
415concept regular = semiregular<_Tp> && equality_comparable<_Tp>;
416
417// [concept.invocable]
418template<class _Fn, class... _Args>
419concept invocable = requires(_Fn&& __fn, _Args&&... __args) {
420 _VSTD::invoke(_VSTD::forward<_Fn>(__fn), _VSTD::forward<_Args>(__args)...); // not required to be equality preserving
421};
422
423// [concept.regular.invocable]
424template<class _Fn, class... _Args>
425concept regular_invocable = invocable<_Fn, _Args...>;
426
427// [concept.predicate]
428template<class _Fn, class... _Args>
429concept predicate =
430 regular_invocable<_Fn, _Args...> && __boolean_testable<invoke_result_t<_Fn, _Args...>>;
431
432// [concept.relation]
433template<class _Rp, class _Tp, class _Up>
434concept relation =
435 predicate<_Rp, _Tp, _Tp> && predicate<_Rp, _Up, _Up> &&
436 predicate<_Rp, _Tp, _Up> && predicate<_Rp, _Up, _Tp>;
437
438// [concept.equiv]
439template<class _Rp, class _Tp, class _Up>
440concept equivalence_relation = relation<_Rp, _Tp, _Up>;
441
442// [concept.strictweakorder]
443template<class _Rp, class _Tp, class _Up>
444concept strict_weak_order = relation<_Rp, _Tp, _Up>;
445
446template<class _Tp, class _Up>
447concept __different_from = !same_as<remove_cvref_t<_Tp>, remove_cvref_t<_Up>>;
164448
165#endif //_LIBCPP_STD_VER > 17 && defined(__cpp_concepts) && __cpp_concepts >= 201811L
449#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
166450
167451_LIBCPP_END_NAMESPACE_STD
168452
lib/libcxx/include/condition_variable+1-1
......@@ -265,4 +265,4 @@ _LIBCPP_END_NAMESPACE_STD
265265
266266#endif // !_LIBCPP_HAS_NO_THREADS
267267
268#endif // _LIBCPP_CONDITION_VARIABLE
268#endif // _LIBCPP_CONDITION_VARIABLE
lib/libcxx/include/csetjmp+3-3
......@@ -39,9 +39,9 @@ void longjmp(jmp_buf env, int val);
3939
4040_LIBCPP_BEGIN_NAMESPACE_STD
4141
42using ::jmp_buf;
43using ::longjmp;
42using ::jmp_buf _LIBCPP_USING_IF_EXISTS;
43using ::longjmp _LIBCPP_USING_IF_EXISTS;
4444
4545_LIBCPP_END_NAMESPACE_STD
4646
47#endif // _LIBCPP_CSETJMP
47#endif // _LIBCPP_CSETJMP
lib/libcxx/include/csignal+4-4
......@@ -48,10 +48,10 @@ int raise(int sig);
4848
4949_LIBCPP_BEGIN_NAMESPACE_STD
5050
51using ::sig_atomic_t;
52using ::signal;
53using ::raise;
51using ::sig_atomic_t _LIBCPP_USING_IF_EXISTS;
52using ::signal _LIBCPP_USING_IF_EXISTS;
53using ::raise _LIBCPP_USING_IF_EXISTS;
5454
5555_LIBCPP_END_NAMESPACE_STD
5656
57#endif // _LIBCPP_CSIGNAL
57#endif // _LIBCPP_CSIGNAL
lib/libcxx/include/cstdarg+2-2
......@@ -40,8 +40,8 @@ Types:
4040
4141_LIBCPP_BEGIN_NAMESPACE_STD
4242
43using ::va_list;
43using ::va_list _LIBCPP_USING_IF_EXISTS;
4444
4545_LIBCPP_END_NAMESPACE_STD
4646
47#endif // _LIBCPP_CSTDARG
47#endif // _LIBCPP_CSTDARG
lib/libcxx/include/cstdbool+1-1
......@@ -28,4 +28,4 @@ Macros:
2828#undef __bool_true_false_are_defined
2929#define __bool_true_false_are_defined 1
3030
31#endif // _LIBCPP_CSTDBOOL
31#endif // _LIBCPP_CSTDBOOL
lib/libcxx/include/cstddef+7-7
......@@ -46,11 +46,11 @@ Types:
4646
4747_LIBCPP_BEGIN_NAMESPACE_STD
4848
49using ::ptrdiff_t;
50using ::size_t;
49using ::ptrdiff_t _LIBCPP_USING_IF_EXISTS;
50using ::size_t _LIBCPP_USING_IF_EXISTS;
5151
5252#if !defined(_LIBCPP_CXX03_LANG)
53using ::max_align_t;
53using ::max_align_t _LIBCPP_USING_IF_EXISTS;
5454#endif
5555
5656template <class _Tp> struct __libcpp_is_integral { enum { value = 0 }; };
......@@ -59,13 +59,13 @@ template <> struct __libcpp_is_integral<char> { enum { va
5959template <> struct __libcpp_is_integral<signed char> { enum { value = 1 }; };
6060template <> struct __libcpp_is_integral<unsigned char> { enum { value = 1 }; };
6161template <> struct __libcpp_is_integral<wchar_t> { enum { value = 1 }; };
62#ifndef _LIBCPP_NO_HAS_CHAR8_T
62#ifndef _LIBCPP_HAS_NO_CHAR8_T
6363template <> struct __libcpp_is_integral<char8_t> { enum { value = 1 }; };
6464#endif
6565#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
6666template <> struct __libcpp_is_integral<char16_t> { enum { value = 1 }; };
6767template <> struct __libcpp_is_integral<char32_t> { enum { value = 1 }; };
68#endif // _LIBCPP_HAS_NO_UNICODE_CHARS
68#endif // _LIBCPP_HAS_NO_UNICODE_CHARS
6969template <> struct __libcpp_is_integral<short> { enum { value = 1 }; };
7070template <> struct __libcpp_is_integral<unsigned short> { enum { value = 1 }; };
7171template <> struct __libcpp_is_integral<int> { enum { value = 1 }; };
......@@ -152,10 +152,10 @@ template <class _Integer>
152152 { return static_cast<byte>(static_cast<unsigned char>(static_cast<unsigned int>(__lhs) >> __shift)); }
153153
154154template <class _Integer, class = _EnableByteOverload<_Integer> >
155 constexpr _Integer
155 _LIBCPP_NODISCARD_EXT constexpr _Integer
156156 to_integer(byte __b) noexcept { return static_cast<_Integer>(__b); }
157157}
158158
159159#endif
160160
161#endif // _LIBCPP_CSTDDEF
161#endif // _LIBCPP_CSTDDEF
lib/libcxx/include/cstdint+36-36
......@@ -149,42 +149,42 @@ Types:
149149
150150_LIBCPP_BEGIN_NAMESPACE_STD
151151
152using::int8_t;
153using::int16_t;
154using::int32_t;
155using::int64_t;
156
157using::uint8_t;
158using::uint16_t;
159using::uint32_t;
160using::uint64_t;
161
162using::int_least8_t;
163using::int_least16_t;
164using::int_least32_t;
165using::int_least64_t;
166
167using::uint_least8_t;
168using::uint_least16_t;
169using::uint_least32_t;
170using::uint_least64_t;
171
172using::int_fast8_t;
173using::int_fast16_t;
174using::int_fast32_t;
175using::int_fast64_t;
176
177using::uint_fast8_t;
178using::uint_fast16_t;
179using::uint_fast32_t;
180using::uint_fast64_t;
181
182using::intptr_t;
183using::uintptr_t;
184
185using::intmax_t;
186using::uintmax_t;
152using ::int8_t _LIBCPP_USING_IF_EXISTS;
153using ::int16_t _LIBCPP_USING_IF_EXISTS;
154using ::int32_t _LIBCPP_USING_IF_EXISTS;
155using ::int64_t _LIBCPP_USING_IF_EXISTS;
156
157using ::uint8_t _LIBCPP_USING_IF_EXISTS;
158using ::uint16_t _LIBCPP_USING_IF_EXISTS;
159using ::uint32_t _LIBCPP_USING_IF_EXISTS;
160using ::uint64_t _LIBCPP_USING_IF_EXISTS;
161
162using ::int_least8_t _LIBCPP_USING_IF_EXISTS;
163using ::int_least16_t _LIBCPP_USING_IF_EXISTS;
164using ::int_least32_t _LIBCPP_USING_IF_EXISTS;
165using ::int_least64_t _LIBCPP_USING_IF_EXISTS;
166
167using ::uint_least8_t _LIBCPP_USING_IF_EXISTS;
168using ::uint_least16_t _LIBCPP_USING_IF_EXISTS;
169using ::uint_least32_t _LIBCPP_USING_IF_EXISTS;
170using ::uint_least64_t _LIBCPP_USING_IF_EXISTS;
171
172using ::int_fast8_t _LIBCPP_USING_IF_EXISTS;
173using ::int_fast16_t _LIBCPP_USING_IF_EXISTS;
174using ::int_fast32_t _LIBCPP_USING_IF_EXISTS;
175using ::int_fast64_t _LIBCPP_USING_IF_EXISTS;
176
177using ::uint_fast8_t _LIBCPP_USING_IF_EXISTS;
178using ::uint_fast16_t _LIBCPP_USING_IF_EXISTS;
179using ::uint_fast32_t _LIBCPP_USING_IF_EXISTS;
180using ::uint_fast64_t _LIBCPP_USING_IF_EXISTS;
181
182using ::intptr_t _LIBCPP_USING_IF_EXISTS;
183using ::uintptr_t _LIBCPP_USING_IF_EXISTS;
184
185using ::intmax_t _LIBCPP_USING_IF_EXISTS;
186using ::uintmax_t _LIBCPP_USING_IF_EXISTS;
187187
188188_LIBCPP_END_NAMESPACE_STD
189189
190#endif // _LIBCPP_CSTDINT
190#endif // _LIBCPP_CSTDINT
lib/libcxx/include/cstdio+51-51
......@@ -104,72 +104,72 @@ void perror(const char* s);
104104
105105_LIBCPP_BEGIN_NAMESPACE_STD
106106
107using ::FILE;
108using ::fpos_t;
109using ::size_t;
110
111using ::fclose;
112using ::fflush;
113using ::setbuf;
114using ::setvbuf;
115using ::fprintf;
116using ::fscanf;
117using ::snprintf;
118using ::sprintf;
119using ::sscanf;
120using ::vfprintf;
121using ::vfscanf;
122using ::vsscanf;
123using ::vsnprintf;
124using ::vsprintf;
125using ::fgetc;
126using ::fgets;
127using ::fputc;
128using ::fputs;
129using ::getc;
130using ::putc;
131using ::ungetc;
132using ::fread;
133using ::fwrite;
107using ::FILE _LIBCPP_USING_IF_EXISTS;
108using ::fpos_t _LIBCPP_USING_IF_EXISTS;
109using ::size_t _LIBCPP_USING_IF_EXISTS;
110
111using ::fclose _LIBCPP_USING_IF_EXISTS;
112using ::fflush _LIBCPP_USING_IF_EXISTS;
113using ::setbuf _LIBCPP_USING_IF_EXISTS;
114using ::setvbuf _LIBCPP_USING_IF_EXISTS;
115using ::fprintf _LIBCPP_USING_IF_EXISTS;
116using ::fscanf _LIBCPP_USING_IF_EXISTS;
117using ::snprintf _LIBCPP_USING_IF_EXISTS;
118using ::sprintf _LIBCPP_USING_IF_EXISTS;
119using ::sscanf _LIBCPP_USING_IF_EXISTS;
120using ::vfprintf _LIBCPP_USING_IF_EXISTS;
121using ::vfscanf _LIBCPP_USING_IF_EXISTS;
122using ::vsscanf _LIBCPP_USING_IF_EXISTS;
123using ::vsnprintf _LIBCPP_USING_IF_EXISTS;
124using ::vsprintf _LIBCPP_USING_IF_EXISTS;
125using ::fgetc _LIBCPP_USING_IF_EXISTS;
126using ::fgets _LIBCPP_USING_IF_EXISTS;
127using ::fputc _LIBCPP_USING_IF_EXISTS;
128using ::fputs _LIBCPP_USING_IF_EXISTS;
129using ::getc _LIBCPP_USING_IF_EXISTS;
130using ::putc _LIBCPP_USING_IF_EXISTS;
131using ::ungetc _LIBCPP_USING_IF_EXISTS;
132using ::fread _LIBCPP_USING_IF_EXISTS;
133using ::fwrite _LIBCPP_USING_IF_EXISTS;
134134#ifndef _LIBCPP_HAS_NO_FGETPOS_FSETPOS
135using ::fgetpos;
135using ::fgetpos _LIBCPP_USING_IF_EXISTS;
136136#endif
137using ::fseek;
137using ::fseek _LIBCPP_USING_IF_EXISTS;
138138#ifndef _LIBCPP_HAS_NO_FGETPOS_FSETPOS
139using ::fsetpos;
139using ::fsetpos _LIBCPP_USING_IF_EXISTS;
140140#endif
141using ::ftell;
142using ::rewind;
143using ::clearerr;
144using ::feof;
145using ::ferror;
146using ::perror;
141using ::ftell _LIBCPP_USING_IF_EXISTS;
142using ::rewind _LIBCPP_USING_IF_EXISTS;
143using ::clearerr _LIBCPP_USING_IF_EXISTS;
144using ::feof _LIBCPP_USING_IF_EXISTS;
145using ::ferror _LIBCPP_USING_IF_EXISTS;
146using ::perror _LIBCPP_USING_IF_EXISTS;
147147
148148#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
149using ::fopen;
150using ::freopen;
151using ::remove;
152using ::rename;
153using ::tmpfile;
154using ::tmpnam;
149using ::fopen _LIBCPP_USING_IF_EXISTS;
150using ::freopen _LIBCPP_USING_IF_EXISTS;
151using ::remove _LIBCPP_USING_IF_EXISTS;
152using ::rename _LIBCPP_USING_IF_EXISTS;
153using ::tmpfile _LIBCPP_USING_IF_EXISTS;
154using ::tmpnam _LIBCPP_USING_IF_EXISTS;
155155#endif
156156
157157#ifndef _LIBCPP_HAS_NO_STDIN
158using ::getchar;
158using ::getchar _LIBCPP_USING_IF_EXISTS;
159159#if _LIBCPP_STD_VER <= 11 && !defined(_LIBCPP_C_HAS_NO_GETS)
160using ::gets;
160using ::gets _LIBCPP_USING_IF_EXISTS;
161161#endif
162using ::scanf;
163using ::vscanf;
162using ::scanf _LIBCPP_USING_IF_EXISTS;
163using ::vscanf _LIBCPP_USING_IF_EXISTS;
164164#endif
165165
166166#ifndef _LIBCPP_HAS_NO_STDOUT
167using ::printf;
168using ::putchar;
169using ::puts;
170using ::vprintf;
167using ::printf _LIBCPP_USING_IF_EXISTS;
168using ::putchar _LIBCPP_USING_IF_EXISTS;
169using ::puts _LIBCPP_USING_IF_EXISTS;
170using ::vprintf _LIBCPP_USING_IF_EXISTS;
171171#endif
172172
173173_LIBCPP_END_NAMESPACE_STD
174174
175#endif // _LIBCPP_CSTDIO
175#endif // _LIBCPP_CSTDIO
lib/libcxx/include/cstdlib+44-44
......@@ -96,68 +96,68 @@ void *aligned_alloc(size_t alignment, size_t size); // C11
9696
9797_LIBCPP_BEGIN_NAMESPACE_STD
9898
99using ::size_t;
100using ::div_t;
101using ::ldiv_t;
99using ::size_t _LIBCPP_USING_IF_EXISTS;
100using ::div_t _LIBCPP_USING_IF_EXISTS;
101using ::ldiv_t _LIBCPP_USING_IF_EXISTS;
102102#ifndef _LIBCPP_HAS_NO_LONG_LONG
103using ::lldiv_t;
103using ::lldiv_t _LIBCPP_USING_IF_EXISTS;
104104#endif // _LIBCPP_HAS_NO_LONG_LONG
105using ::atof;
106using ::atoi;
107using ::atol;
105using ::atof _LIBCPP_USING_IF_EXISTS;
106using ::atoi _LIBCPP_USING_IF_EXISTS;
107using ::atol _LIBCPP_USING_IF_EXISTS;
108108#ifndef _LIBCPP_HAS_NO_LONG_LONG
109using ::atoll;
109using ::atoll _LIBCPP_USING_IF_EXISTS;
110110#endif // _LIBCPP_HAS_NO_LONG_LONG
111using ::strtod;
112using ::strtof;
113using ::strtold;
114using ::strtol;
111using ::strtod _LIBCPP_USING_IF_EXISTS;
112using ::strtof _LIBCPP_USING_IF_EXISTS;
113using ::strtold _LIBCPP_USING_IF_EXISTS;
114using ::strtol _LIBCPP_USING_IF_EXISTS;
115115#ifndef _LIBCPP_HAS_NO_LONG_LONG
116using ::strtoll;
116using ::strtoll _LIBCPP_USING_IF_EXISTS;
117117#endif // _LIBCPP_HAS_NO_LONG_LONG
118using ::strtoul;
118using ::strtoul _LIBCPP_USING_IF_EXISTS;
119119#ifndef _LIBCPP_HAS_NO_LONG_LONG
120using ::strtoull;
120using ::strtoull _LIBCPP_USING_IF_EXISTS;
121121#endif // _LIBCPP_HAS_NO_LONG_LONG
122using ::rand;
123using ::srand;
124using ::calloc;
125using ::free;
126using ::malloc;
127using ::realloc;
128using ::abort;
129using ::atexit;
130using ::exit;
131using ::_Exit;
122using ::rand _LIBCPP_USING_IF_EXISTS;
123using ::srand _LIBCPP_USING_IF_EXISTS;
124using ::calloc _LIBCPP_USING_IF_EXISTS;
125using ::free _LIBCPP_USING_IF_EXISTS;
126using ::malloc _LIBCPP_USING_IF_EXISTS;
127using ::realloc _LIBCPP_USING_IF_EXISTS;
128using ::abort _LIBCPP_USING_IF_EXISTS;
129using ::atexit _LIBCPP_USING_IF_EXISTS;
130using ::exit _LIBCPP_USING_IF_EXISTS;
131using ::_Exit _LIBCPP_USING_IF_EXISTS;
132132#ifndef _LIBCPP_WINDOWS_STORE_APP
133using ::getenv;
134using ::system;
133using ::getenv _LIBCPP_USING_IF_EXISTS;
134using ::system _LIBCPP_USING_IF_EXISTS;
135135#endif
136using ::bsearch;
137using ::qsort;
138using ::abs;
139using ::labs;
136using ::bsearch _LIBCPP_USING_IF_EXISTS;
137using ::qsort _LIBCPP_USING_IF_EXISTS;
138using ::abs _LIBCPP_USING_IF_EXISTS;
139using ::labs _LIBCPP_USING_IF_EXISTS;
140140#ifndef _LIBCPP_HAS_NO_LONG_LONG
141using ::llabs;
141using ::llabs _LIBCPP_USING_IF_EXISTS;
142142#endif // _LIBCPP_HAS_NO_LONG_LONG
143using ::div;
144using ::ldiv;
143using ::div _LIBCPP_USING_IF_EXISTS;
144using ::ldiv _LIBCPP_USING_IF_EXISTS;
145145#ifndef _LIBCPP_HAS_NO_LONG_LONG
146using ::lldiv;
146using ::lldiv _LIBCPP_USING_IF_EXISTS;
147147#endif // _LIBCPP_HAS_NO_LONG_LONG
148using ::mblen;
149using ::mbtowc;
150using ::wctomb;
151using ::mbstowcs;
152using ::wcstombs;
148using ::mblen _LIBCPP_USING_IF_EXISTS;
149using ::mbtowc _LIBCPP_USING_IF_EXISTS;
150using ::wctomb _LIBCPP_USING_IF_EXISTS;
151using ::mbstowcs _LIBCPP_USING_IF_EXISTS;
152using ::wcstombs _LIBCPP_USING_IF_EXISTS;
153153#if !defined(_LIBCPP_CXX03_LANG) && defined(_LIBCPP_HAS_QUICK_EXIT)
154using ::at_quick_exit;
155using ::quick_exit;
154using ::at_quick_exit _LIBCPP_USING_IF_EXISTS;
155using ::quick_exit _LIBCPP_USING_IF_EXISTS;
156156#endif
157157#if _LIBCPP_STD_VER > 14 && defined(_LIBCPP_HAS_ALIGNED_ALLOC)
158using ::aligned_alloc;
158using ::aligned_alloc _LIBCPP_USING_IF_EXISTS;
159159#endif
160160
161161_LIBCPP_END_NAMESPACE_STD
162162
163#endif // _LIBCPP_CSTDLIB
163#endif // _LIBCPP_CSTDLIB
lib/libcxx/include/cstring+24-24
......@@ -65,32 +65,32 @@ size_t strlen(const char* s);
6565
6666_LIBCPP_BEGIN_NAMESPACE_STD
6767
68using ::size_t;
69using ::memcpy;
70using ::memmove;
71using ::strcpy;
72using ::strncpy;
73using ::strcat;
74using ::strncat;
75using ::memcmp;
76using ::strcmp;
77using ::strncmp;
78using ::strcoll;
79using ::strxfrm;
80using ::memchr;
81using ::strchr;
82using ::strcspn;
83using ::strpbrk;
84using ::strrchr;
85using ::strspn;
86using ::strstr;
68using ::size_t _LIBCPP_USING_IF_EXISTS;
69using ::memcpy _LIBCPP_USING_IF_EXISTS;
70using ::memmove _LIBCPP_USING_IF_EXISTS;
71using ::strcpy _LIBCPP_USING_IF_EXISTS;
72using ::strncpy _LIBCPP_USING_IF_EXISTS;
73using ::strcat _LIBCPP_USING_IF_EXISTS;
74using ::strncat _LIBCPP_USING_IF_EXISTS;
75using ::memcmp _LIBCPP_USING_IF_EXISTS;
76using ::strcmp _LIBCPP_USING_IF_EXISTS;
77using ::strncmp _LIBCPP_USING_IF_EXISTS;
78using ::strcoll _LIBCPP_USING_IF_EXISTS;
79using ::strxfrm _LIBCPP_USING_IF_EXISTS;
80using ::memchr _LIBCPP_USING_IF_EXISTS;
81using ::strchr _LIBCPP_USING_IF_EXISTS;
82using ::strcspn _LIBCPP_USING_IF_EXISTS;
83using ::strpbrk _LIBCPP_USING_IF_EXISTS;
84using ::strrchr _LIBCPP_USING_IF_EXISTS;
85using ::strspn _LIBCPP_USING_IF_EXISTS;
86using ::strstr _LIBCPP_USING_IF_EXISTS;
8787#ifndef _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS
88using ::strtok;
88using ::strtok _LIBCPP_USING_IF_EXISTS;
8989#endif
90using ::memset;
91using ::strerror;
92using ::strlen;
90using ::memset _LIBCPP_USING_IF_EXISTS;
91using ::strerror _LIBCPP_USING_IF_EXISTS;
92using ::strlen _LIBCPP_USING_IF_EXISTS;
9393
9494_LIBCPP_END_NAMESPACE_STD
9595
96#endif // _LIBCPP_CSTRING
96#endif // _LIBCPP_CSTRING
lib/libcxx/include/ctgmath+1-1
......@@ -25,4 +25,4 @@
2525#pragma GCC system_header
2626#endif
2727
28#endif // _LIBCPP_CTGMATH
28#endif // _LIBCPP_CTGMATH
lib/libcxx/include/ctime+16-16
......@@ -68,28 +68,28 @@ int timespec_get( struct timespec *ts, int base); // C++17
6868
6969_LIBCPP_BEGIN_NAMESPACE_STD
7070
71using ::clock_t;
72using ::size_t;
73using ::time_t;
74using ::tm;
71using ::clock_t _LIBCPP_USING_IF_EXISTS;
72using ::size_t _LIBCPP_USING_IF_EXISTS;
73using ::time_t _LIBCPP_USING_IF_EXISTS;
74using ::tm _LIBCPP_USING_IF_EXISTS;
7575#if _LIBCPP_STD_VER > 14 && defined(_LIBCPP_HAS_TIMESPEC_GET)
76using ::timespec;
76using ::timespec _LIBCPP_USING_IF_EXISTS;
7777#endif
78using ::clock;
79using ::difftime;
80using ::mktime;
81using ::time;
78using ::clock _LIBCPP_USING_IF_EXISTS;
79using ::difftime _LIBCPP_USING_IF_EXISTS;
80using ::mktime _LIBCPP_USING_IF_EXISTS;
81using ::time _LIBCPP_USING_IF_EXISTS;
8282#ifndef _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS
83using ::asctime;
84using ::ctime;
85using ::gmtime;
86using ::localtime;
83using ::asctime _LIBCPP_USING_IF_EXISTS;
84using ::ctime _LIBCPP_USING_IF_EXISTS;
85using ::gmtime _LIBCPP_USING_IF_EXISTS;
86using ::localtime _LIBCPP_USING_IF_EXISTS;
8787#endif
88using ::strftime;
88using ::strftime _LIBCPP_USING_IF_EXISTS;
8989#if _LIBCPP_STD_VER > 14 && defined(_LIBCPP_HAS_TIMESPEC_GET) && !defined(_LIBCPP_HAS_TIMESPEC_GET_NOT_ACTUALLY_PROVIDED)
90using ::timespec_get;
90using ::timespec_get _LIBCPP_USING_IF_EXISTS;
9191#endif
9292
9393_LIBCPP_END_NAMESPACE_STD
9494
95#endif // _LIBCPP_CTIME
95#endif // _LIBCPP_CTIME
lib/libcxx/include/ctype.h+1-1
......@@ -56,4 +56,4 @@ int toupper(int c);
5656
5757#endif
5858
59#endif // _LIBCPP_CTYPE_H
59#endif // _LIBCPP_CTYPE_H
lib/libcxx/include/cwchar+65-65
......@@ -112,81 +112,81 @@ size_t wcsrtombs(char* restrict dst, const wchar_t** restrict src, size_t len,
112112
113113_LIBCPP_BEGIN_NAMESPACE_STD
114114
115using ::mbstate_t;
116using ::size_t;
117using ::tm;
118using ::wint_t;
119using ::FILE;
120using ::fwprintf;
121using ::fwscanf;
122using ::swprintf;
123using ::vfwprintf;
124using ::vswprintf;
125using ::swscanf;
126using ::vfwscanf;
127using ::vswscanf;
128using ::fgetwc;
129using ::fgetws;
130using ::fputwc;
131using ::fputws;
132using ::fwide;
133using ::getwc;
134using ::putwc;
135using ::ungetwc;
136using ::wcstod;
137using ::wcstof;
138using ::wcstold;
139using ::wcstol;
115using ::mbstate_t _LIBCPP_USING_IF_EXISTS;
116using ::size_t _LIBCPP_USING_IF_EXISTS;
117using ::tm _LIBCPP_USING_IF_EXISTS;
118using ::wint_t _LIBCPP_USING_IF_EXISTS;
119using ::FILE _LIBCPP_USING_IF_EXISTS;
120using ::fwprintf _LIBCPP_USING_IF_EXISTS;
121using ::fwscanf _LIBCPP_USING_IF_EXISTS;
122using ::swprintf _LIBCPP_USING_IF_EXISTS;
123using ::vfwprintf _LIBCPP_USING_IF_EXISTS;
124using ::vswprintf _LIBCPP_USING_IF_EXISTS;
125using ::swscanf _LIBCPP_USING_IF_EXISTS;
126using ::vfwscanf _LIBCPP_USING_IF_EXISTS;
127using ::vswscanf _LIBCPP_USING_IF_EXISTS;
128using ::fgetwc _LIBCPP_USING_IF_EXISTS;
129using ::fgetws _LIBCPP_USING_IF_EXISTS;
130using ::fputwc _LIBCPP_USING_IF_EXISTS;
131using ::fputws _LIBCPP_USING_IF_EXISTS;
132using ::fwide _LIBCPP_USING_IF_EXISTS;
133using ::getwc _LIBCPP_USING_IF_EXISTS;
134using ::putwc _LIBCPP_USING_IF_EXISTS;
135using ::ungetwc _LIBCPP_USING_IF_EXISTS;
136using ::wcstod _LIBCPP_USING_IF_EXISTS;
137using ::wcstof _LIBCPP_USING_IF_EXISTS;
138using ::wcstold _LIBCPP_USING_IF_EXISTS;
139using ::wcstol _LIBCPP_USING_IF_EXISTS;
140140#ifndef _LIBCPP_HAS_NO_LONG_LONG
141using ::wcstoll;
141using ::wcstoll _LIBCPP_USING_IF_EXISTS;
142142#endif // _LIBCPP_HAS_NO_LONG_LONG
143using ::wcstoul;
143using ::wcstoul _LIBCPP_USING_IF_EXISTS;
144144#ifndef _LIBCPP_HAS_NO_LONG_LONG
145using ::wcstoull;
145using ::wcstoull _LIBCPP_USING_IF_EXISTS;
146146#endif // _LIBCPP_HAS_NO_LONG_LONG
147using ::wcscpy;
148using ::wcsncpy;
149using ::wcscat;
150using ::wcsncat;
151using ::wcscmp;
152using ::wcscoll;
153using ::wcsncmp;
154using ::wcsxfrm;
155using ::wcschr;
156using ::wcspbrk;
157using ::wcsrchr;
158using ::wcsstr;
159using ::wmemchr;
160using ::wcscspn;
161using ::wcslen;
162using ::wcsspn;
163using ::wcstok;
164using ::wmemcmp;
165using ::wmemcpy;
166using ::wmemmove;
167using ::wmemset;
168using ::wcsftime;
169using ::btowc;
170using ::wctob;
171using ::mbsinit;
172using ::mbrlen;
173using ::mbrtowc;
174using ::wcrtomb;
175using ::mbsrtowcs;
176using ::wcsrtombs;
147using ::wcscpy _LIBCPP_USING_IF_EXISTS;
148using ::wcsncpy _LIBCPP_USING_IF_EXISTS;
149using ::wcscat _LIBCPP_USING_IF_EXISTS;
150using ::wcsncat _LIBCPP_USING_IF_EXISTS;
151using ::wcscmp _LIBCPP_USING_IF_EXISTS;
152using ::wcscoll _LIBCPP_USING_IF_EXISTS;
153using ::wcsncmp _LIBCPP_USING_IF_EXISTS;
154using ::wcsxfrm _LIBCPP_USING_IF_EXISTS;
155using ::wcschr _LIBCPP_USING_IF_EXISTS;
156using ::wcspbrk _LIBCPP_USING_IF_EXISTS;
157using ::wcsrchr _LIBCPP_USING_IF_EXISTS;
158using ::wcsstr _LIBCPP_USING_IF_EXISTS;
159using ::wmemchr _LIBCPP_USING_IF_EXISTS;
160using ::wcscspn _LIBCPP_USING_IF_EXISTS;
161using ::wcslen _LIBCPP_USING_IF_EXISTS;
162using ::wcsspn _LIBCPP_USING_IF_EXISTS;
163using ::wcstok _LIBCPP_USING_IF_EXISTS;
164using ::wmemcmp _LIBCPP_USING_IF_EXISTS;
165using ::wmemcpy _LIBCPP_USING_IF_EXISTS;
166using ::wmemmove _LIBCPP_USING_IF_EXISTS;
167using ::wmemset _LIBCPP_USING_IF_EXISTS;
168using ::wcsftime _LIBCPP_USING_IF_EXISTS;
169using ::btowc _LIBCPP_USING_IF_EXISTS;
170using ::wctob _LIBCPP_USING_IF_EXISTS;
171using ::mbsinit _LIBCPP_USING_IF_EXISTS;
172using ::mbrlen _LIBCPP_USING_IF_EXISTS;
173using ::mbrtowc _LIBCPP_USING_IF_EXISTS;
174using ::wcrtomb _LIBCPP_USING_IF_EXISTS;
175using ::mbsrtowcs _LIBCPP_USING_IF_EXISTS;
176using ::wcsrtombs _LIBCPP_USING_IF_EXISTS;
177177
178178#ifndef _LIBCPP_HAS_NO_STDIN
179using ::getwchar;
180using ::vwscanf;
181using ::wscanf;
179using ::getwchar _LIBCPP_USING_IF_EXISTS;
180using ::vwscanf _LIBCPP_USING_IF_EXISTS;
181using ::wscanf _LIBCPP_USING_IF_EXISTS;
182182#endif
183183
184184#ifndef _LIBCPP_HAS_NO_STDOUT
185using ::putwchar;
186using ::vwprintf;
187using ::wprintf;
185using ::putwchar _LIBCPP_USING_IF_EXISTS;
186using ::vwprintf _LIBCPP_USING_IF_EXISTS;
187using ::wprintf _LIBCPP_USING_IF_EXISTS;
188188#endif
189189
190190_LIBCPP_END_NAMESPACE_STD
191191
192#endif // _LIBCPP_CWCHAR
192#endif // _LIBCPP_CWCHAR
lib/libcxx/include/cwctype+22-22
......@@ -59,28 +59,28 @@ wctrans_t wctrans(const char* property);
5959
6060_LIBCPP_BEGIN_NAMESPACE_STD
6161
62using ::wint_t;
63using ::wctrans_t;
64using ::wctype_t;
65using ::iswalnum;
66using ::iswalpha;
67using ::iswblank;
68using ::iswcntrl;
69using ::iswdigit;
70using ::iswgraph;
71using ::iswlower;
72using ::iswprint;
73using ::iswpunct;
74using ::iswspace;
75using ::iswupper;
76using ::iswxdigit;
77using ::iswctype;
78using ::wctype;
79using ::towlower;
80using ::towupper;
81using ::towctrans;
82using ::wctrans;
62using ::wint_t _LIBCPP_USING_IF_EXISTS;
63using ::wctrans_t _LIBCPP_USING_IF_EXISTS;
64using ::wctype_t _LIBCPP_USING_IF_EXISTS;
65using ::iswalnum _LIBCPP_USING_IF_EXISTS;
66using ::iswalpha _LIBCPP_USING_IF_EXISTS;
67using ::iswblank _LIBCPP_USING_IF_EXISTS;
68using ::iswcntrl _LIBCPP_USING_IF_EXISTS;
69using ::iswdigit _LIBCPP_USING_IF_EXISTS;
70using ::iswgraph _LIBCPP_USING_IF_EXISTS;
71using ::iswlower _LIBCPP_USING_IF_EXISTS;
72using ::iswprint _LIBCPP_USING_IF_EXISTS;
73using ::iswpunct _LIBCPP_USING_IF_EXISTS;
74using ::iswspace _LIBCPP_USING_IF_EXISTS;
75using ::iswupper _LIBCPP_USING_IF_EXISTS;
76using ::iswxdigit _LIBCPP_USING_IF_EXISTS;
77using ::iswctype _LIBCPP_USING_IF_EXISTS;
78using ::wctype _LIBCPP_USING_IF_EXISTS;
79using ::towlower _LIBCPP_USING_IF_EXISTS;
80using ::towupper _LIBCPP_USING_IF_EXISTS;
81using ::towctrans _LIBCPP_USING_IF_EXISTS;
82using ::wctrans _LIBCPP_USING_IF_EXISTS;
8383
8484_LIBCPP_END_NAMESPACE_STD
8585
86#endif // _LIBCPP_CWCTYPE
86#endif // _LIBCPP_CWCTYPE
lib/libcxx/include/deque+27-23
......@@ -161,12 +161,16 @@ template <class T, class Allocator, class Predicate>
161161*/
162162
163163#include <__config>
164#include <__debug>
164165#include <__split_buffer>
165#include <type_traits>
166#include <__utility/forward.h>
167#include <algorithm>
168#include <compare>
166169#include <initializer_list>
167170#include <iterator>
168#include <algorithm>
171#include <limits>
169172#include <stdexcept>
173#include <type_traits>
170174#include <version>
171175
172176#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
......@@ -1055,7 +1059,7 @@ public:
10551059 __deque_base(__deque_base&& __c)
10561060 _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value);
10571061 __deque_base(__deque_base&& __c, const allocator_type& __a);
1058#endif // _LIBCPP_CXX03_LANG
1062#endif // _LIBCPP_CXX03_LANG
10591063
10601064 void swap(__deque_base& __c)
10611065#if _LIBCPP_STD_VER >= 14
......@@ -1222,7 +1226,7 @@ __deque_base<_Tp, _Allocator>::__deque_base(__deque_base&& __c, const allocator_
12221226 }
12231227}
12241228
1225#endif // _LIBCPP_CXX03_LANG
1229#endif // _LIBCPP_CXX03_LANG
12261230
12271231template <class _Tp, class _Allocator>
12281232void
......@@ -1315,7 +1319,7 @@ public:
13151319 deque(_InputIter __f, _InputIter __l, const allocator_type& __a,
13161320 typename enable_if<__is_cpp17_input_iterator<_InputIter>::value>::type* = 0);
13171321 deque(const deque& __c);
1318 deque(const deque& __c, const allocator_type& __a);
1322 deque(const deque& __c, const __identity_t<allocator_type>& __a);
13191323
13201324 deque& operator=(const deque& __c);
13211325
......@@ -1329,7 +1333,7 @@ public:
13291333 _LIBCPP_INLINE_VISIBILITY
13301334 deque(deque&& __c) _NOEXCEPT_(is_nothrow_move_constructible<__base>::value);
13311335 _LIBCPP_INLINE_VISIBILITY
1332 deque(deque&& __c, const allocator_type& __a);
1336 deque(deque&& __c, const __identity_t<allocator_type>& __a);
13331337 _LIBCPP_INLINE_VISIBILITY
13341338 deque& operator=(deque&& __c)
13351339 _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value &&
......@@ -1337,7 +1341,7 @@ public:
13371341
13381342 _LIBCPP_INLINE_VISIBILITY
13391343 void assign(initializer_list<value_type> __il) {assign(__il.begin(), __il.end());}
1340#endif // _LIBCPP_CXX03_LANG
1344#endif // _LIBCPP_CXX03_LANG
13411345
13421346 template <class _InputIter>
13431347 void assign(_InputIter __f, _InputIter __l,
......@@ -1440,7 +1444,7 @@ public:
14401444 _LIBCPP_INLINE_VISIBILITY
14411445 iterator insert(const_iterator __p, initializer_list<value_type> __il)
14421446 {return insert(__p, __il.begin(), __il.end());}
1443#endif // _LIBCPP_CXX03_LANG
1447#endif // _LIBCPP_CXX03_LANG
14441448 iterator insert(const_iterator __p, const value_type& __v);
14451449 iterator insert(const_iterator __p, size_type __n, const value_type& __v);
14461450 template <class _InputIter>
......@@ -1586,18 +1590,18 @@ public:
15861590
15871591#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
15881592template<class _InputIterator,
1589 class _Alloc = allocator<typename iterator_traits<_InputIterator>::value_type>,
1590 class = typename enable_if<__is_allocator<_Alloc>::value, void>::type
1593 class _Alloc = allocator<__iter_value_type<_InputIterator>>,
1594 class = _EnableIf<__is_allocator<_Alloc>::value>
15911595 >
15921596deque(_InputIterator, _InputIterator)
1593 -> deque<typename iterator_traits<_InputIterator>::value_type, _Alloc>;
1597 -> deque<__iter_value_type<_InputIterator>, _Alloc>;
15941598
15951599template<class _InputIterator,
15961600 class _Alloc,
1597 class = typename enable_if<__is_allocator<_Alloc>::value, void>::type
1601 class = _EnableIf<__is_allocator<_Alloc>::value>
15981602 >
15991603deque(_InputIterator, _InputIterator, _Alloc)
1600 -> deque<typename iterator_traits<_InputIterator>::value_type, _Alloc>;
1604 -> deque<__iter_value_type<_InputIterator>, _Alloc>;
16011605#endif
16021606
16031607
......@@ -1658,7 +1662,7 @@ deque<_Tp, _Allocator>::deque(const deque& __c)
16581662}
16591663
16601664template <class _Tp, class _Allocator>
1661deque<_Tp, _Allocator>::deque(const deque& __c, const allocator_type& __a)
1665deque<_Tp, _Allocator>::deque(const deque& __c, const __identity_t<allocator_type>& __a)
16621666 : __base(__a)
16631667{
16641668 __append(__c.begin(), __c.end());
......@@ -1701,7 +1705,7 @@ deque<_Tp, _Allocator>::deque(deque&& __c)
17011705
17021706template <class _Tp, class _Allocator>
17031707inline
1704deque<_Tp, _Allocator>::deque(deque&& __c, const allocator_type& __a)
1708deque<_Tp, _Allocator>::deque(deque&& __c, const __identity_t<allocator_type>& __a)
17051709 : __base(_VSTD::move(__c), __a)
17061710{
17071711 if (__a != __c.__alloc())
......@@ -1746,7 +1750,7 @@ deque<_Tp, _Allocator>::__move_assign(deque& __c, true_type)
17461750 __base::__move_assign(__c);
17471751}
17481752
1749#endif // _LIBCPP_CXX03_LANG
1753#endif // _LIBCPP_CXX03_LANG
17501754
17511755template <class _Tp, class _Allocator>
17521756template <class _InputIter>
......@@ -2128,7 +2132,7 @@ deque<_Tp, _Allocator>::emplace(const_iterator __p, _Args&&... __args)
21282132 return __base::begin() + __pos;
21292133}
21302134
2131#endif // _LIBCPP_CXX03_LANG
2135#endif // _LIBCPP_CXX03_LANG
21322136
21332137
21342138template <class _Tp, class _Allocator>
......@@ -2532,7 +2536,7 @@ deque<_Tp, _Allocator>::__add_front_capacity(size_type __n)
25322536#ifndef _LIBCPP_NO_EXCEPTIONS
25332537 try
25342538 {
2535#endif // _LIBCPP_NO_EXCEPTIONS
2539#endif // _LIBCPP_NO_EXCEPTIONS
25362540 for (; __nb > 0; --__nb)
25372541 __buf.push_back(__alloc_traits::allocate(__a, __base::__block_size));
25382542#ifndef _LIBCPP_NO_EXCEPTIONS
......@@ -2544,7 +2548,7 @@ deque<_Tp, _Allocator>::__add_front_capacity(size_type __n)
25442548 __alloc_traits::deallocate(__a, *__i, __base::__block_size);
25452549 throw;
25462550 }
2547#endif // _LIBCPP_NO_EXCEPTIONS
2551#endif // _LIBCPP_NO_EXCEPTIONS
25482552 for (; __back_capacity > 0; --__back_capacity)
25492553 {
25502554 __buf.push_back(__base::__map_.back());
......@@ -2674,7 +2678,7 @@ deque<_Tp, _Allocator>::__add_back_capacity(size_type __n)
26742678#ifndef _LIBCPP_NO_EXCEPTIONS
26752679 try
26762680 {
2677#endif // _LIBCPP_NO_EXCEPTIONS
2681#endif // _LIBCPP_NO_EXCEPTIONS
26782682 for (; __nb > 0; --__nb)
26792683 __buf.push_back(__alloc_traits::allocate(__a, __base::__block_size));
26802684#ifndef _LIBCPP_NO_EXCEPTIONS
......@@ -2686,7 +2690,7 @@ deque<_Tp, _Allocator>::__add_back_capacity(size_type __n)
26862690 __alloc_traits::deallocate(__a, *__i, __base::__block_size);
26872691 throw;
26882692 }
2689#endif // _LIBCPP_NO_EXCEPTIONS
2693#endif // _LIBCPP_NO_EXCEPTIONS
26902694 for (; __front_capacity > 0; --__front_capacity)
26912695 {
26922696 __buf.push_back(__base::__map_.front());
......@@ -2720,7 +2724,7 @@ template <class _Tp, class _Allocator>
27202724void
27212725deque<_Tp, _Allocator>::pop_back()
27222726{
2723 _LIBCPP_ASSERT(!empty(), "deque::pop_back called for empty deque");
2727 _LIBCPP_ASSERT(!empty(), "deque::pop_back called on an empty deque");
27242728 allocator_type& __a = __base::__alloc();
27252729 size_type __p = __base::size() + __base::__start_ - 1;
27262730 __alloc_traits::destroy(__a, _VSTD::__to_address(*(__base::__map_.begin() +
......@@ -3044,4 +3048,4 @@ _LIBCPP_END_NAMESPACE_STD
30443048
30453049_LIBCPP_POP_MACROS
30463050
3047#endif // _LIBCPP_DEQUE
3051#endif // _LIBCPP_DEQUE
lib/libcxx/include/errno.h+3-3
......@@ -72,9 +72,9 @@ static const int __elast2 = 105;
7272#define ELAST ENOTRECOVERABLE
7373#endif
7474
75#endif // defined(EOWNERDEAD)
75#endif // defined(EOWNERDEAD)
7676
77#endif // !defined(EOWNERDEAD) || !defined(ENOTRECOVERABLE)
77#endif // !defined(EOWNERDEAD) || !defined(ENOTRECOVERABLE)
7878
7979// supply errno values likely to be missing, particularly on Windows
8080
......@@ -394,4 +394,4 @@ static const int __elast2 = 105;
394394
395395#endif // __cplusplus
396396
397#endif // _LIBCPP_ERRNO_H
397#endif // _LIBCPP_ERRNO_H
lib/libcxx/include/exception+9-9
......@@ -76,9 +76,9 @@ template <class E> void rethrow_if_nested(const E& e);
7676
7777*/
7878
79#include <__config>
8079#include <__availability>
81#include <__memory/base.h>
80#include <__config>
81#include <__memory/addressof.h>
8282#include <cstddef>
8383#include <cstdlib>
8484#include <type_traits>
......@@ -151,7 +151,7 @@ public:
151151 exception_ptr& operator=(const exception_ptr&) _NOEXCEPT;
152152 ~exception_ptr() _NOEXCEPT;
153153
154 _LIBCPP_INLINE_VISIBILITY _LIBCPP_EXPLICIT operator bool() const _NOEXCEPT
154 _LIBCPP_INLINE_VISIBILITY explicit operator bool() const _NOEXCEPT
155155 {return __ptr_ != nullptr;}
156156
157157 friend _LIBCPP_INLINE_VISIBILITY
......@@ -205,7 +205,7 @@ public:
205205 exception_ptr& operator=(const exception_ptr& __other) _NOEXCEPT;
206206 exception_ptr& operator=(nullptr_t) _NOEXCEPT;
207207 ~exception_ptr() _NOEXCEPT;
208 _LIBCPP_EXPLICIT operator bool() const _NOEXCEPT;
208 explicit operator bool() const _NOEXCEPT;
209209};
210210
211211_LIBCPP_FUNC_VIS
......@@ -266,7 +266,7 @@ struct __throw_with_nested<_Tp, _Up, true> {
266266 _LIBCPP_NORETURN static inline _LIBCPP_INLINE_VISIBILITY void
267267 __do_throw(_Tp&& __t)
268268 {
269 throw __nested<_Up>(_VSTD::forward<_Tp>(__t));
269 throw __nested<_Up>(static_cast<_Tp&&>(__t));
270270 }
271271};
272272
......@@ -277,9 +277,9 @@ struct __throw_with_nested<_Tp, _Up, false> {
277277 __do_throw(_Tp&& __t)
278278#else
279279 __do_throw (_Tp& __t)
280#endif // _LIBCPP_CXX03_LANG
280#endif // _LIBCPP_CXX03_LANG
281281 {
282 throw _VSTD::forward<_Tp>(__t);
282 throw static_cast<_Tp&&>(__t);
283283 }
284284};
285285#endif
......@@ -296,7 +296,7 @@ throw_with_nested(_Tp&& __t)
296296 is_class<_Up>::value &&
297297 !is_base_of<nested_exception, _Up>::value &&
298298 !__libcpp_is_final<_Up>::value>::
299 __do_throw(_VSTD::forward<_Tp>(__t));
299 __do_throw(static_cast<_Tp&&>(__t));
300300#else
301301 ((void)__t);
302302 // FIXME: Make this abort
......@@ -330,4 +330,4 @@ rethrow_if_nested(const _Ep&,
330330
331331} // std
332332
333#endif // _LIBCPP_EXCEPTION
333#endif // _LIBCPP_EXCEPTION
lib/libcxx/include/experimental/__config-4
......@@ -32,10 +32,6 @@
3232#define _LIBCPP_END_NAMESPACE_LFTS_PMR _LIBCPP_END_NAMESPACE_LFTS }
3333#define _VSTD_LFTS_PMR _VSTD_LFTS::pmr
3434
35#define _LIBCPP_BEGIN_NAMESPACE_CHRONO_LFTS _LIBCPP_BEGIN_NAMESPACE_STD \
36 namespace chrono { namespace experimental { inline namespace fundamentals_v1 {
37#define _LIBCPP_END_NAMESPACE_CHRONO_LFTS _LIBCPP_END_NAMESPACE_STD } } }
38
3935#if defined(_LIBCPP_NO_EXPERIMENTAL_DEPRECATION_WARNING_FILESYSTEM)
4036# define _LIBCPP_DEPRECATED_EXPERIMENTAL_FILESYSTEM /* nothing */
4137#else
lib/libcxx/include/experimental/__memory+26-1
......@@ -10,6 +10,8 @@
1010#ifndef _LIBCPP_EXPERIMENTAL___MEMORY
1111#define _LIBCPP_EXPERIMENTAL___MEMORY
1212
13#include <__memory/allocator_arg_t.h>
14#include <__memory/uses_allocator.h>
1315#include <experimental/__config>
1416#include <experimental/utility> // for erased_type
1517#include <__functional_base>
......@@ -73,12 +75,35 @@ struct __lfts_uses_alloc_ctor
7375 >
7476{};
7577
78template <class _Tp, class _Allocator, class... _Args>
79inline _LIBCPP_INLINE_VISIBILITY
80void __user_alloc_construct_impl (integral_constant<int, 0>, _Tp *__storage, const _Allocator &, _Args &&... __args )
81{
82 new (__storage) _Tp (_VSTD::forward<_Args>(__args)...);
83}
84
85// FIXME: This should have a version which takes a non-const alloc.
86template <class _Tp, class _Allocator, class... _Args>
87inline _LIBCPP_INLINE_VISIBILITY
88void __user_alloc_construct_impl (integral_constant<int, 1>, _Tp *__storage, const _Allocator &__a, _Args &&... __args )
89{
90 new (__storage) _Tp (allocator_arg, __a, _VSTD::forward<_Args>(__args)...);
91}
92
93// FIXME: This should have a version which takes a non-const alloc.
94template <class _Tp, class _Allocator, class... _Args>
95inline _LIBCPP_INLINE_VISIBILITY
96void __user_alloc_construct_impl (integral_constant<int, 2>, _Tp *__storage, const _Allocator &__a, _Args &&... __args )
97{
98 new (__storage) _Tp (_VSTD::forward<_Args>(__args)..., __a);
99}
100
76101template <class _Tp, class _Alloc, class ..._Args>
77102inline _LIBCPP_INLINE_VISIBILITY
78103void __lfts_user_alloc_construct(
79104 _Tp * __store, const _Alloc & __a, _Args &&... __args)
80105{
81 _VSTD::__user_alloc_construct_impl(
106 ::std::experimental::fundamentals_v1::__user_alloc_construct_impl(
82107 typename __lfts_uses_alloc_ctor<_Tp, _Alloc, _Args...>::type()
83108 , __store, __a, _VSTD::forward<_Args>(__args)...
84109 );
lib/libcxx/include/experimental/functional+23-22
......@@ -86,6 +86,7 @@ inline namespace fundamentals_v1 {
8686
8787*/
8888
89#include <__memory/uses_allocator.h>
8990#include <experimental/__config>
9091#include <functional>
9192#include <algorithm>
......@@ -109,7 +110,7 @@ _LIBCPP_BEGIN_NAMESPACE_LFTS
109110#if _LIBCPP_STD_VER > 11
110111// default searcher
111112template<class _ForwardIterator, class _BinaryPredicate = equal_to<>>
112class _LIBCPP_TYPE_VIS default_searcher {
113class _LIBCPP_TEMPLATE_VIS default_searcher {
113114public:
114115 _LIBCPP_INLINE_VISIBILITY
115116 default_searcher(_ForwardIterator __f, _ForwardIterator __l,
......@@ -122,8 +123,8 @@ public:
122123 operator () (_ForwardIterator2 __f, _ForwardIterator2 __l) const
123124 {
124125 return _VSTD::__search(__f, __l, __first_, __last_, __pred_,
125 typename _VSTD::iterator_traits<_ForwardIterator>::iterator_category(),
126 typename _VSTD::iterator_traits<_ForwardIterator2>::iterator_category());
126 typename iterator_traits<_ForwardIterator>::iterator_category(),
127 typename iterator_traits<_ForwardIterator2>::iterator_category());
127128 }
128129
129130private:
......@@ -154,7 +155,7 @@ public: // TODO private:
154155
155156public:
156157 _LIBCPP_INLINE_VISIBILITY
157 _BMSkipTable(std::size_t __sz, _Value __default, _Hash __hf, _BinaryPredicate __pred)
158 _BMSkipTable(size_t __sz, _Value __default, _Hash __hf, _BinaryPredicate __pred)
158159 : __default_value_(__default), __table(__sz, __hf, __pred) {}
159160
160161 _LIBCPP_INLINE_VISIBILITY
......@@ -179,13 +180,13 @@ private:
179180 typedef _Value value_type;
180181 typedef _Key key_type;
181182
182 typedef typename std::make_unsigned<key_type>::type unsigned_key_type;
183 typedef std::array<value_type, _VSTD::numeric_limits<unsigned_key_type>::max()> skip_map;
183 typedef typename make_unsigned<key_type>::type unsigned_key_type;
184 typedef std::array<value_type, numeric_limits<unsigned_key_type>::max()> skip_map;
184185 skip_map __table;
185186
186187public:
187188 _LIBCPP_INLINE_VISIBILITY
188 _BMSkipTable(std::size_t /*__sz*/, _Value __default, _Hash /*__hf*/, _BinaryPredicate /*__pred*/)
189 _BMSkipTable(size_t /*__sz*/, _Value __default, _Hash /*__hf*/, _BinaryPredicate /*__pred*/)
189190 {
190191 std::fill_n(__table.begin(), __table.size(), __default);
191192 }
......@@ -207,12 +208,12 @@ public:
207208template <class _RandomAccessIterator1,
208209 class _Hash = hash<typename iterator_traits<_RandomAccessIterator1>::value_type>,
209210 class _BinaryPredicate = equal_to<>>
210class _LIBCPP_TYPE_VIS boyer_moore_searcher {
211class _LIBCPP_TEMPLATE_VIS boyer_moore_searcher {
211212private:
212213 typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type difference_type;
213214 typedef typename std::iterator_traits<_RandomAccessIterator1>::value_type value_type;
214215 typedef _BMSkipTable<value_type, difference_type, _Hash, _BinaryPredicate,
215 _VSTD::is_integral<value_type>::value && // what about enums?
216 is_integral<value_type>::value && // what about enums?
216217 sizeof(value_type) == 1 &&
217218 is_same<_Hash, hash<value_type>>::value &&
218219 is_same<_BinaryPredicate, equal_to<>>::value
......@@ -247,7 +248,7 @@ public:
247248 if (__first_ == __last_) return make_pair(__f, __f); // empty pattern
248249
249250 // If the pattern is larger than the corpus, we can't find it!
250 if ( __pattern_length_ > _VSTD::distance (__f, __l))
251 if ( __pattern_length_ > _VSTD::distance(__f, __l))
251252 return make_pair(__l, __l);
252253
253254 // Do the search
......@@ -299,11 +300,11 @@ public: // TODO private:
299300 template<typename _Iterator, typename _Container>
300301 void __compute_bm_prefix ( _Iterator __f, _Iterator __l, _BinaryPredicate __pred, _Container &__prefix )
301302 {
302 const std::size_t __count = _VSTD::distance(__f, __l);
303 const size_t __count = _VSTD::distance(__f, __l);
303304
304305 __prefix[0] = 0;
305 std::size_t __k = 0;
306 for ( std::size_t __i = 1; __i < __count; ++__i )
306 size_t __k = 0;
307 for ( size_t __i = 1; __i < __count; ++__i )
307308 {
308309 while ( __k > 0 && !__pred ( __f[__k], __f[__i] ))
309310 __k = __prefix [ __k - 1 ];
......@@ -317,22 +318,22 @@ public: // TODO private:
317318 void __build_suffix_table(_RandomAccessIterator1 __f, _RandomAccessIterator1 __l,
318319 _BinaryPredicate __pred)
319320 {
320 const std::size_t __count = _VSTD::distance(__f, __l);
321 const size_t __count = _VSTD::distance(__f, __l);
321322 vector<difference_type> & __suffix = *__suffix_.get();
322323 if (__count > 0)
323324 {
324 _VSTD::vector<value_type> __scratch(__count);
325 vector<value_type> __scratch(__count);
325326
326327 __compute_bm_prefix(__f, __l, __pred, __scratch);
327 for ( std::size_t __i = 0; __i <= __count; __i++ )
328 for ( size_t __i = 0; __i <= __count; __i++ )
328329 __suffix[__i] = __count - __scratch[__count-1];
329330
330 typedef _VSTD::reverse_iterator<_RandomAccessIterator1> _RevIter;
331 typedef reverse_iterator<_RandomAccessIterator1> _RevIter;
331332 __compute_bm_prefix(_RevIter(__l), _RevIter(__f), __pred, __scratch);
332333
333 for ( std::size_t __i = 0; __i < __count; __i++ )
334 for ( size_t __i = 0; __i < __count; __i++ )
334335 {
335 const std::size_t __j = __count - __scratch[__i];
336 const size_t __j = __count - __scratch[__i];
336337 const difference_type __k = __i - __scratch[__i] + 1;
337338
338339 if (__suffix[__j] > __k)
......@@ -358,12 +359,12 @@ make_boyer_moore_searcher( _RandomAccessIterator __f, _RandomAccessIterator __l,
358359template <class _RandomAccessIterator1,
359360 class _Hash = hash<typename iterator_traits<_RandomAccessIterator1>::value_type>,
360361 class _BinaryPredicate = equal_to<>>
361class _LIBCPP_TYPE_VIS boyer_moore_horspool_searcher {
362class _LIBCPP_TEMPLATE_VIS boyer_moore_horspool_searcher {
362363private:
363364 typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type difference_type;
364365 typedef typename std::iterator_traits<_RandomAccessIterator1>::value_type value_type;
365366 typedef _BMSkipTable<value_type, difference_type, _Hash, _BinaryPredicate,
366 _VSTD::is_integral<value_type>::value && // what about enums?
367 is_integral<value_type>::value && // what about enums?
367368 sizeof(value_type) == 1 &&
368369 is_same<_Hash, hash<value_type>>::value &&
369370 is_same<_BinaryPredicate, equal_to<>>::value
......@@ -399,7 +400,7 @@ public:
399400 if (__first_ == __last_) return make_pair(__f, __f); // empty pattern
400401
401402 // If the pattern is larger than the corpus, we can't find it!
402 if ( __pattern_length_ > _VSTD::distance (__f, __l))
403 if ( __pattern_length_ > _VSTD::distance(__f, __l))
403404 return make_pair(__l, __l);
404405
405406 // Do the search
lib/libcxx/include/experimental/iterator+3
......@@ -56,6 +56,9 @@ namespace std {
5656
5757#if _LIBCPP_STD_VER > 11
5858
59#include <__memory/addressof.h>
60#include <__utility/move.h>
61#include <__utility/forward.h>
5962#include <iterator>
6063
6164_LIBCPP_BEGIN_NAMESPACE_LFTS
lib/libcxx/include/experimental/propagate_const+1-1
......@@ -135,7 +135,7 @@ template <class _Tp>
135135class propagate_const
136136{
137137public:
138 typedef remove_reference_t<decltype(*_VSTD::declval<_Tp&>())> element_type;
138 typedef remove_reference_t<decltype(*declval<_Tp&>())> element_type;
139139
140140 static_assert(!is_array<_Tp>::value,
141141 "Instantiation of propagate_const with an array type is ill-formed.");
lib/libcxx/include/experimental/simd+2-2
......@@ -725,12 +725,12 @@ constexpr size_t __ceil_pow_of_2(size_t __val) {
725725
726726template <class _Tp, size_t __bytes>
727727struct __vec_ext_traits {
728#if !defined(_LIBCPP_COMPILER_CLANG)
728#if !defined(_LIBCPP_COMPILER_CLANG_BASED)
729729 typedef _Tp type __attribute__((vector_size(__ceil_pow_of_2(__bytes))));
730730#endif
731731};
732732
733#if defined(_LIBCPP_COMPILER_CLANG)
733#if defined(_LIBCPP_COMPILER_CLANG_BASED)
734734#define _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, _NUM_ELEMENT) \
735735 template <> \
736736 struct __vec_ext_traits<_TYPE, sizeof(_TYPE) * _NUM_ELEMENT> { \
lib/libcxx/include/experimental/type_traits+1-1
......@@ -105,7 +105,7 @@ using raw_invocation_type_t = typename raw_invocation_type<_Tp>::type;
105105// 3.3.4, Detection idiom
106106template <class...> using void_t = void;
107107
108struct nonesuch : private _VSTD::__nat { // make nonesuch "not an aggregate"
108struct nonesuch : private __nat { // make nonesuch "not an aggregate"
109109 ~nonesuch() = delete;
110110 nonesuch (nonesuch const&) = delete;
111111 void operator=(nonesuch const&) = delete;
lib/libcxx/include/ext/__hash+2-1
......@@ -12,6 +12,7 @@
1212
1313#pragma GCC system_header
1414
15#include <__string>
1516#include <string>
1617#include <cstring>
1718
......@@ -130,4 +131,4 @@ template <> struct _LIBCPP_TEMPLATE_VIS hash<unsigned long>
130131};
131132}
132133
133#endif // _LIBCPP_EXT_HASH
134#endif // _LIBCPP_EXT_HASH
lib/libcxx/include/ext/hash_map+3-3
......@@ -208,7 +208,7 @@ template <class Key, class T, class Hash, class Pred, class Alloc>
208208#include <type_traits>
209209#include <ext/__hash>
210210
211#if __DEPRECATED
211#if defined(__DEPRECATED) && __DEPRECATED
212212#if defined(_LIBCPP_WARNING)
213213 _LIBCPP_WARNING("Use of the header <ext/hash_map> is deprecated. Migrate to <unordered_map>")
214214#else
......@@ -350,7 +350,7 @@ public:
350350 {
351351 const_cast<bool&>(__x.__value_constructed) = false;
352352 }
353#endif // _LIBCPP_CXX03_LANG
353#endif // _LIBCPP_CXX03_LANG
354354
355355 _LIBCPP_INLINE_VISIBILITY
356356 void operator()(pointer __p)
......@@ -981,4 +981,4 @@ operator!=(const hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
981981
982982} // __gnu_cxx
983983
984#endif // _LIBCPP_HASH_MAP
984#endif // _LIBCPP_HASH_MAP
lib/libcxx/include/ext/hash_set+2-2
......@@ -197,7 +197,7 @@ template <class Value, class Hash, class Pred, class Alloc>
197197#include <functional>
198198#include <ext/__hash>
199199
200#if __DEPRECATED
200#if defined(__DEPRECATED) && __DEPRECATED
201201#if defined(_LIBCPP_WARNING)
202202 _LIBCPP_WARNING("Use of the header <ext/hash_set> is deprecated. Migrate to <unordered_set>")
203203#else
......@@ -656,4 +656,4 @@ operator!=(const hash_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
656656
657657} // __gnu_cxx
658658
659#endif // _LIBCPP_HASH_SET
659#endif // _LIBCPP_HASH_SET
lib/libcxx/include/filesystem+111-31
......@@ -229,19 +229,22 @@
229229
230230*/
231231
232#include <__config>
233232#include <__availability>
233#include <__config>
234#include <__debug>
235#include <__utility/forward.h>
236#include <chrono>
237#include <compare>
234238#include <cstddef>
235239#include <cstdlib>
236#include <chrono>
237#include <iterator>
238240#include <iosfwd>
241#include <iterator>
239242#include <memory>
240243#include <stack>
241244#include <string>
245#include <string_view>
242246#include <system_error>
243247#include <utility>
244#include <string_view>
245248#include <version>
246249
247250#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
......@@ -249,8 +252,6 @@
249252# include <iomanip> // for quoted
250253#endif
251254
252#include <__debug>
253
254255#if defined(_LIBCPP_HAS_NO_FILESYSTEM_LIBRARY)
255256# error "The Filesystem library is not supported by this configuration of libc++"
256257#endif
......@@ -276,6 +277,8 @@ struct _LIBCPP_TYPE_VIS space_info {
276277 uintmax_t available;
277278};
278279
280// On Windows, the library never identifies files as block, character, fifo
281// or socket.
279282enum class _LIBCPP_ENUM_VIS file_type : signed char {
280283 none = 0,
281284 not_found = -1,
......@@ -289,6 +292,10 @@ enum class _LIBCPP_ENUM_VIS file_type : signed char {
289292 unknown = 8
290293};
291294
295// On Windows, these permission bits map to one single readonly flag per
296// file, and the executable bit is always returned as set. When setting
297// permissions, as long as the write bit is set for either owner, group or
298// others, the readonly flag is cleared.
292299enum class _LIBCPP_ENUM_VIS perms : unsigned {
293300 none = 0,
294301
......@@ -551,7 +558,7 @@ struct __can_convert_char<wchar_t> {
551558 static const bool value = true;
552559 using __char_type = wchar_t;
553560};
554#ifndef _LIBCPP_NO_HAS_CHAR8_T
561#ifndef _LIBCPP_HAS_NO_CHAR8_T
555562template <>
556563struct __can_convert_char<char8_t> {
557564 static const bool value = true;
......@@ -579,7 +586,7 @@ __is_separator(_ECharT __e) {
579586#endif
580587}
581588
582#ifndef _LIBCPP_NO_HAS_CHAR8_T
589#ifndef _LIBCPP_HAS_NO_CHAR8_T
583590typedef u8string __u8_string;
584591#else
585592typedef string __u8_string;
......@@ -785,7 +792,7 @@ struct _PathCVT<__path_value> {
785792 template <class _Iter>
786793 static typename enable_if<__is_cpp17_forward_iterator<_Iter>::value>::type
787794 __append_range(__path_string& __dest, _Iter __b, _Iter __e) {
788 __dest.__append_forward_unsafe(__b, __e);
795 __dest.append(__b, __e);
789796 }
790797
791798 template <class _Iter>
......@@ -886,7 +893,7 @@ struct _PathExport<char16_t> {
886893 }
887894};
888895
889#ifndef _LIBCPP_NO_HAS_CHAR8_T
896#ifndef _LIBCPP_HAS_NO_CHAR8_T
890897template <>
891898struct _PathExport<char8_t> {
892899 typedef __narrow_to_utf8<sizeof(wchar_t) * __CHAR_BIT__> _Narrower;
......@@ -896,7 +903,7 @@ struct _PathExport<char8_t> {
896903 _Narrower()(back_inserter(__dest), __src.data(), __src.data() + __src.size());
897904 }
898905};
899#endif /* !_LIBCPP_NO_HAS_CHAR8_T */
906#endif /* !_LIBCPP_HAS_NO_CHAR8_T */
900907#endif /* _LIBCPP_WIN32API */
901908
902909class _LIBCPP_TYPE_VIS path {
......@@ -921,7 +928,7 @@ public:
921928 typedef basic_string<value_type> string_type;
922929 typedef basic_string_view<value_type> __string_view;
923930
924 enum class _LIBCPP_ENUM_VIS format : unsigned char {
931 enum _LIBCPP_ENUM_VIS format : unsigned char {
925932 auto_format,
926933 native_format,
927934 generic_format
......@@ -973,8 +980,8 @@ public:
973980 return *this;
974981 }
975982
976 template <class = void>
977 _LIBCPP_INLINE_VISIBILITY path& operator=(string_type&& __s) noexcept {
983 _LIBCPP_INLINE_VISIBILITY
984 path& operator=(string_type&& __s) noexcept {
978985 __pn_ = _VSTD::move(__s);
979986 return *this;
980987 }
......@@ -1006,14 +1013,44 @@ public:
10061013 return *this;
10071014 }
10081015
1009private:
1010 template <class _ECharT>
1011 static bool __source_is_absolute(_ECharT __first_or_null) {
1012 return __is_separator(__first_or_null);
1013 }
1014
10151016public:
10161017 // appends
1018#if defined(_LIBCPP_WIN32API)
1019 path& operator/=(const path& __p) {
1020 auto __p_root_name = __p.__root_name();
1021 auto __p_root_name_size = __p_root_name.size();
1022 if (__p.is_absolute() ||
1023 (!__p_root_name.empty() && __p_root_name != root_name())) {
1024 __pn_ = __p.__pn_;
1025 return *this;
1026 }
1027 if (__p.has_root_directory()) {
1028 path __root_name_str = root_name();
1029 __pn_ = __root_name_str.native();
1030 __pn_ += __string_view(__p.__pn_).substr(__p_root_name_size);
1031 return *this;
1032 }
1033 if (has_filename() || (!has_root_directory() && is_absolute()))
1034 __pn_ += preferred_separator;
1035 __pn_ += __string_view(__p.__pn_).substr(__p_root_name_size);
1036 return *this;
1037 }
1038 template <class _Source>
1039 _LIBCPP_INLINE_VISIBILITY _EnableIfPathable<_Source>
1040 operator/=(const _Source& __src) {
1041 return operator/=(path(__src));
1042 }
1043
1044 template <class _Source>
1045 _EnableIfPathable<_Source> append(const _Source& __src) {
1046 return operator/=(path(__src));
1047 }
1048
1049 template <class _InputIt>
1050 path& append(_InputIt __first, _InputIt __last) {
1051 return operator/=(path(__first, __last));
1052 }
1053#else
10171054 path& operator/=(const path& __p) {
10181055 if (__p.is_absolute()) {
10191056 __pn_ = __p.__pn_;
......@@ -1038,7 +1075,8 @@ public:
10381075 _EnableIfPathable<_Source> append(const _Source& __src) {
10391076 using _Traits = __is_pathable<_Source>;
10401077 using _CVT = _PathCVT<_SourceChar<_Source> >;
1041 if (__source_is_absolute(_Traits::__first_or_null(__src)))
1078 bool __source_is_absolute = __is_separator(_Traits::__first_or_null(__src));
1079 if (__source_is_absolute)
10421080 __pn_.clear();
10431081 else if (has_filename())
10441082 __pn_ += preferred_separator;
......@@ -1051,13 +1089,14 @@ public:
10511089 typedef typename iterator_traits<_InputIt>::value_type _ItVal;
10521090 static_assert(__can_convert_char<_ItVal>::value, "Must convertible");
10531091 using _CVT = _PathCVT<_ItVal>;
1054 if (__first != __last && __source_is_absolute(*__first))
1092 if (__first != __last && __is_separator(*__first))
10551093 __pn_.clear();
10561094 else if (has_filename())
10571095 __pn_ += preferred_separator;
10581096 _CVT::__append_range(__pn_, __first, __last);
10591097 return *this;
10601098 }
1099#endif
10611100
10621101 // concatenation
10631102 _LIBCPP_INLINE_VISIBILITY
......@@ -1161,7 +1200,12 @@ public:
11611200#if defined(_LIBCPP_WIN32API)
11621201 _LIBCPP_INLINE_VISIBILITY _VSTD::wstring wstring() const { return __pn_; }
11631202
1164 _VSTD::wstring generic_wstring() const { return __pn_; }
1203 _VSTD::wstring generic_wstring() const {
1204 _VSTD::wstring __s;
1205 __s.resize(__pn_.size());
1206 _VSTD::replace_copy(__pn_.begin(), __pn_.end(), __s.begin(), '\\', '/');
1207 return __s;
1208 }
11651209
11661210#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
11671211 template <class _ECharT, class _Traits = char_traits<_ECharT>,
......@@ -1198,18 +1242,29 @@ public:
11981242 class _Allocator = allocator<_ECharT> >
11991243 basic_string<_ECharT, _Traits, _Allocator>
12001244 generic_string(const _Allocator& __a = _Allocator()) const {
1201 return string<_ECharT, _Traits, _Allocator>(__a);
1245 using _Str = basic_string<_ECharT, _Traits, _Allocator>;
1246 _Str __s = string<_ECharT, _Traits, _Allocator>(__a);
1247 // Note: This (and generic_u8string below) is slightly suboptimal as
1248 // it iterates twice over the string; once to convert it to the right
1249 // character type, and once to replace path delimiters.
1250 _VSTD::replace(__s.begin(), __s.end(),
1251 static_cast<_ECharT>('\\'), static_cast<_ECharT>('/'));
1252 return __s;
12021253 }
12031254
12041255 _VSTD::string generic_string() const { return generic_string<char>(); }
12051256 _VSTD::u16string generic_u16string() const { return generic_string<char16_t>(); }
12061257 _VSTD::u32string generic_u32string() const { return generic_string<char32_t>(); }
1207 __u8_string generic_u8string() const { return u8string(); }
1258 __u8_string generic_u8string() const {
1259 __u8_string __s = u8string();
1260 _VSTD::replace(__s.begin(), __s.end(), '\\', '/');
1261 return __s;
1262 }
12081263#endif /* !_LIBCPP_HAS_NO_LOCALIZATION */
12091264#else /* _LIBCPP_WIN32API */
12101265
12111266 _LIBCPP_INLINE_VISIBILITY _VSTD::string string() const { return __pn_; }
1212#ifndef _LIBCPP_NO_HAS_CHAR8_T
1267#ifndef _LIBCPP_HAS_NO_CHAR8_T
12131268 _LIBCPP_INLINE_VISIBILITY _VSTD::u8string u8string() const { return _VSTD::u8string(__pn_.begin(), __pn_.end()); }
12141269#else
12151270 _LIBCPP_INLINE_VISIBILITY _VSTD::string u8string() const { return __pn_; }
......@@ -1241,7 +1296,7 @@ public:
12411296
12421297 // generic format observers
12431298 _VSTD::string generic_string() const { return __pn_; }
1244#ifndef _LIBCPP_NO_HAS_CHAR8_T
1299#ifndef _LIBCPP_HAS_NO_CHAR8_T
12451300 _VSTD::u8string generic_u8string() const { return _VSTD::u8string(__pn_.begin(), __pn_.end()); }
12461301#else
12471302 _VSTD::string generic_u8string() const { return __pn_; }
......@@ -1295,7 +1350,11 @@ public:
12951350 return string_type(__root_directory());
12961351 }
12971352 _LIBCPP_INLINE_VISIBILITY path root_path() const {
1353#if defined(_LIBCPP_WIN32API)
1354 return string_type(__root_path_raw());
1355#else
12981356 return root_name().append(string_type(__root_directory()));
1357#endif
12991358 }
13001359 _LIBCPP_INLINE_VISIBILITY path relative_path() const {
13011360 return string_type(__relative_path());
......@@ -1341,7 +1400,28 @@ public:
13411400 }
13421401
13431402 _LIBCPP_INLINE_VISIBILITY bool is_absolute() const {
1403#if defined(_LIBCPP_WIN32API)
1404 __string_view __root_name_str = __root_name();
1405 __string_view __root_dir = __root_directory();
1406 if (__root_name_str.size() == 2 && __root_name_str[1] == ':') {
1407 // A drive letter with no root directory is relative, e.g. x:example.
1408 return !__root_dir.empty();
1409 }
1410 // If no root name, it's relative, e.g. \example is relative to the current drive
1411 if (__root_name_str.empty())
1412 return false;
1413 if (__root_name_str.size() < 3)
1414 return false;
1415 // A server root name, like \\server, is always absolute
1416 if (__root_name_str[0] != '/' && __root_name_str[0] != '\\')
1417 return false;
1418 if (__root_name_str[1] != '/' && __root_name_str[1] != '\\')
1419 return false;
1420 // Seems to be a server root name
1421 return true;
1422#else
13441423 return has_root_directory();
1424#endif
13451425 }
13461426 _LIBCPP_INLINE_VISIBILITY bool is_relative() const { return !is_absolute(); }
13471427
......@@ -1440,7 +1520,7 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_WITH_CHAR8_T
14401520 typename enable_if<__is_pathable<_InputIt>::value, path>::type
14411521 u8path(_InputIt __f, _InputIt __l) {
14421522 static_assert(
1443#ifndef _LIBCPP_NO_HAS_CHAR8_T
1523#ifndef _LIBCPP_HAS_NO_CHAR8_T
14441524 is_same<typename __is_pathable<_InputIt>::__char_type, char8_t>::value ||
14451525#endif
14461526 is_same<typename __is_pathable<_InputIt>::__char_type, char>::value,
......@@ -1464,7 +1544,7 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_WITH_CHAR8_T
14641544 typename enable_if<__is_pathable<_InputIt>::value, path>::type
14651545 u8path(_InputIt __f, _NullSentinel) {
14661546 static_assert(
1467#ifndef _LIBCPP_NO_HAS_CHAR8_T
1547#ifndef _LIBCPP_HAS_NO_CHAR8_T
14681548 is_same<typename __is_pathable<_InputIt>::__char_type, char8_t>::value ||
14691549#endif
14701550 is_same<typename __is_pathable<_InputIt>::__char_type, char>::value,
......@@ -1487,7 +1567,7 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_WITH_CHAR8_T
14871567 typename enable_if<__is_pathable<_Source>::value, path>::type
14881568 u8path(const _Source& __s) {
14891569 static_assert(
1490#ifndef _LIBCPP_NO_HAS_CHAR8_T
1570#ifndef _LIBCPP_HAS_NO_CHAR8_T
14911571 is_same<typename __is_pathable<_Source>::__char_type, char8_t>::value ||
14921572#endif
14931573 is_same<typename __is_pathable<_Source>::__char_type, char>::value,
......@@ -1495,7 +1575,7 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_WITH_CHAR8_T
14951575 "'char' or 'char8_t'");
14961576#if defined(_LIBCPP_WIN32API)
14971577 using _Traits = __is_pathable<_Source>;
1498 return u8path(__unwrap_iter(_Traits::__range_begin(__s)), __unwrap_iter(_Traits::__range_end(__s)));
1578 return u8path(_VSTD::__unwrap_iter(_Traits::__range_begin(__s)), _VSTD::__unwrap_iter(_Traits::__range_end(__s)));
14991579#else
15001580 return path(__s);
15011581#endif
lib/libcxx/include/float.h+1-1
......@@ -90,4 +90,4 @@ Macros:
9090
9191#endif // __cplusplus
9292
93#endif // _LIBCPP_FLOAT_H
93#endif // _LIBCPP_FLOAT_H
lib/libcxx/include/format created+86
......@@ -0,0 +1,86 @@
1// -*- C++ -*-
2//===--------------------------- format -----------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP_FORMAT
11#define _LIBCPP_FORMAT
12
13/*
14
15namespace std {
16 // [format.error], class format_error
17 class format_error : public runtime_error {
18 public:
19 explicit format_error(const string& what_arg);
20 explicit format_error(const char* what_arg);
21 };
22
23 // [format.parse.ctx], class template basic_format_parse_context
24 template<class charT>
25 class basic_format_parse_context {
26 public:
27 using char_type = charT;
28 using const_iterator = typename basic_string_view<charT>::const_iterator;
29 using iterator = const_iterator;
30
31 private:
32 iterator begin_; // exposition only
33 iterator end_; // exposition only
34 enum indexing { unknown, manual, automatic }; // exposition only
35 indexing indexing_; // exposition only
36 size_t next_arg_id_; // exposition only
37 size_t num_args_; // exposition only
38
39 public:
40 constexpr explicit basic_format_parse_context(basic_string_view<charT> fmt,
41 size_t num_args = 0) noexcept;
42 basic_format_parse_context(const basic_format_parse_context&) = delete;
43 basic_format_parse_context& operator=(const basic_format_parse_context&) = delete;
44
45 constexpr const_iterator begin() const noexcept;
46 constexpr const_iterator end() const noexcept;
47 constexpr void advance_to(const_iterator it);
48
49 constexpr size_t next_arg_id();
50 constexpr void check_arg_id(size_t id);
51 };
52 using format_parse_context = basic_format_parse_context<char>;
53 using wformat_parse_context = basic_format_parse_context<wchar_t>;
54}
55
56*/
57
58// Make sure all feature tests macros are always available.
59#include <version>
60// Only enable the contents of the header when libc++ was build with LIBCXX_ENABLE_INCOMPLETE_FEATURES enabled
61#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)
62
63#include <__config>
64#include <__format/format_error.h>
65#include <__format/format_parse_context.h>
66
67#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
68# pragma GCC system_header
69#endif
70
71_LIBCPP_PUSH_MACROS
72#include <__undef_macros>
73
74_LIBCPP_BEGIN_NAMESPACE_STD
75
76#if _LIBCPP_STD_VER > 17
77
78#endif //_LIBCPP_STD_VER > 17
79
80_LIBCPP_END_NAMESPACE_STD
81
82_LIBCPP_POP_MACROS
83
84#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)
85
86#endif // _LIBCPP_FORMAT
lib/libcxx/include/forward_list+31-30
......@@ -180,11 +180,12 @@ template <class T, class Allocator, class Predicate>
180180*/
181181
182182#include <__config>
183#include <__utility/forward.h>
184#include <algorithm>
183185#include <initializer_list>
184#include <memory>
185#include <limits>
186186#include <iterator>
187#include <algorithm>
187#include <limits>
188#include <memory>
188189#include <version>
189190
190191#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
......@@ -272,7 +273,7 @@ struct _LIBCPP_HIDDEN __begin_node_of
272273};
273274
274275template <class _Tp, class _VoidPtr>
275struct __forward_list_node
276struct _LIBCPP_STANDALONE_DEBUG __forward_list_node
276277 : public __begin_node_of<_Tp, _VoidPtr>::type
277278{
278279 typedef _Tp value_type;
......@@ -506,7 +507,7 @@ public:
506507 _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value);
507508 _LIBCPP_INLINE_VISIBILITY
508509 __forward_list_base(__forward_list_base&& __x, const allocator_type& __a);
509#endif // _LIBCPP_CXX03_LANG
510#endif // _LIBCPP_CXX03_LANG
510511
511512private:
512513 __forward_list_base(const __forward_list_base&);
......@@ -534,7 +535,7 @@ public:
534535#if _LIBCPP_STD_VER >= 14
535536 _NOEXCEPT;
536537#else
537 _NOEXCEPT_(!__node_traits::propagate_on_container_move_assignment::value ||
538 _NOEXCEPT_(!__node_traits::propagate_on_container_swap::value ||
538539 __is_nothrow_swappable<__node_allocator>::value);
539540#endif
540541protected:
......@@ -584,7 +585,7 @@ __forward_list_base<_Tp, _Alloc>::__forward_list_base(__forward_list_base&& __x,
584585 }
585586}
586587
587#endif // _LIBCPP_CXX03_LANG
588#endif // _LIBCPP_CXX03_LANG
588589
589590template <class _Tp, class _Alloc>
590591__forward_list_base<_Tp, _Alloc>::~__forward_list_base()
......@@ -599,7 +600,7 @@ __forward_list_base<_Tp, _Alloc>::swap(__forward_list_base& __x)
599600#if _LIBCPP_STD_VER >= 14
600601 _NOEXCEPT
601602#else
602 _NOEXCEPT_(!__node_traits::propagate_on_container_move_assignment::value ||
603 _NOEXCEPT_(!__node_traits::propagate_on_container_swap::value ||
603604 __is_nothrow_swappable<__node_allocator>::value)
604605#endif
605606{
......@@ -681,7 +682,7 @@ public:
681682 __is_cpp17_input_iterator<_InputIterator>::value
682683 >::type* = nullptr);
683684 forward_list(const forward_list& __x);
684 forward_list(const forward_list& __x, const allocator_type& __a);
685 forward_list(const forward_list& __x, const __identity_t<allocator_type>& __a);
685686
686687 forward_list& operator=(const forward_list& __x);
687688
......@@ -690,7 +691,7 @@ public:
690691 forward_list(forward_list&& __x)
691692 _NOEXCEPT_(is_nothrow_move_constructible<base>::value)
692693 : base(_VSTD::move(__x)) {}
693 forward_list(forward_list&& __x, const allocator_type& __a);
694 forward_list(forward_list&& __x, const __identity_t<allocator_type>& __a);
694695
695696 forward_list(initializer_list<value_type> __il);
696697 forward_list(initializer_list<value_type> __il, const allocator_type& __a);
......@@ -706,7 +707,7 @@ public:
706707
707708 _LIBCPP_INLINE_VISIBILITY
708709 void assign(initializer_list<value_type> __il);
709#endif // _LIBCPP_CXX03_LANG
710#endif // _LIBCPP_CXX03_LANG
710711
711712 // ~forward_list() = default;
712713
......@@ -775,7 +776,7 @@ public:
775776 template <class... _Args> void emplace_front(_Args&&... __args);
776777#endif
777778 void push_front(value_type&& __v);
778#endif // _LIBCPP_CXX03_LANG
779#endif // _LIBCPP_CXX03_LANG
779780 void push_front(const value_type& __v);
780781
781782 void pop_front();
......@@ -787,7 +788,7 @@ public:
787788 iterator insert_after(const_iterator __p, value_type&& __v);
788789 iterator insert_after(const_iterator __p, initializer_list<value_type> __il)
789790 {return insert_after(__p, __il.begin(), __il.end());}
790#endif // _LIBCPP_CXX03_LANG
791#endif // _LIBCPP_CXX03_LANG
791792 iterator insert_after(const_iterator __p, const value_type& __v);
792793 iterator insert_after(const_iterator __p, size_type __n, const value_type& __v);
793794 template <class _InputIterator>
......@@ -840,7 +841,7 @@ public:
840841 _LIBCPP_INLINE_VISIBILITY
841842 void merge(forward_list&& __x, _Compare __comp)
842843 {merge(__x, _VSTD::move(__comp));}
843#endif // _LIBCPP_CXX03_LANG
844#endif // _LIBCPP_CXX03_LANG
844845 _LIBCPP_INLINE_VISIBILITY
845846 void merge(forward_list& __x) {merge(__x, __less<value_type>());}
846847 template <class _Compare> void merge(forward_list& __x, _Compare __comp);
......@@ -855,7 +856,7 @@ private:
855856 void __move_assign(forward_list& __x, true_type)
856857 _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value);
857858 void __move_assign(forward_list& __x, false_type);
858#endif // _LIBCPP_CXX03_LANG
859#endif // _LIBCPP_CXX03_LANG
859860
860861 template <class _Compare>
861862 static
......@@ -871,18 +872,18 @@ private:
871872
872873#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
873874template<class _InputIterator,
874 class _Alloc = allocator<typename iterator_traits<_InputIterator>::value_type>,
875 class = typename enable_if<__is_allocator<_Alloc>::value, void>::type
875 class _Alloc = allocator<__iter_value_type<_InputIterator>>,
876 class = _EnableIf<__is_allocator<_Alloc>::value>
876877 >
877878forward_list(_InputIterator, _InputIterator)
878 -> forward_list<typename iterator_traits<_InputIterator>::value_type, _Alloc>;
879 -> forward_list<__iter_value_type<_InputIterator>, _Alloc>;
879880
880881template<class _InputIterator,
881882 class _Alloc,
882 class = typename enable_if<__is_allocator<_Alloc>::value, void>::type
883 class = _EnableIf<__is_allocator<_Alloc>::value>
883884 >
884885forward_list(_InputIterator, _InputIterator, _Alloc)
885 -> forward_list<typename iterator_traits<_InputIterator>::value_type, _Alloc>;
886 -> forward_list<__iter_value_type<_InputIterator>, _Alloc>;
886887#endif
887888
888889template <class _Tp, class _Alloc>
......@@ -979,7 +980,7 @@ forward_list<_Tp, _Alloc>::forward_list(const forward_list& __x)
979980
980981template <class _Tp, class _Alloc>
981982forward_list<_Tp, _Alloc>::forward_list(const forward_list& __x,
982 const allocator_type& __a)
983 const __identity_t<allocator_type>& __a)
983984 : base(__a)
984985{
985986 insert_after(cbefore_begin(), __x.begin(), __x.end());
......@@ -1000,7 +1001,7 @@ forward_list<_Tp, _Alloc>::operator=(const forward_list& __x)
10001001#ifndef _LIBCPP_CXX03_LANG
10011002template <class _Tp, class _Alloc>
10021003forward_list<_Tp, _Alloc>::forward_list(forward_list&& __x,
1003 const allocator_type& __a)
1004 const __identity_t<allocator_type>& __a)
10041005 : base(_VSTD::move(__x), __a)
10051006{
10061007 if (base::__alloc() != __x.__alloc())
......@@ -1070,7 +1071,7 @@ forward_list<_Tp, _Alloc>::operator=(initializer_list<value_type> __il)
10701071 return *this;
10711072}
10721073
1073#endif // _LIBCPP_CXX03_LANG
1074#endif // _LIBCPP_CXX03_LANG
10741075
10751076template <class _Tp, class _Alloc>
10761077template <class _InputIterator>
......@@ -1150,7 +1151,7 @@ forward_list<_Tp, _Alloc>::push_front(value_type&& __v)
11501151 base::__before_begin()->__next_ = __h.release();
11511152}
11521153
1153#endif // _LIBCPP_CXX03_LANG
1154#endif // _LIBCPP_CXX03_LANG
11541155
11551156template <class _Tp, class _Alloc>
11561157void
......@@ -1207,7 +1208,7 @@ forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, value_type&& __v)
12071208 return iterator(__r->__next_);
12081209}
12091210
1210#endif // _LIBCPP_CXX03_LANG
1211#endif // _LIBCPP_CXX03_LANG
12111212
12121213template <class _Tp, class _Alloc>
12131214typename forward_list<_Tp, _Alloc>::iterator
......@@ -1240,7 +1241,7 @@ forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, size_type __n,
12401241#ifndef _LIBCPP_NO_EXCEPTIONS
12411242 try
12421243 {
1243#endif // _LIBCPP_NO_EXCEPTIONS
1244#endif // _LIBCPP_NO_EXCEPTIONS
12441245 for (--__n; __n != 0; --__n, __last = __last->__next_)
12451246 {
12461247 __h.reset(__node_traits::allocate(__a, 1));
......@@ -1260,7 +1261,7 @@ forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, size_type __n,
12601261 }
12611262 throw;
12621263 }
1263#endif // _LIBCPP_NO_EXCEPTIONS
1264#endif // _LIBCPP_NO_EXCEPTIONS
12641265 __last->__next_ = __r->__next_;
12651266 __r->__next_ = __first;
12661267 __r = static_cast<__begin_node_pointer>(__last);
......@@ -1290,7 +1291,7 @@ forward_list<_Tp, _Alloc>::insert_after(const_iterator __p,
12901291#ifndef _LIBCPP_NO_EXCEPTIONS
12911292 try
12921293 {
1293#endif // _LIBCPP_NO_EXCEPTIONS
1294#endif // _LIBCPP_NO_EXCEPTIONS
12941295 for (++__f; __f != __l; ++__f, ((void)(__last = __last->__next_)))
12951296 {
12961297 __h.reset(__node_traits::allocate(__a, 1));
......@@ -1310,7 +1311,7 @@ forward_list<_Tp, _Alloc>::insert_after(const_iterator __p,
13101311 }
13111312 throw;
13121313 }
1313#endif // _LIBCPP_NO_EXCEPTIONS
1314#endif // _LIBCPP_NO_EXCEPTIONS
13141315 __last->__next_ = __r->__next_;
13151316 __r->__next_ = __first;
13161317 __r = static_cast<__begin_node_pointer>(__last);
......@@ -1784,4 +1785,4 @@ _LIBCPP_END_NAMESPACE_STD
17841785
17851786_LIBCPP_POP_MACROS
17861787
1787#endif // _LIBCPP_FORWARD_LIST
1788#endif // _LIBCPP_FORWARD_LIST
lib/libcxx/include/fstream+15-36
......@@ -179,13 +179,14 @@ typedef basic_fstream<wchar_t> wfstream;
179179
180180*/
181181
182#include <__config>
183182#include <__availability>
184#include <ostream>
185#include <istream>
183#include <__config>
184#include <__debug>
186185#include <__locale>
187186#include <cstdio>
188187#include <cstdlib>
188#include <istream>
189#include <ostream>
189190
190191#if !defined(_LIBCPP_HAS_NO_FILESYSTEM_LIBRARY)
191192# include <filesystem>
......@@ -198,6 +199,9 @@ typedef basic_fstream<wchar_t> wfstream;
198199_LIBCPP_PUSH_MACROS
199200#include <__undef_macros>
200201
202#if defined(_LIBCPP_MSVCRT) || defined(_NEWLIB_VERSION)
203# define _LIBCPP_HAS_NO_OFF_T_FUNCTIONS
204#endif
201205
202206_LIBCPP_BEGIN_NAMESPACE_STD
203207
......@@ -215,16 +219,12 @@ public:
215219
216220 // 27.9.1.2 Constructors/destructor:
217221 basic_filebuf();
218#ifndef _LIBCPP_CXX03_LANG
219222 basic_filebuf(basic_filebuf&& __rhs);
220#endif
221223 virtual ~basic_filebuf();
222224
223225 // 27.9.1.3 Assign/swap:
224#ifndef _LIBCPP_CXX03_LANG
225226 _LIBCPP_INLINE_VISIBILITY
226227 basic_filebuf& operator=(basic_filebuf&& __rhs);
227#endif
228228 void swap(basic_filebuf& __rhs);
229229
230230 // 27.9.1.4 Members:
......@@ -244,7 +244,7 @@ public:
244244 return open(__p.c_str(), __mode);
245245 }
246246#endif
247 inline _LIBCPP_INLINE_VISIBILITY
247 _LIBCPP_INLINE_VISIBILITY
248248 basic_filebuf* __open(int __fd, ios_base::openmode __mode);
249249#endif
250250 basic_filebuf* close();
......@@ -314,8 +314,6 @@ basic_filebuf<_CharT, _Traits>::basic_filebuf()
314314 setbuf(nullptr, 4096);
315315}
316316
317#ifndef _LIBCPP_CXX03_LANG
318
319317template <class _CharT, class _Traits>
320318basic_filebuf<_CharT, _Traits>::basic_filebuf(basic_filebuf&& __rhs)
321319 : basic_streambuf<_CharT, _Traits>(__rhs)
......@@ -390,22 +388,20 @@ basic_filebuf<_CharT, _Traits>::operator=(basic_filebuf&& __rhs)
390388 return *this;
391389}
392390
393#endif // _LIBCPP_CXX03_LANG
394
395391template <class _CharT, class _Traits>
396392basic_filebuf<_CharT, _Traits>::~basic_filebuf()
397393{
398394#ifndef _LIBCPP_NO_EXCEPTIONS
399395 try
400396 {
401#endif // _LIBCPP_NO_EXCEPTIONS
397#endif // _LIBCPP_NO_EXCEPTIONS
402398 close();
403399#ifndef _LIBCPP_NO_EXCEPTIONS
404400 }
405401 catch (...)
406402 {
407403 }
408#endif // _LIBCPP_NO_EXCEPTIONS
404#endif // _LIBCPP_NO_EXCEPTIONS
409405 if (__owns_eb_)
410406 delete [] __extbuf_;
411407 if (__owns_ib_)
......@@ -574,7 +570,7 @@ basic_filebuf<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode)
574570}
575571
576572template <class _CharT, class _Traits>
577inline _LIBCPP_INLINE_VISIBILITY
573inline
578574basic_filebuf<_CharT, _Traits>*
579575basic_filebuf<_CharT, _Traits>::__open(int __fd, ios_base::openmode __mode) {
580576 basic_filebuf<_CharT, _Traits>* __rt = nullptr;
......@@ -1160,13 +1156,10 @@ public:
11601156 : basic_ifstream(__p.c_str(), __mode) {}
11611157#endif // _LIBCPP_STD_VER >= 17
11621158#endif
1163#ifndef _LIBCPP_CXX03_LANG
11641159 _LIBCPP_INLINE_VISIBILITY
11651160 basic_ifstream(basic_ifstream&& __rhs);
1166
11671161 _LIBCPP_INLINE_VISIBILITY
11681162 basic_ifstream& operator=(basic_ifstream&& __rhs);
1169#endif
11701163 _LIBCPP_INLINE_VISIBILITY
11711164 void swap(basic_ifstream& __rhs);
11721165
......@@ -1236,8 +1229,6 @@ basic_ifstream<_CharT, _Traits>::basic_ifstream(const string& __s, ios_base::ope
12361229}
12371230#endif
12381231
1239#ifndef _LIBCPP_CXX03_LANG
1240
12411232template <class _CharT, class _Traits>
12421233inline
12431234basic_ifstream<_CharT, _Traits>::basic_ifstream(basic_ifstream&& __rhs)
......@@ -1257,8 +1248,6 @@ basic_ifstream<_CharT, _Traits>::operator=(basic_ifstream&& __rhs)
12571248 return *this;
12581249}
12591250
1260#endif // _LIBCPP_CXX03_LANG
1261
12621251template <class _CharT, class _Traits>
12631252inline
12641253void
......@@ -1326,6 +1315,7 @@ basic_ifstream<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mo
13261315}
13271316
13281317template <class _CharT, class _Traits>
1318inline
13291319void basic_ifstream<_CharT, _Traits>::__open(int __fd,
13301320 ios_base::openmode __mode) {
13311321 if (__sb_.__open(__fd, __mode | ios_base::in))
......@@ -1374,13 +1364,10 @@ public:
13741364 : basic_ofstream(__p.c_str(), __mode) {}
13751365#endif // _LIBCPP_STD_VER >= 17
13761366
1377#ifndef _LIBCPP_CXX03_LANG
13781367 _LIBCPP_INLINE_VISIBILITY
13791368 basic_ofstream(basic_ofstream&& __rhs);
1380
13811369 _LIBCPP_INLINE_VISIBILITY
13821370 basic_ofstream& operator=(basic_ofstream&& __rhs);
1383#endif
13841371 _LIBCPP_INLINE_VISIBILITY
13851372 void swap(basic_ofstream& __rhs);
13861373
......@@ -1449,8 +1436,6 @@ basic_ofstream<_CharT, _Traits>::basic_ofstream(const string& __s, ios_base::ope
14491436}
14501437#endif
14511438
1452#ifndef _LIBCPP_CXX03_LANG
1453
14541439template <class _CharT, class _Traits>
14551440inline
14561441basic_ofstream<_CharT, _Traits>::basic_ofstream(basic_ofstream&& __rhs)
......@@ -1470,8 +1455,6 @@ basic_ofstream<_CharT, _Traits>::operator=(basic_ofstream&& __rhs)
14701455 return *this;
14711456}
14721457
1473#endif // _LIBCPP_CXX03_LANG
1474
14751458template <class _CharT, class _Traits>
14761459inline
14771460void
......@@ -1539,6 +1522,7 @@ basic_ofstream<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mo
15391522}
15401523
15411524template <class _CharT, class _Traits>
1525inline
15421526void basic_ofstream<_CharT, _Traits>::__open(int __fd,
15431527 ios_base::openmode __mode) {
15441528 if (__sb_.__open(__fd, __mode | ios_base::out))
......@@ -1589,13 +1573,12 @@ public:
15891573#endif // _LIBCPP_STD_VER >= 17
15901574
15911575#endif
1592#ifndef _LIBCPP_CXX03_LANG
15931576 _LIBCPP_INLINE_VISIBILITY
15941577 basic_fstream(basic_fstream&& __rhs);
15951578
15961579 _LIBCPP_INLINE_VISIBILITY
15971580 basic_fstream& operator=(basic_fstream&& __rhs);
1598#endif
1581
15991582 _LIBCPP_INLINE_VISIBILITY
16001583 void swap(basic_fstream& __rhs);
16011584
......@@ -1662,8 +1645,6 @@ basic_fstream<_CharT, _Traits>::basic_fstream(const string& __s, ios_base::openm
16621645}
16631646#endif
16641647
1665#ifndef _LIBCPP_CXX03_LANG
1666
16671648template <class _CharT, class _Traits>
16681649inline
16691650basic_fstream<_CharT, _Traits>::basic_fstream(basic_fstream&& __rhs)
......@@ -1683,8 +1664,6 @@ basic_fstream<_CharT, _Traits>::operator=(basic_fstream&& __rhs)
16831664 return *this;
16841665}
16851666
1686#endif // _LIBCPP_CXX03_LANG
1687
16881667template <class _CharT, class _Traits>
16891668inline
16901669void
......@@ -1771,4 +1750,4 @@ _LIBCPP_END_NAMESPACE_STD
17711750
17721751_LIBCPP_POP_MACROS
17731752
1774#endif // _LIBCPP_FSTREAM
1753#endif // _LIBCPP_FSTREAM
lib/libcxx/include/functional+64-2722
......@@ -1,5 +1,5 @@
11// -*- C++ -*-
2//===------------------------ functional ----------------------------------===//
2//===----------------------------------------------------------------------===//
33//
44// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
55// See https://llvm.org/LICENSE.txt for license information.
......@@ -42,8 +42,8 @@ public:
4242 typedef see below result_type; // Not always defined
4343
4444 // construct/copy/destroy
45 reference_wrapper(T&) noexcept;
46 reference_wrapper(T&&) = delete; // do not bind to temps
45 template<class U>
46 reference_wrapper(U&&);
4747 reference_wrapper(const reference_wrapper<T>& x) noexcept;
4848
4949 // assignment
......@@ -59,6 +59,9 @@ public:
5959 operator() (ArgTypes&&...) const;
6060};
6161
62template <class T>
63 reference_wrapper(T&) -> reference_wrapper<T>;
64
6265template <class T> reference_wrapper<T> ref(T& t) noexcept;
6366template <class T> void ref(const T&& t) = delete;
6467template <class T> reference_wrapper<T> ref(reference_wrapper<T>t) noexcept;
......@@ -73,121 +76,104 @@ template <class T> using unwrap_reference_t = typename unwrap_reference<T>::type
7376template <class T> using unwrap_ref_decay_t = typename unwrap_ref_decay<T>::type; // since C++20
7477
7578template <class T> // <class T=void> in C++14
76struct plus : binary_function<T, T, T>
77{
79struct plus {
7880 T operator()(const T& x, const T& y) const;
7981};
8082
8183template <class T> // <class T=void> in C++14
82struct minus : binary_function<T, T, T>
83{
84struct minus {
8485 T operator()(const T& x, const T& y) const;
8586};
8687
8788template <class T> // <class T=void> in C++14
88struct multiplies : binary_function<T, T, T>
89{
89struct multiplies {
9090 T operator()(const T& x, const T& y) const;
9191};
9292
9393template <class T> // <class T=void> in C++14
94struct divides : binary_function<T, T, T>
95{
94struct divides {
9695 T operator()(const T& x, const T& y) const;
9796};
9897
9998template <class T> // <class T=void> in C++14
100struct modulus : binary_function<T, T, T>
101{
99struct modulus {
102100 T operator()(const T& x, const T& y) const;
103101};
104102
105103template <class T> // <class T=void> in C++14
106struct negate : unary_function<T, T>
107{
104struct negate {
108105 T operator()(const T& x) const;
109106};
110107
111108template <class T> // <class T=void> in C++14
112struct equal_to : binary_function<T, T, bool>
113{
109struct equal_to {
114110 bool operator()(const T& x, const T& y) const;
115111};
116112
117113template <class T> // <class T=void> in C++14
118struct not_equal_to : binary_function<T, T, bool>
119{
114struct not_equal_to {
120115 bool operator()(const T& x, const T& y) const;
121116};
122117
123118template <class T> // <class T=void> in C++14
124struct greater : binary_function<T, T, bool>
125{
119struct greater {
126120 bool operator()(const T& x, const T& y) const;
127121};
128122
129123template <class T> // <class T=void> in C++14
130struct less : binary_function<T, T, bool>
131{
124struct less {
132125 bool operator()(const T& x, const T& y) const;
133126};
134127
135128template <class T> // <class T=void> in C++14
136struct greater_equal : binary_function<T, T, bool>
137{
129struct greater_equal {
138130 bool operator()(const T& x, const T& y) const;
139131};
140132
141133template <class T> // <class T=void> in C++14
142struct less_equal : binary_function<T, T, bool>
143{
134struct less_equal {
144135 bool operator()(const T& x, const T& y) const;
145136};
146137
147138template <class T> // <class T=void> in C++14
148struct logical_and : binary_function<T, T, bool>
149{
139struct logical_and {
150140 bool operator()(const T& x, const T& y) const;
151141};
152142
153143template <class T> // <class T=void> in C++14
154struct logical_or : binary_function<T, T, bool>
155{
144struct logical_or {
156145 bool operator()(const T& x, const T& y) const;
157146};
158147
159148template <class T> // <class T=void> in C++14
160struct logical_not : unary_function<T, bool>
161{
149struct logical_not {
162150 bool operator()(const T& x) const;
163151};
164152
165153template <class T> // <class T=void> in C++14
166struct bit_and : unary_function<T, bool>
167{
168 bool operator()(const T& x, const T& y) const;
154struct bit_and {
155 T operator()(const T& x, const T& y) const;
169156};
170157
171158template <class T> // <class T=void> in C++14
172struct bit_or : unary_function<T, bool>
173{
174 bool operator()(const T& x, const T& y) const;
159struct bit_or {
160 T operator()(const T& x, const T& y) const;
175161};
176162
177163template <class T> // <class T=void> in C++14
178struct bit_xor : unary_function<T, bool>
179{
180 bool operator()(const T& x, const T& y) const;
164struct bit_xor {
165 T operator()(const T& x, const T& y) const;
181166};
182167
183168template <class T=void> // C++14
184struct bit_xor : unary_function<T, bool>
185{
186 bool operator()(const T& x) const;
169struct bit_not {
170 T operator()(const T& x) const;
187171};
188172
173struct identity; // C++20
174
189175template <class Predicate>
190class unary_negate // deprecated in C++17
176class unary_negate // deprecated in C++17, removed in C++20
191177 : public unary_function<typename Predicate::argument_type, bool>
192178{
193179public:
......@@ -195,11 +181,11 @@ public:
195181 bool operator()(const typename Predicate::argument_type& x) const;
196182};
197183
198template <class Predicate> // deprecated in C++17
184template <class Predicate> // deprecated in C++17, removed in C++20
199185unary_negate<Predicate> not1(const Predicate& pred);
200186
201187template <class Predicate>
202class binary_negate // deprecated in C++17
188class binary_negate // deprecated in C++17, removed in C++20
203189 : public binary_function<typename Predicate::first_argument_type,
204190 typename Predicate::second_argument_type,
205191 bool>
......@@ -210,7 +196,7 @@ public:
210196 const typename Predicate::second_argument_type& y) const;
211197};
212198
213template <class Predicate> // deprecated in C++17
199template <class Predicate> // deprecated in C++17, removed in C++20
214200binary_negate<Predicate> not2(const Predicate& pred);
215201
216202template <class F>
......@@ -501,2687 +487,43 @@ POLICY: For non-variadic implementations, the number of arguments is limited
501487
502488*/
503489
490#include <__algorithm/search.h>
504491#include <__config>
505#include <type_traits>
506#include <typeinfo>
492#include <__debug>
493#include <__functional/binary_function.h> // TODO: deprecate
494#include <__functional/binary_negate.h>
495#include <__functional/bind_front.h>
496#include <__functional/bind.h>
497#include <__functional/binder1st.h>
498#include <__functional/binder2nd.h>
499#include <__functional/default_searcher.h>
500#include <__functional/function.h>
501#include <__functional/hash.h>
502#include <__functional/identity.h>
503#include <__functional/invoke.h>
504#include <__functional/mem_fn.h> // TODO: deprecate
505#include <__functional/mem_fun_ref.h>
506#include <__functional/not_fn.h>
507#include <__functional/operations.h>
508#include <__functional/pointer_to_binary_function.h>
509#include <__functional/pointer_to_unary_function.h>
510#include <__functional/ranges_operations.h>
511#include <__functional/reference_wrapper.h>
512#include <__functional/unary_function.h> // TODO: deprecate
513#include <__functional/unary_negate.h>
514#include <__functional/unwrap_ref.h>
515#include <__utility/forward.h>
516#include <concepts>
507517#include <exception>
508518#include <memory>
509519#include <tuple>
520#include <type_traits>
521#include <typeinfo>
510522#include <utility>
511523#include <version>
512524
513#include <__functional_base>
514
515525#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
516526#pragma GCC system_header
517527#endif
518528
519_LIBCPP_BEGIN_NAMESPACE_STD
520
521#if _LIBCPP_STD_VER > 11
522template <class _Tp = void>
523#else
524template <class _Tp>
525#endif
526struct _LIBCPP_TEMPLATE_VIS plus : binary_function<_Tp, _Tp, _Tp>
527{
528 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
529 _Tp operator()(const _Tp& __x, const _Tp& __y) const
530 {return __x + __y;}
531};
532
533#if _LIBCPP_STD_VER > 11
534template <>
535struct _LIBCPP_TEMPLATE_VIS plus<void>
536{
537 template <class _T1, class _T2>
538 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
539 auto operator()(_T1&& __t, _T2&& __u) const
540 _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) + _VSTD::forward<_T2>(__u)))
541 -> decltype (_VSTD::forward<_T1>(__t) + _VSTD::forward<_T2>(__u))
542 { return _VSTD::forward<_T1>(__t) + _VSTD::forward<_T2>(__u); }
543 typedef void is_transparent;
544};
545#endif
546
547
548#if _LIBCPP_STD_VER > 11
549template <class _Tp = void>
550#else
551template <class _Tp>
552#endif
553struct _LIBCPP_TEMPLATE_VIS minus : binary_function<_Tp, _Tp, _Tp>
554{
555 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
556 _Tp operator()(const _Tp& __x, const _Tp& __y) const
557 {return __x - __y;}
558};
559
560#if _LIBCPP_STD_VER > 11
561template <>
562struct _LIBCPP_TEMPLATE_VIS minus<void>
563{
564 template <class _T1, class _T2>
565 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
566 auto operator()(_T1&& __t, _T2&& __u) const
567 _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) - _VSTD::forward<_T2>(__u)))
568 -> decltype (_VSTD::forward<_T1>(__t) - _VSTD::forward<_T2>(__u))
569 { return _VSTD::forward<_T1>(__t) - _VSTD::forward<_T2>(__u); }
570 typedef void is_transparent;
571};
572#endif
573
574
575#if _LIBCPP_STD_VER > 11
576template <class _Tp = void>
577#else
578template <class _Tp>
579#endif
580struct _LIBCPP_TEMPLATE_VIS multiplies : binary_function<_Tp, _Tp, _Tp>
581{
582 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
583 _Tp operator()(const _Tp& __x, const _Tp& __y) const
584 {return __x * __y;}
585};
586
587#if _LIBCPP_STD_VER > 11
588template <>
589struct _LIBCPP_TEMPLATE_VIS multiplies<void>
590{
591 template <class _T1, class _T2>
592 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
593 auto operator()(_T1&& __t, _T2&& __u) const
594 _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) * _VSTD::forward<_T2>(__u)))
595 -> decltype (_VSTD::forward<_T1>(__t) * _VSTD::forward<_T2>(__u))
596 { return _VSTD::forward<_T1>(__t) * _VSTD::forward<_T2>(__u); }
597 typedef void is_transparent;
598};
599#endif
600
601
602#if _LIBCPP_STD_VER > 11
603template <class _Tp = void>
604#else
605template <class _Tp>
606#endif
607struct _LIBCPP_TEMPLATE_VIS divides : binary_function<_Tp, _Tp, _Tp>
608{
609 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
610 _Tp operator()(const _Tp& __x, const _Tp& __y) const
611 {return __x / __y;}
612};
613
614#if _LIBCPP_STD_VER > 11
615template <>
616struct _LIBCPP_TEMPLATE_VIS divides<void>
617{
618 template <class _T1, class _T2>
619 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
620 auto operator()(_T1&& __t, _T2&& __u) const
621 _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) / _VSTD::forward<_T2>(__u)))
622 -> decltype (_VSTD::forward<_T1>(__t) / _VSTD::forward<_T2>(__u))
623 { return _VSTD::forward<_T1>(__t) / _VSTD::forward<_T2>(__u); }
624 typedef void is_transparent;
625};
626#endif
627
628
629#if _LIBCPP_STD_VER > 11
630template <class _Tp = void>
631#else
632template <class _Tp>
633#endif
634struct _LIBCPP_TEMPLATE_VIS modulus : binary_function<_Tp, _Tp, _Tp>
635{
636 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
637 _Tp operator()(const _Tp& __x, const _Tp& __y) const
638 {return __x % __y;}
639};
640
641#if _LIBCPP_STD_VER > 11
642template <>
643struct _LIBCPP_TEMPLATE_VIS modulus<void>
644{
645 template <class _T1, class _T2>
646 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
647 auto operator()(_T1&& __t, _T2&& __u) const
648 _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) % _VSTD::forward<_T2>(__u)))
649 -> decltype (_VSTD::forward<_T1>(__t) % _VSTD::forward<_T2>(__u))
650 { return _VSTD::forward<_T1>(__t) % _VSTD::forward<_T2>(__u); }
651 typedef void is_transparent;
652};
653#endif
654
655
656#if _LIBCPP_STD_VER > 11
657template <class _Tp = void>
658#else
659template <class _Tp>
660#endif
661struct _LIBCPP_TEMPLATE_VIS negate : unary_function<_Tp, _Tp>
662{
663 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
664 _Tp operator()(const _Tp& __x) const
665 {return -__x;}
666};
667
668#if _LIBCPP_STD_VER > 11
669template <>
670struct _LIBCPP_TEMPLATE_VIS negate<void>
671{
672 template <class _Tp>
673 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
674 auto operator()(_Tp&& __x) const
675 _NOEXCEPT_(noexcept(- _VSTD::forward<_Tp>(__x)))
676 -> decltype (- _VSTD::forward<_Tp>(__x))
677 { return - _VSTD::forward<_Tp>(__x); }
678 typedef void is_transparent;
679};
680#endif
681
682
683#if _LIBCPP_STD_VER > 11
684template <class _Tp = void>
685#else
686template <class _Tp>
687#endif
688struct _LIBCPP_TEMPLATE_VIS equal_to : binary_function<_Tp, _Tp, bool>
689{
690 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
691 bool operator()(const _Tp& __x, const _Tp& __y) const
692 {return __x == __y;}
693};
694
695#if _LIBCPP_STD_VER > 11
696template <>
697struct _LIBCPP_TEMPLATE_VIS equal_to<void>
698{
699 template <class _T1, class _T2>
700 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
701 auto operator()(_T1&& __t, _T2&& __u) const
702 _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) == _VSTD::forward<_T2>(__u)))
703 -> decltype (_VSTD::forward<_T1>(__t) == _VSTD::forward<_T2>(__u))
704 { return _VSTD::forward<_T1>(__t) == _VSTD::forward<_T2>(__u); }
705 typedef void is_transparent;
706};
707#endif
708
709
710#if _LIBCPP_STD_VER > 11
711template <class _Tp = void>
712#else
713template <class _Tp>
714#endif
715struct _LIBCPP_TEMPLATE_VIS not_equal_to : binary_function<_Tp, _Tp, bool>
716{
717 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
718 bool operator()(const _Tp& __x, const _Tp& __y) const
719 {return __x != __y;}
720};
721
722#if _LIBCPP_STD_VER > 11
723template <>
724struct _LIBCPP_TEMPLATE_VIS not_equal_to<void>
725{
726 template <class _T1, class _T2>
727 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
728 auto operator()(_T1&& __t, _T2&& __u) const
729 _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) != _VSTD::forward<_T2>(__u)))
730 -> decltype (_VSTD::forward<_T1>(__t) != _VSTD::forward<_T2>(__u))
731 { return _VSTD::forward<_T1>(__t) != _VSTD::forward<_T2>(__u); }
732 typedef void is_transparent;
733};
734#endif
735
736
737#if _LIBCPP_STD_VER > 11
738template <class _Tp = void>
739#else
740template <class _Tp>
741#endif
742struct _LIBCPP_TEMPLATE_VIS greater : binary_function<_Tp, _Tp, bool>
743{
744 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
745 bool operator()(const _Tp& __x, const _Tp& __y) const
746 {return __x > __y;}
747};
748
749#if _LIBCPP_STD_VER > 11
750template <>
751struct _LIBCPP_TEMPLATE_VIS greater<void>
752{
753 template <class _T1, class _T2>
754 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
755 auto operator()(_T1&& __t, _T2&& __u) const
756 _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) > _VSTD::forward<_T2>(__u)))
757 -> decltype (_VSTD::forward<_T1>(__t) > _VSTD::forward<_T2>(__u))
758 { return _VSTD::forward<_T1>(__t) > _VSTD::forward<_T2>(__u); }
759 typedef void is_transparent;
760};
761#endif
762
763
764// less in <__functional_base>
765
766#if _LIBCPP_STD_VER > 11
767template <class _Tp = void>
768#else
769template <class _Tp>
770#endif
771struct _LIBCPP_TEMPLATE_VIS greater_equal : binary_function<_Tp, _Tp, bool>
772{
773 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
774 bool operator()(const _Tp& __x, const _Tp& __y) const
775 {return __x >= __y;}
776};
777
778#if _LIBCPP_STD_VER > 11
779template <>
780struct _LIBCPP_TEMPLATE_VIS greater_equal<void>
781{
782 template <class _T1, class _T2>
783 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
784 auto operator()(_T1&& __t, _T2&& __u) const
785 _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) >= _VSTD::forward<_T2>(__u)))
786 -> decltype (_VSTD::forward<_T1>(__t) >= _VSTD::forward<_T2>(__u))
787 { return _VSTD::forward<_T1>(__t) >= _VSTD::forward<_T2>(__u); }
788 typedef void is_transparent;
789};
790#endif
791
792
793#if _LIBCPP_STD_VER > 11
794template <class _Tp = void>
795#else
796template <class _Tp>
797#endif
798struct _LIBCPP_TEMPLATE_VIS less_equal : binary_function<_Tp, _Tp, bool>
799{
800 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
801 bool operator()(const _Tp& __x, const _Tp& __y) const
802 {return __x <= __y;}
803};
804
805#if _LIBCPP_STD_VER > 11
806template <>
807struct _LIBCPP_TEMPLATE_VIS less_equal<void>
808{
809 template <class _T1, class _T2>
810 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
811 auto operator()(_T1&& __t, _T2&& __u) const
812 _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) <= _VSTD::forward<_T2>(__u)))
813 -> decltype (_VSTD::forward<_T1>(__t) <= _VSTD::forward<_T2>(__u))
814 { return _VSTD::forward<_T1>(__t) <= _VSTD::forward<_T2>(__u); }
815 typedef void is_transparent;
816};
817#endif
818
819
820#if _LIBCPP_STD_VER > 11
821template <class _Tp = void>
822#else
823template <class _Tp>
824#endif
825struct _LIBCPP_TEMPLATE_VIS logical_and : binary_function<_Tp, _Tp, bool>
826{
827 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
828 bool operator()(const _Tp& __x, const _Tp& __y) const
829 {return __x && __y;}
830};
831
832#if _LIBCPP_STD_VER > 11
833template <>
834struct _LIBCPP_TEMPLATE_VIS logical_and<void>
835{
836 template <class _T1, class _T2>
837 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
838 auto operator()(_T1&& __t, _T2&& __u) const
839 _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) && _VSTD::forward<_T2>(__u)))
840 -> decltype (_VSTD::forward<_T1>(__t) && _VSTD::forward<_T2>(__u))
841 { return _VSTD::forward<_T1>(__t) && _VSTD::forward<_T2>(__u); }
842 typedef void is_transparent;
843};
844#endif
845
846
847#if _LIBCPP_STD_VER > 11
848template <class _Tp = void>
849#else
850template <class _Tp>
851#endif
852struct _LIBCPP_TEMPLATE_VIS logical_or : binary_function<_Tp, _Tp, bool>
853{
854 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
855 bool operator()(const _Tp& __x, const _Tp& __y) const
856 {return __x || __y;}
857};
858
859#if _LIBCPP_STD_VER > 11
860template <>
861struct _LIBCPP_TEMPLATE_VIS logical_or<void>
862{
863 template <class _T1, class _T2>
864 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
865 auto operator()(_T1&& __t, _T2&& __u) const
866 _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) || _VSTD::forward<_T2>(__u)))
867 -> decltype (_VSTD::forward<_T1>(__t) || _VSTD::forward<_T2>(__u))
868 { return _VSTD::forward<_T1>(__t) || _VSTD::forward<_T2>(__u); }
869 typedef void is_transparent;
870};
871#endif
872
873
874#if _LIBCPP_STD_VER > 11
875template <class _Tp = void>
876#else
877template <class _Tp>
878#endif
879struct _LIBCPP_TEMPLATE_VIS logical_not : unary_function<_Tp, bool>
880{
881 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
882 bool operator()(const _Tp& __x) const
883 {return !__x;}
884};
885
886#if _LIBCPP_STD_VER > 11
887template <>
888struct _LIBCPP_TEMPLATE_VIS logical_not<void>
889{
890 template <class _Tp>
891 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
892 auto operator()(_Tp&& __x) const
893 _NOEXCEPT_(noexcept(!_VSTD::forward<_Tp>(__x)))
894 -> decltype (!_VSTD::forward<_Tp>(__x))
895 { return !_VSTD::forward<_Tp>(__x); }
896 typedef void is_transparent;
897};
898#endif
899
900
901#if _LIBCPP_STD_VER > 11
902template <class _Tp = void>
903#else
904template <class _Tp>
905#endif
906struct _LIBCPP_TEMPLATE_VIS bit_and : binary_function<_Tp, _Tp, _Tp>
907{
908 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
909 _Tp operator()(const _Tp& __x, const _Tp& __y) const
910 {return __x & __y;}
911};
912
913#if _LIBCPP_STD_VER > 11
914template <>
915struct _LIBCPP_TEMPLATE_VIS bit_and<void>
916{
917 template <class _T1, class _T2>
918 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
919 auto operator()(_T1&& __t, _T2&& __u) const
920 _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) & _VSTD::forward<_T2>(__u)))
921 -> decltype (_VSTD::forward<_T1>(__t) & _VSTD::forward<_T2>(__u))
922 { return _VSTD::forward<_T1>(__t) & _VSTD::forward<_T2>(__u); }
923 typedef void is_transparent;
924};
925#endif
926
927
928#if _LIBCPP_STD_VER > 11
929template <class _Tp = void>
930#else
931template <class _Tp>
932#endif
933struct _LIBCPP_TEMPLATE_VIS bit_or : binary_function<_Tp, _Tp, _Tp>
934{
935 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
936 _Tp operator()(const _Tp& __x, const _Tp& __y) const
937 {return __x | __y;}
938};
939
940#if _LIBCPP_STD_VER > 11
941template <>
942struct _LIBCPP_TEMPLATE_VIS bit_or<void>
943{
944 template <class _T1, class _T2>
945 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
946 auto operator()(_T1&& __t, _T2&& __u) const
947 _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) | _VSTD::forward<_T2>(__u)))
948 -> decltype (_VSTD::forward<_T1>(__t) | _VSTD::forward<_T2>(__u))
949 { return _VSTD::forward<_T1>(__t) | _VSTD::forward<_T2>(__u); }
950 typedef void is_transparent;
951};
952#endif
953
954
955#if _LIBCPP_STD_VER > 11
956template <class _Tp = void>
957#else
958template <class _Tp>
959#endif
960struct _LIBCPP_TEMPLATE_VIS bit_xor : binary_function<_Tp, _Tp, _Tp>
961{
962 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
963 _Tp operator()(const _Tp& __x, const _Tp& __y) const
964 {return __x ^ __y;}
965};
966
967#if _LIBCPP_STD_VER > 11
968template <>
969struct _LIBCPP_TEMPLATE_VIS bit_xor<void>
970{
971 template <class _T1, class _T2>
972 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
973 auto operator()(_T1&& __t, _T2&& __u) const
974 _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) ^ _VSTD::forward<_T2>(__u)))
975 -> decltype (_VSTD::forward<_T1>(__t) ^ _VSTD::forward<_T2>(__u))
976 { return _VSTD::forward<_T1>(__t) ^ _VSTD::forward<_T2>(__u); }
977 typedef void is_transparent;
978};
979#endif
980
981
982#if _LIBCPP_STD_VER > 11
983template <class _Tp = void>
984struct _LIBCPP_TEMPLATE_VIS bit_not : unary_function<_Tp, _Tp>
985{
986 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
987 _Tp operator()(const _Tp& __x) const
988 {return ~__x;}
989};
990
991template <>
992struct _LIBCPP_TEMPLATE_VIS bit_not<void>
993{
994 template <class _Tp>
995 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
996 auto operator()(_Tp&& __x) const
997 _NOEXCEPT_(noexcept(~_VSTD::forward<_Tp>(__x)))
998 -> decltype (~_VSTD::forward<_Tp>(__x))
999 { return ~_VSTD::forward<_Tp>(__x); }
1000 typedef void is_transparent;
1001};
1002#endif
1003
1004template <class _Predicate>
1005class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 unary_negate
1006 : public unary_function<typename _Predicate::argument_type, bool>
1007{
1008 _Predicate __pred_;
1009public:
1010 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
1011 explicit unary_negate(const _Predicate& __pred)
1012 : __pred_(__pred) {}
1013 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
1014 bool operator()(const typename _Predicate::argument_type& __x) const
1015 {return !__pred_(__x);}
1016};
1017
1018template <class _Predicate>
1019_LIBCPP_DEPRECATED_IN_CXX17 inline _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
1020unary_negate<_Predicate>
1021not1(const _Predicate& __pred) {return unary_negate<_Predicate>(__pred);}
1022
1023template <class _Predicate>
1024class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 binary_negate
1025 : public binary_function<typename _Predicate::first_argument_type,
1026 typename _Predicate::second_argument_type,
1027 bool>
1028{
1029 _Predicate __pred_;
1030public:
1031 _LIBCPP_INLINE_VISIBILITY explicit _LIBCPP_CONSTEXPR_AFTER_CXX11
1032 binary_negate(const _Predicate& __pred) : __pred_(__pred) {}
1033
1034 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
1035 bool operator()(const typename _Predicate::first_argument_type& __x,
1036 const typename _Predicate::second_argument_type& __y) const
1037 {return !__pred_(__x, __y);}
1038};
1039
1040template <class _Predicate>
1041_LIBCPP_DEPRECATED_IN_CXX17 inline _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
1042binary_negate<_Predicate>
1043not2(const _Predicate& __pred) {return binary_negate<_Predicate>(__pred);}
1044
1045#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS)
1046template <class __Operation>
1047class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 binder1st
1048 : public unary_function<typename __Operation::second_argument_type,
1049 typename __Operation::result_type>
1050{
1051protected:
1052 __Operation op;
1053 typename __Operation::first_argument_type value;
1054public:
1055 _LIBCPP_INLINE_VISIBILITY binder1st(const __Operation& __x,
1056 const typename __Operation::first_argument_type __y)
1057 : op(__x), value(__y) {}
1058 _LIBCPP_INLINE_VISIBILITY typename __Operation::result_type operator()
1059 (typename __Operation::second_argument_type& __x) const
1060 {return op(value, __x);}
1061 _LIBCPP_INLINE_VISIBILITY typename __Operation::result_type operator()
1062 (const typename __Operation::second_argument_type& __x) const
1063 {return op(value, __x);}
1064};
1065
1066template <class __Operation, class _Tp>
1067_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY
1068binder1st<__Operation>
1069bind1st(const __Operation& __op, const _Tp& __x)
1070 {return binder1st<__Operation>(__op, __x);}
1071
1072template <class __Operation>
1073class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 binder2nd
1074 : public unary_function<typename __Operation::first_argument_type,
1075 typename __Operation::result_type>
1076{
1077protected:
1078 __Operation op;
1079 typename __Operation::second_argument_type value;
1080public:
1081 _LIBCPP_INLINE_VISIBILITY
1082 binder2nd(const __Operation& __x, const typename __Operation::second_argument_type __y)
1083 : op(__x), value(__y) {}
1084 _LIBCPP_INLINE_VISIBILITY typename __Operation::result_type operator()
1085 ( typename __Operation::first_argument_type& __x) const
1086 {return op(__x, value);}
1087 _LIBCPP_INLINE_VISIBILITY typename __Operation::result_type operator()
1088 (const typename __Operation::first_argument_type& __x) const
1089 {return op(__x, value);}
1090};
1091
1092template <class __Operation, class _Tp>
1093_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY
1094binder2nd<__Operation>
1095bind2nd(const __Operation& __op, const _Tp& __x)
1096 {return binder2nd<__Operation>(__op, __x);}
1097
1098template <class _Arg, class _Result>
1099class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 pointer_to_unary_function
1100 : public unary_function<_Arg, _Result>
1101{
1102 _Result (*__f_)(_Arg);
1103public:
1104 _LIBCPP_INLINE_VISIBILITY explicit pointer_to_unary_function(_Result (*__f)(_Arg))
1105 : __f_(__f) {}
1106 _LIBCPP_INLINE_VISIBILITY _Result operator()(_Arg __x) const
1107 {return __f_(__x);}
1108};
1109
1110template <class _Arg, class _Result>
1111_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY
1112pointer_to_unary_function<_Arg,_Result>
1113ptr_fun(_Result (*__f)(_Arg))
1114 {return pointer_to_unary_function<_Arg,_Result>(__f);}
1115
1116template <class _Arg1, class _Arg2, class _Result>
1117class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 pointer_to_binary_function
1118 : public binary_function<_Arg1, _Arg2, _Result>
1119{
1120 _Result (*__f_)(_Arg1, _Arg2);
1121public:
1122 _LIBCPP_INLINE_VISIBILITY explicit pointer_to_binary_function(_Result (*__f)(_Arg1, _Arg2))
1123 : __f_(__f) {}
1124 _LIBCPP_INLINE_VISIBILITY _Result operator()(_Arg1 __x, _Arg2 __y) const
1125 {return __f_(__x, __y);}
1126};
1127
1128template <class _Arg1, class _Arg2, class _Result>
1129_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY
1130pointer_to_binary_function<_Arg1,_Arg2,_Result>
1131ptr_fun(_Result (*__f)(_Arg1,_Arg2))
1132 {return pointer_to_binary_function<_Arg1,_Arg2,_Result>(__f);}
1133
1134template<class _Sp, class _Tp>
1135class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 mem_fun_t
1136 : public unary_function<_Tp*, _Sp>
1137{
1138 _Sp (_Tp::*__p_)();
1139public:
1140 _LIBCPP_INLINE_VISIBILITY explicit mem_fun_t(_Sp (_Tp::*__p)())
1141 : __p_(__p) {}
1142 _LIBCPP_INLINE_VISIBILITY _Sp operator()(_Tp* __p) const
1143 {return (__p->*__p_)();}
1144};
1145
1146template<class _Sp, class _Tp, class _Ap>
1147class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 mem_fun1_t
1148 : public binary_function<_Tp*, _Ap, _Sp>
1149{
1150 _Sp (_Tp::*__p_)(_Ap);
1151public:
1152 _LIBCPP_INLINE_VISIBILITY explicit mem_fun1_t(_Sp (_Tp::*__p)(_Ap))
1153 : __p_(__p) {}
1154 _LIBCPP_INLINE_VISIBILITY _Sp operator()(_Tp* __p, _Ap __x) const
1155 {return (__p->*__p_)(__x);}
1156};
1157
1158template<class _Sp, class _Tp>
1159_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY
1160mem_fun_t<_Sp,_Tp>
1161mem_fun(_Sp (_Tp::*__f)())
1162 {return mem_fun_t<_Sp,_Tp>(__f);}
1163
1164template<class _Sp, class _Tp, class _Ap>
1165_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY
1166mem_fun1_t<_Sp,_Tp,_Ap>
1167mem_fun(_Sp (_Tp::*__f)(_Ap))
1168 {return mem_fun1_t<_Sp,_Tp,_Ap>(__f);}
1169
1170template<class _Sp, class _Tp>
1171class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 mem_fun_ref_t
1172 : public unary_function<_Tp, _Sp>
1173{
1174 _Sp (_Tp::*__p_)();
1175public:
1176 _LIBCPP_INLINE_VISIBILITY explicit mem_fun_ref_t(_Sp (_Tp::*__p)())
1177 : __p_(__p) {}
1178 _LIBCPP_INLINE_VISIBILITY _Sp operator()(_Tp& __p) const
1179 {return (__p.*__p_)();}
1180};
1181
1182template<class _Sp, class _Tp, class _Ap>
1183class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 mem_fun1_ref_t
1184 : public binary_function<_Tp, _Ap, _Sp>
1185{
1186 _Sp (_Tp::*__p_)(_Ap);
1187public:
1188 _LIBCPP_INLINE_VISIBILITY explicit mem_fun1_ref_t(_Sp (_Tp::*__p)(_Ap))
1189 : __p_(__p) {}
1190 _LIBCPP_INLINE_VISIBILITY _Sp operator()(_Tp& __p, _Ap __x) const
1191 {return (__p.*__p_)(__x);}
1192};
1193
1194template<class _Sp, class _Tp>
1195_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY
1196mem_fun_ref_t<_Sp,_Tp>
1197mem_fun_ref(_Sp (_Tp::*__f)())
1198 {return mem_fun_ref_t<_Sp,_Tp>(__f);}
1199
1200template<class _Sp, class _Tp, class _Ap>
1201_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY
1202mem_fun1_ref_t<_Sp,_Tp,_Ap>
1203mem_fun_ref(_Sp (_Tp::*__f)(_Ap))
1204 {return mem_fun1_ref_t<_Sp,_Tp,_Ap>(__f);}
1205
1206template <class _Sp, class _Tp>
1207class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 const_mem_fun_t
1208 : public unary_function<const _Tp*, _Sp>
1209{
1210 _Sp (_Tp::*__p_)() const;
1211public:
1212 _LIBCPP_INLINE_VISIBILITY explicit const_mem_fun_t(_Sp (_Tp::*__p)() const)
1213 : __p_(__p) {}
1214 _LIBCPP_INLINE_VISIBILITY _Sp operator()(const _Tp* __p) const
1215 {return (__p->*__p_)();}
1216};
1217
1218template <class _Sp, class _Tp, class _Ap>
1219class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 const_mem_fun1_t
1220 : public binary_function<const _Tp*, _Ap, _Sp>
1221{
1222 _Sp (_Tp::*__p_)(_Ap) const;
1223public:
1224 _LIBCPP_INLINE_VISIBILITY explicit const_mem_fun1_t(_Sp (_Tp::*__p)(_Ap) const)
1225 : __p_(__p) {}
1226 _LIBCPP_INLINE_VISIBILITY _Sp operator()(const _Tp* __p, _Ap __x) const
1227 {return (__p->*__p_)(__x);}
1228};
1229
1230template <class _Sp, class _Tp>
1231_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY
1232const_mem_fun_t<_Sp,_Tp>
1233mem_fun(_Sp (_Tp::*__f)() const)
1234 {return const_mem_fun_t<_Sp,_Tp>(__f);}
1235
1236template <class _Sp, class _Tp, class _Ap>
1237_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY
1238const_mem_fun1_t<_Sp,_Tp,_Ap>
1239mem_fun(_Sp (_Tp::*__f)(_Ap) const)
1240 {return const_mem_fun1_t<_Sp,_Tp,_Ap>(__f);}
1241
1242template <class _Sp, class _Tp>
1243class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 const_mem_fun_ref_t
1244 : public unary_function<_Tp, _Sp>
1245{
1246 _Sp (_Tp::*__p_)() const;
1247public:
1248 _LIBCPP_INLINE_VISIBILITY explicit const_mem_fun_ref_t(_Sp (_Tp::*__p)() const)
1249 : __p_(__p) {}
1250 _LIBCPP_INLINE_VISIBILITY _Sp operator()(const _Tp& __p) const
1251 {return (__p.*__p_)();}
1252};
1253
1254template <class _Sp, class _Tp, class _Ap>
1255class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 const_mem_fun1_ref_t
1256 : public binary_function<_Tp, _Ap, _Sp>
1257{
1258 _Sp (_Tp::*__p_)(_Ap) const;
1259public:
1260 _LIBCPP_INLINE_VISIBILITY explicit const_mem_fun1_ref_t(_Sp (_Tp::*__p)(_Ap) const)
1261 : __p_(__p) {}
1262 _LIBCPP_INLINE_VISIBILITY _Sp operator()(const _Tp& __p, _Ap __x) const
1263 {return (__p.*__p_)(__x);}
1264};
1265
1266template <class _Sp, class _Tp>
1267_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY
1268const_mem_fun_ref_t<_Sp,_Tp>
1269mem_fun_ref(_Sp (_Tp::*__f)() const)
1270 {return const_mem_fun_ref_t<_Sp,_Tp>(__f);}
1271
1272template <class _Sp, class _Tp, class _Ap>
1273_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY
1274const_mem_fun1_ref_t<_Sp,_Tp,_Ap>
1275mem_fun_ref(_Sp (_Tp::*__f)(_Ap) const)
1276 {return const_mem_fun1_ref_t<_Sp,_Tp,_Ap>(__f);}
1277#endif
1278
1279////////////////////////////////////////////////////////////////////////////////
1280// MEMFUN
1281//==============================================================================
1282
1283template <class _Tp>
1284class __mem_fn
1285 : public __weak_result_type<_Tp>
1286{
1287public:
1288 // types
1289 typedef _Tp type;
1290private:
1291 type __f_;
1292
1293public:
1294 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1295 __mem_fn(type __f) _NOEXCEPT : __f_(__f) {}
1296
1297#ifndef _LIBCPP_CXX03_LANG
1298 // invoke
1299 template <class... _ArgTypes>
1300 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1301 typename __invoke_return<type, _ArgTypes...>::type
1302 operator() (_ArgTypes&&... __args) const {
1303 return _VSTD::__invoke(__f_, _VSTD::forward<_ArgTypes>(__args)...);
1304 }
1305#else
1306
1307 template <class _A0>
1308 _LIBCPP_INLINE_VISIBILITY
1309 typename __invoke_return0<type, _A0>::type
1310 operator() (_A0& __a0) const {
1311 return _VSTD::__invoke(__f_, __a0);
1312 }
1313
1314 template <class _A0>
1315 _LIBCPP_INLINE_VISIBILITY
1316 typename __invoke_return0<type, _A0 const>::type
1317 operator() (_A0 const& __a0) const {
1318 return _VSTD::__invoke(__f_, __a0);
1319 }
1320
1321 template <class _A0, class _A1>
1322 _LIBCPP_INLINE_VISIBILITY
1323 typename __invoke_return1<type, _A0, _A1>::type
1324 operator() (_A0& __a0, _A1& __a1) const {
1325 return _VSTD::__invoke(__f_, __a0, __a1);
1326 }
1327
1328 template <class _A0, class _A1>
1329 _LIBCPP_INLINE_VISIBILITY
1330 typename __invoke_return1<type, _A0 const, _A1>::type
1331 operator() (_A0 const& __a0, _A1& __a1) const {
1332 return _VSTD::__invoke(__f_, __a0, __a1);
1333 }
1334
1335 template <class _A0, class _A1>
1336 _LIBCPP_INLINE_VISIBILITY
1337 typename __invoke_return1<type, _A0, _A1 const>::type
1338 operator() (_A0& __a0, _A1 const& __a1) const {
1339 return _VSTD::__invoke(__f_, __a0, __a1);
1340 }
1341
1342 template <class _A0, class _A1>
1343 _LIBCPP_INLINE_VISIBILITY
1344 typename __invoke_return1<type, _A0 const, _A1 const>::type
1345 operator() (_A0 const& __a0, _A1 const& __a1) const {
1346 return _VSTD::__invoke(__f_, __a0, __a1);
1347 }
1348
1349 template <class _A0, class _A1, class _A2>
1350 _LIBCPP_INLINE_VISIBILITY
1351 typename __invoke_return2<type, _A0, _A1, _A2>::type
1352 operator() (_A0& __a0, _A1& __a1, _A2& __a2) const {
1353 return _VSTD::__invoke(__f_, __a0, __a1, __a2);
1354 }
1355
1356 template <class _A0, class _A1, class _A2>
1357 _LIBCPP_INLINE_VISIBILITY
1358 typename __invoke_return2<type, _A0 const, _A1, _A2>::type
1359 operator() (_A0 const& __a0, _A1& __a1, _A2& __a2) const {
1360 return _VSTD::__invoke(__f_, __a0, __a1, __a2);
1361 }
1362
1363 template <class _A0, class _A1, class _A2>
1364 _LIBCPP_INLINE_VISIBILITY
1365 typename __invoke_return2<type, _A0, _A1 const, _A2>::type
1366 operator() (_A0& __a0, _A1 const& __a1, _A2& __a2) const {
1367 return _VSTD::__invoke(__f_, __a0, __a1, __a2);
1368 }
1369
1370 template <class _A0, class _A1, class _A2>
1371 _LIBCPP_INLINE_VISIBILITY
1372 typename __invoke_return2<type, _A0, _A1, _A2 const>::type
1373 operator() (_A0& __a0, _A1& __a1, _A2 const& __a2) const {
1374 return _VSTD::__invoke(__f_, __a0, __a1, __a2);
1375 }
1376
1377 template <class _A0, class _A1, class _A2>
1378 _LIBCPP_INLINE_VISIBILITY
1379 typename __invoke_return2<type, _A0 const, _A1 const, _A2>::type
1380 operator() (_A0 const& __a0, _A1 const& __a1, _A2& __a2) const {
1381 return _VSTD::__invoke(__f_, __a0, __a1, __a2);
1382 }
1383
1384 template <class _A0, class _A1, class _A2>
1385 _LIBCPP_INLINE_VISIBILITY
1386 typename __invoke_return2<type, _A0 const, _A1, _A2 const>::type
1387 operator() (_A0 const& __a0, _A1& __a1, _A2 const& __a2) const {
1388 return _VSTD::__invoke(__f_, __a0, __a1, __a2);
1389 }
1390
1391 template <class _A0, class _A1, class _A2>
1392 _LIBCPP_INLINE_VISIBILITY
1393 typename __invoke_return2<type, _A0, _A1 const, _A2 const>::type
1394 operator() (_A0& __a0, _A1 const& __a1, _A2 const& __a2) const {
1395 return _VSTD::__invoke(__f_, __a0, __a1, __a2);
1396 }
1397
1398 template <class _A0, class _A1, class _A2>
1399 _LIBCPP_INLINE_VISIBILITY
1400 typename __invoke_return2<type, _A0 const, _A1 const, _A2 const>::type
1401 operator() (_A0 const& __a0, _A1 const& __a1, _A2 const& __a2) const {
1402 return _VSTD::__invoke(__f_, __a0, __a1, __a2);
1403 }
1404#endif
1405};
1406
1407template<class _Rp, class _Tp>
1408inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1409__mem_fn<_Rp _Tp::*>
1410mem_fn(_Rp _Tp::* __pm) _NOEXCEPT
1411{
1412 return __mem_fn<_Rp _Tp::*>(__pm);
1413}
1414
1415////////////////////////////////////////////////////////////////////////////////
1416// FUNCTION
1417//==============================================================================
1418
1419// bad_function_call
1420
1421class _LIBCPP_EXCEPTION_ABI bad_function_call
1422 : public exception
1423{
1424#ifdef _LIBCPP_ABI_BAD_FUNCTION_CALL_KEY_FUNCTION
1425public:
1426 virtual ~bad_function_call() _NOEXCEPT;
1427
1428 virtual const char* what() const _NOEXCEPT;
1429#endif
1430};
1431
1432_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
1433void __throw_bad_function_call()
1434{
1435#ifndef _LIBCPP_NO_EXCEPTIONS
1436 throw bad_function_call();
1437#else
1438 _VSTD::abort();
1439#endif
1440}
1441
1442#if defined(_LIBCPP_CXX03_LANG) && !defined(_LIBCPP_DISABLE_DEPRECATION_WARNINGS) && __has_attribute(deprecated)
1443# define _LIBCPP_DEPRECATED_CXX03_FUNCTION \
1444 __attribute__((deprecated("Using std::function in C++03 is not supported anymore. Please upgrade to C++11 or later, or use a different type")))
1445#else
1446# define _LIBCPP_DEPRECATED_CXX03_FUNCTION /* nothing */
1447#endif
1448
1449template<class _Fp> class _LIBCPP_DEPRECATED_CXX03_FUNCTION _LIBCPP_TEMPLATE_VIS function; // undefined
1450
1451namespace __function
1452{
1453
1454template<class _Rp>
1455struct __maybe_derive_from_unary_function
1456{
1457};
1458
1459template<class _Rp, class _A1>
1460struct __maybe_derive_from_unary_function<_Rp(_A1)>
1461 : public unary_function<_A1, _Rp>
1462{
1463};
1464
1465template<class _Rp>
1466struct __maybe_derive_from_binary_function
1467{
1468};
1469
1470template<class _Rp, class _A1, class _A2>
1471struct __maybe_derive_from_binary_function<_Rp(_A1, _A2)>
1472 : public binary_function<_A1, _A2, _Rp>
1473{
1474};
1475
1476template <class _Fp>
1477_LIBCPP_INLINE_VISIBILITY
1478bool __not_null(_Fp const&) { return true; }
1479
1480template <class _Fp>
1481_LIBCPP_INLINE_VISIBILITY
1482bool __not_null(_Fp* __ptr) { return __ptr; }
1483
1484template <class _Ret, class _Class>
1485_LIBCPP_INLINE_VISIBILITY
1486bool __not_null(_Ret _Class::*__ptr) { return __ptr; }
1487
1488template <class _Fp>
1489_LIBCPP_INLINE_VISIBILITY
1490bool __not_null(function<_Fp> const& __f) { return !!__f; }
1491
1492#ifdef _LIBCPP_HAS_EXTENSION_BLOCKS
1493template <class _Rp, class ..._Args>
1494_LIBCPP_INLINE_VISIBILITY
1495bool __not_null(_Rp (^__p)(_Args...)) { return __p; }
1496#endif
1497
1498} // namespace __function
1499
1500#ifndef _LIBCPP_CXX03_LANG
1501
1502namespace __function {
1503
1504// __alloc_func holds a functor and an allocator.
1505
1506template <class _Fp, class _Ap, class _FB> class __alloc_func;
1507template <class _Fp, class _FB>
1508class __default_alloc_func;
1509
1510template <class _Fp, class _Ap, class _Rp, class... _ArgTypes>
1511class __alloc_func<_Fp, _Ap, _Rp(_ArgTypes...)>
1512{
1513 __compressed_pair<_Fp, _Ap> __f_;
1514
1515 public:
1516 typedef _LIBCPP_NODEBUG_TYPE _Fp _Target;
1517 typedef _LIBCPP_NODEBUG_TYPE _Ap _Alloc;
1518
1519 _LIBCPP_INLINE_VISIBILITY
1520 const _Target& __target() const { return __f_.first(); }
1521
1522 // WIN32 APIs may define __allocator, so use __get_allocator instead.
1523 _LIBCPP_INLINE_VISIBILITY
1524 const _Alloc& __get_allocator() const { return __f_.second(); }
1525
1526 _LIBCPP_INLINE_VISIBILITY
1527 explicit __alloc_func(_Target&& __f)
1528 : __f_(piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__f)),
1529 _VSTD::forward_as_tuple())
1530 {
1531 }
1532
1533 _LIBCPP_INLINE_VISIBILITY
1534 explicit __alloc_func(const _Target& __f, const _Alloc& __a)
1535 : __f_(piecewise_construct, _VSTD::forward_as_tuple(__f),
1536 _VSTD::forward_as_tuple(__a))
1537 {
1538 }
1539
1540 _LIBCPP_INLINE_VISIBILITY
1541 explicit __alloc_func(const _Target& __f, _Alloc&& __a)
1542 : __f_(piecewise_construct, _VSTD::forward_as_tuple(__f),
1543 _VSTD::forward_as_tuple(_VSTD::move(__a)))
1544 {
1545 }
1546
1547 _LIBCPP_INLINE_VISIBILITY
1548 explicit __alloc_func(_Target&& __f, _Alloc&& __a)
1549 : __f_(piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__f)),
1550 _VSTD::forward_as_tuple(_VSTD::move(__a)))
1551 {
1552 }
1553
1554 _LIBCPP_INLINE_VISIBILITY
1555 _Rp operator()(_ArgTypes&&... __arg)
1556 {
1557 typedef __invoke_void_return_wrapper<_Rp> _Invoker;
1558 return _Invoker::__call(__f_.first(),
1559 _VSTD::forward<_ArgTypes>(__arg)...);
1560 }
1561
1562 _LIBCPP_INLINE_VISIBILITY
1563 __alloc_func* __clone() const
1564 {
1565 typedef allocator_traits<_Alloc> __alloc_traits;
1566 typedef
1567 typename __rebind_alloc_helper<__alloc_traits, __alloc_func>::type
1568 _AA;
1569 _AA __a(__f_.second());
1570 typedef __allocator_destructor<_AA> _Dp;
1571 unique_ptr<__alloc_func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1572 ::new ((void*)__hold.get()) __alloc_func(__f_.first(), _Alloc(__a));
1573 return __hold.release();
1574 }
1575
1576 _LIBCPP_INLINE_VISIBILITY
1577 void destroy() _NOEXCEPT { __f_.~__compressed_pair<_Target, _Alloc>(); }
1578
1579 static void __destroy_and_delete(__alloc_func* __f) {
1580 typedef allocator_traits<_Alloc> __alloc_traits;
1581 typedef typename __rebind_alloc_helper<__alloc_traits, __alloc_func>::type
1582 _FunAlloc;
1583 _FunAlloc __a(__f->__get_allocator());
1584 __f->destroy();
1585 __a.deallocate(__f, 1);
1586 }
1587};
1588
1589template <class _Fp, class _Rp, class... _ArgTypes>
1590class __default_alloc_func<_Fp, _Rp(_ArgTypes...)> {
1591 _Fp __f_;
1592
1593public:
1594 typedef _LIBCPP_NODEBUG_TYPE _Fp _Target;
1595
1596 _LIBCPP_INLINE_VISIBILITY
1597 const _Target& __target() const { return __f_; }
1598
1599 _LIBCPP_INLINE_VISIBILITY
1600 explicit __default_alloc_func(_Target&& __f) : __f_(_VSTD::move(__f)) {}
1601
1602 _LIBCPP_INLINE_VISIBILITY
1603 explicit __default_alloc_func(const _Target& __f) : __f_(__f) {}
1604
1605 _LIBCPP_INLINE_VISIBILITY
1606 _Rp operator()(_ArgTypes&&... __arg) {
1607 typedef __invoke_void_return_wrapper<_Rp> _Invoker;
1608 return _Invoker::__call(__f_, _VSTD::forward<_ArgTypes>(__arg)...);
1609 }
1610
1611 _LIBCPP_INLINE_VISIBILITY
1612 __default_alloc_func* __clone() const {
1613 __builtin_new_allocator::__holder_t __hold =
1614 __builtin_new_allocator::__allocate_type<__default_alloc_func>(1);
1615 __default_alloc_func* __res =
1616 ::new ((void*)__hold.get()) __default_alloc_func(__f_);
1617 (void)__hold.release();
1618 return __res;
1619 }
1620
1621 _LIBCPP_INLINE_VISIBILITY
1622 void destroy() _NOEXCEPT { __f_.~_Target(); }
1623
1624 static void __destroy_and_delete(__default_alloc_func* __f) {
1625 __f->destroy();
1626 __builtin_new_allocator::__deallocate_type<__default_alloc_func>(__f, 1);
1627 }
1628};
1629
1630// __base provides an abstract interface for copyable functors.
1631
1632template<class _Fp> class _LIBCPP_TEMPLATE_VIS __base;
1633
1634template<class _Rp, class ..._ArgTypes>
1635class __base<_Rp(_ArgTypes...)>
1636{
1637 __base(const __base&);
1638 __base& operator=(const __base&);
1639public:
1640 _LIBCPP_INLINE_VISIBILITY __base() {}
1641 _LIBCPP_INLINE_VISIBILITY virtual ~__base() {}
1642 virtual __base* __clone() const = 0;
1643 virtual void __clone(__base*) const = 0;
1644 virtual void destroy() _NOEXCEPT = 0;
1645 virtual void destroy_deallocate() _NOEXCEPT = 0;
1646 virtual _Rp operator()(_ArgTypes&& ...) = 0;
1647#ifndef _LIBCPP_NO_RTTI
1648 virtual const void* target(const type_info&) const _NOEXCEPT = 0;
1649 virtual const std::type_info& target_type() const _NOEXCEPT = 0;
1650#endif // _LIBCPP_NO_RTTI
1651};
1652
1653// __func implements __base for a given functor type.
1654
1655template<class _FD, class _Alloc, class _FB> class __func;
1656
1657template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1658class __func<_Fp, _Alloc, _Rp(_ArgTypes...)>
1659 : public __base<_Rp(_ArgTypes...)>
1660{
1661 __alloc_func<_Fp, _Alloc, _Rp(_ArgTypes...)> __f_;
1662public:
1663 _LIBCPP_INLINE_VISIBILITY
1664 explicit __func(_Fp&& __f)
1665 : __f_(_VSTD::move(__f)) {}
1666
1667 _LIBCPP_INLINE_VISIBILITY
1668 explicit __func(const _Fp& __f, const _Alloc& __a)
1669 : __f_(__f, __a) {}
1670
1671 _LIBCPP_INLINE_VISIBILITY
1672 explicit __func(const _Fp& __f, _Alloc&& __a)
1673 : __f_(__f, _VSTD::move(__a)) {}
1674
1675 _LIBCPP_INLINE_VISIBILITY
1676 explicit __func(_Fp&& __f, _Alloc&& __a)
1677 : __f_(_VSTD::move(__f), _VSTD::move(__a)) {}
1678
1679 virtual __base<_Rp(_ArgTypes...)>* __clone() const;
1680 virtual void __clone(__base<_Rp(_ArgTypes...)>*) const;
1681 virtual void destroy() _NOEXCEPT;
1682 virtual void destroy_deallocate() _NOEXCEPT;
1683 virtual _Rp operator()(_ArgTypes&&... __arg);
1684#ifndef _LIBCPP_NO_RTTI
1685 virtual const void* target(const type_info&) const _NOEXCEPT;
1686 virtual const std::type_info& target_type() const _NOEXCEPT;
1687#endif // _LIBCPP_NO_RTTI
1688};
1689
1690template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1691__base<_Rp(_ArgTypes...)>*
1692__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__clone() const
1693{
1694 typedef allocator_traits<_Alloc> __alloc_traits;
1695 typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
1696 _Ap __a(__f_.__get_allocator());
1697 typedef __allocator_destructor<_Ap> _Dp;
1698 unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1699 ::new ((void*)__hold.get()) __func(__f_.__target(), _Alloc(__a));
1700 return __hold.release();
1701}
1702
1703template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1704void
1705__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__clone(__base<_Rp(_ArgTypes...)>* __p) const
1706{
1707 ::new ((void*)__p) __func(__f_.__target(), __f_.__get_allocator());
1708}
1709
1710template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1711void
1712__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy() _NOEXCEPT
1713{
1714 __f_.destroy();
1715}
1716
1717template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1718void
1719__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate() _NOEXCEPT
1720{
1721 typedef allocator_traits<_Alloc> __alloc_traits;
1722 typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
1723 _Ap __a(__f_.__get_allocator());
1724 __f_.destroy();
1725 __a.deallocate(this, 1);
1726}
1727
1728template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1729_Rp
1730__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg)
1731{
1732 return __f_(_VSTD::forward<_ArgTypes>(__arg)...);
1733}
1734
1735#ifndef _LIBCPP_NO_RTTI
1736
1737template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1738const void*
1739__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::target(const type_info& __ti) const _NOEXCEPT
1740{
1741 if (__ti == typeid(_Fp))
1742 return &__f_.__target();
1743 return nullptr;
1744}
1745
1746template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1747const std::type_info&
1748__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::target_type() const _NOEXCEPT
1749{
1750 return typeid(_Fp);
1751}
1752
1753#endif // _LIBCPP_NO_RTTI
1754
1755// __value_func creates a value-type from a __func.
1756
1757template <class _Fp> class __value_func;
1758
1759template <class _Rp, class... _ArgTypes> class __value_func<_Rp(_ArgTypes...)>
1760{
1761 typename aligned_storage<3 * sizeof(void*)>::type __buf_;
1762
1763 typedef __base<_Rp(_ArgTypes...)> __func;
1764 __func* __f_;
1765
1766 _LIBCPP_NO_CFI static __func* __as_base(void* p)
1767 {
1768 return reinterpret_cast<__func*>(p);
1769 }
1770
1771 public:
1772 _LIBCPP_INLINE_VISIBILITY
1773 __value_func() _NOEXCEPT : __f_(nullptr) {}
1774
1775 template <class _Fp, class _Alloc>
1776 _LIBCPP_INLINE_VISIBILITY __value_func(_Fp&& __f, const _Alloc& __a)
1777 : __f_(nullptr)
1778 {
1779 typedef allocator_traits<_Alloc> __alloc_traits;
1780 typedef __function::__func<_Fp, _Alloc, _Rp(_ArgTypes...)> _Fun;
1781 typedef typename __rebind_alloc_helper<__alloc_traits, _Fun>::type
1782 _FunAlloc;
1783
1784 if (__function::__not_null(__f))
1785 {
1786 _FunAlloc __af(__a);
1787 if (sizeof(_Fun) <= sizeof(__buf_) &&
1788 is_nothrow_copy_constructible<_Fp>::value &&
1789 is_nothrow_copy_constructible<_FunAlloc>::value)
1790 {
1791 __f_ =
1792 ::new ((void*)&__buf_) _Fun(_VSTD::move(__f), _Alloc(__af));
1793 }
1794 else
1795 {
1796 typedef __allocator_destructor<_FunAlloc> _Dp;
1797 unique_ptr<__func, _Dp> __hold(__af.allocate(1), _Dp(__af, 1));
1798 ::new ((void*)__hold.get()) _Fun(_VSTD::move(__f), _Alloc(__a));
1799 __f_ = __hold.release();
1800 }
1801 }
1802 }
1803
1804 template <class _Fp,
1805 class = typename enable_if<!is_same<typename decay<_Fp>::type, __value_func>::value>::type>
1806 _LIBCPP_INLINE_VISIBILITY explicit __value_func(_Fp&& __f)
1807 : __value_func(_VSTD::forward<_Fp>(__f), allocator<_Fp>()) {}
1808
1809 _LIBCPP_INLINE_VISIBILITY
1810 __value_func(const __value_func& __f)
1811 {
1812 if (__f.__f_ == nullptr)
1813 __f_ = nullptr;
1814 else if ((void*)__f.__f_ == &__f.__buf_)
1815 {
1816 __f_ = __as_base(&__buf_);
1817 __f.__f_->__clone(__f_);
1818 }
1819 else
1820 __f_ = __f.__f_->__clone();
1821 }
1822
1823 _LIBCPP_INLINE_VISIBILITY
1824 __value_func(__value_func&& __f) _NOEXCEPT
1825 {
1826 if (__f.__f_ == nullptr)
1827 __f_ = nullptr;
1828 else if ((void*)__f.__f_ == &__f.__buf_)
1829 {
1830 __f_ = __as_base(&__buf_);
1831 __f.__f_->__clone(__f_);
1832 }
1833 else
1834 {
1835 __f_ = __f.__f_;
1836 __f.__f_ = nullptr;
1837 }
1838 }
1839
1840 _LIBCPP_INLINE_VISIBILITY
1841 ~__value_func()
1842 {
1843 if ((void*)__f_ == &__buf_)
1844 __f_->destroy();
1845 else if (__f_)
1846 __f_->destroy_deallocate();
1847 }
1848
1849 _LIBCPP_INLINE_VISIBILITY
1850 __value_func& operator=(__value_func&& __f)
1851 {
1852 *this = nullptr;
1853 if (__f.__f_ == nullptr)
1854 __f_ = nullptr;
1855 else if ((void*)__f.__f_ == &__f.__buf_)
1856 {
1857 __f_ = __as_base(&__buf_);
1858 __f.__f_->__clone(__f_);
1859 }
1860 else
1861 {
1862 __f_ = __f.__f_;
1863 __f.__f_ = nullptr;
1864 }
1865 return *this;
1866 }
1867
1868 _LIBCPP_INLINE_VISIBILITY
1869 __value_func& operator=(nullptr_t)
1870 {
1871 __func* __f = __f_;
1872 __f_ = nullptr;
1873 if ((void*)__f == &__buf_)
1874 __f->destroy();
1875 else if (__f)
1876 __f->destroy_deallocate();
1877 return *this;
1878 }
1879
1880 _LIBCPP_INLINE_VISIBILITY
1881 _Rp operator()(_ArgTypes&&... __args) const
1882 {
1883 if (__f_ == nullptr)
1884 __throw_bad_function_call();
1885 return (*__f_)(_VSTD::forward<_ArgTypes>(__args)...);
1886 }
1887
1888 _LIBCPP_INLINE_VISIBILITY
1889 void swap(__value_func& __f) _NOEXCEPT
1890 {
1891 if (&__f == this)
1892 return;
1893 if ((void*)__f_ == &__buf_ && (void*)__f.__f_ == &__f.__buf_)
1894 {
1895 typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
1896 __func* __t = __as_base(&__tempbuf);
1897 __f_->__clone(__t);
1898 __f_->destroy();
1899 __f_ = nullptr;
1900 __f.__f_->__clone(__as_base(&__buf_));
1901 __f.__f_->destroy();
1902 __f.__f_ = nullptr;
1903 __f_ = __as_base(&__buf_);
1904 __t->__clone(__as_base(&__f.__buf_));
1905 __t->destroy();
1906 __f.__f_ = __as_base(&__f.__buf_);
1907 }
1908 else if ((void*)__f_ == &__buf_)
1909 {
1910 __f_->__clone(__as_base(&__f.__buf_));
1911 __f_->destroy();
1912 __f_ = __f.__f_;
1913 __f.__f_ = __as_base(&__f.__buf_);
1914 }
1915 else if ((void*)__f.__f_ == &__f.__buf_)
1916 {
1917 __f.__f_->__clone(__as_base(&__buf_));
1918 __f.__f_->destroy();
1919 __f.__f_ = __f_;
1920 __f_ = __as_base(&__buf_);
1921 }
1922 else
1923 _VSTD::swap(__f_, __f.__f_);
1924 }
1925
1926 _LIBCPP_INLINE_VISIBILITY
1927 _LIBCPP_EXPLICIT operator bool() const _NOEXCEPT { return __f_ != nullptr; }
1928
1929#ifndef _LIBCPP_NO_RTTI
1930 _LIBCPP_INLINE_VISIBILITY
1931 const std::type_info& target_type() const _NOEXCEPT
1932 {
1933 if (__f_ == nullptr)
1934 return typeid(void);
1935 return __f_->target_type();
1936 }
1937
1938 template <typename _Tp>
1939 _LIBCPP_INLINE_VISIBILITY const _Tp* target() const _NOEXCEPT
1940 {
1941 if (__f_ == nullptr)
1942 return nullptr;
1943 return (const _Tp*)__f_->target(typeid(_Tp));
1944 }
1945#endif // _LIBCPP_NO_RTTI
1946};
1947
1948// Storage for a functor object, to be used with __policy to manage copy and
1949// destruction.
1950union __policy_storage
1951{
1952 mutable char __small[sizeof(void*) * 2];
1953 void* __large;
1954};
1955
1956// True if _Fun can safely be held in __policy_storage.__small.
1957template <typename _Fun>
1958struct __use_small_storage
1959 : public _VSTD::integral_constant<
1960 bool, sizeof(_Fun) <= sizeof(__policy_storage) &&
1961 _LIBCPP_ALIGNOF(_Fun) <= _LIBCPP_ALIGNOF(__policy_storage) &&
1962 _VSTD::is_trivially_copy_constructible<_Fun>::value &&
1963 _VSTD::is_trivially_destructible<_Fun>::value> {};
1964
1965// Policy contains information about how to copy, destroy, and move the
1966// underlying functor. You can think of it as a vtable of sorts.
1967struct __policy
1968{
1969 // Used to copy or destroy __large values. null for trivial objects.
1970 void* (*const __clone)(const void*);
1971 void (*const __destroy)(void*);
1972
1973 // True if this is the null policy (no value).
1974 const bool __is_null;
1975
1976 // The target type. May be null if RTTI is disabled.
1977 const std::type_info* const __type_info;
1978
1979 // Returns a pointer to a static policy object suitable for the functor
1980 // type.
1981 template <typename _Fun>
1982 _LIBCPP_INLINE_VISIBILITY static const __policy* __create()
1983 {
1984 return __choose_policy<_Fun>(__use_small_storage<_Fun>());
1985 }
1986
1987 _LIBCPP_INLINE_VISIBILITY
1988 static const __policy* __create_empty()
1989 {
1990 static const _LIBCPP_CONSTEXPR __policy __policy_ = {nullptr, nullptr,
1991 true,
1992#ifndef _LIBCPP_NO_RTTI
1993 &typeid(void)
1994#else
1995 nullptr
1996#endif
1997 };
1998 return &__policy_;
1999 }
2000
2001 private:
2002 template <typename _Fun> static void* __large_clone(const void* __s)
2003 {
2004 const _Fun* __f = static_cast<const _Fun*>(__s);
2005 return __f->__clone();
2006 }
2007
2008 template <typename _Fun>
2009 static void __large_destroy(void* __s) {
2010 _Fun::__destroy_and_delete(static_cast<_Fun*>(__s));
2011 }
2012
2013 template <typename _Fun>
2014 _LIBCPP_INLINE_VISIBILITY static const __policy*
2015 __choose_policy(/* is_small = */ false_type) {
2016 static const _LIBCPP_CONSTEXPR __policy __policy_ = {
2017 &__large_clone<_Fun>, &__large_destroy<_Fun>, false,
2018#ifndef _LIBCPP_NO_RTTI
2019 &typeid(typename _Fun::_Target)
2020#else
2021 nullptr
2022#endif
2023 };
2024 return &__policy_;
2025 }
2026
2027 template <typename _Fun>
2028 _LIBCPP_INLINE_VISIBILITY static const __policy*
2029 __choose_policy(/* is_small = */ true_type)
2030 {
2031 static const _LIBCPP_CONSTEXPR __policy __policy_ = {
2032 nullptr, nullptr, false,
2033#ifndef _LIBCPP_NO_RTTI
2034 &typeid(typename _Fun::_Target)
2035#else
2036 nullptr
2037#endif
2038 };
2039 return &__policy_;
2040 }
2041};
2042
2043// Used to choose between perfect forwarding or pass-by-value. Pass-by-value is
2044// faster for types that can be passed in registers.
2045template <typename _Tp>
2046using __fast_forward =
2047 typename _VSTD::conditional<_VSTD::is_scalar<_Tp>::value, _Tp, _Tp&&>::type;
2048
2049// __policy_invoker calls an instance of __alloc_func held in __policy_storage.
2050
2051template <class _Fp> struct __policy_invoker;
2052
2053template <class _Rp, class... _ArgTypes>
2054struct __policy_invoker<_Rp(_ArgTypes...)>
2055{
2056 typedef _Rp (*__Call)(const __policy_storage*,
2057 __fast_forward<_ArgTypes>...);
2058
2059 __Call __call_;
2060
2061 // Creates an invoker that throws bad_function_call.
2062 _LIBCPP_INLINE_VISIBILITY
2063 __policy_invoker() : __call_(&__call_empty) {}
2064
2065 // Creates an invoker that calls the given instance of __func.
2066 template <typename _Fun>
2067 _LIBCPP_INLINE_VISIBILITY static __policy_invoker __create()
2068 {
2069 return __policy_invoker(&__call_impl<_Fun>);
2070 }
2071
2072 private:
2073 _LIBCPP_INLINE_VISIBILITY
2074 explicit __policy_invoker(__Call __c) : __call_(__c) {}
2075
2076 static _Rp __call_empty(const __policy_storage*,
2077 __fast_forward<_ArgTypes>...)
2078 {
2079 __throw_bad_function_call();
2080 }
2081
2082 template <typename _Fun>
2083 static _Rp __call_impl(const __policy_storage* __buf,
2084 __fast_forward<_ArgTypes>... __args)
2085 {
2086 _Fun* __f = reinterpret_cast<_Fun*>(__use_small_storage<_Fun>::value
2087 ? &__buf->__small
2088 : __buf->__large);
2089 return (*__f)(_VSTD::forward<_ArgTypes>(__args)...);
2090 }
2091};
2092
2093// __policy_func uses a __policy and __policy_invoker to create a type-erased,
2094// copyable functor.
2095
2096template <class _Fp> class __policy_func;
2097
2098template <class _Rp, class... _ArgTypes> class __policy_func<_Rp(_ArgTypes...)>
2099{
2100 // Inline storage for small objects.
2101 __policy_storage __buf_;
2102
2103 // Calls the value stored in __buf_. This could technically be part of
2104 // policy, but storing it here eliminates a level of indirection inside
2105 // operator().
2106 typedef __function::__policy_invoker<_Rp(_ArgTypes...)> __invoker;
2107 __invoker __invoker_;
2108
2109 // The policy that describes how to move / copy / destroy __buf_. Never
2110 // null, even if the function is empty.
2111 const __policy* __policy_;
2112
2113 public:
2114 _LIBCPP_INLINE_VISIBILITY
2115 __policy_func() : __policy_(__policy::__create_empty()) {}
2116
2117 template <class _Fp, class _Alloc>
2118 _LIBCPP_INLINE_VISIBILITY __policy_func(_Fp&& __f, const _Alloc& __a)
2119 : __policy_(__policy::__create_empty())
2120 {
2121 typedef __alloc_func<_Fp, _Alloc, _Rp(_ArgTypes...)> _Fun;
2122 typedef allocator_traits<_Alloc> __alloc_traits;
2123 typedef typename __rebind_alloc_helper<__alloc_traits, _Fun>::type
2124 _FunAlloc;
2125
2126 if (__function::__not_null(__f))
2127 {
2128 __invoker_ = __invoker::template __create<_Fun>();
2129 __policy_ = __policy::__create<_Fun>();
2130
2131 _FunAlloc __af(__a);
2132 if (__use_small_storage<_Fun>())
2133 {
2134 ::new ((void*)&__buf_.__small)
2135 _Fun(_VSTD::move(__f), _Alloc(__af));
2136 }
2137 else
2138 {
2139 typedef __allocator_destructor<_FunAlloc> _Dp;
2140 unique_ptr<_Fun, _Dp> __hold(__af.allocate(1), _Dp(__af, 1));
2141 ::new ((void*)__hold.get())
2142 _Fun(_VSTD::move(__f), _Alloc(__af));
2143 __buf_.__large = __hold.release();
2144 }
2145 }
2146 }
2147
2148 template <class _Fp, class = typename enable_if<!is_same<typename decay<_Fp>::type, __policy_func>::value>::type>
2149 _LIBCPP_INLINE_VISIBILITY explicit __policy_func(_Fp&& __f)
2150 : __policy_(__policy::__create_empty()) {
2151 typedef __default_alloc_func<_Fp, _Rp(_ArgTypes...)> _Fun;
2152
2153 if (__function::__not_null(__f)) {
2154 __invoker_ = __invoker::template __create<_Fun>();
2155 __policy_ = __policy::__create<_Fun>();
2156 if (__use_small_storage<_Fun>()) {
2157 ::new ((void*)&__buf_.__small) _Fun(_VSTD::move(__f));
2158 } else {
2159 __builtin_new_allocator::__holder_t __hold =
2160 __builtin_new_allocator::__allocate_type<_Fun>(1);
2161 __buf_.__large = ::new ((void*)__hold.get()) _Fun(_VSTD::move(__f));
2162 (void)__hold.release();
2163 }
2164 }
2165 }
2166
2167 _LIBCPP_INLINE_VISIBILITY
2168 __policy_func(const __policy_func& __f)
2169 : __buf_(__f.__buf_), __invoker_(__f.__invoker_),
2170 __policy_(__f.__policy_)
2171 {
2172 if (__policy_->__clone)
2173 __buf_.__large = __policy_->__clone(__f.__buf_.__large);
2174 }
2175
2176 _LIBCPP_INLINE_VISIBILITY
2177 __policy_func(__policy_func&& __f)
2178 : __buf_(__f.__buf_), __invoker_(__f.__invoker_),
2179 __policy_(__f.__policy_)
2180 {
2181 if (__policy_->__destroy)
2182 {
2183 __f.__policy_ = __policy::__create_empty();
2184 __f.__invoker_ = __invoker();
2185 }
2186 }
2187
2188 _LIBCPP_INLINE_VISIBILITY
2189 ~__policy_func()
2190 {
2191 if (__policy_->__destroy)
2192 __policy_->__destroy(__buf_.__large);
2193 }
2194
2195 _LIBCPP_INLINE_VISIBILITY
2196 __policy_func& operator=(__policy_func&& __f)
2197 {
2198 *this = nullptr;
2199 __buf_ = __f.__buf_;
2200 __invoker_ = __f.__invoker_;
2201 __policy_ = __f.__policy_;
2202 __f.__policy_ = __policy::__create_empty();
2203 __f.__invoker_ = __invoker();
2204 return *this;
2205 }
2206
2207 _LIBCPP_INLINE_VISIBILITY
2208 __policy_func& operator=(nullptr_t)
2209 {
2210 const __policy* __p = __policy_;
2211 __policy_ = __policy::__create_empty();
2212 __invoker_ = __invoker();
2213 if (__p->__destroy)
2214 __p->__destroy(__buf_.__large);
2215 return *this;
2216 }
2217
2218 _LIBCPP_INLINE_VISIBILITY
2219 _Rp operator()(_ArgTypes&&... __args) const
2220 {
2221 return __invoker_.__call_(_VSTD::addressof(__buf_),
2222 _VSTD::forward<_ArgTypes>(__args)...);
2223 }
2224
2225 _LIBCPP_INLINE_VISIBILITY
2226 void swap(__policy_func& __f)
2227 {
2228 _VSTD::swap(__invoker_, __f.__invoker_);
2229 _VSTD::swap(__policy_, __f.__policy_);
2230 _VSTD::swap(__buf_, __f.__buf_);
2231 }
2232
2233 _LIBCPP_INLINE_VISIBILITY
2234 explicit operator bool() const _NOEXCEPT
2235 {
2236 return !__policy_->__is_null;
2237 }
2238
2239#ifndef _LIBCPP_NO_RTTI
2240 _LIBCPP_INLINE_VISIBILITY
2241 const std::type_info& target_type() const _NOEXCEPT
2242 {
2243 return *__policy_->__type_info;
2244 }
2245
2246 template <typename _Tp>
2247 _LIBCPP_INLINE_VISIBILITY const _Tp* target() const _NOEXCEPT
2248 {
2249 if (__policy_->__is_null || typeid(_Tp) != *__policy_->__type_info)
2250 return nullptr;
2251 if (__policy_->__clone) // Out of line storage.
2252 return reinterpret_cast<const _Tp*>(__buf_.__large);
2253 else
2254 return reinterpret_cast<const _Tp*>(&__buf_.__small);
2255 }
2256#endif // _LIBCPP_NO_RTTI
2257};
2258
2259#if defined(_LIBCPP_HAS_BLOCKS_RUNTIME) && !defined(_LIBCPP_HAS_OBJC_ARC)
2260
2261extern "C" void *_Block_copy(const void *);
2262extern "C" void _Block_release(const void *);
2263
2264template<class _Rp1, class ..._ArgTypes1, class _Alloc, class _Rp, class ..._ArgTypes>
2265class __func<_Rp1(^)(_ArgTypes1...), _Alloc, _Rp(_ArgTypes...)>
2266 : public __base<_Rp(_ArgTypes...)>
2267{
2268 typedef _Rp1(^__block_type)(_ArgTypes1...);
2269 __block_type __f_;
2270
2271public:
2272 _LIBCPP_INLINE_VISIBILITY
2273 explicit __func(__block_type const& __f)
2274 : __f_(reinterpret_cast<__block_type>(__f ? _Block_copy(__f) : nullptr))
2275 { }
2276
2277 // [TODO] add && to save on a retain
2278
2279 _LIBCPP_INLINE_VISIBILITY
2280 explicit __func(__block_type __f, const _Alloc& /* unused */)
2281 : __f_(reinterpret_cast<__block_type>(__f ? _Block_copy(__f) : nullptr))
2282 { }
2283
2284 virtual __base<_Rp(_ArgTypes...)>* __clone() const {
2285 _LIBCPP_ASSERT(false,
2286 "Block pointers are just pointers, so they should always fit into "
2287 "std::function's small buffer optimization. This function should "
2288 "never be invoked.");
2289 return nullptr;
2290 }
2291
2292 virtual void __clone(__base<_Rp(_ArgTypes...)>* __p) const {
2293 ::new ((void*)__p) __func(__f_);
2294 }
2295
2296 virtual void destroy() _NOEXCEPT {
2297 if (__f_)
2298 _Block_release(__f_);
2299 __f_ = 0;
2300 }
2301
2302 virtual void destroy_deallocate() _NOEXCEPT {
2303 _LIBCPP_ASSERT(false,
2304 "Block pointers are just pointers, so they should always fit into "
2305 "std::function's small buffer optimization. This function should "
2306 "never be invoked.");
2307 }
2308
2309 virtual _Rp operator()(_ArgTypes&& ... __arg) {
2310 return _VSTD::__invoke(__f_, _VSTD::forward<_ArgTypes>(__arg)...);
2311 }
2312
2313#ifndef _LIBCPP_NO_RTTI
2314 virtual const void* target(type_info const& __ti) const _NOEXCEPT {
2315 if (__ti == typeid(__func::__block_type))
2316 return &__f_;
2317 return (const void*)nullptr;
2318 }
2319
2320 virtual const std::type_info& target_type() const _NOEXCEPT {
2321 return typeid(__func::__block_type);
2322 }
2323#endif // _LIBCPP_NO_RTTI
2324};
2325
2326#endif // _LIBCPP_HAS_EXTENSION_BLOCKS && !_LIBCPP_HAS_OBJC_ARC
2327
2328} // __function
2329
2330template<class _Rp, class ..._ArgTypes>
2331class _LIBCPP_TEMPLATE_VIS function<_Rp(_ArgTypes...)>
2332 : public __function::__maybe_derive_from_unary_function<_Rp(_ArgTypes...)>,
2333 public __function::__maybe_derive_from_binary_function<_Rp(_ArgTypes...)>
2334{
2335#ifndef _LIBCPP_ABI_OPTIMIZED_FUNCTION
2336 typedef __function::__value_func<_Rp(_ArgTypes...)> __func;
2337#else
2338 typedef __function::__policy_func<_Rp(_ArgTypes...)> __func;
2339#endif
2340
2341 __func __f_;
2342
2343 template <class _Fp, bool = _And<
2344 _IsNotSame<__uncvref_t<_Fp>, function>,
2345 __invokable<_Fp, _ArgTypes...>
2346 >::value>
2347 struct __callable;
2348 template <class _Fp>
2349 struct __callable<_Fp, true>
2350 {
2351 static const bool value = is_void<_Rp>::value ||
2352 __is_core_convertible<typename __invoke_of<_Fp, _ArgTypes...>::type,
2353 _Rp>::value;
2354 };
2355 template <class _Fp>
2356 struct __callable<_Fp, false>
2357 {
2358 static const bool value = false;
2359 };
2360
2361 template <class _Fp>
2362 using _EnableIfLValueCallable = typename enable_if<__callable<_Fp&>::value>::type;
2363public:
2364 typedef _Rp result_type;
2365
2366 // construct/copy/destroy:
2367 _LIBCPP_INLINE_VISIBILITY
2368 function() _NOEXCEPT { }
2369 _LIBCPP_INLINE_VISIBILITY
2370 function(nullptr_t) _NOEXCEPT {}
2371 function(const function&);
2372 function(function&&) _NOEXCEPT;
2373 template<class _Fp, class = _EnableIfLValueCallable<_Fp>>
2374 function(_Fp);
2375
2376#if _LIBCPP_STD_VER <= 14
2377 template<class _Alloc>
2378 _LIBCPP_INLINE_VISIBILITY
2379 function(allocator_arg_t, const _Alloc&) _NOEXCEPT {}
2380 template<class _Alloc>
2381 _LIBCPP_INLINE_VISIBILITY
2382 function(allocator_arg_t, const _Alloc&, nullptr_t) _NOEXCEPT {}
2383 template<class _Alloc>
2384 function(allocator_arg_t, const _Alloc&, const function&);
2385 template<class _Alloc>
2386 function(allocator_arg_t, const _Alloc&, function&&);
2387 template<class _Fp, class _Alloc, class = _EnableIfLValueCallable<_Fp>>
2388 function(allocator_arg_t, const _Alloc& __a, _Fp __f);
2389#endif
2390
2391 function& operator=(const function&);
2392 function& operator=(function&&) _NOEXCEPT;
2393 function& operator=(nullptr_t) _NOEXCEPT;
2394 template<class _Fp, class = _EnableIfLValueCallable<typename decay<_Fp>::type>>
2395 function& operator=(_Fp&&);
2396
2397 ~function();
2398
2399 // function modifiers:
2400 void swap(function&) _NOEXCEPT;
2401
2402#if _LIBCPP_STD_VER <= 14
2403 template<class _Fp, class _Alloc>
2404 _LIBCPP_INLINE_VISIBILITY
2405 void assign(_Fp&& __f, const _Alloc& __a)
2406 {function(allocator_arg, __a, _VSTD::forward<_Fp>(__f)).swap(*this);}
2407#endif
2408
2409 // function capacity:
2410 _LIBCPP_INLINE_VISIBILITY
2411 _LIBCPP_EXPLICIT operator bool() const _NOEXCEPT {
2412 return static_cast<bool>(__f_);
2413 }
2414
2415 // deleted overloads close possible hole in the type system
2416 template<class _R2, class... _ArgTypes2>
2417 bool operator==(const function<_R2(_ArgTypes2...)>&) const = delete;
2418 template<class _R2, class... _ArgTypes2>
2419 bool operator!=(const function<_R2(_ArgTypes2...)>&) const = delete;
2420public:
2421 // function invocation:
2422 _Rp operator()(_ArgTypes...) const;
2423
2424#ifndef _LIBCPP_NO_RTTI
2425 // function target access:
2426 const std::type_info& target_type() const _NOEXCEPT;
2427 template <typename _Tp> _Tp* target() _NOEXCEPT;
2428 template <typename _Tp> const _Tp* target() const _NOEXCEPT;
2429#endif // _LIBCPP_NO_RTTI
2430};
2431
2432#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
2433template<class _Rp, class ..._Ap>
2434function(_Rp(*)(_Ap...)) -> function<_Rp(_Ap...)>;
2435
2436template<class _Fp>
2437struct __strip_signature;
2438
2439template<class _Rp, class _Gp, class ..._Ap>
2440struct __strip_signature<_Rp (_Gp::*) (_Ap...)> { using type = _Rp(_Ap...); };
2441template<class _Rp, class _Gp, class ..._Ap>
2442struct __strip_signature<_Rp (_Gp::*) (_Ap...) const> { using type = _Rp(_Ap...); };
2443template<class _Rp, class _Gp, class ..._Ap>
2444struct __strip_signature<_Rp (_Gp::*) (_Ap...) volatile> { using type = _Rp(_Ap...); };
2445template<class _Rp, class _Gp, class ..._Ap>
2446struct __strip_signature<_Rp (_Gp::*) (_Ap...) const volatile> { using type = _Rp(_Ap...); };
2447
2448template<class _Rp, class _Gp, class ..._Ap>
2449struct __strip_signature<_Rp (_Gp::*) (_Ap...) &> { using type = _Rp(_Ap...); };
2450template<class _Rp, class _Gp, class ..._Ap>
2451struct __strip_signature<_Rp (_Gp::*) (_Ap...) const &> { using type = _Rp(_Ap...); };
2452template<class _Rp, class _Gp, class ..._Ap>
2453struct __strip_signature<_Rp (_Gp::*) (_Ap...) volatile &> { using type = _Rp(_Ap...); };
2454template<class _Rp, class _Gp, class ..._Ap>
2455struct __strip_signature<_Rp (_Gp::*) (_Ap...) const volatile &> { using type = _Rp(_Ap...); };
2456
2457template<class _Rp, class _Gp, class ..._Ap>
2458struct __strip_signature<_Rp (_Gp::*) (_Ap...) noexcept> { using type = _Rp(_Ap...); };
2459template<class _Rp, class _Gp, class ..._Ap>
2460struct __strip_signature<_Rp (_Gp::*) (_Ap...) const noexcept> { using type = _Rp(_Ap...); };
2461template<class _Rp, class _Gp, class ..._Ap>
2462struct __strip_signature<_Rp (_Gp::*) (_Ap...) volatile noexcept> { using type = _Rp(_Ap...); };
2463template<class _Rp, class _Gp, class ..._Ap>
2464struct __strip_signature<_Rp (_Gp::*) (_Ap...) const volatile noexcept> { using type = _Rp(_Ap...); };
2465
2466template<class _Rp, class _Gp, class ..._Ap>
2467struct __strip_signature<_Rp (_Gp::*) (_Ap...) & noexcept> { using type = _Rp(_Ap...); };
2468template<class _Rp, class _Gp, class ..._Ap>
2469struct __strip_signature<_Rp (_Gp::*) (_Ap...) const & noexcept> { using type = _Rp(_Ap...); };
2470template<class _Rp, class _Gp, class ..._Ap>
2471struct __strip_signature<_Rp (_Gp::*) (_Ap...) volatile & noexcept> { using type = _Rp(_Ap...); };
2472template<class _Rp, class _Gp, class ..._Ap>
2473struct __strip_signature<_Rp (_Gp::*) (_Ap...) const volatile & noexcept> { using type = _Rp(_Ap...); };
2474
2475template<class _Fp, class _Stripped = typename __strip_signature<decltype(&_Fp::operator())>::type>
2476function(_Fp) -> function<_Stripped>;
2477#endif // !_LIBCPP_HAS_NO_DEDUCTION_GUIDES
2478
2479template<class _Rp, class ..._ArgTypes>
2480function<_Rp(_ArgTypes...)>::function(const function& __f) : __f_(__f.__f_) {}
2481
2482#if _LIBCPP_STD_VER <= 14
2483template<class _Rp, class ..._ArgTypes>
2484template <class _Alloc>
2485function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&,
2486 const function& __f) : __f_(__f.__f_) {}
2487#endif
2488
2489template <class _Rp, class... _ArgTypes>
2490function<_Rp(_ArgTypes...)>::function(function&& __f) _NOEXCEPT
2491 : __f_(_VSTD::move(__f.__f_)) {}
2492
2493#if _LIBCPP_STD_VER <= 14
2494template<class _Rp, class ..._ArgTypes>
2495template <class _Alloc>
2496function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&,
2497 function&& __f)
2498 : __f_(_VSTD::move(__f.__f_)) {}
2499#endif
2500
2501template <class _Rp, class... _ArgTypes>
2502template <class _Fp, class>
2503function<_Rp(_ArgTypes...)>::function(_Fp __f) : __f_(_VSTD::move(__f)) {}
2504
2505#if _LIBCPP_STD_VER <= 14
2506template <class _Rp, class... _ArgTypes>
2507template <class _Fp, class _Alloc, class>
2508function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc& __a,
2509 _Fp __f)
2510 : __f_(_VSTD::move(__f), __a) {}
2511#endif
2512
2513template<class _Rp, class ..._ArgTypes>
2514function<_Rp(_ArgTypes...)>&
2515function<_Rp(_ArgTypes...)>::operator=(const function& __f)
2516{
2517 function(__f).swap(*this);
2518 return *this;
2519}
2520
2521template<class _Rp, class ..._ArgTypes>
2522function<_Rp(_ArgTypes...)>&
2523function<_Rp(_ArgTypes...)>::operator=(function&& __f) _NOEXCEPT
2524{
2525 __f_ = _VSTD::move(__f.__f_);
2526 return *this;
2527}
2528
2529template<class _Rp, class ..._ArgTypes>
2530function<_Rp(_ArgTypes...)>&
2531function<_Rp(_ArgTypes...)>::operator=(nullptr_t) _NOEXCEPT
2532{
2533 __f_ = nullptr;
2534 return *this;
2535}
2536
2537template<class _Rp, class ..._ArgTypes>
2538template <class _Fp, class>
2539function<_Rp(_ArgTypes...)>&
2540function<_Rp(_ArgTypes...)>::operator=(_Fp&& __f)
2541{
2542 function(_VSTD::forward<_Fp>(__f)).swap(*this);
2543 return *this;
2544}
2545
2546template<class _Rp, class ..._ArgTypes>
2547function<_Rp(_ArgTypes...)>::~function() {}
2548
2549template<class _Rp, class ..._ArgTypes>
2550void
2551function<_Rp(_ArgTypes...)>::swap(function& __f) _NOEXCEPT
2552{
2553 __f_.swap(__f.__f_);
2554}
2555
2556template<class _Rp, class ..._ArgTypes>
2557_Rp
2558function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const
2559{
2560 return __f_(_VSTD::forward<_ArgTypes>(__arg)...);
2561}
2562
2563#ifndef _LIBCPP_NO_RTTI
2564
2565template<class _Rp, class ..._ArgTypes>
2566const std::type_info&
2567function<_Rp(_ArgTypes...)>::target_type() const _NOEXCEPT
2568{
2569 return __f_.target_type();
2570}
2571
2572template<class _Rp, class ..._ArgTypes>
2573template <typename _Tp>
2574_Tp*
2575function<_Rp(_ArgTypes...)>::target() _NOEXCEPT
2576{
2577 return (_Tp*)(__f_.template target<_Tp>());
2578}
2579
2580template<class _Rp, class ..._ArgTypes>
2581template <typename _Tp>
2582const _Tp*
2583function<_Rp(_ArgTypes...)>::target() const _NOEXCEPT
2584{
2585 return __f_.template target<_Tp>();
2586}
2587
2588#endif // _LIBCPP_NO_RTTI
2589
2590template <class _Rp, class... _ArgTypes>
2591inline _LIBCPP_INLINE_VISIBILITY
2592bool
2593operator==(const function<_Rp(_ArgTypes...)>& __f, nullptr_t) _NOEXCEPT {return !__f;}
2594
2595template <class _Rp, class... _ArgTypes>
2596inline _LIBCPP_INLINE_VISIBILITY
2597bool
2598operator==(nullptr_t, const function<_Rp(_ArgTypes...)>& __f) _NOEXCEPT {return !__f;}
2599
2600template <class _Rp, class... _ArgTypes>
2601inline _LIBCPP_INLINE_VISIBILITY
2602bool
2603operator!=(const function<_Rp(_ArgTypes...)>& __f, nullptr_t) _NOEXCEPT {return (bool)__f;}
2604
2605template <class _Rp, class... _ArgTypes>
2606inline _LIBCPP_INLINE_VISIBILITY
2607bool
2608operator!=(nullptr_t, const function<_Rp(_ArgTypes...)>& __f) _NOEXCEPT {return (bool)__f;}
2609
2610template <class _Rp, class... _ArgTypes>
2611inline _LIBCPP_INLINE_VISIBILITY
2612void
2613swap(function<_Rp(_ArgTypes...)>& __x, function<_Rp(_ArgTypes...)>& __y) _NOEXCEPT
2614{return __x.swap(__y);}
2615
2616#else // _LIBCPP_CXX03_LANG
2617
2618#include <__functional_03>
2619
2620#endif
2621
2622////////////////////////////////////////////////////////////////////////////////
2623// BIND
2624//==============================================================================
2625
2626template<class _Tp> struct __is_bind_expression : public false_type {};
2627template<class _Tp> struct _LIBCPP_TEMPLATE_VIS is_bind_expression
2628 : public __is_bind_expression<typename remove_cv<_Tp>::type> {};
2629
2630#if _LIBCPP_STD_VER > 14
2631template <class _Tp>
2632_LIBCPP_INLINE_VAR constexpr size_t is_bind_expression_v = is_bind_expression<_Tp>::value;
2633#endif
2634
2635template<class _Tp> struct __is_placeholder : public integral_constant<int, 0> {};
2636template<class _Tp> struct _LIBCPP_TEMPLATE_VIS is_placeholder
2637 : public __is_placeholder<typename remove_cv<_Tp>::type> {};
2638
2639#if _LIBCPP_STD_VER > 14
2640template <class _Tp>
2641_LIBCPP_INLINE_VAR constexpr size_t is_placeholder_v = is_placeholder<_Tp>::value;
2642#endif
2643
2644namespace placeholders
2645{
2646
2647template <int _Np> struct __ph {};
2648
2649#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY)
2650_LIBCPP_FUNC_VIS extern const __ph<1> _1;
2651_LIBCPP_FUNC_VIS extern const __ph<2> _2;
2652_LIBCPP_FUNC_VIS extern const __ph<3> _3;
2653_LIBCPP_FUNC_VIS extern const __ph<4> _4;
2654_LIBCPP_FUNC_VIS extern const __ph<5> _5;
2655_LIBCPP_FUNC_VIS extern const __ph<6> _6;
2656_LIBCPP_FUNC_VIS extern const __ph<7> _7;
2657_LIBCPP_FUNC_VIS extern const __ph<8> _8;
2658_LIBCPP_FUNC_VIS extern const __ph<9> _9;
2659_LIBCPP_FUNC_VIS extern const __ph<10> _10;
2660#else
2661/* _LIBCPP_INLINE_VAR */ constexpr __ph<1> _1{};
2662/* _LIBCPP_INLINE_VAR */ constexpr __ph<2> _2{};
2663/* _LIBCPP_INLINE_VAR */ constexpr __ph<3> _3{};
2664/* _LIBCPP_INLINE_VAR */ constexpr __ph<4> _4{};
2665/* _LIBCPP_INLINE_VAR */ constexpr __ph<5> _5{};
2666/* _LIBCPP_INLINE_VAR */ constexpr __ph<6> _6{};
2667/* _LIBCPP_INLINE_VAR */ constexpr __ph<7> _7{};
2668/* _LIBCPP_INLINE_VAR */ constexpr __ph<8> _8{};
2669/* _LIBCPP_INLINE_VAR */ constexpr __ph<9> _9{};
2670/* _LIBCPP_INLINE_VAR */ constexpr __ph<10> _10{};
2671#endif // defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY)
2672
2673} // placeholders
2674
2675template<int _Np>
2676struct __is_placeholder<placeholders::__ph<_Np> >
2677 : public integral_constant<int, _Np> {};
2678
2679
2680#ifndef _LIBCPP_CXX03_LANG
2681
2682template <class _Tp, class _Uj>
2683inline _LIBCPP_INLINE_VISIBILITY
2684_Tp&
2685__mu(reference_wrapper<_Tp> __t, _Uj&)
2686{
2687 return __t.get();
2688}
2689
2690template <class _Ti, class ..._Uj, size_t ..._Indx>
2691inline _LIBCPP_INLINE_VISIBILITY
2692typename __invoke_of<_Ti&, _Uj...>::type
2693__mu_expand(_Ti& __ti, tuple<_Uj...>& __uj, __tuple_indices<_Indx...>)
2694{
2695 return __ti(_VSTD::forward<_Uj>(_VSTD::get<_Indx>(__uj))...);
2696}
2697
2698template <class _Ti, class ..._Uj>
2699inline _LIBCPP_INLINE_VISIBILITY
2700typename _EnableIf
2701<
2702 is_bind_expression<_Ti>::value,
2703 __invoke_of<_Ti&, _Uj...>
2704>::type
2705__mu(_Ti& __ti, tuple<_Uj...>& __uj)
2706{
2707 typedef typename __make_tuple_indices<sizeof...(_Uj)>::type __indices;
2708 return _VSTD::__mu_expand(__ti, __uj, __indices());
2709}
2710
2711template <bool IsPh, class _Ti, class _Uj>
2712struct __mu_return2 {};
2713
2714template <class _Ti, class _Uj>
2715struct __mu_return2<true, _Ti, _Uj>
2716{
2717 typedef typename tuple_element<is_placeholder<_Ti>::value - 1, _Uj>::type type;
2718};
2719
2720template <class _Ti, class _Uj>
2721inline _LIBCPP_INLINE_VISIBILITY
2722typename enable_if
2723<
2724 0 < is_placeholder<_Ti>::value,
2725 typename __mu_return2<0 < is_placeholder<_Ti>::value, _Ti, _Uj>::type
2726>::type
2727__mu(_Ti&, _Uj& __uj)
2728{
2729 const size_t _Indx = is_placeholder<_Ti>::value - 1;
2730 return _VSTD::forward<typename tuple_element<_Indx, _Uj>::type>(_VSTD::get<_Indx>(__uj));
2731}
2732
2733template <class _Ti, class _Uj>
2734inline _LIBCPP_INLINE_VISIBILITY
2735typename enable_if
2736<
2737 !is_bind_expression<_Ti>::value &&
2738 is_placeholder<_Ti>::value == 0 &&
2739 !__is_reference_wrapper<_Ti>::value,
2740 _Ti&
2741>::type
2742__mu(_Ti& __ti, _Uj&)
2743{
2744 return __ti;
2745}
2746
2747template <class _Ti, bool IsReferenceWrapper, bool IsBindEx, bool IsPh,
2748 class _TupleUj>
2749struct __mu_return_impl;
2750
2751template <bool _Invokable, class _Ti, class ..._Uj>
2752struct __mu_return_invokable // false
2753{
2754 typedef __nat type;
2755};
2756
2757template <class _Ti, class ..._Uj>
2758struct __mu_return_invokable<true, _Ti, _Uj...>
2759{
2760 typedef typename __invoke_of<_Ti&, _Uj...>::type type;
2761};
2762
2763template <class _Ti, class ..._Uj>
2764struct __mu_return_impl<_Ti, false, true, false, tuple<_Uj...> >
2765 : public __mu_return_invokable<__invokable<_Ti&, _Uj...>::value, _Ti, _Uj...>
2766{
2767};
2768
2769template <class _Ti, class _TupleUj>
2770struct __mu_return_impl<_Ti, false, false, true, _TupleUj>
2771{
2772 typedef typename tuple_element<is_placeholder<_Ti>::value - 1,
2773 _TupleUj>::type&& type;
2774};
2775
2776template <class _Ti, class _TupleUj>
2777struct __mu_return_impl<_Ti, true, false, false, _TupleUj>
2778{
2779 typedef typename _Ti::type& type;
2780};
2781
2782template <class _Ti, class _TupleUj>
2783struct __mu_return_impl<_Ti, false, false, false, _TupleUj>
2784{
2785 typedef _Ti& type;
2786};
2787
2788template <class _Ti, class _TupleUj>
2789struct __mu_return
2790 : public __mu_return_impl<_Ti,
2791 __is_reference_wrapper<_Ti>::value,
2792 is_bind_expression<_Ti>::value,
2793 0 < is_placeholder<_Ti>::value &&
2794 is_placeholder<_Ti>::value <= tuple_size<_TupleUj>::value,
2795 _TupleUj>
2796{
2797};
2798
2799template <class _Fp, class _BoundArgs, class _TupleUj>
2800struct __is_valid_bind_return
2801{
2802 static const bool value = false;
2803};
2804
2805template <class _Fp, class ..._BoundArgs, class _TupleUj>
2806struct __is_valid_bind_return<_Fp, tuple<_BoundArgs...>, _TupleUj>
2807{
2808 static const bool value = __invokable<_Fp,
2809 typename __mu_return<_BoundArgs, _TupleUj>::type...>::value;
2810};
2811
2812template <class _Fp, class ..._BoundArgs, class _TupleUj>
2813struct __is_valid_bind_return<_Fp, const tuple<_BoundArgs...>, _TupleUj>
2814{
2815 static const bool value = __invokable<_Fp,
2816 typename __mu_return<const _BoundArgs, _TupleUj>::type...>::value;
2817};
2818
2819template <class _Fp, class _BoundArgs, class _TupleUj,
2820 bool = __is_valid_bind_return<_Fp, _BoundArgs, _TupleUj>::value>
2821struct __bind_return;
2822
2823template <class _Fp, class ..._BoundArgs, class _TupleUj>
2824struct __bind_return<_Fp, tuple<_BoundArgs...>, _TupleUj, true>
2825{
2826 typedef typename __invoke_of
2827 <
2828 _Fp&,
2829 typename __mu_return
2830 <
2831 _BoundArgs,
2832 _TupleUj
2833 >::type...
2834 >::type type;
2835};
2836
2837template <class _Fp, class ..._BoundArgs, class _TupleUj>
2838struct __bind_return<_Fp, const tuple<_BoundArgs...>, _TupleUj, true>
2839{
2840 typedef typename __invoke_of
2841 <
2842 _Fp&,
2843 typename __mu_return
2844 <
2845 const _BoundArgs,
2846 _TupleUj
2847 >::type...
2848 >::type type;
2849};
2850
2851template <class _Fp, class _BoundArgs, size_t ..._Indx, class _Args>
2852inline _LIBCPP_INLINE_VISIBILITY
2853typename __bind_return<_Fp, _BoundArgs, _Args>::type
2854__apply_functor(_Fp& __f, _BoundArgs& __bound_args, __tuple_indices<_Indx...>,
2855 _Args&& __args)
2856{
2857 return _VSTD::__invoke(__f, _VSTD::__mu(_VSTD::get<_Indx>(__bound_args), __args)...);
2858}
2859
2860template<class _Fp, class ..._BoundArgs>
2861class __bind
2862 : public __weak_result_type<typename decay<_Fp>::type>
2863{
2864protected:
2865 typedef typename decay<_Fp>::type _Fd;
2866 typedef tuple<typename decay<_BoundArgs>::type...> _Td;
2867private:
2868 _Fd __f_;
2869 _Td __bound_args_;
2870
2871 typedef typename __make_tuple_indices<sizeof...(_BoundArgs)>::type __indices;
2872public:
2873 template <class _Gp, class ..._BA,
2874 class = typename enable_if
2875 <
2876 is_constructible<_Fd, _Gp>::value &&
2877 !is_same<typename remove_reference<_Gp>::type,
2878 __bind>::value
2879 >::type>
2880 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
2881 explicit __bind(_Gp&& __f, _BA&& ...__bound_args)
2882 : __f_(_VSTD::forward<_Gp>(__f)),
2883 __bound_args_(_VSTD::forward<_BA>(__bound_args)...) {}
2884
2885 template <class ..._Args>
2886 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
2887 typename __bind_return<_Fd, _Td, tuple<_Args&&...> >::type
2888 operator()(_Args&& ...__args)
2889 {
2890 return _VSTD::__apply_functor(__f_, __bound_args_, __indices(),
2891 tuple<_Args&&...>(_VSTD::forward<_Args>(__args)...));
2892 }
2893
2894 template <class ..._Args>
2895 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
2896 typename __bind_return<const _Fd, const _Td, tuple<_Args&&...> >::type
2897 operator()(_Args&& ...__args) const
2898 {
2899 return _VSTD::__apply_functor(__f_, __bound_args_, __indices(),
2900 tuple<_Args&&...>(_VSTD::forward<_Args>(__args)...));
2901 }
2902};
2903
2904template<class _Fp, class ..._BoundArgs>
2905struct __is_bind_expression<__bind<_Fp, _BoundArgs...> > : public true_type {};
2906
2907template<class _Rp, class _Fp, class ..._BoundArgs>
2908class __bind_r
2909 : public __bind<_Fp, _BoundArgs...>
2910{
2911 typedef __bind<_Fp, _BoundArgs...> base;
2912 typedef typename base::_Fd _Fd;
2913 typedef typename base::_Td _Td;
2914public:
2915 typedef _Rp result_type;
2916
2917
2918 template <class _Gp, class ..._BA,
2919 class = typename enable_if
2920 <
2921 is_constructible<_Fd, _Gp>::value &&
2922 !is_same<typename remove_reference<_Gp>::type,
2923 __bind_r>::value
2924 >::type>
2925 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
2926 explicit __bind_r(_Gp&& __f, _BA&& ...__bound_args)
2927 : base(_VSTD::forward<_Gp>(__f),
2928 _VSTD::forward<_BA>(__bound_args)...) {}
2929
2930 template <class ..._Args>
2931 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
2932 typename enable_if
2933 <
2934 is_convertible<typename __bind_return<_Fd, _Td, tuple<_Args&&...> >::type,
2935 result_type>::value || is_void<_Rp>::value,
2936 result_type
2937 >::type
2938 operator()(_Args&& ...__args)
2939 {
2940 typedef __invoke_void_return_wrapper<_Rp> _Invoker;
2941 return _Invoker::__call(static_cast<base&>(*this), _VSTD::forward<_Args>(__args)...);
2942 }
2943
2944 template <class ..._Args>
2945 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
2946 typename enable_if
2947 <
2948 is_convertible<typename __bind_return<const _Fd, const _Td, tuple<_Args&&...> >::type,
2949 result_type>::value || is_void<_Rp>::value,
2950 result_type
2951 >::type
2952 operator()(_Args&& ...__args) const
2953 {
2954 typedef __invoke_void_return_wrapper<_Rp> _Invoker;
2955 return _Invoker::__call(static_cast<base const&>(*this), _VSTD::forward<_Args>(__args)...);
2956 }
2957};
2958
2959template<class _Rp, class _Fp, class ..._BoundArgs>
2960struct __is_bind_expression<__bind_r<_Rp, _Fp, _BoundArgs...> > : public true_type {};
2961
2962template<class _Fp, class ..._BoundArgs>
2963inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
2964__bind<_Fp, _BoundArgs...>
2965bind(_Fp&& __f, _BoundArgs&&... __bound_args)
2966{
2967 typedef __bind<_Fp, _BoundArgs...> type;
2968 return type(_VSTD::forward<_Fp>(__f), _VSTD::forward<_BoundArgs>(__bound_args)...);
2969}
2970
2971template<class _Rp, class _Fp, class ..._BoundArgs>
2972inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
2973__bind_r<_Rp, _Fp, _BoundArgs...>
2974bind(_Fp&& __f, _BoundArgs&&... __bound_args)
2975{
2976 typedef __bind_r<_Rp, _Fp, _BoundArgs...> type;
2977 return type(_VSTD::forward<_Fp>(__f), _VSTD::forward<_BoundArgs>(__bound_args)...);
2978}
2979
2980#endif // _LIBCPP_CXX03_LANG
2981
2982#if _LIBCPP_STD_VER > 14
2983
2984template <class _Fn, class ..._Args>
2985_LIBCPP_CONSTEXPR_AFTER_CXX17 invoke_result_t<_Fn, _Args...>
2986invoke(_Fn&& __f, _Args&&... __args)
2987 noexcept(is_nothrow_invocable_v<_Fn, _Args...>)
2988{
2989 return _VSTD::__invoke(_VSTD::forward<_Fn>(__f), _VSTD::forward<_Args>(__args)...);
2990}
2991
2992template <class _DecayFunc>
2993class _LIBCPP_TEMPLATE_VIS __not_fn_imp {
2994 _DecayFunc __fd;
2995
2996public:
2997 __not_fn_imp() = delete;
2998
2999 template <class ..._Args>
3000 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
3001 auto operator()(_Args&& ...__args) &
3002 noexcept(noexcept(!_VSTD::invoke(__fd, _VSTD::forward<_Args>(__args)...)))
3003 -> decltype( !_VSTD::invoke(__fd, _VSTD::forward<_Args>(__args)...))
3004 { return !_VSTD::invoke(__fd, _VSTD::forward<_Args>(__args)...); }
3005
3006 template <class ..._Args>
3007 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
3008 auto operator()(_Args&& ...__args) &&
3009 noexcept(noexcept(!_VSTD::invoke(_VSTD::move(__fd), _VSTD::forward<_Args>(__args)...)))
3010 -> decltype( !_VSTD::invoke(_VSTD::move(__fd), _VSTD::forward<_Args>(__args)...))
3011 { return !_VSTD::invoke(_VSTD::move(__fd), _VSTD::forward<_Args>(__args)...); }
3012
3013 template <class ..._Args>
3014 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
3015 auto operator()(_Args&& ...__args) const&
3016 noexcept(noexcept(!_VSTD::invoke(__fd, _VSTD::forward<_Args>(__args)...)))
3017 -> decltype( !_VSTD::invoke(__fd, _VSTD::forward<_Args>(__args)...))
3018 { return !_VSTD::invoke(__fd, _VSTD::forward<_Args>(__args)...); }
3019
3020
3021 template <class ..._Args>
3022 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
3023 auto operator()(_Args&& ...__args) const&&
3024 noexcept(noexcept(!_VSTD::invoke(_VSTD::move(__fd), _VSTD::forward<_Args>(__args)...)))
3025 -> decltype( !_VSTD::invoke(_VSTD::move(__fd), _VSTD::forward<_Args>(__args)...))
3026 { return !_VSTD::invoke(_VSTD::move(__fd), _VSTD::forward<_Args>(__args)...); }
3027
3028private:
3029 template <class _RawFunc,
3030 class = enable_if_t<!is_same<decay_t<_RawFunc>, __not_fn_imp>::value>>
3031 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
3032 explicit __not_fn_imp(_RawFunc&& __rf)
3033 : __fd(_VSTD::forward<_RawFunc>(__rf)) {}
3034
3035 template <class _RawFunc>
3036 friend inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
3037 __not_fn_imp<decay_t<_RawFunc>> not_fn(_RawFunc&&);
3038};
3039
3040template <class _RawFunc>
3041inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
3042__not_fn_imp<decay_t<_RawFunc>> not_fn(_RawFunc&& __fn) {
3043 return __not_fn_imp<decay_t<_RawFunc>>(_VSTD::forward<_RawFunc>(__fn));
3044}
3045
3046#endif
3047
3048// struct hash<T*> in <memory>
3049
3050template <class _BinaryPredicate, class _ForwardIterator1, class _ForwardIterator2>
3051pair<_ForwardIterator1, _ForwardIterator1> _LIBCPP_CONSTEXPR_AFTER_CXX11
3052__search(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
3053 _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred,
3054 forward_iterator_tag, forward_iterator_tag)
3055{
3056 if (__first2 == __last2)
3057 return _VSTD::make_pair(__first1, __first1); // Everything matches an empty sequence
3058 while (true)
3059 {
3060 // Find first element in sequence 1 that matchs *__first2, with a mininum of loop checks
3061 while (true)
3062 {
3063 if (__first1 == __last1) // return __last1 if no element matches *__first2
3064 return _VSTD::make_pair(__last1, __last1);
3065 if (__pred(*__first1, *__first2))
3066 break;
3067 ++__first1;
3068 }
3069 // *__first1 matches *__first2, now match elements after here
3070 _ForwardIterator1 __m1 = __first1;
3071 _ForwardIterator2 __m2 = __first2;
3072 while (true)
3073 {
3074 if (++__m2 == __last2) // If pattern exhausted, __first1 is the answer (works for 1 element pattern)
3075 return _VSTD::make_pair(__first1, __m1);
3076 if (++__m1 == __last1) // Otherwise if source exhaused, pattern not found
3077 return _VSTD::make_pair(__last1, __last1);
3078 if (!__pred(*__m1, *__m2)) // if there is a mismatch, restart with a new __first1
3079 {
3080 ++__first1;
3081 break;
3082 } // else there is a match, check next elements
3083 }
3084 }
3085}
3086
3087template <class _BinaryPredicate, class _RandomAccessIterator1, class _RandomAccessIterator2>
3088_LIBCPP_CONSTEXPR_AFTER_CXX11
3089pair<_RandomAccessIterator1, _RandomAccessIterator1>
3090__search(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1,
3091 _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, _BinaryPredicate __pred,
3092 random_access_iterator_tag, random_access_iterator_tag)
3093{
3094 typedef typename iterator_traits<_RandomAccessIterator1>::difference_type _D1;
3095 typedef typename iterator_traits<_RandomAccessIterator2>::difference_type _D2;
3096 // Take advantage of knowing source and pattern lengths. Stop short when source is smaller than pattern
3097 const _D2 __len2 = __last2 - __first2;
3098 if (__len2 == 0)
3099 return _VSTD::make_pair(__first1, __first1);
3100 const _D1 __len1 = __last1 - __first1;
3101 if (__len1 < __len2)
3102 return _VSTD::make_pair(__last1, __last1);
3103 const _RandomAccessIterator1 __s = __last1 - (__len2 - 1); // Start of pattern match can't go beyond here
3104
3105 while (true)
3106 {
3107 while (true)
3108 {
3109 if (__first1 == __s)
3110 return _VSTD::make_pair(__last1, __last1);
3111 if (__pred(*__first1, *__first2))
3112 break;
3113 ++__first1;
3114 }
3115
3116 _RandomAccessIterator1 __m1 = __first1;
3117 _RandomAccessIterator2 __m2 = __first2;
3118 while (true)
3119 {
3120 if (++__m2 == __last2)
3121 return _VSTD::make_pair(__first1, __first1 + __len2);
3122 ++__m1; // no need to check range on __m1 because __s guarantees we have enough source
3123 if (!__pred(*__m1, *__m2))
3124 {
3125 ++__first1;
3126 break;
3127 }
3128 }
3129 }
3130}
3131
3132#if _LIBCPP_STD_VER > 14
3133
3134// default searcher
3135template<class _ForwardIterator, class _BinaryPredicate = equal_to<>>
3136class _LIBCPP_TYPE_VIS default_searcher {
3137public:
3138 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
3139 default_searcher(_ForwardIterator __f, _ForwardIterator __l,
3140 _BinaryPredicate __p = _BinaryPredicate())
3141 : __first_(__f), __last_(__l), __pred_(__p) {}
3142
3143 template <typename _ForwardIterator2>
3144 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
3145 pair<_ForwardIterator2, _ForwardIterator2>
3146 operator () (_ForwardIterator2 __f, _ForwardIterator2 __l) const
3147 {
3148 return _VSTD::__search(__f, __l, __first_, __last_, __pred_,
3149 typename _VSTD::iterator_traits<_ForwardIterator>::iterator_category(),
3150 typename _VSTD::iterator_traits<_ForwardIterator2>::iterator_category());
3151 }
3152
3153private:
3154 _ForwardIterator __first_;
3155 _ForwardIterator __last_;
3156 _BinaryPredicate __pred_;
3157 };
3158
3159#endif // _LIBCPP_STD_VER > 14
3160
3161#if _LIBCPP_STD_VER > 17
3162template <class _Tp>
3163using unwrap_reference_t = typename unwrap_reference<_Tp>::type;
3164
3165template <class _Tp>
3166using unwrap_ref_decay_t = typename unwrap_ref_decay<_Tp>::type;
3167#endif // > C++17
3168
3169template <class _Container, class _Predicate>
3170inline typename _Container::size_type
3171__libcpp_erase_if_container(_Container& __c, _Predicate __pred) {
3172 typename _Container::size_type __old_size = __c.size();
3173
3174 const typename _Container::iterator __last = __c.end();
3175 for (typename _Container::iterator __iter = __c.begin(); __iter != __last;) {
3176 if (__pred(*__iter))
3177 __iter = __c.erase(__iter);
3178 else
3179 ++__iter;
3180 }
3181
3182 return __old_size - __c.size();
3183}
3184
3185_LIBCPP_END_NAMESPACE_STD
3186
3187#endif // _LIBCPP_FUNCTIONAL
529#endif // _LIBCPP_FUNCTIONAL
lib/libcxx/include/future+29-26
......@@ -361,13 +361,18 @@ template <class R, class Alloc> struct uses_allocator<packaged_task<R>, Alloc>;
361361
362362*/
363363
364#include <__config>
365364#include <__availability>
366#include <system_error>
367#include <memory>
365#include <__config>
366#include <__debug>
367#include <__memory/allocator_arg_t.h>
368#include <__memory/uses_allocator.h>
369#include <__utility/__decay_copy.h>
370#include <__utility/forward.h>
368371#include <chrono>
369372#include <exception>
373#include <memory>
370374#include <mutex>
375#include <system_error>
371376#include <thread>
372377
373378#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
......@@ -467,7 +472,7 @@ operator^=(launch& __x, launch __y)
467472 __x = __x ^ __y; return __x;
468473}
469474
470#endif // !_LIBCPP_HAS_NO_STRONG_ENUMS
475#endif // !_LIBCPP_HAS_NO_STRONG_ENUMS
471476
472477//enum class future_status
473478_LIBCPP_DECLARE_STRONG_ENUM(future_status)
......@@ -501,9 +506,7 @@ class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_FUTURE_ERROR future_error
501506 error_code __ec_;
502507public:
503508 future_error(error_code __ec);
504#if _LIBCPP_STD_VERS > 14
505 explicit future_error(future_errc _Ev) : logic_error(), __ec_(make_error_code(_Ev)) {}
506#endif
509
507510 _LIBCPP_INLINE_VISIBILITY
508511 const error_code& code() const _NOEXCEPT {return __ec_;}
509512
......@@ -862,7 +865,7 @@ __deferred_assoc_state<_Rp, _Fp>::__execute()
862865#ifndef _LIBCPP_NO_EXCEPTIONS
863866 try
864867 {
865#endif // _LIBCPP_NO_EXCEPTIONS
868#endif // _LIBCPP_NO_EXCEPTIONS
866869 this->set_value(__func_());
867870#ifndef _LIBCPP_NO_EXCEPTIONS
868871 }
......@@ -870,7 +873,7 @@ __deferred_assoc_state<_Rp, _Fp>::__execute()
870873 {
871874 this->set_exception(current_exception());
872875 }
873#endif // _LIBCPP_NO_EXCEPTIONS
876#endif // _LIBCPP_NO_EXCEPTIONS
874877}
875878
876879template <class _Fp>
......@@ -903,7 +906,7 @@ __deferred_assoc_state<void, _Fp>::__execute()
903906#ifndef _LIBCPP_NO_EXCEPTIONS
904907 try
905908 {
906#endif // _LIBCPP_NO_EXCEPTIONS
909#endif // _LIBCPP_NO_EXCEPTIONS
907910 __func_();
908911 this->set_value();
909912#ifndef _LIBCPP_NO_EXCEPTIONS
......@@ -912,7 +915,7 @@ __deferred_assoc_state<void, _Fp>::__execute()
912915 {
913916 this->set_exception(current_exception());
914917 }
915#endif // _LIBCPP_NO_EXCEPTIONS
918#endif // _LIBCPP_NO_EXCEPTIONS
916919}
917920
918921template <class _Rp, class _Fp>
......@@ -945,7 +948,7 @@ __async_assoc_state<_Rp, _Fp>::__execute()
945948#ifndef _LIBCPP_NO_EXCEPTIONS
946949 try
947950 {
948#endif // _LIBCPP_NO_EXCEPTIONS
951#endif // _LIBCPP_NO_EXCEPTIONS
949952 this->set_value(__func_());
950953#ifndef _LIBCPP_NO_EXCEPTIONS
951954 }
......@@ -953,7 +956,7 @@ __async_assoc_state<_Rp, _Fp>::__execute()
953956 {
954957 this->set_exception(current_exception());
955958 }
956#endif // _LIBCPP_NO_EXCEPTIONS
959#endif // _LIBCPP_NO_EXCEPTIONS
957960}
958961
959962template <class _Rp, class _Fp>
......@@ -994,7 +997,7 @@ __async_assoc_state<void, _Fp>::__execute()
994997#ifndef _LIBCPP_NO_EXCEPTIONS
995998 try
996999 {
997#endif // _LIBCPP_NO_EXCEPTIONS
1000#endif // _LIBCPP_NO_EXCEPTIONS
9981001 __func_();
9991002 this->set_value();
10001003#ifndef _LIBCPP_NO_EXCEPTIONS
......@@ -1003,7 +1006,7 @@ __async_assoc_state<void, _Fp>::__execute()
10031006 {
10041007 this->set_exception(current_exception());
10051008 }
1006#endif // _LIBCPP_NO_EXCEPTIONS
1009#endif // _LIBCPP_NO_EXCEPTIONS
10071010}
10081011
10091012template <class _Fp>
......@@ -1953,7 +1956,7 @@ packaged_task<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __args)
19531956#ifndef _LIBCPP_NO_EXCEPTIONS
19541957 try
19551958 {
1956#endif // _LIBCPP_NO_EXCEPTIONS
1959#endif // _LIBCPP_NO_EXCEPTIONS
19571960 __p_.set_value(__f_(_VSTD::forward<_ArgTypes>(__args)...));
19581961#ifndef _LIBCPP_NO_EXCEPTIONS
19591962 }
......@@ -1961,7 +1964,7 @@ packaged_task<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __args)
19611964 {
19621965 __p_.set_exception(current_exception());
19631966 }
1964#endif // _LIBCPP_NO_EXCEPTIONS
1967#endif // _LIBCPP_NO_EXCEPTIONS
19651968}
19661969
19671970template<class _Rp, class ..._ArgTypes>
......@@ -1975,7 +1978,7 @@ packaged_task<_Rp(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
19751978#ifndef _LIBCPP_NO_EXCEPTIONS
19761979 try
19771980 {
1978#endif // _LIBCPP_NO_EXCEPTIONS
1981#endif // _LIBCPP_NO_EXCEPTIONS
19791982 __p_.set_value_at_thread_exit(__f_(_VSTD::forward<_ArgTypes>(__args)...));
19801983#ifndef _LIBCPP_NO_EXCEPTIONS
19811984 }
......@@ -1983,7 +1986,7 @@ packaged_task<_Rp(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
19831986 {
19841987 __p_.set_exception_at_thread_exit(current_exception());
19851988 }
1986#endif // _LIBCPP_NO_EXCEPTIONS
1989#endif // _LIBCPP_NO_EXCEPTIONS
19871990}
19881991
19891992template<class _Rp, class ..._ArgTypes>
......@@ -2082,7 +2085,7 @@ packaged_task<void(_ArgTypes...)>::operator()(_ArgTypes... __args)
20822085#ifndef _LIBCPP_NO_EXCEPTIONS
20832086 try
20842087 {
2085#endif // _LIBCPP_NO_EXCEPTIONS
2088#endif // _LIBCPP_NO_EXCEPTIONS
20862089 __f_(_VSTD::forward<_ArgTypes>(__args)...);
20872090 __p_.set_value();
20882091#ifndef _LIBCPP_NO_EXCEPTIONS
......@@ -2091,7 +2094,7 @@ packaged_task<void(_ArgTypes...)>::operator()(_ArgTypes... __args)
20912094 {
20922095 __p_.set_exception(current_exception());
20932096 }
2094#endif // _LIBCPP_NO_EXCEPTIONS
2097#endif // _LIBCPP_NO_EXCEPTIONS
20952098}
20962099
20972100template<class ..._ArgTypes>
......@@ -2105,7 +2108,7 @@ packaged_task<void(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args
21052108#ifndef _LIBCPP_NO_EXCEPTIONS
21062109 try
21072110 {
2108#endif // _LIBCPP_NO_EXCEPTIONS
2111#endif // _LIBCPP_NO_EXCEPTIONS
21092112 __f_(_VSTD::forward<_ArgTypes>(__args)...);
21102113 __p_.set_value_at_thread_exit();
21112114#ifndef _LIBCPP_NO_EXCEPTIONS
......@@ -2114,7 +2117,7 @@ packaged_task<void(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args
21142117 {
21152118 __p_.set_exception_at_thread_exit(current_exception());
21162119 }
2117#endif // _LIBCPP_NO_EXCEPTIONS
2120#endif // _LIBCPP_NO_EXCEPTIONS
21182121}
21192122
21202123template<class ..._ArgTypes>
......@@ -2126,10 +2129,10 @@ packaged_task<void(_ArgTypes...)>::reset()
21262129 __p_ = promise<result_type>();
21272130}
21282131
2129template <class _Callable>
2132template <class _Rp, class... _ArgTypes>
21302133inline _LIBCPP_INLINE_VISIBILITY
21312134void
2132swap(packaged_task<_Callable>& __x, packaged_task<_Callable>& __y) _NOEXCEPT
2135swap(packaged_task<_Rp(_ArgTypes...)>& __x, packaged_task<_Rp(_ArgTypes...)>& __y) _NOEXCEPT
21332136{
21342137 __x.swap(__y);
21352138}
......@@ -2456,4 +2459,4 @@ _LIBCPP_END_NAMESPACE_STD
24562459
24572460#endif // !_LIBCPP_HAS_NO_THREADS
24582461
2459#endif // _LIBCPP_FUTURE
2462#endif // _LIBCPP_FUTURE
lib/libcxx/include/initializer_list+2-2
......@@ -110,8 +110,8 @@ end(initializer_list<_Ep> __il) _NOEXCEPT
110110 return __il.end();
111111}
112112
113#endif // !defined(_LIBCPP_CXX03_LANG)
113#endif // !defined(_LIBCPP_CXX03_LANG)
114114
115115} // std
116116
117#endif // _LIBCPP_INITIALIZER_LIST
117#endif // _LIBCPP_INITIALIZER_LIST
lib/libcxx/include/inttypes.h+1-1
......@@ -259,4 +259,4 @@ uintmax_t wcstoumax(const wchar_t* restrict nptr, wchar_t** restrict endptr, int
259259
260260#endif // __cplusplus
261261
262#endif // _LIBCPP_INTTYPES_H
262#endif // _LIBCPP_INTTYPES_H
lib/libcxx/include/iomanip+10-10
......@@ -304,7 +304,7 @@ operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t7<_MoneyT>& __x)
304304#ifndef _LIBCPP_NO_EXCEPTIONS
305305 try
306306 {
307#endif // _LIBCPP_NO_EXCEPTIONS
307#endif // _LIBCPP_NO_EXCEPTIONS
308308 typename basic_istream<_CharT, _Traits>::sentry __s(__is);
309309 if (__s)
310310 {
......@@ -321,7 +321,7 @@ operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t7<_MoneyT>& __x)
321321 {
322322 __is.__set_badbit_and_consider_rethrow();
323323 }
324#endif // _LIBCPP_NO_EXCEPTIONS
324#endif // _LIBCPP_NO_EXCEPTIONS
325325 return __is;
326326}
327327
......@@ -364,7 +364,7 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t8<_MoneyT>& __x)
364364#ifndef _LIBCPP_NO_EXCEPTIONS
365365 try
366366 {
367#endif // _LIBCPP_NO_EXCEPTIONS
367#endif // _LIBCPP_NO_EXCEPTIONS
368368 typename basic_ostream<_CharT, _Traits>::sentry __s(__os);
369369 if (__s)
370370 {
......@@ -380,7 +380,7 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t8<_MoneyT>& __x)
380380 {
381381 __os.__set_badbit_and_consider_rethrow();
382382 }
383#endif // _LIBCPP_NO_EXCEPTIONS
383#endif // _LIBCPP_NO_EXCEPTIONS
384384 return __os;
385385}
386386
......@@ -423,7 +423,7 @@ operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t9<_CharT>& __x)
423423#ifndef _LIBCPP_NO_EXCEPTIONS
424424 try
425425 {
426#endif // _LIBCPP_NO_EXCEPTIONS
426#endif // _LIBCPP_NO_EXCEPTIONS
427427 typename basic_istream<_CharT, _Traits>::sentry __s(__is);
428428 if (__s)
429429 {
......@@ -441,7 +441,7 @@ operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t9<_CharT>& __x)
441441 {
442442 __is.__set_badbit_and_consider_rethrow();
443443 }
444#endif // _LIBCPP_NO_EXCEPTIONS
444#endif // _LIBCPP_NO_EXCEPTIONS
445445 return __is;
446446}
447447
......@@ -484,7 +484,7 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t10<_CharT>& __x)
484484#ifndef _LIBCPP_NO_EXCEPTIONS
485485 try
486486 {
487#endif // _LIBCPP_NO_EXCEPTIONS
487#endif // _LIBCPP_NO_EXCEPTIONS
488488 typename basic_ostream<_CharT, _Traits>::sentry __s(__os);
489489 if (__s)
490490 {
......@@ -501,7 +501,7 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t10<_CharT>& __x)
501501 {
502502 __os.__set_badbit_and_consider_rethrow();
503503 }
504#endif // _LIBCPP_NO_EXCEPTIONS
504#endif // _LIBCPP_NO_EXCEPTIONS
505505 return __os;
506506}
507507
......@@ -518,7 +518,7 @@ basic_ostream<_CharT, _Traits> &
518518__quoted_output ( basic_ostream<_CharT, _Traits> &__os,
519519 _ForwardIterator __first, _ForwardIterator __last, _CharT __delim, _CharT __escape )
520520{
521 _VSTD::basic_string<_CharT, _Traits> __str;
521 basic_string<_CharT, _Traits> __str;
522522 __str.push_back(__delim);
523523 for ( ; __first != __last; ++ __first )
524524 {
......@@ -667,4 +667,4 @@ quoted (basic_string_view <_CharT, _Traits> __sv,
667667
668668_LIBCPP_END_NAMESPACE_STD
669669
670#endif // _LIBCPP_IOMANIP
670#endif // _LIBCPP_IOMANIP
lib/libcxx/include/ios+7-19
......@@ -211,8 +211,8 @@ storage-class-specifier const error_category& iostream_category() noexcept;
211211*/
212212
213213#include <__config>
214#include <iosfwd>
215214#include <__locale>
215#include <iosfwd>
216216#include <system_error>
217217
218218#if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER)
......@@ -591,13 +591,6 @@ ios_base::exceptions(iostate __iostate)
591591 clear(__rdstate_);
592592}
593593
594#if defined(_LIBCPP_CXX03_LANG)
595struct _LIBCPP_TYPE_VIS __cxx03_bool {
596 typedef void (__cxx03_bool::*__bool_type)();
597 void __true_value() {}
598};
599#endif
600
601594template <class _CharT, class _Traits>
602595class _LIBCPP_TEMPLATE_VIS basic_ios
603596 : public ios_base
......@@ -614,17 +607,14 @@ public:
614607 static_assert((is_same<_CharT, typename traits_type::char_type>::value),
615608 "traits_type::char_type must be the same type as CharT");
616609
617 // __true_value will generate undefined references when linking unless
618 // we give it internal linkage.
619
620#if defined(_LIBCPP_CXX03_LANG)
610#ifdef _LIBCPP_CXX03_LANG
611 // Preserve the ability to compare with literal 0,
612 // and implicitly convert to bool, but not implicitly convert to int.
621613 _LIBCPP_INLINE_VISIBILITY
622 operator __cxx03_bool::__bool_type() const {
623 return !fail() ? &__cxx03_bool::__true_value : nullptr;
624 }
614 operator void*() const {return fail() ? nullptr : (void*)this;}
625615#else
626616 _LIBCPP_INLINE_VISIBILITY
627 _LIBCPP_EXPLICIT operator bool() const {return !fail();}
617 explicit operator bool() const {return !fail();}
628618#endif
629619
630620 _LIBCPP_INLINE_VISIBILITY bool operator!() const {return fail();}
......@@ -679,10 +669,8 @@ protected:
679669
680670 _LIBCPP_INLINE_VISIBILITY
681671 void move(basic_ios& __rhs);
682#ifndef _LIBCPP_CXX03_LANG
683672 _LIBCPP_INLINE_VISIBILITY
684673 void move(basic_ios&& __rhs) {move(__rhs);}
685#endif
686674 _LIBCPP_INLINE_VISIBILITY
687675 void swap(basic_ios& __rhs) _NOEXCEPT;
688676 _LIBCPP_INLINE_VISIBILITY
......@@ -1037,4 +1025,4 @@ defaultfloat(ios_base& __str)
10371025
10381026_LIBCPP_END_NAMESPACE_STD
10391027
1040#endif // _LIBCPP_IOS
1028#endif // _LIBCPP_IOS
lib/libcxx/include/iosfwd+9-6
......@@ -84,8 +84,11 @@ typedef basic_ofstream<wchar_t> wofstream;
8484typedef basic_fstream<wchar_t> wfstream;
8585
8686template <class state> class fpos;
87typedef fpos<char_traits<char>::state_type> streampos;
88typedef fpos<char_traits<wchar_t>::state_type> wstreampos;
87using streampos = fpos<char_traits<char>::state_type>;
88using wstreampos = fpos<char_traits<wchar_t>::state_type>;
89using u8streampos = fpos<char_traits<char8_t>::state_type>; // C++20
90using u16streampos = fpos<char_traits<char16_t>::state_type>;
91using u32streampos = fpos<char_traits<char32_t>::state_type>;
8992
9093} // std
9194
......@@ -104,7 +107,7 @@ class _LIBCPP_TYPE_VIS ios_base;
104107
105108template<class _CharT> struct _LIBCPP_TEMPLATE_VIS char_traits;
106109template<> struct char_traits<char>;
107#ifndef _LIBCPP_NO_HAS_CHAR8_T
110#ifndef _LIBCPP_HAS_NO_CHAR8_T
108111template<> struct char_traits<char8_t>;
109112#endif
110113template<> struct char_traits<char16_t>;
......@@ -218,13 +221,13 @@ template <class _CharT, class _Traits>
218221template <class _State> class _LIBCPP_TEMPLATE_VIS fpos;
219222typedef fpos<mbstate_t> streampos;
220223typedef fpos<mbstate_t> wstreampos;
221#ifndef _LIBCPP_NO_HAS_CHAR8_T
224#ifndef _LIBCPP_HAS_NO_CHAR8_T
222225typedef fpos<mbstate_t> u8streampos;
223226#endif
224227#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
225228typedef fpos<mbstate_t> u16streampos;
226229typedef fpos<mbstate_t> u32streampos;
227#endif // _LIBCPP_HAS_NO_UNICODE_CHARS
230#endif // _LIBCPP_HAS_NO_UNICODE_CHARS
228231
229232#if defined(_NEWLIB_VERSION)
230233// On newlib, off_t is 'long int'
......@@ -276,4 +279,4 @@ public:
276279
277280_LIBCPP_END_NAMESPACE_STD
278281
279#endif // _LIBCPP_IOSFWD
282#endif // _LIBCPP_IOSFWD
lib/libcxx/include/iostream+3-3
......@@ -14,9 +14,9 @@
1414 iostream synopsis
1515
1616#include <ios>
17#include <streambuf>
1817#include <istream>
1918#include <ostream>
19#include <streambuf>
2020
2121namespace std {
2222
......@@ -35,9 +35,9 @@ extern wostream wclog;
3535
3636#include <__config>
3737#include <ios>
38#include <streambuf>
3938#include <istream>
4039#include <ostream>
40#include <streambuf>
4141
4242#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
4343#pragma GCC system_header
......@@ -60,4 +60,4 @@ extern _LIBCPP_FUNC_VIS wostream wclog;
6060
6161_LIBCPP_END_NAMESPACE_STD
6262
63#endif // _LIBCPP_IOSTREAM
63#endif // _LIBCPP_IOSTREAM
lib/libcxx/include/istream+38-59
......@@ -159,8 +159,9 @@ template <class Stream, class T>
159159*/
160160
161161#include <__config>
162#include <version>
162#include <__utility/forward.h>
163163#include <ostream>
164#include <version>
164165
165166#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
166167#pragma GCC system_header
......@@ -191,14 +192,12 @@ public:
191192 { this->init(__sb); }
192193 virtual ~basic_istream();
193194protected:
194#ifndef _LIBCPP_CXX03_LANG
195195 inline _LIBCPP_INLINE_VISIBILITY
196196 basic_istream(basic_istream&& __rhs);
197197
198198 // 27.7.1.1.2 Assign/swap:
199199 inline _LIBCPP_INLINE_VISIBILITY
200200 basic_istream& operator=(basic_istream&& __rhs);
201#endif
202201
203202 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1
204203 void swap(basic_istream& __rhs) {
......@@ -206,10 +205,8 @@ protected:
206205 basic_ios<char_type, traits_type>::swap(__rhs);
207206 }
208207
209#ifndef _LIBCPP_CXX03_LANG
210208 basic_istream (const basic_istream& __rhs) = delete;
211209 basic_istream& operator=(const basic_istream& __rhs) = delete;
212#endif
213210public:
214211
215212 // 27.7.1.1.3 Prefix/suffix:
......@@ -302,8 +299,7 @@ public:
302299// ~sentry() = default;
303300
304301 _LIBCPP_INLINE_VISIBILITY
305 _LIBCPP_EXPLICIT
306 operator bool() const {return __ok_;}
302 explicit operator bool() const {return __ok_;}
307303};
308304
309305template <class _CharT, class _Traits>
......@@ -333,8 +329,6 @@ basic_istream<_CharT, _Traits>::sentry::sentry(basic_istream<_CharT, _Traits>& _
333329 __is.setstate(ios_base::failbit);
334330}
335331
336#ifndef _LIBCPP_CXX03_LANG
337
338332template <class _CharT, class _Traits>
339333basic_istream<_CharT, _Traits>::basic_istream(basic_istream&& __rhs)
340334 : __gc_(__rhs.__gc_)
......@@ -351,8 +345,6 @@ basic_istream<_CharT, _Traits>::operator=(basic_istream&& __rhs)
351345 return *this;
352346}
353347
354#endif // _LIBCPP_CXX03_LANG
355
356348template <class _CharT, class _Traits>
357349basic_istream<_CharT, _Traits>::~basic_istream()
358350{
......@@ -369,7 +361,7 @@ __input_arithmetic(basic_istream<_CharT, _Traits>& __is, _Tp& __n) {
369361#ifndef _LIBCPP_NO_EXCEPTIONS
370362 try
371363 {
372#endif // _LIBCPP_NO_EXCEPTIONS
364#endif // _LIBCPP_NO_EXCEPTIONS
373365 typedef istreambuf_iterator<_CharT, _Traits> _Ip;
374366 typedef num_get<_CharT, _Ip> _Fp;
375367 use_facet<_Fp>(__is.getloc()).get(_Ip(__is), _Ip(), __is, __state, __n);
......@@ -478,7 +470,7 @@ __input_arithmetic_with_numeric_limits(basic_istream<_CharT, _Traits>& __is, _Tp
478470#ifndef _LIBCPP_NO_EXCEPTIONS
479471 try
480472 {
481#endif // _LIBCPP_NO_EXCEPTIONS
473#endif // _LIBCPP_NO_EXCEPTIONS
482474 typedef istreambuf_iterator<_CharT, _Traits> _Ip;
483475 typedef num_get<_CharT, _Ip> _Fp;
484476 long __temp;
......@@ -508,7 +500,7 @@ __input_arithmetic_with_numeric_limits(basic_istream<_CharT, _Traits>& __is, _Tp
508500 throw;
509501 }
510502 }
511#endif // _LIBCPP_NO_EXCEPTIONS
503#endif // _LIBCPP_NO_EXCEPTIONS
512504 __is.setstate(__state);
513505 }
514506 return __is;
......@@ -636,7 +628,7 @@ operator>>(basic_istream<char, _Traits>& __is, signed char* __s)
636628 return __is >> (char*)__s;
637629}
638630
639#endif // _LIBCPP_STD_VER > 17
631#endif // _LIBCPP_STD_VER > 17
640632
641633template<class _CharT, class _Traits>
642634basic_istream<_CharT, _Traits>&
......@@ -734,7 +726,7 @@ basic_istream<_CharT, _Traits>::operator>>(basic_streambuf<char_type, traits_typ
734726 throw;
735727 }
736728 }
737#endif // _LIBCPP_NO_EXCEPTIONS
729#endif // _LIBCPP_NO_EXCEPTIONS
738730 }
739731 else
740732 {
......@@ -854,7 +846,7 @@ basic_istream<_CharT, _Traits>::get(basic_streambuf<char_type, traits_type>& __s
854846#ifndef _LIBCPP_NO_EXCEPTIONS
855847 try
856848 {
857#endif // _LIBCPP_NO_EXCEPTIONS
849#endif // _LIBCPP_NO_EXCEPTIONS
858850 while (true)
859851 {
860852 typename traits_type::int_type __i = this->rdbuf()->sgetc();
......@@ -878,7 +870,7 @@ basic_istream<_CharT, _Traits>::get(basic_streambuf<char_type, traits_type>& __s
878870 __state |= ios_base::badbit;
879871 // according to the spec, exceptions here are caught but not rethrown
880872 }
881#endif // _LIBCPP_NO_EXCEPTIONS
873#endif // _LIBCPP_NO_EXCEPTIONS
882874 if (__gc_ == 0)
883875 __state |= ios_base::failbit;
884876 this->setstate(__state);
......@@ -898,7 +890,7 @@ basic_istream<_CharT, _Traits>::getline(char_type* __s, streamsize __n, char_typ
898890#ifndef _LIBCPP_NO_EXCEPTIONS
899891 try
900892 {
901#endif // _LIBCPP_NO_EXCEPTIONS
893#endif // _LIBCPP_NO_EXCEPTIONS
902894 while (true)
903895 {
904896 typename traits_type::int_type __i = this->rdbuf()->sgetc();
......@@ -938,7 +930,7 @@ basic_istream<_CharT, _Traits>::getline(char_type* __s, streamsize __n, char_typ
938930 throw;
939931 }
940932 }
941#endif // _LIBCPP_NO_EXCEPTIONS
933#endif // _LIBCPP_NO_EXCEPTIONS
942934 }
943935 if (__n > 0)
944936 *__s = char_type();
......@@ -960,7 +952,7 @@ basic_istream<_CharT, _Traits>::ignore(streamsize __n, int_type __dlm)
960952#ifndef _LIBCPP_NO_EXCEPTIONS
961953 try
962954 {
963#endif // _LIBCPP_NO_EXCEPTIONS
955#endif // _LIBCPP_NO_EXCEPTIONS
964956 if (__n == numeric_limits<streamsize>::max())
965957 {
966958 while (true)
......@@ -1002,7 +994,7 @@ basic_istream<_CharT, _Traits>::ignore(streamsize __n, int_type __dlm)
1002994 throw;
1003995 }
1004996 }
1005#endif // _LIBCPP_NO_EXCEPTIONS
997#endif // _LIBCPP_NO_EXCEPTIONS
1006998 this->setstate(__state);
1007999 }
10081000 return *this;
......@@ -1021,7 +1013,7 @@ basic_istream<_CharT, _Traits>::peek()
10211013#ifndef _LIBCPP_NO_EXCEPTIONS
10221014 try
10231015 {
1024#endif // _LIBCPP_NO_EXCEPTIONS
1016#endif // _LIBCPP_NO_EXCEPTIONS
10251017 __r = this->rdbuf()->sgetc();
10261018 if (traits_type::eq_int_type(__r, traits_type::eof()))
10271019 __state |= ios_base::eofbit;
......@@ -1036,7 +1028,7 @@ basic_istream<_CharT, _Traits>::peek()
10361028 throw;
10371029 }
10381030 }
1039#endif // _LIBCPP_NO_EXCEPTIONS
1031#endif // _LIBCPP_NO_EXCEPTIONS
10401032 this->setstate(__state);
10411033 }
10421034 return __r;
......@@ -1054,7 +1046,7 @@ basic_istream<_CharT, _Traits>::read(char_type* __s, streamsize __n)
10541046#ifndef _LIBCPP_NO_EXCEPTIONS
10551047 try
10561048 {
1057#endif // _LIBCPP_NO_EXCEPTIONS
1049#endif // _LIBCPP_NO_EXCEPTIONS
10581050 __gc_ = this->rdbuf()->sgetn(__s, __n);
10591051 if (__gc_ != __n)
10601052 __state |= ios_base::failbit | ios_base::eofbit;
......@@ -1069,7 +1061,7 @@ basic_istream<_CharT, _Traits>::read(char_type* __s, streamsize __n)
10691061 throw;
10701062 }
10711063 }
1072#endif // _LIBCPP_NO_EXCEPTIONS
1064#endif // _LIBCPP_NO_EXCEPTIONS
10731065 }
10741066 else
10751067 {
......@@ -1091,7 +1083,7 @@ basic_istream<_CharT, _Traits>::readsome(char_type* __s, streamsize __n)
10911083#ifndef _LIBCPP_NO_EXCEPTIONS
10921084 try
10931085 {
1094#endif // _LIBCPP_NO_EXCEPTIONS
1086#endif // _LIBCPP_NO_EXCEPTIONS
10951087 streamsize __c = this->rdbuf()->in_avail();
10961088 switch (__c)
10971089 {
......@@ -1118,7 +1110,7 @@ basic_istream<_CharT, _Traits>::readsome(char_type* __s, streamsize __n)
11181110 throw;
11191111 }
11201112 }
1121#endif // _LIBCPP_NO_EXCEPTIONS
1113#endif // _LIBCPP_NO_EXCEPTIONS
11221114 }
11231115 else
11241116 {
......@@ -1141,7 +1133,7 @@ basic_istream<_CharT, _Traits>::putback(char_type __c)
11411133#ifndef _LIBCPP_NO_EXCEPTIONS
11421134 try
11431135 {
1144#endif // _LIBCPP_NO_EXCEPTIONS
1136#endif // _LIBCPP_NO_EXCEPTIONS
11451137 if (this->rdbuf() == nullptr || this->rdbuf()->sputbackc(__c) == traits_type::eof())
11461138 __state |= ios_base::badbit;
11471139#ifndef _LIBCPP_NO_EXCEPTIONS
......@@ -1155,7 +1147,7 @@ basic_istream<_CharT, _Traits>::putback(char_type __c)
11551147 throw;
11561148 }
11571149 }
1158#endif // _LIBCPP_NO_EXCEPTIONS
1150#endif // _LIBCPP_NO_EXCEPTIONS
11591151 }
11601152 else
11611153 {
......@@ -1178,7 +1170,7 @@ basic_istream<_CharT, _Traits>::unget()
11781170#ifndef _LIBCPP_NO_EXCEPTIONS
11791171 try
11801172 {
1181#endif // _LIBCPP_NO_EXCEPTIONS
1173#endif // _LIBCPP_NO_EXCEPTIONS
11821174 if (this->rdbuf() == nullptr || this->rdbuf()->sungetc() == traits_type::eof())
11831175 __state |= ios_base::badbit;
11841176#ifndef _LIBCPP_NO_EXCEPTIONS
......@@ -1192,7 +1184,7 @@ basic_istream<_CharT, _Traits>::unget()
11921184 throw;
11931185 }
11941186 }
1195#endif // _LIBCPP_NO_EXCEPTIONS
1187#endif // _LIBCPP_NO_EXCEPTIONS
11961188 }
11971189 else
11981190 {
......@@ -1214,7 +1206,7 @@ basic_istream<_CharT, _Traits>::sync()
12141206#ifndef _LIBCPP_NO_EXCEPTIONS
12151207 try
12161208 {
1217#endif // _LIBCPP_NO_EXCEPTIONS
1209#endif // _LIBCPP_NO_EXCEPTIONS
12181210 if (this->rdbuf() == nullptr)
12191211 return -1;
12201212 if (this->rdbuf()->pubsync() == -1)
......@@ -1233,7 +1225,7 @@ basic_istream<_CharT, _Traits>::sync()
12331225 throw;
12341226 }
12351227 }
1236#endif // _LIBCPP_NO_EXCEPTIONS
1228#endif // _LIBCPP_NO_EXCEPTIONS
12371229 this->setstate(__state);
12381230 }
12391231 return __r;
......@@ -1251,7 +1243,7 @@ basic_istream<_CharT, _Traits>::tellg()
12511243#ifndef _LIBCPP_NO_EXCEPTIONS
12521244 try
12531245 {
1254#endif // _LIBCPP_NO_EXCEPTIONS
1246#endif // _LIBCPP_NO_EXCEPTIONS
12551247 __r = this->rdbuf()->pubseekoff(0, ios_base::cur, ios_base::in);
12561248#ifndef _LIBCPP_NO_EXCEPTIONS
12571249 }
......@@ -1264,7 +1256,7 @@ basic_istream<_CharT, _Traits>::tellg()
12641256 throw;
12651257 }
12661258 }
1267#endif // _LIBCPP_NO_EXCEPTIONS
1259#endif // _LIBCPP_NO_EXCEPTIONS
12681260 this->setstate(__state);
12691261 }
12701262 return __r;
......@@ -1282,7 +1274,7 @@ basic_istream<_CharT, _Traits>::seekg(pos_type __pos)
12821274#ifndef _LIBCPP_NO_EXCEPTIONS
12831275 try
12841276 {
1285#endif // _LIBCPP_NO_EXCEPTIONS
1277#endif // _LIBCPP_NO_EXCEPTIONS
12861278 if (this->rdbuf()->pubseekpos(__pos, ios_base::in) == pos_type(-1))
12871279 __state |= ios_base::failbit;
12881280#ifndef _LIBCPP_NO_EXCEPTIONS
......@@ -1296,7 +1288,7 @@ basic_istream<_CharT, _Traits>::seekg(pos_type __pos)
12961288 throw;
12971289 }
12981290 }
1299#endif // _LIBCPP_NO_EXCEPTIONS
1291#endif // _LIBCPP_NO_EXCEPTIONS
13001292 this->setstate(__state);
13011293 }
13021294 return *this;
......@@ -1314,7 +1306,7 @@ basic_istream<_CharT, _Traits>::seekg(off_type __off, ios_base::seekdir __dir)
13141306#ifndef _LIBCPP_NO_EXCEPTIONS
13151307 try
13161308 {
1317#endif // _LIBCPP_NO_EXCEPTIONS
1309#endif // _LIBCPP_NO_EXCEPTIONS
13181310 if (this->rdbuf()->pubseekoff(__off, __dir, ios_base::in) == pos_type(-1))
13191311 __state |= ios_base::failbit;
13201312#ifndef _LIBCPP_NO_EXCEPTIONS
......@@ -1328,7 +1320,7 @@ basic_istream<_CharT, _Traits>::seekg(off_type __off, ios_base::seekdir __dir)
13281320 throw;
13291321 }
13301322 }
1331#endif // _LIBCPP_NO_EXCEPTIONS
1323#endif // _LIBCPP_NO_EXCEPTIONS
13321324 this->setstate(__state);
13331325 }
13341326 return *this;
......@@ -1345,7 +1337,7 @@ ws(basic_istream<_CharT, _Traits>& __is)
13451337#ifndef _LIBCPP_NO_EXCEPTIONS
13461338 try
13471339 {
1348#endif // _LIBCPP_NO_EXCEPTIONS
1340#endif // _LIBCPP_NO_EXCEPTIONS
13491341 const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__is.getloc());
13501342 while (true)
13511343 {
......@@ -1370,25 +1362,23 @@ ws(basic_istream<_CharT, _Traits>& __is)
13701362 throw;
13711363 }
13721364 }
1373#endif // _LIBCPP_NO_EXCEPTIONS
1365#endif // _LIBCPP_NO_EXCEPTIONS
13741366 __is.setstate(__state);
13751367 }
13761368 return __is;
13771369}
13781370
1379#ifndef _LIBCPP_CXX03_LANG
1380
13811371template <class _Stream, class _Tp, class = void>
13821372struct __is_istreamable : false_type { };
13831373
13841374template <class _Stream, class _Tp>
13851375struct __is_istreamable<_Stream, _Tp, decltype(
1386 _VSTD::declval<_Stream>() >> _VSTD::declval<_Tp>(), void()
1376 declval<_Stream>() >> declval<_Tp>(), void()
13871377)> : true_type { };
13881378
13891379template <class _Stream, class _Tp, class = typename enable_if<
13901380 _And<is_base_of<ios_base, _Stream>,
1391 __is_istreamable<_Stream&, _Tp&&>>::value
1381 __is_istreamable<_Stream&, _Tp&&> >::value
13921382>::type>
13931383_LIBCPP_INLINE_VISIBILITY
13941384_Stream&& operator>>(_Stream&& __is, _Tp&& __x)
......@@ -1397,8 +1387,6 @@ _Stream&& operator>>(_Stream&& __is, _Tp&& __x)
13971387 return _VSTD::move(__is);
13981388}
13991389
1400#endif // _LIBCPP_CXX03_LANG
1401
14021390template <class _CharT, class _Traits>
14031391class _LIBCPP_TEMPLATE_VIS basic_iostream
14041392 : public basic_istream<_CharT, _Traits>,
......@@ -1420,21 +1408,18 @@ public:
14201408
14211409 virtual ~basic_iostream();
14221410protected:
1423#ifndef _LIBCPP_CXX03_LANG
14241411 inline _LIBCPP_INLINE_VISIBILITY
14251412 basic_iostream(basic_iostream&& __rhs);
14261413
14271414 // assign/swap
14281415 inline _LIBCPP_INLINE_VISIBILITY
14291416 basic_iostream& operator=(basic_iostream&& __rhs);
1430#endif
1417
14311418 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1
14321419 void swap(basic_iostream& __rhs)
14331420 { basic_istream<char_type, traits_type>::swap(__rhs); }
14341421};
14351422
1436#ifndef _LIBCPP_CXX03_LANG
1437
14381423template <class _CharT, class _Traits>
14391424basic_iostream<_CharT, _Traits>::basic_iostream(basic_iostream&& __rhs)
14401425 : basic_istream<_CharT, _Traits>(_VSTD::move(__rhs))
......@@ -1449,8 +1434,6 @@ basic_iostream<_CharT, _Traits>::operator=(basic_iostream&& __rhs)
14491434 return *this;
14501435}
14511436
1452#endif // _LIBCPP_CXX03_LANG
1453
14541437template <class _CharT, class _Traits>
14551438basic_iostream<_CharT, _Traits>::~basic_iostream()
14561439{
......@@ -1574,8 +1557,6 @@ getline(basic_istream<_CharT, _Traits>& __is,
15741557 return getline(__is, __str, __is.widen('\n'));
15751558}
15761559
1577#ifndef _LIBCPP_CXX03_LANG
1578
15791560template<class _CharT, class _Traits, class _Allocator>
15801561inline _LIBCPP_INLINE_VISIBILITY
15811562basic_istream<_CharT, _Traits>&
......@@ -1594,8 +1575,6 @@ getline(basic_istream<_CharT, _Traits>&& __is,
15941575 return getline(__is, __str, __is.widen('\n'));
15951576}
15961577
1597#endif // _LIBCPP_CXX03_LANG
1598
15991578template <class _CharT, class _Traits, size_t _Size>
16001579basic_istream<_CharT, _Traits>&
16011580operator>>(basic_istream<_CharT, _Traits>& __is, bitset<_Size>& __x)
......@@ -1656,4 +1635,4 @@ _LIBCPP_END_NAMESPACE_STD
16561635
16571636_LIBCPP_POP_MACROS
16581637
1659#endif // _LIBCPP_ISTREAM
1638#endif // _LIBCPP_ISTREAM
lib/libcxx/include/iterator+256-1654
......@@ -13,32 +13,140 @@
1313/*
1414 iterator synopsis
1515
16#include <concepts>
17
1618namespace std
1719{
20template<class> struct incrementable_traits; // since C++20
21template<class T>
22 using iter_difference_t = see below; // since C++20
23
24template<class> struct indirectly_readable_traits; // since C++20
25template<class T>
26 using iter_value_t = see below; // since C++20
1827
1928template<class Iterator>
20struct iterator_traits
21{
22 typedef typename Iterator::difference_type difference_type;
23 typedef typename Iterator::value_type value_type;
24 typedef typename Iterator::pointer pointer;
25 typedef typename Iterator::reference reference;
26 typedef typename Iterator::iterator_category iterator_category;
27};
29struct iterator_traits;
2830
2931template<class T>
30struct iterator_traits<T*>
31{
32 typedef ptrdiff_t difference_type;
33 typedef T value_type;
34 typedef T* pointer;
35 typedef T& reference;
36 typedef random_access_iterator_tag iterator_category;
37};
32 requires is_object_v<T> // since C++20
33struct iterator_traits<T*>;
34
35template<dereferenceable T>
36 using iter_reference_t = decltype(*declval<T&>());
37
38namespace ranges::inline unspecified {
39 inline constexpr unspecified iter_move = unspecified; // since C++20, nodiscard as an extension
40}}
41
42template<dereferenceable T>
43 requires ...
44using iter_rvalue_reference_t = decltype(ranges::iter_move(declval<T&>())); // since C++20
45
46// [iterator.concepts], iterator concepts
47// [iterator.concept.readable], concept indirectly_readable
48template<class In>
49 concept indirectly_readable = see below; // since C++20
50
51template<indirectly_readable T>
52 using iter_common_reference_t =
53 common_reference_t<iter_reference_t<T>, iter_value_t<T>&>; // since C++20
54
55// [iterator.concept.writable], concept indirectly_writable
56template<class Out, class T>
57 concept indirectly_writable = see below; // since C++20
58
59// [iterator.concept.winc], concept weakly_incrementable
60template<class I>
61 concept weakly_incrementable = see below; // since C++20
62
63// [iterator.concept.inc], concept incrementable
64template<class I>
65 concept incrementable = see below; // since C++20
66
67// [iterator.concept.iterator], concept input_or_output_iterator
68 template<class I>
69 concept input_or_output_iterator = see below; // since C++20
70
71// [iterator.concept.sentinel], concept sentinel_for
72template<class S, class I>
73 concept sentinel_for = see below; // since C++20
74
75// [iterator.concept.sizedsentinel], concept sized_sentinel_for
76template<class S, class I>
77 inline constexpr bool disable_sized_sentinel_for = false;
78
79template<class S, class I>
80 concept sized_sentinel_for = see below;
81
82// [iterator.concept.input], concept input_iterator
83template<class I>
84 concept input_iterator = see below; // since C++20
85
86// [iterator.concept.output], concept output_iterator
87template<class I, class T>
88 concept output_iterator = see below; // since C++20
89
90// [iterator.concept.forward], concept forward_iterator
91template<class I>
92 concept forward_iterator = see below; // since C++20
93
94// [iterator.concept.bidir], concept bidirectional_iterator
95template<class I>
96 concept bidirectional_iterator = see below; // since C++20
97
98// [iterator.concept.random.access], concept random_access_iterator
99template<class I>
100 concept random_access_iterator = see below; // since C++20
101
102// [indirectcallable]
103// [indirectcallable.indirectinvocable]
104template<class F, class I>
105 concept indirectly_unary_invocable = see below; // since C++20
106
107template<class F, class I>
108 concept indirectly_regular_unary_invocable = see below; // since C++20
109
110template<class F, class I>
111 concept indirect_unary_predicate = see below; // since C++20
112
113template<class F, class I1, class I2>
114 concept indirect_binary_predicate = see below; // since C++20
115
116template<class F, class I1, class I2 = I1>
117 concept indirect_equivalence_relation = see below; // since C++20
118
119template<class F, class I1, class I2 = I1>
120 concept indirect_strict_weak_order = see below; // since C++20
121
122template<class F, class... Is>
123 using indirect_result_t = see below; // since C++20
124
125// [projected], projected
126template<indirectly_readable I, indirectly_regular_unary_invocable<I> Proj>
127 struct projected; // since C++20
128
129template<weakly_incrementable I, indirectly_regular_unary_invocable<I> Proj>
130 struct incrementable_traits<projected<I, Proj>>; // since C++20
131
132// [alg.req.ind.move], concept indirectly_movable
133template<class In, class Out>
134 concept indirectly_movable = see below; // since C++20
135
136template<class In, class Out>
137 concept indirectly_movable_storable = see below; // since C++20
138
139// [alg.req.ind.swap], concept indirectly_swappable
140template<class I1, class I2 = I1>
141 concept indirectly_swappable = see below; // since C++20
142
143template<input_or_output_iterator I, sentinel_for<I> S>
144 requires (!same_as<I, S> && copyable<I>)
145class common_iterator; // since C++20
38146
39147template<class Category, class T, class Distance = ptrdiff_t,
40148 class Pointer = T*, class Reference = T&>
41struct iterator
149struct iterator // deprecated in C++17
42150{
43151 typedef T value_type;
44152 typedef Distance difference_type;
......@@ -69,9 +177,20 @@ template <class BidirectionalIterator> // constexpr in C++17
69177 constexpr BidirectionalIterator prev(BidirectionalIterator x,
70178 typename iterator_traits<BidirectionalIterator>::difference_type n = 1);
71179
180// [range.iter.ops], range iterator operations
181namespace ranges {
182 // [range.iter.op.advance], ranges::advance
183 template<input_or_output_iterator I>
184 constexpr void advance(I& i, iter_difference_t<I> n); // since C++20
185 template<input_or_output_iterator I, sentinel_for<I> S>
186 constexpr void advance(I& i, S bound); // since C++20
187 template<input_or_output_iterator I, sentinel_for<I> S>
188 constexpr iter_difference_t<I> advance(I& i, iter_difference_t<I> n, S bound); // since C++20
189}
190
72191template <class Iterator>
73192class reverse_iterator
74 : public iterator<typename iterator_traits<Iterator>::iterator_category,
193 : public iterator<typename iterator_traits<Iterator>::iterator_category, // until C++17
75194 typename iterator_traits<Iterator>::value_type,
76195 typename iterator_traits<Iterator>::difference_type,
77196 typename iterator_traits<Iterator>::pointer,
......@@ -142,48 +261,53 @@ constexpr reverse_iterator<Iterator> make_reverse_iterator(Iterator i); // C++14
142261
143262template <class Container>
144263class back_insert_iterator
264 : public iterator<output_iterator_tag, void, void, void, void> // until C++17
145265{
146266protected:
147267 Container* container;
148268public:
149269 typedef Container container_type;
150270 typedef void value_type;
151 typedef void difference_type;
271 typedef void difference_type; // until C++20
272 typedef ptrdiff_t difference_type; // since C++20
152273 typedef void reference;
153274 typedef void pointer;
154275
155 explicit back_insert_iterator(Container& x);
156 back_insert_iterator& operator=(const typename Container::value_type& value);
157 back_insert_iterator& operator*();
158 back_insert_iterator& operator++();
159 back_insert_iterator operator++(int);
276 explicit back_insert_iterator(Container& x); // constexpr in C++20
277 back_insert_iterator& operator=(const typename Container::value_type& value); // constexpr in C++20
278 back_insert_iterator& operator*(); // constexpr in C++20
279 back_insert_iterator& operator++(); // constexpr in C++20
280 back_insert_iterator operator++(int); // constexpr in C++20
160281};
161282
162template <class Container> back_insert_iterator<Container> back_inserter(Container& x);
283template <class Container> back_insert_iterator<Container> back_inserter(Container& x); // constexpr in C++20
163284
164285template <class Container>
165286class front_insert_iterator
287 : public iterator<output_iterator_tag, void, void, void, void> // until C++17
166288{
167289protected:
168290 Container* container;
169291public:
170292 typedef Container container_type;
171293 typedef void value_type;
172 typedef void difference_type;
294 typedef void difference_type; // until C++20
295 typedef ptrdiff_t difference_type; // since C++20
173296 typedef void reference;
174297 typedef void pointer;
175298
176 explicit front_insert_iterator(Container& x);
177 front_insert_iterator& operator=(const typename Container::value_type& value);
178 front_insert_iterator& operator*();
179 front_insert_iterator& operator++();
180 front_insert_iterator operator++(int);
299 explicit front_insert_iterator(Container& x); // constexpr in C++20
300 front_insert_iterator& operator=(const typename Container::value_type& value); // constexpr in C++20
301 front_insert_iterator& operator*(); // constexpr in C++20
302 front_insert_iterator& operator++(); // constexpr in C++20
303 front_insert_iterator operator++(int); // constexpr in C++20
181304};
182305
183template <class Container> front_insert_iterator<Container> front_inserter(Container& x);
306template <class Container> front_insert_iterator<Container> front_inserter(Container& x); // constexpr in C++20
184307
185308template <class Container>
186309class insert_iterator
310 : public iterator<output_iterator_tag, void, void, void, void> // until C++17
187311{
188312protected:
189313 Container* container;
......@@ -191,19 +315,20 @@ protected:
191315public:
192316 typedef Container container_type;
193317 typedef void value_type;
194 typedef void difference_type;
318 typedef void difference_type; // until C++20
319 typedef ptrdiff_t difference_type; // since C++20
195320 typedef void reference;
196321 typedef void pointer;
197322
198 insert_iterator(Container& x, typename Container::iterator i);
199 insert_iterator& operator=(const typename Container::value_type& value);
200 insert_iterator& operator*();
201 insert_iterator& operator++();
202 insert_iterator& operator++(int);
323 insert_iterator(Container& x, typename Container::iterator i); // constexpr in C++20
324 insert_iterator& operator=(const typename Container::value_type& value); // constexpr in C++20
325 insert_iterator& operator*(); // constexpr in C++20
326 insert_iterator& operator++(); // constexpr in C++20
327 insert_iterator& operator++(int); // constexpr in C++20
203328};
204329
205330template <class Container, class Iterator>
206insert_iterator<Container> inserter(Container& x, Iterator i);
331insert_iterator<Container> inserter(Container& x, Iterator i); // constexpr in C++20
207332
208333template <class Iterator>
209334class move_iterator {
......@@ -274,15 +399,31 @@ constexpr move_iterator<Iterator> operator+( // constexpr in C++17
274399template <class Iterator> // constexpr in C++17
275400constexpr move_iterator<Iterator> make_move_iterator(const Iterator& i);
276401
402// [default.sentinel], default sentinel
403struct default_sentinel_t;
404inline constexpr default_sentinel_t default_sentinel{};
405
406// [iterators.counted], counted iterators
407template<input_or_output_iterator I> class counted_iterator;
408
409template<input_iterator I>
410 requires see below
411 struct iterator_traits<counted_iterator<I>>;
277412
278413template <class T, class charT = char, class traits = char_traits<charT>, class Distance = ptrdiff_t>
279414class istream_iterator
280 : public iterator<input_iterator_tag, T, Distance, const T*, const T&>
415 : public iterator<input_iterator_tag, T, Distance, const T*, const T&> // until C++17
281416{
282417public:
283 typedef charT char_type;
284 typedef traits traits_type;
285 typedef basic_istream<charT,traits> istream_type;
418 typedef input_iterator_tag iterator_category;
419 typedef T value_type;
420 typedef Distance difference_type;
421 typedef const T* pointer;
422 typedef const T& reference;
423
424 typedef charT char_type;
425 typedef traits traits_type;
426 typedef basic_istream<charT, traits> istream_type;
286427
287428 constexpr istream_iterator();
288429 istream_iterator(istream_type& s);
......@@ -304,9 +445,16 @@ bool operator!=(const istream_iterator<T,charT,traits,Distance>& x,
304445
305446template <class T, class charT = char, class traits = char_traits<charT> >
306447class ostream_iterator
307 : public iterator<output_iterator_tag, void, void, void ,void>
448 : public iterator<output_iterator_tag, void, void, void, void> // until C++17
308449{
309450public:
451 typedef output_iterator_tag iterator_category;
452 typedef void value_type;
453 typedef void difference_type; // until C++20
454 typedef ptrdiff_t difference_type; // since C++20
455 typedef void pointer;
456 typedef void reference;
457
310458 typedef charT char_type;
311459 typedef traits traits_type;
312460 typedef basic_ostream<charT,traits> ostream_type;
......@@ -324,16 +472,20 @@ public:
324472
325473template<class charT, class traits = char_traits<charT> >
326474class istreambuf_iterator
327 : public iterator<input_iterator_tag, charT,
328 typename traits::off_type, unspecified,
329 charT>
475 : public iterator<input_iterator_tag, charT, traits::off_type, unspecified, charT> // until C++17
330476{
331477public:
332 typedef charT char_type;
333 typedef traits traits_type;
334 typedef typename traits::int_type int_type;
335 typedef basic_streambuf<charT,traits> streambuf_type;
336 typedef basic_istream<charT,traits> istream_type;
478 typedef input_iterator_tag iterator_category;
479 typedef charT value_type;
480 typedef traits::off_type difference_type;
481 typedef unspecified pointer;
482 typedef charT reference;
483
484 typedef charT char_type;
485 typedef traits traits_type;
486 typedef traits::int_type int_type;
487 typedef basic_streambuf<charT, traits> streambuf_type;
488 typedef basic_istream<charT, traits> istream_type;
337489
338490 istreambuf_iterator() noexcept;
339491 istreambuf_iterator(istream_type& s) noexcept;
......@@ -357,13 +509,20 @@ bool operator!=(const istreambuf_iterator<charT,traits>& a,
357509
358510template <class charT, class traits = char_traits<charT> >
359511class ostreambuf_iterator
360 : public iterator<output_iterator_tag, void, void, void, void>
512 : public iterator<output_iterator_tag, void, void, void, void> // until C++17
361513{
362514public:
363 typedef charT char_type;
364 typedef traits traits_type;
365 typedef basic_streambuf<charT,traits> streambuf_type;
366 typedef basic_ostream<charT,traits> ostream_type;
515 typedef output_iterator_tag iterator_category;
516 typedef void value_type;
517 typedef void difference_type; // until C++20
518 typedef ptrdiff_t difference_type; // since C++20
519 typedef void pointer;
520 typedef void reference;
521
522 typedef charT char_type;
523 typedef traits traits_type;
524 typedef basic_streambuf<charT, traits> streambuf_type;
525 typedef basic_ostream<charT, traits> ostream_type;
367526
368527 ostreambuf_iterator(ostream_type& s) noexcept;
369528 ostreambuf_iterator(streambuf_type* s) noexcept;
......@@ -399,7 +558,7 @@ template <class C> constexpr auto size(const C& c) -> decltype(c.size());
399558template <class T, size_t N> constexpr size_t size(const T (&array)[N]) noexcept; // C++17
400559
401560template <class C> constexpr auto ssize(const C& c)
402 -> common_type_t<ptrdiff_t, make_signed_t<decltype(c.size())>>; // C++20
561 -> common_type_t<ptrdiff_t, make_signed_t<decltype(c.size())>>; // C++20
403562template <class T, ptrdiff_t> constexpr ptrdiff_t ssize(const T (&array)[N]) noexcept; // C++20
404563
405564template <class C> constexpr auto empty(const C& c) -> decltype(c.empty()); // C++17
......@@ -415,1608 +574,51 @@ template <class E> constexpr const E* data(initializer_list<E> il) noexcept;
415574*/
416575
417576#include <__config>
418#include <iosfwd> // for forward declarations of vector and string.
577#include <__debug>
419578#include <__functional_base>
420#include <type_traits>
579#include <__iterator/access.h>
580#include <__iterator/advance.h>
581#include <__iterator/back_insert_iterator.h>
582#include <__iterator/common_iterator.h>
583#include <__iterator/concepts.h>
584#include <__iterator/counted_iterator.h>
585#include <__iterator/data.h>
586#include <__iterator/default_sentinel.h>
587#include <__iterator/distance.h>
588#include <__iterator/empty.h>
589#include <__iterator/erase_if_container.h>
590#include <__iterator/front_insert_iterator.h>
591#include <__iterator/incrementable_traits.h>
592#include <__iterator/insert_iterator.h>
593#include <__iterator/istreambuf_iterator.h>
594#include <__iterator/istream_iterator.h>
595#include <__iterator/iterator.h>
596#include <__iterator/iterator_traits.h>
597#include <__iterator/iter_move.h>
598#include <__iterator/iter_swap.h>
599#include <__iterator/move_iterator.h>
600#include <__iterator/next.h>
601#include <__iterator/ostreambuf_iterator.h>
602#include <__iterator/ostream_iterator.h>
603#include <__iterator/prev.h>
604#include <__iterator/projected.h>
605#include <__iterator/readable_traits.h>
606#include <__iterator/reverse_access.h>
607#include <__iterator/reverse_iterator.h>
608#include <__iterator/size.h>
609#include <__iterator/wrap_iter.h>
610#include <__memory/addressof.h>
611#include <__memory/pointer_traits.h>
612#include <__utility/forward.h>
613#include <compare>
614#include <concepts> // Mandated by the Standard.
421615#include <cstddef>
422616#include <initializer_list>
423#include <__memory/base.h>
617#include <type_traits>
424618#include <version>
425619
426#include <__debug>
427
428620#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
429621#pragma GCC system_header
430622#endif
431623
432_LIBCPP_BEGIN_NAMESPACE_STD
433template <class _Iter>
434struct _LIBCPP_TEMPLATE_VIS iterator_traits;
435
436struct _LIBCPP_TEMPLATE_VIS input_iterator_tag {};
437struct _LIBCPP_TEMPLATE_VIS output_iterator_tag {};
438struct _LIBCPP_TEMPLATE_VIS forward_iterator_tag : public input_iterator_tag {};
439struct _LIBCPP_TEMPLATE_VIS bidirectional_iterator_tag : public forward_iterator_tag {};
440struct _LIBCPP_TEMPLATE_VIS random_access_iterator_tag : public bidirectional_iterator_tag {};
441#if _LIBCPP_STD_VER > 17
442// TODO(EricWF) contiguous_iterator_tag is provided as an extension prior to
443// C++20 to allow optimizations for users providing wrapped iterator types.
444struct _LIBCPP_TEMPLATE_VIS contiguous_iterator_tag: public random_access_iterator_tag { };
445#endif
446
447template <class _Iter>
448struct __iter_traits_cache {
449 using type = _If<
450 __is_primary_template<iterator_traits<_Iter> >::value,
451 _Iter,
452 iterator_traits<_Iter>
453 >;
454};
455template <class _Iter>
456using _ITER_TRAITS = typename __iter_traits_cache<_Iter>::type;
457
458struct __iter_concept_concept_test {
459 template <class _Iter>
460 using _Apply = typename _ITER_TRAITS<_Iter>::iterator_concept;
461};
462struct __iter_concept_category_test {
463 template <class _Iter>
464 using _Apply = typename _ITER_TRAITS<_Iter>::iterator_category;
465};
466struct __iter_concept_random_fallback {
467 template <class _Iter>
468 using _Apply = _EnableIf<
469 __is_primary_template<iterator_traits<_Iter> >::value,
470 random_access_iterator_tag
471 >;
472};
473
474template <class _Iter, class _Tester> struct __test_iter_concept
475 : _IsValidExpansion<_Tester::template _Apply, _Iter>,
476 _Tester
477{
478};
479
480template <class _Iter>
481struct __iter_concept_cache {
482 using type = _Or<
483 __test_iter_concept<_Iter, __iter_concept_concept_test>,
484 __test_iter_concept<_Iter, __iter_concept_category_test>,
485 __test_iter_concept<_Iter, __iter_concept_random_fallback>
486 >;
487};
488
489template <class _Iter>
490using _ITER_CONCEPT = typename __iter_concept_cache<_Iter>::type::template _Apply<_Iter>;
491
492
493template <class _Tp>
494struct __has_iterator_typedefs
495{
496private:
497 struct __two {char __lx; char __lxx;};
498 template <class _Up> static __two __test(...);
499 template <class _Up> static char __test(typename __void_t<typename _Up::iterator_category>::type* = 0,
500 typename __void_t<typename _Up::difference_type>::type* = 0,
501 typename __void_t<typename _Up::value_type>::type* = 0,
502 typename __void_t<typename _Up::reference>::type* = 0,
503 typename __void_t<typename _Up::pointer>::type* = 0);
504public:
505 static const bool value = sizeof(__test<_Tp>(0,0,0,0,0)) == 1;
506};
507
508
509template <class _Tp>
510struct __has_iterator_category
511{
512private:
513 struct __two {char __lx; char __lxx;};
514 template <class _Up> static __two __test(...);
515 template <class _Up> static char __test(typename _Up::iterator_category* = nullptr);
516public:
517 static const bool value = sizeof(__test<_Tp>(nullptr)) == 1;
518};
519
520template <class _Iter, bool> struct __iterator_traits_impl {};
521
522template <class _Iter>
523struct __iterator_traits_impl<_Iter, true>
524{
525 typedef typename _Iter::difference_type difference_type;
526 typedef typename _Iter::value_type value_type;
527 typedef typename _Iter::pointer pointer;
528 typedef typename _Iter::reference reference;
529 typedef typename _Iter::iterator_category iterator_category;
530};
531
532template <class _Iter, bool> struct __iterator_traits {};
533
534template <class _Iter>
535struct __iterator_traits<_Iter, true>
536 : __iterator_traits_impl
537 <
538 _Iter,
539 is_convertible<typename _Iter::iterator_category, input_iterator_tag>::value ||
540 is_convertible<typename _Iter::iterator_category, output_iterator_tag>::value
541 >
542{};
543
544// iterator_traits<Iterator> will only have the nested types if Iterator::iterator_category
545// exists. Else iterator_traits<Iterator> will be an empty class. This is a
546// conforming extension which allows some programs to compile and behave as
547// the client expects instead of failing at compile time.
548
549template <class _Iter>
550struct _LIBCPP_TEMPLATE_VIS iterator_traits
551 : __iterator_traits<_Iter, __has_iterator_typedefs<_Iter>::value> {
552
553 using __primary_template = iterator_traits;
554};
555
556template<class _Tp>
557struct _LIBCPP_TEMPLATE_VIS iterator_traits<_Tp*>
558{
559 typedef ptrdiff_t difference_type;
560 typedef typename remove_cv<_Tp>::type value_type;
561 typedef _Tp* pointer;
562 typedef _Tp& reference;
563 typedef random_access_iterator_tag iterator_category;
564#if _LIBCPP_STD_VER > 17
565 typedef contiguous_iterator_tag iterator_concept;
566#endif
567};
568
569template <class _Tp, class _Up, bool = __has_iterator_category<iterator_traits<_Tp> >::value>
570struct __has_iterator_category_convertible_to
571 : public integral_constant<bool, is_convertible<typename iterator_traits<_Tp>::iterator_category, _Up>::value>
572{};
573
574template <class _Tp, class _Up>
575struct __has_iterator_category_convertible_to<_Tp, _Up, false> : public false_type {};
576
577template <class _Tp>
578struct __is_cpp17_input_iterator : public __has_iterator_category_convertible_to<_Tp, input_iterator_tag> {};
579
580template <class _Tp>
581struct __is_cpp17_forward_iterator : public __has_iterator_category_convertible_to<_Tp, forward_iterator_tag> {};
582
583template <class _Tp>
584struct __is_cpp17_bidirectional_iterator : public __has_iterator_category_convertible_to<_Tp, bidirectional_iterator_tag> {};
585
586template <class _Tp>
587struct __is_cpp17_random_access_iterator : public __has_iterator_category_convertible_to<_Tp, random_access_iterator_tag> {};
588
589#if _LIBCPP_STD_VER > 17
590template <class _Tp>
591struct __is_cpp17_contiguous_iterator : public __has_iterator_category_convertible_to<_Tp, contiguous_iterator_tag> {};
592#else
593template <class _Tp>
594struct __is_cpp17_contiguous_iterator : public false_type {};
595#endif
596
597
598template <class _Tp>
599struct __is_exactly_cpp17_input_iterator
600 : public integral_constant<bool,
601 __has_iterator_category_convertible_to<_Tp, input_iterator_tag>::value &&
602 !__has_iterator_category_convertible_to<_Tp, forward_iterator_tag>::value> {};
603
604#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
605template<class _InputIterator>
606using __iter_value_type = typename iterator_traits<_InputIterator>::value_type;
607
608template<class _InputIterator>
609using __iter_key_type = remove_const_t<typename iterator_traits<_InputIterator>::value_type::first_type>;
610
611template<class _InputIterator>
612using __iter_mapped_type = typename iterator_traits<_InputIterator>::value_type::second_type;
613
614template<class _InputIterator>
615using __iter_to_alloc_type = pair<
616 add_const_t<typename iterator_traits<_InputIterator>::value_type::first_type>,
617 typename iterator_traits<_InputIterator>::value_type::second_type>;
618#endif
619
620template<class _Category, class _Tp, class _Distance = ptrdiff_t,
621 class _Pointer = _Tp*, class _Reference = _Tp&>
622struct _LIBCPP_TEMPLATE_VIS iterator
623{
624 typedef _Tp value_type;
625 typedef _Distance difference_type;
626 typedef _Pointer pointer;
627 typedef _Reference reference;
628 typedef _Category iterator_category;
629};
630
631template <class _InputIter>
632inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
633void __advance(_InputIter& __i,
634 typename iterator_traits<_InputIter>::difference_type __n, input_iterator_tag)
635{
636 for (; __n > 0; --__n)
637 ++__i;
638}
639
640template <class _BiDirIter>
641inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
642void __advance(_BiDirIter& __i,
643 typename iterator_traits<_BiDirIter>::difference_type __n, bidirectional_iterator_tag)
644{
645 if (__n >= 0)
646 for (; __n > 0; --__n)
647 ++__i;
648 else
649 for (; __n < 0; ++__n)
650 --__i;
651}
652
653template <class _RandIter>
654inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
655void __advance(_RandIter& __i,
656 typename iterator_traits<_RandIter>::difference_type __n, random_access_iterator_tag)
657{
658 __i += __n;
659}
660
661template <class _InputIter, class _Distance>
662inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
663void advance(_InputIter& __i, _Distance __orig_n)
664{
665 _LIBCPP_ASSERT(__orig_n >= 0 || __is_cpp17_bidirectional_iterator<_InputIter>::value,
666 "Attempt to advance(it, n) with negative n on a non-bidirectional iterator");
667 typedef decltype(_VSTD::__convert_to_integral(__orig_n)) _IntegralSize;
668 _IntegralSize __n = __orig_n;
669 _VSTD::__advance(__i, __n, typename iterator_traits<_InputIter>::iterator_category());
670}
671
672template <class _InputIter>
673inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
674typename iterator_traits<_InputIter>::difference_type
675__distance(_InputIter __first, _InputIter __last, input_iterator_tag)
676{
677 typename iterator_traits<_InputIter>::difference_type __r(0);
678 for (; __first != __last; ++__first)
679 ++__r;
680 return __r;
681}
682
683template <class _RandIter>
684inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
685typename iterator_traits<_RandIter>::difference_type
686__distance(_RandIter __first, _RandIter __last, random_access_iterator_tag)
687{
688 return __last - __first;
689}
690
691template <class _InputIter>
692inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
693typename iterator_traits<_InputIter>::difference_type
694distance(_InputIter __first, _InputIter __last)
695{
696 return _VSTD::__distance(__first, __last, typename iterator_traits<_InputIter>::iterator_category());
697}
698
699template <class _InputIter>
700inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
701typename enable_if
702<
703 __is_cpp17_input_iterator<_InputIter>::value,
704 _InputIter
705>::type
706next(_InputIter __x,
707 typename iterator_traits<_InputIter>::difference_type __n = 1)
708{
709 _LIBCPP_ASSERT(__n >= 0 || __is_cpp17_bidirectional_iterator<_InputIter>::value,
710 "Attempt to next(it, n) with negative n on a non-bidirectional iterator");
711
712 _VSTD::advance(__x, __n);
713 return __x;
714}
715
716template <class _InputIter>
717inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
718typename enable_if
719<
720 __is_cpp17_input_iterator<_InputIter>::value,
721 _InputIter
722>::type
723prev(_InputIter __x,
724 typename iterator_traits<_InputIter>::difference_type __n = 1)
725{
726 _LIBCPP_ASSERT(__n <= 0 || __is_cpp17_bidirectional_iterator<_InputIter>::value,
727 "Attempt to prev(it, n) with a positive n on a non-bidirectional iterator");
728 _VSTD::advance(__x, -__n);
729 return __x;
730}
731
732
733template <class _Tp, class = void>
734struct __is_stashing_iterator : false_type {};
735
736template <class _Tp>
737struct __is_stashing_iterator<_Tp, typename __void_t<typename _Tp::__stashing_iterator_tag>::type>
738 : true_type {};
739
740template <class _Iter>
741class _LIBCPP_TEMPLATE_VIS reverse_iterator
742 : public iterator<typename iterator_traits<_Iter>::iterator_category,
743 typename iterator_traits<_Iter>::value_type,
744 typename iterator_traits<_Iter>::difference_type,
745 typename iterator_traits<_Iter>::pointer,
746 typename iterator_traits<_Iter>::reference>
747{
748private:
749 /*mutable*/ _Iter __t; // no longer used as of LWG #2360, not removed due to ABI break
750
751 static_assert(!__is_stashing_iterator<_Iter>::value,
752 "The specified iterator type cannot be used with reverse_iterator; "
753 "Using stashing iterators with reverse_iterator causes undefined behavior");
754
755protected:
756 _Iter current;
757public:
758 typedef _Iter iterator_type;
759 typedef typename iterator_traits<_Iter>::difference_type difference_type;
760 typedef typename iterator_traits<_Iter>::reference reference;
761 typedef typename iterator_traits<_Iter>::pointer pointer;
762
763 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
764 reverse_iterator() : __t(), current() {}
765 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
766 explicit reverse_iterator(_Iter __x) : __t(__x), current(__x) {}
767 template <class _Up>
768 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
769 reverse_iterator(const reverse_iterator<_Up>& __u) : __t(__u.base()), current(__u.base()) {}
770 template <class _Up>
771 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
772 reverse_iterator& operator=(const reverse_iterator<_Up>& __u)
773 { __t = current = __u.base(); return *this; }
774 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
775 _Iter base() const {return current;}
776 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
777 reference operator*() const {_Iter __tmp = current; return *--__tmp;}
778 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
779 pointer operator->() const {return _VSTD::addressof(operator*());}
780 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
781 reverse_iterator& operator++() {--current; return *this;}
782 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
783 reverse_iterator operator++(int) {reverse_iterator __tmp(*this); --current; return __tmp;}
784 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
785 reverse_iterator& operator--() {++current; return *this;}
786 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
787 reverse_iterator operator--(int) {reverse_iterator __tmp(*this); ++current; return __tmp;}
788 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
789 reverse_iterator operator+ (difference_type __n) const {return reverse_iterator(current - __n);}
790 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
791 reverse_iterator& operator+=(difference_type __n) {current -= __n; return *this;}
792 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
793 reverse_iterator operator- (difference_type __n) const {return reverse_iterator(current + __n);}
794 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
795 reverse_iterator& operator-=(difference_type __n) {current += __n; return *this;}
796 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
797 reference operator[](difference_type __n) const {return *(*this + __n);}
798};
799
800template <class _Iter1, class _Iter2>
801inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
802bool
803operator==(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
804{
805 return __x.base() == __y.base();
806}
807
808template <class _Iter1, class _Iter2>
809inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
810bool
811operator<(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
812{
813 return __x.base() > __y.base();
814}
815
816template <class _Iter1, class _Iter2>
817inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
818bool
819operator!=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
820{
821 return __x.base() != __y.base();
822}
823
824template <class _Iter1, class _Iter2>
825inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
826bool
827operator>(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
828{
829 return __x.base() < __y.base();
830}
831
832template <class _Iter1, class _Iter2>
833inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
834bool
835operator>=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
836{
837 return __x.base() <= __y.base();
838}
839
840template <class _Iter1, class _Iter2>
841inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
842bool
843operator<=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
844{
845 return __x.base() >= __y.base();
846}
847
848#ifndef _LIBCPP_CXX03_LANG
849template <class _Iter1, class _Iter2>
850inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
851auto
852operator-(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
853-> decltype(__y.base() - __x.base())
854{
855 return __y.base() - __x.base();
856}
857#else
858template <class _Iter1, class _Iter2>
859inline _LIBCPP_INLINE_VISIBILITY
860typename reverse_iterator<_Iter1>::difference_type
861operator-(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
862{
863 return __y.base() - __x.base();
864}
865#endif
866
867template <class _Iter>
868inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
869reverse_iterator<_Iter>
870operator+(typename reverse_iterator<_Iter>::difference_type __n, const reverse_iterator<_Iter>& __x)
871{
872 return reverse_iterator<_Iter>(__x.base() - __n);
873}
874
875#if _LIBCPP_STD_VER > 11
876template <class _Iter>
877inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
878reverse_iterator<_Iter> make_reverse_iterator(_Iter __i)
879{
880 return reverse_iterator<_Iter>(__i);
881}
882#endif
883
884template <class _Container>
885class _LIBCPP_TEMPLATE_VIS back_insert_iterator
886 : public iterator<output_iterator_tag,
887 void,
888 void,
889 void,
890 void>
891{
892protected:
893 _Container* container;
894public:
895 typedef _Container container_type;
896
897 _LIBCPP_INLINE_VISIBILITY explicit back_insert_iterator(_Container& __x) : container(_VSTD::addressof(__x)) {}
898 _LIBCPP_INLINE_VISIBILITY back_insert_iterator& operator=(const typename _Container::value_type& __value_)
899 {container->push_back(__value_); return *this;}
900#ifndef _LIBCPP_CXX03_LANG
901 _LIBCPP_INLINE_VISIBILITY back_insert_iterator& operator=(typename _Container::value_type&& __value_)
902 {container->push_back(_VSTD::move(__value_)); return *this;}
903#endif // _LIBCPP_CXX03_LANG
904 _LIBCPP_INLINE_VISIBILITY back_insert_iterator& operator*() {return *this;}
905 _LIBCPP_INLINE_VISIBILITY back_insert_iterator& operator++() {return *this;}
906 _LIBCPP_INLINE_VISIBILITY back_insert_iterator operator++(int) {return *this;}
907};
908
909template <class _Container>
910inline _LIBCPP_INLINE_VISIBILITY
911back_insert_iterator<_Container>
912back_inserter(_Container& __x)
913{
914 return back_insert_iterator<_Container>(__x);
915}
916
917template <class _Container>
918class _LIBCPP_TEMPLATE_VIS front_insert_iterator
919 : public iterator<output_iterator_tag,
920 void,
921 void,
922 void,
923 void>
924{
925protected:
926 _Container* container;
927public:
928 typedef _Container container_type;
929
930 _LIBCPP_INLINE_VISIBILITY explicit front_insert_iterator(_Container& __x) : container(_VSTD::addressof(__x)) {}
931 _LIBCPP_INLINE_VISIBILITY front_insert_iterator& operator=(const typename _Container::value_type& __value_)
932 {container->push_front(__value_); return *this;}
933#ifndef _LIBCPP_CXX03_LANG
934 _LIBCPP_INLINE_VISIBILITY front_insert_iterator& operator=(typename _Container::value_type&& __value_)
935 {container->push_front(_VSTD::move(__value_)); return *this;}
936#endif // _LIBCPP_CXX03_LANG
937 _LIBCPP_INLINE_VISIBILITY front_insert_iterator& operator*() {return *this;}
938 _LIBCPP_INLINE_VISIBILITY front_insert_iterator& operator++() {return *this;}
939 _LIBCPP_INLINE_VISIBILITY front_insert_iterator operator++(int) {return *this;}
940};
941
942template <class _Container>
943inline _LIBCPP_INLINE_VISIBILITY
944front_insert_iterator<_Container>
945front_inserter(_Container& __x)
946{
947 return front_insert_iterator<_Container>(__x);
948}
949
950template <class _Container>
951class _LIBCPP_TEMPLATE_VIS insert_iterator
952 : public iterator<output_iterator_tag,
953 void,
954 void,
955 void,
956 void>
957{
958protected:
959 _Container* container;
960 typename _Container::iterator iter;
961public:
962 typedef _Container container_type;
963
964 _LIBCPP_INLINE_VISIBILITY insert_iterator(_Container& __x, typename _Container::iterator __i)
965 : container(_VSTD::addressof(__x)), iter(__i) {}
966 _LIBCPP_INLINE_VISIBILITY insert_iterator& operator=(const typename _Container::value_type& __value_)
967 {iter = container->insert(iter, __value_); ++iter; return *this;}
968#ifndef _LIBCPP_CXX03_LANG
969 _LIBCPP_INLINE_VISIBILITY insert_iterator& operator=(typename _Container::value_type&& __value_)
970 {iter = container->insert(iter, _VSTD::move(__value_)); ++iter; return *this;}
971#endif // _LIBCPP_CXX03_LANG
972 _LIBCPP_INLINE_VISIBILITY insert_iterator& operator*() {return *this;}
973 _LIBCPP_INLINE_VISIBILITY insert_iterator& operator++() {return *this;}
974 _LIBCPP_INLINE_VISIBILITY insert_iterator& operator++(int) {return *this;}
975};
976
977template <class _Container>
978inline _LIBCPP_INLINE_VISIBILITY
979insert_iterator<_Container>
980inserter(_Container& __x, typename _Container::iterator __i)
981{
982 return insert_iterator<_Container>(__x, __i);
983}
984
985template <class _Tp, class _CharT = char,
986 class _Traits = char_traits<_CharT>, class _Distance = ptrdiff_t>
987class _LIBCPP_TEMPLATE_VIS istream_iterator
988 : public iterator<input_iterator_tag, _Tp, _Distance, const _Tp*, const _Tp&>
989{
990public:
991 typedef _CharT char_type;
992 typedef _Traits traits_type;
993 typedef basic_istream<_CharT,_Traits> istream_type;
994private:
995 istream_type* __in_stream_;
996 _Tp __value_;
997public:
998 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR istream_iterator() : __in_stream_(nullptr), __value_() {}
999 _LIBCPP_INLINE_VISIBILITY istream_iterator(istream_type& __s) : __in_stream_(_VSTD::addressof(__s))
1000 {
1001 if (!(*__in_stream_ >> __value_))
1002 __in_stream_ = nullptr;
1003 }
1004
1005 _LIBCPP_INLINE_VISIBILITY const _Tp& operator*() const {return __value_;}
1006 _LIBCPP_INLINE_VISIBILITY const _Tp* operator->() const {return _VSTD::addressof((operator*()));}
1007 _LIBCPP_INLINE_VISIBILITY istream_iterator& operator++()
1008 {
1009 if (!(*__in_stream_ >> __value_))
1010 __in_stream_ = nullptr;
1011 return *this;
1012 }
1013 _LIBCPP_INLINE_VISIBILITY istream_iterator operator++(int)
1014 {istream_iterator __t(*this); ++(*this); return __t;}
1015
1016 template <class _Up, class _CharU, class _TraitsU, class _DistanceU>
1017 friend _LIBCPP_INLINE_VISIBILITY
1018 bool
1019 operator==(const istream_iterator<_Up, _CharU, _TraitsU, _DistanceU>& __x,
1020 const istream_iterator<_Up, _CharU, _TraitsU, _DistanceU>& __y);
1021
1022 template <class _Up, class _CharU, class _TraitsU, class _DistanceU>
1023 friend _LIBCPP_INLINE_VISIBILITY
1024 bool
1025 operator==(const istream_iterator<_Up, _CharU, _TraitsU, _DistanceU>& __x,
1026 const istream_iterator<_Up, _CharU, _TraitsU, _DistanceU>& __y);
1027};
1028
1029template <class _Tp, class _CharT, class _Traits, class _Distance>
1030inline _LIBCPP_INLINE_VISIBILITY
1031bool
1032operator==(const istream_iterator<_Tp, _CharT, _Traits, _Distance>& __x,
1033 const istream_iterator<_Tp, _CharT, _Traits, _Distance>& __y)
1034{
1035 return __x.__in_stream_ == __y.__in_stream_;
1036}
1037
1038template <class _Tp, class _CharT, class _Traits, class _Distance>
1039inline _LIBCPP_INLINE_VISIBILITY
1040bool
1041operator!=(const istream_iterator<_Tp, _CharT, _Traits, _Distance>& __x,
1042 const istream_iterator<_Tp, _CharT, _Traits, _Distance>& __y)
1043{
1044 return !(__x == __y);
1045}
1046
1047template <class _Tp, class _CharT = char, class _Traits = char_traits<_CharT> >
1048class _LIBCPP_TEMPLATE_VIS ostream_iterator
1049 : public iterator<output_iterator_tag, void, void, void, void>
1050{
1051public:
1052 typedef output_iterator_tag iterator_category;
1053 typedef void value_type;
1054#if _LIBCPP_STD_VER > 17
1055 typedef std::ptrdiff_t difference_type;
1056#else
1057 typedef void difference_type;
1058#endif
1059 typedef void pointer;
1060 typedef void reference;
1061 typedef _CharT char_type;
1062 typedef _Traits traits_type;
1063 typedef basic_ostream<_CharT, _Traits> ostream_type;
1064
1065private:
1066 ostream_type* __out_stream_;
1067 const char_type* __delim_;
1068public:
1069 _LIBCPP_INLINE_VISIBILITY ostream_iterator(ostream_type& __s) _NOEXCEPT
1070 : __out_stream_(_VSTD::addressof(__s)), __delim_(nullptr) {}
1071 _LIBCPP_INLINE_VISIBILITY ostream_iterator(ostream_type& __s, const _CharT* __delimiter) _NOEXCEPT
1072 : __out_stream_(_VSTD::addressof(__s)), __delim_(__delimiter) {}
1073 _LIBCPP_INLINE_VISIBILITY ostream_iterator& operator=(const _Tp& __value_)
1074 {
1075 *__out_stream_ << __value_;
1076 if (__delim_)
1077 *__out_stream_ << __delim_;
1078 return *this;
1079 }
1080
1081 _LIBCPP_INLINE_VISIBILITY ostream_iterator& operator*() {return *this;}
1082 _LIBCPP_INLINE_VISIBILITY ostream_iterator& operator++() {return *this;}
1083 _LIBCPP_INLINE_VISIBILITY ostream_iterator& operator++(int) {return *this;}
1084};
1085
1086template<class _CharT, class _Traits>
1087class _LIBCPP_TEMPLATE_VIS istreambuf_iterator
1088 : public iterator<input_iterator_tag, _CharT,
1089 typename _Traits::off_type, _CharT*,
1090 _CharT>
1091{
1092public:
1093 typedef _CharT char_type;
1094 typedef _Traits traits_type;
1095 typedef typename _Traits::int_type int_type;
1096 typedef basic_streambuf<_CharT,_Traits> streambuf_type;
1097 typedef basic_istream<_CharT,_Traits> istream_type;
1098private:
1099 mutable streambuf_type* __sbuf_;
1100
1101 class __proxy
1102 {
1103 char_type __keep_;
1104 streambuf_type* __sbuf_;
1105 _LIBCPP_INLINE_VISIBILITY __proxy(char_type __c, streambuf_type* __s)
1106 : __keep_(__c), __sbuf_(__s) {}
1107 friend class istreambuf_iterator;
1108 public:
1109 _LIBCPP_INLINE_VISIBILITY char_type operator*() const {return __keep_;}
1110 };
1111
1112 _LIBCPP_INLINE_VISIBILITY
1113 bool __test_for_eof() const
1114 {
1115 if (__sbuf_ && traits_type::eq_int_type(__sbuf_->sgetc(), traits_type::eof()))
1116 __sbuf_ = nullptr;
1117 return __sbuf_ == nullptr;
1118 }
1119public:
1120 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR istreambuf_iterator() _NOEXCEPT : __sbuf_(nullptr) {}
1121 _LIBCPP_INLINE_VISIBILITY istreambuf_iterator(istream_type& __s) _NOEXCEPT
1122 : __sbuf_(__s.rdbuf()) {}
1123 _LIBCPP_INLINE_VISIBILITY istreambuf_iterator(streambuf_type* __s) _NOEXCEPT
1124 : __sbuf_(__s) {}
1125 _LIBCPP_INLINE_VISIBILITY istreambuf_iterator(const __proxy& __p) _NOEXCEPT
1126 : __sbuf_(__p.__sbuf_) {}
1127
1128 _LIBCPP_INLINE_VISIBILITY char_type operator*() const
1129 {return static_cast<char_type>(__sbuf_->sgetc());}
1130 _LIBCPP_INLINE_VISIBILITY istreambuf_iterator& operator++()
1131 {
1132 __sbuf_->sbumpc();
1133 return *this;
1134 }
1135 _LIBCPP_INLINE_VISIBILITY __proxy operator++(int)
1136 {
1137 return __proxy(__sbuf_->sbumpc(), __sbuf_);
1138 }
1139
1140 _LIBCPP_INLINE_VISIBILITY bool equal(const istreambuf_iterator& __b) const
1141 {return __test_for_eof() == __b.__test_for_eof();}
1142};
1143
1144template <class _CharT, class _Traits>
1145inline _LIBCPP_INLINE_VISIBILITY
1146bool operator==(const istreambuf_iterator<_CharT,_Traits>& __a,
1147 const istreambuf_iterator<_CharT,_Traits>& __b)
1148 {return __a.equal(__b);}
1149
1150template <class _CharT, class _Traits>
1151inline _LIBCPP_INLINE_VISIBILITY
1152bool operator!=(const istreambuf_iterator<_CharT,_Traits>& __a,
1153 const istreambuf_iterator<_CharT,_Traits>& __b)
1154 {return !__a.equal(__b);}
1155
1156template <class _CharT, class _Traits>
1157class _LIBCPP_TEMPLATE_VIS ostreambuf_iterator
1158 : public iterator<output_iterator_tag, void, void, void, void>
1159{
1160public:
1161 typedef output_iterator_tag iterator_category;
1162 typedef void value_type;
1163#if _LIBCPP_STD_VER > 17
1164 typedef std::ptrdiff_t difference_type;
1165#else
1166 typedef void difference_type;
1167#endif
1168 typedef void pointer;
1169 typedef void reference;
1170 typedef _CharT char_type;
1171 typedef _Traits traits_type;
1172 typedef basic_streambuf<_CharT, _Traits> streambuf_type;
1173 typedef basic_ostream<_CharT, _Traits> ostream_type;
1174
1175private:
1176 streambuf_type* __sbuf_;
1177public:
1178 _LIBCPP_INLINE_VISIBILITY ostreambuf_iterator(ostream_type& __s) _NOEXCEPT
1179 : __sbuf_(__s.rdbuf()) {}
1180 _LIBCPP_INLINE_VISIBILITY ostreambuf_iterator(streambuf_type* __s) _NOEXCEPT
1181 : __sbuf_(__s) {}
1182 _LIBCPP_INLINE_VISIBILITY ostreambuf_iterator& operator=(_CharT __c)
1183 {
1184 if (__sbuf_ && traits_type::eq_int_type(__sbuf_->sputc(__c), traits_type::eof()))
1185 __sbuf_ = nullptr;
1186 return *this;
1187 }
1188 _LIBCPP_INLINE_VISIBILITY ostreambuf_iterator& operator*() {return *this;}
1189 _LIBCPP_INLINE_VISIBILITY ostreambuf_iterator& operator++() {return *this;}
1190 _LIBCPP_INLINE_VISIBILITY ostreambuf_iterator& operator++(int) {return *this;}
1191 _LIBCPP_INLINE_VISIBILITY bool failed() const _NOEXCEPT {return __sbuf_ == nullptr;}
1192
1193 template <class _Ch, class _Tr>
1194 friend
1195 _LIBCPP_HIDDEN
1196 ostreambuf_iterator<_Ch, _Tr>
1197 __pad_and_output(ostreambuf_iterator<_Ch, _Tr> __s,
1198 const _Ch* __ob, const _Ch* __op, const _Ch* __oe,
1199 ios_base& __iob, _Ch __fl);
1200};
1201
1202template <class _Iter>
1203class _LIBCPP_TEMPLATE_VIS move_iterator
1204{
1205private:
1206 _Iter __i;
1207public:
1208 typedef _Iter iterator_type;
1209 typedef typename iterator_traits<iterator_type>::iterator_category iterator_category;
1210 typedef typename iterator_traits<iterator_type>::value_type value_type;
1211 typedef typename iterator_traits<iterator_type>::difference_type difference_type;
1212 typedef iterator_type pointer;
1213#ifndef _LIBCPP_CXX03_LANG
1214 typedef typename iterator_traits<iterator_type>::reference __reference;
1215 typedef typename conditional<
1216 is_reference<__reference>::value,
1217 typename remove_reference<__reference>::type&&,
1218 __reference
1219 >::type reference;
1220#else
1221 typedef typename iterator_traits<iterator_type>::reference reference;
1222#endif
1223
1224 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1225 move_iterator() : __i() {}
1226 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1227 explicit move_iterator(_Iter __x) : __i(__x) {}
1228 template <class _Up>
1229 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1230 move_iterator(const move_iterator<_Up>& __u) : __i(__u.base()) {}
1231 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 _Iter base() const {return __i;}
1232 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1233 reference operator*() const { return static_cast<reference>(*__i); }
1234 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1235 pointer operator->() const { return __i;}
1236 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1237 move_iterator& operator++() {++__i; return *this;}
1238 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1239 move_iterator operator++(int) {move_iterator __tmp(*this); ++__i; return __tmp;}
1240 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1241 move_iterator& operator--() {--__i; return *this;}
1242 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1243 move_iterator operator--(int) {move_iterator __tmp(*this); --__i; return __tmp;}
1244 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1245 move_iterator operator+ (difference_type __n) const {return move_iterator(__i + __n);}
1246 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1247 move_iterator& operator+=(difference_type __n) {__i += __n; return *this;}
1248 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1249 move_iterator operator- (difference_type __n) const {return move_iterator(__i - __n);}
1250 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1251 move_iterator& operator-=(difference_type __n) {__i -= __n; return *this;}
1252 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1253 reference operator[](difference_type __n) const { return static_cast<reference>(__i[__n]); }
1254};
1255
1256template <class _Iter1, class _Iter2>
1257inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1258bool
1259operator==(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
1260{
1261 return __x.base() == __y.base();
1262}
1263
1264template <class _Iter1, class _Iter2>
1265inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1266bool
1267operator<(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
1268{
1269 return __x.base() < __y.base();
1270}
1271
1272template <class _Iter1, class _Iter2>
1273inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1274bool
1275operator!=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
1276{
1277 return __x.base() != __y.base();
1278}
1279
1280template <class _Iter1, class _Iter2>
1281inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1282bool
1283operator>(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
1284{
1285 return __x.base() > __y.base();
1286}
1287
1288template <class _Iter1, class _Iter2>
1289inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1290bool
1291operator>=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
1292{
1293 return __x.base() >= __y.base();
1294}
1295
1296template <class _Iter1, class _Iter2>
1297inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1298bool
1299operator<=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
1300{
1301 return __x.base() <= __y.base();
1302}
1303
1304#ifndef _LIBCPP_CXX03_LANG
1305template <class _Iter1, class _Iter2>
1306inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1307auto
1308operator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
1309-> decltype(__x.base() - __y.base())
1310{
1311 return __x.base() - __y.base();
1312}
1313#else
1314template <class _Iter1, class _Iter2>
1315inline _LIBCPP_INLINE_VISIBILITY
1316typename move_iterator<_Iter1>::difference_type
1317operator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
1318{
1319 return __x.base() - __y.base();
1320}
1321#endif
1322
1323template <class _Iter>
1324inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1325move_iterator<_Iter>
1326operator+(typename move_iterator<_Iter>::difference_type __n, const move_iterator<_Iter>& __x)
1327{
1328 return move_iterator<_Iter>(__x.base() + __n);
1329}
1330
1331template <class _Iter>
1332inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1333move_iterator<_Iter>
1334make_move_iterator(_Iter __i)
1335{
1336 return move_iterator<_Iter>(__i);
1337}
1338
1339// __wrap_iter
1340
1341template <class _Iter> class __wrap_iter;
1342
1343template <class _Iter1, class _Iter2>
1344_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
1345bool
1346operator==(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
1347
1348template <class _Iter1, class _Iter2>
1349_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
1350bool
1351operator<(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
1352
1353template <class _Iter1, class _Iter2>
1354_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
1355bool
1356operator!=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
1357
1358template <class _Iter1, class _Iter2>
1359_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
1360bool
1361operator>(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
1362
1363template <class _Iter1, class _Iter2>
1364_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
1365bool
1366operator>=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
1367
1368template <class _Iter1, class _Iter2>
1369_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
1370bool
1371operator<=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
1372
1373#ifndef _LIBCPP_CXX03_LANG
1374template <class _Iter1, class _Iter2>
1375_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
1376auto
1377operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
1378-> decltype(__x.base() - __y.base());
1379#else
1380template <class _Iter1, class _Iter2>
1381_LIBCPP_INLINE_VISIBILITY
1382typename __wrap_iter<_Iter1>::difference_type
1383operator-(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
1384#endif
1385
1386template <class _Iter>
1387_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
1388__wrap_iter<_Iter>
1389operator+(typename __wrap_iter<_Iter>::difference_type, __wrap_iter<_Iter>) _NOEXCEPT;
1390
1391template <class _Ip, class _Op> _Op _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 copy(_Ip, _Ip, _Op);
1392template <class _B1, class _B2> _B2 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 copy_backward(_B1, _B1, _B2);
1393template <class _Ip, class _Op> _Op _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 move(_Ip, _Ip, _Op);
1394template <class _B1, class _B2> _B2 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 move_backward(_B1, _B1, _B2);
1395
1396#if _LIBCPP_DEBUG_LEVEL < 2
1397
1398template <class _Tp>
1399_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
1400typename enable_if
1401<
1402 is_trivially_copy_assignable<_Tp>::value,
1403 _Tp*
1404>::type
1405__unwrap_iter(__wrap_iter<_Tp*>);
1406
1407#else
1408
1409template <class _Tp>
1410inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
1411typename enable_if
1412<
1413 is_trivially_copy_assignable<_Tp>::value,
1414 __wrap_iter<_Tp*>
1415>::type
1416__unwrap_iter(__wrap_iter<_Tp*> __i);
1417
1418#endif
1419
1420template <class _Iter>
1421class __wrap_iter
1422{
1423public:
1424 typedef _Iter iterator_type;
1425 typedef typename iterator_traits<iterator_type>::iterator_category iterator_category;
1426 typedef typename iterator_traits<iterator_type>::value_type value_type;
1427 typedef typename iterator_traits<iterator_type>::difference_type difference_type;
1428 typedef typename iterator_traits<iterator_type>::pointer pointer;
1429 typedef typename iterator_traits<iterator_type>::reference reference;
1430private:
1431 iterator_type __i;
1432public:
1433 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter() _NOEXCEPT
1434#if _LIBCPP_STD_VER > 11
1435 : __i{}
1436#endif
1437 {
1438#if _LIBCPP_DEBUG_LEVEL == 2
1439 __get_db()->__insert_i(this);
1440#endif
1441 }
1442 template <class _Up> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
1443 __wrap_iter(const __wrap_iter<_Up>& __u,
1444 typename enable_if<is_convertible<_Up, iterator_type>::value>::type* = nullptr) _NOEXCEPT
1445 : __i(__u.base())
1446 {
1447#if _LIBCPP_DEBUG_LEVEL == 2
1448 __get_db()->__iterator_copy(this, &__u);
1449#endif
1450 }
1451#if _LIBCPP_DEBUG_LEVEL == 2
1452 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
1453 __wrap_iter(const __wrap_iter& __x)
1454 : __i(__x.base())
1455 {
1456 __get_db()->__iterator_copy(this, &__x);
1457 }
1458 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
1459 __wrap_iter& operator=(const __wrap_iter& __x)
1460 {
1461 if (this != &__x)
1462 {
1463 __get_db()->__iterator_copy(this, &__x);
1464 __i = __x.__i;
1465 }
1466 return *this;
1467 }
1468 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
1469 ~__wrap_iter()
1470 {
1471 __get_db()->__erase_i(this);
1472 }
1473#endif
1474 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG reference operator*() const _NOEXCEPT
1475 {
1476#if _LIBCPP_DEBUG_LEVEL == 2
1477 _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
1478 "Attempted to dereference a non-dereferenceable iterator");
1479#endif
1480 return *__i;
1481 }
1482 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG pointer operator->() const _NOEXCEPT
1483 {
1484#if _LIBCPP_DEBUG_LEVEL == 2
1485 _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
1486 "Attempted to dereference a non-dereferenceable iterator");
1487#endif
1488 return (pointer)_VSTD::addressof(*__i);
1489 }
1490 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter& operator++() _NOEXCEPT
1491 {
1492#if _LIBCPP_DEBUG_LEVEL == 2
1493 _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
1494 "Attempted to increment non-incrementable iterator");
1495#endif
1496 ++__i;
1497 return *this;
1498 }
1499 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter operator++(int) _NOEXCEPT
1500 {__wrap_iter __tmp(*this); ++(*this); return __tmp;}
1501
1502 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter& operator--() _NOEXCEPT
1503 {
1504#if _LIBCPP_DEBUG_LEVEL == 2
1505 _LIBCPP_ASSERT(__get_const_db()->__decrementable(this),
1506 "Attempted to decrement non-decrementable iterator");
1507#endif
1508 --__i;
1509 return *this;
1510 }
1511 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter operator--(int) _NOEXCEPT
1512 {__wrap_iter __tmp(*this); --(*this); return __tmp;}
1513 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter operator+ (difference_type __n) const _NOEXCEPT
1514 {__wrap_iter __w(*this); __w += __n; return __w;}
1515 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter& operator+=(difference_type __n) _NOEXCEPT
1516 {
1517#if _LIBCPP_DEBUG_LEVEL == 2
1518 _LIBCPP_ASSERT(__get_const_db()->__addable(this, __n),
1519 "Attempted to add/subtract iterator outside of valid range");
1520#endif
1521 __i += __n;
1522 return *this;
1523 }
1524 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter operator- (difference_type __n) const _NOEXCEPT
1525 {return *this + (-__n);}
1526 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter& operator-=(difference_type __n) _NOEXCEPT
1527 {*this += -__n; return *this;}
1528 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG reference operator[](difference_type __n) const _NOEXCEPT
1529 {
1530#if _LIBCPP_DEBUG_LEVEL == 2
1531 _LIBCPP_ASSERT(__get_const_db()->__subscriptable(this, __n),
1532 "Attempted to subscript iterator outside of valid range");
1533#endif
1534 return __i[__n];
1535 }
1536
1537 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG iterator_type base() const _NOEXCEPT {return __i;}
1538
1539private:
1540#if _LIBCPP_DEBUG_LEVEL == 2
1541 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter(const void* __p, iterator_type __x) : __i(__x)
1542 {
1543 __get_db()->__insert_ic(this, __p);
1544 }
1545#else
1546 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter(iterator_type __x) _NOEXCEPT : __i(__x) {}
1547#endif
1548
1549 template <class _Up> friend class __wrap_iter;
1550 template <class _CharT, class _Traits, class _Alloc> friend class basic_string;
1551 template <class _Tp, class _Alloc> friend class _LIBCPP_TEMPLATE_VIS vector;
1552 template <class _Tp, size_t> friend class _LIBCPP_TEMPLATE_VIS span;
1553
1554 template <class _Iter1, class _Iter2>
1555 _LIBCPP_CONSTEXPR_IF_NODEBUG friend
1556 bool
1557 operator==(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
1558
1559 template <class _Iter1, class _Iter2>
1560 _LIBCPP_CONSTEXPR_IF_NODEBUG friend
1561 bool
1562 operator<(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
1563
1564 template <class _Iter1, class _Iter2>
1565 _LIBCPP_CONSTEXPR_IF_NODEBUG friend
1566 bool
1567 operator!=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
1568
1569 template <class _Iter1, class _Iter2>
1570 _LIBCPP_CONSTEXPR_IF_NODEBUG friend
1571 bool
1572 operator>(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
1573
1574 template <class _Iter1, class _Iter2>
1575 _LIBCPP_CONSTEXPR_IF_NODEBUG friend
1576 bool
1577 operator>=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
1578
1579 template <class _Iter1, class _Iter2>
1580 _LIBCPP_CONSTEXPR_IF_NODEBUG friend
1581 bool
1582 operator<=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
1583
1584#ifndef _LIBCPP_CXX03_LANG
1585 template <class _Iter1, class _Iter2>
1586 _LIBCPP_CONSTEXPR_IF_NODEBUG friend
1587 auto
1588 operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
1589 -> decltype(__x.base() - __y.base());
1590#else
1591 template <class _Iter1, class _Iter2>
1592 _LIBCPP_CONSTEXPR_IF_NODEBUG friend
1593 typename __wrap_iter<_Iter1>::difference_type
1594 operator-(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
1595#endif
1596
1597 template <class _Iter1>
1598 _LIBCPP_CONSTEXPR_IF_NODEBUG friend
1599 __wrap_iter<_Iter1>
1600 operator+(typename __wrap_iter<_Iter1>::difference_type, __wrap_iter<_Iter1>) _NOEXCEPT;
1601
1602 template <class _Ip, class _Op> friend _LIBCPP_CONSTEXPR_AFTER_CXX17 _Op copy(_Ip, _Ip, _Op);
1603 template <class _B1, class _B2> friend _LIBCPP_CONSTEXPR_AFTER_CXX17 _B2 copy_backward(_B1, _B1, _B2);
1604 template <class _Ip, class _Op> friend _LIBCPP_CONSTEXPR_AFTER_CXX17 _Op move(_Ip, _Ip, _Op);
1605 template <class _B1, class _B2> friend _LIBCPP_CONSTEXPR_AFTER_CXX17 _B2 move_backward(_B1, _B1, _B2);
1606
1607#if _LIBCPP_DEBUG_LEVEL < 2
1608 template <class _Tp>
1609 _LIBCPP_CONSTEXPR friend
1610 typename enable_if
1611 <
1612 is_trivially_copy_assignable<_Tp>::value,
1613 _Tp*
1614 >::type
1615 __unwrap_iter(__wrap_iter<_Tp*>);
1616#else
1617 template <class _Tp>
1618 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR friend
1619 typename enable_if
1620 <
1621 is_trivially_copy_assignable<_Tp>::value,
1622 __wrap_iter<_Tp*>
1623 >::type
1624 __unwrap_iter(__wrap_iter<_Tp*> __i);
1625#endif
1626};
1627
1628template <class _Iter1, class _Iter2>
1629inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
1630bool
1631operator==(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
1632{
1633 return __x.base() == __y.base();
1634}
1635
1636template <class _Iter1, class _Iter2>
1637inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
1638bool
1639operator<(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
1640{
1641#if _LIBCPP_DEBUG_LEVEL == 2
1642 _LIBCPP_ASSERT(__get_const_db()->__less_than_comparable(&__x, &__y),
1643 "Attempted to compare incomparable iterators");
1644#endif
1645 return __x.base() < __y.base();
1646}
1647
1648template <class _Iter1, class _Iter2>
1649inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
1650bool
1651operator!=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
1652{
1653 return !(__x == __y);
1654}
1655
1656template <class _Iter1, class _Iter2>
1657inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
1658bool
1659operator>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
1660{
1661 return __y < __x;
1662}
1663
1664template <class _Iter1, class _Iter2>
1665inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
1666bool
1667operator>=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
1668{
1669 return !(__x < __y);
1670}
1671
1672template <class _Iter1, class _Iter2>
1673inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
1674bool
1675operator<=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
1676{
1677 return !(__y < __x);
1678}
1679
1680template <class _Iter1>
1681inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
1682bool
1683operator!=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT
1684{
1685 return !(__x == __y);
1686}
1687
1688template <class _Iter1>
1689inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
1690bool
1691operator>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT
1692{
1693 return __y < __x;
1694}
1695
1696template <class _Iter1>
1697inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
1698bool
1699operator>=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT
1700{
1701 return !(__x < __y);
1702}
1703
1704template <class _Iter1>
1705inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
1706bool
1707operator<=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT
1708{
1709 return !(__y < __x);
1710}
1711
1712#ifndef _LIBCPP_CXX03_LANG
1713template <class _Iter1, class _Iter2>
1714inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
1715auto
1716operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
1717-> decltype(__x.base() - __y.base())
1718{
1719#if _LIBCPP_DEBUG_LEVEL == 2
1720 _LIBCPP_ASSERT(__get_const_db()->__less_than_comparable(&__x, &__y),
1721 "Attempted to subtract incompatible iterators");
1722#endif
1723 return __x.base() - __y.base();
1724}
1725#else
1726template <class _Iter1, class _Iter2>
1727inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
1728typename __wrap_iter<_Iter1>::difference_type
1729operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
1730{
1731#if _LIBCPP_DEBUG_LEVEL == 2
1732 _LIBCPP_ASSERT(__get_const_db()->__less_than_comparable(&__x, &__y),
1733 "Attempted to subtract incompatible iterators");
1734#endif
1735 return __x.base() - __y.base();
1736}
1737#endif
1738
1739template <class _Iter>
1740inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
1741__wrap_iter<_Iter>
1742operator+(typename __wrap_iter<_Iter>::difference_type __n,
1743 __wrap_iter<_Iter> __x) _NOEXCEPT
1744{
1745 __x += __n;
1746 return __x;
1747}
1748
1749template <class _Iter>
1750struct __libcpp_is_trivial_iterator
1751 : public _LIBCPP_BOOL_CONSTANT(is_pointer<_Iter>::value) {};
1752
1753template <class _Iter>
1754struct __libcpp_is_trivial_iterator<move_iterator<_Iter> >
1755 : public _LIBCPP_BOOL_CONSTANT(__libcpp_is_trivial_iterator<_Iter>::value) {};
1756
1757template <class _Iter>
1758struct __libcpp_is_trivial_iterator<reverse_iterator<_Iter> >
1759 : public _LIBCPP_BOOL_CONSTANT(__libcpp_is_trivial_iterator<_Iter>::value) {};
1760
1761template <class _Iter>
1762struct __libcpp_is_trivial_iterator<__wrap_iter<_Iter> >
1763 : public _LIBCPP_BOOL_CONSTANT(__libcpp_is_trivial_iterator<_Iter>::value) {};
1764
1765
1766template <class _Tp, size_t _Np>
1767_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1768_Tp*
1769begin(_Tp (&__array)[_Np])
1770{
1771 return __array;
1772}
1773
1774template <class _Tp, size_t _Np>
1775_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1776_Tp*
1777end(_Tp (&__array)[_Np])
1778{
1779 return __array + _Np;
1780}
1781
1782#if !defined(_LIBCPP_CXX03_LANG)
1783
1784template <class _Cp>
1785_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1786auto
1787begin(_Cp& __c) -> decltype(__c.begin())
1788{
1789 return __c.begin();
1790}
1791
1792template <class _Cp>
1793_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1794auto
1795begin(const _Cp& __c) -> decltype(__c.begin())
1796{
1797 return __c.begin();
1798}
1799
1800template <class _Cp>
1801_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1802auto
1803end(_Cp& __c) -> decltype(__c.end())
1804{
1805 return __c.end();
1806}
1807
1808template <class _Cp>
1809_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1810auto
1811end(const _Cp& __c) -> decltype(__c.end())
1812{
1813 return __c.end();
1814}
1815
1816#if _LIBCPP_STD_VER > 11
1817
1818template <class _Tp, size_t _Np>
1819_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1820reverse_iterator<_Tp*> rbegin(_Tp (&__array)[_Np])
1821{
1822 return reverse_iterator<_Tp*>(__array + _Np);
1823}
1824
1825template <class _Tp, size_t _Np>
1826_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1827reverse_iterator<_Tp*> rend(_Tp (&__array)[_Np])
1828{
1829 return reverse_iterator<_Tp*>(__array);
1830}
1831
1832template <class _Ep>
1833_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1834reverse_iterator<const _Ep*> rbegin(initializer_list<_Ep> __il)
1835{
1836 return reverse_iterator<const _Ep*>(__il.end());
1837}
1838
1839template <class _Ep>
1840_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1841reverse_iterator<const _Ep*> rend(initializer_list<_Ep> __il)
1842{
1843 return reverse_iterator<const _Ep*>(__il.begin());
1844}
1845
1846template <class _Cp>
1847_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1848auto cbegin(const _Cp& __c) -> decltype(_VSTD::begin(__c))
1849{
1850 return _VSTD::begin(__c);
1851}
1852
1853template <class _Cp>
1854_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1855auto cend(const _Cp& __c) -> decltype(_VSTD::end(__c))
1856{
1857 return _VSTD::end(__c);
1858}
1859
1860template <class _Cp>
1861_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1862auto rbegin(_Cp& __c) -> decltype(__c.rbegin())
1863{
1864 return __c.rbegin();
1865}
1866
1867template <class _Cp>
1868_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1869auto rbegin(const _Cp& __c) -> decltype(__c.rbegin())
1870{
1871 return __c.rbegin();
1872}
1873
1874template <class _Cp>
1875_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1876auto rend(_Cp& __c) -> decltype(__c.rend())
1877{
1878 return __c.rend();
1879}
1880
1881template <class _Cp>
1882_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1883auto rend(const _Cp& __c) -> decltype(__c.rend())
1884{
1885 return __c.rend();
1886}
1887
1888template <class _Cp>
1889_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1890auto crbegin(const _Cp& __c) -> decltype(_VSTD::rbegin(__c))
1891{
1892 return _VSTD::rbegin(__c);
1893}
1894
1895template <class _Cp>
1896_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1897auto crend(const _Cp& __c) -> decltype(_VSTD::rend(__c))
1898{
1899 return _VSTD::rend(__c);
1900}
1901
1902#endif
1903
1904
1905#else // defined(_LIBCPP_CXX03_LANG)
1906
1907template <class _Cp>
1908_LIBCPP_INLINE_VISIBILITY
1909typename _Cp::iterator
1910begin(_Cp& __c)
1911{
1912 return __c.begin();
1913}
1914
1915template <class _Cp>
1916_LIBCPP_INLINE_VISIBILITY
1917typename _Cp::const_iterator
1918begin(const _Cp& __c)
1919{
1920 return __c.begin();
1921}
1922
1923template <class _Cp>
1924_LIBCPP_INLINE_VISIBILITY
1925typename _Cp::iterator
1926end(_Cp& __c)
1927{
1928 return __c.end();
1929}
1930
1931template <class _Cp>
1932_LIBCPP_INLINE_VISIBILITY
1933typename _Cp::const_iterator
1934end(const _Cp& __c)
1935{
1936 return __c.end();
1937}
1938
1939#endif // !defined(_LIBCPP_CXX03_LANG)
1940
1941#if _LIBCPP_STD_VER > 14
1942
1943// #if _LIBCPP_STD_VER > 11
1944// template <>
1945// struct _LIBCPP_TEMPLATE_VIS plus<void>
1946// {
1947// template <class _T1, class _T2>
1948// _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
1949// auto operator()(_T1&& __t, _T2&& __u) const
1950// _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) + _VSTD::forward<_T2>(__u)))
1951// -> decltype (_VSTD::forward<_T1>(__t) + _VSTD::forward<_T2>(__u))
1952// { return _VSTD::forward<_T1>(__t) + _VSTD::forward<_T2>(__u); }
1953// typedef void is_transparent;
1954// };
1955// #endif
1956
1957template <class _Cont>
1958_LIBCPP_INLINE_VISIBILITY
1959constexpr auto size(const _Cont& __c)
1960_NOEXCEPT_(noexcept(__c.size()))
1961-> decltype (__c.size())
1962{ return __c.size(); }
1963
1964template <class _Tp, size_t _Sz>
1965_LIBCPP_INLINE_VISIBILITY
1966constexpr size_t size(const _Tp (&)[_Sz]) noexcept { return _Sz; }
1967
1968#if _LIBCPP_STD_VER > 17
1969template <class _Cont>
1970_LIBCPP_INLINE_VISIBILITY
1971constexpr auto ssize(const _Cont& __c)
1972_NOEXCEPT_(noexcept(static_cast<common_type_t<ptrdiff_t, make_signed_t<decltype(__c.size())>>>(__c.size())))
1973-> common_type_t<ptrdiff_t, make_signed_t<decltype(__c.size())>>
1974{ return static_cast<common_type_t<ptrdiff_t, make_signed_t<decltype(__c.size())>>>(__c.size()); }
1975
1976template <class _Tp, ptrdiff_t _Sz>
1977_LIBCPP_INLINE_VISIBILITY
1978constexpr ptrdiff_t ssize(const _Tp (&)[_Sz]) noexcept { return _Sz; }
1979#endif
1980
1981template <class _Cont>
1982_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
1983constexpr auto empty(const _Cont& __c)
1984_NOEXCEPT_(noexcept(__c.empty()))
1985-> decltype (__c.empty())
1986{ return __c.empty(); }
1987
1988template <class _Tp, size_t _Sz>
1989_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
1990constexpr bool empty(const _Tp (&)[_Sz]) noexcept { return false; }
1991
1992template <class _Ep>
1993_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
1994constexpr bool empty(initializer_list<_Ep> __il) noexcept { return __il.size() == 0; }
1995
1996template <class _Cont> constexpr
1997_LIBCPP_INLINE_VISIBILITY
1998auto data(_Cont& __c)
1999_NOEXCEPT_(noexcept(__c.data()))
2000-> decltype (__c.data())
2001{ return __c.data(); }
2002
2003template <class _Cont> constexpr
2004_LIBCPP_INLINE_VISIBILITY
2005auto data(const _Cont& __c)
2006_NOEXCEPT_(noexcept(__c.data()))
2007-> decltype (__c.data())
2008{ return __c.data(); }
2009
2010template <class _Tp, size_t _Sz>
2011_LIBCPP_INLINE_VISIBILITY
2012constexpr _Tp* data(_Tp (&__array)[_Sz]) noexcept { return __array; }
2013
2014template <class _Ep>
2015_LIBCPP_INLINE_VISIBILITY
2016constexpr const _Ep* data(initializer_list<_Ep> __il) noexcept { return __il.begin(); }
2017#endif
2018
2019
2020_LIBCPP_END_NAMESPACE_STD
2021
2022#endif // _LIBCPP_ITERATOR
624#endif // _LIBCPP_ITERATOR
lib/libcxx/include/latch+1-1
......@@ -40,8 +40,8 @@ namespace std
4040
4141*/
4242
43#include <__config>
4443#include <__availability>
44#include <__config>
4545#include <atomic>
4646
4747#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
lib/libcxx/include/limits+1-1
......@@ -815,4 +815,4 @@ _LIBCPP_END_NAMESPACE_STD
815815
816816_LIBCPP_POP_MACROS
817817
818#endif // _LIBCPP_LIMITS
818#endif // _LIBCPP_LIMITS
lib/libcxx/include/limits.h+1-1
......@@ -61,4 +61,4 @@ Macros:
6161#include_next <limits.h>
6262#endif // __GNUC__
6363
64#endif // _LIBCPP_LIMITS_H
64#endif // _LIBCPP_LIMITS_H
lib/libcxx/include/list+47-45
......@@ -181,17 +181,16 @@ template <class T, class Allocator, class Predicate>
181181*/
182182
183183#include <__config>
184
185#include <memory>
186#include <limits>
184#include <__debug>
185#include <__utility/forward.h>
186#include <algorithm>
187187#include <initializer_list>
188188#include <iterator>
189#include <algorithm>
189#include <limits>
190#include <memory>
190191#include <type_traits>
191192#include <version>
192193
193#include <__debug>
194
195194#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
196195#pragma GCC system_header
197196#endif
......@@ -267,7 +266,7 @@ struct __list_node_base
267266};
268267
269268template <class _Tp, class _VoidPtr>
270struct __list_node
269struct _LIBCPP_STANDALONE_DEBUG __list_node
271270 : public __list_node_base<_Tp, _VoidPtr>
272271{
273272 _Tp __value_;
......@@ -351,7 +350,7 @@ public:
351350 return *this;
352351 }
353352
354#endif // _LIBCPP_DEBUG_LEVEL == 2
353#endif // _LIBCPP_DEBUG_LEVEL == 2
355354
356355 _LIBCPP_INLINE_VISIBILITY
357356 reference operator*() const
......@@ -377,7 +376,7 @@ public:
377376 {
378377#if _LIBCPP_DEBUG_LEVEL == 2
379378 _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
380 "Attempted to increment non-incrementable list::iterator");
379 "Attempted to increment a non-incrementable list::iterator");
381380#endif
382381 __ptr_ = __ptr_->__next_;
383382 return *this;
......@@ -390,7 +389,7 @@ public:
390389 {
391390#if _LIBCPP_DEBUG_LEVEL == 2
392391 _LIBCPP_ASSERT(__get_const_db()->__decrementable(this),
393 "Attempted to decrement non-decrementable list::iterator");
392 "Attempted to decrement a non-decrementable list::iterator");
394393#endif
395394 __ptr_ = __ptr_->__prev_;
396395 return *this;
......@@ -479,7 +478,7 @@ public:
479478 return *this;
480479 }
481480
482#endif // _LIBCPP_DEBUG_LEVEL == 2
481#endif // _LIBCPP_DEBUG_LEVEL == 2
483482 _LIBCPP_INLINE_VISIBILITY
484483 reference operator*() const
485484 {
......@@ -504,7 +503,7 @@ public:
504503 {
505504#if _LIBCPP_DEBUG_LEVEL == 2
506505 _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
507 "Attempted to increment non-incrementable list::const_iterator");
506 "Attempted to increment a non-incrementable list::const_iterator");
508507#endif
509508 __ptr_ = __ptr_->__next_;
510509 return *this;
......@@ -517,7 +516,7 @@ public:
517516 {
518517#if _LIBCPP_DEBUG_LEVEL == 2
519518 _LIBCPP_ASSERT(__get_const_db()->__decrementable(this),
520 "Attempted to decrement non-decrementable list::const_iterator");
519 "Attempted to decrement a non-decrementable list::const_iterator");
521520#endif
522521 __ptr_ = __ptr_->__prev_;
523522 return *this;
......@@ -895,7 +894,7 @@ public:
895894 typename enable_if<__is_cpp17_input_iterator<_InpIter>::value>::type* = 0);
896895
897896 list(const list& __c);
898 list(const list& __c, const allocator_type& __a);
897 list(const list& __c, const __identity_t<allocator_type>& __a);
899898 _LIBCPP_INLINE_VISIBILITY
900899 list& operator=(const list& __c);
901900#ifndef _LIBCPP_CXX03_LANG
......@@ -906,7 +905,7 @@ public:
906905 list(list&& __c)
907906 _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value);
908907 _LIBCPP_INLINE_VISIBILITY
909 list(list&& __c, const allocator_type& __a);
908 list(list&& __c, const __identity_t<allocator_type>& __a);
910909 _LIBCPP_INLINE_VISIBILITY
911910 list& operator=(list&& __c)
912911 _NOEXCEPT_(
......@@ -920,7 +919,7 @@ public:
920919 _LIBCPP_INLINE_VISIBILITY
921920 void assign(initializer_list<value_type> __il)
922921 {assign(__il.begin(), __il.end());}
923#endif // _LIBCPP_CXX03_LANG
922#endif // _LIBCPP_CXX03_LANG
924923
925924 template <class _InpIter>
926925 void assign(_InpIter __f, _InpIter __l,
......@@ -1023,7 +1022,7 @@ public:
10231022 _LIBCPP_INLINE_VISIBILITY
10241023 iterator insert(const_iterator __p, initializer_list<value_type> __il)
10251024 {return insert(__p, __il.begin(), __il.end());}
1026#endif // _LIBCPP_CXX03_LANG
1025#endif // _LIBCPP_CXX03_LANG
10271026
10281027 void push_front(const value_type& __x);
10291028 void push_back(const value_type& __x);
......@@ -1124,7 +1123,7 @@ public:
11241123 bool __addable(const const_iterator* __i, ptrdiff_t __n) const;
11251124 bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const;
11261125
1127#endif // _LIBCPP_DEBUG_LEVEL == 2
1126#endif // _LIBCPP_DEBUG_LEVEL == 2
11281127
11291128private:
11301129 _LIBCPP_INLINE_VISIBILITY
......@@ -1144,18 +1143,18 @@ private:
11441143
11451144#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
11461145template<class _InputIterator,
1147 class _Alloc = allocator<typename iterator_traits<_InputIterator>::value_type>,
1148 class = typename enable_if<__is_allocator<_Alloc>::value, void>::type
1146 class _Alloc = allocator<__iter_value_type<_InputIterator>>,
1147 class = _EnableIf<__is_allocator<_Alloc>::value>
11491148 >
11501149list(_InputIterator, _InputIterator)
1151 -> list<typename iterator_traits<_InputIterator>::value_type, _Alloc>;
1150 -> list<__iter_value_type<_InputIterator>, _Alloc>;
11521151
11531152template<class _InputIterator,
11541153 class _Alloc,
1155 class = typename enable_if<__is_allocator<_Alloc>::value, void>::type
1154 class = _EnableIf<__is_allocator<_Alloc>::value>
11561155 >
11571156list(_InputIterator, _InputIterator, _Alloc)
1158 -> list<typename iterator_traits<_InputIterator>::value_type, _Alloc>;
1157 -> list<__iter_value_type<_InputIterator>, _Alloc>;
11591158#endif
11601159
11611160// Link in nodes [__f, __l] just prior to __p
......@@ -1288,7 +1287,7 @@ list<_Tp, _Alloc>::list(const list& __c)
12881287}
12891288
12901289template <class _Tp, class _Alloc>
1291list<_Tp, _Alloc>::list(const list& __c, const allocator_type& __a)
1290list<_Tp, _Alloc>::list(const list& __c, const __identity_t<allocator_type>& __a)
12921291 : base(__a)
12931292{
12941293#if _LIBCPP_DEBUG_LEVEL == 2
......@@ -1335,7 +1334,7 @@ inline list<_Tp, _Alloc>::list(list&& __c)
13351334
13361335template <class _Tp, class _Alloc>
13371336inline
1338list<_Tp, _Alloc>::list(list&& __c, const allocator_type& __a)
1337list<_Tp, _Alloc>::list(list&& __c, const __identity_t<allocator_type>& __a)
13391338 : base(__a)
13401339{
13411340#if _LIBCPP_DEBUG_LEVEL == 2
......@@ -1386,7 +1385,7 @@ list<_Tp, _Alloc>::__move_assign(list& __c, true_type)
13861385 splice(end(), __c);
13871386}
13881387
1389#endif // _LIBCPP_CXX03_LANG
1388#endif // _LIBCPP_CXX03_LANG
13901389
13911390template <class _Tp, class _Alloc>
13921391inline
......@@ -1495,7 +1494,7 @@ list<_Tp, _Alloc>::insert(const_iterator __p, size_type __n, const value_type& _
14951494#ifndef _LIBCPP_NO_EXCEPTIONS
14961495 try
14971496 {
1498#endif // _LIBCPP_NO_EXCEPTIONS
1497#endif // _LIBCPP_NO_EXCEPTIONS
14991498 for (--__n; __n != 0; --__n, ++__e, ++__ds)
15001499 {
15011500 __hold.reset(__node_alloc_traits::allocate(__na, 1));
......@@ -1523,7 +1522,7 @@ list<_Tp, _Alloc>::insert(const_iterator __p, size_type __n, const value_type& _
15231522 }
15241523 throw;
15251524 }
1526#endif // _LIBCPP_NO_EXCEPTIONS
1525#endif // _LIBCPP_NO_EXCEPTIONS
15271526 __link_nodes(__p.__ptr_, __r.__ptr_, __e.__ptr_);
15281527 base::__sz() += __ds;
15291528 }
......@@ -1561,7 +1560,7 @@ list<_Tp, _Alloc>::insert(const_iterator __p, _InpIter __f, _InpIter __l,
15611560#ifndef _LIBCPP_NO_EXCEPTIONS
15621561 try
15631562 {
1564#endif // _LIBCPP_NO_EXCEPTIONS
1563#endif // _LIBCPP_NO_EXCEPTIONS
15651564 for (++__f; __f != __l; ++__f, (void) ++__e, (void) ++__ds)
15661565 {
15671566 __hold.reset(__node_alloc_traits::allocate(__na, 1));
......@@ -1589,7 +1588,7 @@ list<_Tp, _Alloc>::insert(const_iterator __p, _InpIter __f, _InpIter __l,
15891588 }
15901589 throw;
15911590 }
1592#endif // _LIBCPP_NO_EXCEPTIONS
1591#endif // _LIBCPP_NO_EXCEPTIONS
15931592 __link_nodes(__p.__ptr_, __r.__ptr_, __e.__ptr_);
15941593 base::__sz() += __ds;
15951594 }
......@@ -1737,7 +1736,7 @@ list<_Tp, _Alloc>::insert(const_iterator __p, value_type&& __x)
17371736#endif
17381737}
17391738
1740#endif // _LIBCPP_CXX03_LANG
1739#endif // _LIBCPP_CXX03_LANG
17411740
17421741template <class _Tp, class _Alloc>
17431742void
......@@ -1772,7 +1771,7 @@ template <class _Tp, class _Alloc>
17721771void
17731772list<_Tp, _Alloc>::pop_back()
17741773{
1775 _LIBCPP_ASSERT(!empty(), "list::pop_back() called with empty list");
1774 _LIBCPP_ASSERT(!empty(), "list::pop_back() called on an empty list");
17761775 __node_allocator& __na = base::__node_alloc();
17771776 __link_pointer __n = base::__end_.__prev_;
17781777 base::__unlink_nodes(__n, __n);
......@@ -1909,7 +1908,7 @@ list<_Tp, _Alloc>::resize(size_type __n)
19091908#ifndef _LIBCPP_NO_EXCEPTIONS
19101909 try
19111910 {
1912#endif // _LIBCPP_NO_EXCEPTIONS
1911#endif // _LIBCPP_NO_EXCEPTIONS
19131912 for (--__n; __n != 0; --__n, ++__e, ++__ds)
19141913 {
19151914 __hold.reset(__node_alloc_traits::allocate(__na, 1));
......@@ -1937,7 +1936,7 @@ list<_Tp, _Alloc>::resize(size_type __n)
19371936 }
19381937 throw;
19391938 }
1940#endif // _LIBCPP_NO_EXCEPTIONS
1939#endif // _LIBCPP_NO_EXCEPTIONS
19411940 __link_nodes_at_back(__r.__ptr_, __e.__ptr_);
19421941 base::__sz() += __ds;
19431942 }
......@@ -1967,7 +1966,7 @@ list<_Tp, _Alloc>::resize(size_type __n, const value_type& __x)
19671966#ifndef _LIBCPP_NO_EXCEPTIONS
19681967 try
19691968 {
1970#endif // _LIBCPP_NO_EXCEPTIONS
1969#endif // _LIBCPP_NO_EXCEPTIONS
19711970 for (--__n; __n != 0; --__n, ++__e, ++__ds)
19721971 {
19731972 __hold.reset(__node_alloc_traits::allocate(__na, 1));
......@@ -1995,7 +1994,7 @@ list<_Tp, _Alloc>::resize(size_type __n, const value_type& __x)
19951994 }
19961995 throw;
19971996 }
1998#endif // _LIBCPP_NO_EXCEPTIONS
1997#endif // _LIBCPP_NO_EXCEPTIONS
19991998 __link_nodes(base::__end_as_link(), __r.__ptr_, __e.__ptr_);
20001999 base::__sz() += __ds;
20012000 }
......@@ -2049,14 +2048,14 @@ list<_Tp, _Alloc>::splice(const_iterator __p, list& __c, const_iterator __i)
20492048{
20502049#if _LIBCPP_DEBUG_LEVEL == 2
20512050 _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,
2052 "list::splice(iterator, list, iterator) called with first iterator not"
2053 " referring to this list");
2051 "list::splice(iterator, list, iterator) called with the first iterator"
2052 " not referring to this list");
20542053 _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__i) == &__c,
2055 "list::splice(iterator, list, iterator) called with second iterator not"
2056 " referring to list argument");
2054 "list::splice(iterator, list, iterator) called with the second iterator"
2055 " not referring to the list argument");
20572056 _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(&__i),
2058 "list::splice(iterator, list, iterator) called with second iterator not"
2059 " dereferenceable");
2057 "list::splice(iterator, list, iterator) called with the second iterator"
2058 " not dereferenceable");
20602059#endif
20612060 if (__p.__ptr_ != __i.__ptr_ && __p.__ptr_ != __i.__ptr_->__next_)
20622061 {
......@@ -2098,7 +2097,10 @@ list<_Tp, _Alloc>::splice(const_iterator __p, list& __c, const_iterator __f, con
20982097 " referring to this list");
20992098 _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__f) == &__c,
21002099 "list::splice(iterator, list, iterator, iterator) called with second iterator not"
2101 " referring to list argument");
2100 " referring to the list argument");
2101 _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__l) == &__c,
2102 "list::splice(iterator, list, iterator, iterator) called with third iterator not"
2103 " referring to the list argument");
21022104 if (this == &__c)
21032105 {
21042106 for (const_iterator __i = __f; __i != __l; ++__i)
......@@ -2412,7 +2414,7 @@ list<_Tp, _Alloc>::__subscriptable(const const_iterator*, ptrdiff_t) const
24122414 return false;
24132415}
24142416
2415#endif // _LIBCPP_DEBUG_LEVEL == 2
2417#endif // _LIBCPP_DEBUG_LEVEL == 2
24162418
24172419template <class _Tp, class _Alloc>
24182420inline _LIBCPP_INLINE_VISIBILITY
......@@ -2489,4 +2491,4 @@ _LIBCPP_END_NAMESPACE_STD
24892491
24902492_LIBCPP_POP_MACROS
24912493
2492#endif // _LIBCPP_LIST
2494#endif // _LIBCPP_LIST
lib/libcxx/include/locale+45-34
......@@ -188,23 +188,28 @@ template <class charT> class messages_byname;
188188*/
189189
190190#include <__config>
191#include <__locale>
192191#include <__debug>
192#include <__locale>
193193#include <algorithm>
194#include <memory>
195#include <ios>
196#include <streambuf>
197#include <iterator>
198#include <limits>
199#include <version>
200194#ifndef __APPLE__
201#include <cstdarg>
195# include <cstdarg>
202196#endif
197#include <cstdio>
203198#include <cstdlib>
204199#include <ctime>
205#include <cstdio>
206#ifdef _LIBCPP_HAS_CATOPEN
207#include <nl_types.h>
200#include <ios>
201#include <iterator>
202#include <limits>
203#include <memory>
204#include <streambuf>
205#include <version>
206
207#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
208// Most unix variants have catopen. These are the specific ones that don't.
209# if !defined(__BIONIC__) && !defined(_NEWLIB_VERSION)
210# define _LIBCPP_HAS_CATOPEN 1
211# include <nl_types.h>
212# endif
208213#endif
209214
210215#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
......@@ -1453,10 +1458,12 @@ num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
14531458 char __fmt[6] = {'%', 0};
14541459 const char* __len = "l";
14551460 this->__format_int(__fmt+1, __len, true, __iob.flags());
1456 const unsigned __nbuf = (numeric_limits<long>::digits / 3)
1457 + ((numeric_limits<long>::digits % 3) != 0)
1458 + ((__iob.flags() & ios_base::showbase) != 0)
1459 + 2;
1461 // Worst case is octal, with showbase enabled. Note that octal is always
1462 // printed as an unsigned value.
1463 _LIBCPP_CONSTEXPR const unsigned __nbuf
1464 = (numeric_limits<unsigned long>::digits / 3) // 1 char per 3 bits
1465 + ((numeric_limits<unsigned long>::digits % 3) != 0) // round up
1466 + 2; // base prefix + terminating null character
14601467 char __nar[__nbuf];
14611468 int __nc = __libcpp_snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
14621469 char* __ne = __nar + __nc;
......@@ -1480,10 +1487,12 @@ num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
14801487 char __fmt[8] = {'%', 0};
14811488 const char* __len = "ll";
14821489 this->__format_int(__fmt+1, __len, true, __iob.flags());
1483 const unsigned __nbuf = (numeric_limits<long long>::digits / 3)
1484 + ((numeric_limits<long long>::digits % 3) != 0)
1485 + ((__iob.flags() & ios_base::showbase) != 0)
1486 + 2;
1490 // Worst case is octal, with showbase enabled. Note that octal is always
1491 // printed as an unsigned value.
1492 _LIBCPP_CONSTEXPR const unsigned __nbuf
1493 = (numeric_limits<unsigned long long>::digits / 3) // 1 char per 3 bits
1494 + ((numeric_limits<unsigned long long>::digits % 3) != 0) // round up
1495 + 2; // base prefix + terminating null character
14871496 char __nar[__nbuf];
14881497 int __nc = __libcpp_snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
14891498 char* __ne = __nar + __nc;
......@@ -1507,10 +1516,11 @@ num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
15071516 char __fmt[6] = {'%', 0};
15081517 const char* __len = "l";
15091518 this->__format_int(__fmt+1, __len, false, __iob.flags());
1510 const unsigned __nbuf = (numeric_limits<unsigned long>::digits / 3)
1511 + ((numeric_limits<unsigned long>::digits % 3) != 0)
1512 + ((__iob.flags() & ios_base::showbase) != 0)
1513 + 1;
1519 // Worst case is octal, with showbase enabled.
1520 _LIBCPP_CONSTEXPR const unsigned __nbuf
1521 = (numeric_limits<unsigned long>::digits / 3) // 1 char per 3 bits
1522 + ((numeric_limits<unsigned long>::digits % 3) != 0) // round up
1523 + 2; // base prefix + terminating null character
15141524 char __nar[__nbuf];
15151525 int __nc = __libcpp_snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
15161526 char* __ne = __nar + __nc;
......@@ -1534,10 +1544,11 @@ num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
15341544 char __fmt[8] = {'%', 0};
15351545 const char* __len = "ll";
15361546 this->__format_int(__fmt+1, __len, false, __iob.flags());
1537 const unsigned __nbuf = (numeric_limits<unsigned long long>::digits / 3)
1538 + ((numeric_limits<unsigned long long>::digits % 3) != 0)
1539 + ((__iob.flags() & ios_base::showbase) != 0)
1540 + 1;
1547 // Worst case is octal, with showbase enabled.
1548 _LIBCPP_CONSTEXPR const unsigned __nbuf
1549 = (numeric_limits<unsigned long long>::digits / 3) // 1 char per 3 bits
1550 + ((numeric_limits<unsigned long long>::digits % 3) != 0) // round up
1551 + 2; // base prefix + terminating null character
15411552 char __nar[__nbuf];
15421553 int __nc = __libcpp_snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
15431554 char* __ne = __nar + __nc;
......@@ -3567,7 +3578,7 @@ messages<_CharT>::do_open(const basic_string<char>& __nm, const locale&) const
35673578 __cat = static_cast<catalog>((static_cast<size_t>(__cat) >> 1));
35683579 return __cat;
35693580#else // !_LIBCPP_HAS_CATOPEN
3570 _LIBCPP_UNUSED_VAR(__nm);
3581 (void)__nm;
35713582 return -1;
35723583#endif // _LIBCPP_HAS_CATOPEN
35733584}
......@@ -3591,9 +3602,9 @@ messages<_CharT>::do_get(catalog __c, int __set, int __msgid,
35913602 __n, __n + _VSTD::strlen(__n));
35923603 return __w;
35933604#else // !_LIBCPP_HAS_CATOPEN
3594 _LIBCPP_UNUSED_VAR(__c);
3595 _LIBCPP_UNUSED_VAR(__set);
3596 _LIBCPP_UNUSED_VAR(__msgid);
3605 (void)__c;
3606 (void)__set;
3607 (void)__msgid;
35973608 return __dflt;
35983609#endif // _LIBCPP_HAS_CATOPEN
35993610}
......@@ -3608,7 +3619,7 @@ messages<_CharT>::do_close(catalog __c) const
36083619 nl_catd __cat = (nl_catd)__c;
36093620 catclose(__cat);
36103621#else // !_LIBCPP_HAS_CATOPEN
3611 _LIBCPP_UNUSED_VAR(__c);
3622 (void)__c;
36123623#endif // _LIBCPP_HAS_CATOPEN
36133624}
36143625
......@@ -3748,7 +3759,7 @@ wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
37483759 __wc.__cvtptr_ = nullptr;
37493760}
37503761
3751#endif // _LIBCPP_CXX03_LANG
3762#endif // _LIBCPP_CXX03_LANG
37523763
37533764template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
37543765wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::~wstring_convert()
......@@ -4376,4 +4387,4 @@ _LIBCPP_END_NAMESPACE_STD
43764387
43774388_LIBCPP_POP_MACROS
43784389
4379#endif // _LIBCPP_LOCALE
4390#endif // _LIBCPP_LOCALE
lib/libcxx/include/locale.h+1-1
......@@ -45,4 +45,4 @@ Functions:
4545
4646#include_next <locale.h>
4747
48#endif // _LIBCPP_LOCALE_H
48#endif // _LIBCPP_LOCALE_H
lib/libcxx/include/map+64-22
......@@ -43,7 +43,6 @@ public:
4343 typedef INSERT_RETURN_TYPE<iterator, node_type> insert_return_type; // C++17
4444
4545 class value_compare
46 : public binary_function<value_type, value_type, bool>
4746 {
4847 friend class map;
4948 protected:
......@@ -51,6 +50,9 @@ public:
5150
5251 value_compare(key_compare c);
5352 public:
53 typedef bool result_type; // deprecated in C++17, removed in C++20
54 typedef value_type first_argument_type; // deprecated in C++17, removed in C++20
55 typedef value_type second_argument_type; // deprecated in C++17, removed in C++20
5456 bool operator()(const value_type& x, const value_type& y) const;
5557 };
5658
......@@ -191,10 +193,14 @@ public:
191193 iterator find(const K& x); // C++14
192194 template<typename K>
193195 const_iterator find(const K& x) const; // C++14
196
194197 template<typename K>
195198 size_type count(const K& x) const; // C++14
196199 size_type count(const key_type& k) const;
197 bool contains(const key_type& x) const; // C++20
200
201 bool contains(const key_type& x) const; // C++20
202 template<class K> bool contains(const K& x) const; // C++20
203
198204 iterator lower_bound(const key_type& k);
199205 const_iterator lower_bound(const key_type& k) const;
200206 template<typename K>
......@@ -283,13 +289,15 @@ public:
283289 typedef unspecified node_type; // C++17
284290
285291 class value_compare
286 : public binary_function<value_type,value_type,bool>
287292 {
288293 friend class multimap;
289294 protected:
290295 key_compare comp;
291296 value_compare(key_compare c);
292297 public:
298 typedef bool result_type; // deprecated in C++17, removed in C++20
299 typedef value_type first_argument_type; // deprecated in C++17, removed in C++20
300 typedef value_type second_argument_type; // deprecated in C++17, removed in C++20
293301 bool operator()(const value_type& x, const value_type& y) const;
294302 };
295303
......@@ -406,10 +414,14 @@ public:
406414 iterator find(const K& x); // C++14
407415 template<typename K>
408416 const_iterator find(const K& x) const; // C++14
417
409418 template<typename K>
410419 size_type count(const K& x) const; // C++14
411420 size_type count(const key_type& k) const;
412 bool contains(const key_type& x) const; // C++20
421
422 bool contains(const key_type& x) const; // C++20
423 template<class K> bool contains(const K& x) const; // C++20
424
413425 iterator lower_bound(const key_type& k);
414426 const_iterator lower_bound(const key_type& k) const;
415427 template<typename K>
......@@ -478,14 +490,18 @@ erase_if(multimap<Key, T, Compare, Allocator>& c, Predicate pred); // C++20
478490*/
479491
480492#include <__config>
481#include <__tree>
493#include <__debug>
494#include <__functional/is_transparent.h>
482495#include <__node_handle>
483#include <iterator>
484#include <memory>
485#include <utility>
496#include <__tree>
497#include <__utility/forward.h>
498#include <compare>
486499#include <functional>
487500#include <initializer_list>
501#include <iterator> // __libcpp_erase_if_container
502#include <memory>
488503#include <type_traits>
504#include <utility>
489505#include <version>
490506
491507#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
......@@ -633,7 +649,7 @@ public:
633649 {
634650 __x.__value_constructed = false;
635651 }
636#endif // _LIBCPP_CXX03_LANG
652#endif // _LIBCPP_CXX03_LANG
637653
638654 _LIBCPP_INLINE_VISIBILITY
639655 void operator()(pointer __p) _NOEXCEPT
......@@ -656,7 +672,7 @@ template <class _TreeIterator> class __map_const_iterator;
656672#ifndef _LIBCPP_CXX03_LANG
657673
658674template <class _Key, class _Tp>
659struct __value_type
675struct _LIBCPP_STANDALONE_DEBUG __value_type
660676{
661677 typedef _Key key_type;
662678 typedef _Tp mapped_type;
......@@ -904,23 +920,32 @@ public:
904920 typedef _Key key_type;
905921 typedef _Tp mapped_type;
906922 typedef pair<const key_type, mapped_type> value_type;
907 typedef typename __identity<_Compare>::type key_compare;
908 typedef typename __identity<_Allocator>::type allocator_type;
923 typedef __identity_t<_Compare> key_compare;
924 typedef __identity_t<_Allocator> allocator_type;
909925 typedef value_type& reference;
910926 typedef const value_type& const_reference;
911927
912928 static_assert((is_same<typename allocator_type::value_type, value_type>::value),
913929 "Allocator::value_type must be same type as value_type");
914930
931_LIBCPP_SUPPRESS_DEPRECATED_PUSH
915932 class _LIBCPP_TEMPLATE_VIS value_compare
933#if defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
916934 : public binary_function<value_type, value_type, bool>
935#endif
917936 {
937_LIBCPP_SUPPRESS_DEPRECATED_POP
918938 friend class map;
919939 protected:
920940 key_compare comp;
921941
922942 _LIBCPP_INLINE_VISIBILITY value_compare(key_compare c) : comp(c) {}
923943 public:
944#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
945 _LIBCPP_DEPRECATED_IN_CXX17 typedef bool result_type;
946 _LIBCPP_DEPRECATED_IN_CXX17 typedef value_type first_argument_type;
947 _LIBCPP_DEPRECATED_IN_CXX17 typedef value_type second_argument_type;
948#endif
924949 _LIBCPP_INLINE_VISIBILITY
925950 bool operator()(const value_type& __x, const value_type& __y) const
926951 {return comp(__x.first, __y.first);}
......@@ -1071,7 +1096,7 @@ public:
10711096 return *this;
10721097 }
10731098
1074#endif // _LIBCPP_CXX03_LANG
1099#endif // _LIBCPP_CXX03_LANG
10751100
10761101 _LIBCPP_INLINE_VISIBILITY
10771102 explicit map(const allocator_type& __a)
......@@ -1168,7 +1193,7 @@ public:
11681193 iterator insert(const_iterator __pos, _Pp&& __p)
11691194 {return __tree_.__insert_unique(__pos.__i_, _VSTD::forward<_Pp>(__p));}
11701195
1171#endif // _LIBCPP_CXX03_LANG
1196#endif // _LIBCPP_CXX03_LANG
11721197
11731198 _LIBCPP_INLINE_VISIBILITY
11741199 pair<iterator, bool>
......@@ -1404,6 +1429,10 @@ public:
14041429#if _LIBCPP_STD_VER > 17
14051430 _LIBCPP_INLINE_VISIBILITY
14061431 bool contains(const key_type& __k) const {return find(__k) != end();}
1432 template <typename _K2>
1433 _LIBCPP_INLINE_VISIBILITY
1434 typename enable_if<__is_transparent<_Compare, _K2>::value, bool>::type
1435 contains(const _K2& __k) const { return find(__k) != end(); }
14071436#endif // _LIBCPP_STD_VER > 17
14081437
14091438 _LIBCPP_INLINE_VISIBILITY
......@@ -1565,7 +1594,7 @@ map<_Key, _Tp, _Compare, _Allocator>::operator[](const key_type& __k)
15651594 return __r->__value_.__get_value().second;
15661595}
15671596
1568#endif // _LIBCPP_CXX03_LANG
1597#endif // _LIBCPP_CXX03_LANG
15691598
15701599template <class _Key, class _Tp, class _Compare, class _Allocator>
15711600_Tp&
......@@ -1660,7 +1689,7 @@ template <class _Key, class _Tp, class _Compare, class _Allocator,
16601689inline _LIBCPP_INLINE_VISIBILITY
16611690 typename map<_Key, _Tp, _Compare, _Allocator>::size_type
16621691 erase_if(map<_Key, _Tp, _Compare, _Allocator>& __c, _Predicate __pred) {
1663 return __libcpp_erase_if_container(__c, __pred);
1692 return _VSTD::__libcpp_erase_if_container(__c, __pred);
16641693}
16651694#endif
16661695
......@@ -1674,17 +1703,21 @@ public:
16741703 typedef _Key key_type;
16751704 typedef _Tp mapped_type;
16761705 typedef pair<const key_type, mapped_type> value_type;
1677 typedef typename __identity<_Compare>::type key_compare;
1678 typedef typename __identity<_Allocator>::type allocator_type;
1706 typedef __identity_t<_Compare> key_compare;
1707 typedef __identity_t<_Allocator> allocator_type;
16791708 typedef value_type& reference;
16801709 typedef const value_type& const_reference;
16811710
16821711 static_assert((is_same<typename allocator_type::value_type, value_type>::value),
16831712 "Allocator::value_type must be same type as value_type");
16841713
1714_LIBCPP_SUPPRESS_DEPRECATED_PUSH
16851715 class _LIBCPP_TEMPLATE_VIS value_compare
1716#if defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
16861717 : public binary_function<value_type, value_type, bool>
1718#endif
16871719 {
1720_LIBCPP_SUPPRESS_DEPRECATED_POP
16881721 friend class multimap;
16891722 protected:
16901723 key_compare comp;
......@@ -1692,6 +1725,11 @@ public:
16921725 _LIBCPP_INLINE_VISIBILITY
16931726 value_compare(key_compare c) : comp(c) {}
16941727 public:
1728#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
1729 _LIBCPP_DEPRECATED_IN_CXX17 typedef bool result_type;
1730 _LIBCPP_DEPRECATED_IN_CXX17 typedef value_type first_argument_type;
1731 _LIBCPP_DEPRECATED_IN_CXX17 typedef value_type second_argument_type;
1732#endif
16951733 _LIBCPP_INLINE_VISIBILITY
16961734 bool operator()(const value_type& __x, const value_type& __y) const
16971735 {return comp(__x.first, __y.first);}
......@@ -1842,7 +1880,7 @@ public:
18421880 return *this;
18431881 }
18441882
1845#endif // _LIBCPP_CXX03_LANG
1883#endif // _LIBCPP_CXX03_LANG
18461884
18471885 _LIBCPP_INLINE_VISIBILITY
18481886 explicit multimap(const allocator_type& __a)
......@@ -1945,7 +1983,7 @@ public:
19451983 void insert(initializer_list<value_type> __il)
19461984 {insert(__il.begin(), __il.end());}
19471985
1948#endif // _LIBCPP_CXX03_LANG
1986#endif // _LIBCPP_CXX03_LANG
19491987
19501988 _LIBCPP_INLINE_VISIBILITY
19511989 iterator insert(const value_type& __v) {return __tree_.__insert_multi(__v);}
......@@ -2070,6 +2108,10 @@ public:
20702108#if _LIBCPP_STD_VER > 17
20712109 _LIBCPP_INLINE_VISIBILITY
20722110 bool contains(const key_type& __k) const {return find(__k) != end();}
2111 template <typename _K2>
2112 _LIBCPP_INLINE_VISIBILITY
2113 typename enable_if<__is_transparent<_Compare, _K2>::value, bool>::type
2114 contains(const _K2& __k) const { return find(__k) != end(); }
20732115#endif // _LIBCPP_STD_VER > 17
20742116
20752117 _LIBCPP_INLINE_VISIBILITY
......@@ -2246,10 +2288,10 @@ inline _LIBCPP_INLINE_VISIBILITY
22462288 typename multimap<_Key, _Tp, _Compare, _Allocator>::size_type
22472289 erase_if(multimap<_Key, _Tp, _Compare, _Allocator>& __c,
22482290 _Predicate __pred) {
2249 return __libcpp_erase_if_container(__c, __pred);
2291 return _VSTD::__libcpp_erase_if_container(__c, __pred);
22502292}
22512293#endif
22522294
22532295_LIBCPP_END_NAMESPACE_STD
22542296
2255#endif // _LIBCPP_MAP
2297#endif // _LIBCPP_MAP
lib/libcxx/include/math.h+278-42
......@@ -318,7 +318,11 @@ _LIBCPP_INLINE_VISIBILITY
318318bool
319319__libcpp_signbit(_A1 __lcpp_x) _NOEXCEPT
320320{
321#if __has_builtin(__builtin_signbit)
322 return __builtin_signbit(__lcpp_x);
323#else
321324 return signbit(__lcpp_x);
325#endif
322326}
323327
324328#undef signbit
......@@ -369,7 +373,7 @@ typename std::enable_if<
369373signbit(_A1) _NOEXCEPT
370374{ return false; }
371375
372#endif // signbit
376#endif // signbit
373377
374378// fpclassify
375379
......@@ -380,7 +384,12 @@ _LIBCPP_INLINE_VISIBILITY
380384int
381385__libcpp_fpclassify(_A1 __lcpp_x) _NOEXCEPT
382386{
387#if __has_builtin(__builtin_fpclassify)
388 return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL,
389 FP_ZERO, __lcpp_x);
390#else
383391 return fpclassify(__lcpp_x);
392#endif
384393}
385394
386395#undef fpclassify
......@@ -415,7 +424,7 @@ typename std::enable_if<std::is_integral<_A1>::value, int>::type
415424fpclassify(_A1 __lcpp_x) _NOEXCEPT
416425{ return __lcpp_x == 0 ? FP_ZERO : FP_NORMAL; }
417426
418#endif // fpclassify
427#endif // fpclassify
419428
420429// isfinite
421430
......@@ -426,7 +435,11 @@ _LIBCPP_INLINE_VISIBILITY
426435bool
427436__libcpp_isfinite(_A1 __lcpp_x) _NOEXCEPT
428437{
438#if __has_builtin(__builtin_isfinite)
439 return __builtin_isfinite(__lcpp_x);
440#else
429441 return isfinite(__lcpp_x);
442#endif
430443}
431444
432445#undef isfinite
......@@ -449,7 +462,7 @@ typename std::enable_if<
449462isfinite(_A1) _NOEXCEPT
450463{ return true; }
451464
452#endif // isfinite
465#endif // isfinite
453466
454467// isinf
455468
......@@ -460,7 +473,11 @@ _LIBCPP_INLINE_VISIBILITY
460473bool
461474__libcpp_isinf(_A1 __lcpp_x) _NOEXCEPT
462475{
476#if __has_builtin(__builtin_isinf)
477 return __builtin_isinf(__lcpp_x);
478#else
463479 return isinf(__lcpp_x);
480#endif
464481}
465482
466483#undef isinf
......@@ -497,7 +514,7 @@ bool
497514isinf(long double __lcpp_x) _NOEXCEPT { return __libcpp_isinf(__lcpp_x); }
498515#endif
499516
500#endif // isinf
517#endif // isinf
501518
502519// isnan
503520
......@@ -545,7 +562,7 @@ bool
545562isnan(long double __lcpp_x) _NOEXCEPT { return __libcpp_isnan(__lcpp_x); }
546563#endif
547564
548#endif // isnan
565#endif // isnan
549566
550567// isnormal
551568
......@@ -556,7 +573,11 @@ _LIBCPP_INLINE_VISIBILITY
556573bool
557574__libcpp_isnormal(_A1 __lcpp_x) _NOEXCEPT
558575{
576#if __has_builtin(__builtin_isnormal)
577 return __builtin_isnormal(__lcpp_x);
578#else
559579 return isnormal(__lcpp_x);
580#endif
560581}
561582
562583#undef isnormal
......@@ -575,7 +596,7 @@ typename std::enable_if<std::is_integral<_A1>::value, bool>::type
575596isnormal(_A1 __lcpp_x) _NOEXCEPT
576597{ return __lcpp_x != 0; }
577598
578#endif // isnormal
599#endif // isnormal
579600
580601// isgreater
581602
......@@ -605,7 +626,7 @@ isgreater(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
605626 return __libcpp_isgreater((type)__lcpp_x, (type)__lcpp_y);
606627}
607628
608#endif // isgreater
629#endif // isgreater
609630
610631// isgreaterequal
611632
......@@ -635,7 +656,7 @@ isgreaterequal(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
635656 return __libcpp_isgreaterequal((type)__lcpp_x, (type)__lcpp_y);
636657}
637658
638#endif // isgreaterequal
659#endif // isgreaterequal
639660
640661// isless
641662
......@@ -665,7 +686,7 @@ isless(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
665686 return __libcpp_isless((type)__lcpp_x, (type)__lcpp_y);
666687}
667688
668#endif // isless
689#endif // isless
669690
670691// islessequal
671692
......@@ -695,7 +716,7 @@ islessequal(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
695716 return __libcpp_islessequal((type)__lcpp_x, (type)__lcpp_y);
696717}
697718
698#endif // islessequal
719#endif // islessequal
699720
700721// islessgreater
701722
......@@ -725,7 +746,7 @@ islessgreater(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
725746 return __libcpp_islessgreater((type)__lcpp_x, (type)__lcpp_y);
726747}
727748
728#endif // islessgreater
749#endif // islessgreater
729750
730751// isunordered
731752
......@@ -755,7 +776,7 @@ isunordered(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
755776 return __libcpp_isunordered((type)__lcpp_x, (type)__lcpp_y);
756777}
757778
758#endif // isunordered
779#endif // isunordered
759780
760781// abs
761782//
......@@ -1099,16 +1120,43 @@ cbrt(_A1 __lcpp_x) _NOEXCEPT {return ::cbrt((double)__lcpp_x);}
10991120
11001121// copysign
11011122
1102inline _LIBCPP_INLINE_VISIBILITY float copysign(float __lcpp_x,
1103 float __lcpp_y) _NOEXCEPT {
1123#if __has_builtin(__builtin_copysignf)
1124_LIBCPP_CONSTEXPR
1125#endif
1126inline _LIBCPP_INLINE_VISIBILITY float __libcpp_copysign(float __lcpp_x, float __lcpp_y) _NOEXCEPT {
1127#if __has_builtin(__builtin_copysignf)
1128 return __builtin_copysignf(__lcpp_x, __lcpp_y);
1129#else
11041130 return ::copysignf(__lcpp_x, __lcpp_y);
1131#endif
1132}
1133
1134#if __has_builtin(__builtin_copysign)
1135_LIBCPP_CONSTEXPR
1136#endif
1137inline _LIBCPP_INLINE_VISIBILITY double __libcpp_copysign(double __lcpp_x, double __lcpp_y) _NOEXCEPT {
1138#if __has_builtin(__builtin_copysign)
1139 return __builtin_copysign(__lcpp_x, __lcpp_y);
1140#else
1141 return ::copysign(__lcpp_x, __lcpp_y);
1142#endif
11051143}
1106inline _LIBCPP_INLINE_VISIBILITY long double
1107copysign(long double __lcpp_x, long double __lcpp_y) _NOEXCEPT {
1144
1145#if __has_builtin(__builtin_copysignl)
1146_LIBCPP_CONSTEXPR
1147#endif
1148inline _LIBCPP_INLINE_VISIBILITY long double __libcpp_copysign(long double __lcpp_x, long double __lcpp_y) _NOEXCEPT {
1149#if __has_builtin(__builtin_copysignl)
1150 return __builtin_copysignl(__lcpp_x, __lcpp_y);
1151#else
11081152 return ::copysignl(__lcpp_x, __lcpp_y);
1153#endif
11091154}
11101155
11111156template <class _A1, class _A2>
1157#if __has_builtin(__builtin_copysign)
1158_LIBCPP_CONSTEXPR
1159#endif
11121160inline _LIBCPP_INLINE_VISIBILITY
11131161typename std::_EnableIf
11141162<
......@@ -1116,12 +1164,35 @@ typename std::_EnableIf
11161164 std::is_arithmetic<_A2>::value,
11171165 std::__promote<_A1, _A2>
11181166>::type
1119copysign(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
1120{
1167__libcpp_copysign(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT {
11211168 typedef typename std::__promote<_A1, _A2>::type __result_type;
11221169 static_assert((!(std::_IsSame<_A1, __result_type>::value &&
11231170 std::_IsSame<_A2, __result_type>::value)), "");
1171#if __has_builtin(__builtin_copysign)
1172 return __builtin_copysign((__result_type)__lcpp_x, (__result_type)__lcpp_y);
1173#else
11241174 return ::copysign((__result_type)__lcpp_x, (__result_type)__lcpp_y);
1175#endif
1176}
1177
1178inline _LIBCPP_INLINE_VISIBILITY float copysign(float __lcpp_x, float __lcpp_y) _NOEXCEPT {
1179 return ::__libcpp_copysign(__lcpp_x, __lcpp_y);
1180}
1181
1182inline _LIBCPP_INLINE_VISIBILITY long double copysign(long double __lcpp_x, long double __lcpp_y) _NOEXCEPT {
1183 return ::__libcpp_copysign(__lcpp_x, __lcpp_y);
1184}
1185
1186template <class _A1, class _A2>
1187inline _LIBCPP_INLINE_VISIBILITY
1188typename std::_EnableIf
1189<
1190 std::is_arithmetic<_A1>::value &&
1191 std::is_arithmetic<_A2>::value,
1192 std::__promote<_A1, _A2>
1193>::type
1194 copysign(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT {
1195 return ::__libcpp_copysign(__lcpp_x, __lcpp_y);
11251196}
11261197
11271198// erf
......@@ -1187,8 +1258,22 @@ fdim(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
11871258
11881259// fma
11891260
1190inline _LIBCPP_INLINE_VISIBILITY float fma(float __lcpp_x, float __lcpp_y, float __lcpp_z) _NOEXCEPT {return ::fmaf(__lcpp_x, __lcpp_y, __lcpp_z);}
1191inline _LIBCPP_INLINE_VISIBILITY long double fma(long double __lcpp_x, long double __lcpp_y, long double __lcpp_z) _NOEXCEPT {return ::fmal(__lcpp_x, __lcpp_y, __lcpp_z);}
1261inline _LIBCPP_INLINE_VISIBILITY float fma(float __lcpp_x, float __lcpp_y, float __lcpp_z) _NOEXCEPT
1262{
1263#if __has_builtin(__builtin_fmaf)
1264 return __builtin_fmaf(__lcpp_x, __lcpp_y, __lcpp_z);
1265#else
1266 return ::fmaf(__lcpp_x, __lcpp_y, __lcpp_z);
1267#endif
1268}
1269inline _LIBCPP_INLINE_VISIBILITY long double fma(long double __lcpp_x, long double __lcpp_y, long double __lcpp_z) _NOEXCEPT
1270{
1271#if __has_builtin(__builtin_fmal)
1272 return __builtin_fmal(__lcpp_x, __lcpp_y, __lcpp_z);
1273#else
1274 return ::fmal(__lcpp_x, __lcpp_y, __lcpp_z);
1275#endif
1276}
11921277
11931278template <class _A1, class _A2, class _A3>
11941279inline _LIBCPP_INLINE_VISIBILITY
......@@ -1205,7 +1290,11 @@ fma(_A1 __lcpp_x, _A2 __lcpp_y, _A3 __lcpp_z) _NOEXCEPT
12051290 static_assert((!(std::_IsSame<_A1, __result_type>::value &&
12061291 std::_IsSame<_A2, __result_type>::value &&
12071292 std::_IsSame<_A3, __result_type>::value)), "");
1293#if __has_builtin(__builtin_fma)
1294 return __builtin_fma((__result_type)__lcpp_x, (__result_type)__lcpp_y, (__result_type)__lcpp_z);
1295#else
12081296 return ::fma((__result_type)__lcpp_x, (__result_type)__lcpp_y, (__result_type)__lcpp_z);
1297#endif
12091298}
12101299
12111300// fmax
......@@ -1293,23 +1382,65 @@ lgamma(_A1 __lcpp_x) _NOEXCEPT {return ::lgamma((double)__lcpp_x);}
12931382
12941383// llrint
12951384
1296inline _LIBCPP_INLINE_VISIBILITY long long llrint(float __lcpp_x) _NOEXCEPT {return ::llrintf(__lcpp_x);}
1297inline _LIBCPP_INLINE_VISIBILITY long long llrint(long double __lcpp_x) _NOEXCEPT {return ::llrintl(__lcpp_x);}
1385inline _LIBCPP_INLINE_VISIBILITY long long llrint(float __lcpp_x) _NOEXCEPT
1386{
1387#if __has_builtin(__builtin_llrintf)
1388 return __builtin_llrintf(__lcpp_x);
1389#else
1390 return ::llrintf(__lcpp_x);
1391#endif
1392}
1393inline _LIBCPP_INLINE_VISIBILITY long long llrint(long double __lcpp_x) _NOEXCEPT
1394{
1395#if __has_builtin(__builtin_llrintl)
1396 return __builtin_llrintl(__lcpp_x);
1397#else
1398 return ::llrintl(__lcpp_x);
1399#endif
1400}
12981401
12991402template <class _A1>
13001403inline _LIBCPP_INLINE_VISIBILITY
13011404typename std::enable_if<std::is_integral<_A1>::value, long long>::type
1302llrint(_A1 __lcpp_x) _NOEXCEPT {return ::llrint((double)__lcpp_x);}
1405llrint(_A1 __lcpp_x) _NOEXCEPT
1406{
1407#if __has_builtin(__builtin_llrint)
1408 return __builtin_llrint((double)__lcpp_x);
1409#else
1410 return ::llrint((double)__lcpp_x);
1411#endif
1412}
13031413
13041414// llround
13051415
1306inline _LIBCPP_INLINE_VISIBILITY long long llround(float __lcpp_x) _NOEXCEPT {return ::llroundf(__lcpp_x);}
1307inline _LIBCPP_INLINE_VISIBILITY long long llround(long double __lcpp_x) _NOEXCEPT {return ::llroundl(__lcpp_x);}
1416inline _LIBCPP_INLINE_VISIBILITY long long llround(float __lcpp_x) _NOEXCEPT
1417{
1418#if __has_builtin(__builtin_llroundf)
1419 return __builtin_llroundf(__lcpp_x);
1420#else
1421 return ::llroundf(__lcpp_x);
1422#endif
1423}
1424inline _LIBCPP_INLINE_VISIBILITY long long llround(long double __lcpp_x) _NOEXCEPT
1425{
1426#if __has_builtin(__builtin_llroundl)
1427 return __builtin_llroundl(__lcpp_x);
1428#else
1429 return ::llroundl(__lcpp_x);
1430#endif
1431}
13081432
13091433template <class _A1>
13101434inline _LIBCPP_INLINE_VISIBILITY
13111435typename std::enable_if<std::is_integral<_A1>::value, long long>::type
1312llround(_A1 __lcpp_x) _NOEXCEPT {return ::llround((double)__lcpp_x);}
1436llround(_A1 __lcpp_x) _NOEXCEPT
1437{
1438#if __has_builtin(__builtin_llround)
1439 return __builtin_llround((double)__lcpp_x);
1440#else
1441 return ::llround((double)__lcpp_x);
1442#endif
1443}
13131444
13141445// log1p
13151446
......@@ -1343,23 +1474,65 @@ logb(_A1 __lcpp_x) _NOEXCEPT {return ::logb((double)__lcpp_x);}
13431474
13441475// lrint
13451476
1346inline _LIBCPP_INLINE_VISIBILITY long lrint(float __lcpp_x) _NOEXCEPT {return ::lrintf(__lcpp_x);}
1347inline _LIBCPP_INLINE_VISIBILITY long lrint(long double __lcpp_x) _NOEXCEPT {return ::lrintl(__lcpp_x);}
1477inline _LIBCPP_INLINE_VISIBILITY long lrint(float __lcpp_x) _NOEXCEPT
1478{
1479#if __has_builtin(__builtin_lrintf)
1480 return __builtin_lrintf(__lcpp_x);
1481#else
1482 return ::lrintf(__lcpp_x);
1483#endif
1484}
1485inline _LIBCPP_INLINE_VISIBILITY long lrint(long double __lcpp_x) _NOEXCEPT
1486{
1487#if __has_builtin(__builtin_lrintl)
1488 return __builtin_lrintl(__lcpp_x);
1489#else
1490 return ::lrintl(__lcpp_x);
1491#endif
1492}
13481493
13491494template <class _A1>
13501495inline _LIBCPP_INLINE_VISIBILITY
13511496typename std::enable_if<std::is_integral<_A1>::value, long>::type
1352lrint(_A1 __lcpp_x) _NOEXCEPT {return ::lrint((double)__lcpp_x);}
1497lrint(_A1 __lcpp_x) _NOEXCEPT
1498{
1499#if __has_builtin(__builtin_lrint)
1500 return __builtin_lrint((double)__lcpp_x);
1501#else
1502 return ::lrint((double)__lcpp_x);
1503#endif
1504}
13531505
13541506// lround
13551507
1356inline _LIBCPP_INLINE_VISIBILITY long lround(float __lcpp_x) _NOEXCEPT {return ::lroundf(__lcpp_x);}
1357inline _LIBCPP_INLINE_VISIBILITY long lround(long double __lcpp_x) _NOEXCEPT {return ::lroundl(__lcpp_x);}
1508inline _LIBCPP_INLINE_VISIBILITY long lround(float __lcpp_x) _NOEXCEPT
1509{
1510#if __has_builtin(__builtin_lroundf)
1511 return __builtin_lroundf(__lcpp_x);
1512#else
1513 return ::lroundf(__lcpp_x);
1514#endif
1515}
1516inline _LIBCPP_INLINE_VISIBILITY long lround(long double __lcpp_x) _NOEXCEPT
1517{
1518#if __has_builtin(__builtin_lroundl)
1519 return __builtin_lroundl(__lcpp_x);
1520#else
1521 return ::lroundl(__lcpp_x);
1522#endif
1523}
13581524
13591525template <class _A1>
13601526inline _LIBCPP_INLINE_VISIBILITY
13611527typename std::enable_if<std::is_integral<_A1>::value, long>::type
1362lround(_A1 __lcpp_x) _NOEXCEPT {return ::lround((double)__lcpp_x);}
1528lround(_A1 __lcpp_x) _NOEXCEPT
1529{
1530#if __has_builtin(__builtin_lround)
1531 return __builtin_lround((double)__lcpp_x);
1532#else
1533 return ::lround((double)__lcpp_x);
1534#endif
1535}
13631536
13641537// nan
13651538
......@@ -1448,23 +1621,65 @@ remquo(_A1 __lcpp_x, _A2 __lcpp_y, int* __lcpp_z) _NOEXCEPT
14481621
14491622// rint
14501623
1451inline _LIBCPP_INLINE_VISIBILITY float rint(float __lcpp_x) _NOEXCEPT {return ::rintf(__lcpp_x);}
1452inline _LIBCPP_INLINE_VISIBILITY long double rint(long double __lcpp_x) _NOEXCEPT {return ::rintl(__lcpp_x);}
1624inline _LIBCPP_INLINE_VISIBILITY float rint(float __lcpp_x) _NOEXCEPT
1625{
1626#if __has_builtin(__builtin_rintf)
1627 return __builtin_rintf(__lcpp_x);
1628#else
1629 return ::rintf(__lcpp_x);
1630#endif
1631}
1632inline _LIBCPP_INLINE_VISIBILITY long double rint(long double __lcpp_x) _NOEXCEPT
1633{
1634#if __has_builtin(__builtin_rintl)
1635 return __builtin_rintl(__lcpp_x);
1636#else
1637 return ::rintl(__lcpp_x);
1638#endif
1639}
14531640
14541641template <class _A1>
14551642inline _LIBCPP_INLINE_VISIBILITY
14561643typename std::enable_if<std::is_integral<_A1>::value, double>::type
1457rint(_A1 __lcpp_x) _NOEXCEPT {return ::rint((double)__lcpp_x);}
1644rint(_A1 __lcpp_x) _NOEXCEPT
1645{
1646#if __has_builtin(__builtin_rint)
1647 return __builtin_rint((double)__lcpp_x);
1648#else
1649 return ::rint((double)__lcpp_x);
1650#endif
1651}
14581652
14591653// round
14601654
1461inline _LIBCPP_INLINE_VISIBILITY float round(float __lcpp_x) _NOEXCEPT {return ::roundf(__lcpp_x);}
1462inline _LIBCPP_INLINE_VISIBILITY long double round(long double __lcpp_x) _NOEXCEPT {return ::roundl(__lcpp_x);}
1655inline _LIBCPP_INLINE_VISIBILITY float round(float __lcpp_x) _NOEXCEPT
1656{
1657#if __has_builtin(__builtin_round)
1658 return __builtin_round(__lcpp_x);
1659#else
1660 return ::round(__lcpp_x);
1661#endif
1662}
1663inline _LIBCPP_INLINE_VISIBILITY long double round(long double __lcpp_x) _NOEXCEPT
1664{
1665#if __has_builtin(__builtin_roundl)
1666 return __builtin_roundl(__lcpp_x);
1667#else
1668 return ::roundl(__lcpp_x);
1669#endif
1670}
14631671
14641672template <class _A1>
14651673inline _LIBCPP_INLINE_VISIBILITY
14661674typename std::enable_if<std::is_integral<_A1>::value, double>::type
1467round(_A1 __lcpp_x) _NOEXCEPT {return ::round((double)__lcpp_x);}
1675round(_A1 __lcpp_x) _NOEXCEPT
1676{
1677#if __has_builtin(__builtin_round)
1678 return __builtin_round((double)__lcpp_x);
1679#else
1680 return ::round((double)__lcpp_x);
1681#endif
1682}
14681683
14691684// scalbln
14701685
......@@ -1498,13 +1713,34 @@ tgamma(_A1 __lcpp_x) _NOEXCEPT {return ::tgamma((double)__lcpp_x);}
14981713
14991714// trunc
15001715
1501inline _LIBCPP_INLINE_VISIBILITY float trunc(float __lcpp_x) _NOEXCEPT {return ::truncf(__lcpp_x);}
1502inline _LIBCPP_INLINE_VISIBILITY long double trunc(long double __lcpp_x) _NOEXCEPT {return ::truncl(__lcpp_x);}
1716inline _LIBCPP_INLINE_VISIBILITY float trunc(float __lcpp_x) _NOEXCEPT
1717{
1718#if __has_builtin(__builtin_trunc)
1719 return __builtin_trunc(__lcpp_x);
1720#else
1721 return ::trunc(__lcpp_x);
1722#endif
1723}
1724inline _LIBCPP_INLINE_VISIBILITY long double trunc(long double __lcpp_x) _NOEXCEPT
1725{
1726#if __has_builtin(__builtin_truncl)
1727 return __builtin_truncl(__lcpp_x);
1728#else
1729 return ::truncl(__lcpp_x);
1730#endif
1731}
15031732
15041733template <class _A1>
15051734inline _LIBCPP_INLINE_VISIBILITY
15061735typename std::enable_if<std::is_integral<_A1>::value, double>::type
1507trunc(_A1 __lcpp_x) _NOEXCEPT {return ::trunc((double)__lcpp_x);}
1736trunc(_A1 __lcpp_x) _NOEXCEPT
1737{
1738#if __has_builtin(__builtin_trunc)
1739 return __builtin_trunc((double)__lcpp_x);
1740#else
1741 return ::trunc((double)__lcpp_x);
1742#endif
1743}
15081744
15091745} // extern "C++"
15101746
......@@ -1524,4 +1760,4 @@ trunc(_A1 __lcpp_x) _NOEXCEPT {return ::trunc((double)__lcpp_x);}
15241760#include_next <math.h>
15251761#endif
15261762
1527#endif // _LIBCPP_MATH_H
1763#endif // _LIBCPP_MATH_H
lib/libcxx/include/memory+75-3400
......@@ -99,7 +99,7 @@ struct allocator_traits
9999};
100100
101101template <>
102class allocator<void> // deprecated in C++17, removed in C++20
102class allocator<void> // removed in C++20
103103{
104104public:
105105 typedef void* pointer;
......@@ -153,14 +153,17 @@ template <class T, class U>
153153bool operator!=(const allocator<T>&, const allocator<U>&) noexcept; // constexpr in C++20
154154
155155template <class OutputIterator, class T>
156class raw_storage_iterator
157 : public iterator<output_iterator_tag,
158 T, // purposefully not C++03
159 ptrdiff_t, // purposefully not C++03
160 T*, // purposefully not C++03
161 raw_storage_iterator&> // purposefully not C++03
156class raw_storage_iterator // deprecated in C++17, removed in C++20
157 : public iterator<output_iterator_tag, void, void, void, void> // until C++17
162158{
163159public:
160 typedef output_iterator_tag iterator_category;
161 typedef void value_type;
162 typedef void difference_type; // until C++20
163 typedef ptrdiff_t difference_type; // since C++20
164 typedef void pointer;
165 typedef void reference;
166
164167 explicit raw_storage_iterator(OutputIterator x);
165168 raw_storage_iterator& operator*();
166169 raw_storage_iterator& operator=(const T& element);
......@@ -651,12 +654,12 @@ template <class T, class Alloc>
651654 inline constexpr bool uses_allocator_v = uses_allocator<T, Alloc>::value;
652655
653656// Pointer safety
654enum class pointer_safety { relaxed, preferred, strict };
655void declare_reachable(void *p);
656template <class T> T *undeclare_reachable(T *p);
657void declare_no_pointers(char *p, size_t n);
658void undeclare_no_pointers(char *p, size_t n);
659pointer_safety get_pointer_safety() noexcept;
657enum class pointer_safety { relaxed, preferred, strict }; // since C++11
658void declare_reachable(void *p); // since C++11
659template <class T> T *undeclare_reachable(T *p); // since C++11
660void declare_no_pointers(char *p, size_t n); // since C++11
661void undeclare_no_pointers(char *p, size_t n); // since C++11
662pointer_safety get_pointer_safety() noexcept; // since C++11
660663
661664void* align(size_t alignment, size_t size, void*& ptr, size_t& space);
662665
......@@ -665,29 +668,40 @@ void* align(size_t alignment, size_t size, void*& ptr, size_t& space);
665668*/
666669
667670#include <__config>
668#include <__availability>
669#include <type_traits>
670#include <typeinfo>
671#include <__functional_base>
672#include <__memory/addressof.h>
673#include <__memory/allocation_guard.h>
674#include <__memory/allocator.h>
675#include <__memory/allocator_arg_t.h>
676#include <__memory/allocator_traits.h>
677#include <__memory/compressed_pair.h>
678#include <__memory/construct_at.h>
679#include <__memory/pointer_safety.h>
680#include <__memory/pointer_traits.h>
681#include <__memory/raw_storage_iterator.h>
682#include <__memory/shared_ptr.h>
683#include <__memory/temporary_buffer.h>
684#include <__memory/uninitialized_algorithms.h>
685#include <__memory/unique_ptr.h>
686#include <__memory/uses_allocator.h>
687#include <compare>
671688#include <cstddef>
672689#include <cstdint>
673#include <new>
674#include <utility>
675#include <limits>
676#include <iterator>
677#include <__functional_base>
690#include <cstring>
678691#include <iosfwd>
679#include <tuple>
692#include <iterator>
693#include <new>
680694#include <stdexcept>
681#include <cstring>
682#include <__memory/allocator_traits.h>
683#include <__memory/base.h>
684#include <__memory/pointer_traits.h>
685#include <__memory/utilities.h>
686#if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER)
687# include <atomic>
688#endif
695#include <tuple>
696#include <type_traits>
697#include <typeinfo>
698#include <utility>
689699#include <version>
690700
701#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
702# include <__memory/auto_ptr.h>
703#endif
704
691705#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
692706#pragma GCC system_header
693707#endif
......@@ -698,286 +712,6 @@ _LIBCPP_PUSH_MACROS
698712
699713_LIBCPP_BEGIN_NAMESPACE_STD
700714
701template <class _ValueType>
702inline _LIBCPP_INLINE_VISIBILITY
703_ValueType __libcpp_relaxed_load(_ValueType const* __value) {
704#if !defined(_LIBCPP_HAS_NO_THREADS) && \
705 defined(__ATOMIC_RELAXED) && \
706 (__has_builtin(__atomic_load_n) || defined(_LIBCPP_COMPILER_GCC))
707 return __atomic_load_n(__value, __ATOMIC_RELAXED);
708#else
709 return *__value;
710#endif
711}
712
713template <class _ValueType>
714inline _LIBCPP_INLINE_VISIBILITY
715_ValueType __libcpp_acquire_load(_ValueType const* __value) {
716#if !defined(_LIBCPP_HAS_NO_THREADS) && \
717 defined(__ATOMIC_ACQUIRE) && \
718 (__has_builtin(__atomic_load_n) || defined(_LIBCPP_COMPILER_GCC))
719 return __atomic_load_n(__value, __ATOMIC_ACQUIRE);
720#else
721 return *__value;
722#endif
723}
724
725template <bool _UsePointerTraits> struct __to_address_helper;
726
727template <> struct __to_address_helper<true> {
728 template <class _Pointer>
729 using __return_type = decltype(pointer_traits<_Pointer>::to_address(_VSTD::declval<const _Pointer&>()));
730
731 template <class _Pointer>
732 _LIBCPP_CONSTEXPR
733 static __return_type<_Pointer>
734 __do_it(const _Pointer &__p) _NOEXCEPT { return pointer_traits<_Pointer>::to_address(__p); }
735};
736
737template <class _Pointer, bool _Dummy = true>
738using __choose_to_address = __to_address_helper<_IsValidExpansion<__to_address_helper<_Dummy>::template __return_type, _Pointer>::value>;
739
740
741template <class _Tp>
742inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
743_Tp*
744__to_address(_Tp* __p) _NOEXCEPT
745{
746 static_assert(!is_function<_Tp>::value, "_Tp is a function type");
747 return __p;
748}
749
750template <class _Pointer>
751inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
752typename __choose_to_address<_Pointer>::template __return_type<_Pointer>
753__to_address(const _Pointer& __p) _NOEXCEPT {
754 return __choose_to_address<_Pointer>::__do_it(__p);
755}
756
757template <> struct __to_address_helper<false> {
758 template <class _Pointer>
759 using __return_type = typename pointer_traits<_Pointer>::element_type*;
760
761 template <class _Pointer>
762 _LIBCPP_CONSTEXPR
763 static __return_type<_Pointer>
764 __do_it(const _Pointer &__p) _NOEXCEPT { return _VSTD::__to_address(__p.operator->()); }
765};
766
767
768#if _LIBCPP_STD_VER > 17
769template <class _Tp>
770inline _LIBCPP_INLINE_VISIBILITY constexpr
771_Tp*
772to_address(_Tp* __p) _NOEXCEPT
773{
774 static_assert(!is_function_v<_Tp>, "_Tp is a function type");
775 return __p;
776}
777
778template <class _Pointer>
779inline _LIBCPP_INLINE_VISIBILITY constexpr
780auto
781to_address(const _Pointer& __p) _NOEXCEPT
782{
783 return _VSTD::__to_address(__p);
784}
785#endif
786
787template <class _Tp> class allocator;
788
789#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS)
790template <>
791class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 allocator<void>
792{
793public:
794 typedef void* pointer;
795 typedef const void* const_pointer;
796 typedef void value_type;
797
798 template <class _Up> struct rebind {typedef allocator<_Up> other;};
799};
800
801template <>
802class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 allocator<const void>
803{
804public:
805 typedef const void* pointer;
806 typedef const void* const_pointer;
807 typedef const void value_type;
808
809 template <class _Up> struct rebind {typedef allocator<_Up> other;};
810};
811#endif
812
813// allocator
814
815template <class _Tp>
816class _LIBCPP_TEMPLATE_VIS allocator
817{
818public:
819 typedef size_t size_type;
820 typedef ptrdiff_t difference_type;
821 typedef _Tp value_type;
822 typedef true_type propagate_on_container_move_assignment;
823 typedef true_type is_always_equal;
824
825 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
826 allocator() _NOEXCEPT { }
827
828 template <class _Up>
829 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
830 allocator(const allocator<_Up>&) _NOEXCEPT { }
831
832 _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
833 _Tp* allocate(size_t __n) {
834 if (__n > allocator_traits<allocator>::max_size(*this))
835 __throw_length_error("allocator<T>::allocate(size_t n)"
836 " 'n' exceeds maximum supported size");
837 if (__libcpp_is_constant_evaluated()) {
838 return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp)));
839 } else {
840 return static_cast<_Tp*>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)));
841 }
842 }
843
844 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
845 void deallocate(_Tp* __p, size_t __n) _NOEXCEPT {
846 if (__libcpp_is_constant_evaluated()) {
847 ::operator delete(__p);
848 } else {
849 _VSTD::__libcpp_deallocate((void*)__p, __n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp));
850 }
851 }
852
853 // C++20 Removed members
854#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS)
855 _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp* pointer;
856 _LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp* const_pointer;
857 _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp& reference;
858 _LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp& const_reference;
859
860 template <class _Up>
861 struct _LIBCPP_DEPRECATED_IN_CXX17 rebind {
862 typedef allocator<_Up> other;
863 };
864
865 _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY
866 pointer address(reference __x) const _NOEXCEPT {
867 return _VSTD::addressof(__x);
868 }
869 _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY
870 const_pointer address(const_reference __x) const _NOEXCEPT {
871 return _VSTD::addressof(__x);
872 }
873
874 _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_IN_CXX17
875 _Tp* allocate(size_t __n, const void*) {
876 return allocate(__n);
877 }
878
879 _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT {
880 return size_type(~0) / sizeof(_Tp);
881 }
882
883 template <class _Up, class... _Args>
884 _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY
885 void construct(_Up* __p, _Args&&... __args) {
886 ::new ((void*)__p) _Up(_VSTD::forward<_Args>(__args)...);
887 }
888
889 _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY
890 void destroy(pointer __p) {
891 __p->~_Tp();
892 }
893#endif
894};
895
896template <class _Tp>
897class _LIBCPP_TEMPLATE_VIS allocator<const _Tp>
898{
899public:
900 typedef size_t size_type;
901 typedef ptrdiff_t difference_type;
902 typedef const _Tp value_type;
903 typedef true_type propagate_on_container_move_assignment;
904 typedef true_type is_always_equal;
905
906 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
907 allocator() _NOEXCEPT { }
908
909 template <class _Up>
910 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
911 allocator(const allocator<_Up>&) _NOEXCEPT { }
912
913 _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
914 const _Tp* allocate(size_t __n) {
915 if (__n > allocator_traits<allocator>::max_size(*this))
916 __throw_length_error("allocator<const T>::allocate(size_t n)"
917 " 'n' exceeds maximum supported size");
918 if (__libcpp_is_constant_evaluated()) {
919 return static_cast<const _Tp*>(::operator new(__n * sizeof(_Tp)));
920 } else {
921 return static_cast<const _Tp*>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)));
922 }
923 }
924
925 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
926 void deallocate(const _Tp* __p, size_t __n) {
927 if (__libcpp_is_constant_evaluated()) {
928 ::operator delete(const_cast<_Tp*>(__p));
929 } else {
930 _VSTD::__libcpp_deallocate((void*) const_cast<_Tp *>(__p), __n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp));
931 }
932 }
933
934 // C++20 Removed members
935#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS)
936 _LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp* pointer;
937 _LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp* const_pointer;
938 _LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp& reference;
939 _LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp& const_reference;
940
941 template <class _Up>
942 struct _LIBCPP_DEPRECATED_IN_CXX17 rebind {
943 typedef allocator<_Up> other;
944 };
945
946 _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY
947 const_pointer address(const_reference __x) const _NOEXCEPT {
948 return _VSTD::addressof(__x);
949 }
950
951 _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_IN_CXX17
952 const _Tp* allocate(size_t __n, const void*) {
953 return allocate(__n);
954 }
955
956 _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT {
957 return size_type(~0) / sizeof(_Tp);
958 }
959
960 template <class _Up, class... _Args>
961 _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY
962 void construct(_Up* __p, _Args&&... __args) {
963 ::new ((void*)__p) _Up(_VSTD::forward<_Args>(__args)...);
964 }
965
966 _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY
967 void destroy(pointer __p) {
968 __p->~_Tp();
969 }
970#endif
971};
972
973template <class _Tp, class _Up>
974inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
975bool operator==(const allocator<_Tp>&, const allocator<_Up>&) _NOEXCEPT {return true;}
976
977template <class _Tp, class _Up>
978inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
979bool operator!=(const allocator<_Tp>&, const allocator<_Up>&) _NOEXCEPT {return false;}
980
981715template <class _Alloc, class _Ptr>
982716_LIBCPP_INLINE_VISIBILITY
983717void __construct_forward_with_exception_guarantees(_Alloc& __a, _Ptr __begin1, _Ptr __end1, _Ptr& __begin2) {
......@@ -1062,3107 +796,48 @@ void __construct_backward_with_exception_guarantees(_Alloc&, _Tp* __begin1, _Tp*
1062796 ptrdiff_t _Np = __end1 - __begin1;
1063797 __end2 -= _Np;
1064798 if (_Np > 0)
1065 _VSTD::memcpy(__end2, __begin1, _Np * sizeof(_Tp));
1066}
1067
1068template <class _OutputIterator, class _Tp>
1069class _LIBCPP_TEMPLATE_VIS raw_storage_iterator
1070 : public iterator<output_iterator_tag,
1071 _Tp, // purposefully not C++03
1072 ptrdiff_t, // purposefully not C++03
1073 _Tp*, // purposefully not C++03
1074 raw_storage_iterator<_OutputIterator, _Tp>&> // purposefully not C++03
1075{
1076private:
1077 _OutputIterator __x_;
1078public:
1079 _LIBCPP_INLINE_VISIBILITY explicit raw_storage_iterator(_OutputIterator __x) : __x_(__x) {}
1080 _LIBCPP_INLINE_VISIBILITY raw_storage_iterator& operator*() {return *this;}
1081 _LIBCPP_INLINE_VISIBILITY raw_storage_iterator& operator=(const _Tp& __element)
1082 {::new ((void*)_VSTD::addressof(*__x_)) _Tp(__element); return *this;}
1083#if _LIBCPP_STD_VER >= 14
1084 _LIBCPP_INLINE_VISIBILITY raw_storage_iterator& operator=(_Tp&& __element)
1085 {::new ((void*)_VSTD::addressof(*__x_)) _Tp(_VSTD::move(__element)); return *this;}
1086#endif
1087 _LIBCPP_INLINE_VISIBILITY raw_storage_iterator& operator++() {++__x_; return *this;}
1088 _LIBCPP_INLINE_VISIBILITY raw_storage_iterator operator++(int)
1089 {raw_storage_iterator __t(*this); ++__x_; return __t;}
1090#if _LIBCPP_STD_VER >= 14
1091 _LIBCPP_INLINE_VISIBILITY _OutputIterator base() const { return __x_; }
1092#endif
1093};
1094
1095template <class _Tp>
1096_LIBCPP_NODISCARD_EXT _LIBCPP_NO_CFI
1097pair<_Tp*, ptrdiff_t>
1098get_temporary_buffer(ptrdiff_t __n) _NOEXCEPT
1099{
1100 pair<_Tp*, ptrdiff_t> __r(0, 0);
1101 const ptrdiff_t __m = (~ptrdiff_t(0) ^
1102 ptrdiff_t(ptrdiff_t(1) << (sizeof(ptrdiff_t) * __CHAR_BIT__ - 1)))
1103 / sizeof(_Tp);
1104 if (__n > __m)
1105 __n = __m;
1106 while (__n > 0)
1107 {
1108#if !defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION)
1109 if (__is_overaligned_for_new(_LIBCPP_ALIGNOF(_Tp)))
1110 {
1111 align_val_t __al =
1112 align_val_t(alignment_of<_Tp>::value);
1113 __r.first = static_cast<_Tp*>(::operator new(
1114 __n * sizeof(_Tp), __al, nothrow));
1115 } else {
1116 __r.first = static_cast<_Tp*>(::operator new(
1117 __n * sizeof(_Tp), nothrow));
1118 }
1119#else
1120 if (__is_overaligned_for_new(_LIBCPP_ALIGNOF(_Tp)))
1121 {
1122 // Since aligned operator new is unavailable, return an empty
1123 // buffer rather than one with invalid alignment.
1124 return __r;
1125 }
1126
1127 __r.first = static_cast<_Tp*>(::operator new(__n * sizeof(_Tp), nothrow));
1128#endif
1129
1130 if (__r.first)
1131 {
1132 __r.second = __n;
1133 break;
1134 }
1135 __n /= 2;
1136 }
1137 return __r;
1138}
1139
1140template <class _Tp>
1141inline _LIBCPP_INLINE_VISIBILITY
1142void return_temporary_buffer(_Tp* __p) _NOEXCEPT
1143{
1144 _VSTD::__libcpp_deallocate_unsized((void*)__p, _LIBCPP_ALIGNOF(_Tp));
799 _VSTD::memcpy(static_cast<void*>(__end2), static_cast<void const*>(__begin1), _Np * sizeof(_Tp));
1145800}
1146801
1147#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
1148template <class _Tp>
1149struct _LIBCPP_DEPRECATED_IN_CXX11 auto_ptr_ref
1150{
1151 _Tp* __ptr_;
1152};
1153
1154template<class _Tp>
1155class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 auto_ptr
1156{
1157private:
1158 _Tp* __ptr_;
1159public:
1160 typedef _Tp element_type;
1161
1162 _LIBCPP_INLINE_VISIBILITY explicit auto_ptr(_Tp* __p = 0) _NOEXCEPT : __ptr_(__p) {}
1163 _LIBCPP_INLINE_VISIBILITY auto_ptr(auto_ptr& __p) _NOEXCEPT : __ptr_(__p.release()) {}
1164 template<class _Up> _LIBCPP_INLINE_VISIBILITY auto_ptr(auto_ptr<_Up>& __p) _NOEXCEPT
1165 : __ptr_(__p.release()) {}
1166 _LIBCPP_INLINE_VISIBILITY auto_ptr& operator=(auto_ptr& __p) _NOEXCEPT
1167 {reset(__p.release()); return *this;}
1168 template<class _Up> _LIBCPP_INLINE_VISIBILITY auto_ptr& operator=(auto_ptr<_Up>& __p) _NOEXCEPT
1169 {reset(__p.release()); return *this;}
1170 _LIBCPP_INLINE_VISIBILITY auto_ptr& operator=(auto_ptr_ref<_Tp> __p) _NOEXCEPT
1171 {reset(__p.__ptr_); return *this;}
1172 _LIBCPP_INLINE_VISIBILITY ~auto_ptr() _NOEXCEPT {delete __ptr_;}
1173
1174 _LIBCPP_INLINE_VISIBILITY _Tp& operator*() const _NOEXCEPT
1175 {return *__ptr_;}
1176 _LIBCPP_INLINE_VISIBILITY _Tp* operator->() const _NOEXCEPT {return __ptr_;}
1177 _LIBCPP_INLINE_VISIBILITY _Tp* get() const _NOEXCEPT {return __ptr_;}
1178 _LIBCPP_INLINE_VISIBILITY _Tp* release() _NOEXCEPT
1179 {
1180 _Tp* __t = __ptr_;
1181 __ptr_ = nullptr;
1182 return __t;
1183 }
1184 _LIBCPP_INLINE_VISIBILITY void reset(_Tp* __p = 0) _NOEXCEPT
1185 {
1186 if (__ptr_ != __p)
1187 delete __ptr_;
1188 __ptr_ = __p;
1189 }
1190
1191 _LIBCPP_INLINE_VISIBILITY auto_ptr(auto_ptr_ref<_Tp> __p) _NOEXCEPT : __ptr_(__p.__ptr_) {}
1192 template<class _Up> _LIBCPP_INLINE_VISIBILITY operator auto_ptr_ref<_Up>() _NOEXCEPT
1193 {auto_ptr_ref<_Up> __t; __t.__ptr_ = release(); return __t;}
1194 template<class _Up> _LIBCPP_INLINE_VISIBILITY operator auto_ptr<_Up>() _NOEXCEPT
1195 {return auto_ptr<_Up>(release());}
1196};
1197
1198template <>
1199class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 auto_ptr<void>
802struct __destruct_n
1200803{
1201public:
1202 typedef void element_type;
1203};
1204#endif
1205
1206// Tag used to default initialize one or both of the pair's elements.
1207struct __default_init_tag {};
1208struct __value_init_tag {};
1209
1210template <class _Tp, int _Idx,
1211 bool _CanBeEmptyBase =
1212 is_empty<_Tp>::value && !__libcpp_is_final<_Tp>::value>
1213struct __compressed_pair_elem {
1214 typedef _Tp _ParamT;
1215 typedef _Tp& reference;
1216 typedef const _Tp& const_reference;
1217
1218 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
1219 __compressed_pair_elem(__default_init_tag) {}
1220 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
1221 __compressed_pair_elem(__value_init_tag) : __value_() {}
1222
1223 template <class _Up, class = typename enable_if<
1224 !is_same<__compressed_pair_elem, typename decay<_Up>::type>::value
1225 >::type>
1226 _LIBCPP_INLINE_VISIBILITY
1227 _LIBCPP_CONSTEXPR explicit
1228 __compressed_pair_elem(_Up&& __u)
1229 : __value_(_VSTD::forward<_Up>(__u))
1230 {
1231 }
1232
1233
1234#ifndef _LIBCPP_CXX03_LANG
1235 template <class... _Args, size_t... _Indexes>
1236 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1237 __compressed_pair_elem(piecewise_construct_t, tuple<_Args...> __args,
1238 __tuple_indices<_Indexes...>)
1239 : __value_(_VSTD::forward<_Args>(_VSTD::get<_Indexes>(__args))...) {}
1240#endif
1241
1242
1243 _LIBCPP_INLINE_VISIBILITY reference __get() _NOEXCEPT { return __value_; }
1244 _LIBCPP_INLINE_VISIBILITY
1245 const_reference __get() const _NOEXCEPT { return __value_; }
1246
1247804private:
1248 _Tp __value_;
1249};
1250
1251template <class _Tp, int _Idx>
1252struct __compressed_pair_elem<_Tp, _Idx, true> : private _Tp {
1253 typedef _Tp _ParamT;
1254 typedef _Tp& reference;
1255 typedef const _Tp& const_reference;
1256 typedef _Tp __value_type;
1257
1258 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR __compressed_pair_elem() = default;
1259 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
1260 __compressed_pair_elem(__default_init_tag) {}
1261 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
1262 __compressed_pair_elem(__value_init_tag) : __value_type() {}
1263
1264 template <class _Up, class = typename enable_if<
1265 !is_same<__compressed_pair_elem, typename decay<_Up>::type>::value
1266 >::type>
1267 _LIBCPP_INLINE_VISIBILITY
1268 _LIBCPP_CONSTEXPR explicit
1269 __compressed_pair_elem(_Up&& __u)
1270 : __value_type(_VSTD::forward<_Up>(__u))
1271 {}
1272
1273#ifndef _LIBCPP_CXX03_LANG
1274 template <class... _Args, size_t... _Indexes>
1275 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1276 __compressed_pair_elem(piecewise_construct_t, tuple<_Args...> __args,
1277 __tuple_indices<_Indexes...>)
1278 : __value_type(_VSTD::forward<_Args>(_VSTD::get<_Indexes>(__args))...) {}
1279#endif
1280
1281 _LIBCPP_INLINE_VISIBILITY reference __get() _NOEXCEPT { return *this; }
1282 _LIBCPP_INLINE_VISIBILITY
1283 const_reference __get() const _NOEXCEPT { return *this; }
1284};
1285
1286template <class _T1, class _T2>
1287class __compressed_pair : private __compressed_pair_elem<_T1, 0>,
1288 private __compressed_pair_elem<_T2, 1> {
1289public:
1290 // NOTE: This static assert should never fire because __compressed_pair
1291 // is *almost never* used in a scenario where it's possible for T1 == T2.
1292 // (The exception is std::function where it is possible that the function
1293 // object and the allocator have the same type).
1294 static_assert((!is_same<_T1, _T2>::value),
1295 "__compressed_pair cannot be instantiated when T1 and T2 are the same type; "
1296 "The current implementation is NOT ABI-compatible with the previous "
1297 "implementation for this configuration");
1298
1299 typedef _LIBCPP_NODEBUG_TYPE __compressed_pair_elem<_T1, 0> _Base1;
1300 typedef _LIBCPP_NODEBUG_TYPE __compressed_pair_elem<_T2, 1> _Base2;
1301
1302 template <bool _Dummy = true,
1303 class = typename enable_if<
1304 __dependent_type<is_default_constructible<_T1>, _Dummy>::value &&
1305 __dependent_type<is_default_constructible<_T2>, _Dummy>::value
1306 >::type
1307 >
1308 _LIBCPP_INLINE_VISIBILITY
1309 _LIBCPP_CONSTEXPR __compressed_pair() : _Base1(__value_init_tag()), _Base2(__value_init_tag()) {}
1310
1311 template <class _U1, class _U2>
1312 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
1313 __compressed_pair(_U1&& __t1, _U2&& __t2)
1314 : _Base1(_VSTD::forward<_U1>(__t1)), _Base2(_VSTD::forward<_U2>(__t2)) {}
1315
1316#ifndef _LIBCPP_CXX03_LANG
1317 template <class... _Args1, class... _Args2>
1318 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1319 __compressed_pair(piecewise_construct_t __pc, tuple<_Args1...> __first_args,
1320 tuple<_Args2...> __second_args)
1321 : _Base1(__pc, _VSTD::move(__first_args),
1322 typename __make_tuple_indices<sizeof...(_Args1)>::type()),
1323 _Base2(__pc, _VSTD::move(__second_args),
1324 typename __make_tuple_indices<sizeof...(_Args2)>::type()) {}
1325#endif
1326
1327 _LIBCPP_INLINE_VISIBILITY
1328 typename _Base1::reference first() _NOEXCEPT {
1329 return static_cast<_Base1&>(*this).__get();
1330 }
1331
1332 _LIBCPP_INLINE_VISIBILITY
1333 typename _Base1::const_reference first() const _NOEXCEPT {
1334 return static_cast<_Base1 const&>(*this).__get();
1335 }
1336
1337 _LIBCPP_INLINE_VISIBILITY
1338 typename _Base2::reference second() _NOEXCEPT {
1339 return static_cast<_Base2&>(*this).__get();
1340 }
1341
1342 _LIBCPP_INLINE_VISIBILITY
1343 typename _Base2::const_reference second() const _NOEXCEPT {
1344 return static_cast<_Base2 const&>(*this).__get();
1345 }
1346
1347 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
1348 static _Base1* __get_first_base(__compressed_pair* __pair) _NOEXCEPT {
1349 return static_cast<_Base1*>(__pair);
1350 }
1351 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
1352 static _Base2* __get_second_base(__compressed_pair* __pair) _NOEXCEPT {
1353 return static_cast<_Base2*>(__pair);
1354 }
1355
1356 _LIBCPP_INLINE_VISIBILITY
1357 void swap(__compressed_pair& __x)
1358 _NOEXCEPT_(__is_nothrow_swappable<_T1>::value &&
1359 __is_nothrow_swappable<_T2>::value)
1360 {
1361 using _VSTD::swap;
1362 swap(first(), __x.first());
1363 swap(second(), __x.second());
1364 }
1365};
1366
1367template <class _T1, class _T2>
1368inline _LIBCPP_INLINE_VISIBILITY
1369void swap(__compressed_pair<_T1, _T2>& __x, __compressed_pair<_T1, _T2>& __y)
1370 _NOEXCEPT_(__is_nothrow_swappable<_T1>::value &&
1371 __is_nothrow_swappable<_T2>::value) {
1372 __x.swap(__y);
1373}
805 size_t __size_;
1374806
1375// default_delete
807 template <class _Tp>
808 _LIBCPP_INLINE_VISIBILITY void __process(_Tp* __p, false_type) _NOEXCEPT
809 {for (size_t __i = 0; __i < __size_; ++__i, ++__p) __p->~_Tp();}
1376810
1377template <class _Tp>
1378struct _LIBCPP_TEMPLATE_VIS default_delete {
1379 static_assert(!is_function<_Tp>::value,
1380 "default_delete cannot be instantiated for function types");
1381#ifndef _LIBCPP_CXX03_LANG
1382 _LIBCPP_INLINE_VISIBILITY constexpr default_delete() _NOEXCEPT = default;
1383#else
1384 _LIBCPP_INLINE_VISIBILITY default_delete() {}
1385#endif
1386 template <class _Up>
1387 _LIBCPP_INLINE_VISIBILITY
1388 default_delete(const default_delete<_Up>&,
1389 typename enable_if<is_convertible<_Up*, _Tp*>::value>::type* =
1390 0) _NOEXCEPT {}
1391
1392 _LIBCPP_INLINE_VISIBILITY void operator()(_Tp* __ptr) const _NOEXCEPT {
1393 static_assert(sizeof(_Tp) > 0,
1394 "default_delete can not delete incomplete type");
1395 static_assert(!is_void<_Tp>::value,
1396 "default_delete can not delete incomplete type");
1397 delete __ptr;
1398 }
1399};
811 template <class _Tp>
812 _LIBCPP_INLINE_VISIBILITY void __process(_Tp*, true_type) _NOEXCEPT
813 {}
1400814
1401template <class _Tp>
1402struct _LIBCPP_TEMPLATE_VIS default_delete<_Tp[]> {
1403private:
1404 template <class _Up>
1405 struct _EnableIfConvertible
1406 : enable_if<is_convertible<_Up(*)[], _Tp(*)[]>::value> {};
815 _LIBCPP_INLINE_VISIBILITY void __incr(false_type) _NOEXCEPT
816 {++__size_;}
817 _LIBCPP_INLINE_VISIBILITY void __incr(true_type) _NOEXCEPT
818 {}
1407819
820 _LIBCPP_INLINE_VISIBILITY void __set(size_t __s, false_type) _NOEXCEPT
821 {__size_ = __s;}
822 _LIBCPP_INLINE_VISIBILITY void __set(size_t, true_type) _NOEXCEPT
823 {}
1408824public:
1409#ifndef _LIBCPP_CXX03_LANG
1410 _LIBCPP_INLINE_VISIBILITY constexpr default_delete() _NOEXCEPT = default;
1411#else
1412 _LIBCPP_INLINE_VISIBILITY default_delete() {}
1413#endif
1414
1415 template <class _Up>
1416 _LIBCPP_INLINE_VISIBILITY
1417 default_delete(const default_delete<_Up[]>&,
1418 typename _EnableIfConvertible<_Up>::type* = 0) _NOEXCEPT {}
1419
1420 template <class _Up>
1421 _LIBCPP_INLINE_VISIBILITY
1422 typename _EnableIfConvertible<_Up>::type
1423 operator()(_Up* __ptr) const _NOEXCEPT {
1424 static_assert(sizeof(_Tp) > 0,
1425 "default_delete can not delete incomplete type");
1426 static_assert(!is_void<_Tp>::value,
1427 "default_delete can not delete void type");
1428 delete[] __ptr;
1429 }
1430};
825 _LIBCPP_INLINE_VISIBILITY explicit __destruct_n(size_t __s) _NOEXCEPT
826 : __size_(__s) {}
1431827
1432template <class _Deleter>
1433struct __unique_ptr_deleter_sfinae {
1434 static_assert(!is_reference<_Deleter>::value, "incorrect specialization");
1435 typedef const _Deleter& __lval_ref_type;
1436 typedef _Deleter&& __good_rval_ref_type;
1437 typedef true_type __enable_rval_overload;
1438};
828 template <class _Tp>
829 _LIBCPP_INLINE_VISIBILITY void __incr() _NOEXCEPT
830 {__incr(integral_constant<bool, is_trivially_destructible<_Tp>::value>());}
1439831
1440template <class _Deleter>
1441struct __unique_ptr_deleter_sfinae<_Deleter const&> {
1442 typedef const _Deleter& __lval_ref_type;
1443 typedef const _Deleter&& __bad_rval_ref_type;
1444 typedef false_type __enable_rval_overload;
1445};
832 template <class _Tp>
833 _LIBCPP_INLINE_VISIBILITY void __set(size_t __s, _Tp*) _NOEXCEPT
834 {__set(__s, integral_constant<bool, is_trivially_destructible<_Tp>::value>());}
1446835
1447template <class _Deleter>
1448struct __unique_ptr_deleter_sfinae<_Deleter&> {
1449 typedef _Deleter& __lval_ref_type;
1450 typedef _Deleter&& __bad_rval_ref_type;
1451 typedef false_type __enable_rval_overload;
836 template <class _Tp>
837 _LIBCPP_INLINE_VISIBILITY void operator()(_Tp* __p) _NOEXCEPT
838 {__process(__p, integral_constant<bool, is_trivially_destructible<_Tp>::value>());}
1452839};
1453840
1454#if defined(_LIBCPP_ABI_ENABLE_UNIQUE_PTR_TRIVIAL_ABI)
1455# define _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI __attribute__((trivial_abi))
1456#else
1457# define _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI
1458#endif
1459
1460template <class _Tp, class _Dp = default_delete<_Tp> >
1461class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr {
1462public:
1463 typedef _Tp element_type;
1464 typedef _Dp deleter_type;
1465 typedef _LIBCPP_NODEBUG_TYPE typename __pointer<_Tp, deleter_type>::type pointer;
1466
1467 static_assert(!is_rvalue_reference<deleter_type>::value,
1468 "the specified deleter type cannot be an rvalue reference");
1469
1470private:
1471 __compressed_pair<pointer, deleter_type> __ptr_;
1472
1473 struct __nat { int __for_bool_; };
1474
1475 typedef _LIBCPP_NODEBUG_TYPE __unique_ptr_deleter_sfinae<_Dp> _DeleterSFINAE;
1476
1477 template <bool _Dummy>
1478 using _LValRefType _LIBCPP_NODEBUG_TYPE =
1479 typename __dependent_type<_DeleterSFINAE, _Dummy>::__lval_ref_type;
1480
1481 template <bool _Dummy>
1482 using _GoodRValRefType _LIBCPP_NODEBUG_TYPE =
1483 typename __dependent_type<_DeleterSFINAE, _Dummy>::__good_rval_ref_type;
1484
1485 template <bool _Dummy>
1486 using _BadRValRefType _LIBCPP_NODEBUG_TYPE =
1487 typename __dependent_type<_DeleterSFINAE, _Dummy>::__bad_rval_ref_type;
1488
1489 template <bool _Dummy, class _Deleter = typename __dependent_type<
1490 __identity<deleter_type>, _Dummy>::type>
1491 using _EnableIfDeleterDefaultConstructible _LIBCPP_NODEBUG_TYPE =
1492 typename enable_if<is_default_constructible<_Deleter>::value &&
1493 !is_pointer<_Deleter>::value>::type;
1494
1495 template <class _ArgType>
1496 using _EnableIfDeleterConstructible _LIBCPP_NODEBUG_TYPE =
1497 typename enable_if<is_constructible<deleter_type, _ArgType>::value>::type;
1498
1499 template <class _UPtr, class _Up>
1500 using _EnableIfMoveConvertible _LIBCPP_NODEBUG_TYPE = typename enable_if<
1501 is_convertible<typename _UPtr::pointer, pointer>::value &&
1502 !is_array<_Up>::value
1503 >::type;
1504
1505 template <class _UDel>
1506 using _EnableIfDeleterConvertible _LIBCPP_NODEBUG_TYPE = typename enable_if<
1507 (is_reference<_Dp>::value && is_same<_Dp, _UDel>::value) ||
1508 (!is_reference<_Dp>::value && is_convertible<_UDel, _Dp>::value)
1509 >::type;
1510
1511 template <class _UDel>
1512 using _EnableIfDeleterAssignable = typename enable_if<
1513 is_assignable<_Dp&, _UDel&&>::value
1514 >::type;
1515
1516public:
1517 template <bool _Dummy = true,
1518 class = _EnableIfDeleterDefaultConstructible<_Dummy> >
1519 _LIBCPP_INLINE_VISIBILITY
1520 _LIBCPP_CONSTEXPR unique_ptr() _NOEXCEPT : __ptr_(pointer(), __default_init_tag()) {}
1521
1522 template <bool _Dummy = true,
1523 class = _EnableIfDeleterDefaultConstructible<_Dummy> >
1524 _LIBCPP_INLINE_VISIBILITY
1525 _LIBCPP_CONSTEXPR unique_ptr(nullptr_t) _NOEXCEPT : __ptr_(pointer(), __default_init_tag()) {}
1526
1527 template <bool _Dummy = true,
1528 class = _EnableIfDeleterDefaultConstructible<_Dummy> >
1529 _LIBCPP_INLINE_VISIBILITY
1530 explicit unique_ptr(pointer __p) _NOEXCEPT : __ptr_(__p, __default_init_tag()) {}
1531
1532 template <bool _Dummy = true,
1533 class = _EnableIfDeleterConstructible<_LValRefType<_Dummy> > >
1534 _LIBCPP_INLINE_VISIBILITY
1535 unique_ptr(pointer __p, _LValRefType<_Dummy> __d) _NOEXCEPT
1536 : __ptr_(__p, __d) {}
1537
1538 template <bool _Dummy = true,
1539 class = _EnableIfDeleterConstructible<_GoodRValRefType<_Dummy> > >
1540 _LIBCPP_INLINE_VISIBILITY
1541 unique_ptr(pointer __p, _GoodRValRefType<_Dummy> __d) _NOEXCEPT
1542 : __ptr_(__p, _VSTD::move(__d)) {
1543 static_assert(!is_reference<deleter_type>::value,
1544 "rvalue deleter bound to reference");
1545 }
1546
1547 template <bool _Dummy = true,
1548 class = _EnableIfDeleterConstructible<_BadRValRefType<_Dummy> > >
1549 _LIBCPP_INLINE_VISIBILITY
1550 unique_ptr(pointer __p, _BadRValRefType<_Dummy> __d) = delete;
1551
1552 _LIBCPP_INLINE_VISIBILITY
1553 unique_ptr(unique_ptr&& __u) _NOEXCEPT
1554 : __ptr_(__u.release(), _VSTD::forward<deleter_type>(__u.get_deleter())) {
1555 }
1556
1557 template <class _Up, class _Ep,
1558 class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>,
1559 class = _EnableIfDeleterConvertible<_Ep>
1560 >
1561 _LIBCPP_INLINE_VISIBILITY
1562 unique_ptr(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT
1563 : __ptr_(__u.release(), _VSTD::forward<_Ep>(__u.get_deleter())) {}
1564
1565#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
1566 template <class _Up>
1567 _LIBCPP_INLINE_VISIBILITY
1568 unique_ptr(auto_ptr<_Up>&& __p,
1569 typename enable_if<is_convertible<_Up*, _Tp*>::value &&
1570 is_same<_Dp, default_delete<_Tp> >::value,
1571 __nat>::type = __nat()) _NOEXCEPT
1572 : __ptr_(__p.release(), __default_init_tag()) {}
1573#endif
1574
1575 _LIBCPP_INLINE_VISIBILITY
1576 unique_ptr& operator=(unique_ptr&& __u) _NOEXCEPT {
1577 reset(__u.release());
1578 __ptr_.second() = _VSTD::forward<deleter_type>(__u.get_deleter());
1579 return *this;
1580 }
1581
1582 template <class _Up, class _Ep,
1583 class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>,
1584 class = _EnableIfDeleterAssignable<_Ep>
1585 >
1586 _LIBCPP_INLINE_VISIBILITY
1587 unique_ptr& operator=(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT {
1588 reset(__u.release());
1589 __ptr_.second() = _VSTD::forward<_Ep>(__u.get_deleter());
1590 return *this;
1591 }
1592
1593#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
1594 template <class _Up>
1595 _LIBCPP_INLINE_VISIBILITY
1596 typename enable_if<is_convertible<_Up*, _Tp*>::value &&
1597 is_same<_Dp, default_delete<_Tp> >::value,
1598 unique_ptr&>::type
1599 operator=(auto_ptr<_Up> __p) {
1600 reset(__p.release());
1601 return *this;
1602 }
1603#endif
1604
1605#ifdef _LIBCPP_CXX03_LANG
1606 unique_ptr(unique_ptr const&) = delete;
1607 unique_ptr& operator=(unique_ptr const&) = delete;
1608#endif
1609
1610
1611 _LIBCPP_INLINE_VISIBILITY
1612 ~unique_ptr() { reset(); }
1613
1614 _LIBCPP_INLINE_VISIBILITY
1615 unique_ptr& operator=(nullptr_t) _NOEXCEPT {
1616 reset();
1617 return *this;
1618 }
1619
1620 _LIBCPP_INLINE_VISIBILITY
1621 typename add_lvalue_reference<_Tp>::type
1622 operator*() const {
1623 return *__ptr_.first();
1624 }
1625 _LIBCPP_INLINE_VISIBILITY
1626 pointer operator->() const _NOEXCEPT {
1627 return __ptr_.first();
1628 }
1629 _LIBCPP_INLINE_VISIBILITY
1630 pointer get() const _NOEXCEPT {
1631 return __ptr_.first();
1632 }
1633 _LIBCPP_INLINE_VISIBILITY
1634 deleter_type& get_deleter() _NOEXCEPT {
1635 return __ptr_.second();
1636 }
1637 _LIBCPP_INLINE_VISIBILITY
1638 const deleter_type& get_deleter() const _NOEXCEPT {
1639 return __ptr_.second();
1640 }
1641 _LIBCPP_INLINE_VISIBILITY
1642 _LIBCPP_EXPLICIT operator bool() const _NOEXCEPT {
1643 return __ptr_.first() != nullptr;
1644 }
1645
1646 _LIBCPP_INLINE_VISIBILITY
1647 pointer release() _NOEXCEPT {
1648 pointer __t = __ptr_.first();
1649 __ptr_.first() = pointer();
1650 return __t;
1651 }
1652
1653 _LIBCPP_INLINE_VISIBILITY
1654 void reset(pointer __p = pointer()) _NOEXCEPT {
1655 pointer __tmp = __ptr_.first();
1656 __ptr_.first() = __p;
1657 if (__tmp)
1658 __ptr_.second()(__tmp);
1659 }
1660
1661 _LIBCPP_INLINE_VISIBILITY
1662 void swap(unique_ptr& __u) _NOEXCEPT {
1663 __ptr_.swap(__u.__ptr_);
1664 }
1665};
1666
1667
1668template <class _Tp, class _Dp>
1669class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr<_Tp[], _Dp> {
1670public:
1671 typedef _Tp element_type;
1672 typedef _Dp deleter_type;
1673 typedef typename __pointer<_Tp, deleter_type>::type pointer;
1674
1675private:
1676 __compressed_pair<pointer, deleter_type> __ptr_;
1677
1678 template <class _From>
1679 struct _CheckArrayPointerConversion : is_same<_From, pointer> {};
1680
1681 template <class _FromElem>
1682 struct _CheckArrayPointerConversion<_FromElem*>
1683 : integral_constant<bool,
1684 is_same<_FromElem*, pointer>::value ||
1685 (is_same<pointer, element_type*>::value &&
1686 is_convertible<_FromElem(*)[], element_type(*)[]>::value)
1687 >
1688 {};
1689
1690 typedef __unique_ptr_deleter_sfinae<_Dp> _DeleterSFINAE;
1691
1692 template <bool _Dummy>
1693 using _LValRefType _LIBCPP_NODEBUG_TYPE =
1694 typename __dependent_type<_DeleterSFINAE, _Dummy>::__lval_ref_type;
1695
1696 template <bool _Dummy>
1697 using _GoodRValRefType _LIBCPP_NODEBUG_TYPE =
1698 typename __dependent_type<_DeleterSFINAE, _Dummy>::__good_rval_ref_type;
1699
1700 template <bool _Dummy>
1701 using _BadRValRefType _LIBCPP_NODEBUG_TYPE =
1702 typename __dependent_type<_DeleterSFINAE, _Dummy>::__bad_rval_ref_type;
1703
1704 template <bool _Dummy, class _Deleter = typename __dependent_type<
1705 __identity<deleter_type>, _Dummy>::type>
1706 using _EnableIfDeleterDefaultConstructible _LIBCPP_NODEBUG_TYPE =
1707 typename enable_if<is_default_constructible<_Deleter>::value &&
1708 !is_pointer<_Deleter>::value>::type;
1709
1710 template <class _ArgType>
1711 using _EnableIfDeleterConstructible _LIBCPP_NODEBUG_TYPE =
1712 typename enable_if<is_constructible<deleter_type, _ArgType>::value>::type;
1713
1714 template <class _Pp>
1715 using _EnableIfPointerConvertible _LIBCPP_NODEBUG_TYPE = typename enable_if<
1716 _CheckArrayPointerConversion<_Pp>::value
1717 >::type;
1718
1719 template <class _UPtr, class _Up,
1720 class _ElemT = typename _UPtr::element_type>
1721 using _EnableIfMoveConvertible _LIBCPP_NODEBUG_TYPE = typename enable_if<
1722 is_array<_Up>::value &&
1723 is_same<pointer, element_type*>::value &&
1724 is_same<typename _UPtr::pointer, _ElemT*>::value &&
1725 is_convertible<_ElemT(*)[], element_type(*)[]>::value
1726 >::type;
1727
1728 template <class _UDel>
1729 using _EnableIfDeleterConvertible _LIBCPP_NODEBUG_TYPE = typename enable_if<
1730 (is_reference<_Dp>::value && is_same<_Dp, _UDel>::value) ||
1731 (!is_reference<_Dp>::value && is_convertible<_UDel, _Dp>::value)
1732 >::type;
1733
1734 template <class _UDel>
1735 using _EnableIfDeleterAssignable _LIBCPP_NODEBUG_TYPE = typename enable_if<
1736 is_assignable<_Dp&, _UDel&&>::value
1737 >::type;
1738
1739public:
1740 template <bool _Dummy = true,
1741 class = _EnableIfDeleterDefaultConstructible<_Dummy> >
1742 _LIBCPP_INLINE_VISIBILITY
1743 _LIBCPP_CONSTEXPR unique_ptr() _NOEXCEPT : __ptr_(pointer(), __default_init_tag()) {}
1744
1745 template <bool _Dummy = true,
1746 class = _EnableIfDeleterDefaultConstructible<_Dummy> >
1747 _LIBCPP_INLINE_VISIBILITY
1748 _LIBCPP_CONSTEXPR unique_ptr(nullptr_t) _NOEXCEPT : __ptr_(pointer(), __default_init_tag()) {}
1749
1750 template <class _Pp, bool _Dummy = true,
1751 class = _EnableIfDeleterDefaultConstructible<_Dummy>,
1752 class = _EnableIfPointerConvertible<_Pp> >
1753 _LIBCPP_INLINE_VISIBILITY
1754 explicit unique_ptr(_Pp __p) _NOEXCEPT
1755 : __ptr_(__p, __default_init_tag()) {}
1756
1757 template <class _Pp, bool _Dummy = true,
1758 class = _EnableIfDeleterConstructible<_LValRefType<_Dummy> >,
1759 class = _EnableIfPointerConvertible<_Pp> >
1760 _LIBCPP_INLINE_VISIBILITY
1761 unique_ptr(_Pp __p, _LValRefType<_Dummy> __d) _NOEXCEPT
1762 : __ptr_(__p, __d) {}
1763
1764 template <bool _Dummy = true,
1765 class = _EnableIfDeleterConstructible<_LValRefType<_Dummy> > >
1766 _LIBCPP_INLINE_VISIBILITY
1767 unique_ptr(nullptr_t, _LValRefType<_Dummy> __d) _NOEXCEPT
1768 : __ptr_(nullptr, __d) {}
1769
1770 template <class _Pp, bool _Dummy = true,
1771 class = _EnableIfDeleterConstructible<_GoodRValRefType<_Dummy> >,
1772 class = _EnableIfPointerConvertible<_Pp> >
1773 _LIBCPP_INLINE_VISIBILITY
1774 unique_ptr(_Pp __p, _GoodRValRefType<_Dummy> __d) _NOEXCEPT
1775 : __ptr_(__p, _VSTD::move(__d)) {
1776 static_assert(!is_reference<deleter_type>::value,
1777 "rvalue deleter bound to reference");
1778 }
1779
1780 template <bool _Dummy = true,
1781 class = _EnableIfDeleterConstructible<_GoodRValRefType<_Dummy> > >
1782 _LIBCPP_INLINE_VISIBILITY
1783 unique_ptr(nullptr_t, _GoodRValRefType<_Dummy> __d) _NOEXCEPT
1784 : __ptr_(nullptr, _VSTD::move(__d)) {
1785 static_assert(!is_reference<deleter_type>::value,
1786 "rvalue deleter bound to reference");
1787 }
1788
1789 template <class _Pp, bool _Dummy = true,
1790 class = _EnableIfDeleterConstructible<_BadRValRefType<_Dummy> >,
1791 class = _EnableIfPointerConvertible<_Pp> >
1792 _LIBCPP_INLINE_VISIBILITY
1793 unique_ptr(_Pp __p, _BadRValRefType<_Dummy> __d) = delete;
1794
1795 _LIBCPP_INLINE_VISIBILITY
1796 unique_ptr(unique_ptr&& __u) _NOEXCEPT
1797 : __ptr_(__u.release(), _VSTD::forward<deleter_type>(__u.get_deleter())) {
1798 }
1799
1800 _LIBCPP_INLINE_VISIBILITY
1801 unique_ptr& operator=(unique_ptr&& __u) _NOEXCEPT {
1802 reset(__u.release());
1803 __ptr_.second() = _VSTD::forward<deleter_type>(__u.get_deleter());
1804 return *this;
1805 }
1806
1807 template <class _Up, class _Ep,
1808 class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>,
1809 class = _EnableIfDeleterConvertible<_Ep>
1810 >
1811 _LIBCPP_INLINE_VISIBILITY
1812 unique_ptr(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT
1813 : __ptr_(__u.release(), _VSTD::forward<_Ep>(__u.get_deleter())) {
1814 }
1815
1816 template <class _Up, class _Ep,
1817 class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>,
1818 class = _EnableIfDeleterAssignable<_Ep>
1819 >
1820 _LIBCPP_INLINE_VISIBILITY
1821 unique_ptr&
1822 operator=(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT {
1823 reset(__u.release());
1824 __ptr_.second() = _VSTD::forward<_Ep>(__u.get_deleter());
1825 return *this;
1826 }
1827
1828#ifdef _LIBCPP_CXX03_LANG
1829 unique_ptr(unique_ptr const&) = delete;
1830 unique_ptr& operator=(unique_ptr const&) = delete;
1831#endif
1832
1833public:
1834 _LIBCPP_INLINE_VISIBILITY
1835 ~unique_ptr() { reset(); }
1836
1837 _LIBCPP_INLINE_VISIBILITY
1838 unique_ptr& operator=(nullptr_t) _NOEXCEPT {
1839 reset();
1840 return *this;
1841 }
1842
1843 _LIBCPP_INLINE_VISIBILITY
1844 typename add_lvalue_reference<_Tp>::type
1845 operator[](size_t __i) const {
1846 return __ptr_.first()[__i];
1847 }
1848 _LIBCPP_INLINE_VISIBILITY
1849 pointer get() const _NOEXCEPT {
1850 return __ptr_.first();
1851 }
1852
1853 _LIBCPP_INLINE_VISIBILITY
1854 deleter_type& get_deleter() _NOEXCEPT {
1855 return __ptr_.second();
1856 }
1857
1858 _LIBCPP_INLINE_VISIBILITY
1859 const deleter_type& get_deleter() const _NOEXCEPT {
1860 return __ptr_.second();
1861 }
1862 _LIBCPP_INLINE_VISIBILITY
1863 _LIBCPP_EXPLICIT operator bool() const _NOEXCEPT {
1864 return __ptr_.first() != nullptr;
1865 }
1866
1867 _LIBCPP_INLINE_VISIBILITY
1868 pointer release() _NOEXCEPT {
1869 pointer __t = __ptr_.first();
1870 __ptr_.first() = pointer();
1871 return __t;
1872 }
1873
1874 template <class _Pp>
1875 _LIBCPP_INLINE_VISIBILITY
1876 typename enable_if<
1877 _CheckArrayPointerConversion<_Pp>::value
1878 >::type
1879 reset(_Pp __p) _NOEXCEPT {
1880 pointer __tmp = __ptr_.first();
1881 __ptr_.first() = __p;
1882 if (__tmp)
1883 __ptr_.second()(__tmp);
1884 }
1885
1886 _LIBCPP_INLINE_VISIBILITY
1887 void reset(nullptr_t = nullptr) _NOEXCEPT {
1888 pointer __tmp = __ptr_.first();
1889 __ptr_.first() = nullptr;
1890 if (__tmp)
1891 __ptr_.second()(__tmp);
1892 }
1893
1894 _LIBCPP_INLINE_VISIBILITY
1895 void swap(unique_ptr& __u) _NOEXCEPT {
1896 __ptr_.swap(__u.__ptr_);
1897 }
1898
1899};
1900
1901template <class _Tp, class _Dp>
1902inline _LIBCPP_INLINE_VISIBILITY
1903typename enable_if<
1904 __is_swappable<_Dp>::value,
1905 void
1906>::type
1907swap(unique_ptr<_Tp, _Dp>& __x, unique_ptr<_Tp, _Dp>& __y) _NOEXCEPT {__x.swap(__y);}
1908
1909template <class _T1, class _D1, class _T2, class _D2>
1910inline _LIBCPP_INLINE_VISIBILITY
1911bool
1912operator==(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return __x.get() == __y.get();}
1913
1914template <class _T1, class _D1, class _T2, class _D2>
1915inline _LIBCPP_INLINE_VISIBILITY
1916bool
1917operator!=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return !(__x == __y);}
1918
1919template <class _T1, class _D1, class _T2, class _D2>
1920inline _LIBCPP_INLINE_VISIBILITY
1921bool
1922operator< (const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y)
1923{
1924 typedef typename unique_ptr<_T1, _D1>::pointer _P1;
1925 typedef typename unique_ptr<_T2, _D2>::pointer _P2;
1926 typedef typename common_type<_P1, _P2>::type _Vp;
1927 return less<_Vp>()(__x.get(), __y.get());
1928}
1929
1930template <class _T1, class _D1, class _T2, class _D2>
1931inline _LIBCPP_INLINE_VISIBILITY
1932bool
1933operator> (const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return __y < __x;}
1934
1935template <class _T1, class _D1, class _T2, class _D2>
1936inline _LIBCPP_INLINE_VISIBILITY
1937bool
1938operator<=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return !(__y < __x);}
1939
1940template <class _T1, class _D1, class _T2, class _D2>
1941inline _LIBCPP_INLINE_VISIBILITY
1942bool
1943operator>=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return !(__x < __y);}
1944
1945template <class _T1, class _D1>
1946inline _LIBCPP_INLINE_VISIBILITY
1947bool
1948operator==(const unique_ptr<_T1, _D1>& __x, nullptr_t) _NOEXCEPT
1949{
1950 return !__x;
1951}
1952
1953template <class _T1, class _D1>
1954inline _LIBCPP_INLINE_VISIBILITY
1955bool
1956operator==(nullptr_t, const unique_ptr<_T1, _D1>& __x) _NOEXCEPT
1957{
1958 return !__x;
1959}
1960
1961template <class _T1, class _D1>
1962inline _LIBCPP_INLINE_VISIBILITY
1963bool
1964operator!=(const unique_ptr<_T1, _D1>& __x, nullptr_t) _NOEXCEPT
1965{
1966 return static_cast<bool>(__x);
1967}
1968
1969template <class _T1, class _D1>
1970inline _LIBCPP_INLINE_VISIBILITY
1971bool
1972operator!=(nullptr_t, const unique_ptr<_T1, _D1>& __x) _NOEXCEPT
1973{
1974 return static_cast<bool>(__x);
1975}
1976
1977template <class _T1, class _D1>
1978inline _LIBCPP_INLINE_VISIBILITY
1979bool
1980operator<(const unique_ptr<_T1, _D1>& __x, nullptr_t)
1981{
1982 typedef typename unique_ptr<_T1, _D1>::pointer _P1;
1983 return less<_P1>()(__x.get(), nullptr);
1984}
1985
1986template <class _T1, class _D1>
1987inline _LIBCPP_INLINE_VISIBILITY
1988bool
1989operator<(nullptr_t, const unique_ptr<_T1, _D1>& __x)
1990{
1991 typedef typename unique_ptr<_T1, _D1>::pointer _P1;
1992 return less<_P1>()(nullptr, __x.get());
1993}
1994
1995template <class _T1, class _D1>
1996inline _LIBCPP_INLINE_VISIBILITY
1997bool
1998operator>(const unique_ptr<_T1, _D1>& __x, nullptr_t)
1999{
2000 return nullptr < __x;
2001}
2002
2003template <class _T1, class _D1>
2004inline _LIBCPP_INLINE_VISIBILITY
2005bool
2006operator>(nullptr_t, const unique_ptr<_T1, _D1>& __x)
2007{
2008 return __x < nullptr;
2009}
2010
2011template <class _T1, class _D1>
2012inline _LIBCPP_INLINE_VISIBILITY
2013bool
2014operator<=(const unique_ptr<_T1, _D1>& __x, nullptr_t)
2015{
2016 return !(nullptr < __x);
2017}
2018
2019template <class _T1, class _D1>
2020inline _LIBCPP_INLINE_VISIBILITY
2021bool
2022operator<=(nullptr_t, const unique_ptr<_T1, _D1>& __x)
2023{
2024 return !(__x < nullptr);
2025}
2026
2027template <class _T1, class _D1>
2028inline _LIBCPP_INLINE_VISIBILITY
2029bool
2030operator>=(const unique_ptr<_T1, _D1>& __x, nullptr_t)
2031{
2032 return !(__x < nullptr);
2033}
2034
2035template <class _T1, class _D1>
2036inline _LIBCPP_INLINE_VISIBILITY
2037bool
2038operator>=(nullptr_t, const unique_ptr<_T1, _D1>& __x)
2039{
2040 return !(nullptr < __x);
2041}
2042
2043#if _LIBCPP_STD_VER > 11
2044
2045template<class _Tp>
2046struct __unique_if
2047{
2048 typedef unique_ptr<_Tp> __unique_single;
2049};
2050
2051template<class _Tp>
2052struct __unique_if<_Tp[]>
2053{
2054 typedef unique_ptr<_Tp[]> __unique_array_unknown_bound;
2055};
2056
2057template<class _Tp, size_t _Np>
2058struct __unique_if<_Tp[_Np]>
2059{
2060 typedef void __unique_array_known_bound;
2061};
2062
2063template<class _Tp, class... _Args>
2064inline _LIBCPP_INLINE_VISIBILITY
2065typename __unique_if<_Tp>::__unique_single
2066make_unique(_Args&&... __args)
2067{
2068 return unique_ptr<_Tp>(new _Tp(_VSTD::forward<_Args>(__args)...));
2069}
2070
2071template<class _Tp>
2072inline _LIBCPP_INLINE_VISIBILITY
2073typename __unique_if<_Tp>::__unique_array_unknown_bound
2074make_unique(size_t __n)
2075{
2076 typedef typename remove_extent<_Tp>::type _Up;
2077 return unique_ptr<_Tp>(new _Up[__n]());
2078}
2079
2080template<class _Tp, class... _Args>
2081 typename __unique_if<_Tp>::__unique_array_known_bound
2082 make_unique(_Args&&...) = delete;
2083
2084#endif // _LIBCPP_STD_VER > 11
2085
2086template <class _Tp, class _Dp>
2087#ifdef _LIBCPP_CXX03_LANG
2088struct _LIBCPP_TEMPLATE_VIS hash<unique_ptr<_Tp, _Dp> >
2089#else
2090struct _LIBCPP_TEMPLATE_VIS hash<__enable_hash_helper<
2091 unique_ptr<_Tp, _Dp>, typename unique_ptr<_Tp, _Dp>::pointer> >
2092#endif
2093{
2094 typedef unique_ptr<_Tp, _Dp> argument_type;
2095 typedef size_t result_type;
2096 _LIBCPP_INLINE_VISIBILITY
2097 result_type operator()(const argument_type& __ptr) const
2098 {
2099 typedef typename argument_type::pointer pointer;
2100 return hash<pointer>()(__ptr.get());
2101 }
2102};
2103
2104struct __destruct_n
2105{
2106private:
2107 size_t __size_;
2108
2109 template <class _Tp>
2110 _LIBCPP_INLINE_VISIBILITY void __process(_Tp* __p, false_type) _NOEXCEPT
2111 {for (size_t __i = 0; __i < __size_; ++__i, ++__p) __p->~_Tp();}
2112
2113 template <class _Tp>
2114 _LIBCPP_INLINE_VISIBILITY void __process(_Tp*, true_type) _NOEXCEPT
2115 {}
2116
2117 _LIBCPP_INLINE_VISIBILITY void __incr(false_type) _NOEXCEPT
2118 {++__size_;}
2119 _LIBCPP_INLINE_VISIBILITY void __incr(true_type) _NOEXCEPT
2120 {}
2121
2122 _LIBCPP_INLINE_VISIBILITY void __set(size_t __s, false_type) _NOEXCEPT
2123 {__size_ = __s;}
2124 _LIBCPP_INLINE_VISIBILITY void __set(size_t, true_type) _NOEXCEPT
2125 {}
2126public:
2127 _LIBCPP_INLINE_VISIBILITY explicit __destruct_n(size_t __s) _NOEXCEPT
2128 : __size_(__s) {}
2129
2130 template <class _Tp>
2131 _LIBCPP_INLINE_VISIBILITY void __incr() _NOEXCEPT
2132 {__incr(integral_constant<bool, is_trivially_destructible<_Tp>::value>());}
2133
2134 template <class _Tp>
2135 _LIBCPP_INLINE_VISIBILITY void __set(size_t __s, _Tp*) _NOEXCEPT
2136 {__set(__s, integral_constant<bool, is_trivially_destructible<_Tp>::value>());}
2137
2138 template <class _Tp>
2139 _LIBCPP_INLINE_VISIBILITY void operator()(_Tp* __p) _NOEXCEPT
2140 {__process(__p, integral_constant<bool, is_trivially_destructible<_Tp>::value>());}
2141};
2142
2143template <class _Alloc>
2144class __allocator_destructor
2145{
2146 typedef _LIBCPP_NODEBUG_TYPE allocator_traits<_Alloc> __alloc_traits;
2147public:
2148 typedef _LIBCPP_NODEBUG_TYPE typename __alloc_traits::pointer pointer;
2149 typedef _LIBCPP_NODEBUG_TYPE typename __alloc_traits::size_type size_type;
2150private:
2151 _Alloc& __alloc_;
2152 size_type __s_;
2153public:
2154 _LIBCPP_INLINE_VISIBILITY __allocator_destructor(_Alloc& __a, size_type __s)
2155 _NOEXCEPT
2156 : __alloc_(__a), __s_(__s) {}
2157 _LIBCPP_INLINE_VISIBILITY
2158 void operator()(pointer __p) _NOEXCEPT
2159 {__alloc_traits::deallocate(__alloc_, __p, __s_);}
2160};
2161
2162template <class _InputIterator, class _ForwardIterator>
2163_ForwardIterator
2164uninitialized_copy(_InputIterator __f, _InputIterator __l, _ForwardIterator __r)
2165{
2166 typedef typename iterator_traits<_ForwardIterator>::value_type value_type;
2167#ifndef _LIBCPP_NO_EXCEPTIONS
2168 _ForwardIterator __s = __r;
2169 try
2170 {
2171#endif
2172 for (; __f != __l; ++__f, (void) ++__r)
2173 ::new ((void*)_VSTD::addressof(*__r)) value_type(*__f);
2174#ifndef _LIBCPP_NO_EXCEPTIONS
2175 }
2176 catch (...)
2177 {
2178 for (; __s != __r; ++__s)
2179 __s->~value_type();
2180 throw;
2181 }
2182#endif
2183 return __r;
2184}
2185
2186template <class _InputIterator, class _Size, class _ForwardIterator>
2187_ForwardIterator
2188uninitialized_copy_n(_InputIterator __f, _Size __n, _ForwardIterator __r)
2189{
2190 typedef typename iterator_traits<_ForwardIterator>::value_type value_type;
2191#ifndef _LIBCPP_NO_EXCEPTIONS
2192 _ForwardIterator __s = __r;
2193 try
2194 {
2195#endif
2196 for (; __n > 0; ++__f, (void) ++__r, (void) --__n)
2197 ::new ((void*)_VSTD::addressof(*__r)) value_type(*__f);
2198#ifndef _LIBCPP_NO_EXCEPTIONS
2199 }
2200 catch (...)
2201 {
2202 for (; __s != __r; ++__s)
2203 __s->~value_type();
2204 throw;
2205 }
2206#endif
2207 return __r;
2208}
2209
2210template <class _ForwardIterator, class _Tp>
2211void
2212uninitialized_fill(_ForwardIterator __f, _ForwardIterator __l, const _Tp& __x)
2213{
2214 typedef typename iterator_traits<_ForwardIterator>::value_type value_type;
2215#ifndef _LIBCPP_NO_EXCEPTIONS
2216 _ForwardIterator __s = __f;
2217 try
2218 {
2219#endif
2220 for (; __f != __l; ++__f)
2221 ::new ((void*)_VSTD::addressof(*__f)) value_type(__x);
2222#ifndef _LIBCPP_NO_EXCEPTIONS
2223 }
2224 catch (...)
2225 {
2226 for (; __s != __f; ++__s)
2227 __s->~value_type();
2228 throw;
2229 }
2230#endif
2231}
2232
2233template <class _ForwardIterator, class _Size, class _Tp>
2234_ForwardIterator
2235uninitialized_fill_n(_ForwardIterator __f, _Size __n, const _Tp& __x)
2236{
2237 typedef typename iterator_traits<_ForwardIterator>::value_type value_type;
2238#ifndef _LIBCPP_NO_EXCEPTIONS
2239 _ForwardIterator __s = __f;
2240 try
2241 {
2242#endif
2243 for (; __n > 0; ++__f, (void) --__n)
2244 ::new ((void*)_VSTD::addressof(*__f)) value_type(__x);
2245#ifndef _LIBCPP_NO_EXCEPTIONS
2246 }
2247 catch (...)
2248 {
2249 for (; __s != __f; ++__s)
2250 __s->~value_type();
2251 throw;
2252 }
2253#endif
2254 return __f;
2255}
2256
2257#if _LIBCPP_STD_VER > 14
2258
2259template <class _ForwardIterator>
2260inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
2261void destroy(_ForwardIterator __first, _ForwardIterator __last) {
2262 for (; __first != __last; ++__first)
2263 _VSTD::destroy_at(_VSTD::addressof(*__first));
2264}
2265
2266template <class _ForwardIterator, class _Size>
2267inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
2268_ForwardIterator destroy_n(_ForwardIterator __first, _Size __n) {
2269 for (; __n > 0; (void)++__first, --__n)
2270 _VSTD::destroy_at(_VSTD::addressof(*__first));
2271 return __first;
2272}
2273
2274template <class _ForwardIterator>
2275inline _LIBCPP_INLINE_VISIBILITY
2276void uninitialized_default_construct(_ForwardIterator __first, _ForwardIterator __last) {
2277 using _Vt = typename iterator_traits<_ForwardIterator>::value_type;
2278 auto __idx = __first;
2279#ifndef _LIBCPP_NO_EXCEPTIONS
2280 try {
2281#endif
2282 for (; __idx != __last; ++__idx)
2283 ::new ((void*)_VSTD::addressof(*__idx)) _Vt;
2284#ifndef _LIBCPP_NO_EXCEPTIONS
2285 } catch (...) {
2286 _VSTD::destroy(__first, __idx);
2287 throw;
2288 }
2289#endif
2290}
2291
2292template <class _ForwardIterator, class _Size>
2293inline _LIBCPP_INLINE_VISIBILITY
2294_ForwardIterator uninitialized_default_construct_n(_ForwardIterator __first, _Size __n) {
2295 using _Vt = typename iterator_traits<_ForwardIterator>::value_type;
2296 auto __idx = __first;
2297#ifndef _LIBCPP_NO_EXCEPTIONS
2298 try {
2299#endif
2300 for (; __n > 0; (void)++__idx, --__n)
2301 ::new ((void*)_VSTD::addressof(*__idx)) _Vt;
2302 return __idx;
2303#ifndef _LIBCPP_NO_EXCEPTIONS
2304 } catch (...) {
2305 _VSTD::destroy(__first, __idx);
2306 throw;
2307 }
2308#endif
2309}
2310
2311
2312template <class _ForwardIterator>
2313inline _LIBCPP_INLINE_VISIBILITY
2314void uninitialized_value_construct(_ForwardIterator __first, _ForwardIterator __last) {
2315 using _Vt = typename iterator_traits<_ForwardIterator>::value_type;
2316 auto __idx = __first;
2317#ifndef _LIBCPP_NO_EXCEPTIONS
2318 try {
2319#endif
2320 for (; __idx != __last; ++__idx)
2321 ::new ((void*)_VSTD::addressof(*__idx)) _Vt();
2322#ifndef _LIBCPP_NO_EXCEPTIONS
2323 } catch (...) {
2324 _VSTD::destroy(__first, __idx);
2325 throw;
2326 }
2327#endif
2328}
2329
2330template <class _ForwardIterator, class _Size>
2331inline _LIBCPP_INLINE_VISIBILITY
2332_ForwardIterator uninitialized_value_construct_n(_ForwardIterator __first, _Size __n) {
2333 using _Vt = typename iterator_traits<_ForwardIterator>::value_type;
2334 auto __idx = __first;
2335#ifndef _LIBCPP_NO_EXCEPTIONS
2336 try {
2337#endif
2338 for (; __n > 0; (void)++__idx, --__n)
2339 ::new ((void*)_VSTD::addressof(*__idx)) _Vt();
2340 return __idx;
2341#ifndef _LIBCPP_NO_EXCEPTIONS
2342 } catch (...) {
2343 _VSTD::destroy(__first, __idx);
2344 throw;
2345 }
2346#endif
2347}
2348
2349
2350template <class _InputIt, class _ForwardIt>
2351inline _LIBCPP_INLINE_VISIBILITY
2352_ForwardIt uninitialized_move(_InputIt __first, _InputIt __last, _ForwardIt __first_res) {
2353 using _Vt = typename iterator_traits<_ForwardIt>::value_type;
2354 auto __idx = __first_res;
2355#ifndef _LIBCPP_NO_EXCEPTIONS
2356 try {
2357#endif
2358 for (; __first != __last; (void)++__idx, ++__first)
2359 ::new ((void*)_VSTD::addressof(*__idx)) _Vt(_VSTD::move(*__first));
2360 return __idx;
2361#ifndef _LIBCPP_NO_EXCEPTIONS
2362 } catch (...) {
2363 _VSTD::destroy(__first_res, __idx);
2364 throw;
2365 }
2366#endif
2367}
2368
2369template <class _InputIt, class _Size, class _ForwardIt>
2370inline _LIBCPP_INLINE_VISIBILITY
2371pair<_InputIt, _ForwardIt>
2372uninitialized_move_n(_InputIt __first, _Size __n, _ForwardIt __first_res) {
2373 using _Vt = typename iterator_traits<_ForwardIt>::value_type;
2374 auto __idx = __first_res;
2375#ifndef _LIBCPP_NO_EXCEPTIONS
2376 try {
2377#endif
2378 for (; __n > 0; ++__idx, (void)++__first, --__n)
2379 ::new ((void*)_VSTD::addressof(*__idx)) _Vt(_VSTD::move(*__first));
2380 return {__first, __idx};
2381#ifndef _LIBCPP_NO_EXCEPTIONS
2382 } catch (...) {
2383 _VSTD::destroy(__first_res, __idx);
2384 throw;
2385 }
2386#endif
2387}
2388
2389
2390#endif // _LIBCPP_STD_VER > 14
2391
2392// NOTE: Relaxed and acq/rel atomics (for increment and decrement respectively)
2393// should be sufficient for thread safety.
2394// See https://bugs.llvm.org/show_bug.cgi?id=22803
2395#if defined(__clang__) && __has_builtin(__atomic_add_fetch) \
2396 && defined(__ATOMIC_RELAXED) \
2397 && defined(__ATOMIC_ACQ_REL)
2398# define _LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT
2399#elif defined(_LIBCPP_COMPILER_GCC)
2400# define _LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT
2401#endif
2402
2403template <class _Tp>
2404inline _LIBCPP_INLINE_VISIBILITY _Tp
2405__libcpp_atomic_refcount_increment(_Tp& __t) _NOEXCEPT
2406{
2407#if defined(_LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT) && !defined(_LIBCPP_HAS_NO_THREADS)
2408 return __atomic_add_fetch(&__t, 1, __ATOMIC_RELAXED);
2409#else
2410 return __t += 1;
2411#endif
2412}
2413
2414template <class _Tp>
2415inline _LIBCPP_INLINE_VISIBILITY _Tp
2416__libcpp_atomic_refcount_decrement(_Tp& __t) _NOEXCEPT
2417{
2418#if defined(_LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT) && !defined(_LIBCPP_HAS_NO_THREADS)
2419 return __atomic_add_fetch(&__t, -1, __ATOMIC_ACQ_REL);
2420#else
2421 return __t -= 1;
2422#endif
2423}
2424
2425class _LIBCPP_EXCEPTION_ABI bad_weak_ptr
2426 : public std::exception
2427{
2428public:
2429 bad_weak_ptr() _NOEXCEPT = default;
2430 bad_weak_ptr(const bad_weak_ptr&) _NOEXCEPT = default;
2431 virtual ~bad_weak_ptr() _NOEXCEPT;
2432 virtual const char* what() const _NOEXCEPT;
2433};
2434
2435_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
2436void __throw_bad_weak_ptr()
2437{
2438#ifndef _LIBCPP_NO_EXCEPTIONS
2439 throw bad_weak_ptr();
2440#else
2441 _VSTD::abort();
2442#endif
2443}
2444
2445template<class _Tp> class _LIBCPP_TEMPLATE_VIS weak_ptr;
2446
2447class _LIBCPP_TYPE_VIS __shared_count
2448{
2449 __shared_count(const __shared_count&);
2450 __shared_count& operator=(const __shared_count&);
2451
2452protected:
2453 long __shared_owners_;
2454 virtual ~__shared_count();
2455private:
2456 virtual void __on_zero_shared() _NOEXCEPT = 0;
2457
2458public:
2459 _LIBCPP_INLINE_VISIBILITY
2460 explicit __shared_count(long __refs = 0) _NOEXCEPT
2461 : __shared_owners_(__refs) {}
2462
2463#if defined(_LIBCPP_BUILDING_LIBRARY) && \
2464 defined(_LIBCPP_DEPRECATED_ABI_LEGACY_LIBRARY_DEFINITIONS_FOR_INLINE_FUNCTIONS)
2465 void __add_shared() _NOEXCEPT;
2466 bool __release_shared() _NOEXCEPT;
2467#else
2468 _LIBCPP_INLINE_VISIBILITY
2469 void __add_shared() _NOEXCEPT {
2470 __libcpp_atomic_refcount_increment(__shared_owners_);
2471 }
2472 _LIBCPP_INLINE_VISIBILITY
2473 bool __release_shared() _NOEXCEPT {
2474 if (__libcpp_atomic_refcount_decrement(__shared_owners_) == -1) {
2475 __on_zero_shared();
2476 return true;
2477 }
2478 return false;
2479 }
2480#endif
2481 _LIBCPP_INLINE_VISIBILITY
2482 long use_count() const _NOEXCEPT {
2483 return __libcpp_relaxed_load(&__shared_owners_) + 1;
2484 }
2485};
2486
2487class _LIBCPP_TYPE_VIS __shared_weak_count
2488 : private __shared_count
2489{
2490 long __shared_weak_owners_;
2491
2492public:
2493 _LIBCPP_INLINE_VISIBILITY
2494 explicit __shared_weak_count(long __refs = 0) _NOEXCEPT
2495 : __shared_count(__refs),
2496 __shared_weak_owners_(__refs) {}
2497protected:
2498 virtual ~__shared_weak_count();
2499
2500public:
2501#if defined(_LIBCPP_BUILDING_LIBRARY) && \
2502 defined(_LIBCPP_DEPRECATED_ABI_LEGACY_LIBRARY_DEFINITIONS_FOR_INLINE_FUNCTIONS)
2503 void __add_shared() _NOEXCEPT;
2504 void __add_weak() _NOEXCEPT;
2505 void __release_shared() _NOEXCEPT;
2506#else
2507 _LIBCPP_INLINE_VISIBILITY
2508 void __add_shared() _NOEXCEPT {
2509 __shared_count::__add_shared();
2510 }
2511 _LIBCPP_INLINE_VISIBILITY
2512 void __add_weak() _NOEXCEPT {
2513 __libcpp_atomic_refcount_increment(__shared_weak_owners_);
2514 }
2515 _LIBCPP_INLINE_VISIBILITY
2516 void __release_shared() _NOEXCEPT {
2517 if (__shared_count::__release_shared())
2518 __release_weak();
2519 }
2520#endif
2521 void __release_weak() _NOEXCEPT;
2522 _LIBCPP_INLINE_VISIBILITY
2523 long use_count() const _NOEXCEPT {return __shared_count::use_count();}
2524 __shared_weak_count* lock() _NOEXCEPT;
2525
2526 virtual const void* __get_deleter(const type_info&) const _NOEXCEPT;
2527private:
2528 virtual void __on_zero_shared_weak() _NOEXCEPT = 0;
2529};
2530
2531template <class _Tp, class _Dp, class _Alloc>
2532class __shared_ptr_pointer
2533 : public __shared_weak_count
2534{
2535 __compressed_pair<__compressed_pair<_Tp, _Dp>, _Alloc> __data_;
2536public:
2537 _LIBCPP_INLINE_VISIBILITY
2538 __shared_ptr_pointer(_Tp __p, _Dp __d, _Alloc __a)
2539 : __data_(__compressed_pair<_Tp, _Dp>(__p, _VSTD::move(__d)), _VSTD::move(__a)) {}
2540
2541#ifndef _LIBCPP_NO_RTTI
2542 virtual const void* __get_deleter(const type_info&) const _NOEXCEPT;
2543#endif
2544
2545private:
2546 virtual void __on_zero_shared() _NOEXCEPT;
2547 virtual void __on_zero_shared_weak() _NOEXCEPT;
2548};
2549
2550#ifndef _LIBCPP_NO_RTTI
2551
2552template <class _Tp, class _Dp, class _Alloc>
2553const void*
2554__shared_ptr_pointer<_Tp, _Dp, _Alloc>::__get_deleter(const type_info& __t) const _NOEXCEPT
2555{
2556 return __t == typeid(_Dp) ? _VSTD::addressof(__data_.first().second()) : nullptr;
2557}
2558
2559#endif // _LIBCPP_NO_RTTI
2560
2561template <class _Tp, class _Dp, class _Alloc>
2562void
2563__shared_ptr_pointer<_Tp, _Dp, _Alloc>::__on_zero_shared() _NOEXCEPT
2564{
2565 __data_.first().second()(__data_.first().first());
2566 __data_.first().second().~_Dp();
2567}
2568
2569template <class _Tp, class _Dp, class _Alloc>
2570void
2571__shared_ptr_pointer<_Tp, _Dp, _Alloc>::__on_zero_shared_weak() _NOEXCEPT
2572{
2573 typedef typename __allocator_traits_rebind<_Alloc, __shared_ptr_pointer>::type _Al;
2574 typedef allocator_traits<_Al> _ATraits;
2575 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
2576
2577 _Al __a(__data_.second());
2578 __data_.second().~_Alloc();
2579 __a.deallocate(_PTraits::pointer_to(*this), 1);
2580}
2581
2582template <class _Tp, class _Alloc>
2583struct __shared_ptr_emplace
2584 : __shared_weak_count
2585{
2586 template<class ..._Args>
2587 _LIBCPP_HIDE_FROM_ABI
2588 explicit __shared_ptr_emplace(_Alloc __a, _Args&& ...__args)
2589 : __storage_(_VSTD::move(__a))
2590 {
2591#if _LIBCPP_STD_VER > 17
2592 using _TpAlloc = typename __allocator_traits_rebind<_Alloc, _Tp>::type;
2593 _TpAlloc __tmp(*__get_alloc());
2594 allocator_traits<_TpAlloc>::construct(__tmp, __get_elem(), _VSTD::forward<_Args>(__args)...);
2595#else
2596 ::new ((void*)__get_elem()) _Tp(_VSTD::forward<_Args>(__args)...);
2597#endif
2598 }
2599
2600 _LIBCPP_HIDE_FROM_ABI
2601 _Alloc* __get_alloc() _NOEXCEPT { return __storage_.__get_alloc(); }
2602
2603 _LIBCPP_HIDE_FROM_ABI
2604 _Tp* __get_elem() _NOEXCEPT { return __storage_.__get_elem(); }
2605
2606private:
2607 virtual void __on_zero_shared() _NOEXCEPT {
2608#if _LIBCPP_STD_VER > 17
2609 using _TpAlloc = typename __allocator_traits_rebind<_Alloc, _Tp>::type;
2610 _TpAlloc __tmp(*__get_alloc());
2611 allocator_traits<_TpAlloc>::destroy(__tmp, __get_elem());
2612#else
2613 __get_elem()->~_Tp();
2614#endif
2615 }
2616
2617 virtual void __on_zero_shared_weak() _NOEXCEPT {
2618 using _ControlBlockAlloc = typename __allocator_traits_rebind<_Alloc, __shared_ptr_emplace>::type;
2619 using _ControlBlockPointer = typename allocator_traits<_ControlBlockAlloc>::pointer;
2620 _ControlBlockAlloc __tmp(*__get_alloc());
2621 __storage_.~_Storage();
2622 allocator_traits<_ControlBlockAlloc>::deallocate(__tmp,
2623 pointer_traits<_ControlBlockPointer>::pointer_to(*this), 1);
2624 }
2625
2626 // This class implements the control block for non-array shared pointers created
2627 // through `std::allocate_shared` and `std::make_shared`.
2628 //
2629 // In previous versions of the library, we used a compressed pair to store
2630 // both the _Alloc and the _Tp. This implies using EBO, which is incompatible
2631 // with Allocator construction for _Tp. To allow implementing P0674 in C++20,
2632 // we now use a properly aligned char buffer while making sure that we maintain
2633 // the same layout that we had when we used a compressed pair.
2634 using _CompressedPair = __compressed_pair<_Alloc, _Tp>;
2635 struct _ALIGNAS_TYPE(_CompressedPair) _Storage {
2636 char __blob_[sizeof(_CompressedPair)];
2637
2638 _LIBCPP_HIDE_FROM_ABI explicit _Storage(_Alloc&& __a) {
2639 ::new ((void*)__get_alloc()) _Alloc(_VSTD::move(__a));
2640 }
2641 _LIBCPP_HIDE_FROM_ABI ~_Storage() {
2642 __get_alloc()->~_Alloc();
2643 }
2644 _Alloc* __get_alloc() _NOEXCEPT {
2645 _CompressedPair *__as_pair = reinterpret_cast<_CompressedPair*>(__blob_);
2646 typename _CompressedPair::_Base1* __first = _CompressedPair::__get_first_base(__as_pair);
2647 _Alloc *__alloc = reinterpret_cast<_Alloc*>(__first);
2648 return __alloc;
2649 }
2650 _LIBCPP_NO_CFI _Tp* __get_elem() _NOEXCEPT {
2651 _CompressedPair *__as_pair = reinterpret_cast<_CompressedPair*>(__blob_);
2652 typename _CompressedPair::_Base2* __second = _CompressedPair::__get_second_base(__as_pair);
2653 _Tp *__elem = reinterpret_cast<_Tp*>(__second);
2654 return __elem;
2655 }
2656 };
2657
2658 static_assert(_LIBCPP_ALIGNOF(_Storage) == _LIBCPP_ALIGNOF(_CompressedPair), "");
2659 static_assert(sizeof(_Storage) == sizeof(_CompressedPair), "");
2660 _Storage __storage_;
2661};
2662
2663struct __shared_ptr_dummy_rebind_allocator_type;
2664template <>
2665class _LIBCPP_TEMPLATE_VIS allocator<__shared_ptr_dummy_rebind_allocator_type>
2666{
2667public:
2668 template <class _Other>
2669 struct rebind
2670 {
2671 typedef allocator<_Other> other;
2672 };
2673};
2674
2675template<class _Tp> class _LIBCPP_TEMPLATE_VIS enable_shared_from_this;
2676
2677template<class _Tp, class _Up>
2678struct __compatible_with
2679#if _LIBCPP_STD_VER > 14
2680 : is_convertible<remove_extent_t<_Tp>*, remove_extent_t<_Up>*> {};
2681#else
2682 : is_convertible<_Tp*, _Up*> {};
2683#endif // _LIBCPP_STD_VER > 14
2684
2685#if defined(_LIBCPP_ABI_ENABLE_SHARED_PTR_TRIVIAL_ABI)
2686# define _LIBCPP_SHARED_PTR_TRIVIAL_ABI __attribute__((trivial_abi))
2687#else
2688# define _LIBCPP_SHARED_PTR_TRIVIAL_ABI
2689#endif
2690
2691template<class _Tp>
2692class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS shared_ptr
2693{
2694public:
2695#if _LIBCPP_STD_VER > 14
2696 typedef weak_ptr<_Tp> weak_type;
2697 typedef remove_extent_t<_Tp> element_type;
2698#else
2699 typedef _Tp element_type;
2700#endif
2701
2702private:
2703 element_type* __ptr_;
2704 __shared_weak_count* __cntrl_;
2705
2706 struct __nat {int __for_bool_;};
2707public:
2708 _LIBCPP_INLINE_VISIBILITY
2709 _LIBCPP_CONSTEXPR shared_ptr() _NOEXCEPT;
2710 _LIBCPP_INLINE_VISIBILITY
2711 _LIBCPP_CONSTEXPR shared_ptr(nullptr_t) _NOEXCEPT;
2712 template<class _Yp>
2713 explicit shared_ptr(_Yp* __p,
2714 typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type = __nat());
2715 template<class _Yp, class _Dp>
2716 shared_ptr(_Yp* __p, _Dp __d,
2717 typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type = __nat());
2718 template<class _Yp, class _Dp, class _Alloc>
2719 shared_ptr(_Yp* __p, _Dp __d, _Alloc __a,
2720 typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type = __nat());
2721 template <class _Dp> shared_ptr(nullptr_t __p, _Dp __d);
2722 template <class _Dp, class _Alloc> shared_ptr(nullptr_t __p, _Dp __d, _Alloc __a);
2723 template<class _Yp> _LIBCPP_INLINE_VISIBILITY shared_ptr(const shared_ptr<_Yp>& __r, element_type* __p) _NOEXCEPT;
2724 _LIBCPP_INLINE_VISIBILITY
2725 shared_ptr(const shared_ptr& __r) _NOEXCEPT;
2726 template<class _Yp>
2727 _LIBCPP_INLINE_VISIBILITY
2728 shared_ptr(const shared_ptr<_Yp>& __r,
2729 typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type = __nat())
2730 _NOEXCEPT;
2731 _LIBCPP_INLINE_VISIBILITY
2732 shared_ptr(shared_ptr&& __r) _NOEXCEPT;
2733 template<class _Yp> _LIBCPP_INLINE_VISIBILITY shared_ptr(shared_ptr<_Yp>&& __r,
2734 typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type = __nat())
2735 _NOEXCEPT;
2736 template<class _Yp> explicit shared_ptr(const weak_ptr<_Yp>& __r,
2737 typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type= __nat());
2738#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
2739 template<class _Yp>
2740 shared_ptr(auto_ptr<_Yp>&& __r,
2741 typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type = __nat());
2742#endif
2743 template <class _Yp, class _Dp>
2744 shared_ptr(unique_ptr<_Yp, _Dp>&&,
2745 typename enable_if
2746 <
2747 !is_lvalue_reference<_Dp>::value &&
2748 !is_array<_Yp>::value &&
2749 is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
2750 __nat
2751 >::type = __nat());
2752 template <class _Yp, class _Dp>
2753 shared_ptr(unique_ptr<_Yp, _Dp>&&,
2754 typename enable_if
2755 <
2756 is_lvalue_reference<_Dp>::value &&
2757 !is_array<_Yp>::value &&
2758 is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
2759 __nat
2760 >::type = __nat());
2761
2762 ~shared_ptr();
2763
2764 _LIBCPP_INLINE_VISIBILITY
2765 shared_ptr& operator=(const shared_ptr& __r) _NOEXCEPT;
2766 template<class _Yp>
2767 typename enable_if
2768 <
2769 __compatible_with<_Yp, element_type>::value,
2770 shared_ptr&
2771 >::type
2772 _LIBCPP_INLINE_VISIBILITY
2773 operator=(const shared_ptr<_Yp>& __r) _NOEXCEPT;
2774 _LIBCPP_INLINE_VISIBILITY
2775 shared_ptr& operator=(shared_ptr&& __r) _NOEXCEPT;
2776 template<class _Yp>
2777 typename enable_if
2778 <
2779 __compatible_with<_Yp, element_type>::value,
2780 shared_ptr&
2781 >::type
2782 _LIBCPP_INLINE_VISIBILITY
2783 operator=(shared_ptr<_Yp>&& __r);
2784#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
2785 template<class _Yp>
2786 _LIBCPP_INLINE_VISIBILITY
2787 typename enable_if
2788 <
2789 !is_array<_Yp>::value &&
2790 is_convertible<_Yp*, element_type*>::value,
2791 shared_ptr
2792 >::type&
2793 operator=(auto_ptr<_Yp>&& __r);
2794#endif
2795 template <class _Yp, class _Dp>
2796 typename enable_if
2797 <
2798 !is_array<_Yp>::value &&
2799 is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
2800 shared_ptr&
2801 >::type
2802 _LIBCPP_INLINE_VISIBILITY
2803 operator=(unique_ptr<_Yp, _Dp>&& __r);
2804
2805 _LIBCPP_INLINE_VISIBILITY
2806 void swap(shared_ptr& __r) _NOEXCEPT;
2807 _LIBCPP_INLINE_VISIBILITY
2808 void reset() _NOEXCEPT;
2809 template<class _Yp>
2810 typename enable_if
2811 <
2812 __compatible_with<_Yp, element_type>::value,
2813 void
2814 >::type
2815 _LIBCPP_INLINE_VISIBILITY
2816 reset(_Yp* __p);
2817 template<class _Yp, class _Dp>
2818 typename enable_if
2819 <
2820 __compatible_with<_Yp, element_type>::value,
2821 void
2822 >::type
2823 _LIBCPP_INLINE_VISIBILITY
2824 reset(_Yp* __p, _Dp __d);
2825 template<class _Yp, class _Dp, class _Alloc>
2826 typename enable_if
2827 <
2828 __compatible_with<_Yp, element_type>::value,
2829 void
2830 >::type
2831 _LIBCPP_INLINE_VISIBILITY
2832 reset(_Yp* __p, _Dp __d, _Alloc __a);
2833
2834 _LIBCPP_INLINE_VISIBILITY
2835 element_type* get() const _NOEXCEPT {return __ptr_;}
2836 _LIBCPP_INLINE_VISIBILITY
2837 typename add_lvalue_reference<element_type>::type operator*() const _NOEXCEPT
2838 {return *__ptr_;}
2839 _LIBCPP_INLINE_VISIBILITY
2840 element_type* operator->() const _NOEXCEPT
2841 {
2842 static_assert(!_VSTD::is_array<_Tp>::value,
2843 "std::shared_ptr<T>::operator-> is only valid when T is not an array type.");
2844 return __ptr_;
2845 }
2846 _LIBCPP_INLINE_VISIBILITY
2847 long use_count() const _NOEXCEPT {return __cntrl_ ? __cntrl_->use_count() : 0;}
2848 _LIBCPP_INLINE_VISIBILITY
2849 bool unique() const _NOEXCEPT {return use_count() == 1;}
2850 _LIBCPP_INLINE_VISIBILITY
2851 _LIBCPP_EXPLICIT operator bool() const _NOEXCEPT {return get() != nullptr;}
2852 template <class _Up>
2853 _LIBCPP_INLINE_VISIBILITY
2854 bool owner_before(shared_ptr<_Up> const& __p) const _NOEXCEPT
2855 {return __cntrl_ < __p.__cntrl_;}
2856 template <class _Up>
2857 _LIBCPP_INLINE_VISIBILITY
2858 bool owner_before(weak_ptr<_Up> const& __p) const _NOEXCEPT
2859 {return __cntrl_ < __p.__cntrl_;}
2860 _LIBCPP_INLINE_VISIBILITY
2861 bool
2862 __owner_equivalent(const shared_ptr& __p) const
2863 {return __cntrl_ == __p.__cntrl_;}
2864
2865#if _LIBCPP_STD_VER > 14
2866 typename add_lvalue_reference<element_type>::type
2867 _LIBCPP_INLINE_VISIBILITY
2868 operator[](ptrdiff_t __i) const
2869 {
2870 static_assert(_VSTD::is_array<_Tp>::value,
2871 "std::shared_ptr<T>::operator[] is only valid when T is an array type.");
2872 return __ptr_[__i];
2873 }
2874#endif
2875
2876#ifndef _LIBCPP_NO_RTTI
2877 template <class _Dp>
2878 _LIBCPP_INLINE_VISIBILITY
2879 _Dp* __get_deleter() const _NOEXCEPT
2880 {return static_cast<_Dp*>(__cntrl_
2881 ? const_cast<void *>(__cntrl_->__get_deleter(typeid(_Dp)))
2882 : nullptr);}
2883#endif // _LIBCPP_NO_RTTI
2884
2885 template<class _Yp, class _CntrlBlk>
2886 static shared_ptr<_Tp>
2887 __create_with_control_block(_Yp* __p, _CntrlBlk* __cntrl) _NOEXCEPT
2888 {
2889 shared_ptr<_Tp> __r;
2890 __r.__ptr_ = __p;
2891 __r.__cntrl_ = __cntrl;
2892 __r.__enable_weak_this(__r.__ptr_, __r.__ptr_);
2893 return __r;
2894 }
2895
2896private:
2897 template <class _Yp, bool = is_function<_Yp>::value>
2898 struct __shared_ptr_default_allocator
2899 {
2900 typedef allocator<_Yp> type;
2901 };
2902
2903 template <class _Yp>
2904 struct __shared_ptr_default_allocator<_Yp, true>
2905 {
2906 typedef allocator<__shared_ptr_dummy_rebind_allocator_type> type;
2907 };
2908
2909 template <class _Yp, class _OrigPtr>
2910 _LIBCPP_INLINE_VISIBILITY
2911 typename enable_if<is_convertible<_OrigPtr*,
2912 const enable_shared_from_this<_Yp>*
2913 >::value,
2914 void>::type
2915 __enable_weak_this(const enable_shared_from_this<_Yp>* __e,
2916 _OrigPtr* __ptr) _NOEXCEPT
2917 {
2918 typedef typename remove_cv<_Yp>::type _RawYp;
2919 if (__e && __e->__weak_this_.expired())
2920 {
2921 __e->__weak_this_ = shared_ptr<_RawYp>(*this,
2922 const_cast<_RawYp*>(static_cast<const _Yp*>(__ptr)));
2923 }
2924 }
2925
2926 _LIBCPP_INLINE_VISIBILITY void __enable_weak_this(...) _NOEXCEPT {}
2927
2928 template <class, class _Yp>
2929 struct __shared_ptr_default_delete
2930 : default_delete<_Yp> {};
2931
2932 template <class _Yp, class _Un, size_t _Sz>
2933 struct __shared_ptr_default_delete<_Yp[_Sz], _Un>
2934 : default_delete<_Yp[]> {};
2935
2936 template <class _Yp, class _Un>
2937 struct __shared_ptr_default_delete<_Yp[], _Un>
2938 : default_delete<_Yp[]> {};
2939
2940 template <class _Up> friend class _LIBCPP_TEMPLATE_VIS shared_ptr;
2941 template <class _Up> friend class _LIBCPP_TEMPLATE_VIS weak_ptr;
2942};
2943
2944#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
2945template<class _Tp>
2946shared_ptr(weak_ptr<_Tp>) -> shared_ptr<_Tp>;
2947template<class _Tp, class _Dp>
2948shared_ptr(unique_ptr<_Tp, _Dp>) -> shared_ptr<_Tp>;
2949#endif
2950
2951template<class _Tp>
2952inline
2953_LIBCPP_CONSTEXPR
2954shared_ptr<_Tp>::shared_ptr() _NOEXCEPT
2955 : __ptr_(nullptr),
2956 __cntrl_(nullptr)
2957{
2958}
2959
2960template<class _Tp>
2961inline
2962_LIBCPP_CONSTEXPR
2963shared_ptr<_Tp>::shared_ptr(nullptr_t) _NOEXCEPT
2964 : __ptr_(nullptr),
2965 __cntrl_(nullptr)
2966{
2967}
2968
2969template<class _Tp>
2970template<class _Yp>
2971shared_ptr<_Tp>::shared_ptr(_Yp* __p,
2972 typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type)
2973 : __ptr_(__p)
2974{
2975 unique_ptr<_Yp> __hold(__p);
2976 typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;
2977 typedef __shared_ptr_pointer<_Yp*, __shared_ptr_default_delete<_Tp, _Yp>, _AllocT > _CntrlBlk;
2978 __cntrl_ = new _CntrlBlk(__p, __shared_ptr_default_delete<_Tp, _Yp>(), _AllocT());
2979 __hold.release();
2980 __enable_weak_this(__p, __p);
2981}
2982
2983template<class _Tp>
2984template<class _Yp, class _Dp>
2985shared_ptr<_Tp>::shared_ptr(_Yp* __p, _Dp __d,
2986 typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type)
2987 : __ptr_(__p)
2988{
2989#ifndef _LIBCPP_NO_EXCEPTIONS
2990 try
2991 {
2992#endif // _LIBCPP_NO_EXCEPTIONS
2993 typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;
2994 typedef __shared_ptr_pointer<_Yp*, _Dp, _AllocT > _CntrlBlk;
2995 __cntrl_ = new _CntrlBlk(__p, __d, _AllocT());
2996 __enable_weak_this(__p, __p);
2997#ifndef _LIBCPP_NO_EXCEPTIONS
2998 }
2999 catch (...)
3000 {
3001 __d(__p);
3002 throw;
3003 }
3004#endif // _LIBCPP_NO_EXCEPTIONS
3005}
3006
3007template<class _Tp>
3008template<class _Dp>
3009shared_ptr<_Tp>::shared_ptr(nullptr_t __p, _Dp __d)
3010 : __ptr_(nullptr)
3011{
3012#ifndef _LIBCPP_NO_EXCEPTIONS
3013 try
3014 {
3015#endif // _LIBCPP_NO_EXCEPTIONS
3016 typedef typename __shared_ptr_default_allocator<_Tp>::type _AllocT;
3017 typedef __shared_ptr_pointer<nullptr_t, _Dp, _AllocT > _CntrlBlk;
3018 __cntrl_ = new _CntrlBlk(__p, __d, _AllocT());
3019#ifndef _LIBCPP_NO_EXCEPTIONS
3020 }
3021 catch (...)
3022 {
3023 __d(__p);
3024 throw;
3025 }
3026#endif // _LIBCPP_NO_EXCEPTIONS
3027}
3028
3029template<class _Tp>
3030template<class _Yp, class _Dp, class _Alloc>
3031shared_ptr<_Tp>::shared_ptr(_Yp* __p, _Dp __d, _Alloc __a,
3032 typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type)
3033 : __ptr_(__p)
3034{
3035#ifndef _LIBCPP_NO_EXCEPTIONS
3036 try
3037 {
3038#endif // _LIBCPP_NO_EXCEPTIONS
3039 typedef __shared_ptr_pointer<_Yp*, _Dp, _Alloc> _CntrlBlk;
3040 typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _A2;
3041 typedef __allocator_destructor<_A2> _D2;
3042 _A2 __a2(__a);
3043 unique_ptr<_CntrlBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1));
3044 ::new ((void*)_VSTD::addressof(*__hold2.get())) _CntrlBlk(__p, __d, __a);
3045 __cntrl_ = _VSTD::addressof(*__hold2.release());
3046 __enable_weak_this(__p, __p);
3047#ifndef _LIBCPP_NO_EXCEPTIONS
3048 }
3049 catch (...)
3050 {
3051 __d(__p);
3052 throw;
3053 }
3054#endif // _LIBCPP_NO_EXCEPTIONS
3055}
3056
3057template<class _Tp>
3058template<class _Dp, class _Alloc>
3059shared_ptr<_Tp>::shared_ptr(nullptr_t __p, _Dp __d, _Alloc __a)
3060 : __ptr_(nullptr)
3061{
3062#ifndef _LIBCPP_NO_EXCEPTIONS
3063 try
3064 {
3065#endif // _LIBCPP_NO_EXCEPTIONS
3066 typedef __shared_ptr_pointer<nullptr_t, _Dp, _Alloc> _CntrlBlk;
3067 typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _A2;
3068 typedef __allocator_destructor<_A2> _D2;
3069 _A2 __a2(__a);
3070 unique_ptr<_CntrlBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1));
3071 ::new ((void*)_VSTD::addressof(*__hold2.get())) _CntrlBlk(__p, __d, __a);
3072 __cntrl_ = _VSTD::addressof(*__hold2.release());
3073#ifndef _LIBCPP_NO_EXCEPTIONS
3074 }
3075 catch (...)
3076 {
3077 __d(__p);
3078 throw;
3079 }
3080#endif // _LIBCPP_NO_EXCEPTIONS
3081}
3082
3083template<class _Tp>
3084template<class _Yp>
3085inline
3086shared_ptr<_Tp>::shared_ptr(const shared_ptr<_Yp>& __r, element_type *__p) _NOEXCEPT
3087 : __ptr_(__p),
3088 __cntrl_(__r.__cntrl_)
3089{
3090 if (__cntrl_)
3091 __cntrl_->__add_shared();
3092}
3093
3094template<class _Tp>
3095inline
3096shared_ptr<_Tp>::shared_ptr(const shared_ptr& __r) _NOEXCEPT
3097 : __ptr_(__r.__ptr_),
3098 __cntrl_(__r.__cntrl_)
3099{
3100 if (__cntrl_)
3101 __cntrl_->__add_shared();
3102}
3103
3104template<class _Tp>
3105template<class _Yp>
3106inline
3107shared_ptr<_Tp>::shared_ptr(const shared_ptr<_Yp>& __r,
3108 typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type)
3109 _NOEXCEPT
3110 : __ptr_(__r.__ptr_),
3111 __cntrl_(__r.__cntrl_)
3112{
3113 if (__cntrl_)
3114 __cntrl_->__add_shared();
3115}
3116
3117template<class _Tp>
3118inline
3119shared_ptr<_Tp>::shared_ptr(shared_ptr&& __r) _NOEXCEPT
3120 : __ptr_(__r.__ptr_),
3121 __cntrl_(__r.__cntrl_)
3122{
3123 __r.__ptr_ = nullptr;
3124 __r.__cntrl_ = nullptr;
3125}
3126
3127template<class _Tp>
3128template<class _Yp>
3129inline
3130shared_ptr<_Tp>::shared_ptr(shared_ptr<_Yp>&& __r,
3131 typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type)
3132 _NOEXCEPT
3133 : __ptr_(__r.__ptr_),
3134 __cntrl_(__r.__cntrl_)
3135{
3136 __r.__ptr_ = nullptr;
3137 __r.__cntrl_ = nullptr;
3138}
3139
3140#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
3141template<class _Tp>
3142template<class _Yp>
3143shared_ptr<_Tp>::shared_ptr(auto_ptr<_Yp>&& __r,
3144 typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type)
3145 : __ptr_(__r.get())
3146{
3147 typedef __shared_ptr_pointer<_Yp*, default_delete<_Yp>, allocator<_Yp> > _CntrlBlk;
3148 __cntrl_ = new _CntrlBlk(__r.get(), default_delete<_Yp>(), allocator<_Yp>());
3149 __enable_weak_this(__r.get(), __r.get());
3150 __r.release();
3151}
3152#endif
3153
3154template<class _Tp>
3155template <class _Yp, class _Dp>
3156shared_ptr<_Tp>::shared_ptr(unique_ptr<_Yp, _Dp>&& __r,
3157 typename enable_if
3158 <
3159 !is_lvalue_reference<_Dp>::value &&
3160 !is_array<_Yp>::value &&
3161 is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
3162 __nat
3163 >::type)
3164 : __ptr_(__r.get())
3165{
3166#if _LIBCPP_STD_VER > 11
3167 if (__ptr_ == nullptr)
3168 __cntrl_ = nullptr;
3169 else
3170#endif
3171 {
3172 typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;
3173 typedef __shared_ptr_pointer<_Yp*, _Dp, _AllocT > _CntrlBlk;
3174 __cntrl_ = new _CntrlBlk(__r.get(), __r.get_deleter(), _AllocT());
3175 __enable_weak_this(__r.get(), __r.get());
3176 }
3177 __r.release();
3178}
3179
3180template<class _Tp>
3181template <class _Yp, class _Dp>
3182shared_ptr<_Tp>::shared_ptr(unique_ptr<_Yp, _Dp>&& __r,
3183 typename enable_if
3184 <
3185 is_lvalue_reference<_Dp>::value &&
3186 !is_array<_Yp>::value &&
3187 is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
3188 __nat
3189 >::type)
3190 : __ptr_(__r.get())
3191{
3192#if _LIBCPP_STD_VER > 11
3193 if (__ptr_ == nullptr)
3194 __cntrl_ = nullptr;
3195 else
3196#endif
3197 {
3198 typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;
3199 typedef __shared_ptr_pointer<_Yp*,
3200 reference_wrapper<typename remove_reference<_Dp>::type>,
3201 _AllocT > _CntrlBlk;
3202 __cntrl_ = new _CntrlBlk(__r.get(), _VSTD::ref(__r.get_deleter()), _AllocT());
3203 __enable_weak_this(__r.get(), __r.get());
3204 }
3205 __r.release();
3206}
3207
3208template<class _Tp>
3209shared_ptr<_Tp>::~shared_ptr()
3210{
3211 if (__cntrl_)
3212 __cntrl_->__release_shared();
3213}
3214
3215template<class _Tp>
3216inline
3217shared_ptr<_Tp>&
3218shared_ptr<_Tp>::operator=(const shared_ptr& __r) _NOEXCEPT
3219{
3220 shared_ptr(__r).swap(*this);
3221 return *this;
3222}
3223
3224template<class _Tp>
3225template<class _Yp>
3226inline
3227typename enable_if
3228<
3229 __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value,
3230 shared_ptr<_Tp>&
3231>::type
3232shared_ptr<_Tp>::operator=(const shared_ptr<_Yp>& __r) _NOEXCEPT
3233{
3234 shared_ptr(__r).swap(*this);
3235 return *this;
3236}
3237
3238template<class _Tp>
3239inline
3240shared_ptr<_Tp>&
3241shared_ptr<_Tp>::operator=(shared_ptr&& __r) _NOEXCEPT
3242{
3243 shared_ptr(_VSTD::move(__r)).swap(*this);
3244 return *this;
3245}
3246
3247template<class _Tp>
3248template<class _Yp>
3249inline
3250typename enable_if
3251<
3252 __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value,
3253 shared_ptr<_Tp>&
3254>::type
3255shared_ptr<_Tp>::operator=(shared_ptr<_Yp>&& __r)
3256{
3257 shared_ptr(_VSTD::move(__r)).swap(*this);
3258 return *this;
3259}
3260
3261#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
3262template<class _Tp>
3263template<class _Yp>
3264inline
3265typename enable_if
3266<
3267 !is_array<_Yp>::value &&
3268 is_convertible<_Yp*, typename shared_ptr<_Tp>::element_type*>::value,
3269 shared_ptr<_Tp>
3270>::type&
3271shared_ptr<_Tp>::operator=(auto_ptr<_Yp>&& __r)
3272{
3273 shared_ptr(_VSTD::move(__r)).swap(*this);
3274 return *this;
3275}
3276#endif
3277
3278template<class _Tp>
3279template <class _Yp, class _Dp>
3280inline
3281typename enable_if
3282<
3283 !is_array<_Yp>::value &&
3284 is_convertible<typename unique_ptr<_Yp, _Dp>::pointer,
3285 typename shared_ptr<_Tp>::element_type*>::value,
3286 shared_ptr<_Tp>&
3287>::type
3288shared_ptr<_Tp>::operator=(unique_ptr<_Yp, _Dp>&& __r)
3289{
3290 shared_ptr(_VSTD::move(__r)).swap(*this);
3291 return *this;
3292}
3293
3294template<class _Tp>
3295inline
3296void
3297shared_ptr<_Tp>::swap(shared_ptr& __r) _NOEXCEPT
3298{
3299 _VSTD::swap(__ptr_, __r.__ptr_);
3300 _VSTD::swap(__cntrl_, __r.__cntrl_);
3301}
3302
3303template<class _Tp>
3304inline
3305void
3306shared_ptr<_Tp>::reset() _NOEXCEPT
3307{
3308 shared_ptr().swap(*this);
3309}
3310
3311template<class _Tp>
3312template<class _Yp>
3313inline
3314typename enable_if
3315<
3316 __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value,
3317 void
3318>::type
3319shared_ptr<_Tp>::reset(_Yp* __p)
3320{
3321 shared_ptr(__p).swap(*this);
3322}
3323
3324template<class _Tp>
3325template<class _Yp, class _Dp>
3326inline
3327typename enable_if
3328<
3329 __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value,
3330 void
3331>::type
3332shared_ptr<_Tp>::reset(_Yp* __p, _Dp __d)
3333{
3334 shared_ptr(__p, __d).swap(*this);
3335}
3336
3337template<class _Tp>
3338template<class _Yp, class _Dp, class _Alloc>
3339inline
3340typename enable_if
3341<
3342 __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value,
3343 void
3344>::type
3345shared_ptr<_Tp>::reset(_Yp* __p, _Dp __d, _Alloc __a)
3346{
3347 shared_ptr(__p, __d, __a).swap(*this);
3348}
3349
3350//
3351// std::allocate_shared and std::make_shared
3352//
3353template<class _Tp, class _Alloc, class ..._Args, class = _EnableIf<!is_array<_Tp>::value> >
3354_LIBCPP_HIDE_FROM_ABI
3355shared_ptr<_Tp> allocate_shared(const _Alloc& __a, _Args&& ...__args)
3356{
3357 using _ControlBlock = __shared_ptr_emplace<_Tp, _Alloc>;
3358 using _ControlBlockAllocator = typename __allocator_traits_rebind<_Alloc, _ControlBlock>::type;
3359 __allocation_guard<_ControlBlockAllocator> __guard(__a, 1);
3360 ::new ((void*)_VSTD::addressof(*__guard.__get())) _ControlBlock(__a, _VSTD::forward<_Args>(__args)...);
3361 auto __control_block = __guard.__release_ptr();
3362 return shared_ptr<_Tp>::__create_with_control_block((*__control_block).__get_elem(), _VSTD::addressof(*__control_block));
3363}
3364
3365template<class _Tp, class ..._Args, class = _EnableIf<!is_array<_Tp>::value> >
3366_LIBCPP_HIDE_FROM_ABI
3367shared_ptr<_Tp> make_shared(_Args&& ...__args)
3368{
3369 return _VSTD::allocate_shared<_Tp>(allocator<_Tp>(), _VSTD::forward<_Args>(__args)...);
3370}
3371
3372template<class _Tp, class _Up>
3373inline _LIBCPP_INLINE_VISIBILITY
3374bool
3375operator==(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
3376{
3377 return __x.get() == __y.get();
3378}
3379
3380template<class _Tp, class _Up>
3381inline _LIBCPP_INLINE_VISIBILITY
3382bool
3383operator!=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
3384{
3385 return !(__x == __y);
3386}
3387
3388template<class _Tp, class _Up>
3389inline _LIBCPP_INLINE_VISIBILITY
3390bool
3391operator<(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
3392{
3393#if _LIBCPP_STD_VER <= 11
3394 typedef typename common_type<_Tp*, _Up*>::type _Vp;
3395 return less<_Vp>()(__x.get(), __y.get());
3396#else
3397 return less<>()(__x.get(), __y.get());
3398#endif
3399
3400}
3401
3402template<class _Tp, class _Up>
3403inline _LIBCPP_INLINE_VISIBILITY
3404bool
3405operator>(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
3406{
3407 return __y < __x;
3408}
3409
3410template<class _Tp, class _Up>
3411inline _LIBCPP_INLINE_VISIBILITY
3412bool
3413operator<=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
3414{
3415 return !(__y < __x);
3416}
3417
3418template<class _Tp, class _Up>
3419inline _LIBCPP_INLINE_VISIBILITY
3420bool
3421operator>=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
3422{
3423 return !(__x < __y);
3424}
3425
3426template<class _Tp>
3427inline _LIBCPP_INLINE_VISIBILITY
3428bool
3429operator==(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
3430{
3431 return !__x;
3432}
3433
3434template<class _Tp>
3435inline _LIBCPP_INLINE_VISIBILITY
3436bool
3437operator==(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
3438{
3439 return !__x;
3440}
3441
3442template<class _Tp>
3443inline _LIBCPP_INLINE_VISIBILITY
3444bool
3445operator!=(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
3446{
3447 return static_cast<bool>(__x);
3448}
3449
3450template<class _Tp>
3451inline _LIBCPP_INLINE_VISIBILITY
3452bool
3453operator!=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
3454{
3455 return static_cast<bool>(__x);
3456}
3457
3458template<class _Tp>
3459inline _LIBCPP_INLINE_VISIBILITY
3460bool
3461operator<(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
3462{
3463 return less<_Tp*>()(__x.get(), nullptr);
3464}
3465
3466template<class _Tp>
3467inline _LIBCPP_INLINE_VISIBILITY
3468bool
3469operator<(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
3470{
3471 return less<_Tp*>()(nullptr, __x.get());
3472}
3473
3474template<class _Tp>
3475inline _LIBCPP_INLINE_VISIBILITY
3476bool
3477operator>(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
3478{
3479 return nullptr < __x;
3480}
3481
3482template<class _Tp>
3483inline _LIBCPP_INLINE_VISIBILITY
3484bool
3485operator>(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
3486{
3487 return __x < nullptr;
3488}
3489
3490template<class _Tp>
3491inline _LIBCPP_INLINE_VISIBILITY
3492bool
3493operator<=(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
3494{
3495 return !(nullptr < __x);
3496}
3497
3498template<class _Tp>
3499inline _LIBCPP_INLINE_VISIBILITY
3500bool
3501operator<=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
3502{
3503 return !(__x < nullptr);
3504}
3505
3506template<class _Tp>
3507inline _LIBCPP_INLINE_VISIBILITY
3508bool
3509operator>=(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
3510{
3511 return !(__x < nullptr);
3512}
3513
3514template<class _Tp>
3515inline _LIBCPP_INLINE_VISIBILITY
3516bool
3517operator>=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
3518{
3519 return !(nullptr < __x);
3520}
3521
3522template<class _Tp>
3523inline _LIBCPP_INLINE_VISIBILITY
3524void
3525swap(shared_ptr<_Tp>& __x, shared_ptr<_Tp>& __y) _NOEXCEPT
3526{
3527 __x.swap(__y);
3528}
3529
3530template<class _Tp, class _Up>
3531inline _LIBCPP_INLINE_VISIBILITY
3532shared_ptr<_Tp>
3533static_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT
3534{
3535 return shared_ptr<_Tp>(__r,
3536 static_cast<
3537 typename shared_ptr<_Tp>::element_type*>(__r.get()));
3538}
3539
3540template<class _Tp, class _Up>
3541inline _LIBCPP_INLINE_VISIBILITY
3542shared_ptr<_Tp>
3543dynamic_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT
3544{
3545 typedef typename shared_ptr<_Tp>::element_type _ET;
3546 _ET* __p = dynamic_cast<_ET*>(__r.get());
3547 return __p ? shared_ptr<_Tp>(__r, __p) : shared_ptr<_Tp>();
3548}
3549
3550template<class _Tp, class _Up>
3551shared_ptr<_Tp>
3552const_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT
3553{
3554 typedef typename shared_ptr<_Tp>::element_type _RTp;
3555 return shared_ptr<_Tp>(__r, const_cast<_RTp*>(__r.get()));
3556}
3557
3558template<class _Tp, class _Up>
3559shared_ptr<_Tp>
3560reinterpret_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT
3561{
3562 return shared_ptr<_Tp>(__r,
3563 reinterpret_cast<
3564 typename shared_ptr<_Tp>::element_type*>(__r.get()));
3565}
3566
3567#ifndef _LIBCPP_NO_RTTI
3568
3569template<class _Dp, class _Tp>
3570inline _LIBCPP_INLINE_VISIBILITY
3571_Dp*
3572get_deleter(const shared_ptr<_Tp>& __p) _NOEXCEPT
3573{
3574 return __p.template __get_deleter<_Dp>();
3575}
3576
3577#endif // _LIBCPP_NO_RTTI
3578
3579template<class _Tp>
3580class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS weak_ptr
3581{
3582public:
3583 typedef _Tp element_type;
3584private:
3585 element_type* __ptr_;
3586 __shared_weak_count* __cntrl_;
3587
3588public:
3589 _LIBCPP_INLINE_VISIBILITY
3590 _LIBCPP_CONSTEXPR weak_ptr() _NOEXCEPT;
3591 template<class _Yp> _LIBCPP_INLINE_VISIBILITY weak_ptr(shared_ptr<_Yp> const& __r,
3592 typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type = 0)
3593 _NOEXCEPT;
3594 _LIBCPP_INLINE_VISIBILITY
3595 weak_ptr(weak_ptr const& __r) _NOEXCEPT;
3596 template<class _Yp> _LIBCPP_INLINE_VISIBILITY weak_ptr(weak_ptr<_Yp> const& __r,
3597 typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type = 0)
3598 _NOEXCEPT;
3599
3600 _LIBCPP_INLINE_VISIBILITY
3601 weak_ptr(weak_ptr&& __r) _NOEXCEPT;
3602 template<class _Yp> _LIBCPP_INLINE_VISIBILITY weak_ptr(weak_ptr<_Yp>&& __r,
3603 typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type = 0)
3604 _NOEXCEPT;
3605 ~weak_ptr();
3606
3607 _LIBCPP_INLINE_VISIBILITY
3608 weak_ptr& operator=(weak_ptr const& __r) _NOEXCEPT;
3609 template<class _Yp>
3610 typename enable_if
3611 <
3612 is_convertible<_Yp*, element_type*>::value,
3613 weak_ptr&
3614 >::type
3615 _LIBCPP_INLINE_VISIBILITY
3616 operator=(weak_ptr<_Yp> const& __r) _NOEXCEPT;
3617
3618 _LIBCPP_INLINE_VISIBILITY
3619 weak_ptr& operator=(weak_ptr&& __r) _NOEXCEPT;
3620 template<class _Yp>
3621 typename enable_if
3622 <
3623 is_convertible<_Yp*, element_type*>::value,
3624 weak_ptr&
3625 >::type
3626 _LIBCPP_INLINE_VISIBILITY
3627 operator=(weak_ptr<_Yp>&& __r) _NOEXCEPT;
3628
3629 template<class _Yp>
3630 typename enable_if
3631 <
3632 is_convertible<_Yp*, element_type*>::value,
3633 weak_ptr&
3634 >::type
3635 _LIBCPP_INLINE_VISIBILITY
3636 operator=(shared_ptr<_Yp> const& __r) _NOEXCEPT;
3637
3638 _LIBCPP_INLINE_VISIBILITY
3639 void swap(weak_ptr& __r) _NOEXCEPT;
3640 _LIBCPP_INLINE_VISIBILITY
3641 void reset() _NOEXCEPT;
3642
3643 _LIBCPP_INLINE_VISIBILITY
3644 long use_count() const _NOEXCEPT
3645 {return __cntrl_ ? __cntrl_->use_count() : 0;}
3646 _LIBCPP_INLINE_VISIBILITY
3647 bool expired() const _NOEXCEPT
3648 {return __cntrl_ == nullptr || __cntrl_->use_count() == 0;}
3649 shared_ptr<_Tp> lock() const _NOEXCEPT;
3650 template<class _Up>
3651 _LIBCPP_INLINE_VISIBILITY
3652 bool owner_before(const shared_ptr<_Up>& __r) const _NOEXCEPT
3653 {return __cntrl_ < __r.__cntrl_;}
3654 template<class _Up>
3655 _LIBCPP_INLINE_VISIBILITY
3656 bool owner_before(const weak_ptr<_Up>& __r) const _NOEXCEPT
3657 {return __cntrl_ < __r.__cntrl_;}
3658
3659 template <class _Up> friend class _LIBCPP_TEMPLATE_VIS weak_ptr;
3660 template <class _Up> friend class _LIBCPP_TEMPLATE_VIS shared_ptr;
3661};
3662
3663#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
3664template<class _Tp>
3665weak_ptr(shared_ptr<_Tp>) -> weak_ptr<_Tp>;
3666#endif
3667
3668template<class _Tp>
3669inline
3670_LIBCPP_CONSTEXPR
3671weak_ptr<_Tp>::weak_ptr() _NOEXCEPT
3672 : __ptr_(nullptr),
3673 __cntrl_(nullptr)
3674{
3675}
3676
3677template<class _Tp>
3678inline
3679weak_ptr<_Tp>::weak_ptr(weak_ptr const& __r) _NOEXCEPT
3680 : __ptr_(__r.__ptr_),
3681 __cntrl_(__r.__cntrl_)
3682{
3683 if (__cntrl_)
3684 __cntrl_->__add_weak();
3685}
3686
3687template<class _Tp>
3688template<class _Yp>
3689inline
3690weak_ptr<_Tp>::weak_ptr(shared_ptr<_Yp> const& __r,
3691 typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type)
3692 _NOEXCEPT
3693 : __ptr_(__r.__ptr_),
3694 __cntrl_(__r.__cntrl_)
3695{
3696 if (__cntrl_)
3697 __cntrl_->__add_weak();
3698}
3699
3700template<class _Tp>
3701template<class _Yp>
3702inline
3703weak_ptr<_Tp>::weak_ptr(weak_ptr<_Yp> const& __r,
3704 typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type)
3705 _NOEXCEPT
3706 : __ptr_(__r.__ptr_),
3707 __cntrl_(__r.__cntrl_)
3708{
3709 if (__cntrl_)
3710 __cntrl_->__add_weak();
3711}
3712
3713template<class _Tp>
3714inline
3715weak_ptr<_Tp>::weak_ptr(weak_ptr&& __r) _NOEXCEPT
3716 : __ptr_(__r.__ptr_),
3717 __cntrl_(__r.__cntrl_)
3718{
3719 __r.__ptr_ = nullptr;
3720 __r.__cntrl_ = nullptr;
3721}
3722
3723template<class _Tp>
3724template<class _Yp>
3725inline
3726weak_ptr<_Tp>::weak_ptr(weak_ptr<_Yp>&& __r,
3727 typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type)
3728 _NOEXCEPT
3729 : __ptr_(__r.__ptr_),
3730 __cntrl_(__r.__cntrl_)
3731{
3732 __r.__ptr_ = nullptr;
3733 __r.__cntrl_ = nullptr;
3734}
3735
3736template<class _Tp>
3737weak_ptr<_Tp>::~weak_ptr()
3738{
3739 if (__cntrl_)
3740 __cntrl_->__release_weak();
3741}
3742
3743template<class _Tp>
3744inline
3745weak_ptr<_Tp>&
3746weak_ptr<_Tp>::operator=(weak_ptr const& __r) _NOEXCEPT
3747{
3748 weak_ptr(__r).swap(*this);
3749 return *this;
3750}
3751
3752template<class _Tp>
3753template<class _Yp>
3754inline
3755typename enable_if
3756<
3757 is_convertible<_Yp*, _Tp*>::value,
3758 weak_ptr<_Tp>&
3759>::type
3760weak_ptr<_Tp>::operator=(weak_ptr<_Yp> const& __r) _NOEXCEPT
3761{
3762 weak_ptr(__r).swap(*this);
3763 return *this;
3764}
3765
3766template<class _Tp>
3767inline
3768weak_ptr<_Tp>&
3769weak_ptr<_Tp>::operator=(weak_ptr&& __r) _NOEXCEPT
3770{
3771 weak_ptr(_VSTD::move(__r)).swap(*this);
3772 return *this;
3773}
3774
3775template<class _Tp>
3776template<class _Yp>
3777inline
3778typename enable_if
3779<
3780 is_convertible<_Yp*, _Tp*>::value,
3781 weak_ptr<_Tp>&
3782>::type
3783weak_ptr<_Tp>::operator=(weak_ptr<_Yp>&& __r) _NOEXCEPT
3784{
3785 weak_ptr(_VSTD::move(__r)).swap(*this);
3786 return *this;
3787}
3788
3789template<class _Tp>
3790template<class _Yp>
3791inline
3792typename enable_if
3793<
3794 is_convertible<_Yp*, _Tp*>::value,
3795 weak_ptr<_Tp>&
3796>::type
3797weak_ptr<_Tp>::operator=(shared_ptr<_Yp> const& __r) _NOEXCEPT
3798{
3799 weak_ptr(__r).swap(*this);
3800 return *this;
3801}
3802
3803template<class _Tp>
3804inline
3805void
3806weak_ptr<_Tp>::swap(weak_ptr& __r) _NOEXCEPT
3807{
3808 _VSTD::swap(__ptr_, __r.__ptr_);
3809 _VSTD::swap(__cntrl_, __r.__cntrl_);
3810}
3811
3812template<class _Tp>
3813inline _LIBCPP_INLINE_VISIBILITY
3814void
3815swap(weak_ptr<_Tp>& __x, weak_ptr<_Tp>& __y) _NOEXCEPT
3816{
3817 __x.swap(__y);
3818}
3819
3820template<class _Tp>
3821inline
3822void
3823weak_ptr<_Tp>::reset() _NOEXCEPT
3824{
3825 weak_ptr().swap(*this);
3826}
3827
3828template<class _Tp>
3829template<class _Yp>
3830shared_ptr<_Tp>::shared_ptr(const weak_ptr<_Yp>& __r,
3831 typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type)
3832 : __ptr_(__r.__ptr_),
3833 __cntrl_(__r.__cntrl_ ? __r.__cntrl_->lock() : __r.__cntrl_)
3834{
3835 if (__cntrl_ == nullptr)
3836 __throw_bad_weak_ptr();
3837}
3838
3839template<class _Tp>
3840shared_ptr<_Tp>
3841weak_ptr<_Tp>::lock() const _NOEXCEPT
3842{
3843 shared_ptr<_Tp> __r;
3844 __r.__cntrl_ = __cntrl_ ? __cntrl_->lock() : __cntrl_;
3845 if (__r.__cntrl_)
3846 __r.__ptr_ = __ptr_;
3847 return __r;
3848}
3849
3850#if _LIBCPP_STD_VER > 14
3851template <class _Tp = void> struct owner_less;
3852#else
3853template <class _Tp> struct owner_less;
3854#endif
3855
3856template <class _Tp>
3857struct _LIBCPP_TEMPLATE_VIS owner_less<shared_ptr<_Tp> >
3858 : binary_function<shared_ptr<_Tp>, shared_ptr<_Tp>, bool>
3859{
3860 typedef bool result_type;
3861 _LIBCPP_INLINE_VISIBILITY
3862 bool operator()(shared_ptr<_Tp> const& __x, shared_ptr<_Tp> const& __y) const _NOEXCEPT
3863 {return __x.owner_before(__y);}
3864 _LIBCPP_INLINE_VISIBILITY
3865 bool operator()(shared_ptr<_Tp> const& __x, weak_ptr<_Tp> const& __y) const _NOEXCEPT
3866 {return __x.owner_before(__y);}
3867 _LIBCPP_INLINE_VISIBILITY
3868 bool operator()( weak_ptr<_Tp> const& __x, shared_ptr<_Tp> const& __y) const _NOEXCEPT
3869 {return __x.owner_before(__y);}
3870};
3871
3872template <class _Tp>
3873struct _LIBCPP_TEMPLATE_VIS owner_less<weak_ptr<_Tp> >
3874 : binary_function<weak_ptr<_Tp>, weak_ptr<_Tp>, bool>
3875{
3876 typedef bool result_type;
3877 _LIBCPP_INLINE_VISIBILITY
3878 bool operator()( weak_ptr<_Tp> const& __x, weak_ptr<_Tp> const& __y) const _NOEXCEPT
3879 {return __x.owner_before(__y);}
3880 _LIBCPP_INLINE_VISIBILITY
3881 bool operator()(shared_ptr<_Tp> const& __x, weak_ptr<_Tp> const& __y) const _NOEXCEPT
3882 {return __x.owner_before(__y);}
3883 _LIBCPP_INLINE_VISIBILITY
3884 bool operator()( weak_ptr<_Tp> const& __x, shared_ptr<_Tp> const& __y) const _NOEXCEPT
3885 {return __x.owner_before(__y);}
3886};
3887
3888#if _LIBCPP_STD_VER > 14
3889template <>
3890struct _LIBCPP_TEMPLATE_VIS owner_less<void>
3891{
3892 template <class _Tp, class _Up>
3893 _LIBCPP_INLINE_VISIBILITY
3894 bool operator()( shared_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) const _NOEXCEPT
3895 {return __x.owner_before(__y);}
3896 template <class _Tp, class _Up>
3897 _LIBCPP_INLINE_VISIBILITY
3898 bool operator()( shared_ptr<_Tp> const& __x, weak_ptr<_Up> const& __y) const _NOEXCEPT
3899 {return __x.owner_before(__y);}
3900 template <class _Tp, class _Up>
3901 _LIBCPP_INLINE_VISIBILITY
3902 bool operator()( weak_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) const _NOEXCEPT
3903 {return __x.owner_before(__y);}
3904 template <class _Tp, class _Up>
3905 _LIBCPP_INLINE_VISIBILITY
3906 bool operator()( weak_ptr<_Tp> const& __x, weak_ptr<_Up> const& __y) const _NOEXCEPT
3907 {return __x.owner_before(__y);}
3908 typedef void is_transparent;
3909};
3910#endif
3911
3912template<class _Tp>
3913class _LIBCPP_TEMPLATE_VIS enable_shared_from_this
3914{
3915 mutable weak_ptr<_Tp> __weak_this_;
3916protected:
3917 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
3918 enable_shared_from_this() _NOEXCEPT {}
3919 _LIBCPP_INLINE_VISIBILITY
3920 enable_shared_from_this(enable_shared_from_this const&) _NOEXCEPT {}
3921 _LIBCPP_INLINE_VISIBILITY
3922 enable_shared_from_this& operator=(enable_shared_from_this const&) _NOEXCEPT
3923 {return *this;}
3924 _LIBCPP_INLINE_VISIBILITY
3925 ~enable_shared_from_this() {}
3926public:
3927 _LIBCPP_INLINE_VISIBILITY
3928 shared_ptr<_Tp> shared_from_this()
3929 {return shared_ptr<_Tp>(__weak_this_);}
3930 _LIBCPP_INLINE_VISIBILITY
3931 shared_ptr<_Tp const> shared_from_this() const
3932 {return shared_ptr<const _Tp>(__weak_this_);}
3933
3934#if _LIBCPP_STD_VER > 14
3935 _LIBCPP_INLINE_VISIBILITY
3936 weak_ptr<_Tp> weak_from_this() _NOEXCEPT
3937 { return __weak_this_; }
3938
3939 _LIBCPP_INLINE_VISIBILITY
3940 weak_ptr<const _Tp> weak_from_this() const _NOEXCEPT
3941 { return __weak_this_; }
3942#endif // _LIBCPP_STD_VER > 14
3943
3944 template <class _Up> friend class shared_ptr;
3945};
3946
3947template <class _Tp>
3948struct _LIBCPP_TEMPLATE_VIS hash<shared_ptr<_Tp> >
3949{
3950 typedef shared_ptr<_Tp> argument_type;
3951 typedef size_t result_type;
3952
3953 _LIBCPP_INLINE_VISIBILITY
3954 result_type operator()(const argument_type& __ptr) const _NOEXCEPT
3955 {
3956 return hash<typename shared_ptr<_Tp>::element_type*>()(__ptr.get());
3957 }
3958};
3959
3960template<class _CharT, class _Traits, class _Yp>
3961inline _LIBCPP_INLINE_VISIBILITY
3962basic_ostream<_CharT, _Traits>&
3963operator<<(basic_ostream<_CharT, _Traits>& __os, shared_ptr<_Yp> const& __p);
3964
3965
3966#if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER)
3967
3968class _LIBCPP_TYPE_VIS __sp_mut
3969{
3970 void* __lx;
3971public:
3972 void lock() _NOEXCEPT;
3973 void unlock() _NOEXCEPT;
3974
3975private:
3976 _LIBCPP_CONSTEXPR __sp_mut(void*) _NOEXCEPT;
3977 __sp_mut(const __sp_mut&);
3978 __sp_mut& operator=(const __sp_mut&);
3979
3980 friend _LIBCPP_FUNC_VIS __sp_mut& __get_sp_mut(const void*);
3981};
3982
3983_LIBCPP_FUNC_VIS _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
3984__sp_mut& __get_sp_mut(const void*);
3985
3986template <class _Tp>
3987inline _LIBCPP_INLINE_VISIBILITY
3988bool
3989atomic_is_lock_free(const shared_ptr<_Tp>*)
3990{
3991 return false;
3992}
3993
3994template <class _Tp>
3995_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
3996shared_ptr<_Tp>
3997atomic_load(const shared_ptr<_Tp>* __p)
3998{
3999 __sp_mut& __m = __get_sp_mut(__p);
4000 __m.lock();
4001 shared_ptr<_Tp> __q = *__p;
4002 __m.unlock();
4003 return __q;
4004}
4005
4006template <class _Tp>
4007inline _LIBCPP_INLINE_VISIBILITY
4008_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
4009shared_ptr<_Tp>
4010atomic_load_explicit(const shared_ptr<_Tp>* __p, memory_order)
4011{
4012 return atomic_load(__p);
4013}
4014
4015template <class _Tp>
4016_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
4017void
4018atomic_store(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r)
4019{
4020 __sp_mut& __m = __get_sp_mut(__p);
4021 __m.lock();
4022 __p->swap(__r);
4023 __m.unlock();
4024}
4025
4026template <class _Tp>
4027inline _LIBCPP_INLINE_VISIBILITY
4028_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
4029void
4030atomic_store_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r, memory_order)
4031{
4032 atomic_store(__p, __r);
4033}
4034
4035template <class _Tp>
4036_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
4037shared_ptr<_Tp>
4038atomic_exchange(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r)
4039{
4040 __sp_mut& __m = __get_sp_mut(__p);
4041 __m.lock();
4042 __p->swap(__r);
4043 __m.unlock();
4044 return __r;
4045}
4046
4047template <class _Tp>
4048inline _LIBCPP_INLINE_VISIBILITY
4049_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
4050shared_ptr<_Tp>
4051atomic_exchange_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r, memory_order)
4052{
4053 return atomic_exchange(__p, __r);
4054}
4055
4056template <class _Tp>
4057_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
4058bool
4059atomic_compare_exchange_strong(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v, shared_ptr<_Tp> __w)
4060{
4061 shared_ptr<_Tp> __temp;
4062 __sp_mut& __m = __get_sp_mut(__p);
4063 __m.lock();
4064 if (__p->__owner_equivalent(*__v))
4065 {
4066 _VSTD::swap(__temp, *__p);
4067 *__p = __w;
4068 __m.unlock();
4069 return true;
4070 }
4071 _VSTD::swap(__temp, *__v);
4072 *__v = *__p;
4073 __m.unlock();
4074 return false;
4075}
4076
4077template <class _Tp>
4078inline _LIBCPP_INLINE_VISIBILITY
4079_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
4080bool
4081atomic_compare_exchange_weak(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v, shared_ptr<_Tp> __w)
4082{
4083 return atomic_compare_exchange_strong(__p, __v, __w);
4084}
4085
4086template <class _Tp>
4087inline _LIBCPP_INLINE_VISIBILITY
4088_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
4089bool
4090atomic_compare_exchange_strong_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v,
4091 shared_ptr<_Tp> __w, memory_order, memory_order)
4092{
4093 return atomic_compare_exchange_strong(__p, __v, __w);
4094}
4095
4096template <class _Tp>
4097inline _LIBCPP_INLINE_VISIBILITY
4098_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
4099bool
4100atomic_compare_exchange_weak_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v,
4101 shared_ptr<_Tp> __w, memory_order, memory_order)
4102{
4103 return atomic_compare_exchange_weak(__p, __v, __w);
4104}
4105
4106#endif // !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER)
4107
4108//enum class
4109#if defined(_LIBCPP_ABI_POINTER_SAFETY_ENUM_TYPE)
4110# ifndef _LIBCPP_CXX03_LANG
4111enum class pointer_safety : unsigned char {
4112 relaxed,
4113 preferred,
4114 strict
4115};
4116# endif
4117#else
4118struct _LIBCPP_TYPE_VIS pointer_safety
4119{
4120 enum __lx
4121 {
4122 relaxed,
4123 preferred,
4124 strict
4125 };
4126
4127 __lx __v_;
4128
4129 _LIBCPP_INLINE_VISIBILITY
4130 pointer_safety() : __v_() {}
4131
4132 _LIBCPP_INLINE_VISIBILITY
4133 pointer_safety(__lx __v) : __v_(__v) {}
4134 _LIBCPP_INLINE_VISIBILITY
4135 operator int() const {return __v_;}
4136};
4137#endif
4138
4139#if !defined(_LIBCPP_ABI_POINTER_SAFETY_ENUM_TYPE) && \
4140 defined(_LIBCPP_BUILDING_LIBRARY)
4141_LIBCPP_FUNC_VIS pointer_safety get_pointer_safety() _NOEXCEPT;
4142#else
4143// This function is only offered in C++03 under ABI v1.
4144# if !defined(_LIBCPP_ABI_POINTER_SAFETY_ENUM_TYPE) || !defined(_LIBCPP_CXX03_LANG)
4145inline _LIBCPP_INLINE_VISIBILITY
4146pointer_safety get_pointer_safety() _NOEXCEPT {
4147 return pointer_safety::relaxed;
4148}
4149# endif
4150#endif
4151
4152
4153_LIBCPP_FUNC_VIS void declare_reachable(void* __p);
4154_LIBCPP_FUNC_VIS void declare_no_pointers(char* __p, size_t __n);
4155_LIBCPP_FUNC_VIS void undeclare_no_pointers(char* __p, size_t __n);
4156_LIBCPP_FUNC_VIS void* __undeclare_reachable(void* __p);
4157
4158template <class _Tp>
4159inline _LIBCPP_INLINE_VISIBILITY
4160_Tp*
4161undeclare_reachable(_Tp* __p)
4162{
4163 return static_cast<_Tp*>(__undeclare_reachable(__p));
4164}
4165
4166841_LIBCPP_FUNC_VIS void* align(size_t __align, size_t __sz, void*& __ptr, size_t& __space);
4167842
4168843// --- Helper for container swap --
......@@ -4193,7 +868,7 @@ void __swap_allocator(_Alloc & __a1, _Alloc & __a2)
4193868#endif
4194869{
4195870 _VSTD::__swap_allocator(__a1, __a2,
4196 integral_constant<bool, _VSTD::allocator_traits<_Alloc>::propagate_on_container_swap::value>());
871 integral_constant<bool, allocator_traits<_Alloc>::propagate_on_container_swap::value>());
4197872}
4198873
4199874template <typename _Alloc, typename _Traits=allocator_traits<_Alloc> >
......@@ -4233,7 +908,7 @@ struct __is_allocator : false_type {};
4233908template<typename _Alloc>
4234909struct __is_allocator<_Alloc,
4235910 typename __void_t<typename _Alloc::value_type>::type,
4236 typename __void_t<decltype(_VSTD::declval<_Alloc&>().allocate(size_t(0)))>::type
911 typename __void_t<decltype(declval<_Alloc&>().allocate(size_t(0)))>::type
4237912 >
4238913 : true_type {};
4239914
......@@ -4291,4 +966,4 @@ _LIBCPP_POP_MACROS
4291966# include <__pstl_memory>
4292967#endif
4293968
4294#endif // _LIBCPP_MEMORY
969#endif // _LIBCPP_MEMORY
lib/libcxx/include/module.modulemap+277-16
......@@ -217,6 +217,102 @@ module std [system] {
217217 header "algorithm"
218218 export initializer_list
219219 export *
220
221 module __algorithm {
222 module adjacent_find { private header "__algorithm/adjacent_find.h" }
223 module all_of { private header "__algorithm/all_of.h" }
224 module any_of { private header "__algorithm/any_of.h" }
225 module binary_search { private header "__algorithm/binary_search.h" }
226 module clamp { private header "__algorithm/clamp.h" }
227 module comp { private header "__algorithm/comp.h" }
228 module comp_ref_type { private header "__algorithm/comp_ref_type.h" }
229 module copy { private header "__algorithm/copy.h" }
230 module copy_backward { private header "__algorithm/copy_backward.h" }
231 module copy_if { private header "__algorithm/copy_if.h" }
232 module copy_n { private header "__algorithm/copy_n.h" }
233 module count { private header "__algorithm/count.h" }
234 module count_if { private header "__algorithm/count_if.h" }
235 module equal { private header "__algorithm/equal.h" }
236 module equal_range { private header "__algorithm/equal_range.h" }
237 module fill { private header "__algorithm/fill.h" }
238 module fill_n { private header "__algorithm/fill_n.h" }
239 module find { private header "__algorithm/find.h" }
240 module find_end { private header "__algorithm/find_end.h" }
241 module find_first_of { private header "__algorithm/find_first_of.h" }
242 module find_if { private header "__algorithm/find_if.h" }
243 module find_if_not { private header "__algorithm/find_if_not.h" }
244 module for_each { private header "__algorithm/for_each.h" }
245 module for_each_n { private header "__algorithm/for_each_n.h" }
246 module generate { private header "__algorithm/generate.h" }
247 module generate_n { private header "__algorithm/generate_n.h" }
248 module half_positive { private header "__algorithm/half_positive.h" }
249 module includes { private header "__algorithm/includes.h" }
250 module inplace_merge { private header "__algorithm/inplace_merge.h" }
251 module is_heap { private header "__algorithm/is_heap.h" }
252 module is_heap_until { private header "__algorithm/is_heap_until.h" }
253 module is_partitioned { private header "__algorithm/is_partitioned.h" }
254 module is_permutation { private header "__algorithm/is_permutation.h" }
255 module is_sorted { private header "__algorithm/is_sorted.h" }
256 module is_sorted_until { private header "__algorithm/is_sorted_until.h" }
257 module iter_swap { private header "__algorithm/iter_swap.h" }
258 module lexicographical_compare { private header "__algorithm/lexicographical_compare.h" }
259 module lower_bound { private header "__algorithm/lower_bound.h" }
260 module make_heap { private header "__algorithm/make_heap.h" }
261 module max { private header "__algorithm/max.h" }
262 module max_element { private header "__algorithm/max_element.h" }
263 module merge { private header "__algorithm/merge.h" }
264 module min { private header "__algorithm/min.h" }
265 module min_element { private header "__algorithm/min_element.h" }
266 module minmax { private header "__algorithm/minmax.h" }
267 module minmax_element { private header "__algorithm/minmax_element.h" }
268 module mismatch { private header "__algorithm/mismatch.h" }
269 module move { private header "__algorithm/move.h" }
270 module move_backward { private header "__algorithm/move_backward.h" }
271 module next_permutation { private header "__algorithm/next_permutation.h" }
272 module none_of { private header "__algorithm/none_of.h" }
273 module nth_element { private header "__algorithm/nth_element.h" }
274 module partial_sort { private header "__algorithm/partial_sort.h" }
275 module partial_sort_copy { private header "__algorithm/partial_sort_copy.h" }
276 module partition { private header "__algorithm/partition.h" }
277 module partition_copy { private header "__algorithm/partition_copy.h" }
278 module partition_point { private header "__algorithm/partition_point.h" }
279 module pop_heap { private header "__algorithm/pop_heap.h" }
280 module prev_permutation { private header "__algorithm/prev_permutation.h" }
281 module push_heap { private header "__algorithm/push_heap.h" }
282 module remove { private header "__algorithm/remove.h" }
283 module remove_copy { private header "__algorithm/remove_copy.h" }
284 module remove_copy_if { private header "__algorithm/remove_copy_if.h" }
285 module remove_if { private header "__algorithm/remove_if.h" }
286 module replace { private header "__algorithm/replace.h" }
287 module replace_copy { private header "__algorithm/replace_copy.h" }
288 module replace_copy_if { private header "__algorithm/replace_copy_if.h" }
289 module replace_if { private header "__algorithm/replace_if.h" }
290 module reverse { private header "__algorithm/reverse.h" }
291 module reverse_copy { private header "__algorithm/reverse_copy.h" }
292 module rotate { private header "__algorithm/rotate.h" }
293 module rotate_copy { private header "__algorithm/rotate_copy.h" }
294 module sample { private header "__algorithm/sample.h" }
295 module search { private header "__algorithm/search.h" }
296 module search_n { private header "__algorithm/search_n.h" }
297 module set_difference { private header "__algorithm/set_difference.h" }
298 module set_intersection { private header "__algorithm/set_intersection.h" }
299 module set_symmetric_difference { private header "__algorithm/set_symmetric_difference.h" }
300 module set_union { private header "__algorithm/set_union.h" }
301 module shift_left { private header "__algorithm/shift_left.h" }
302 module shift_right { private header "__algorithm/shift_right.h" }
303 module shuffle { private header "__algorithm/shuffle.h" }
304 module sift_down { private header "__algorithm/sift_down.h" }
305 module sort { private header "__algorithm/sort.h" }
306 module sort_heap { private header "__algorithm/sort_heap.h" }
307 module stable_partition { private header "__algorithm/stable_partition.h" }
308 module stable_sort { private header "__algorithm/stable_sort.h" }
309 module swap_ranges { private header "__algorithm/swap_ranges.h" }
310 module transform { private header "__algorithm/transform.h" }
311 module unique { private header "__algorithm/unique.h" }
312 module unique_copy { private header "__algorithm/unique_copy.h" }
313 module unwrap_iter { private header "__algorithm/unwrap_iter.h" }
314 module upper_bound { private header "__algorithm/upper_bound.h" }
315 }
220316 }
221317 module any {
222318 header "any"
......@@ -292,6 +388,15 @@ module std [system] {
292388 header "filesystem"
293389 export *
294390 }
391 module format {
392 header "format"
393 export *
394
395 module __format {
396 module format_error { private header "__format/format_error.h" }
397 module format_parse_context { private header "__format/format_parse_context.h" }
398 }
399 }
295400 module forward_list {
296401 header "forward_list"
297402 export initializer_list
......@@ -304,6 +409,34 @@ module std [system] {
304409 module functional {
305410 header "functional"
306411 export *
412
413 module __functional {
414 module binary_function { private header "__functional/binary_function.h" }
415 module binary_negate { private header "__functional/binary_negate.h" }
416 module bind { private header "__functional/bind.h" }
417 module bind_front { private header "__functional/bind_front.h" }
418 module binder1st { private header "__functional/binder1st.h" }
419 module binder2nd { private header "__functional/binder2nd.h" }
420 module default_searcher { private header "__functional/default_searcher.h" }
421 module function { private header "__functional/function.h" }
422 module hash { private header "__functional/hash.h" }
423 module identity { private header "__functional/identity.h" }
424 module is_transparent { private header "__functional/is_transparent.h" }
425 module invoke { private header "__functional/invoke.h" }
426 module mem_fn { private header "__functional/mem_fn.h" }
427 module mem_fun_ref { private header "__functional/mem_fun_ref.h" }
428 module not_fn { private header "__functional/not_fn.h" }
429 module operations { private header "__functional/operations.h" }
430 module perfect_forward { private header "__functional/perfect_forward.h" }
431 module pointer_to_binary_function { private header "__functional/pointer_to_binary_function.h" }
432 module pointer_to_unary_function { private header "__functional/pointer_to_unary_function.h" }
433 module ranges_operations { private header "__functional/ranges_operations.h" }
434 module reference_wrapper { private header "__functional/reference_wrapper.h" }
435 module unary_function { private header "__functional/unary_function.h" }
436 module unary_negate { private header "__functional/unary_negate.h" }
437 module unwrap_ref { private header "__functional/unwrap_ref.h" }
438 module weak_result_type { private header "__functional/weak_result_type.h" }
439 }
307440 }
308441 module future {
309442 header "future"
......@@ -342,6 +475,49 @@ module std [system] {
342475 module iterator {
343476 header "iterator"
344477 export *
478
479 module __iterator {
480 module access { private header "__iterator/access.h" }
481 module advance {
482 private header "__iterator/advance.h"
483 export __function_like
484 }
485 module back_insert_iterator { private header "__iterator/back_insert_iterator.h" }
486 module common_iterator { private header "__iterator/common_iterator.h" }
487 module concepts { private header "__iterator/concepts.h" }
488 module counted_iterator { private header "__iterator/counted_iterator.h" }
489 module data { private header "__iterator/data.h" }
490 module default_sentinel { private header "__iterator/default_sentinel.h" }
491 module distance { private header "__iterator/distance.h" }
492 module empty { private header "__iterator/empty.h" }
493 module erase_if_container { private header "__iterator/erase_if_container.h" }
494 module front_insert_iterator { private header "__iterator/front_insert_iterator.h" }
495 module incrementable_traits { private header "__iterator/incrementable_traits.h" }
496 module insert_iterator { private header "__iterator/insert_iterator.h" }
497 module istream_iterator { private header "__iterator/istream_iterator.h" }
498 module istreambuf_iterator { private header "__iterator/istreambuf_iterator.h" }
499 module iter_move { private header "__iterator/iter_move.h" }
500 module iter_swap { private header "__iterator/iter_swap.h" }
501 module iterator { private header "__iterator/iterator.h" }
502 module iterator_traits { private header "__iterator/iterator_traits.h" }
503 module move_iterator { private header "__iterator/move_iterator.h" }
504 module next {
505 private header "__iterator/next.h"
506 export __function_like
507 }
508 module ostream_iterator { private header "__iterator/ostream_iterator.h" }
509 module ostreambuf_iterator { private header "__iterator/ostreambuf_iterator.h" }
510 module prev {
511 private header "__iterator/prev.h"
512 export __function_like
513 }
514 module projected { private header "__iterator/projected.h" }
515 module readable_traits { private header "__iterator/readable_traits.h" }
516 module reverse_access { private header "__iterator/reverse_access.h" }
517 module reverse_iterator { private header "__iterator/reverse_iterator.h" }
518 module size { private header "__iterator/size.h" }
519 module wrap_iter { private header "__iterator/wrap_iter.h" }
520 }
345521 }
346522 module latch {
347523 requires cplusplus14
......@@ -369,6 +545,25 @@ module std [system] {
369545 module memory {
370546 header "memory"
371547 export *
548
549 module __memory {
550 module addressof { private header "__memory/addressof.h" }
551 module allocation_guard { private header "__memory/allocation_guard.h" }
552 module allocator { private header "__memory/allocator.h" }
553 module allocator_arg_t { private header "__memory/allocator_arg_t.h" }
554 module allocator_traits { private header "__memory/allocator_traits.h" }
555 module auto_ptr { private header "__memory/auto_ptr.h" }
556 module compressed_pair { private header "__memory/compressed_pair.h" }
557 module construct_at { private header "__memory/construct_at.h" }
558 module pointer_safety { private header "__memory/pointer_safety.h" }
559 module pointer_traits { private header "__memory/pointer_traits.h" }
560 module raw_storage_iterator { private header "__memory/raw_storage_iterator.h" }
561 module shared_ptr { private header "__memory/shared_ptr.h" }
562 module temporary_buffer { private header "__memory/temporary_buffer.h" }
563 module uninitialized_algorithms { private header "__memory/uninitialized_algorithms.h" }
564 module unique_ptr { private header "__memory/unique_ptr.h" }
565 module uses_allocator { private header "__memory/uses_allocator.h" }
566 }
372567 }
373568 module mutex {
374569 header "mutex"
......@@ -404,6 +599,38 @@ module std [system] {
404599 header "random"
405600 export initializer_list
406601 export *
602
603 module __random {
604 module uniform_int_distribution { private header "__random/uniform_int_distribution.h" }
605 }
606 }
607 module ranges {
608 header "ranges"
609 export compare
610 export initializer_list
611 export iterator
612 export *
613
614 module __ranges {
615 module access { private header "__ranges/access.h" }
616 module all { private header "__ranges/all.h" }
617 module common_view { private header "__ranges/common_view.h" }
618 module concepts { private header "__ranges/concepts.h" }
619 module copyable_box { private header "__ranges/copyable_box.h" }
620 module dangling { private header "__ranges/dangling.h" }
621 module data { private header "__ranges/data.h" }
622 module drop_view { private header "__ranges/drop_view.h" }
623 module empty { private header "__ranges/empty.h" }
624 module empty_view { private header "__ranges/empty_view.h" }
625 module enable_borrowed_range { private header "__ranges/enable_borrowed_range.h" }
626 module enable_view { private header "__ranges/enable_view.h" }
627 module non_propagating_cache { private header "__ranges/non_propagating_cache.h" }
628 module ref_view { private header "__ranges/ref_view.h" }
629 module size { private header "__ranges/size.h" }
630 module subrange { private header "__ranges/subrange.h" }
631 module transform_view { private header "__ranges/transform_view.h" }
632 module view_interface { private header "__ranges/view_interface.h" }
633 }
407634 }
408635 module ratio {
409636 header "ratio"
......@@ -428,6 +655,15 @@ module std [system] {
428655 export initializer_list
429656 export *
430657 }
658 module shared_mutex {
659 header "shared_mutex"
660 export version
661 }
662 module span {
663 header "span"
664 export ranges.__ranges.enable_borrowed_range
665 export version
666 }
431667 module sstream {
432668 header "sstream"
433669 // FIXME: should re-export istream, ostream, ios, streambuf, string?
......@@ -477,6 +713,7 @@ module std [system] {
477713 }
478714 module type_traits {
479715 header "type_traits"
716 export functional.__functional.unwrap_ref
480717 export *
481718 }
482719 module typeindex {
......@@ -501,6 +738,23 @@ module std [system] {
501738 header "utility"
502739 export initializer_list
503740 export *
741
742 module __utility {
743 module __decay_copy { private header "__utility/__decay_copy.h" }
744 module as_const { private header "__utility/as_const.h" }
745 module cmp { private header "__utility/cmp.h" }
746 module declval { private header "__utility/declval.h" }
747 module exchange { private header "__utility/exchange.h" }
748 module forward { private header "__utility/forward.h" }
749 module in_place { private header "__utility/in_place.h" }
750 module integer_sequence { private header "__utility/integer_sequence.h" }
751 module move { private header "__utility/move.h" }
752 module pair { private header "__utility/pair.h" }
753 module piecewise_construct { private header "__utility/piecewise_construct.h" }
754 module rel_ops { private header "__utility/rel_ops.h" }
755 module swap { private header "__utility/swap.h" }
756 module to_underlying { private header "__utility/to_underlying.h" }
757 }
504758 }
505759 module valarray {
506760 header "valarray"
......@@ -510,6 +764,10 @@ module std [system] {
510764 module variant {
511765 header "variant"
512766 export *
767
768 module __variant {
769 module monostate { private header "__variant/monostate.h" }
770 }
513771 }
514772 module vector {
515773 header "vector"
......@@ -521,23 +779,26 @@ module std [system] {
521779 export *
522780 }
523781
782 // __config not modularised due to a bug in Clang
524783 // FIXME: These should be private.
525 module __bits { header "__bits" export * }
526 module __bit_reference { header "__bit_reference" export * }
527 module __debug { header "__debug" export * }
528 module __errc { header "__errc" export * }
529 module __functional_base { header "__functional_base" export * }
530 module __hash_table { header "__hash_table" export * }
531 module __locale { header "__locale" export * }
532 module __mutex_base { header "__mutex_base" export * }
533 module __split_buffer { header "__split_buffer" export * }
534 module __sso_allocator { header "__sso_allocator" export * }
535 module __std_stream { header "__std_stream" export * }
536 module __string { header "__string" export * }
537 module __tree { header "__tree" export * }
538 module __tuple { header "__tuple" export * }
539 module __undef_macros { header "__undef_macros" export * }
540 module __node_handle { header "__node_handle" export * }
784 module __availability { private header "__availability" export * }
785 module __bit_reference { private header "__bit_reference" export * }
786 module __bits { private header "__bits" export * }
787 module __debug { header "__debug" export * }
788 module __errc { private header "__errc" export * }
789 module __function_like { private header "__function_like.h" export * }
790 module __hash_table { header "__hash_table" export * }
791 module __locale { private header "__locale" export * }
792 module __mutex_base { private header "__mutex_base" export * }
793 module __node_handle { private header "__node_handle" export * }
794 module __nullptr { header "__nullptr" export * }
795 module __split_buffer { private header "__split_buffer" export * }
796 module __std_stream { private header "__std_stream" export * }
797 module __string { private header "__string" export * }
798 module __threading_support { header "__threading_support" export * }
799 module __tree { header "__tree" export * }
800 module __tuple { private header "__tuple" export * }
801 module __undef_macros { header "__undef_macros" export * }
541802
542803 module experimental {
543804 requires cplusplus11
lib/libcxx/include/mutex+9-8
......@@ -188,14 +188,15 @@ template<class Callable, class ...Args>
188188
189189#include <__config>
190190#include <__mutex_base>
191#include <__threading_support>
192#include <__utility/forward.h>
191193#include <cstdint>
192194#include <functional>
193195#include <memory>
194196#ifndef _LIBCPP_CXX03_LANG
195#include <tuple>
197# include <tuple>
196198#endif
197199#include <version>
198#include <__threading_support>
199200
200201#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
201202#pragma GCC system_header
......@@ -365,7 +366,7 @@ try_lock(_L0& __l0, _L1& __l1, _L2& __l2, _L3&... __l3)
365366 return __r;
366367}
367368
368#endif // _LIBCPP_CXX03_LANG
369#endif // _LIBCPP_CXX03_LANG
369370
370371template <class _L0, class _L1>
371372void
......@@ -469,7 +470,7 @@ void __unlock(_L0& __l0, _L1& __l1, _L2& __l2, _L3&... __l3) {
469470 _VSTD::__unlock(__l2, __l3...);
470471}
471472
472#endif // _LIBCPP_CXX03_LANG
473#endif // _LIBCPP_CXX03_LANG
473474
474475#if _LIBCPP_STD_VER > 14
475476template <class ..._Mutexes>
......@@ -568,7 +569,7 @@ template<class _Callable>
568569_LIBCPP_INLINE_VISIBILITY
569570void call_once(once_flag&, const _Callable&);
570571
571#endif // _LIBCPP_CXX03_LANG
572#endif // _LIBCPP_CXX03_LANG
572573
573574struct _LIBCPP_TEMPLATE_VIS once_flag
574575{
......@@ -601,7 +602,7 @@ private:
601602 template<class _Callable>
602603 friend
603604 void call_once(once_flag&, const _Callable&);
604#endif // _LIBCPP_CXX03_LANG
605#endif // _LIBCPP_CXX03_LANG
605606};
606607
607608#ifndef _LIBCPP_CXX03_LANG
......@@ -702,10 +703,10 @@ call_once(once_flag& __flag, const _Callable& __func)
702703 }
703704}
704705
705#endif // _LIBCPP_CXX03_LANG
706#endif // _LIBCPP_CXX03_LANG
706707
707708_LIBCPP_END_NAMESPACE_STD
708709
709710_LIBCPP_POP_MACROS
710711
711#endif // _LIBCPP_MUTEX
712#endif // _LIBCPP_MUTEX
lib/libcxx/include/new+3-3
......@@ -86,8 +86,8 @@ void operator delete[](void* ptr, void*) noexcept;
8686
8787*/
8888
89#include <__config>
9089#include <__availability>
90#include <__config>
9191#include <cstddef>
9292#include <cstdlib>
9393#include <exception>
......@@ -314,7 +314,7 @@ void* __libcpp_aligned_alloc(std::size_t __alignment, std::size_t __size) {
314314 return ::_aligned_malloc(__size, __alignment);
315315#else
316316 void* __result = nullptr;
317 ::posix_memalign(&__result, __alignment, __size);
317 (void)::posix_memalign(&__result, __alignment, __size);
318318 // If posix_memalign fails, __result is unmodified so we still return `nullptr`.
319319 return __result;
320320#endif
......@@ -356,4 +356,4 @@ constexpr _Tp* launder(_Tp* __p) noexcept
356356
357357_LIBCPP_END_NAMESPACE_STD
358358
359#endif // _LIBCPP_NEW
359#endif // _LIBCPP_NEW
lib/libcxx/include/numbers+17-20
......@@ -59,12 +59,12 @@ namespace std::numbers {
5959*/
6060
6161#include <__config>
62
63#if _LIBCPP_STD_VER > 17 && defined(__cpp_concepts) && __cpp_concepts >= 201811L
64
62#include <concepts>
6563#include <type_traits>
6664#include <version>
6765
66#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
67
6868#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
6969#pragma GCC system_header
7070#endif
......@@ -99,22 +99,19 @@ template <class T> inline constexpr T inv_sqrt3_v = __illformed<T>{};
9999template <class T> inline constexpr T egamma_v = __illformed<T>{};
100100template <class T> inline constexpr T phi_v = __illformed<T>{};
101101
102template <class T>
103concept __floating_point = is_floating_point_v<T>;
104
105template <__floating_point T> inline constexpr T e_v<T> = 2.718281828459045235360287471352662;
106template <__floating_point T> inline constexpr T log2e_v<T> = 1.442695040888963407359924681001892;
107template <__floating_point T> inline constexpr T log10e_v<T> = 0.434294481903251827651128918916605;
108template <__floating_point T> inline constexpr T pi_v<T> = 3.141592653589793238462643383279502;
109template <__floating_point T> inline constexpr T inv_pi_v<T> = 0.318309886183790671537767526745028;
110template <__floating_point T> inline constexpr T inv_sqrtpi_v<T> = 0.564189583547756286948079451560772;
111template <__floating_point T> inline constexpr T ln2_v<T> = 0.693147180559945309417232121458176;
112template <__floating_point T> inline constexpr T ln10_v<T> = 2.302585092994045684017991454684364;
113template <__floating_point T> inline constexpr T sqrt2_v<T> = 1.414213562373095048801688724209698;
114template <__floating_point T> inline constexpr T sqrt3_v<T> = 1.732050807568877293527446341505872;
115template <__floating_point T> inline constexpr T inv_sqrt3_v<T> = 0.577350269189625764509148780501957;
116template <__floating_point T> inline constexpr T egamma_v<T> = 0.577215664901532860606512090082402;
117template <__floating_point T> inline constexpr T phi_v<T> = 1.618033988749894848204586834365638;
102template <floating_point T> inline constexpr T e_v<T> = 2.718281828459045235360287471352662;
103template <floating_point T> inline constexpr T log2e_v<T> = 1.442695040888963407359924681001892;
104template <floating_point T> inline constexpr T log10e_v<T> = 0.434294481903251827651128918916605;
105template <floating_point T> inline constexpr T pi_v<T> = 3.141592653589793238462643383279502;
106template <floating_point T> inline constexpr T inv_pi_v<T> = 0.318309886183790671537767526745028;
107template <floating_point T> inline constexpr T inv_sqrtpi_v<T> = 0.564189583547756286948079451560772;
108template <floating_point T> inline constexpr T ln2_v<T> = 0.693147180559945309417232121458176;
109template <floating_point T> inline constexpr T ln10_v<T> = 2.302585092994045684017991454684364;
110template <floating_point T> inline constexpr T sqrt2_v<T> = 1.414213562373095048801688724209698;
111template <floating_point T> inline constexpr T sqrt3_v<T> = 1.732050807568877293527446341505872;
112template <floating_point T> inline constexpr T inv_sqrt3_v<T> = 0.577350269189625764509148780501957;
113template <floating_point T> inline constexpr T egamma_v<T> = 0.577215664901532860606512090082402;
114template <floating_point T> inline constexpr T phi_v<T> = 1.618033988749894848204586834365638;
118115
119116inline constexpr double e = e_v<double>;
120117inline constexpr double log2e = log2e_v<double>;
......@@ -136,6 +133,6 @@ _LIBCPP_END_NAMESPACE_STD
136133
137134_LIBCPP_POP_MACROS
138135
139#endif //_LIBCPP_STD_VER > 17 && defined(__cpp_concepts) && __cpp_concepts >= 201811L
136#endif //_LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
140137
141138#endif // _LIBCPP_NUMBERS
lib/libcxx/include/numeric+6-5
......@@ -145,10 +145,11 @@ template<class T>
145145*/
146146
147147#include <__config>
148#include <__debug>
149#include <cmath> // for isnormal
150#include <functional>
148151#include <iterator>
149152#include <limits> // for numeric_limits
150#include <functional>
151#include <cmath> // for isnormal
152153#include <version>
153154
154155#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
......@@ -613,8 +614,8 @@ _LIBCPP_INLINE_VISIBILITY constexpr
613614enable_if_t<is_floating_point_v<_Fp>, _Fp>
614615midpoint(_Fp __a, _Fp __b) noexcept
615616{
616 constexpr _Fp __lo = numeric_limits<_Fp>::min()*2;
617 constexpr _Fp __hi = numeric_limits<_Fp>::max()/2;
617 constexpr _Fp __lo = numeric_limits<_Fp>::min()*2;
618 constexpr _Fp __hi = numeric_limits<_Fp>::max()/2;
618619 return __fp_abs(__a) <= __hi && __fp_abs(__b) <= __hi ? // typical case: overflow is impossible
619620 (__a + __b)/2 : // always correctly rounded
620621 __fp_abs(__a) < __lo ? __a + __b/2 : // not safe to halve a
......@@ -632,4 +633,4 @@ _LIBCPP_POP_MACROS
632633# include <__pstl_numeric>
633634#endif
634635
635#endif // _LIBCPP_NUMERIC
636#endif // _LIBCPP_NUMERIC
lib/libcxx/include/optional+100-93
......@@ -69,7 +69,7 @@ namespace std {
6969 template <class T, class U> constexpr bool operator>=(const T&, const optional<U>&);
7070
7171 // 23.6.9, specialized algorithms
72 template <class T> void swap(optional<T>&, optional<T>&) noexcept(see below );
72 template <class T> void swap(optional<T>&, optional<T>&) noexcept(see below ); // constexpr in C++20
7373 template <class T> constexpr optional<see below > make_optional(T&&);
7474 template <class T, class... Args>
7575 constexpr optional<T> make_optional(Args&&... args);
......@@ -95,26 +95,26 @@ namespace std {
9595 template <class U = T>
9696 constexpr EXPLICIT optional(U &&);
9797 template <class U>
98 constexpr EXPLICIT optional(const optional<U> &);
98 EXPLICIT optional(const optional<U> &); // constexpr in C++20
9999 template <class U>
100 constexpr EXPLICIT optional(optional<U> &&);
100 EXPLICIT optional(optional<U> &&); // constexpr in C++20
101101
102102 // 23.6.3.2, destructor
103 ~optional();
103 ~optional(); // constexpr in C++20
104104
105105 // 23.6.3.3, assignment
106 optional &operator=(nullopt_t) noexcept;
107 optional &operator=(const optional &); // constexpr in C++20
108 optional &operator=(optional &&) noexcept(see below); // constexpr in C++20
109 template <class U = T> optional &operator=(U &&);
110 template <class U> optional &operator=(const optional<U> &);
111 template <class U> optional &operator=(optional<U> &&);
112 template <class... Args> T& emplace(Args &&...);
106 optional &operator=(nullopt_t) noexcept; // constexpr in C++20
107 optional &operator=(const optional &); // constexpr in C++20
108 optional &operator=(optional &&) noexcept(see below); // constexpr in C++20
109 template <class U = T> optional &operator=(U &&); // constexpr in C++20
110 template <class U> optional &operator=(const optional<U> &); // constexpr in C++20
111 template <class U> optional &operator=(optional<U> &&); // constexpr in C++20
112 template <class... Args> T& emplace(Args &&...); // constexpr in C++20
113113 template <class U, class... Args>
114 T& emplace(initializer_list<U>, Args &&...);
114 T& emplace(initializer_list<U>, Args &&...); // constexpr in C++20
115115
116116 // 23.6.3.4, swap
117 void swap(optional &) noexcept(see below );
117 void swap(optional &) noexcept(see below ); // constexpr in C++20
118118
119119 // 23.6.3.5, observers
120120 constexpr T const *operator->() const;
......@@ -133,7 +133,7 @@ namespace std {
133133 template <class U> constexpr T value_or(U &&) &&;
134134
135135 // 23.6.3.6, modifiers
136 void reset() noexcept;
136 void reset() noexcept; // constexpr in C++20
137137
138138 private:
139139 T *val; // exposition only
......@@ -146,10 +146,11 @@ template<class T>
146146
147147*/
148148
149#include <__config>
150149#include <__availability>
150#include <__config>
151151#include <__debug>
152152#include <__functional_base>
153#include <compare>
153154#include <functional>
154155#include <initializer_list>
155156#include <new>
......@@ -220,7 +221,7 @@ struct __optional_destruct_base<_Tp, false>
220221 bool __engaged_;
221222
222223 _LIBCPP_INLINE_VISIBILITY
223 ~__optional_destruct_base()
224 _LIBCPP_CONSTEXPR_AFTER_CXX17 ~__optional_destruct_base()
224225 {
225226 if (__engaged_)
226227 __val_.~value_type();
......@@ -238,7 +239,7 @@ struct __optional_destruct_base<_Tp, false>
238239 __engaged_(true) {}
239240
240241 _LIBCPP_INLINE_VISIBILITY
241 void reset() noexcept
242 _LIBCPP_CONSTEXPR_AFTER_CXX17 void reset() noexcept
242243 {
243244 if (__engaged_)
244245 {
......@@ -273,7 +274,7 @@ struct __optional_destruct_base<_Tp, true>
273274 __engaged_(true) {}
274275
275276 _LIBCPP_INLINE_VISIBILITY
276 void reset() noexcept
277 _LIBCPP_CONSTEXPR_AFTER_CXX17 void reset() noexcept
277278 {
278279 if (__engaged_)
279280 {
......@@ -318,16 +319,20 @@ struct __optional_storage_base : __optional_destruct_base<_Tp>
318319
319320 template <class... _Args>
320321 _LIBCPP_INLINE_VISIBILITY
321 void __construct(_Args&&... __args)
322 _LIBCPP_CONSTEXPR_AFTER_CXX17 void __construct(_Args&&... __args)
322323 {
323324 _LIBCPP_ASSERT(!has_value(), "__construct called for engaged __optional_storage");
325#if _LIBCPP_STD_VER > 17
326 _VSTD::construct_at(_VSTD::addressof(this->__val_), _VSTD::forward<_Args>(__args)...);
327#else
324328 ::new ((void*)_VSTD::addressof(this->__val_)) value_type(_VSTD::forward<_Args>(__args)...);
329#endif
325330 this->__engaged_ = true;
326331 }
327332
328333 template <class _That>
329334 _LIBCPP_INLINE_VISIBILITY
330 void __construct_from(_That&& __opt)
335 _LIBCPP_CONSTEXPR_AFTER_CXX17 void __construct_from(_That&& __opt)
331336 {
332337 if (__opt.has_value())
333338 __construct(_VSTD::forward<_That>(__opt).__get());
......@@ -335,7 +340,7 @@ struct __optional_storage_base : __optional_destruct_base<_Tp>
335340
336341 template <class _That>
337342 _LIBCPP_INLINE_VISIBILITY
338 void __assign_from(_That&& __opt)
343 _LIBCPP_CONSTEXPR_AFTER_CXX17 void __assign_from(_That&& __opt)
339344 {
340345 if (this->__engaged_ == __opt.has_value())
341346 {
......@@ -393,7 +398,7 @@ struct __optional_storage_base<_Tp, true>
393398 }
394399
395400 _LIBCPP_INLINE_VISIBILITY
396 void reset() noexcept { __value_ = nullptr; }
401 _LIBCPP_CONSTEXPR_AFTER_CXX17 void reset() noexcept { __value_ = nullptr; }
397402
398403 _LIBCPP_INLINE_VISIBILITY
399404 constexpr bool has_value() const noexcept
......@@ -409,7 +414,7 @@ struct __optional_storage_base<_Tp, true>
409414
410415 template <class _UArg>
411416 _LIBCPP_INLINE_VISIBILITY
412 void __construct(_UArg&& __val)
417 _LIBCPP_CONSTEXPR_AFTER_CXX17 void __construct(_UArg&& __val)
413418 {
414419 _LIBCPP_ASSERT(!has_value(), "__construct called for engaged __optional_storage");
415420 static_assert(__can_bind_reference<_UArg>(),
......@@ -420,7 +425,7 @@ struct __optional_storage_base<_Tp, true>
420425
421426 template <class _That>
422427 _LIBCPP_INLINE_VISIBILITY
423 void __construct_from(_That&& __opt)
428 _LIBCPP_CONSTEXPR_AFTER_CXX17 void __construct_from(_That&& __opt)
424429 {
425430 if (__opt.has_value())
426431 __construct(_VSTD::forward<_That>(__opt).__get());
......@@ -428,7 +433,7 @@ struct __optional_storage_base<_Tp, true>
428433
429434 template <class _That>
430435 _LIBCPP_INLINE_VISIBILITY
431 void __assign_from(_That&& __opt)
436 _LIBCPP_CONSTEXPR_AFTER_CXX17 void __assign_from(_That&& __opt)
432437 {
433438 if (has_value() == __opt.has_value())
434439 {
......@@ -460,7 +465,7 @@ struct __optional_copy_base<_Tp, false> : __optional_storage_base<_Tp>
460465 __optional_copy_base() = default;
461466
462467 _LIBCPP_INLINE_VISIBILITY
463 __optional_copy_base(const __optional_copy_base& __opt)
468 _LIBCPP_CONSTEXPR_AFTER_CXX17 __optional_copy_base(const __optional_copy_base& __opt)
464469 {
465470 this->__construct_from(__opt);
466471 }
......@@ -491,7 +496,7 @@ struct __optional_move_base<_Tp, false> : __optional_copy_base<_Tp>
491496 __optional_move_base(const __optional_move_base&) = default;
492497
493498 _LIBCPP_INLINE_VISIBILITY
494 __optional_move_base(__optional_move_base&& __opt)
499 _LIBCPP_CONSTEXPR_AFTER_CXX17 __optional_move_base(__optional_move_base&& __opt)
495500 noexcept(is_nothrow_move_constructible_v<value_type>)
496501 {
497502 this->__construct_from(_VSTD::move(__opt));
......@@ -525,7 +530,7 @@ struct __optional_copy_assign_base<_Tp, false> : __optional_move_base<_Tp>
525530 __optional_copy_assign_base(__optional_copy_assign_base&&) = default;
526531
527532 _LIBCPP_INLINE_VISIBILITY
528 __optional_copy_assign_base& operator=(const __optional_copy_assign_base& __opt)
533 _LIBCPP_CONSTEXPR_AFTER_CXX17 __optional_copy_assign_base& operator=(const __optional_copy_assign_base& __opt)
529534 {
530535 this->__assign_from(__opt);
531536 return *this;
......@@ -560,7 +565,7 @@ struct __optional_move_assign_base<_Tp, false> : __optional_copy_assign_base<_Tp
560565 __optional_move_assign_base& operator=(const __optional_move_assign_base&) = default;
561566
562567 _LIBCPP_INLINE_VISIBILITY
563 __optional_move_assign_base& operator=(__optional_move_assign_base&& __opt)
568 _LIBCPP_CONSTEXPR_AFTER_CXX17 __optional_move_assign_base& operator=(__optional_move_assign_base&& __opt)
564569 noexcept(is_nothrow_move_assignable_v<value_type> &&
565570 is_nothrow_move_constructible_v<value_type>)
566571 {
......@@ -727,7 +732,7 @@ public:
727732 _CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_implicit<_Up>()
728733 , int> = 0>
729734 _LIBCPP_INLINE_VISIBILITY
730 optional(const optional<_Up>& __v)
735 _LIBCPP_CONSTEXPR_AFTER_CXX17 optional(const optional<_Up>& __v)
731736 {
732737 this->__construct_from(__v);
733738 }
......@@ -735,7 +740,7 @@ public:
735740 _CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_explicit<_Up>()
736741 , int> = 0>
737742 _LIBCPP_INLINE_VISIBILITY
738 explicit optional(const optional<_Up>& __v)
743 _LIBCPP_CONSTEXPR_AFTER_CXX17 explicit optional(const optional<_Up>& __v)
739744 {
740745 this->__construct_from(__v);
741746 }
......@@ -745,7 +750,7 @@ public:
745750 _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_implicit<_Up>()
746751 , int> = 0>
747752 _LIBCPP_INLINE_VISIBILITY
748 optional(optional<_Up>&& __v)
753 _LIBCPP_CONSTEXPR_AFTER_CXX17 optional(optional<_Up>&& __v)
749754 {
750755 this->__construct_from(_VSTD::move(__v));
751756 }
......@@ -753,13 +758,13 @@ public:
753758 _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_explicit<_Up>()
754759 , int> = 0>
755760 _LIBCPP_INLINE_VISIBILITY
756 explicit optional(optional<_Up>&& __v)
761 _LIBCPP_CONSTEXPR_AFTER_CXX17 explicit optional(optional<_Up>&& __v)
757762 {
758763 this->__construct_from(_VSTD::move(__v));
759764 }
760765
761766 _LIBCPP_INLINE_VISIBILITY
762 optional& operator=(nullopt_t) noexcept
767 _LIBCPP_CONSTEXPR_AFTER_CXX17 optional& operator=(nullopt_t) noexcept
763768 {
764769 reset();
765770 return *this;
......@@ -782,7 +787,7 @@ public:
782787 >::value>
783788 >
784789 _LIBCPP_INLINE_VISIBILITY
785 optional&
790 _LIBCPP_CONSTEXPR_AFTER_CXX17 optional&
786791 operator=(_Up&& __v)
787792 {
788793 if (this->has_value())
......@@ -797,7 +802,7 @@ public:
797802 _CheckOptionalLikeAssign<_Up, _Up const&>::template __enable_assign<_Up>()
798803 , int> = 0>
799804 _LIBCPP_INLINE_VISIBILITY
800 optional&
805 _LIBCPP_CONSTEXPR_AFTER_CXX17 optional&
801806 operator=(const optional<_Up>& __v)
802807 {
803808 this->__assign_from(__v);
......@@ -809,7 +814,7 @@ public:
809814 _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_assign<_Up>()
810815 , int> = 0>
811816 _LIBCPP_INLINE_VISIBILITY
812 optional&
817 _LIBCPP_CONSTEXPR_AFTER_CXX17 optional&
813818 operator=(optional<_Up>&& __v)
814819 {
815820 this->__assign_from(_VSTD::move(__v));
......@@ -823,7 +828,7 @@ public:
823828 >
824829 >
825830 _LIBCPP_INLINE_VISIBILITY
826 _Tp &
831 _LIBCPP_CONSTEXPR_AFTER_CXX17 _Tp &
827832 emplace(_Args&&... __args)
828833 {
829834 reset();
......@@ -838,7 +843,7 @@ public:
838843 >
839844 >
840845 _LIBCPP_INLINE_VISIBILITY
841 _Tp &
846 _LIBCPP_CONSTEXPR_AFTER_CXX17 _Tp &
842847 emplace(initializer_list<_Up> __il, _Args&&... __args)
843848 {
844849 reset();
......@@ -847,7 +852,7 @@ public:
847852 }
848853
849854 _LIBCPP_INLINE_VISIBILITY
850 void swap(optional& __opt)
855 _LIBCPP_CONSTEXPR_AFTER_CXX17 void swap(optional& __opt)
851856 noexcept(is_nothrow_move_constructible_v<value_type> &&
852857 is_nothrow_swappable_v<value_type>)
853858 {
......@@ -877,7 +882,7 @@ public:
877882 add_pointer_t<value_type const>
878883 operator->() const
879884 {
880 _LIBCPP_ASSERT(this->has_value(), "optional operator-> called for disengaged value");
885 _LIBCPP_ASSERT(this->has_value(), "optional operator-> called on a disengaged value");
881886#ifndef _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF
882887 return _VSTD::addressof(this->__get());
883888#else
......@@ -890,7 +895,7 @@ public:
890895 add_pointer_t<value_type>
891896 operator->()
892897 {
893 _LIBCPP_ASSERT(this->has_value(), "optional operator-> called for disengaged value");
898 _LIBCPP_ASSERT(this->has_value(), "optional operator-> called on a disengaged value");
894899#ifndef _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF
895900 return _VSTD::addressof(this->__get());
896901#else
......@@ -901,36 +906,36 @@ public:
901906 _LIBCPP_INLINE_VISIBILITY
902907 constexpr
903908 const value_type&
904 operator*() const&
909 operator*() const& noexcept
905910 {
906 _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value");
911 _LIBCPP_ASSERT(this->has_value(), "optional operator* called on a disengaged value");
907912 return this->__get();
908913 }
909914
910915 _LIBCPP_INLINE_VISIBILITY
911916 constexpr
912917 value_type&
913 operator*() &
918 operator*() & noexcept
914919 {
915 _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value");
920 _LIBCPP_ASSERT(this->has_value(), "optional operator* called on a disengaged value");
916921 return this->__get();
917922 }
918923
919924 _LIBCPP_INLINE_VISIBILITY
920925 constexpr
921926 value_type&&
922 operator*() &&
927 operator*() && noexcept
923928 {
924 _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value");
929 _LIBCPP_ASSERT(this->has_value(), "optional operator* called on a disengaged value");
925930 return _VSTD::move(this->__get());
926931 }
927932
928933 _LIBCPP_INLINE_VISIBILITY
929934 constexpr
930935 const value_type&&
931 operator*() const&&
936 operator*() const&& noexcept
932937 {
933 _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value");
938 _LIBCPP_ASSERT(this->has_value(), "optional operator* called on a disengaged value");
934939 return _VSTD::move(this->__get());
935940 }
936941
......@@ -1005,7 +1010,7 @@ public:
10051010private:
10061011 template <class _Up>
10071012 _LIBCPP_INLINE_VISIBILITY
1008 static _Up*
1013 static _LIBCPP_CONSTEXPR_AFTER_CXX17 _Up*
10091014 __operator_arrow(true_type, _Up& __x)
10101015 {
10111016 return _VSTD::addressof(__x);
......@@ -1029,8 +1034,8 @@ template<class T>
10291034template <class _Tp, class _Up>
10301035_LIBCPP_INLINE_VISIBILITY constexpr
10311036_EnableIf<
1032 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() ==
1033 _VSTD::declval<const _Up&>()), bool>,
1037 is_convertible_v<decltype(declval<const _Tp&>() ==
1038 declval<const _Up&>()), bool>,
10341039 bool
10351040>
10361041operator==(const optional<_Tp>& __x, const optional<_Up>& __y)
......@@ -1045,8 +1050,8 @@ operator==(const optional<_Tp>& __x, const optional<_Up>& __y)
10451050template <class _Tp, class _Up>
10461051_LIBCPP_INLINE_VISIBILITY constexpr
10471052_EnableIf<
1048 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() !=
1049 _VSTD::declval<const _Up&>()), bool>,
1053 is_convertible_v<decltype(declval<const _Tp&>() !=
1054 declval<const _Up&>()), bool>,
10501055 bool
10511056>
10521057operator!=(const optional<_Tp>& __x, const optional<_Up>& __y)
......@@ -1061,8 +1066,8 @@ operator!=(const optional<_Tp>& __x, const optional<_Up>& __y)
10611066template <class _Tp, class _Up>
10621067_LIBCPP_INLINE_VISIBILITY constexpr
10631068_EnableIf<
1064 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <
1065 _VSTD::declval<const _Up&>()), bool>,
1069 is_convertible_v<decltype(declval<const _Tp&>() <
1070 declval<const _Up&>()), bool>,
10661071 bool
10671072>
10681073operator<(const optional<_Tp>& __x, const optional<_Up>& __y)
......@@ -1077,8 +1082,8 @@ operator<(const optional<_Tp>& __x, const optional<_Up>& __y)
10771082template <class _Tp, class _Up>
10781083_LIBCPP_INLINE_VISIBILITY constexpr
10791084_EnableIf<
1080 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >
1081 _VSTD::declval<const _Up&>()), bool>,
1085 is_convertible_v<decltype(declval<const _Tp&>() >
1086 declval<const _Up&>()), bool>,
10821087 bool
10831088>
10841089operator>(const optional<_Tp>& __x, const optional<_Up>& __y)
......@@ -1093,8 +1098,8 @@ operator>(const optional<_Tp>& __x, const optional<_Up>& __y)
10931098template <class _Tp, class _Up>
10941099_LIBCPP_INLINE_VISIBILITY constexpr
10951100_EnableIf<
1096 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <=
1097 _VSTD::declval<const _Up&>()), bool>,
1101 is_convertible_v<decltype(declval<const _Tp&>() <=
1102 declval<const _Up&>()), bool>,
10981103 bool
10991104>
11001105operator<=(const optional<_Tp>& __x, const optional<_Up>& __y)
......@@ -1109,8 +1114,8 @@ operator<=(const optional<_Tp>& __x, const optional<_Up>& __y)
11091114template <class _Tp, class _Up>
11101115_LIBCPP_INLINE_VISIBILITY constexpr
11111116_EnableIf<
1112 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >=
1113 _VSTD::declval<const _Up&>()), bool>,
1117 is_convertible_v<decltype(declval<const _Tp&>() >=
1118 declval<const _Up&>()), bool>,
11141119 bool
11151120>
11161121operator>=(const optional<_Tp>& __x, const optional<_Up>& __y)
......@@ -1223,8 +1228,8 @@ operator>=(nullopt_t, const optional<_Tp>& __x) noexcept
12231228template <class _Tp, class _Up>
12241229_LIBCPP_INLINE_VISIBILITY constexpr
12251230_EnableIf<
1226 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() ==
1227 _VSTD::declval<const _Up&>()), bool>,
1231 is_convertible_v<decltype(declval<const _Tp&>() ==
1232 declval<const _Up&>()), bool>,
12281233 bool
12291234>
12301235operator==(const optional<_Tp>& __x, const _Up& __v)
......@@ -1235,8 +1240,8 @@ operator==(const optional<_Tp>& __x, const _Up& __v)
12351240template <class _Tp, class _Up>
12361241_LIBCPP_INLINE_VISIBILITY constexpr
12371242_EnableIf<
1238 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() ==
1239 _VSTD::declval<const _Up&>()), bool>,
1243 is_convertible_v<decltype(declval<const _Tp&>() ==
1244 declval<const _Up&>()), bool>,
12401245 bool
12411246>
12421247operator==(const _Tp& __v, const optional<_Up>& __x)
......@@ -1247,8 +1252,8 @@ operator==(const _Tp& __v, const optional<_Up>& __x)
12471252template <class _Tp, class _Up>
12481253_LIBCPP_INLINE_VISIBILITY constexpr
12491254_EnableIf<
1250 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() !=
1251 _VSTD::declval<const _Up&>()), bool>,
1255 is_convertible_v<decltype(declval<const _Tp&>() !=
1256 declval<const _Up&>()), bool>,
12521257 bool
12531258>
12541259operator!=(const optional<_Tp>& __x, const _Up& __v)
......@@ -1259,8 +1264,8 @@ operator!=(const optional<_Tp>& __x, const _Up& __v)
12591264template <class _Tp, class _Up>
12601265_LIBCPP_INLINE_VISIBILITY constexpr
12611266_EnableIf<
1262 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() !=
1263 _VSTD::declval<const _Up&>()), bool>,
1267 is_convertible_v<decltype(declval<const _Tp&>() !=
1268 declval<const _Up&>()), bool>,
12641269 bool
12651270>
12661271operator!=(const _Tp& __v, const optional<_Up>& __x)
......@@ -1271,8 +1276,8 @@ operator!=(const _Tp& __v, const optional<_Up>& __x)
12711276template <class _Tp, class _Up>
12721277_LIBCPP_INLINE_VISIBILITY constexpr
12731278_EnableIf<
1274 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <
1275 _VSTD::declval<const _Up&>()), bool>,
1279 is_convertible_v<decltype(declval<const _Tp&>() <
1280 declval<const _Up&>()), bool>,
12761281 bool
12771282>
12781283operator<(const optional<_Tp>& __x, const _Up& __v)
......@@ -1283,8 +1288,8 @@ operator<(const optional<_Tp>& __x, const _Up& __v)
12831288template <class _Tp, class _Up>
12841289_LIBCPP_INLINE_VISIBILITY constexpr
12851290_EnableIf<
1286 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <
1287 _VSTD::declval<const _Up&>()), bool>,
1291 is_convertible_v<decltype(declval<const _Tp&>() <
1292 declval<const _Up&>()), bool>,
12881293 bool
12891294>
12901295operator<(const _Tp& __v, const optional<_Up>& __x)
......@@ -1295,8 +1300,8 @@ operator<(const _Tp& __v, const optional<_Up>& __x)
12951300template <class _Tp, class _Up>
12961301_LIBCPP_INLINE_VISIBILITY constexpr
12971302_EnableIf<
1298 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <=
1299 _VSTD::declval<const _Up&>()), bool>,
1303 is_convertible_v<decltype(declval<const _Tp&>() <=
1304 declval<const _Up&>()), bool>,
13001305 bool
13011306>
13021307operator<=(const optional<_Tp>& __x, const _Up& __v)
......@@ -1307,8 +1312,8 @@ operator<=(const optional<_Tp>& __x, const _Up& __v)
13071312template <class _Tp, class _Up>
13081313_LIBCPP_INLINE_VISIBILITY constexpr
13091314_EnableIf<
1310 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <=
1311 _VSTD::declval<const _Up&>()), bool>,
1315 is_convertible_v<decltype(declval<const _Tp&>() <=
1316 declval<const _Up&>()), bool>,
13121317 bool
13131318>
13141319operator<=(const _Tp& __v, const optional<_Up>& __x)
......@@ -1319,8 +1324,8 @@ operator<=(const _Tp& __v, const optional<_Up>& __x)
13191324template <class _Tp, class _Up>
13201325_LIBCPP_INLINE_VISIBILITY constexpr
13211326_EnableIf<
1322 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >
1323 _VSTD::declval<const _Up&>()), bool>,
1327 is_convertible_v<decltype(declval<const _Tp&>() >
1328 declval<const _Up&>()), bool>,
13241329 bool
13251330>
13261331operator>(const optional<_Tp>& __x, const _Up& __v)
......@@ -1331,8 +1336,8 @@ operator>(const optional<_Tp>& __x, const _Up& __v)
13311336template <class _Tp, class _Up>
13321337_LIBCPP_INLINE_VISIBILITY constexpr
13331338_EnableIf<
1334 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >
1335 _VSTD::declval<const _Up&>()), bool>,
1339 is_convertible_v<decltype(declval<const _Tp&>() >
1340 declval<const _Up&>()), bool>,
13361341 bool
13371342>
13381343operator>(const _Tp& __v, const optional<_Up>& __x)
......@@ -1343,8 +1348,8 @@ operator>(const _Tp& __v, const optional<_Up>& __x)
13431348template <class _Tp, class _Up>
13441349_LIBCPP_INLINE_VISIBILITY constexpr
13451350_EnableIf<
1346 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >=
1347 _VSTD::declval<const _Up&>()), bool>,
1351 is_convertible_v<decltype(declval<const _Tp&>() >=
1352 declval<const _Up&>()), bool>,
13481353 bool
13491354>
13501355operator>=(const optional<_Tp>& __x, const _Up& __v)
......@@ -1355,8 +1360,8 @@ operator>=(const optional<_Tp>& __x, const _Up& __v)
13551360template <class _Tp, class _Up>
13561361_LIBCPP_INLINE_VISIBILITY constexpr
13571362_EnableIf<
1358 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >=
1359 _VSTD::declval<const _Up&>()), bool>,
1363 is_convertible_v<decltype(declval<const _Tp&>() >=
1364 declval<const _Up&>()), bool>,
13601365 bool
13611366>
13621367operator>=(const _Tp& __v, const optional<_Up>& __x)
......@@ -1366,7 +1371,7 @@ operator>=(const _Tp& __v, const optional<_Up>& __x)
13661371
13671372
13681373template <class _Tp>
1369inline _LIBCPP_INLINE_VISIBILITY
1374inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
13701375_EnableIf<
13711376 is_move_constructible_v<_Tp> && is_swappable_v<_Tp>,
13721377 void
......@@ -1402,11 +1407,13 @@ struct _LIBCPP_TEMPLATE_VIS hash<
14021407 __enable_hash_helper<optional<_Tp>, remove_const_t<_Tp>>
14031408>
14041409{
1405 typedef optional<_Tp> argument_type;
1406 typedef size_t result_type;
1410#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
1411 _LIBCPP_DEPRECATED_IN_CXX17 typedef optional<_Tp> argument_type;
1412 _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
1413#endif
14071414
14081415 _LIBCPP_INLINE_VISIBILITY
1409 result_type operator()(const argument_type& __opt) const
1416 size_t operator()(const optional<_Tp>& __opt) const
14101417 {
14111418 return static_cast<bool>(__opt) ? hash<remove_const_t<_Tp>>()(*__opt) : 0;
14121419 }
......@@ -1414,8 +1421,8 @@ struct _LIBCPP_TEMPLATE_VIS hash<
14141421
14151422_LIBCPP_END_NAMESPACE_STD
14161423
1417#endif // _LIBCPP_STD_VER > 14
1424#endif // _LIBCPP_STD_VER > 14
14181425
14191426_LIBCPP_POP_MACROS
14201427
1421#endif // _LIBCPP_OPTIONAL
1428#endif // _LIBCPP_OPTIONAL
lib/libcxx/include/ostream+53-68
......@@ -134,11 +134,11 @@ template <class Stream, class T>
134134*/
135135
136136#include <__config>
137#include <bitset>
137138#include <ios>
138#include <streambuf>
139#include <locale>
140139#include <iterator>
141#include <bitset>
140#include <locale>
141#include <streambuf>
142142#include <version>
143143
144144#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
......@@ -165,27 +165,21 @@ public:
165165 { this->init(__sb); }
166166 virtual ~basic_ostream();
167167protected:
168#ifndef _LIBCPP_CXX03_LANG
169168 inline _LIBCPP_INLINE_VISIBILITY
170169 basic_ostream(basic_ostream&& __rhs);
171170
172171 // 27.7.2.3 Assign/swap
173172 inline _LIBCPP_INLINE_VISIBILITY
174173 basic_ostream& operator=(basic_ostream&& __rhs);
175#endif
174
176175 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1
177176 void swap(basic_ostream& __rhs)
178177 { basic_ios<char_type, traits_type>::swap(__rhs); }
179178
180#ifndef _LIBCPP_CXX03_LANG
181179 basic_ostream (const basic_ostream& __rhs) = delete;
182180 basic_ostream& operator=(const basic_ostream& __rhs) = delete;
183#else
184 basic_ostream (const basic_ostream& __rhs); // not defined
185 basic_ostream& operator=(const basic_ostream& __rhs); // not defined
186#endif
187public:
188181
182public:
189183 // 27.7.2.4 Prefix/suffix:
190184 class _LIBCPP_TEMPLATE_VIS sentry;
191185
......@@ -254,8 +248,7 @@ public:
254248 ~sentry();
255249
256250 _LIBCPP_INLINE_VISIBILITY
257 _LIBCPP_EXPLICIT
258 operator bool() const {return __ok_;}
251 explicit operator bool() const {return __ok_;}
259252};
260253
261254template <class _CharT, class _Traits>
......@@ -280,7 +273,7 @@ basic_ostream<_CharT, _Traits>::sentry::~sentry()
280273#ifndef _LIBCPP_NO_EXCEPTIONS
281274 try
282275 {
283#endif // _LIBCPP_NO_EXCEPTIONS
276#endif // _LIBCPP_NO_EXCEPTIONS
284277 if (__os_.rdbuf()->pubsync() == -1)
285278 __os_.setstate(ios_base::badbit);
286279#ifndef _LIBCPP_NO_EXCEPTIONS
......@@ -288,12 +281,10 @@ basic_ostream<_CharT, _Traits>::sentry::~sentry()
288281 catch (...)
289282 {
290283 }
291#endif // _LIBCPP_NO_EXCEPTIONS
284#endif // _LIBCPP_NO_EXCEPTIONS
292285 }
293286}
294287
295#ifndef _LIBCPP_CXX03_LANG
296
297288template <class _CharT, class _Traits>
298289basic_ostream<_CharT, _Traits>::basic_ostream(basic_ostream&& __rhs)
299290{
......@@ -308,8 +299,6 @@ basic_ostream<_CharT, _Traits>::operator=(basic_ostream&& __rhs)
308299 return *this;
309300}
310301
311#endif // _LIBCPP_CXX03_LANG
312
313302template <class _CharT, class _Traits>
314303basic_ostream<_CharT, _Traits>::~basic_ostream()
315304{
......@@ -322,7 +311,7 @@ basic_ostream<_CharT, _Traits>::operator<<(basic_streambuf<char_type, traits_typ
322311#ifndef _LIBCPP_NO_EXCEPTIONS
323312 try
324313 {
325#endif // _LIBCPP_NO_EXCEPTIONS
314#endif // _LIBCPP_NO_EXCEPTIONS
326315 sentry __s(*this);
327316 if (__s)
328317 {
......@@ -331,7 +320,7 @@ basic_ostream<_CharT, _Traits>::operator<<(basic_streambuf<char_type, traits_typ
331320#ifndef _LIBCPP_NO_EXCEPTIONS
332321 try
333322 {
334#endif // _LIBCPP_NO_EXCEPTIONS
323#endif // _LIBCPP_NO_EXCEPTIONS
335324 typedef istreambuf_iterator<_CharT, _Traits> _Ip;
336325 typedef ostreambuf_iterator<_CharT, _Traits> _Op;
337326 _Ip __i(__sb);
......@@ -352,7 +341,7 @@ basic_ostream<_CharT, _Traits>::operator<<(basic_streambuf<char_type, traits_typ
352341 {
353342 this->__set_failbit_and_consider_rethrow();
354343 }
355#endif // _LIBCPP_NO_EXCEPTIONS
344#endif // _LIBCPP_NO_EXCEPTIONS
356345 }
357346 else
358347 this->setstate(ios_base::badbit);
......@@ -363,7 +352,7 @@ basic_ostream<_CharT, _Traits>::operator<<(basic_streambuf<char_type, traits_typ
363352 {
364353 this->__set_badbit_and_consider_rethrow();
365354 }
366#endif // _LIBCPP_NO_EXCEPTIONS
355#endif // _LIBCPP_NO_EXCEPTIONS
367356 return *this;
368357}
369358
......@@ -374,7 +363,7 @@ basic_ostream<_CharT, _Traits>::operator<<(bool __n)
374363#ifndef _LIBCPP_NO_EXCEPTIONS
375364 try
376365 {
377#endif // _LIBCPP_NO_EXCEPTIONS
366#endif // _LIBCPP_NO_EXCEPTIONS
378367 sentry __s(*this);
379368 if (__s)
380369 {
......@@ -389,7 +378,7 @@ basic_ostream<_CharT, _Traits>::operator<<(bool __n)
389378 {
390379 this->__set_badbit_and_consider_rethrow();
391380 }
392#endif // _LIBCPP_NO_EXCEPTIONS
381#endif // _LIBCPP_NO_EXCEPTIONS
393382 return *this;
394383}
395384
......@@ -400,7 +389,7 @@ basic_ostream<_CharT, _Traits>::operator<<(short __n)
400389#ifndef _LIBCPP_NO_EXCEPTIONS
401390 try
402391 {
403#endif // _LIBCPP_NO_EXCEPTIONS
392#endif // _LIBCPP_NO_EXCEPTIONS
404393 sentry __s(*this);
405394 if (__s)
406395 {
......@@ -419,7 +408,7 @@ basic_ostream<_CharT, _Traits>::operator<<(short __n)
419408 {
420409 this->__set_badbit_and_consider_rethrow();
421410 }
422#endif // _LIBCPP_NO_EXCEPTIONS
411#endif // _LIBCPP_NO_EXCEPTIONS
423412 return *this;
424413}
425414
......@@ -430,7 +419,7 @@ basic_ostream<_CharT, _Traits>::operator<<(unsigned short __n)
430419#ifndef _LIBCPP_NO_EXCEPTIONS
431420 try
432421 {
433#endif // _LIBCPP_NO_EXCEPTIONS
422#endif // _LIBCPP_NO_EXCEPTIONS
434423 sentry __s(*this);
435424 if (__s)
436425 {
......@@ -445,7 +434,7 @@ basic_ostream<_CharT, _Traits>::operator<<(unsigned short __n)
445434 {
446435 this->__set_badbit_and_consider_rethrow();
447436 }
448#endif // _LIBCPP_NO_EXCEPTIONS
437#endif // _LIBCPP_NO_EXCEPTIONS
449438 return *this;
450439}
451440
......@@ -456,7 +445,7 @@ basic_ostream<_CharT, _Traits>::operator<<(int __n)
456445#ifndef _LIBCPP_NO_EXCEPTIONS
457446 try
458447 {
459#endif // _LIBCPP_NO_EXCEPTIONS
448#endif // _LIBCPP_NO_EXCEPTIONS
460449 sentry __s(*this);
461450 if (__s)
462451 {
......@@ -475,7 +464,7 @@ basic_ostream<_CharT, _Traits>::operator<<(int __n)
475464 {
476465 this->__set_badbit_and_consider_rethrow();
477466 }
478#endif // _LIBCPP_NO_EXCEPTIONS
467#endif // _LIBCPP_NO_EXCEPTIONS
479468 return *this;
480469}
481470
......@@ -486,7 +475,7 @@ basic_ostream<_CharT, _Traits>::operator<<(unsigned int __n)
486475#ifndef _LIBCPP_NO_EXCEPTIONS
487476 try
488477 {
489#endif // _LIBCPP_NO_EXCEPTIONS
478#endif // _LIBCPP_NO_EXCEPTIONS
490479 sentry __s(*this);
491480 if (__s)
492481 {
......@@ -501,7 +490,7 @@ basic_ostream<_CharT, _Traits>::operator<<(unsigned int __n)
501490 {
502491 this->__set_badbit_and_consider_rethrow();
503492 }
504#endif // _LIBCPP_NO_EXCEPTIONS
493#endif // _LIBCPP_NO_EXCEPTIONS
505494 return *this;
506495}
507496
......@@ -512,7 +501,7 @@ basic_ostream<_CharT, _Traits>::operator<<(long __n)
512501#ifndef _LIBCPP_NO_EXCEPTIONS
513502 try
514503 {
515#endif // _LIBCPP_NO_EXCEPTIONS
504#endif // _LIBCPP_NO_EXCEPTIONS
516505 sentry __s(*this);
517506 if (__s)
518507 {
......@@ -527,7 +516,7 @@ basic_ostream<_CharT, _Traits>::operator<<(long __n)
527516 {
528517 this->__set_badbit_and_consider_rethrow();
529518 }
530#endif // _LIBCPP_NO_EXCEPTIONS
519#endif // _LIBCPP_NO_EXCEPTIONS
531520 return *this;
532521}
533522
......@@ -538,7 +527,7 @@ basic_ostream<_CharT, _Traits>::operator<<(unsigned long __n)
538527#ifndef _LIBCPP_NO_EXCEPTIONS
539528 try
540529 {
541#endif // _LIBCPP_NO_EXCEPTIONS
530#endif // _LIBCPP_NO_EXCEPTIONS
542531 sentry __s(*this);
543532 if (__s)
544533 {
......@@ -553,7 +542,7 @@ basic_ostream<_CharT, _Traits>::operator<<(unsigned long __n)
553542 {
554543 this->__set_badbit_and_consider_rethrow();
555544 }
556#endif // _LIBCPP_NO_EXCEPTIONS
545#endif // _LIBCPP_NO_EXCEPTIONS
557546 return *this;
558547}
559548
......@@ -564,7 +553,7 @@ basic_ostream<_CharT, _Traits>::operator<<(long long __n)
564553#ifndef _LIBCPP_NO_EXCEPTIONS
565554 try
566555 {
567#endif // _LIBCPP_NO_EXCEPTIONS
556#endif // _LIBCPP_NO_EXCEPTIONS
568557 sentry __s(*this);
569558 if (__s)
570559 {
......@@ -579,7 +568,7 @@ basic_ostream<_CharT, _Traits>::operator<<(long long __n)
579568 {
580569 this->__set_badbit_and_consider_rethrow();
581570 }
582#endif // _LIBCPP_NO_EXCEPTIONS
571#endif // _LIBCPP_NO_EXCEPTIONS
583572 return *this;
584573}
585574
......@@ -590,7 +579,7 @@ basic_ostream<_CharT, _Traits>::operator<<(unsigned long long __n)
590579#ifndef _LIBCPP_NO_EXCEPTIONS
591580 try
592581 {
593#endif // _LIBCPP_NO_EXCEPTIONS
582#endif // _LIBCPP_NO_EXCEPTIONS
594583 sentry __s(*this);
595584 if (__s)
596585 {
......@@ -605,7 +594,7 @@ basic_ostream<_CharT, _Traits>::operator<<(unsigned long long __n)
605594 {
606595 this->__set_badbit_and_consider_rethrow();
607596 }
608#endif // _LIBCPP_NO_EXCEPTIONS
597#endif // _LIBCPP_NO_EXCEPTIONS
609598 return *this;
610599}
611600
......@@ -616,7 +605,7 @@ basic_ostream<_CharT, _Traits>::operator<<(float __n)
616605#ifndef _LIBCPP_NO_EXCEPTIONS
617606 try
618607 {
619#endif // _LIBCPP_NO_EXCEPTIONS
608#endif // _LIBCPP_NO_EXCEPTIONS
620609 sentry __s(*this);
621610 if (__s)
622611 {
......@@ -631,7 +620,7 @@ basic_ostream<_CharT, _Traits>::operator<<(float __n)
631620 {
632621 this->__set_badbit_and_consider_rethrow();
633622 }
634#endif // _LIBCPP_NO_EXCEPTIONS
623#endif // _LIBCPP_NO_EXCEPTIONS
635624 return *this;
636625}
637626
......@@ -642,7 +631,7 @@ basic_ostream<_CharT, _Traits>::operator<<(double __n)
642631#ifndef _LIBCPP_NO_EXCEPTIONS
643632 try
644633 {
645#endif // _LIBCPP_NO_EXCEPTIONS
634#endif // _LIBCPP_NO_EXCEPTIONS
646635 sentry __s(*this);
647636 if (__s)
648637 {
......@@ -657,7 +646,7 @@ basic_ostream<_CharT, _Traits>::operator<<(double __n)
657646 {
658647 this->__set_badbit_and_consider_rethrow();
659648 }
660#endif // _LIBCPP_NO_EXCEPTIONS
649#endif // _LIBCPP_NO_EXCEPTIONS
661650 return *this;
662651}
663652
......@@ -668,7 +657,7 @@ basic_ostream<_CharT, _Traits>::operator<<(long double __n)
668657#ifndef _LIBCPP_NO_EXCEPTIONS
669658 try
670659 {
671#endif // _LIBCPP_NO_EXCEPTIONS
660#endif // _LIBCPP_NO_EXCEPTIONS
672661 sentry __s(*this);
673662 if (__s)
674663 {
......@@ -683,7 +672,7 @@ basic_ostream<_CharT, _Traits>::operator<<(long double __n)
683672 {
684673 this->__set_badbit_and_consider_rethrow();
685674 }
686#endif // _LIBCPP_NO_EXCEPTIONS
675#endif // _LIBCPP_NO_EXCEPTIONS
687676 return *this;
688677}
689678
......@@ -694,7 +683,7 @@ basic_ostream<_CharT, _Traits>::operator<<(const void* __n)
694683#ifndef _LIBCPP_NO_EXCEPTIONS
695684 try
696685 {
697#endif // _LIBCPP_NO_EXCEPTIONS
686#endif // _LIBCPP_NO_EXCEPTIONS
698687 sentry __s(*this);
699688 if (__s)
700689 {
......@@ -709,7 +698,7 @@ basic_ostream<_CharT, _Traits>::operator<<(const void* __n)
709698 {
710699 this->__set_badbit_and_consider_rethrow();
711700 }
712#endif // _LIBCPP_NO_EXCEPTIONS
701#endif // _LIBCPP_NO_EXCEPTIONS
713702 return *this;
714703}
715704
......@@ -721,7 +710,7 @@ __put_character_sequence(basic_ostream<_CharT, _Traits>& __os,
721710#ifndef _LIBCPP_NO_EXCEPTIONS
722711 try
723712 {
724#endif // _LIBCPP_NO_EXCEPTIONS
713#endif // _LIBCPP_NO_EXCEPTIONS
725714 typename basic_ostream<_CharT, _Traits>::sentry __s(__os);
726715 if (__s)
727716 {
......@@ -742,7 +731,7 @@ __put_character_sequence(basic_ostream<_CharT, _Traits>& __os,
742731 {
743732 __os.__set_badbit_and_consider_rethrow();
744733 }
745#endif // _LIBCPP_NO_EXCEPTIONS
734#endif // _LIBCPP_NO_EXCEPTIONS
746735 return __os;
747736}
748737
......@@ -761,7 +750,7 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, char __cn)
761750#ifndef _LIBCPP_NO_EXCEPTIONS
762751 try
763752 {
764#endif // _LIBCPP_NO_EXCEPTIONS
753#endif // _LIBCPP_NO_EXCEPTIONS
765754 typename basic_ostream<_CharT, _Traits>::sentry __s(__os);
766755 if (__s)
767756 {
......@@ -783,7 +772,7 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, char __cn)
783772 {
784773 __os.__set_badbit_and_consider_rethrow();
785774 }
786#endif // _LIBCPP_NO_EXCEPTIONS
775#endif // _LIBCPP_NO_EXCEPTIONS
787776 return __os;
788777}
789778
......@@ -822,7 +811,7 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, const char* __strn)
822811#ifndef _LIBCPP_NO_EXCEPTIONS
823812 try
824813 {
825#endif // _LIBCPP_NO_EXCEPTIONS
814#endif // _LIBCPP_NO_EXCEPTIONS
826815 typename basic_ostream<_CharT, _Traits>::sentry __s(__os);
827816 if (__s)
828817 {
......@@ -857,7 +846,7 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, const char* __strn)
857846 {
858847 __os.__set_badbit_and_consider_rethrow();
859848 }
860#endif // _LIBCPP_NO_EXCEPTIONS
849#endif // _LIBCPP_NO_EXCEPTIONS
861850 return __os;
862851}
863852
......@@ -891,7 +880,7 @@ basic_ostream<_CharT, _Traits>::put(char_type __c)
891880#ifndef _LIBCPP_NO_EXCEPTIONS
892881 try
893882 {
894#endif // _LIBCPP_NO_EXCEPTIONS
883#endif // _LIBCPP_NO_EXCEPTIONS
895884 sentry __s(*this);
896885 if (__s)
897886 {
......@@ -907,7 +896,7 @@ basic_ostream<_CharT, _Traits>::put(char_type __c)
907896 {
908897 this->__set_badbit_and_consider_rethrow();
909898 }
910#endif // _LIBCPP_NO_EXCEPTIONS
899#endif // _LIBCPP_NO_EXCEPTIONS
911900 return *this;
912901}
913902
......@@ -918,7 +907,7 @@ basic_ostream<_CharT, _Traits>::write(const char_type* __s, streamsize __n)
918907#ifndef _LIBCPP_NO_EXCEPTIONS
919908 try
920909 {
921#endif // _LIBCPP_NO_EXCEPTIONS
910#endif // _LIBCPP_NO_EXCEPTIONS
922911 sentry __sen(*this);
923912 if (__sen && __n)
924913 {
......@@ -931,7 +920,7 @@ basic_ostream<_CharT, _Traits>::write(const char_type* __s, streamsize __n)
931920 {
932921 this->__set_badbit_and_consider_rethrow();
933922 }
934#endif // _LIBCPP_NO_EXCEPTIONS
923#endif // _LIBCPP_NO_EXCEPTIONS
935924 return *this;
936925}
937926
......@@ -942,7 +931,7 @@ basic_ostream<_CharT, _Traits>::flush()
942931#ifndef _LIBCPP_NO_EXCEPTIONS
943932 try
944933 {
945#endif // _LIBCPP_NO_EXCEPTIONS
934#endif // _LIBCPP_NO_EXCEPTIONS
946935 if (this->rdbuf())
947936 {
948937 sentry __s(*this);
......@@ -958,7 +947,7 @@ basic_ostream<_CharT, _Traits>::flush()
958947 {
959948 this->__set_badbit_and_consider_rethrow();
960949 }
961#endif // _LIBCPP_NO_EXCEPTIONS
950#endif // _LIBCPP_NO_EXCEPTIONS
962951 return *this;
963952}
964953
......@@ -1025,19 +1014,17 @@ flush(basic_ostream<_CharT, _Traits>& __os)
10251014 return __os;
10261015}
10271016
1028#ifndef _LIBCPP_CXX03_LANG
1029
10301017template <class _Stream, class _Tp, class = void>
10311018struct __is_ostreamable : false_type { };
10321019
10331020template <class _Stream, class _Tp>
10341021struct __is_ostreamable<_Stream, _Tp, decltype(
1035 _VSTD::declval<_Stream>() << _VSTD::declval<_Tp>(), void()
1022 declval<_Stream>() << declval<_Tp>(), void()
10361023)> : true_type { };
10371024
10381025template <class _Stream, class _Tp, class = typename enable_if<
10391026 _And<is_base_of<ios_base, _Stream>,
1040 __is_ostreamable<_Stream&, const _Tp&>>::value
1027 __is_ostreamable<_Stream&, const _Tp&> >::value
10411028>::type>
10421029_LIBCPP_INLINE_VISIBILITY
10431030_Stream&& operator<<(_Stream&& __os, const _Tp& __x)
......@@ -1046,8 +1033,6 @@ _Stream&& operator<<(_Stream&& __os, const _Tp& __x)
10461033 return _VSTD::move(__os);
10471034}
10481035
1049#endif // _LIBCPP_CXX03_LANG
1050
10511036template<class _CharT, class _Traits, class _Allocator>
10521037basic_ostream<_CharT, _Traits>&
10531038operator<<(basic_ostream<_CharT, _Traits>& __os,
......@@ -1106,4 +1091,4 @@ _LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ostream<wch
11061091
11071092_LIBCPP_END_NAMESPACE_STD
11081093
1109#endif // _LIBCPP_OSTREAM
1094#endif // _LIBCPP_OSTREAM
lib/libcxx/include/queue+53-71
......@@ -179,10 +179,13 @@ template <class T, class Container, class Compare>
179179*/
180180
181181#include <__config>
182#include <__memory/uses_allocator.h>
183#include <__utility/forward.h>
184#include <algorithm>
185#include <compare>
182186#include <deque>
183#include <vector>
184187#include <functional>
185#include <algorithm>
188#include <vector>
186189
187190#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
188191#pragma GCC system_header
......@@ -238,47 +241,42 @@ public:
238241 queue& operator=(queue&& __q)
239242 _NOEXCEPT_(is_nothrow_move_assignable<container_type>::value)
240243 {c = _VSTD::move(__q.c); return *this;}
241#endif // _LIBCPP_CXX03_LANG
244#endif // _LIBCPP_CXX03_LANG
242245
243246 _LIBCPP_INLINE_VISIBILITY
244247 explicit queue(const container_type& __c) : c(__c) {}
245248#ifndef _LIBCPP_CXX03_LANG
246249 _LIBCPP_INLINE_VISIBILITY
247250 explicit queue(container_type&& __c) : c(_VSTD::move(__c)) {}
248#endif // _LIBCPP_CXX03_LANG
251#endif // _LIBCPP_CXX03_LANG
249252 template <class _Alloc>
250253 _LIBCPP_INLINE_VISIBILITY
251254 explicit queue(const _Alloc& __a,
252 typename enable_if<uses_allocator<container_type,
253 _Alloc>::value>::type* = 0)
255 _EnableIf<uses_allocator<container_type, _Alloc>::value>* = 0)
254256 : c(__a) {}
255257 template <class _Alloc>
256258 _LIBCPP_INLINE_VISIBILITY
257259 queue(const queue& __q, const _Alloc& __a,
258 typename enable_if<uses_allocator<container_type,
259 _Alloc>::value>::type* = 0)
260 _EnableIf<uses_allocator<container_type, _Alloc>::value>* = 0)
260261 : c(__q.c, __a) {}
261262 template <class _Alloc>
262263 _LIBCPP_INLINE_VISIBILITY
263264 queue(const container_type& __c, const _Alloc& __a,
264 typename enable_if<uses_allocator<container_type,
265 _Alloc>::value>::type* = 0)
265 _EnableIf<uses_allocator<container_type, _Alloc>::value>* = 0)
266266 : c(__c, __a) {}
267267#ifndef _LIBCPP_CXX03_LANG
268268 template <class _Alloc>
269269 _LIBCPP_INLINE_VISIBILITY
270270 queue(container_type&& __c, const _Alloc& __a,
271 typename enable_if<uses_allocator<container_type,
272 _Alloc>::value>::type* = 0)
271 _EnableIf<uses_allocator<container_type, _Alloc>::value>* = 0)
273272 : c(_VSTD::move(__c), __a) {}
274273 template <class _Alloc>
275274 _LIBCPP_INLINE_VISIBILITY
276275 queue(queue&& __q, const _Alloc& __a,
277 typename enable_if<uses_allocator<container_type,
278 _Alloc>::value>::type* = 0)
276 _EnableIf<uses_allocator<container_type, _Alloc>::value>* = 0)
279277 : c(_VSTD::move(__q.c), __a) {}
280278
281#endif // _LIBCPP_CXX03_LANG
279#endif // _LIBCPP_CXX03_LANG
282280
283281 _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
284282 bool empty() const {return c.empty();}
......@@ -308,7 +306,7 @@ public:
308306 void emplace(_Args&&... __args)
309307 { c.emplace_back(_VSTD::forward<_Args>(__args)...);}
310308#endif
311#endif // _LIBCPP_CXX03_LANG
309#endif // _LIBCPP_CXX03_LANG
312310 _LIBCPP_INLINE_VISIBILITY
313311 void pop() {c.pop_front();}
314312
......@@ -335,15 +333,15 @@ public:
335333
336334#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
337335template<class _Container,
338 class = typename enable_if<!__is_allocator<_Container>::value, nullptr_t>::type
336 class = _EnableIf<!__is_allocator<_Container>::value>
339337>
340338queue(_Container)
341339 -> queue<typename _Container::value_type, _Container>;
342340
343341template<class _Container,
344342 class _Alloc,
345 class = typename enable_if<!__is_allocator<_Container>::value, nullptr_t>::type,
346 class = typename enable_if< __is_allocator<_Alloc>::value, nullptr_t>::type
343 class = _EnableIf<!__is_allocator<_Container>::value>,
344 class = _EnableIf<uses_allocator<_Container, _Alloc>::value>
347345>
348346queue(_Container, _Alloc)
349347 -> queue<typename _Container::value_type, _Container>;
......@@ -399,10 +397,7 @@ operator<=(const queue<_Tp, _Container>& __x,const queue<_Tp, _Container>& __y)
399397
400398template <class _Tp, class _Container>
401399inline _LIBCPP_INLINE_VISIBILITY
402typename enable_if<
403 __is_swappable<_Container>::value,
404 void
405>::type
400_EnableIf<__is_swappable<_Container>::value, void>
406401swap(queue<_Tp, _Container>& __x, queue<_Tp, _Container>& __y)
407402 _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
408403{
......@@ -458,7 +453,7 @@ public:
458453 _NOEXCEPT_(is_nothrow_move_assignable<container_type>::value &&
459454 is_nothrow_move_assignable<value_compare>::value)
460455 {c = _VSTD::move(__q.c); comp = _VSTD::move(__q.comp); return *this;}
461#endif // _LIBCPP_CXX03_LANG
456#endif // _LIBCPP_CXX03_LANG
462457
463458 _LIBCPP_INLINE_VISIBILITY
464459 explicit priority_queue(const value_compare& __comp)
......@@ -482,41 +477,35 @@ public:
482477 _LIBCPP_INLINE_VISIBILITY
483478 priority_queue(_InputIter __f, _InputIter __l,
484479 const value_compare& __comp, container_type&& __c);
485#endif // _LIBCPP_CXX03_LANG
480#endif // _LIBCPP_CXX03_LANG
486481 template <class _Alloc>
487482 _LIBCPP_INLINE_VISIBILITY
488483 explicit priority_queue(const _Alloc& __a,
489 typename enable_if<uses_allocator<container_type,
490 _Alloc>::value>::type* = 0);
484 _EnableIf<uses_allocator<container_type, _Alloc>::value>* = 0);
491485 template <class _Alloc>
492486 _LIBCPP_INLINE_VISIBILITY
493487 priority_queue(const value_compare& __comp, const _Alloc& __a,
494 typename enable_if<uses_allocator<container_type,
495 _Alloc>::value>::type* = 0);
488 _EnableIf<uses_allocator<container_type, _Alloc>::value>* = 0);
496489 template <class _Alloc>
497490 _LIBCPP_INLINE_VISIBILITY
498491 priority_queue(const value_compare& __comp, const container_type& __c,
499492 const _Alloc& __a,
500 typename enable_if<uses_allocator<container_type,
501 _Alloc>::value>::type* = 0);
493 _EnableIf<uses_allocator<container_type, _Alloc>::value>* = 0);
502494 template <class _Alloc>
503495 _LIBCPP_INLINE_VISIBILITY
504496 priority_queue(const priority_queue& __q, const _Alloc& __a,
505 typename enable_if<uses_allocator<container_type,
506 _Alloc>::value>::type* = 0);
497 _EnableIf<uses_allocator<container_type, _Alloc>::value>* = 0);
507498#ifndef _LIBCPP_CXX03_LANG
508499 template <class _Alloc>
509500 _LIBCPP_INLINE_VISIBILITY
510501 priority_queue(const value_compare& __comp, container_type&& __c,
511502 const _Alloc& __a,
512 typename enable_if<uses_allocator<container_type,
513 _Alloc>::value>::type* = 0);
503 _EnableIf<uses_allocator<container_type, _Alloc>::value>* = 0);
514504 template <class _Alloc>
515505 _LIBCPP_INLINE_VISIBILITY
516506 priority_queue(priority_queue&& __q, const _Alloc& __a,
517 typename enable_if<uses_allocator<container_type,
518 _Alloc>::value>::type* = 0);
519#endif // _LIBCPP_CXX03_LANG
507 _EnableIf<uses_allocator<container_type, _Alloc>::value>* = 0);
508#endif // _LIBCPP_CXX03_LANG
520509
521510 _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
522511 bool empty() const {return c.empty();}
......@@ -533,7 +522,7 @@ public:
533522 template <class... _Args>
534523 _LIBCPP_INLINE_VISIBILITY
535524 void emplace(_Args&&... __args);
536#endif // _LIBCPP_CXX03_LANG
525#endif // _LIBCPP_CXX03_LANG
537526 _LIBCPP_INLINE_VISIBILITY
538527 void pop();
539528
......@@ -546,28 +535,28 @@ public:
546535#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
547536template <class _Compare,
548537 class _Container,
549 class = typename enable_if<!__is_allocator<_Compare>::value, nullptr_t>::type,
550 class = typename enable_if<!__is_allocator<_Container>::value, nullptr_t>::type
538 class = _EnableIf<!__is_allocator<_Compare>::value>,
539 class = _EnableIf<!__is_allocator<_Container>::value>
551540>
552541priority_queue(_Compare, _Container)
553542 -> priority_queue<typename _Container::value_type, _Container, _Compare>;
554543
555544template<class _InputIterator,
556 class _Compare = less<typename iterator_traits<_InputIterator>::value_type>,
557 class _Container = vector<typename iterator_traits<_InputIterator>::value_type>,
558 class = typename enable_if< __is_cpp17_input_iterator<_InputIterator>::value, nullptr_t>::type,
559 class = typename enable_if<!__is_allocator<_Compare>::value, nullptr_t>::type,
560 class = typename enable_if<!__is_allocator<_Container>::value, nullptr_t>::type
545 class _Compare = less<__iter_value_type<_InputIterator>>,
546 class _Container = vector<__iter_value_type<_InputIterator>>,
547 class = _EnableIf<__is_cpp17_input_iterator<_InputIterator>::value>,
548 class = _EnableIf<!__is_allocator<_Compare>::value>,
549 class = _EnableIf<!__is_allocator<_Container>::value>
561550>
562551priority_queue(_InputIterator, _InputIterator, _Compare = _Compare(), _Container = _Container())
563 -> priority_queue<typename iterator_traits<_InputIterator>::value_type, _Container, _Compare>;
552 -> priority_queue<__iter_value_type<_InputIterator>, _Container, _Compare>;
564553
565554template<class _Compare,
566555 class _Container,
567556 class _Alloc,
568 class = typename enable_if<!__is_allocator<_Compare>::value, nullptr_t>::type,
569 class = typename enable_if<!__is_allocator<_Container>::value, nullptr_t>::type,
570 class = typename enable_if< __is_allocator<_Alloc>::value, nullptr_t>::type
557 class = _EnableIf<!__is_allocator<_Compare>::value>,
558 class = _EnableIf<!__is_allocator<_Container>::value>,
559 class = _EnableIf<uses_allocator<_Container, _Alloc>::value>
571560>
572561priority_queue(_Compare, _Container, _Alloc)
573562 -> priority_queue<typename _Container::value_type, _Container, _Compare>;
......@@ -595,7 +584,7 @@ priority_queue<_Tp, _Container, _Compare>::priority_queue(const value_compare& _
595584 _VSTD::make_heap(c.begin(), c.end(), comp);
596585}
597586
598#endif // _LIBCPP_CXX03_LANG
587#endif // _LIBCPP_CXX03_LANG
599588
600589template <class _Tp, class _Container, class _Compare>
601590template <class _InputIter>
......@@ -636,14 +625,13 @@ priority_queue<_Tp, _Container, _Compare>::priority_queue(_InputIter __f, _Input
636625 _VSTD::make_heap(c.begin(), c.end(), comp);
637626}
638627
639#endif // _LIBCPP_CXX03_LANG
628#endif // _LIBCPP_CXX03_LANG
640629
641630template <class _Tp, class _Container, class _Compare>
642631template <class _Alloc>
643632inline
644633priority_queue<_Tp, _Container, _Compare>::priority_queue(const _Alloc& __a,
645 typename enable_if<uses_allocator<container_type,
646 _Alloc>::value>::type*)
634 _EnableIf<uses_allocator<container_type, _Alloc>::value>*)
647635 : c(__a)
648636{
649637}
......@@ -653,8 +641,7 @@ template <class _Alloc>
653641inline
654642priority_queue<_Tp, _Container, _Compare>::priority_queue(const value_compare& __comp,
655643 const _Alloc& __a,
656 typename enable_if<uses_allocator<container_type,
657 _Alloc>::value>::type*)
644 _EnableIf<uses_allocator<container_type, _Alloc>::value>*)
658645 : c(__a),
659646 comp(__comp)
660647{
......@@ -666,8 +653,7 @@ inline
666653priority_queue<_Tp, _Container, _Compare>::priority_queue(const value_compare& __comp,
667654 const container_type& __c,
668655 const _Alloc& __a,
669 typename enable_if<uses_allocator<container_type,
670 _Alloc>::value>::type*)
656 _EnableIf<uses_allocator<container_type, _Alloc>::value>*)
671657 : c(__c, __a),
672658 comp(__comp)
673659{
......@@ -679,8 +665,7 @@ template <class _Alloc>
679665inline
680666priority_queue<_Tp, _Container, _Compare>::priority_queue(const priority_queue& __q,
681667 const _Alloc& __a,
682 typename enable_if<uses_allocator<container_type,
683 _Alloc>::value>::type*)
668 _EnableIf<uses_allocator<container_type, _Alloc>::value>*)
684669 : c(__q.c, __a),
685670 comp(__q.comp)
686671{
......@@ -695,8 +680,7 @@ inline
695680priority_queue<_Tp, _Container, _Compare>::priority_queue(const value_compare& __comp,
696681 container_type&& __c,
697682 const _Alloc& __a,
698 typename enable_if<uses_allocator<container_type,
699 _Alloc>::value>::type*)
683 _EnableIf<uses_allocator<container_type, _Alloc>::value>*)
700684 : c(_VSTD::move(__c), __a),
701685 comp(__comp)
702686{
......@@ -708,15 +692,14 @@ template <class _Alloc>
708692inline
709693priority_queue<_Tp, _Container, _Compare>::priority_queue(priority_queue&& __q,
710694 const _Alloc& __a,
711 typename enable_if<uses_allocator<container_type,
712 _Alloc>::value>::type*)
695 _EnableIf<uses_allocator<container_type, _Alloc>::value>*)
713696 : c(_VSTD::move(__q.c), __a),
714697 comp(_VSTD::move(__q.comp))
715698{
716699 _VSTD::make_heap(c.begin(), c.end(), comp);
717700}
718701
719#endif // _LIBCPP_CXX03_LANG
702#endif // _LIBCPP_CXX03_LANG
720703
721704template <class _Tp, class _Container, class _Compare>
722705inline
......@@ -748,7 +731,7 @@ priority_queue<_Tp, _Container, _Compare>::emplace(_Args&&... __args)
748731 _VSTD::push_heap(c.begin(), c.end(), comp);
749732}
750733
751#endif // _LIBCPP_CXX03_LANG
734#endif // _LIBCPP_CXX03_LANG
752735
753736template <class _Tp, class _Container, class _Compare>
754737inline
......@@ -773,11 +756,10 @@ priority_queue<_Tp, _Container, _Compare>::swap(priority_queue& __q)
773756
774757template <class _Tp, class _Container, class _Compare>
775758inline _LIBCPP_INLINE_VISIBILITY
776typename enable_if<
777 __is_swappable<_Container>::value
778 && __is_swappable<_Compare>::value,
759_EnableIf<
760 __is_swappable<_Container>::value && __is_swappable<_Compare>::value,
779761 void
780>::type
762>
781763swap(priority_queue<_Tp, _Container, _Compare>& __x,
782764 priority_queue<_Tp, _Container, _Compare>& __y)
783765 _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
......@@ -793,4 +775,4 @@ struct _LIBCPP_TEMPLATE_VIS uses_allocator<priority_queue<_Tp, _Container, _Comp
793775
794776_LIBCPP_END_NAMESPACE_STD
795777
796#endif // _LIBCPP_QUEUE
778#endif // _LIBCPP_QUEUE
lib/libcxx/include/random+42-60
......@@ -17,6 +17,9 @@
1717
1818namespace std
1919{
20// [rand.req.urng], uniform random bit generator requirements
21template<class G>
22concept uniform_random_bit_generator = see below; // C++20
2023
2124// Engines
2225
......@@ -1675,17 +1678,19 @@ class piecewise_linear_distribution
16751678*/
16761679
16771680#include <__config>
1681#include <__random/uniform_int_distribution.h>
1682#include <algorithm>
1683#include <cmath>
1684#include <concepts>
16781685#include <cstddef>
16791686#include <cstdint>
1680#include <cmath>
1681#include <type_traits>
16821687#include <initializer_list>
1688#include <iosfwd>
16831689#include <limits>
1684#include <algorithm>
16851690#include <numeric>
1686#include <vector>
16871691#include <string>
1688#include <iosfwd>
1692#include <type_traits>
1693#include <vector>
16891694
16901695#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
16911696#pragma GCC system_header
......@@ -1697,6 +1702,20 @@ _LIBCPP_PUSH_MACROS
16971702
16981703_LIBCPP_BEGIN_NAMESPACE_STD
16991704
1705#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
1706
1707// [rand.req.urng]
1708template<class _Gen>
1709concept uniform_random_bit_generator =
1710 invocable<_Gen&> && unsigned_integral<invoke_result_t<_Gen&>> &&
1711 requires {
1712 { _Gen::min() } -> same_as<invoke_result_t<_Gen&>>;
1713 { _Gen::max() } -> same_as<invoke_result_t<_Gen&>>;
1714 requires bool_constant<(_Gen::min() < _Gen::max())>::value;
1715 };
1716
1717#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
1718
17001719// __is_seed_sequence
17011720
17021721template <class _Sseq, class _Engine>
......@@ -1712,7 +1731,7 @@ struct __is_seed_sequence
17121731template <unsigned long long __a, unsigned long long __c,
17131732 unsigned long long __m, unsigned long long _Mp,
17141733 bool _MightOverflow = (__a != 0 && __m != 0 && __m-1 > (_Mp-__c)/__a),
1715 bool _OverflowOK = ((__m|__m-1) > __m), // m = 2^n
1734 bool _OverflowOK = ((__m | (__m-1)) > __m), // m = 2^n
17161735 bool _SchrageOK = (__a != 0 && __m != 0 && __m % __a <= __m / __a)> // r <= q
17171736struct __lce_alg_picker
17181737{
......@@ -1901,7 +1920,7 @@ private:
19011920
19021921 static_assert(__m == 0 || __a < __m, "linear_congruential_engine invalid parameters");
19031922 static_assert(__m == 0 || __c < __m, "linear_congruential_engine invalid parameters");
1904 static_assert(_VSTD::is_unsigned<_UIntType>::value, "_UIntType must be unsigned type");
1923 static_assert(is_unsigned<_UIntType>::value, "_UIntType must be unsigned type");
19051924public:
19061925 static _LIBCPP_CONSTEXPR const result_type _Min = __c == 0u ? 1u: 0u;
19071926 static _LIBCPP_CONSTEXPR const result_type _Max = __m - 1u;
......@@ -2940,7 +2959,7 @@ public:
29402959 _LIBCPP_INLINE_VISIBILITY
29412960 explicit discard_block_engine(_Engine&& __e)
29422961 : __e_(_VSTD::move(__e)), __n_(0) {}
2943#endif // _LIBCPP_CXX03_LANG
2962#endif // _LIBCPP_CXX03_LANG
29442963 _LIBCPP_INLINE_VISIBILITY
29452964 explicit discard_block_engine(result_type __sd) : __e_(__sd), __n_(0) {}
29462965 template<class _Sseq>
......@@ -3152,7 +3171,7 @@ public:
31523171 _LIBCPP_INLINE_VISIBILITY
31533172 explicit independent_bits_engine(_Engine&& __e)
31543173 : __e_(_VSTD::move(__e)) {}
3155#endif // _LIBCPP_CXX03_LANG
3174#endif // _LIBCPP_CXX03_LANG
31563175 _LIBCPP_INLINE_VISIBILITY
31573176 explicit independent_bits_engine(result_type __sd) : __e_(__sd) {}
31583177 template<class _Sseq>
......@@ -3382,7 +3401,7 @@ public:
33823401 _LIBCPP_INLINE_VISIBILITY
33833402 explicit shuffle_order_engine(_Engine&& __e)
33843403 : __e_(_VSTD::move(__e)) {__init();}
3385#endif // _LIBCPP_CXX03_LANG
3404#endif // _LIBCPP_CXX03_LANG
33863405 _LIBCPP_INLINE_VISIBILITY
33873406 explicit shuffle_order_engine(result_type __sd) : __e_(__sd) {__init();}
33883407 template<class _Sseq>
......@@ -3634,7 +3653,7 @@ public:
36343653 template<class _Tp>
36353654 _LIBCPP_INLINE_VISIBILITY
36363655 seed_seq(initializer_list<_Tp> __il) {init(__il.begin(), __il.end());}
3637#endif // _LIBCPP_CXX03_LANG
3656#endif // _LIBCPP_CXX03_LANG
36383657
36393658 template<class _InputIterator>
36403659 _LIBCPP_INLINE_VISIBILITY
......@@ -3755,42 +3774,6 @@ generate_canonical(_URNG& __g)
37553774 return _Sp / __base;
37563775}
37573776
3758// uniform_int_distribution
3759
3760// in <algorithm>
3761
3762template <class _CharT, class _Traits, class _IT>
3763basic_ostream<_CharT, _Traits>&
3764operator<<(basic_ostream<_CharT, _Traits>& __os,
3765 const uniform_int_distribution<_IT>& __x)
3766{
3767 __save_flags<_CharT, _Traits> __lx(__os);
3768 typedef basic_ostream<_CharT, _Traits> _Ostream;
3769 __os.flags(_Ostream::dec | _Ostream::left);
3770 _CharT __sp = __os.widen(' ');
3771 __os.fill(__sp);
3772 return __os << __x.a() << __sp << __x.b();
3773}
3774
3775template <class _CharT, class _Traits, class _IT>
3776basic_istream<_CharT, _Traits>&
3777operator>>(basic_istream<_CharT, _Traits>& __is,
3778 uniform_int_distribution<_IT>& __x)
3779{
3780 typedef uniform_int_distribution<_IT> _Eng;
3781 typedef typename _Eng::result_type result_type;
3782 typedef typename _Eng::param_type param_type;
3783 __save_flags<_CharT, _Traits> __lx(__is);
3784 typedef basic_istream<_CharT, _Traits> _Istream;
3785 __is.flags(_Istream::dec | _Istream::skipws);
3786 result_type __a;
3787 result_type __b;
3788 __is >> __a >> __b;
3789 if (!__is.fail())
3790 __x.param(param_type(__a, __b));
3791 return __is;
3792}
3793
37943777// uniform_real_distribution
37953778
37963779template<class _RealType = double>
......@@ -4142,7 +4125,7 @@ inline _LIBCPP_INLINE_VISIBILITY double __libcpp_lgamma(double __d) {
41424125}
41434126
41444127template<class _IntType>
4145binomial_distribution<_IntType>::param_type::param_type(const result_type __t, const double __p)
4128binomial_distribution<_IntType>::param_type::param_type(result_type __t, double __p)
41464129 : __t_(__t), __p_(__p)
41474130{
41484131 if (0 < __p_ && __p_ < 1)
......@@ -6145,7 +6128,7 @@ public:
61456128 _LIBCPP_INLINE_VISIBILITY
61466129 param_type(initializer_list<double> __wl)
61476130 : __p_(__wl.begin(), __wl.end()) {__init();}
6148#endif // _LIBCPP_CXX03_LANG
6131#endif // _LIBCPP_CXX03_LANG
61496132 template<class _UnaryOperation>
61506133 param_type(size_t __nw, double __xmin, double __xmax,
61516134 _UnaryOperation __fw);
......@@ -6192,7 +6175,7 @@ public:
61926175 _LIBCPP_INLINE_VISIBILITY
61936176 discrete_distribution(initializer_list<double> __wl)
61946177 : __p_(__wl) {}
6195#endif // _LIBCPP_CXX03_LANG
6178#endif // _LIBCPP_CXX03_LANG
61966179 template<class _UnaryOperation>
61976180 _LIBCPP_INLINE_VISIBILITY
61986181 discrete_distribution(size_t __nw, double __xmin, double __xmax,
......@@ -6274,8 +6257,7 @@ discrete_distribution<_IntType>::param_type::__init()
62746257 if (__p_.size() > 1)
62756258 {
62766259 double __s = _VSTD::accumulate(__p_.begin(), __p_.end(), 0.0);
6277 for (_VSTD::vector<double>::iterator __i = __p_.begin(), __e = __p_.end();
6278 __i < __e; ++__i)
6260 for (vector<double>::iterator __i = __p_.begin(), __e = __p_.end(); __i < __e; ++__i)
62796261 *__i /= __s;
62806262 vector<double> __t(__p_.size() - 1);
62816263 _VSTD::partial_sum(__p_.begin(), __p_.end() - 1, __t.begin());
......@@ -6294,7 +6276,7 @@ vector<double>
62946276discrete_distribution<_IntType>::param_type::probabilities() const
62956277{
62966278 size_t __n = __p_.size();
6297 _VSTD::vector<double> __p(__n+1);
6279 vector<double> __p(__n+1);
62986280 _VSTD::adjacent_difference(__p_.begin(), __p_.end(), __p.begin());
62996281 if (__n > 0)
63006282 __p[__n] = 1 - __p_[__n-1];
......@@ -6374,7 +6356,7 @@ public:
63746356#ifndef _LIBCPP_CXX03_LANG
63756357 template<class _UnaryOperation>
63766358 param_type(initializer_list<result_type> __bl, _UnaryOperation __fw);
6377#endif // _LIBCPP_CXX03_LANG
6359#endif // _LIBCPP_CXX03_LANG
63786360 template<class _UnaryOperation>
63796361 param_type(size_t __nw, result_type __xmin, result_type __xmax,
63806362 _UnaryOperation __fw);
......@@ -6431,7 +6413,7 @@ public:
64316413 piecewise_constant_distribution(initializer_list<result_type> __bl,
64326414 _UnaryOperation __fw)
64336415 : __p_(__bl, __fw) {}
6434#endif // _LIBCPP_CXX03_LANG
6416#endif // _LIBCPP_CXX03_LANG
64356417
64366418 template<class _UnaryOperation>
64376419 _LIBCPP_INLINE_VISIBILITY
......@@ -6586,7 +6568,7 @@ piecewise_constant_distribution<_RealType>::param_type::param_type(
65866568 }
65876569}
65886570
6589#endif // _LIBCPP_CXX03_LANG
6571#endif // _LIBCPP_CXX03_LANG
65906572
65916573template<class _RealType>
65926574template<class _UnaryOperation>
......@@ -6700,7 +6682,7 @@ public:
67006682#ifndef _LIBCPP_CXX03_LANG
67016683 template<class _UnaryOperation>
67026684 param_type(initializer_list<result_type> __bl, _UnaryOperation __fw);
6703#endif // _LIBCPP_CXX03_LANG
6685#endif // _LIBCPP_CXX03_LANG
67046686 template<class _UnaryOperation>
67056687 param_type(size_t __nw, result_type __xmin, result_type __xmax,
67066688 _UnaryOperation __fw);
......@@ -6757,7 +6739,7 @@ public:
67576739 piecewise_linear_distribution(initializer_list<result_type> __bl,
67586740 _UnaryOperation __fw)
67596741 : __p_(__bl, __fw) {}
6760#endif // _LIBCPP_CXX03_LANG
6742#endif // _LIBCPP_CXX03_LANG
67616743
67626744 template<class _UnaryOperation>
67636745 _LIBCPP_INLINE_VISIBILITY
......@@ -6916,7 +6898,7 @@ piecewise_linear_distribution<_RealType>::param_type::param_type(
69166898 }
69176899}
69186900
6919#endif // _LIBCPP_CXX03_LANG
6901#endif // _LIBCPP_CXX03_LANG
69206902
69216903template<class _RealType>
69226904template<class _UnaryOperation>
......@@ -7022,4 +7004,4 @@ _LIBCPP_END_NAMESPACE_STD
70227004
70237005_LIBCPP_POP_MACROS
70247006
7025#endif // _LIBCPP_RANDOM
7007#endif // _LIBCPP_RANDOM
lib/libcxx/include/ranges created+209
......@@ -0,0 +1,209 @@
1// -*- C++ -*-
2//===--------------------------- ranges -----------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP_RANGES
11#define _LIBCPP_RANGES
12
13/*
14
15#include <compare> // see [compare.syn]
16#include <initializer_list> // see [initializer.list.syn]
17#include <iterator> // see [iterator.synopsis]
18
19namespace std::ranges {
20 inline namespace unspecified {
21 // [range.access], range access
22 inline constexpr unspecified begin = unspecified;
23 inline constexpr unspecified end = unspecified;
24 inline constexpr unspecified cbegin = unspecified;
25 inline constexpr unspecified cend = unspecified;
26
27 inline constexpr unspecified size = unspecified;
28 inline constexpr unspecified ssize = unspecified;
29 }
30
31 // [range.range], ranges
32 template<class T>
33 concept range = see below;
34
35 template<class T>
36 inline constexpr bool enable_borrowed_range = false;
37
38 template<class T>
39 using iterator_t = decltype(ranges::begin(declval<R&>()));
40 template<range R>
41 using sentinel_t = decltype(ranges::end(declval<R&>()));
42 template<range R>
43 using range_difference_t = iter_difference_t<iterator_t<R>>;
44 template<sized_range R>
45 using range_size_t = decltype(ranges::size(declval<R&>()));
46 template<range R>
47 using range_value_t = iter_value_t<iterator_t<R>>;
48 template<range R>
49 using range_reference_t = iter_reference_t<iterator_t<R>>;
50 template<range R>
51 using range_rvalue_reference_t = iter_rvalue_reference_t<iterator_t<R>>;
52
53 // [range.sized], sized ranges
54 template<class>
55 inline constexpr bool disable_sized_range = false;
56
57 template<class T>
58 concept sized_range = ...;
59
60 // [range.view], views
61 template<class T>
62 inline constexpr bool enable_view = ...;
63
64 struct view_base { };
65
66 template<class T>
67 concept view = ...;
68
69 // [range.refinements], other range refinements
70 template<class R, class T>
71 concept output_range = see below;
72
73 template<class T>
74 concept input_range = see below;
75
76 template<class T>
77 concept forward_range = see below;
78
79 template<class T>
80 concept bidirectional_range = see below;
81
82 template<class T>
83 concept random_access_range = see below;
84
85 template<class T>
86 concept contiguous_range = see below;
87
88 template <class _Tp>
89 concept common_range = see below;
90
91 template<class T>
92 concept viewable_range = see below;
93
94 // [view.interface], class template view_interface
95 template<class D>
96 requires is_class_v<D> && same_as<D, remove_cv_t<D>>
97 class view_interface;
98
99 // [range.subrange], sub-ranges
100 enum class subrange_kind : bool { unsized, sized };
101
102 template<input_or_output_iterator I, sentinel_for<I> S = I, subrange_kind K = see below>
103 requires (K == subrange_kind::sized || !sized_sentinel_for<S, I>)
104 class subrange;
105
106 template<class I, class S, subrange_kind K>
107 inline constexpr bool enable_borrowed_range<subrange<I, S, K>> = true;
108
109 // [range.dangling], dangling iterator handling
110 struct dangling;
111
112 template<range R>
113 using borrowed_iterator_t = see below;
114
115 template<range R>
116 using borrowed_subrange_t = see below;
117
118 // [range.empty], empty view
119 template<class T>
120 requires is_object_v<T>
121 class empty_view;
122
123 // [range.all], all view
124 namespace views {
125 inline constexpr unspecified all = unspecified;
126
127 template<viewable_range R>
128 using all_t = decltype(all(declval<R>()));
129 }
130
131 template<range R>
132 requires is_object_v<R>
133 class ref_view;
134
135 template<class T>
136 inline constexpr bool enable_borrowed_range<ref_view<T>> = true;
137
138 // [range.drop], drop view
139 template<view V>
140 class drop_view;
141
142 template<class T>
143 inline constexpr bool enable_borrowed_range<drop_view<T>> = enable_borrowed_range<T>;
144
145 // [range.transform], transform view
146 template<input_range V, copy_constructible F>
147 requires view<V> && is_object_v<F> &&
148 regular_invocable<F&, range_reference_t<V>> &&
149 can-reference<invoke_result_t<F&, range_reference_t<V>>>
150 class transform_view;
151
152 // [range.common], common view
153 template<view V>
154 requires (!common_range<V> && copyable<iterator_t<V>>)
155 class common_view;
156
157 template<class T>
158 inline constexpr bool enable_borrowed_range<common_view<T>> = enable_borrowed_range<T>;
159}
160
161*/
162
163// Make sure all feature tests macros are always available.
164#include <version>
165// Only enable the contents of the header when libc++ was build with LIBCXX_ENABLE_INCOMPLETE_FEATURES enabled
166#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
167
168#include <__config>
169#include <__ranges/access.h>
170#include <__ranges/all.h>
171#include <__ranges/common_view.h>
172#include <__ranges/concepts.h>
173#include <__ranges/dangling.h>
174#include <__ranges/data.h>
175#include <__ranges/drop_view.h>
176#include <__ranges/empty.h>
177#include <__ranges/empty_view.h>
178#include <__ranges/enable_borrowed_range.h>
179#include <__ranges/enable_view.h>
180#include <__ranges/ref_view.h>
181#include <__ranges/size.h>
182#include <__ranges/subrange.h>
183#include <__ranges/transform_view.h>
184#include <__ranges/view_interface.h>
185#include <compare> // Required by the standard.
186#include <initializer_list> // Required by the standard.
187#include <iterator> // Required by the standard.
188#include <type_traits>
189
190#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
191#pragma GCC system_header
192#endif
193
194_LIBCPP_PUSH_MACROS
195#include <__undef_macros>
196
197_LIBCPP_BEGIN_NAMESPACE_STD
198
199#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_RANGES)
200
201#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_RANGES)
202
203_LIBCPP_END_NAMESPACE_STD
204
205_LIBCPP_POP_MACROS
206
207#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
208
209#endif // _LIBCPP_RANGES
lib/libcxx/include/ratio+6-6
......@@ -78,8 +78,8 @@ typedef ratio<1000000000000000000000000, 1> yotta; // not supported
7878*/
7979
8080#include <__config>
81#include <cstdint>
8281#include <climits>
82#include <cstdint>
8383#include <type_traits>
8484
8585#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
......@@ -312,7 +312,7 @@ template <class _R1, class _R2>
312312struct _LIBCPP_TEMPLATE_VIS ratio_multiply
313313 : public __ratio_multiply<_R1, _R2>::type {};
314314
315#endif // _LIBCPP_CXX03_LANG
315#endif // _LIBCPP_CXX03_LANG
316316
317317template <class _R1, class _R2>
318318struct __ratio_divide
......@@ -339,7 +339,7 @@ template <class _R1, class _R2>
339339struct _LIBCPP_TEMPLATE_VIS ratio_divide
340340 : public __ratio_divide<_R1, _R2>::type {};
341341
342#endif // _LIBCPP_CXX03_LANG
342#endif // _LIBCPP_CXX03_LANG
343343
344344template <class _R1, class _R2>
345345struct __ratio_add
......@@ -374,7 +374,7 @@ template <class _R1, class _R2>
374374struct _LIBCPP_TEMPLATE_VIS ratio_add
375375 : public __ratio_add<_R1, _R2>::type {};
376376
377#endif // _LIBCPP_CXX03_LANG
377#endif // _LIBCPP_CXX03_LANG
378378
379379template <class _R1, class _R2>
380380struct __ratio_subtract
......@@ -409,7 +409,7 @@ template <class _R1, class _R2>
409409struct _LIBCPP_TEMPLATE_VIS ratio_subtract
410410 : public __ratio_subtract<_R1, _R2>::type {};
411411
412#endif // _LIBCPP_CXX03_LANG
412#endif // _LIBCPP_CXX03_LANG
413413
414414// ratio_equal
415415
......@@ -529,4 +529,4 @@ _LIBCPP_END_NAMESPACE_STD
529529
530530_LIBCPP_POP_MACROS
531531
532#endif // _LIBCPP_RATIO
532#endif // _LIBCPP_RATIO
lib/libcxx/include/regex+17-19
......@@ -763,15 +763,18 @@ typedef regex_token_iterator<wstring::const_iterator> wsregex_token_iterator;
763763*/
764764
765765#include <__config>
766#include <stdexcept>
766#include <__debug>
767#include <__iterator/wrap_iter.h>
767768#include <__locale>
769#include <compare>
770#include <deque>
768771#include <initializer_list>
769#include <utility>
770772#include <iterator>
771#include <string>
772773#include <memory>
774#include <stdexcept>
775#include <string>
776#include <utility>
773777#include <vector>
774#include <deque>
775778#include <version>
776779
777780#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
......@@ -2000,14 +2003,14 @@ class __l_anchor_multiline
20002003{
20012004 typedef __owns_one_state<_CharT> base;
20022005
2003 bool __multiline;
2006 bool __multiline_;
20042007
20052008public:
20062009 typedef _VSTD::__state<_CharT> __state;
20072010
20082011 _LIBCPP_INLINE_VISIBILITY
20092012 __l_anchor_multiline(bool __multiline, __node<_CharT>* __s)
2010 : base(__s), __multiline(__multiline) {}
2013 : base(__s), __multiline_(__multiline) {}
20112014
20122015 virtual void __exec(__state&) const;
20132016};
......@@ -2022,7 +2025,7 @@ __l_anchor_multiline<_CharT>::__exec(__state& __s) const
20222025 __s.__do_ = __state::__accept_but_not_consume;
20232026 __s.__node_ = this->first();
20242027 }
2025 else if (__multiline &&
2028 else if (__multiline_ &&
20262029 !__s.__at_first_ &&
20272030 __is_eol(*_VSTD::prev(__s.__current_)))
20282031 {
......@@ -2634,7 +2637,7 @@ public:
26342637 {
26352638 __init(__il.begin(), __il.end());
26362639 }
2637#endif // _LIBCPP_CXX03_LANG
2640#endif // _LIBCPP_CXX03_LANG
26382641
26392642// ~basic_regex() = default;
26402643
......@@ -2647,7 +2650,7 @@ public:
26472650 _LIBCPP_INLINE_VISIBILITY
26482651 basic_regex& operator=(initializer_list<value_type> __il)
26492652 {return assign(__il);}
2650#endif // _LIBCPP_CXX03_LANG
2653#endif // _LIBCPP_CXX03_LANG
26512654 template <class _ST, class _SA>
26522655 _LIBCPP_INLINE_VISIBILITY
26532656 basic_regex& operator=(const basic_string<value_type, _ST, _SA>& __p)
......@@ -2721,7 +2724,7 @@ public:
27212724 flag_type __f = regex_constants::ECMAScript)
27222725 {return assign(__il.begin(), __il.end(), __f);}
27232726
2724#endif // _LIBCPP_CXX03_LANG
2727#endif // _LIBCPP_CXX03_LANG
27252728
27262729 // const operations:
27272730 _LIBCPP_INLINE_VISIBILITY
......@@ -4571,7 +4574,7 @@ basic_regex<_CharT, _Traits>::__parse_character_escape(_ForwardIterator __first,
45714574 if (__hd == -1)
45724575 __throw_regex_error<regex_constants::error_escape>();
45734576 __sum = 16 * __sum + static_cast<unsigned>(__hd);
4574 // drop through
4577 // fallthrough
45754578 case 'x':
45764579 ++__first;
45774580 if (__first == __last)
......@@ -5882,7 +5885,6 @@ basic_regex<_CharT, _Traits>::__match_at_start_posix_subs(
58825885{
58835886 vector<__state> __states;
58845887 __state __best_state;
5885 ptrdiff_t __j = 0;
58865888 ptrdiff_t __highest_j = 0;
58875889 ptrdiff_t _Np = _VSTD::distance(__first, __last);
58885890 __node* __st = __start_.get();
......@@ -5903,7 +5905,6 @@ basic_regex<_CharT, _Traits>::__match_at_start_posix_subs(
59035905 __states.back().__node_ = __st;
59045906 __states.back().__flags_ = __flags;
59055907 __states.back().__at_first_ = __at_first;
5906 const _CharT* __current = __first;
59075908 bool __matched = false;
59085909 int __counter = 0;
59095910 int __length = __last - __first;
......@@ -5943,9 +5944,6 @@ basic_regex<_CharT, _Traits>::__match_at_start_posix_subs(
59435944 __states.pop_back();
59445945 break;
59455946 case __state::__accept_and_consume:
5946 __j += __s.__current_ - __current;
5947 __current = __s.__current_;
5948 break;
59495947 case __state::__repeat:
59505948 case __state::__accept_but_not_consume:
59515949 break;
......@@ -6442,7 +6440,7 @@ public:
64426440 regex_constants::match_flag_type __m =
64436441 regex_constants::match_default) = delete;
64446442#endif
6445#endif // _LIBCPP_CXX03_LANG
6443#endif // _LIBCPP_CXX03_LANG
64466444 template <size_t _Np>
64476445 regex_token_iterator(_BidirectionalIterator __a,
64486446 _BidirectionalIterator __b,
......@@ -6557,7 +6555,7 @@ regex_token_iterator<_BidirectionalIterator, _CharT, _Traits>::
65576555 __init(__a, __b);
65586556}
65596557
6560#endif // _LIBCPP_CXX03_LANG
6558#endif // _LIBCPP_CXX03_LANG
65616559
65626560template <class _BidirectionalIterator, class _CharT, class _Traits>
65636561template <size_t _Np>
......@@ -6774,4 +6772,4 @@ _LIBCPP_END_NAMESPACE_STD
67746772
67756773_LIBCPP_POP_MACROS
67766774
6777#endif // _LIBCPP_REGEX
6775#endif // _LIBCPP_REGEX
lib/libcxx/include/scoped_allocator+4-3
......@@ -106,6 +106,7 @@ template <class OuterA1, class OuterA2, class... InnerAllocs>
106106*/
107107
108108#include <__config>
109#include <__utility/forward.h>
109110#include <memory>
110111#include <version>
111112
......@@ -375,7 +376,7 @@ struct __outermost<_Alloc, true>
375376{
376377 typedef typename remove_reference
377378 <
378 decltype(_VSTD::declval<_Alloc>().outer_allocator())
379 decltype(declval<_Alloc>().outer_allocator())
379380 >::type _OuterAlloc;
380381 typedef typename __outermost<_OuterAlloc>::type type;
381382 _LIBCPP_INLINE_VISIBILITY
......@@ -676,8 +677,8 @@ operator!=(const scoped_allocator_adaptor<_OuterA1, _InnerAllocs...>& __a,
676677 return !(__a == __b);
677678}
678679
679#endif // !defined(_LIBCPP_CXX03_LANG)
680#endif // !defined(_LIBCPP_CXX03_LANG)
680681
681682_LIBCPP_END_NAMESPACE_STD
682683
683#endif // _LIBCPP_SCOPED_ALLOCATOR
684#endif // _LIBCPP_SCOPED_ALLOCATOR
lib/libcxx/include/semaphore+3-3
......@@ -45,8 +45,8 @@ using binary_semaphore = counting_semaphore<1>;
4545
4646*/
4747
48#include <__config>
4948#include <__availability>
49#include <__config>
5050#include <__threading_support>
5151#include <atomic>
5252
......@@ -98,7 +98,7 @@ public:
9898 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
9999 void acquire()
100100 {
101 auto const __test_fn = [=]() -> bool {
101 auto const __test_fn = [this]() -> bool {
102102 auto __old = __a.load(memory_order_relaxed);
103103 return (__old != 0) && __a.compare_exchange_strong(__old, __old - 1, memory_order_acquire, memory_order_relaxed);
104104 };
......@@ -108,7 +108,7 @@ public:
108108 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
109109 bool try_acquire_for(chrono::duration<Rep, Period> const& __rel_time)
110110 {
111 auto const __test_fn = [=]() -> bool {
111 auto const __test_fn = [this]() -> bool {
112112 auto __old = __a.load(memory_order_acquire);
113113 while(1) {
114114 if (__old == 0)
lib/libcxx/include/set+60-38
......@@ -154,10 +154,14 @@ public:
154154 iterator find(const K& x);
155155 template<typename K>
156156 const_iterator find(const K& x) const; // C++14
157
157158 template<typename K>
158159 size_type count(const K& x) const; // C++14
159160 size_type count(const key_type& k) const;
160 bool contains(const key_type& x) const; // C++20
161
162 bool contains(const key_type& x) const; // C++20
163 template<class K> bool contains(const K& x) const; // C++20
164
161165 iterator lower_bound(const key_type& k);
162166 const_iterator lower_bound(const key_type& k) const;
163167 template<typename K>
......@@ -355,10 +359,14 @@ public:
355359 iterator find(const K& x);
356360 template<typename K>
357361 const_iterator find(const K& x) const; // C++14
362
358363 template<typename K>
359364 size_type count(const K& x) const; // C++14
360365 size_type count(const key_type& k) const;
361 bool contains(const key_type& x) const; // C++20
366
367 bool contains(const key_type& x) const; // C++20
368 template<class K> bool contains(const K& x) const; // C++20
369
362370 iterator lower_bound(const key_type& k);
363371 const_iterator lower_bound(const key_type& k) const;
364372 template<typename K>
......@@ -426,9 +434,15 @@ erase_if(multiset<Key, Compare, Allocator>& c, Predicate pred); // C++20
426434*/
427435
428436#include <__config>
429#include <__tree>
437#include <__debug>
438#include <__functional/is_transparent.h>
430439#include <__node_handle>
440#include <__tree>
441#include <__utility/forward.h>
442#include <compare>
431443#include <functional>
444#include <initializer_list>
445#include <iterator> // __libcpp_erase_if_container
432446#include <version>
433447
434448#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
......@@ -450,7 +464,7 @@ public:
450464 typedef key_type value_type;
451465 typedef _Compare key_compare;
452466 typedef key_compare value_compare;
453 typedef typename __identity<_Allocator>::type allocator_type;
467 typedef __identity_t<_Allocator> allocator_type;
454468 typedef value_type& reference;
455469 typedef const value_type& const_reference;
456470
......@@ -546,7 +560,7 @@ public:
546560 set(set&& __s)
547561 _NOEXCEPT_(is_nothrow_move_constructible<__base>::value)
548562 : __tree_(_VSTD::move(__s.__tree_)) {}
549#endif // _LIBCPP_CXX03_LANG
563#endif // _LIBCPP_CXX03_LANG
550564
551565 _LIBCPP_INLINE_VISIBILITY
552566 explicit set(const allocator_type& __a)
......@@ -597,7 +611,7 @@ public:
597611 __tree_ = _VSTD::move(__s.__tree_);
598612 return *this;
599613 }
600#endif // _LIBCPP_CXX03_LANG
614#endif // _LIBCPP_CXX03_LANG
601615
602616 _LIBCPP_INLINE_VISIBILITY
603617 ~set() {
......@@ -652,7 +666,7 @@ public:
652666 _LIBCPP_INLINE_VISIBILITY
653667 iterator emplace_hint(const_iterator __p, _Args&&... __args)
654668 {return __tree_.__emplace_hint_unique(__p, _VSTD::forward<_Args>(__args)...);}
655#endif // _LIBCPP_CXX03_LANG
669#endif // _LIBCPP_CXX03_LANG
656670
657671 _LIBCPP_INLINE_VISIBILITY
658672 pair<iterator,bool> insert(const value_type& __v)
......@@ -681,7 +695,7 @@ public:
681695 _LIBCPP_INLINE_VISIBILITY
682696 void insert(initializer_list<value_type> __il)
683697 {insert(__il.begin(), __il.end());}
684#endif // _LIBCPP_CXX03_LANG
698#endif // _LIBCPP_CXX03_LANG
685699
686700 _LIBCPP_INLINE_VISIBILITY
687701 iterator erase(const_iterator __p) {return __tree_.erase(__p);}
......@@ -795,6 +809,10 @@ public:
795809#if _LIBCPP_STD_VER > 17
796810 _LIBCPP_INLINE_VISIBILITY
797811 bool contains(const key_type& __k) const {return find(__k) != end();}
812 template <typename _K2>
813 _LIBCPP_INLINE_VISIBILITY
814 typename enable_if<__is_transparent<_Compare, _K2>::value, bool>::type
815 contains(const _K2& __k) const { return find(__k) != end(); }
798816#endif // _LIBCPP_STD_VER > 17
799817
800818 _LIBCPP_INLINE_VISIBILITY
......@@ -852,12 +870,12 @@ public:
852870
853871#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
854872template<class _InputIterator,
855 class _Compare = less<typename iterator_traits<_InputIterator>::value_type>,
856 class _Allocator = allocator<typename iterator_traits<_InputIterator>::value_type>,
873 class _Compare = less<__iter_value_type<_InputIterator>>,
874 class _Allocator = allocator<__iter_value_type<_InputIterator>>,
857875 class = _EnableIf<__is_allocator<_Allocator>::value, void>,
858876 class = _EnableIf<!__is_allocator<_Compare>::value, void>>
859877set(_InputIterator, _InputIterator, _Compare = _Compare(), _Allocator = _Allocator())
860 -> set<typename iterator_traits<_InputIterator>::value_type, _Compare, _Allocator>;
878 -> set<__iter_value_type<_InputIterator>, _Compare, _Allocator>;
861879
862880template<class _Key, class _Compare = less<_Key>,
863881 class _Allocator = allocator<_Key>,
......@@ -869,8 +887,8 @@ set(initializer_list<_Key>, _Compare = _Compare(), _Allocator = _Allocator())
869887template<class _InputIterator, class _Allocator,
870888 class = _EnableIf<__is_allocator<_Allocator>::value, void>>
871889set(_InputIterator, _InputIterator, _Allocator)
872 -> set<typename iterator_traits<_InputIterator>::value_type,
873 less<typename iterator_traits<_InputIterator>::value_type>, _Allocator>;
890 -> set<__iter_value_type<_InputIterator>,
891 less<__iter_value_type<_InputIterator>>, _Allocator>;
874892
875893template<class _Key, class _Allocator,
876894 class = _EnableIf<__is_allocator<_Allocator>::value, void>>
......@@ -892,7 +910,7 @@ set<_Key, _Compare, _Allocator>::set(set&& __s, const allocator_type& __a)
892910 }
893911}
894912
895#endif // _LIBCPP_CXX03_LANG
913#endif // _LIBCPP_CXX03_LANG
896914
897915template <class _Key, class _Compare, class _Allocator>
898916inline _LIBCPP_INLINE_VISIBILITY
......@@ -964,7 +982,7 @@ template <class _Key, class _Compare, class _Allocator, class _Predicate>
964982inline _LIBCPP_INLINE_VISIBILITY
965983 typename set<_Key, _Compare, _Allocator>::size_type
966984 erase_if(set<_Key, _Compare, _Allocator>& __c, _Predicate __pred) {
967 return __libcpp_erase_if_container(__c, __pred);
985 return _VSTD::__libcpp_erase_if_container(__c, __pred);
968986}
969987#endif
970988
......@@ -974,11 +992,11 @@ class _LIBCPP_TEMPLATE_VIS multiset
974992{
975993public:
976994 // types:
977 typedef _Key key_type;
995 typedef _Key key_type;
978996 typedef key_type value_type;
979 typedef _Compare key_compare;
997 typedef _Compare key_compare;
980998 typedef key_compare value_compare;
981 typedef typename __identity<_Allocator>::type allocator_type;
999 typedef __identity_t<_Allocator> allocator_type;
9821000 typedef value_type& reference;
9831001 typedef const value_type& const_reference;
9841002
......@@ -1077,7 +1095,7 @@ public:
10771095 : __tree_(_VSTD::move(__s.__tree_)) {}
10781096
10791097 multiset(multiset&& __s, const allocator_type& __a);
1080#endif // _LIBCPP_CXX03_LANG
1098#endif // _LIBCPP_CXX03_LANG
10811099 _LIBCPP_INLINE_VISIBILITY
10821100 explicit multiset(const allocator_type& __a)
10831101 : __tree_(__a) {}
......@@ -1124,7 +1142,7 @@ public:
11241142 __tree_ = _VSTD::move(__s.__tree_);
11251143 return *this;
11261144 }
1127#endif // _LIBCPP_CXX03_LANG
1145#endif // _LIBCPP_CXX03_LANG
11281146
11291147 _LIBCPP_INLINE_VISIBILITY
11301148 ~multiset() {
......@@ -1179,7 +1197,7 @@ public:
11791197 _LIBCPP_INLINE_VISIBILITY
11801198 iterator emplace_hint(const_iterator __p, _Args&&... __args)
11811199 {return __tree_.__emplace_hint_multi(__p, _VSTD::forward<_Args>(__args)...);}
1182#endif // _LIBCPP_CXX03_LANG
1200#endif // _LIBCPP_CXX03_LANG
11831201
11841202 _LIBCPP_INLINE_VISIBILITY
11851203 iterator insert(const value_type& __v)
......@@ -1208,7 +1226,7 @@ public:
12081226 _LIBCPP_INLINE_VISIBILITY
12091227 void insert(initializer_list<value_type> __il)
12101228 {insert(__il.begin(), __il.end());}
1211#endif // _LIBCPP_CXX03_LANG
1229#endif // _LIBCPP_CXX03_LANG
12121230
12131231 _LIBCPP_INLINE_VISIBILITY
12141232 iterator erase(const_iterator __p) {return __tree_.erase(__p);}
......@@ -1301,11 +1319,11 @@ public:
13011319#if _LIBCPP_STD_VER > 11
13021320 template <typename _K2>
13031321 _LIBCPP_INLINE_VISIBILITY
1304 typename _VSTD::enable_if<_VSTD::__is_transparent<_Compare, _K2>::value,iterator>::type
1322 typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type
13051323 find(const _K2& __k) {return __tree_.find(__k);}
13061324 template <typename _K2>
13071325 _LIBCPP_INLINE_VISIBILITY
1308 typename _VSTD::enable_if<_VSTD::__is_transparent<_Compare, _K2>::value,const_iterator>::type
1326 typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type
13091327 find(const _K2& __k) const {return __tree_.find(__k);}
13101328#endif
13111329
......@@ -1322,6 +1340,10 @@ public:
13221340#if _LIBCPP_STD_VER > 17
13231341 _LIBCPP_INLINE_VISIBILITY
13241342 bool contains(const key_type& __k) const {return find(__k) != end();}
1343 template <typename _K2>
1344 _LIBCPP_INLINE_VISIBILITY
1345 typename enable_if<__is_transparent<_Compare, _K2>::value, bool>::type
1346 contains(const _K2& __k) const { return find(__k) != end(); }
13251347#endif // _LIBCPP_STD_VER > 17
13261348
13271349 _LIBCPP_INLINE_VISIBILITY
......@@ -1333,12 +1355,12 @@ public:
13331355#if _LIBCPP_STD_VER > 11
13341356 template <typename _K2>
13351357 _LIBCPP_INLINE_VISIBILITY
1336 typename _VSTD::enable_if<_VSTD::__is_transparent<_Compare, _K2>::value,iterator>::type
1358 typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type
13371359 lower_bound(const _K2& __k) {return __tree_.lower_bound(__k);}
13381360
13391361 template <typename _K2>
13401362 _LIBCPP_INLINE_VISIBILITY
1341 typename _VSTD::enable_if<_VSTD::__is_transparent<_Compare, _K2>::value,const_iterator>::type
1363 typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type
13421364 lower_bound(const _K2& __k) const {return __tree_.lower_bound(__k);}
13431365#endif
13441366
......@@ -1351,11 +1373,11 @@ public:
13511373#if _LIBCPP_STD_VER > 11
13521374 template <typename _K2>
13531375 _LIBCPP_INLINE_VISIBILITY
1354 typename _VSTD::enable_if<_VSTD::__is_transparent<_Compare, _K2>::value,iterator>::type
1376 typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type
13551377 upper_bound(const _K2& __k) {return __tree_.upper_bound(__k);}
13561378 template <typename _K2>
13571379 _LIBCPP_INLINE_VISIBILITY
1358 typename _VSTD::enable_if<_VSTD::__is_transparent<_Compare, _K2>::value,const_iterator>::type
1380 typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type
13591381 upper_bound(const _K2& __k) const {return __tree_.upper_bound(__k);}
13601382#endif
13611383
......@@ -1368,23 +1390,23 @@ public:
13681390#if _LIBCPP_STD_VER > 11
13691391 template <typename _K2>
13701392 _LIBCPP_INLINE_VISIBILITY
1371 typename _VSTD::enable_if<_VSTD::__is_transparent<_Compare, _K2>::value,pair<iterator,iterator>>::type
1393 typename enable_if<__is_transparent<_Compare, _K2>::value,pair<iterator,iterator>>::type
13721394 equal_range(const _K2& __k) {return __tree_.__equal_range_multi(__k);}
13731395 template <typename _K2>
13741396 _LIBCPP_INLINE_VISIBILITY
1375 typename _VSTD::enable_if<_VSTD::__is_transparent<_Compare, _K2>::value,pair<const_iterator,const_iterator>>::type
1397 typename enable_if<__is_transparent<_Compare, _K2>::value,pair<const_iterator,const_iterator>>::type
13761398 equal_range(const _K2& __k) const {return __tree_.__equal_range_multi(__k);}
13771399#endif
13781400};
13791401
13801402#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
13811403template<class _InputIterator,
1382 class _Compare = less<typename iterator_traits<_InputIterator>::value_type>,
1383 class _Allocator = allocator<typename iterator_traits<_InputIterator>::value_type>,
1404 class _Compare = less<__iter_value_type<_InputIterator>>,
1405 class _Allocator = allocator<__iter_value_type<_InputIterator>>,
13841406 class = _EnableIf<__is_allocator<_Allocator>::value, void>,
13851407 class = _EnableIf<!__is_allocator<_Compare>::value, void>>
13861408multiset(_InputIterator, _InputIterator, _Compare = _Compare(), _Allocator = _Allocator())
1387 -> multiset<typename iterator_traits<_InputIterator>::value_type, _Compare, _Allocator>;
1409 -> multiset<__iter_value_type<_InputIterator>, _Compare, _Allocator>;
13881410
13891411template<class _Key, class _Compare = less<_Key>,
13901412 class _Allocator = allocator<_Key>,
......@@ -1396,8 +1418,8 @@ multiset(initializer_list<_Key>, _Compare = _Compare(), _Allocator = _Allocator(
13961418template<class _InputIterator, class _Allocator,
13971419 class = _EnableIf<__is_allocator<_Allocator>::value, void>>
13981420multiset(_InputIterator, _InputIterator, _Allocator)
1399 -> multiset<typename iterator_traits<_InputIterator>::value_type,
1400 less<typename iterator_traits<_InputIterator>::value_type>, _Allocator>;
1421 -> multiset<__iter_value_type<_InputIterator>,
1422 less<__iter_value_type<_InputIterator>>, _Allocator>;
14011423
14021424template<class _Key, class _Allocator,
14031425 class = _EnableIf<__is_allocator<_Allocator>::value, void>>
......@@ -1419,7 +1441,7 @@ multiset<_Key, _Compare, _Allocator>::multiset(multiset&& __s, const allocator_t
14191441 }
14201442}
14211443
1422#endif // _LIBCPP_CXX03_LANG
1444#endif // _LIBCPP_CXX03_LANG
14231445
14241446template <class _Key, class _Compare, class _Allocator>
14251447inline _LIBCPP_INLINE_VISIBILITY
......@@ -1490,10 +1512,10 @@ template <class _Key, class _Compare, class _Allocator, class _Predicate>
14901512inline _LIBCPP_INLINE_VISIBILITY
14911513 typename multiset<_Key, _Compare, _Allocator>::size_type
14921514 erase_if(multiset<_Key, _Compare, _Allocator>& __c, _Predicate __pred) {
1493 return __libcpp_erase_if_container(__c, __pred);
1515 return _VSTD::__libcpp_erase_if_container(__c, __pred);
14941516}
14951517#endif
14961518
14971519_LIBCPP_END_NAMESPACE_STD
14981520
1499#endif // _LIBCPP_SET
1521#endif // _LIBCPP_SET
lib/libcxx/include/setjmp.h+1-1
......@@ -41,4 +41,4 @@ void longjmp(jmp_buf env, int val);
4141
4242#endif // __cplusplus
4343
44#endif // _LIBCPP_SETJMP_H
44#endif // _LIBCPP_SETJMP_H
lib/libcxx/include/shared_mutex+4-4
......@@ -122,8 +122,8 @@ template <class Mutex>
122122
123123*/
124124
125#include <__config>
126125#include <__availability>
126#include <__config>
127127#include <version>
128128
129129_LIBCPP_PUSH_MACROS
......@@ -500,10 +500,10 @@ swap(shared_lock<_Mutex>& __x, shared_lock<_Mutex>& __y) _NOEXCEPT
500500
501501_LIBCPP_END_NAMESPACE_STD
502502
503#endif // !_LIBCPP_HAS_NO_THREADS
503#endif // !_LIBCPP_HAS_NO_THREADS
504504
505#endif // _LIBCPP_STD_VER > 11
505#endif // _LIBCPP_STD_VER > 11
506506
507507_LIBCPP_POP_MACROS
508508
509#endif // _LIBCPP_SHARED_MUTEX
509#endif // _LIBCPP_SHARED_MUTEX
lib/libcxx/include/span+30-3
......@@ -22,6 +22,12 @@ inline constexpr size_t dynamic_extent = numeric_limits<size_t>::max();
2222template <class ElementType, size_t Extent = dynamic_extent>
2323 class span;
2424
25template<class ElementType, size_t Extent>
26 inline constexpr bool ranges::enable_view<span<ElementType, Extent>> = true;
27
28template<class ElementType, size_t Extent>
29 inline constexpr bool ranges::enable_borrowed_range<span<ElementType, Extent>> = true;
30
2531// [span.objectrep], views of object representation
2632template <class ElementType, size_t Extent>
2733 span<const byte, ((Extent == dynamic_extent) ? dynamic_extent :
......@@ -32,7 +38,6 @@ template <class ElementType, size_t Extent>
3238 (sizeof(ElementType) * Extent))> as_writable_bytes(span<ElementType, Extent> s) noexcept;
3339
3440
35namespace std {
3641template <class ElementType, size_t Extent = dynamic_extent>
3742class span {
3843public:
......@@ -123,10 +128,16 @@ template<class Container>
123128*/
124129
125130#include <__config>
131#include <__debug>
132#include <__iterator/wrap_iter.h>
133#include <__ranges/enable_borrowed_range.h>
134#include <__ranges/enable_view.h>
126135#include <array> // for array
127136#include <cstddef> // for byte
128137#include <iterator> // for iterators
138#include <limits>
129139#include <type_traits> // for remove_cv, etc
140#include <version>
130141
131142#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
132143#pragma GCC system_header
......@@ -197,7 +208,11 @@ public:
197208 using const_pointer = const _Tp *;
198209 using reference = _Tp &;
199210 using const_reference = const _Tp &;
200 using iterator = __wrap_iter<pointer>;
211#if (_LIBCPP_DEBUG_LEVEL == 2) || defined(_LIBCPP_ABI_SPAN_POINTER_ITERATORS)
212 using iterator = pointer;
213#else
214 using iterator = __wrap_iter<pointer>;
215#endif
201216 using reverse_iterator = _VSTD::reverse_iterator<iterator>;
202217
203218 static constexpr size_type extent = _Extent;
......@@ -372,7 +387,11 @@ public:
372387 using const_pointer = const _Tp *;
373388 using reference = _Tp &;
374389 using const_reference = const _Tp &;
375 using iterator = __wrap_iter<pointer>;
390#if (_LIBCPP_DEBUG_LEVEL == 2) || defined(_LIBCPP_ABI_SPAN_POINTER_ITERATORS)
391 using iterator = pointer;
392#else
393 using iterator = __wrap_iter<pointer>;
394#endif
376395 using reverse_iterator = _VSTD::reverse_iterator<iterator>;
377396
378397 static constexpr size_type extent = dynamic_extent;
......@@ -516,6 +535,14 @@ private:
516535 size_type __size;
517536};
518537
538#if !defined(_LIBCPP_HAS_NO_RANGES)
539template <class _Tp, size_t _Extent>
540inline constexpr bool ranges::enable_borrowed_range<span<_Tp, _Extent> > = true;
541
542template <class _ElementType, size_t _Extent>
543inline constexpr bool ranges::enable_view<span<_ElementType, _Extent>> = true;
544#endif // !defined(_LIBCPP_HAS_NO_RANGES)
545
519546// as_bytes & as_writable_bytes
520547template <class _Tp, size_t _Extent>
521548_LIBCPP_INLINE_VISIBILITY
lib/libcxx/include/sstream+13-37
......@@ -181,8 +181,8 @@ typedef basic_stringstream<wchar_t> wstringstream;
181181*/
182182
183183#include <__config>
184#include <ostream>
185184#include <istream>
185#include <ostream>
186186#include <string>
187187
188188#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
......@@ -219,19 +219,13 @@ private:
219219
220220public:
221221 // 30.8.2.1 [stringbuf.cons], constructors
222#ifndef _LIBCPP_CXX03_LANG
223222 _LIBCPP_INLINE_VISIBILITY
224 basic_stringbuf() : basic_stringbuf(ios_base::in | ios_base::out) {}
223 basic_stringbuf()
224 : __hm_(nullptr), __mode_(ios_base::in | ios_base::out) {}
225225
226226 _LIBCPP_INLINE_VISIBILITY
227227 explicit basic_stringbuf(ios_base::openmode __wch)
228228 : __hm_(nullptr), __mode_(__wch) {}
229#else
230 _LIBCPP_INLINE_VISIBILITY
231 explicit basic_stringbuf(ios_base::openmode __wch = ios_base::in |
232 ios_base::out)
233 : __hm_(nullptr), __mode_(__wch) {}
234#endif
235229
236230 _LIBCPP_INLINE_VISIBILITY
237231 explicit basic_stringbuf(const string_type& __s,
......@@ -542,7 +536,7 @@ basic_stringbuf<_CharT, _Traits, _Allocator>::overflow(int_type __c)
542536#ifndef _LIBCPP_NO_EXCEPTIONS
543537 try
544538 {
545#endif // _LIBCPP_NO_EXCEPTIONS
539#endif // _LIBCPP_NO_EXCEPTIONS
546540 ptrdiff_t __nout = this->pptr() - this->pbase();
547541 ptrdiff_t __hm = __hm_ - this->pbase();
548542 __str_.push_back(char_type());
......@@ -557,7 +551,7 @@ basic_stringbuf<_CharT, _Traits, _Allocator>::overflow(int_type __c)
557551 {
558552 return traits_type::eof();
559553 }
560#endif // _LIBCPP_NO_EXCEPTIONS
554#endif // _LIBCPP_NO_EXCEPTIONS
561555 }
562556 __hm_ = _VSTD::max(this->pptr() + 1, __hm_);
563557 if (__mode_ & ios_base::in)
......@@ -643,18 +637,13 @@ private:
643637
644638public:
645639 // 30.8.3.1 [istringstream.cons], constructors
646#ifndef _LIBCPP_CXX03_LANG
647640 _LIBCPP_INLINE_VISIBILITY
648 basic_istringstream() : basic_istringstream(ios_base::in) {}
641 basic_istringstream()
642 : basic_istream<_CharT, _Traits>(&__sb_), __sb_(ios_base::in) {}
649643
650644 _LIBCPP_INLINE_VISIBILITY
651645 explicit basic_istringstream(ios_base::openmode __wch)
652646 : basic_istream<_CharT, _Traits>(&__sb_), __sb_(__wch | ios_base::in) {}
653#else
654 _LIBCPP_INLINE_VISIBILITY
655 explicit basic_istringstream(ios_base::openmode __wch = ios_base::in)
656 : basic_istream<_CharT, _Traits>(&__sb_), __sb_(__wch | ios_base::in) {}
657#endif
658647
659648 _LIBCPP_INLINE_VISIBILITY
660649 explicit basic_istringstream(const string_type& __s,
......@@ -728,20 +717,13 @@ private:
728717
729718public:
730719 // 30.8.4.1 [ostringstream.cons], constructors
731#ifndef _LIBCPP_CXX03_LANG
732720 _LIBCPP_INLINE_VISIBILITY
733 basic_ostringstream() : basic_ostringstream(ios_base::out) {}
721 basic_ostringstream()
722 : basic_ostream<_CharT, _Traits>(&__sb_), __sb_(ios_base::out) {}
734723
735724 _LIBCPP_INLINE_VISIBILITY
736725 explicit basic_ostringstream(ios_base::openmode __wch)
737 : basic_ostream<_CharT, _Traits>(&__sb_),
738 __sb_(__wch | ios_base::out) {}
739#else
740 _LIBCPP_INLINE_VISIBILITY
741 explicit basic_ostringstream(ios_base::openmode __wch = ios_base::out)
742 : basic_ostream<_CharT, _Traits>(&__sb_),
743 __sb_(__wch | ios_base::out) {}
744#endif
726 : basic_ostream<_CharT, _Traits>(&__sb_), __sb_(__wch | ios_base::out) {}
745727
746728 _LIBCPP_INLINE_VISIBILITY
747729 explicit basic_ostringstream(const string_type& __s,
......@@ -816,19 +798,13 @@ private:
816798
817799public:
818800 // 30.8.5.1 [stringstream.cons], constructors
819#ifndef _LIBCPP_CXX03_LANG
820801 _LIBCPP_INLINE_VISIBILITY
821 basic_stringstream() : basic_stringstream(ios_base::in | ios_base::out) {}
802 basic_stringstream()
803 : basic_iostream<_CharT, _Traits>(&__sb_), __sb_(ios_base::in | ios_base::out) {}
822804
823805 _LIBCPP_INLINE_VISIBILITY
824806 explicit basic_stringstream(ios_base::openmode __wch)
825807 : basic_iostream<_CharT, _Traits>(&__sb_), __sb_(__wch) {}
826#else
827 _LIBCPP_INLINE_VISIBILITY
828 explicit basic_stringstream(ios_base::openmode __wch = ios_base::in |
829 ios_base::out)
830 : basic_iostream<_CharT, _Traits>(&__sb_), __sb_(__wch) {}
831#endif
832808
833809 _LIBCPP_INLINE_VISIBILITY
834810 explicit basic_stringstream(const string_type& __s,
......@@ -892,4 +868,4 @@ _LIBCPP_END_NAMESPACE_STD
892868
893869_LIBCPP_POP_MACROS
894870
895#endif // _LIBCPP_SSTREAM
871#endif // _LIBCPP_SSTREAM
lib/libcxx/include/stack+15-21
......@@ -88,6 +88,8 @@ template <class T, class Container>
8888*/
8989
9090#include <__config>
91#include <__memory/uses_allocator.h>
92#include <__utility/forward.h>
9193#include <deque>
9294
9395#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
......@@ -148,7 +150,7 @@ public:
148150
149151 _LIBCPP_INLINE_VISIBILITY
150152 explicit stack(container_type&& __c) : c(_VSTD::move(__c)) {}
151#endif // _LIBCPP_CXX03_LANG
153#endif // _LIBCPP_CXX03_LANG
152154
153155 _LIBCPP_INLINE_VISIBILITY
154156 explicit stack(const container_type& __c) : c(__c) {}
......@@ -156,35 +158,30 @@ public:
156158 template <class _Alloc>
157159 _LIBCPP_INLINE_VISIBILITY
158160 explicit stack(const _Alloc& __a,
159 typename enable_if<uses_allocator<container_type,
160 _Alloc>::value>::type* = 0)
161 _EnableIf<uses_allocator<container_type, _Alloc>::value>* = 0)
161162 : c(__a) {}
162163 template <class _Alloc>
163164 _LIBCPP_INLINE_VISIBILITY
164165 stack(const container_type& __c, const _Alloc& __a,
165 typename enable_if<uses_allocator<container_type,
166 _Alloc>::value>::type* = 0)
166 _EnableIf<uses_allocator<container_type, _Alloc>::value>* = 0)
167167 : c(__c, __a) {}
168168 template <class _Alloc>
169169 _LIBCPP_INLINE_VISIBILITY
170170 stack(const stack& __s, const _Alloc& __a,
171 typename enable_if<uses_allocator<container_type,
172 _Alloc>::value>::type* = 0)
171 _EnableIf<uses_allocator<container_type, _Alloc>::value>* = 0)
173172 : c(__s.c, __a) {}
174173#ifndef _LIBCPP_CXX03_LANG
175174 template <class _Alloc>
176175 _LIBCPP_INLINE_VISIBILITY
177176 stack(container_type&& __c, const _Alloc& __a,
178 typename enable_if<uses_allocator<container_type,
179 _Alloc>::value>::type* = 0)
177 _EnableIf<uses_allocator<container_type, _Alloc>::value>* = 0)
180178 : c(_VSTD::move(__c), __a) {}
181179 template <class _Alloc>
182180 _LIBCPP_INLINE_VISIBILITY
183181 stack(stack&& __s, const _Alloc& __a,
184 typename enable_if<uses_allocator<container_type,
185 _Alloc>::value>::type* = 0)
182 _EnableIf<uses_allocator<container_type, _Alloc>::value>* = 0)
186183 : c(_VSTD::move(__s.c), __a) {}
187#endif // _LIBCPP_CXX03_LANG
184#endif // _LIBCPP_CXX03_LANG
188185
189186 _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
190187 bool empty() const {return c.empty();}
......@@ -210,7 +207,7 @@ public:
210207 void emplace(_Args&&... __args)
211208 { c.emplace_back(_VSTD::forward<_Args>(__args)...);}
212209#endif
213#endif // _LIBCPP_CXX03_LANG
210#endif // _LIBCPP_CXX03_LANG
214211
215212 _LIBCPP_INLINE_VISIBILITY
216213 void pop() {c.pop_back();}
......@@ -236,15 +233,15 @@ public:
236233
237234#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
238235template<class _Container,
239 class = typename enable_if<!__is_allocator<_Container>::value, nullptr_t>::type
236 class = _EnableIf<!__is_allocator<_Container>::value>
240237>
241238stack(_Container)
242239 -> stack<typename _Container::value_type, _Container>;
243240
244241template<class _Container,
245242 class _Alloc,
246 class = typename enable_if<!__is_allocator<_Container>::value, nullptr_t>::type,
247 class = typename enable_if< __is_allocator<_Alloc>::value, nullptr_t>::type
243 class = _EnableIf<!__is_allocator<_Container>::value>,
244 class = _EnableIf<uses_allocator<_Container, _Alloc>::value>
248245 >
249246stack(_Container, _Alloc)
250247 -> stack<typename _Container::value_type, _Container>;
......@@ -300,10 +297,7 @@ operator<=(const stack<_Tp, _Container>& __x, const stack<_Tp, _Container>& __y)
300297
301298template <class _Tp, class _Container>
302299inline _LIBCPP_INLINE_VISIBILITY
303typename enable_if<
304 __is_swappable<_Container>::value,
305 void
306>::type
300_EnableIf<__is_swappable<_Container>::value, void>
307301swap(stack<_Tp, _Container>& __x, stack<_Tp, _Container>& __y)
308302 _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
309303{
......@@ -318,4 +312,4 @@ struct _LIBCPP_TEMPLATE_VIS uses_allocator<stack<_Tp, _Container>, _Alloc>
318312
319313_LIBCPP_END_NAMESPACE_STD
320314
321#endif // _LIBCPP_STACK
315#endif // _LIBCPP_STACK
lib/libcxx/include/stdbool.h+1-1
......@@ -35,4 +35,4 @@ Macros:
3535#define __bool_true_false_are_defined 1
3636#endif
3737
38#endif // _LIBCPP_STDBOOL_H
38#endif // _LIBCPP_STDBOOL_H
lib/libcxx/include/stddef.h+1-1
......@@ -53,4 +53,4 @@ using std::nullptr_t;
5353
5454#endif
5555
56#endif // _LIBCPP_STDDEF_H
56#endif // _LIBCPP_STDDEF_H
lib/libcxx/include/stdexcept+2-2
......@@ -42,9 +42,9 @@ public:
4242*/
4343
4444#include <__config>
45#include <cstdlib>
4645#include <exception>
4746#include <iosfwd> // for string forward decl
47#include <cstdlib>
4848
4949#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
5050#pragma GCC system_header
......@@ -306,4 +306,4 @@ void __throw_underflow_error(const char*__msg)
306306
307307_LIBCPP_END_NAMESPACE_STD
308308
309#endif // _LIBCPP_STDEXCEPT
309#endif // _LIBCPP_STDEXCEPT
lib/libcxx/include/stdint.h+1-1
......@@ -122,4 +122,4 @@ Macros:
122122
123123#include_next <stdint.h>
124124
125#endif // _LIBCPP_STDINT_H
125#endif // _LIBCPP_STDINT_H
lib/libcxx/include/stdio.h+1-1
......@@ -116,4 +116,4 @@ void perror(const char* s);
116116
117117#endif
118118
119#endif // _LIBCPP_STDIO_H
119#endif // _LIBCPP_STDIO_H
lib/libcxx/include/stdlib.h+8-8
......@@ -103,7 +103,7 @@ extern "C++" {
103103#endif
104104
105105// MSVCRT already has the correct prototype in <stdlib.h> if __cplusplus is defined
106#if !defined(_LIBCPP_MSVCRT) && !defined(__sun__) && !defined(_AIX)
106#if !defined(_LIBCPP_MSVCRT) && !defined(__sun__)
107107inline _LIBCPP_INLINE_VISIBILITY long abs(long __x) _NOEXCEPT {
108108 return __builtin_labs(__x);
109109}
......@@ -112,9 +112,9 @@ inline _LIBCPP_INLINE_VISIBILITY long long abs(long long __x) _NOEXCEPT {
112112 return __builtin_llabs(__x);
113113}
114114#endif // _LIBCPP_HAS_NO_LONG_LONG
115#endif // !defined(_LIBCPP_MSVCRT) && !defined(__sun__) && !defined(_AIX)
115#endif // !defined(_LIBCPP_MSVCRT) && !defined(__sun__)
116116
117#if !(defined(_AIX) || defined(__sun__))
117#if !defined(__sun__)
118118inline _LIBCPP_INLINE_VISIBILITY float abs(float __lcpp_x) _NOEXCEPT {
119119 return __builtin_fabsf(__lcpp_x); // Use builtins to prevent needing math.h
120120}
......@@ -127,7 +127,7 @@ inline _LIBCPP_INLINE_VISIBILITY long double
127127abs(long double __lcpp_x) _NOEXCEPT {
128128 return __builtin_fabsl(__lcpp_x);
129129}
130#endif // !(defined(_AIX) || defined(__sun__))
130#endif // !defined(__sun__)
131131
132132// div
133133
......@@ -138,7 +138,7 @@ abs(long double __lcpp_x) _NOEXCEPT {
138138#endif
139139
140140// MSVCRT already has the correct prototype in <stdlib.h> if __cplusplus is defined
141#if !defined(_LIBCPP_MSVCRT) && !defined(__sun__) && !defined(_AIX)
141#if !defined(_LIBCPP_MSVCRT) && !defined(__sun__)
142142inline _LIBCPP_INLINE_VISIBILITY ldiv_t div(long __x, long __y) _NOEXCEPT {
143143 return ::ldiv(__x, __y);
144144}
......@@ -148,8 +148,8 @@ inline _LIBCPP_INLINE_VISIBILITY lldiv_t div(long long __x,
148148 return ::lldiv(__x, __y);
149149}
150150#endif // _LIBCPP_HAS_NO_LONG_LONG
151#endif // _LIBCPP_MSVCRT / __sun__ / _AIX
151#endif // _LIBCPP_MSVCRT / __sun__
152152} // extern "C++"
153#endif // __cplusplus
153#endif // __cplusplus
154154
155#endif // _LIBCPP_STDLIB_H
155#endif // _LIBCPP_STDLIB_H
lib/libcxx/include/streambuf+4-4
......@@ -7,8 +7,8 @@
77//
88//===----------------------------------------------------------------------===//
99
10#ifndef _LIBCPP_STEAMBUF
11#define _LIBCPP_STEAMBUF
10#ifndef _LIBCPP_STREAMBUF
11#define _LIBCPP_STREAMBUF
1212
1313/*
1414 streambuf synopsis
......@@ -108,8 +108,8 @@ protected:
108108*/
109109
110110#include <__config>
111#include <iosfwd>
112111#include <ios>
112#include <iosfwd>
113113
114114#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
115115#pragma GCC system_header
......@@ -495,4 +495,4 @@ _LIBCPP_END_NAMESPACE_STD
495495
496496_LIBCPP_POP_MACROS
497497
498#endif // _LIBCPP_STEAMBUF
498#endif // _LIBCPP_STREAMBUF
lib/libcxx/include/string+179-176
......@@ -69,6 +69,9 @@ struct char_traits
6969
7070template <> struct char_traits<char>;
7171template <> struct char_traits<wchar_t>;
72template <> struct char_traits<char8_t>; // C++20
73template <> struct char_traits<char16_t>;
74template <> struct char_traits<char32_t>;
7275
7376template<class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >
7477class basic_string
......@@ -107,6 +110,7 @@ public:
107110 explicit basic_string(const T& t, const Allocator& a = Allocator()); // C++17
108111 basic_string(const value_type* s, const allocator_type& a = allocator_type());
109112 basic_string(const value_type* s, size_type n, const allocator_type& a = allocator_type());
113 basic_string(nullptr_t) = delete; // C++2b
110114 basic_string(size_type n, value_type c, const allocator_type& a = allocator_type());
111115 template<class InputIterator>
112116 basic_string(InputIterator begin, InputIterator end,
......@@ -127,6 +131,7 @@ public:
127131 allocator_type::propagate_on_container_move_assignment::value ||
128132 allocator_type::is_always_equal::value ); // C++17
129133 basic_string& operator=(const value_type* s);
134 basic_string& operator=(nullptr_t) = delete; // C++2b
130135 basic_string& operator=(value_type c);
131136 basic_string& operator=(initializer_list<value_type>);
132137
......@@ -262,49 +267,49 @@ public:
262267
263268 size_type find(const basic_string& str, size_type pos = 0) const noexcept;
264269 template <class T>
265 size_type find(const T& t, size_type pos = 0) const; // C++17
270 size_type find(const T& t, size_type pos = 0) const noexcept; // C++17, noexcept as an extension
266271 size_type find(const value_type* s, size_type pos, size_type n) const noexcept;
267272 size_type find(const value_type* s, size_type pos = 0) const noexcept;
268273 size_type find(value_type c, size_type pos = 0) const noexcept;
269274
270275 size_type rfind(const basic_string& str, size_type pos = npos) const noexcept;
271276 template <class T>
272 size_type rfind(const T& t, size_type pos = npos) const; // C++17
277 size_type rfind(const T& t, size_type pos = npos) const noexcept; // C++17, noexcept as an extension
273278 size_type rfind(const value_type* s, size_type pos, size_type n) const noexcept;
274279 size_type rfind(const value_type* s, size_type pos = npos) const noexcept;
275280 size_type rfind(value_type c, size_type pos = npos) const noexcept;
276281
277282 size_type find_first_of(const basic_string& str, size_type pos = 0) const noexcept;
278283 template <class T>
279 size_type find_first_of(const T& t, size_type pos = 0) const; // C++17
284 size_type find_first_of(const T& t, size_type pos = 0) const noexcept; // C++17, noexcept as an extension
280285 size_type find_first_of(const value_type* s, size_type pos, size_type n) const noexcept;
281286 size_type find_first_of(const value_type* s, size_type pos = 0) const noexcept;
282287 size_type find_first_of(value_type c, size_type pos = 0) const noexcept;
283288
284289 size_type find_last_of(const basic_string& str, size_type pos = npos) const noexcept;
285290 template <class T>
286 size_type find_last_of(const T& t, size_type pos = npos) const noexcept; // C++17
291 size_type find_last_of(const T& t, size_type pos = npos) const noexcept noexcept; // C++17, noexcept as an extension
287292 size_type find_last_of(const value_type* s, size_type pos, size_type n) const noexcept;
288293 size_type find_last_of(const value_type* s, size_type pos = npos) const noexcept;
289294 size_type find_last_of(value_type c, size_type pos = npos) const noexcept;
290295
291296 size_type find_first_not_of(const basic_string& str, size_type pos = 0) const noexcept;
292297 template <class T>
293 size_type find_first_not_of(const T& t, size_type pos = 0) const; // C++17
298 size_type find_first_not_of(const T& t, size_type pos = 0) const noexcept; // C++17, noexcept as an extension
294299 size_type find_first_not_of(const value_type* s, size_type pos, size_type n) const noexcept;
295300 size_type find_first_not_of(const value_type* s, size_type pos = 0) const noexcept;
296301 size_type find_first_not_of(value_type c, size_type pos = 0) const noexcept;
297302
298303 size_type find_last_not_of(const basic_string& str, size_type pos = npos) const noexcept;
299304 template <class T>
300 size_type find_last_not_of(const T& t, size_type pos = npos) const; // C++17
305 size_type find_last_not_of(const T& t, size_type pos = npos) const noexcept; // C++17, noexcept as an extension
301306 size_type find_last_not_of(const value_type* s, size_type pos, size_type n) const noexcept;
302307 size_type find_last_not_of(const value_type* s, size_type pos = npos) const noexcept;
303308 size_type find_last_not_of(value_type c, size_type pos = npos) const noexcept;
304309
305310 int compare(const basic_string& str) const noexcept;
306311 template <class T>
307 int compare(const T& t) const noexcept; // C++17
312 int compare(const T& t) const noexcept; // C++17, noexcept as an extension
308313 int compare(size_type pos1, size_type n1, const basic_string& str) const;
309314 template <class T>
310315 int compare(size_type pos1, size_type n1, const T& t) const; // C++17
......@@ -450,6 +455,7 @@ erase_if(basic_string<charT, traits, Allocator>& c, Predicate pred); // C++20
450455
451456typedef basic_string<char> string;
452457typedef basic_string<wchar_t> wstring;
458typedef basic_string<char8_t> u8string; // C++20
453459typedef basic_string<char16_t> u16string;
454460typedef basic_string<char32_t> u32string;
455461
......@@ -494,12 +500,14 @@ wstring to_wstring(double val);
494500wstring to_wstring(long double val);
495501
496502template <> struct hash<string>;
503template <> struct hash<u8string>; // C++20
497504template <> struct hash<u16string>;
498505template <> struct hash<u32string>;
499506template <> struct hash<wstring>;
500507
501508basic_string<char> operator "" s( const char *str, size_t len ); // C++14
502509basic_string<wchar_t> operator "" s( const wchar_t *str, size_t len ); // C++14
510basic_string<char8_t> operator "" s( const char8_t *str, size_t len ); // C++20
503511basic_string<char16_t> operator "" s( const char16_t *str, size_t len ); // C++14
504512basic_string<char32_t> operator "" s( const char32_t *str, size_t len ); // C++14
505513
......@@ -508,26 +516,28 @@ basic_string<char32_t> operator "" s( const char32_t *str, size_t len ); // C++1
508516*/
509517
510518#include <__config>
511#include <string_view>
512#include <iosfwd>
519#include <__debug>
520#include <__functional_base>
521#include <__iterator/wrap_iter.h>
522#include <algorithm>
523#include <compare>
524#include <cstdio> // EOF
513525#include <cstring>
514#include <cstdio> // For EOF.
515526#include <cwchar>
516#include <algorithm>
527#include <initializer_list>
528#include <iosfwd>
517529#include <iterator>
518#include <utility>
519530#include <memory>
520531#include <stdexcept>
532#include <string_view>
521533#include <type_traits>
522#include <initializer_list>
523#include <__functional_base>
534#include <utility>
524535#include <version>
536
525537#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
526#include <cstdint>
538# include <cstdint>
527539#endif
528540
529#include <__debug>
530
531541#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
532542#pragma GCC system_header
533543#endif
......@@ -625,29 +635,16 @@ __basic_string_common<__b>::__throw_out_of_range() const
625635
626636_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __basic_string_common<true>)
627637
628#ifdef _LIBCPP_NO_EXCEPTIONS
629template <class _Iter>
630struct __libcpp_string_gets_noexcept_iterator_impl : public true_type {};
631#elif defined(_LIBCPP_HAS_NO_NOEXCEPT)
632638template <class _Iter>
633struct __libcpp_string_gets_noexcept_iterator_impl : public false_type {};
634#else
635template <class _Iter, bool = __is_cpp17_forward_iterator<_Iter>::value>
636struct __libcpp_string_gets_noexcept_iterator_impl : public _LIBCPP_BOOL_CONSTANT((
637 noexcept(++(declval<_Iter&>())) &&
638 is_nothrow_assignable<_Iter&, _Iter>::value &&
639 noexcept(declval<_Iter>() == declval<_Iter>()) &&
640 noexcept(*declval<_Iter>())
641)) {};
642
643template <class _Iter>
644struct __libcpp_string_gets_noexcept_iterator_impl<_Iter, false> : public false_type {};
645#endif
639struct __string_is_trivial_iterator : public false_type {};
646640
641template <class _Tp>
642struct __string_is_trivial_iterator<_Tp*>
643 : public is_arithmetic<_Tp> {};
647644
648645template <class _Iter>
649struct __libcpp_string_gets_noexcept_iterator
650 : public _LIBCPP_BOOL_CONSTANT(__libcpp_is_trivial_iterator<_Iter>::value || __libcpp_string_gets_noexcept_iterator_impl<_Iter>::value) {};
646struct __string_is_trivial_iterator<__wrap_iter<_Iter> >
647 : public __string_is_trivial_iterator<_Iter> {};
651648
652649template <class _CharT, class _Traits, class _Tp>
653650struct __can_be_converted_to_string_view : public _BoolConstant<
......@@ -668,21 +665,21 @@ struct __padding<_CharT, 1>
668665{
669666};
670667
671#endif // _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
668#endif // _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
672669
673#ifndef _LIBCPP_NO_HAS_CHAR8_T
670#ifndef _LIBCPP_HAS_NO_CHAR8_T
674671typedef basic_string<char8_t> u8string;
675672#endif
676673
677674#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
678675typedef basic_string<char16_t> u16string;
679676typedef basic_string<char32_t> u32string;
680#endif // _LIBCPP_HAS_NO_UNICODE_CHARS
677#endif // _LIBCPP_HAS_NO_UNICODE_CHARS
681678
682679template<class _CharT, class _Traits, class _Allocator>
683680class
684681 _LIBCPP_TEMPLATE_VIS
685#ifndef _LIBCPP_NO_HAS_CHAR8_T
682#ifndef _LIBCPP_HAS_NO_CHAR8_T
686683 _LIBCPP_PREFERRED_NAME(u8string)
687684#endif
688685#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
......@@ -736,7 +733,7 @@ private:
736733#else // _LIBCPP_BIG_ENDIAN
737734 static const size_type __short_mask = 0x80;
738735 static const size_type __long_mask = ~(size_type(~0) >> 1);
739#endif // _LIBCPP_BIG_ENDIAN
736#endif // _LIBCPP_BIG_ENDIAN
740737
741738 enum {__min_cap = (sizeof(__long) - 1)/sizeof(value_type) > 2 ?
742739 (sizeof(__long) - 1)/sizeof(value_type) : 2};
......@@ -766,7 +763,7 @@ private:
766763#else // _LIBCPP_BIG_ENDIAN
767764 static const size_type __short_mask = 0x01;
768765 static const size_type __long_mask = 0x1ul;
769#endif // _LIBCPP_BIG_ENDIAN
766#endif // _LIBCPP_BIG_ENDIAN
770767
771768 enum {__min_cap = (sizeof(__long) - 1)/sizeof(value_type) > 2 ?
772769 (sizeof(__long) - 1)/sizeof(value_type) : 2};
......@@ -781,7 +778,7 @@ private:
781778 value_type __data_[__min_cap];
782779 };
783780
784#endif // _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
781#endif // _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
785782
786783 union __ulx{__long __lx; __short __lxx;};
787784
......@@ -805,7 +802,7 @@ private:
805802 __compressed_pair<__rep, allocator_type> __r_;
806803
807804public:
808 _LIBCPP_FUNC_VIS
805 _LIBCPP_TEMPLATE_DATA_VIS
809806 static const size_type npos = -1;
810807
811808 _LIBCPP_INLINE_VISIBILITY basic_string()
......@@ -832,7 +829,7 @@ public:
832829
833830 _LIBCPP_INLINE_VISIBILITY
834831 basic_string(basic_string&& __str, const allocator_type& __a);
835#endif // _LIBCPP_CXX03_LANG
832#endif // _LIBCPP_CXX03_LANG
836833
837834 template <class = _EnableIf<__is_allocator<_Allocator>::value, nullptr_t> >
838835 _LIBCPP_INLINE_VISIBILITY
......@@ -848,6 +845,10 @@ public:
848845 _LIBCPP_INLINE_VISIBILITY
849846 basic_string(const _CharT* __s, const _Allocator& __a);
850847
848#if _LIBCPP_STD_VER > 20
849 basic_string(nullptr_t) = delete;
850#endif
851
851852 _LIBCPP_INLINE_VISIBILITY
852853 basic_string(const _CharT* __s, size_type __n);
853854 _LIBCPP_INLINE_VISIBILITY
......@@ -890,7 +891,7 @@ public:
890891 basic_string(initializer_list<_CharT> __il);
891892 _LIBCPP_INLINE_VISIBILITY
892893 basic_string(initializer_list<_CharT> __il, const _Allocator& __a);
893#endif // _LIBCPP_CXX03_LANG
894#endif // _LIBCPP_CXX03_LANG
894895
895896 inline ~basic_string();
896897
......@@ -911,6 +912,9 @@ public:
911912 basic_string& operator=(initializer_list<value_type> __il) {return assign(__il.begin(), __il.size());}
912913#endif
913914 _LIBCPP_INLINE_VISIBILITY basic_string& operator=(const value_type* __s) {return assign(__s);}
915#if _LIBCPP_STD_VER > 20
916 basic_string& operator=(nullptr_t) = delete;
917#endif
914918 basic_string& operator=(value_type __c);
915919
916920#if _LIBCPP_DEBUG_LEVEL == 2
......@@ -939,7 +943,7 @@ public:
939943 _LIBCPP_INLINE_VISIBILITY
940944 const_iterator end() const _NOEXCEPT
941945 {return const_iterator(__get_pointer() + size());}
942#endif // _LIBCPP_DEBUG_LEVEL == 2
946#endif // _LIBCPP_DEBUG_LEVEL == 2
943947 _LIBCPP_INLINE_VISIBILITY
944948 reverse_iterator rbegin() _NOEXCEPT
945949 {return reverse_iterator(end());}
......@@ -1010,7 +1014,7 @@ public:
10101014 _LIBCPP_INLINE_VISIBILITY basic_string& operator+=(value_type __c) {push_back(__c); return *this;}
10111015#ifndef _LIBCPP_CXX03_LANG
10121016 _LIBCPP_INLINE_VISIBILITY basic_string& operator+=(initializer_list<value_type> __il) {return append(__il);}
1013#endif // _LIBCPP_CXX03_LANG
1017#endif // _LIBCPP_CXX03_LANG
10141018
10151019 _LIBCPP_INLINE_VISIBILITY
10161020 basic_string& append(const basic_string& __str);
......@@ -1041,20 +1045,16 @@ public:
10411045 _LIBCPP_INLINE_VISIBILITY
10421046 void __append_default_init(size_type __n);
10431047
1044 template <class _ForwardIterator>
1045 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
1046 basic_string& __append_forward_unsafe(_ForwardIterator, _ForwardIterator);
10471048 template<class _InputIterator>
10481049 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
10491050 _EnableIf
10501051 <
1051 __is_exactly_cpp17_input_iterator<_InputIterator>::value
1052 || !__libcpp_string_gets_noexcept_iterator<_InputIterator>::value,
1052 __is_exactly_cpp17_input_iterator<_InputIterator>::value,
10531053 basic_string&
10541054 >
10551055 _LIBCPP_INLINE_VISIBILITY
10561056 append(_InputIterator __first, _InputIterator __last) {
1057 const basic_string __temp (__first, __last, __alloc());
1057 const basic_string __temp(__first, __last, __alloc());
10581058 append(__temp.data(), __temp.size());
10591059 return *this;
10601060 }
......@@ -1062,19 +1062,16 @@ public:
10621062 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
10631063 _EnableIf
10641064 <
1065 __is_cpp17_forward_iterator<_ForwardIterator>::value
1066 && __libcpp_string_gets_noexcept_iterator<_ForwardIterator>::value,
1065 __is_cpp17_forward_iterator<_ForwardIterator>::value,
10671066 basic_string&
10681067 >
10691068 _LIBCPP_INLINE_VISIBILITY
1070 append(_ForwardIterator __first, _ForwardIterator __last) {
1071 return __append_forward_unsafe(__first, __last);
1072 }
1069 append(_ForwardIterator __first, _ForwardIterator __last);
10731070
10741071#ifndef _LIBCPP_CXX03_LANG
10751072 _LIBCPP_INLINE_VISIBILITY
10761073 basic_string& append(initializer_list<value_type> __il) {return append(__il.begin(), __il.size());}
1077#endif // _LIBCPP_CXX03_LANG
1074#endif // _LIBCPP_CXX03_LANG
10781075
10791076 void push_back(value_type __c);
10801077 _LIBCPP_INLINE_VISIBILITY
......@@ -1117,8 +1114,7 @@ public:
11171114 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
11181115 _EnableIf
11191116 <
1120 __is_exactly_cpp17_input_iterator<_InputIterator>::value
1121 || !__libcpp_string_gets_noexcept_iterator<_InputIterator>::value,
1117 __is_exactly_cpp17_input_iterator<_InputIterator>::value,
11221118 basic_string&
11231119 >
11241120 assign(_InputIterator __first, _InputIterator __last);
......@@ -1126,15 +1122,14 @@ public:
11261122 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
11271123 _EnableIf
11281124 <
1129 __is_cpp17_forward_iterator<_ForwardIterator>::value
1130 && __libcpp_string_gets_noexcept_iterator<_ForwardIterator>::value,
1125 __is_cpp17_forward_iterator<_ForwardIterator>::value,
11311126 basic_string&
11321127 >
11331128 assign(_ForwardIterator __first, _ForwardIterator __last);
11341129#ifndef _LIBCPP_CXX03_LANG
11351130 _LIBCPP_INLINE_VISIBILITY
11361131 basic_string& assign(initializer_list<value_type> __il) {return assign(__il.begin(), __il.size());}
1137#endif // _LIBCPP_CXX03_LANG
1132#endif // _LIBCPP_CXX03_LANG
11381133
11391134 _LIBCPP_INLINE_VISIBILITY
11401135 basic_string& insert(size_type __pos1, const basic_string& __str);
......@@ -1168,8 +1163,7 @@ public:
11681163 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
11691164 _EnableIf
11701165 <
1171 __is_exactly_cpp17_input_iterator<_InputIterator>::value
1172 || !__libcpp_string_gets_noexcept_iterator<_InputIterator>::value,
1166 __is_exactly_cpp17_input_iterator<_InputIterator>::value,
11731167 iterator
11741168 >
11751169 insert(const_iterator __pos, _InputIterator __first, _InputIterator __last);
......@@ -1177,8 +1171,7 @@ public:
11771171 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
11781172 _EnableIf
11791173 <
1180 __is_cpp17_forward_iterator<_ForwardIterator>::value
1181 && __libcpp_string_gets_noexcept_iterator<_ForwardIterator>::value,
1174 __is_cpp17_forward_iterator<_ForwardIterator>::value,
11821175 iterator
11831176 >
11841177 insert(const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last);
......@@ -1186,7 +1179,7 @@ public:
11861179 _LIBCPP_INLINE_VISIBILITY
11871180 iterator insert(const_iterator __pos, initializer_list<value_type> __il)
11881181 {return insert(__pos, __il.begin(), __il.end());}
1189#endif // _LIBCPP_CXX03_LANG
1182#endif // _LIBCPP_CXX03_LANG
11901183
11911184 basic_string& erase(size_type __pos = 0, size_type __n = npos);
11921185 _LIBCPP_INLINE_VISIBILITY
......@@ -1247,7 +1240,7 @@ public:
12471240 _LIBCPP_INLINE_VISIBILITY
12481241 basic_string& replace(const_iterator __i1, const_iterator __i2, initializer_list<value_type> __il)
12491242 {return replace(__i1, __i2, __il.begin(), __il.end());}
1250#endif // _LIBCPP_CXX03_LANG
1243#endif // _LIBCPP_CXX03_LANG
12511244
12521245 size_type copy(value_type* __s, size_type __n, size_type __pos = 0) const;
12531246 _LIBCPP_INLINE_VISIBILITY
......@@ -1284,7 +1277,7 @@ public:
12841277 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
12851278 size_type
12861279 >
1287 find(const _Tp& __t, size_type __pos = 0) const;
1280 find(const _Tp& __t, size_type __pos = 0) const _NOEXCEPT;
12881281 size_type find(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
12891282 _LIBCPP_INLINE_VISIBILITY
12901283 size_type find(const value_type* __s, size_type __pos = 0) const _NOEXCEPT;
......@@ -1300,7 +1293,7 @@ public:
13001293 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
13011294 size_type
13021295 >
1303 rfind(const _Tp& __t, size_type __pos = npos) const;
1296 rfind(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT;
13041297 size_type rfind(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
13051298 _LIBCPP_INLINE_VISIBILITY
13061299 size_type rfind(const value_type* __s, size_type __pos = npos) const _NOEXCEPT;
......@@ -1316,7 +1309,7 @@ public:
13161309 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
13171310 size_type
13181311 >
1319 find_first_of(const _Tp& __t, size_type __pos = 0) const;
1312 find_first_of(const _Tp& __t, size_type __pos = 0) const _NOEXCEPT;
13201313 size_type find_first_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
13211314 _LIBCPP_INLINE_VISIBILITY
13221315 size_type find_first_of(const value_type* __s, size_type __pos = 0) const _NOEXCEPT;
......@@ -1333,7 +1326,7 @@ public:
13331326 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
13341327 size_type
13351328 >
1336 find_last_of(const _Tp& __t, size_type __pos = npos) const;
1329 find_last_of(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT;
13371330 size_type find_last_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
13381331 _LIBCPP_INLINE_VISIBILITY
13391332 size_type find_last_of(const value_type* __s, size_type __pos = npos) const _NOEXCEPT;
......@@ -1350,7 +1343,7 @@ public:
13501343 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
13511344 size_type
13521345 >
1353 find_first_not_of(const _Tp &__t, size_type __pos = 0) const;
1346 find_first_not_of(const _Tp &__t, size_type __pos = 0) const _NOEXCEPT;
13541347 size_type find_first_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
13551348 _LIBCPP_INLINE_VISIBILITY
13561349 size_type find_first_not_of(const value_type* __s, size_type __pos = 0) const _NOEXCEPT;
......@@ -1367,7 +1360,7 @@ public:
13671360 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
13681361 size_type
13691362 >
1370 find_last_not_of(const _Tp& __t, size_type __pos = npos) const;
1363 find_last_not_of(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT;
13711364 size_type find_last_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
13721365 _LIBCPP_INLINE_VISIBILITY
13731366 size_type find_last_not_of(const value_type* __s, size_type __pos = npos) const _NOEXCEPT;
......@@ -1384,7 +1377,7 @@ public:
13841377 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
13851378 int
13861379 >
1387 compare(const _Tp &__t) const;
1380 compare(const _Tp &__t) const _NOEXCEPT;
13881381
13891382 template <class _Tp>
13901383 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
......@@ -1468,7 +1461,7 @@ public:
14681461 bool __addable(const const_iterator* __i, ptrdiff_t __n) const;
14691462 bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const;
14701463
1471#endif // _LIBCPP_DEBUG_LEVEL == 2
1464#endif // _LIBCPP_DEBUG_LEVEL == 2
14721465
14731466private:
14741467 _LIBCPP_INLINE_VISIBILITY
......@@ -1514,7 +1507,7 @@ private:
15141507 {return __r_.first().__s.__size_ >> 1;}
15151508# endif
15161509
1517#endif // _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
1510#endif // _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
15181511
15191512 _LIBCPP_INLINE_VISIBILITY
15201513 void __set_long_size(size_type __s) _NOEXCEPT
......@@ -1714,6 +1707,13 @@ private:
17141707 _LIBCPP_INLINE_VISIBILITY void __invalidate_all_iterators();
17151708 _LIBCPP_INLINE_VISIBILITY void __invalidate_iterators_past(size_type);
17161709
1710 template<class _Tp>
1711 _LIBCPP_INLINE_VISIBILITY
1712 bool __addr_in_range(_Tp&& __t) const {
1713 const volatile void *__p = _VSTD::addressof(__t);
1714 return data() <= __p && __p <= data() + size();
1715 }
1716
17171717 friend basic_string operator+<>(const basic_string&, const basic_string&);
17181718 friend basic_string operator+<>(const value_type*, const basic_string&);
17191719 friend basic_string operator+<>(value_type, const basic_string&);
......@@ -1734,7 +1734,7 @@ _LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE, wchar_t)
17341734
17351735#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
17361736template<class _InputIterator,
1737 class _CharT = typename iterator_traits<_InputIterator>::value_type,
1737 class _CharT = __iter_value_type<_InputIterator>,
17381738 class _Allocator = allocator<_CharT>,
17391739 class = _EnableIf<__is_cpp17_input_iterator<_InputIterator>::value>,
17401740 class = _EnableIf<__is_allocator<_Allocator>::value>
......@@ -1773,11 +1773,7 @@ basic_string<_CharT, _Traits, _Allocator>::__invalidate_all_iterators()
17731773template <class _CharT, class _Traits, class _Allocator>
17741774inline
17751775void
1776basic_string<_CharT, _Traits, _Allocator>::__invalidate_iterators_past(size_type
1777#if _LIBCPP_DEBUG_LEVEL == 2
1778 __pos
1779#endif
1780 )
1776basic_string<_CharT, _Traits, _Allocator>::__invalidate_iterators_past(size_type __pos)
17811777{
17821778#if _LIBCPP_DEBUG_LEVEL == 2
17831779 __c_node* __c = __get_db()->__find_c_and_lock(this);
......@@ -1797,7 +1793,9 @@ basic_string<_CharT, _Traits, _Allocator>::__invalidate_iterators_past(size_type
17971793 }
17981794 __get_db()->unlock();
17991795 }
1800#endif // _LIBCPP_DEBUG_LEVEL == 2
1796#else
1797 (void)__pos;
1798#endif // _LIBCPP_DEBUG_LEVEL == 2
18011799}
18021800
18031801template <class _CharT, class _Traits, class _Allocator>
......@@ -2001,7 +1999,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(basic_string&& __str, co
20011999#endif
20022000}
20032001
2004#endif // _LIBCPP_CXX03_LANG
2002#endif // _LIBCPP_CXX03_LANG
20052003
20062004template <class _CharT, class _Traits, class _Allocator>
20072005void
......@@ -2129,7 +2127,7 @@ basic_string<_CharT, _Traits, _Allocator>::__init(_InputIterator __first, _Input
21292127#ifndef _LIBCPP_NO_EXCEPTIONS
21302128 try
21312129 {
2132#endif // _LIBCPP_NO_EXCEPTIONS
2130#endif // _LIBCPP_NO_EXCEPTIONS
21332131 for (; __first != __last; ++__first)
21342132 push_back(*__first);
21352133#ifndef _LIBCPP_NO_EXCEPTIONS
......@@ -2140,7 +2138,7 @@ basic_string<_CharT, _Traits, _Allocator>::__init(_InputIterator __first, _Input
21402138 __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap());
21412139 throw;
21422140 }
2143#endif // _LIBCPP_NO_EXCEPTIONS
2141#endif // _LIBCPP_NO_EXCEPTIONS
21442142}
21452143
21462144template <class _CharT, class _Traits, class _Allocator>
......@@ -2168,9 +2166,23 @@ basic_string<_CharT, _Traits, _Allocator>::__init(_ForwardIterator __first, _For
21682166 __set_long_cap(__cap+1);
21692167 __set_long_size(__sz);
21702168 }
2169
2170#ifndef _LIBCPP_NO_EXCEPTIONS
2171 try
2172 {
2173#endif // _LIBCPP_NO_EXCEPTIONS
21712174 for (; __first != __last; ++__first, (void) ++__p)
21722175 traits_type::assign(*__p, *__first);
21732176 traits_type::assign(*__p, value_type());
2177#ifndef _LIBCPP_NO_EXCEPTIONS
2178 }
2179 catch (...)
2180 {
2181 if (__is_long())
2182 __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap());
2183 throw;
2184 }
2185#endif // _LIBCPP_NO_EXCEPTIONS
21742186}
21752187
21762188template <class _CharT, class _Traits, class _Allocator>
......@@ -2225,7 +2237,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(
22252237#endif
22262238}
22272239
2228#endif // _LIBCPP_CXX03_LANG
2240#endif // _LIBCPP_CXX03_LANG
22292241
22302242template <class _CharT, class _Traits, class _Allocator>
22312243basic_string<_CharT, _Traits, _Allocator>::~basic_string()
......@@ -2357,12 +2369,11 @@ basic_string<_CharT, _Traits, _Allocator>::assign(size_type __n, value_type __c)
23572369 size_type __sz = size();
23582370 __grow_by(__cap, __n - __cap, __sz, 0, __sz);
23592371 }
2360 else
2361 __invalidate_iterators_past(__n);
23622372 value_type* __p = _VSTD::__to_address(__get_pointer());
23632373 traits_type::assign(__p, __n, __c);
23642374 traits_type::assign(__p[__n], value_type());
23652375 __set_size(__n);
2376 __invalidate_iterators_past(__n);
23662377 return *this;
23672378}
23682379
......@@ -2463,8 +2474,7 @@ template <class _CharT, class _Traits, class _Allocator>
24632474template<class _InputIterator>
24642475_EnableIf
24652476<
2466 __is_exactly_cpp17_input_iterator <_InputIterator>::value
2467 || !__libcpp_string_gets_noexcept_iterator<_InputIterator>::value,
2477 __is_exactly_cpp17_input_iterator<_InputIterator>::value,
24682478 basic_string<_CharT, _Traits, _Allocator>&
24692479>
24702480basic_string<_CharT, _Traits, _Allocator>::assign(_InputIterator __first, _InputIterator __last)
......@@ -2478,26 +2488,35 @@ template <class _CharT, class _Traits, class _Allocator>
24782488template<class _ForwardIterator>
24792489_EnableIf
24802490<
2481 __is_cpp17_forward_iterator<_ForwardIterator>::value
2482 && __libcpp_string_gets_noexcept_iterator<_ForwardIterator>::value,
2491 __is_cpp17_forward_iterator<_ForwardIterator>::value,
24832492 basic_string<_CharT, _Traits, _Allocator>&
24842493>
24852494basic_string<_CharT, _Traits, _Allocator>::assign(_ForwardIterator __first, _ForwardIterator __last)
24862495{
2487 size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last));
24882496 size_type __cap = capacity();
2489 if (__cap < __n)
2497 size_type __n = __string_is_trivial_iterator<_ForwardIterator>::value ?
2498 static_cast<size_type>(_VSTD::distance(__first, __last)) : 0;
2499
2500 if (__string_is_trivial_iterator<_ForwardIterator>::value &&
2501 (__cap >= __n || !__addr_in_range(*__first)))
24902502 {
2491 size_type __sz = size();
2492 __grow_by(__cap, __n - __cap, __sz, 0, __sz);
2503 if (__cap < __n)
2504 {
2505 size_type __sz = size();
2506 __grow_by(__cap, __n - __cap, __sz, 0, __sz);
2507 }
2508 pointer __p = __get_pointer();
2509 for (; __first != __last; ++__first, ++__p)
2510 traits_type::assign(*__p, *__first);
2511 traits_type::assign(*__p, value_type());
2512 __set_size(__n);
2513 __invalidate_iterators_past(__n);
24932514 }
24942515 else
2495 __invalidate_iterators_past(__n);
2496 pointer __p = __get_pointer();
2497 for (; __first != __last; ++__first, ++__p)
2498 traits_type::assign(*__p, *__first);
2499 traits_type::assign(*__p, value_type());
2500 __set_size(__n);
2516 {
2517 const basic_string __temp(__first, __last, __alloc());
2518 assign(__temp.data(), __temp.size());
2519 }
25012520 return *this;
25022521}
25032522
......@@ -2644,39 +2663,23 @@ basic_string<_CharT, _Traits, _Allocator>::push_back(value_type __c)
26442663 traits_type::assign(*++__p, value_type());
26452664}
26462665
2647template <class _Tp>
2648bool __ptr_in_range (const _Tp* __p, const _Tp* __first, const _Tp* __last)
2649{
2650 return __first <= __p && __p < __last;
2651}
2652
2653template <class _Tp1, class _Tp2>
2654bool __ptr_in_range (const _Tp1*, const _Tp2*, const _Tp2*)
2655{
2656 return false;
2657}
2658
26592666template <class _CharT, class _Traits, class _Allocator>
26602667template<class _ForwardIterator>
2661basic_string<_CharT, _Traits, _Allocator>&
2662basic_string<_CharT, _Traits, _Allocator>::__append_forward_unsafe(
2668_EnableIf
2669<
2670 __is_cpp17_forward_iterator<_ForwardIterator>::value,
2671 basic_string<_CharT, _Traits, _Allocator>&
2672>
2673basic_string<_CharT, _Traits, _Allocator>::append(
26632674 _ForwardIterator __first, _ForwardIterator __last)
26642675{
2665 static_assert(__is_cpp17_forward_iterator<_ForwardIterator>::value,
2666 "function requires a ForwardIterator");
26672676 size_type __sz = size();
26682677 size_type __cap = capacity();
26692678 size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last));
26702679 if (__n)
26712680 {
2672 typedef typename iterator_traits<_ForwardIterator>::reference _CharRef;
2673 _CharRef __tmp_ref = *__first;
2674 if (__ptr_in_range(_VSTD::addressof(__tmp_ref), data(), data() + size()))
2675 {
2676 const basic_string __temp (__first, __last, __alloc());
2677 append(__temp.data(), __temp.size());
2678 }
2679 else
2681 if (__string_is_trivial_iterator<_ForwardIterator>::value &&
2682 !__addr_in_range(*__first))
26802683 {
26812684 if (__cap - __sz < __n)
26822685 __grow_by(__cap, __sz + __n - __cap, __sz, __sz, 0);
......@@ -2686,6 +2689,11 @@ basic_string<_CharT, _Traits, _Allocator>::__append_forward_unsafe(
26862689 traits_type::assign(*__p, value_type());
26872690 __set_size(__sz + __n);
26882691 }
2692 else
2693 {
2694 const basic_string __temp(__first, __last, __alloc());
2695 append(__temp.data(), __temp.size());
2696 }
26892697 }
26902698 return *this;
26912699}
......@@ -2801,8 +2809,7 @@ template <class _CharT, class _Traits, class _Allocator>
28012809template<class _InputIterator>
28022810_EnableIf
28032811<
2804 __is_exactly_cpp17_input_iterator<_InputIterator>::value
2805 || !__libcpp_string_gets_noexcept_iterator<_InputIterator>::value,
2812 __is_exactly_cpp17_input_iterator<_InputIterator>::value,
28062813 typename basic_string<_CharT, _Traits, _Allocator>::iterator
28072814>
28082815basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _InputIterator __first, _InputIterator __last)
......@@ -2820,8 +2827,7 @@ template <class _CharT, class _Traits, class _Allocator>
28202827template<class _ForwardIterator>
28212828_EnableIf
28222829<
2823 __is_cpp17_forward_iterator<_ForwardIterator>::value
2824 && __libcpp_string_gets_noexcept_iterator<_ForwardIterator>::value,
2830 __is_cpp17_forward_iterator<_ForwardIterator>::value,
28252831 typename basic_string<_CharT, _Traits, _Allocator>::iterator
28262832>
28272833basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last)
......@@ -2835,34 +2841,35 @@ basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _Forward
28352841 size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last));
28362842 if (__n)
28372843 {
2838 typedef typename iterator_traits<_ForwardIterator>::reference _CharRef;
2839 _CharRef __tmp_char = *__first;
2840 if (__ptr_in_range(_VSTD::addressof(__tmp_char), data(), data() + size()))
2844 if (__string_is_trivial_iterator<_ForwardIterator>::value &&
2845 !__addr_in_range(*__first))
28412846 {
2842 const basic_string __temp(__first, __last, __alloc());
2843 return insert(__pos, __temp.data(), __temp.data() + __temp.size());
2844 }
2845
2846 size_type __sz = size();
2847 size_type __cap = capacity();
2848 value_type* __p;
2849 if (__cap - __sz >= __n)
2850 {
2851 __p = _VSTD::__to_address(__get_pointer());
2852 size_type __n_move = __sz - __ip;
2853 if (__n_move != 0)
2854 traits_type::move(__p + __ip + __n, __p + __ip, __n_move);
2847 size_type __sz = size();
2848 size_type __cap = capacity();
2849 value_type* __p;
2850 if (__cap - __sz >= __n)
2851 {
2852 __p = _VSTD::__to_address(__get_pointer());
2853 size_type __n_move = __sz - __ip;
2854 if (__n_move != 0)
2855 traits_type::move(__p + __ip + __n, __p + __ip, __n_move);
2856 }
2857 else
2858 {
2859 __grow_by(__cap, __sz + __n - __cap, __sz, __ip, 0, __n);
2860 __p = _VSTD::__to_address(__get_long_pointer());
2861 }
2862 __sz += __n;
2863 __set_size(__sz);
2864 traits_type::assign(__p[__sz], value_type());
2865 for (__p += __ip; __first != __last; ++__p, ++__first)
2866 traits_type::assign(*__p, *__first);
28552867 }
28562868 else
28572869 {
2858 __grow_by(__cap, __sz + __n - __cap, __sz, __ip, 0, __n);
2859 __p = _VSTD::__to_address(__get_long_pointer());
2870 const basic_string __temp(__first, __last, __alloc());
2871 return insert(__pos, __temp.data(), __temp.data() + __temp.size());
28602872 }
2861 __sz += __n;
2862 __set_size(__sz);
2863 traits_type::assign(__p[__sz], value_type());
2864 for (__p += __ip; __first != __last; ++__p, ++__first)
2865 traits_type::assign(*__p, *__first);
28662873 }
28672874 return begin() + __ip;
28682875}
......@@ -3353,7 +3360,7 @@ basic_string<_CharT, _Traits, _Allocator>::__shrink_or_extend(size_type __target
33533360 #ifndef _LIBCPP_NO_EXCEPTIONS
33543361 try
33553362 {
3356 #endif // _LIBCPP_NO_EXCEPTIONS
3363 #endif // _LIBCPP_NO_EXCEPTIONS
33573364 __new_data = __alloc_traits::allocate(__alloc(), __target_capacity+1);
33583365 #ifndef _LIBCPP_NO_EXCEPTIONS
33593366 }
......@@ -3364,7 +3371,7 @@ basic_string<_CharT, _Traits, _Allocator>::__shrink_or_extend(size_type __target
33643371 #else // _LIBCPP_NO_EXCEPTIONS
33653372 if (__new_data == nullptr)
33663373 return;
3367 #endif // _LIBCPP_NO_EXCEPTIONS
3374 #endif // _LIBCPP_NO_EXCEPTIONS
33683375 }
33693376 __now_long = true;
33703377 __was_long = __is_long();
......@@ -3543,7 +3550,7 @@ _EnableIf
35433550 typename basic_string<_CharT, _Traits, _Allocator>::size_type
35443551>
35453552basic_string<_CharT, _Traits, _Allocator>::find(const _Tp &__t,
3546 size_type __pos) const
3553 size_type __pos) const _NOEXCEPT
35473554{
35483555 __self_view __sv = __t;
35493556 return __str_find<value_type, size_type, traits_type, npos>
......@@ -3601,7 +3608,7 @@ _EnableIf
36013608 typename basic_string<_CharT, _Traits, _Allocator>::size_type
36023609>
36033610basic_string<_CharT, _Traits, _Allocator>::rfind(const _Tp& __t,
3604 size_type __pos) const
3611 size_type __pos) const _NOEXCEPT
36053612{
36063613 __self_view __sv = __t;
36073614 return __str_rfind<value_type, size_type, traits_type, npos>
......@@ -3659,7 +3666,7 @@ _EnableIf
36593666 typename basic_string<_CharT, _Traits, _Allocator>::size_type
36603667>
36613668basic_string<_CharT, _Traits, _Allocator>::find_first_of(const _Tp& __t,
3662 size_type __pos) const
3669 size_type __pos) const _NOEXCEPT
36633670{
36643671 __self_view __sv = __t;
36653672 return __str_find_first_of<value_type, size_type, traits_type, npos>
......@@ -3717,7 +3724,7 @@ _EnableIf
37173724 typename basic_string<_CharT, _Traits, _Allocator>::size_type
37183725>
37193726basic_string<_CharT, _Traits, _Allocator>::find_last_of(const _Tp& __t,
3720 size_type __pos) const
3727 size_type __pos) const _NOEXCEPT
37213728{
37223729 __self_view __sv = __t;
37233730 return __str_find_last_of<value_type, size_type, traits_type, npos>
......@@ -3775,7 +3782,7 @@ _EnableIf
37753782 typename basic_string<_CharT, _Traits, _Allocator>::size_type
37763783>
37773784basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const _Tp& __t,
3778 size_type __pos) const
3785 size_type __pos) const _NOEXCEPT
37793786{
37803787 __self_view __sv = __t;
37813788 return __str_find_first_not_of<value_type, size_type, traits_type, npos>
......@@ -3834,7 +3841,7 @@ _EnableIf
38343841 typename basic_string<_CharT, _Traits, _Allocator>::size_type
38353842>
38363843basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const _Tp& __t,
3837 size_type __pos) const
3844 size_type __pos) const _NOEXCEPT
38383845{
38393846 __self_view __sv = __t;
38403847 return __str_find_last_not_of<value_type, size_type, traits_type, npos>
......@@ -3871,7 +3878,7 @@ _EnableIf
38713878 __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
38723879 int
38733880>
3874basic_string<_CharT, _Traits, _Allocator>::compare(const _Tp& __t) const
3881basic_string<_CharT, _Traits, _Allocator>::compare(const _Tp& __t) const _NOEXCEPT
38753882{
38763883 __self_view __sv = __t;
38773884 size_t __lhs_sz = size();
......@@ -4349,7 +4356,7 @@ operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, _CharT __rhs)
43494356 return _VSTD::move(__lhs);
43504357}
43514358
4352#endif // _LIBCPP_CXX03_LANG
4359#endif // _LIBCPP_CXX03_LANG
43534360
43544361// swap
43554362
......@@ -4404,7 +4411,7 @@ _LIBCPP_FUNC_VIS wstring to_wstring(double __val);
44044411_LIBCPP_FUNC_VIS wstring to_wstring(long double __val);
44054412
44064413template<class _CharT, class _Traits, class _Allocator>
4407_LIBCPP_FUNC_VIS
4414_LIBCPP_TEMPLATE_DATA_VIS
44084415const typename basic_string<_CharT, _Traits, _Allocator>::size_type
44094416 basic_string<_CharT, _Traits, _Allocator>::npos;
44104417
......@@ -4441,8 +4448,6 @@ basic_istream<_CharT, _Traits>&
44414448getline(basic_istream<_CharT, _Traits>& __is,
44424449 basic_string<_CharT, _Traits, _Allocator>& __str);
44434450
4444#ifndef _LIBCPP_CXX03_LANG
4445
44464451template<class _CharT, class _Traits, class _Allocator>
44474452inline _LIBCPP_INLINE_VISIBILITY
44484453basic_istream<_CharT, _Traits>&
......@@ -4455,8 +4460,6 @@ basic_istream<_CharT, _Traits>&
44554460getline(basic_istream<_CharT, _Traits>&& __is,
44564461 basic_string<_CharT, _Traits, _Allocator>& __str);
44574462
4458#endif // _LIBCPP_CXX03_LANG
4459
44604463#if _LIBCPP_STD_VER > 17
44614464template <class _CharT, class _Traits, class _Allocator, class _Up>
44624465inline _LIBCPP_INLINE_VISIBILITY
......@@ -4513,7 +4516,7 @@ basic_string<_CharT, _Traits, _Allocator>::__subscriptable(const const_iterator*
45134516 return this->data() <= __p && __p < this->data() + this->size();
45144517}
45154518
4516#endif // _LIBCPP_DEBUG_LEVEL == 2
4519#endif // _LIBCPP_DEBUG_LEVEL == 2
45174520
45184521#if _LIBCPP_STD_VER > 11
45194522// Literal suffixes for basic_string [basic.string.literals]
......@@ -4533,7 +4536,7 @@ inline namespace literals
45334536 return basic_string<wchar_t> (__str, __len);
45344537 }
45354538
4536#ifndef _LIBCPP_NO_HAS_CHAR8_T
4539#ifndef _LIBCPP_HAS_NO_CHAR8_T
45374540 inline _LIBCPP_INLINE_VISIBILITY
45384541 basic_string<char8_t> operator "" s(const char8_t *__str, size_t __len) _NOEXCEPT
45394542 {
......@@ -4560,4 +4563,4 @@ _LIBCPP_END_NAMESPACE_STD
45604563
45614564_LIBCPP_POP_MACROS
45624565
4563#endif // _LIBCPP_STRING
4566#endif // _LIBCPP_STRING
lib/libcxx/include/string.h+1-1
......@@ -106,4 +106,4 @@ inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_PREFERRED_OVERLOAD
106106}
107107#endif
108108
109#endif // _LIBCPP_STRING_H
109#endif // _LIBCPP_STRING_H
lib/libcxx/include/string_view+55-31
......@@ -19,6 +19,12 @@ namespace std {
1919 template<class charT, class traits = char_traits<charT>>
2020 class basic_string_view;
2121
22 template<class charT, class traits>
23 inline constexpr bool ranges::enable_view<basic_string_view<charT, traits>> = true;
24
25 template<class charT, class traits>
26 inline constexpr bool ranges::enable_borrowed_range<basic_string_view<charT, traits>> = true; // C++20
27
2228 // 7.9, basic_string_view non-member comparison functions
2329 template<class charT, class traits>
2430 constexpr bool operator==(basic_string_view<charT, traits> x,
......@@ -48,6 +54,7 @@ namespace std {
4854
4955 // basic_string_view typedef names
5056 typedef basic_string_view<char> string_view;
57 typedef basic_string_view<char8_t> u8string_view; // C++20
5158 typedef basic_string_view<char16_t> u16string_view;
5259 typedef basic_string_view<char32_t> u32string_view;
5360 typedef basic_string_view<wchar_t> wstring_view;
......@@ -76,6 +83,7 @@ namespace std {
7683 basic_string_view& operator=(const basic_string_view&) noexcept = default;
7784 template<class Allocator>
7885 constexpr basic_string_view(const charT* str);
86 basic_string_view(nullptr_t) = delete; // C++2b
7987 constexpr basic_string_view(const charT* str, size_type len);
8088
8189 // 7.4, basic_string_view iterator support
......@@ -106,7 +114,7 @@ namespace std {
106114 constexpr void remove_suffix(size_type n);
107115 constexpr void swap(basic_string_view& s) noexcept;
108116
109 size_type copy(charT* s, size_type n, size_type pos = 0) const;
117 size_type copy(charT* s, size_type n, size_type pos = 0) const; // constexpr in C++20
110118
111119 constexpr basic_string_view substr(size_type pos = 0, size_type n = npos) const;
112120 constexpr int compare(basic_string_view s) const noexcept;
......@@ -119,28 +127,28 @@ namespace std {
119127 const charT* s, size_type n2) const;
120128 constexpr size_type find(basic_string_view s, size_type pos = 0) const noexcept;
121129 constexpr size_type find(charT c, size_type pos = 0) const noexcept;
122 constexpr size_type find(const charT* s, size_type pos, size_type n) const;
123 constexpr size_type find(const charT* s, size_type pos = 0) const;
130 constexpr size_type find(const charT* s, size_type pos, size_type n) const noexcept; // noexcept as an extension
131 constexpr size_type find(const charT* s, size_type pos = 0) const noexcept; // noexcept as an extension
124132 constexpr size_type rfind(basic_string_view s, size_type pos = npos) const noexcept;
125133 constexpr size_type rfind(charT c, size_type pos = npos) const noexcept;
126 constexpr size_type rfind(const charT* s, size_type pos, size_type n) const;
127 constexpr size_type rfind(const charT* s, size_type pos = npos) const;
134 constexpr size_type rfind(const charT* s, size_type pos, size_type n) const noexcept; // noexcept as an extension
135 constexpr size_type rfind(const charT* s, size_type pos = npos) const noexcept; // noexcept as an extension
128136 constexpr size_type find_first_of(basic_string_view s, size_type pos = 0) const noexcept;
129137 constexpr size_type find_first_of(charT c, size_type pos = 0) const noexcept;
130 constexpr size_type find_first_of(const charT* s, size_type pos, size_type n) const;
131 constexpr size_type find_first_of(const charT* s, size_type pos = 0) const;
138 constexpr size_type find_first_of(const charT* s, size_type pos, size_type n) const noexcept; // noexcept as an extension
139 constexpr size_type find_first_of(const charT* s, size_type pos = 0) const noexcept; // noexcept as an extension
132140 constexpr size_type find_last_of(basic_string_view s, size_type pos = npos) const noexcept;
133141 constexpr size_type find_last_of(charT c, size_type pos = npos) const noexcept;
134 constexpr size_type find_last_of(const charT* s, size_type pos, size_type n) const;
135 constexpr size_type find_last_of(const charT* s, size_type pos = npos) const;
142 constexpr size_type find_last_of(const charT* s, size_type pos, size_type n) const noexcept; // noexcept as an extension
143 constexpr size_type find_last_of(const charT* s, size_type pos = npos) const noexcept; // noexcept as an extension
136144 constexpr size_type find_first_not_of(basic_string_view s, size_type pos = 0) const noexcept;
137145 constexpr size_type find_first_not_of(charT c, size_type pos = 0) const noexcept;
138 constexpr size_type find_first_not_of(const charT* s, size_type pos, size_type n) const;
139 constexpr size_type find_first_not_of(const charT* s, size_type pos = 0) const;
146 constexpr size_type find_first_not_of(const charT* s, size_type pos, size_type n) const noexcept; // noexcept as an extension
147 constexpr size_type find_first_not_of(const charT* s, size_type pos = 0) const noexcept; // noexcept as an extension
140148 constexpr size_type find_last_not_of(basic_string_view s, size_type pos = npos) const noexcept;
141149 constexpr size_type find_last_not_of(charT c, size_type pos = npos) const noexcept;
142 constexpr size_type find_last_not_of(const charT* s, size_type pos, size_type n) const;
143 constexpr size_type find_last_not_of(const charT* s, size_type pos = npos) const;
150 constexpr size_type find_last_not_of(const charT* s, size_type pos, size_type n) const noexcept; // noexcept as an extension
151 constexpr size_type find_last_not_of(const charT* s, size_type pos = npos) const noexcept; // noexcept as an extension
144152
145153 constexpr bool starts_with(basic_string_view s) const noexcept; // C++20
146154 constexpr bool starts_with(charT c) const noexcept; // C++20
......@@ -161,12 +169,14 @@ namespace std {
161169 // 7.11, Hash support
162170 template <class T> struct hash;
163171 template <> struct hash<string_view>;
172 template <> struct hash<u8string_view>; // C++20
164173 template <> struct hash<u16string_view>;
165174 template <> struct hash<u32string_view>;
166175 template <> struct hash<wstring_view>;
167176
168177 constexpr basic_string_view<char> operator "" sv( const char *str, size_t len ) noexcept;
169178 constexpr basic_string_view<wchar_t> operator "" sv( const wchar_t *str, size_t len ) noexcept;
179 constexpr basic_string_view<char8_t> operator "" sv( const char8_t *str, size_t len ) noexcept; // C++20
170180 constexpr basic_string_view<char16_t> operator "" sv( const char16_t *str, size_t len ) noexcept;
171181 constexpr basic_string_view<char32_t> operator "" sv( const char32_t *str, size_t len ) noexcept;
172182
......@@ -176,14 +186,17 @@ namespace std {
176186*/
177187
178188#include <__config>
189#include <__debug>
190#include <__ranges/enable_borrowed_range.h>
191#include <__ranges/enable_view.h>
179192#include <__string>
180#include <iosfwd>
181193#include <algorithm>
194#include <compare>
195#include <iosfwd>
182196#include <iterator>
183197#include <limits>
184198#include <stdexcept>
185199#include <version>
186#include <__debug>
187200
188201#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
189202#pragma GCC system_header
......@@ -199,7 +212,7 @@ template<class _CharT, class _Traits = char_traits<_CharT> >
199212 class _LIBCPP_TEMPLATE_VIS basic_string_view;
200213
201214typedef basic_string_view<char> string_view;
202#ifndef _LIBCPP_NO_HAS_CHAR8_T
215#ifndef _LIBCPP_HAS_NO_CHAR8_T
203216typedef basic_string_view<char8_t> u8string_view;
204217#endif
205218typedef basic_string_view<char16_t> u16string_view;
......@@ -209,7 +222,7 @@ typedef basic_string_view<wchar_t> wstring_view;
209222template<class _CharT, class _Traits>
210223class
211224 _LIBCPP_PREFERRED_NAME(string_view)
212#ifndef _LIBCPP_NO_HAS_CHAR8_T
225#ifndef _LIBCPP_HAS_NO_CHAR8_T
213226 _LIBCPP_PREFERRED_NAME(u8string_view)
214227#endif
215228 _LIBCPP_PREFERRED_NAME(u16string_view)
......@@ -261,6 +274,10 @@ public:
261274 basic_string_view(const _CharT* __s)
262275 : __data(__s), __size(_VSTD::__char_traits_length_checked<_Traits>(__s)) {}
263276
277#if _LIBCPP_STD_VER > 20
278 basic_string_view(nullptr_t) = delete;
279#endif
280
264281 // [string.view.iterators], iterators
265282 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
266283 const_iterator begin() const _NOEXCEPT { return cbegin(); }
......@@ -356,7 +373,7 @@ public:
356373 __other.__size = __sz;
357374 }
358375
359 _LIBCPP_INLINE_VISIBILITY
376 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
360377 size_type copy(_CharT* __s, size_type __n, size_type __pos = 0) const
361378 {
362379 if (__pos > size())
......@@ -431,7 +448,7 @@ public:
431448 }
432449
433450 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
434 size_type find(const _CharT* __s, size_type __pos, size_type __n) const
451 size_type find(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT
435452 {
436453 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find(): received nullptr");
437454 return __str_find<value_type, size_type, traits_type, npos>
......@@ -439,7 +456,7 @@ public:
439456 }
440457
441458 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
442 size_type find(const _CharT* __s, size_type __pos = 0) const
459 size_type find(const _CharT* __s, size_type __pos = 0) const _NOEXCEPT
443460 {
444461 _LIBCPP_ASSERT(__s != nullptr, "string_view::find(): received nullptr");
445462 return __str_find<value_type, size_type, traits_type, npos>
......@@ -463,7 +480,7 @@ public:
463480 }
464481
465482 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
466 size_type rfind(const _CharT* __s, size_type __pos, size_type __n) const
483 size_type rfind(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT
467484 {
468485 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::rfind(): received nullptr");
469486 return __str_rfind<value_type, size_type, traits_type, npos>
......@@ -471,7 +488,7 @@ public:
471488 }
472489
473490 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
474 size_type rfind(const _CharT* __s, size_type __pos=npos) const
491 size_type rfind(const _CharT* __s, size_type __pos=npos) const _NOEXCEPT
475492 {
476493 _LIBCPP_ASSERT(__s != nullptr, "string_view::rfind(): received nullptr");
477494 return __str_rfind<value_type, size_type, traits_type, npos>
......@@ -492,7 +509,7 @@ public:
492509 { return find(__c, __pos); }
493510
494511 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
495 size_type find_first_of(const _CharT* __s, size_type __pos, size_type __n) const
512 size_type find_first_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT
496513 {
497514 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_first_of(): received nullptr");
498515 return __str_find_first_of<value_type, size_type, traits_type, npos>
......@@ -500,7 +517,7 @@ public:
500517 }
501518
502519 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
503 size_type find_first_of(const _CharT* __s, size_type __pos=0) const
520 size_type find_first_of(const _CharT* __s, size_type __pos=0) const _NOEXCEPT
504521 {
505522 _LIBCPP_ASSERT(__s != nullptr, "string_view::find_first_of(): received nullptr");
506523 return __str_find_first_of<value_type, size_type, traits_type, npos>
......@@ -521,7 +538,7 @@ public:
521538 { return rfind(__c, __pos); }
522539
523540 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
524 size_type find_last_of(const _CharT* __s, size_type __pos, size_type __n) const
541 size_type find_last_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT
525542 {
526543 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_last_of(): received nullptr");
527544 return __str_find_last_of<value_type, size_type, traits_type, npos>
......@@ -529,7 +546,7 @@ public:
529546 }
530547
531548 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
532 size_type find_last_of(const _CharT* __s, size_type __pos=npos) const
549 size_type find_last_of(const _CharT* __s, size_type __pos=npos) const _NOEXCEPT
533550 {
534551 _LIBCPP_ASSERT(__s != nullptr, "string_view::find_last_of(): received nullptr");
535552 return __str_find_last_of<value_type, size_type, traits_type, npos>
......@@ -553,7 +570,7 @@ public:
553570 }
554571
555572 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
556 size_type find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const
573 size_type find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT
557574 {
558575 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_first_not_of(): received nullptr");
559576 return __str_find_first_not_of<value_type, size_type, traits_type, npos>
......@@ -561,7 +578,7 @@ public:
561578 }
562579
563580 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
564 size_type find_first_not_of(const _CharT* __s, size_type __pos=0) const
581 size_type find_first_not_of(const _CharT* __s, size_type __pos=0) const _NOEXCEPT
565582 {
566583 _LIBCPP_ASSERT(__s != nullptr, "string_view::find_first_not_of(): received nullptr");
567584 return __str_find_first_not_of<value_type, size_type, traits_type, npos>
......@@ -585,7 +602,7 @@ public:
585602 }
586603
587604 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
588 size_type find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const
605 size_type find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT
589606 {
590607 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_last_not_of(): received nullptr");
591608 return __str_find_last_not_of<value_type, size_type, traits_type, npos>
......@@ -593,7 +610,7 @@ public:
593610 }
594611
595612 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
596 size_type find_last_not_of(const _CharT* __s, size_type __pos=npos) const
613 size_type find_last_not_of(const _CharT* __s, size_type __pos=npos) const _NOEXCEPT
597614 {
598615 _LIBCPP_ASSERT(__s != nullptr, "string_view::find_last_not_of(): received nullptr");
599616 return __str_find_last_not_of<value_type, size_type, traits_type, npos>
......@@ -645,6 +662,13 @@ private:
645662 size_type __size;
646663};
647664
665#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_RANGES)
666template <class _CharT, class _Traits>
667inline constexpr bool ranges::enable_view<basic_string_view<_CharT, _Traits>> = true;
668
669template <class _CharT, class _Traits>
670inline constexpr bool ranges::enable_borrowed_range<basic_string_view<_CharT, _Traits> > = true;
671#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_RANGES)
648672
649673// [string.view.comparison]
650674// operator ==
......@@ -842,7 +866,7 @@ inline namespace literals
842866 return basic_string_view<wchar_t> (__str, __len);
843867 }
844868
845#ifndef _LIBCPP_NO_HAS_CHAR8_T
869#ifndef _LIBCPP_HAS_NO_CHAR8_T
846870 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
847871 basic_string_view<char8_t> operator "" sv(const char8_t *__str, size_t __len) _NOEXCEPT
848872 {
lib/libcxx/include/strstream+7-7
......@@ -130,8 +130,8 @@ private:
130130*/
131131
132132#include <__config>
133#include <ostream>
134133#include <istream>
134#include <ostream>
135135
136136#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
137137#pragma GCC system_header
......@@ -163,7 +163,7 @@ public:
163163 strstreambuf(strstreambuf&& __rhs);
164164 _LIBCPP_INLINE_VISIBILITY
165165 strstreambuf& operator=(strstreambuf&& __rhs);
166#endif // _LIBCPP_CXX03_LANG
166#endif // _LIBCPP_CXX03_LANG
167167
168168 virtual ~strstreambuf();
169169
......@@ -233,7 +233,7 @@ strstreambuf::operator=(strstreambuf&& __rhs)
233233 return *this;
234234}
235235
236#endif // _LIBCPP_CXX03_LANG
236#endif // _LIBCPP_CXX03_LANG
237237
238238class _LIBCPP_TYPE_VIS istrstream
239239 : public istream
......@@ -268,7 +268,7 @@ public:
268268 __sb_ = _VSTD::move(__rhs.__sb_);
269269 return *this;
270270 }
271#endif // _LIBCPP_CXX03_LANG
271#endif // _LIBCPP_CXX03_LANG
272272
273273 virtual ~istrstream();
274274
......@@ -317,7 +317,7 @@ public:
317317 __sb_ = _VSTD::move(__rhs.__sb_);
318318 return *this;
319319 }
320#endif // _LIBCPP_CXX03_LANG
320#endif // _LIBCPP_CXX03_LANG
321321
322322 virtual ~ostrstream();
323323
......@@ -377,7 +377,7 @@ public:
377377 __sb_ = _VSTD::move(__rhs.__sb_);
378378 return *this;
379379 }
380#endif // _LIBCPP_CXX03_LANG
380#endif // _LIBCPP_CXX03_LANG
381381
382382 virtual ~strstream();
383383
......@@ -404,4 +404,4 @@ private:
404404
405405_LIBCPP_END_NAMESPACE_STD
406406
407#endif // _LIBCPP_STRSTREAM
407#endif // _LIBCPP_STRSTREAM
lib/libcxx/include/system_error+8-7
......@@ -142,11 +142,14 @@ template <> struct hash<std::error_condition>;
142142
143143*/
144144
145#include <__config>
145146#include <__errc>
146#include <type_traits>
147#include <stdexcept>
147#include <__functional/unary_function.h>
148148#include <__functional_base>
149#include <compare>
150#include <stdexcept>
149151#include <string>
152#include <type_traits>
150153
151154#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
152155#pragma GCC system_header
......@@ -289,8 +292,7 @@ public:
289292 string message() const;
290293
291294 _LIBCPP_INLINE_VISIBILITY
292 _LIBCPP_EXPLICIT
293 operator bool() const _NOEXCEPT {return __val_ != 0;}
295 explicit operator bool() const _NOEXCEPT {return __val_ != 0;}
294296};
295297
296298inline _LIBCPP_INLINE_VISIBILITY
......@@ -366,8 +368,7 @@ public:
366368 string message() const;
367369
368370 _LIBCPP_INLINE_VISIBILITY
369 _LIBCPP_EXPLICIT
370 operator bool() const _NOEXCEPT {return __val_ != 0;}
371 explicit operator bool() const _NOEXCEPT {return __val_ != 0;}
371372};
372373
373374inline _LIBCPP_INLINE_VISIBILITY
......@@ -484,4 +485,4 @@ void __throw_system_error(int ev, const char* what_arg);
484485
485486_LIBCPP_END_NAMESPACE_STD
486487
487#endif // _LIBCPP_SYSTEM_ERROR
488#endif // _LIBCPP_SYSTEM_ERROR
lib/libcxx/include/tgmath.h+2-2
......@@ -31,6 +31,6 @@
3131
3232#include_next <tgmath.h>
3333
34#endif // __cplusplus
34#endif // __cplusplus
3535
36#endif // _LIBCPP_TGMATH_H
36#endif // _LIBCPP_TGMATH_H
lib/libcxx/include/thread+15-16
......@@ -83,20 +83,20 @@ void sleep_for(const chrono::duration<Rep, Period>& rel_time);
8383*/
8484
8585#include <__config>
86#include <iosfwd>
86#include <__debug>
8787#include <__functional_base>
88#include <type_traits>
88#include <__mutex_base>
89#include <__threading_support>
90#include <__utility/__decay_copy.h>
91#include <__utility/forward.h>
92#include <chrono>
8993#include <cstddef>
9094#include <functional>
95#include <iosfwd>
9196#include <memory>
9297#include <system_error>
93#include <chrono>
94#include <__mutex_base>
95#ifndef _LIBCPP_CXX03_LANG
9698#include <tuple>
97#endif
98#include <__threading_support>
99#include <__debug>
99#include <type_traits>
100100
101101#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
102102#pragma GCC system_header
......@@ -346,7 +346,7 @@ thread::thread(_Fp __f)
346346 __throw_system_error(__ec, "thread constructor failed");
347347}
348348
349#endif // _LIBCPP_CXX03_LANG
349#endif // _LIBCPP_CXX03_LANG
350350
351351inline _LIBCPP_INLINE_VISIBILITY
352352void swap(thread& __x, thread& __y) _NOEXCEPT {__x.swap(__y);}
......@@ -362,12 +362,11 @@ sleep_for(const chrono::duration<_Rep, _Period>& __d)
362362{
363363 if (__d > chrono::duration<_Rep, _Period>::zero())
364364 {
365#if defined(_LIBCPP_COMPILER_GCC) && (__powerpc__ || __POWERPC__)
366 // GCC's long double const folding is incomplete for IBM128 long doubles.
367 _LIBCPP_CONSTEXPR chrono::duration<long double> _Max = chrono::duration<long double>(ULLONG_MAX/1000000000ULL) ;
368#else
369 _LIBCPP_CONSTEXPR chrono::duration<long double> _Max = chrono::nanoseconds::max();
370#endif
365 // The standard guarantees a 64bit signed integer resolution for nanoseconds,
366 // so use INT64_MAX / 1e9 as cut-off point. Use a constant to avoid <climits>
367 // and issues with long double folding on PowerPC with GCC.
368 _LIBCPP_CONSTEXPR chrono::duration<long double> _Max =
369 chrono::duration<long double>(9223372036.0L);
371370 chrono::nanoseconds __ns;
372371 if (__d < _Max)
373372 {
......@@ -411,4 +410,4 @@ _LIBCPP_END_NAMESPACE_STD
411410
412411_LIBCPP_POP_MACROS
413412
414#endif // _LIBCPP_THREAD
413#endif // _LIBCPP_THREAD
lib/libcxx/include/tuple+601-480
......@@ -38,35 +38,39 @@ public:
3838 template <class Alloc>
3939 tuple(allocator_arg_t, const Alloc& a);
4040 template <class Alloc>
41 explicit(see-below) tuple(allocator_arg_t, const Alloc& a, const T&...);
41 explicit(see-below) tuple(allocator_arg_t, const Alloc& a, const T&...); // constexpr in C++20
4242 template <class Alloc, class... U>
43 explicit(see-below) tuple(allocator_arg_t, const Alloc& a, U&&...);
43 explicit(see-below) tuple(allocator_arg_t, const Alloc& a, U&&...); // constexpr in C++20
4444 template <class Alloc>
45 tuple(allocator_arg_t, const Alloc& a, const tuple&);
45 tuple(allocator_arg_t, const Alloc& a, const tuple&); // constexpr in C++20
4646 template <class Alloc>
47 tuple(allocator_arg_t, const Alloc& a, tuple&&);
47 tuple(allocator_arg_t, const Alloc& a, tuple&&); // constexpr in C++20
4848 template <class Alloc, class... U>
49 explicit(see-below) tuple(allocator_arg_t, const Alloc& a, const tuple<U...>&);
49 explicit(see-below) tuple(allocator_arg_t, const Alloc& a, const tuple<U...>&); // constexpr in C++20
5050 template <class Alloc, class... U>
51 explicit(see-below) tuple(allocator_arg_t, const Alloc& a, tuple<U...>&&);
51 explicit(see-below) tuple(allocator_arg_t, const Alloc& a, tuple<U...>&&); // constexpr in C++20
5252 template <class Alloc, class U1, class U2>
53 explicit(see-below) tuple(allocator_arg_t, const Alloc& a, const pair<U1, U2>&);
53 explicit(see-below) tuple(allocator_arg_t, const Alloc& a, const pair<U1, U2>&); // constexpr in C++20
5454 template <class Alloc, class U1, class U2>
55 explicit(see-below) tuple(allocator_arg_t, const Alloc& a, pair<U1, U2>&&);
55 explicit(see-below) tuple(allocator_arg_t, const Alloc& a, pair<U1, U2>&&); // constexpr in C++20
5656
57 tuple& operator=(const tuple&);
58 tuple&
59 operator=(tuple&&) noexcept(AND(is_nothrow_move_assignable<T>::value ...));
57 tuple& operator=(const tuple&); // constexpr in C++20
58 tuple& operator=(tuple&&) noexcept(is_nothrow_move_assignable_v<T> && ...); // constexpr in C++20
6059 template <class... U>
61 tuple& operator=(const tuple<U...>&);
60 tuple& operator=(const tuple<U...>&); // constexpr in C++20
6261 template <class... U>
63 tuple& operator=(tuple<U...>&&);
62 tuple& operator=(tuple<U...>&&); // constexpr in C++20
6463 template <class U1, class U2>
65 tuple& operator=(const pair<U1, U2>&); // iff sizeof...(T) == 2
64 tuple& operator=(const pair<U1, U2>&); // iff sizeof...(T) == 2 // constexpr in C++20
6665 template <class U1, class U2>
67 tuple& operator=(pair<U1, U2>&&); // iff sizeof...(T) == 2
66 tuple& operator=(pair<U1, U2>&&); // iff sizeof...(T) == 2 // constexpr in C++20
6867
69 void swap(tuple&) noexcept(AND(swap(declval<T&>(), declval<T&>())...));
68 template<class U, size_t N>
69 tuple& operator=(array<U, N> const&) // iff sizeof...(T) == N, EXTENSION
70 template<class U, size_t N>
71 tuple& operator=(array<U, N>&&) // iff sizeof...(T) == N, EXTENSION
72
73 void swap(tuple&) noexcept(AND(swap(declval<T&>(), declval<T&>())...)); // constexpr in C++20
7074};
7175
7276template <class ...T>
......@@ -146,10 +150,16 @@ template <class... Types>
146150*/
147151
148152#include <__config>
153#include <__functional/unwrap_ref.h>
154#include <__functional_base>
155#include <__memory/allocator_arg_t.h>
156#include <__memory/uses_allocator.h>
149157#include <__tuple>
158#include <__utility/forward.h>
159#include <__utility/move.h>
160#include <compare>
150161#include <cstddef>
151162#include <type_traits>
152#include <__functional_base>
153163#include <utility>
154164#include <version>
155165
......@@ -170,7 +180,7 @@ template <size_t _Ip, class _Hp,
170180class __tuple_leaf;
171181
172182template <size_t _Ip, class _Hp, bool _Ep>
173inline _LIBCPP_INLINE_VISIBILITY
183inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
174184void swap(__tuple_leaf<_Ip, _Hp, _Ep>& __x, __tuple_leaf<_Ip, _Hp, _Ep>& __y)
175185 _NOEXCEPT_(__is_nothrow_swappable<_Hp>::value)
176186{
......@@ -191,29 +201,30 @@ class __tuple_leaf
191201#endif
192202 }
193203
204 _LIBCPP_CONSTEXPR_AFTER_CXX11
194205 __tuple_leaf& operator=(const __tuple_leaf&);
195206public:
196 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR __tuple_leaf()
207 _LIBCPP_INLINE_VISIBILITY constexpr __tuple_leaf()
197208 _NOEXCEPT_(is_nothrow_default_constructible<_Hp>::value) : __value_()
198209 {static_assert(!is_reference<_Hp>::value,
199210 "Attempted to default construct a reference element in a tuple");}
200211
201212 template <class _Alloc>
202 _LIBCPP_INLINE_VISIBILITY
213 _LIBCPP_INLINE_VISIBILITY constexpr
203214 __tuple_leaf(integral_constant<int, 0>, const _Alloc&)
204215 : __value_()
205216 {static_assert(!is_reference<_Hp>::value,
206217 "Attempted to default construct a reference element in a tuple");}
207218
208219 template <class _Alloc>
209 _LIBCPP_INLINE_VISIBILITY
220 _LIBCPP_INLINE_VISIBILITY constexpr
210221 __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a)
211222 : __value_(allocator_arg_t(), __a)
212223 {static_assert(!is_reference<_Hp>::value,
213224 "Attempted to default construct a reference element in a tuple");}
214225
215226 template <class _Alloc>
216 _LIBCPP_INLINE_VISIBILITY
227 _LIBCPP_INLINE_VISIBILITY constexpr
217228 __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a)
218229 : __value_(__a)
219230 {static_assert(!is_reference<_Hp>::value,
......@@ -234,21 +245,21 @@ public:
234245 "Attempted construction of reference element binds to a temporary whose lifetime has ended");}
235246
236247 template <class _Tp, class _Alloc>
237 _LIBCPP_INLINE_VISIBILITY
248 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
238249 explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t)
239250 : __value_(_VSTD::forward<_Tp>(__t))
240251 {static_assert(__can_bind_reference<_Tp&&>(),
241252 "Attempted construction of reference element binds to a temporary whose lifetime has ended");}
242253
243254 template <class _Tp, class _Alloc>
244 _LIBCPP_INLINE_VISIBILITY
255 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
245256 explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t)
246257 : __value_(allocator_arg_t(), __a, _VSTD::forward<_Tp>(__t))
247258 {static_assert(!is_reference<_Hp>::value,
248259 "Attempted to uses-allocator construct a reference element in a tuple");}
249260
250261 template <class _Tp, class _Alloc>
251 _LIBCPP_INLINE_VISIBILITY
262 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
252263 explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t)
253264 : __value_(_VSTD::forward<_Tp>(__t), __a)
254265 {static_assert(!is_reference<_Hp>::value,
......@@ -257,16 +268,7 @@ public:
257268 __tuple_leaf(const __tuple_leaf& __t) = default;
258269 __tuple_leaf(__tuple_leaf&& __t) = default;
259270
260 template <class _Tp>
261 _LIBCPP_INLINE_VISIBILITY
262 __tuple_leaf&
263 operator=(_Tp&& __t) _NOEXCEPT_((is_nothrow_assignable<_Hp&, _Tp>::value))
264 {
265 __value_ = _VSTD::forward<_Tp>(__t);
266 return *this;
267 }
268
269 _LIBCPP_INLINE_VISIBILITY
271 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
270272 int swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value)
271273 {
272274 _VSTD::swap(*this, __t);
......@@ -281,23 +283,23 @@ template <size_t _Ip, class _Hp>
281283class __tuple_leaf<_Ip, _Hp, true>
282284 : private _Hp
283285{
284
286 _LIBCPP_CONSTEXPR_AFTER_CXX11
285287 __tuple_leaf& operator=(const __tuple_leaf&);
286288public:
287 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR __tuple_leaf()
289 _LIBCPP_INLINE_VISIBILITY constexpr __tuple_leaf()
288290 _NOEXCEPT_(is_nothrow_default_constructible<_Hp>::value) {}
289291
290292 template <class _Alloc>
291 _LIBCPP_INLINE_VISIBILITY
293 _LIBCPP_INLINE_VISIBILITY constexpr
292294 __tuple_leaf(integral_constant<int, 0>, const _Alloc&) {}
293295
294296 template <class _Alloc>
295 _LIBCPP_INLINE_VISIBILITY
297 _LIBCPP_INLINE_VISIBILITY constexpr
296298 __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a)
297299 : _Hp(allocator_arg_t(), __a) {}
298300
299301 template <class _Alloc>
300 _LIBCPP_INLINE_VISIBILITY
302 _LIBCPP_INLINE_VISIBILITY constexpr
301303 __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a)
302304 : _Hp(__a) {}
303305
......@@ -314,33 +316,24 @@ public:
314316 : _Hp(_VSTD::forward<_Tp>(__t)) {}
315317
316318 template <class _Tp, class _Alloc>
317 _LIBCPP_INLINE_VISIBILITY
319 _LIBCPP_INLINE_VISIBILITY constexpr
318320 explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t)
319321 : _Hp(_VSTD::forward<_Tp>(__t)) {}
320322
321323 template <class _Tp, class _Alloc>
322 _LIBCPP_INLINE_VISIBILITY
324 _LIBCPP_INLINE_VISIBILITY constexpr
323325 explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t)
324326 : _Hp(allocator_arg_t(), __a, _VSTD::forward<_Tp>(__t)) {}
325327
326328 template <class _Tp, class _Alloc>
327 _LIBCPP_INLINE_VISIBILITY
329 _LIBCPP_INLINE_VISIBILITY constexpr
328330 explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t)
329331 : _Hp(_VSTD::forward<_Tp>(__t), __a) {}
330332
331333 __tuple_leaf(__tuple_leaf const &) = default;
332334 __tuple_leaf(__tuple_leaf &&) = default;
333335
334 template <class _Tp>
335 _LIBCPP_INLINE_VISIBILITY
336 __tuple_leaf&
337 operator=(_Tp&& __t) _NOEXCEPT_((is_nothrow_assignable<_Hp&, _Tp>::value))
338 {
339 _Hp::operator=(_VSTD::forward<_Tp>(__t));
340 return *this;
341 }
342
343 _LIBCPP_INLINE_VISIBILITY
336 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
344337 int
345338 swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value)
346339 {
......@@ -353,7 +346,7 @@ public:
353346};
354347
355348template <class ..._Tp>
356_LIBCPP_INLINE_VISIBILITY
349_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
357350void __swallow(_Tp&&...) _NOEXCEPT {}
358351
359352template <class _Tp>
......@@ -373,7 +366,7 @@ struct _LIBCPP_DECLSPEC_EMPTY_BASES __tuple_impl<__tuple_indices<_Indx...>, _Tp.
373366 : public __tuple_leaf<_Indx, _Tp>...
374367{
375368 _LIBCPP_INLINE_VISIBILITY
376 _LIBCPP_CONSTEXPR __tuple_impl()
369 constexpr __tuple_impl()
377370 _NOEXCEPT_(__all<is_nothrow_default_constructible<_Tp>::value...>::value) {}
378371
379372 template <size_t ..._Uf, class ..._Tf,
......@@ -391,7 +384,7 @@ struct _LIBCPP_DECLSPEC_EMPTY_BASES __tuple_impl<__tuple_indices<_Indx...>, _Tp.
391384
392385 template <class _Alloc, size_t ..._Uf, class ..._Tf,
393386 size_t ..._Ul, class ..._Tl, class ..._Up>
394 _LIBCPP_INLINE_VISIBILITY
387 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
395388 explicit
396389 __tuple_impl(allocator_arg_t, const _Alloc& __a,
397390 __tuple_indices<_Uf...>, __tuple_types<_Tf...>,
......@@ -421,7 +414,7 @@ struct _LIBCPP_DECLSPEC_EMPTY_BASES __tuple_impl<__tuple_indices<_Indx...>, _Tp.
421414 __tuple_constructible<_Tuple, tuple<_Tp...> >::value
422415 >::type
423416 >
424 _LIBCPP_INLINE_VISIBILITY
417 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
425418 __tuple_impl(allocator_arg_t, const _Alloc& __a, _Tuple&& __t)
426419 : __tuple_leaf<_Indx, _Tp>(__uses_alloc_ctor<_Tp, _Alloc, typename tuple_element<_Indx,
427420 typename __make_tuple_types<_Tuple>::type>::type>(), __a,
......@@ -429,49 +422,30 @@ struct _LIBCPP_DECLSPEC_EMPTY_BASES __tuple_impl<__tuple_indices<_Indx...>, _Tp.
429422 typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))...
430423 {}
431424
432 template <class _Tuple>
433 _LIBCPP_INLINE_VISIBILITY
434 typename enable_if
435 <
436 __tuple_assignable<_Tuple, tuple<_Tp...> >::value,
437 __tuple_impl&
438 >::type
439 operator=(_Tuple&& __t) _NOEXCEPT_((__all<is_nothrow_assignable<_Tp&, typename tuple_element<_Indx,
440 typename __make_tuple_types<_Tuple>::type>::type>::value...>::value))
441 {
442 __swallow(__tuple_leaf<_Indx, _Tp>::operator=(_VSTD::forward<typename tuple_element<_Indx,
443 typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))...);
444 return *this;
445 }
446
447425 __tuple_impl(const __tuple_impl&) = default;
448426 __tuple_impl(__tuple_impl&&) = default;
449427
450 _LIBCPP_INLINE_VISIBILITY
451 __tuple_impl&
452 operator=(const __tuple_impl& __t) _NOEXCEPT_((__all<is_nothrow_copy_assignable<_Tp>::value...>::value))
453 {
454 __swallow(__tuple_leaf<_Indx, _Tp>::operator=(static_cast<const __tuple_leaf<_Indx, _Tp>&>(__t).get())...);
455 return *this;
456 }
457
458 _LIBCPP_INLINE_VISIBILITY
459 __tuple_impl&
460 operator=(__tuple_impl&& __t) _NOEXCEPT_((__all<is_nothrow_move_assignable<_Tp>::value...>::value))
461 {
462 __swallow(__tuple_leaf<_Indx, _Tp>::operator=(_VSTD::forward<_Tp>(static_cast<__tuple_leaf<_Indx, _Tp>&>(__t).get()))...);
463 return *this;
464 }
465
466 _LIBCPP_INLINE_VISIBILITY
428 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
467429 void swap(__tuple_impl& __t)
468430 _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
469431 {
470 __swallow(__tuple_leaf<_Indx, _Tp>::swap(static_cast<__tuple_leaf<_Indx, _Tp>&>(__t))...);
432 _VSTD::__swallow(__tuple_leaf<_Indx, _Tp>::swap(static_cast<__tuple_leaf<_Indx, _Tp>&>(__t))...);
471433 }
472434};
473435
436template<class _Dest, class _Source, size_t ..._Np>
437_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
438void __memberwise_copy_assign(_Dest& __dest, _Source const& __source, __tuple_indices<_Np...>) {
439 _VSTD::__swallow(((_VSTD::get<_Np>(__dest) = _VSTD::get<_Np>(__source)), void(), 0)...);
440}
474441
442template<class _Dest, class _Source, class ..._Up, size_t ..._Np>
443_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
444void __memberwise_forward_assign(_Dest& __dest, _Source&& __source, __tuple_types<_Up...>, __tuple_indices<_Np...>) {
445 _VSTD::__swallow(((
446 _VSTD::get<_Np>(__dest) = _VSTD::forward<_Up>(_VSTD::get<_Np>(__source))
447 ), void(), 0)...);
448}
475449
476450template <class ..._Tp>
477451class _LIBCPP_TEMPLATE_VIS tuple
......@@ -480,165 +454,6 @@ class _LIBCPP_TEMPLATE_VIS tuple
480454
481455 _BaseT __base_;
482456
483#if defined(_LIBCPP_ENABLE_TUPLE_IMPLICIT_REDUCED_ARITY_EXTENSION)
484 static constexpr bool _EnableImplicitReducedArityExtension = true;
485#else
486 static constexpr bool _EnableImplicitReducedArityExtension = false;
487#endif
488
489 template <class ..._Args>
490 struct _PackExpandsToThisTuple : false_type {};
491
492 template <class _Arg>
493 struct _PackExpandsToThisTuple<_Arg>
494 : is_same<typename __uncvref<_Arg>::type, tuple> {};
495
496 template <bool _MaybeEnable, class _Dummy = void>
497 struct _CheckArgsConstructor : __check_tuple_constructor_fail {};
498
499 template <class _Dummy>
500 struct _CheckArgsConstructor<true, _Dummy>
501 {
502 template <int&...>
503 static constexpr bool __enable_implicit_default() {
504 return __all<__is_implicitly_default_constructible<_Tp>::value... >::value;
505 }
506
507 template <int&...>
508 static constexpr bool __enable_explicit_default() {
509 return
510 __all<is_default_constructible<_Tp>::value...>::value &&
511 !__enable_implicit_default< >();
512 }
513
514
515 template <class ..._Args>
516 static constexpr bool __enable_explicit() {
517 return
518 __tuple_constructible<
519 tuple<_Args...>,
520 typename __make_tuple_types<tuple,
521 sizeof...(_Args) < sizeof...(_Tp) ?
522 sizeof...(_Args) :
523 sizeof...(_Tp)>::type
524 >::value &&
525 !__tuple_convertible<
526 tuple<_Args...>,
527 typename __make_tuple_types<tuple,
528 sizeof...(_Args) < sizeof...(_Tp) ?
529 sizeof...(_Args) :
530 sizeof...(_Tp)>::type
531 >::value &&
532 __all_default_constructible<
533 typename __make_tuple_types<tuple, sizeof...(_Tp),
534 sizeof...(_Args) < sizeof...(_Tp) ?
535 sizeof...(_Args) :
536 sizeof...(_Tp)>::type
537 >::value;
538 }
539
540 template <class ..._Args>
541 static constexpr bool __enable_implicit() {
542 return
543 __tuple_constructible<
544 tuple<_Args...>,
545 typename __make_tuple_types<tuple,
546 sizeof...(_Args) < sizeof...(_Tp) ?
547 sizeof...(_Args) :
548 sizeof...(_Tp)>::type
549 >::value &&
550 __tuple_convertible<
551 tuple<_Args...>,
552 typename __make_tuple_types<tuple,
553 sizeof...(_Args) < sizeof...(_Tp) ?
554 sizeof...(_Args) :
555 sizeof...(_Tp)>::type
556 >::value &&
557 __all_default_constructible<
558 typename __make_tuple_types<tuple, sizeof...(_Tp),
559 sizeof...(_Args) < sizeof...(_Tp) ?
560 sizeof...(_Args) :
561 sizeof...(_Tp)>::type
562 >::value;
563 }
564 };
565
566 template <bool _MaybeEnable,
567 bool = sizeof...(_Tp) == 1,
568 class _Dummy = void>
569 struct _CheckTupleLikeConstructor : __check_tuple_constructor_fail {};
570
571 template <class _Dummy>
572 struct _CheckTupleLikeConstructor<true, false, _Dummy>
573 {
574 template <class _Tuple>
575 static constexpr bool __enable_implicit() {
576 return __tuple_constructible<_Tuple, tuple>::value
577 && __tuple_convertible<_Tuple, tuple>::value;
578 }
579
580 template <class _Tuple>
581 static constexpr bool __enable_explicit() {
582 return __tuple_constructible<_Tuple, tuple>::value
583 && !__tuple_convertible<_Tuple, tuple>::value;
584 }
585 };
586
587 template <class _Dummy>
588 struct _CheckTupleLikeConstructor<true, true, _Dummy>
589 {
590 // This trait is used to disable the tuple-like constructor when
591 // the UTypes... constructor should be selected instead.
592 // See LWG issue #2549.
593 template <class _Tuple>
594 using _PreferTupleLikeConstructor = _Or<
595 // Don't attempt the two checks below if the tuple we are given
596 // has the same type as this tuple.
597 _IsSame<__uncvref_t<_Tuple>, tuple>,
598 _Lazy<_And,
599 _Not<is_constructible<_Tp..., _Tuple>>,
600 _Not<is_convertible<_Tuple, _Tp...>>
601 >
602 >;
603
604 template <class _Tuple>
605 static constexpr bool __enable_implicit() {
606 return _And<
607 __tuple_constructible<_Tuple, tuple>,
608 __tuple_convertible<_Tuple, tuple>,
609 _PreferTupleLikeConstructor<_Tuple>
610 >::value;
611 }
612
613 template <class _Tuple>
614 static constexpr bool __enable_explicit() {
615 return _And<
616 __tuple_constructible<_Tuple, tuple>,
617 _PreferTupleLikeConstructor<_Tuple>,
618 _Not<__tuple_convertible<_Tuple, tuple>>
619 >::value;
620 }
621 };
622
623 template <class _Tuple, bool _DisableIfLValue>
624 using _EnableImplicitTupleLikeConstructor = _EnableIf<
625 _CheckTupleLikeConstructor<
626 __tuple_like_with_size<_Tuple, sizeof...(_Tp)>::value
627 && !_PackExpandsToThisTuple<_Tuple>::value
628 && (!is_lvalue_reference<_Tuple>::value || !_DisableIfLValue)
629 >::template __enable_implicit<_Tuple>(),
630 bool
631 >;
632
633 template <class _Tuple, bool _DisableIfLValue>
634 using _EnableExplicitTupleLikeConstructor = _EnableIf<
635 _CheckTupleLikeConstructor<
636 __tuple_like_with_size<_Tuple, sizeof...(_Tp)>::value
637 && !_PackExpandsToThisTuple<_Tuple>::value
638 && (!is_lvalue_reference<_Tuple>::value || !_DisableIfLValue)
639 >::template __enable_explicit<_Tuple>(),
640 bool
641 >;
642457 template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
643458 typename tuple_element<_Jp, tuple<_Up...> >::type& get(tuple<_Up...>&) _NOEXCEPT;
644459 template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
......@@ -648,57 +463,69 @@ class _LIBCPP_TEMPLATE_VIS tuple
648463 template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
649464 const typename tuple_element<_Jp, tuple<_Up...> >::type&& get(const tuple<_Up...>&&) _NOEXCEPT;
650465public:
651
652 template <bool _Dummy = true, _EnableIf<
653 _CheckArgsConstructor<_Dummy>::__enable_implicit_default()
654 , void*> = nullptr>
466 // [tuple.cnstr]
467
468 // tuple() constructors (including allocator_arg_t variants)
469 template <template<class...> class _IsImpDefault = __is_implicitly_default_constructible, _EnableIf<
470 _And<
471 _IsImpDefault<_Tp>... // explicit check
472 >::value
473 , int> = 0>
655474 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
656475 tuple()
657 _NOEXCEPT_(__all<is_nothrow_default_constructible<_Tp>::value...>::value) {}
658
659 template <bool _Dummy = true, _EnableIf<
660 _CheckArgsConstructor<_Dummy>::__enable_explicit_default()
661 , void*> = nullptr>
662 explicit _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
663 tuple()
664 _NOEXCEPT_(__all<is_nothrow_default_constructible<_Tp>::value...>::value) {}
665
666 tuple(tuple const&) = default;
667 tuple(tuple&&) = default;
668
669 template <class _AllocArgT, class _Alloc, _EnableIf<
670 _CheckArgsConstructor<_IsSame<allocator_arg_t, _AllocArgT>::value >::__enable_implicit_default()
671 , void*> = nullptr
672 >
673 _LIBCPP_INLINE_VISIBILITY
674 tuple(_AllocArgT, _Alloc const& __a)
476 _NOEXCEPT_(_And<is_nothrow_default_constructible<_Tp>...>::value)
477 { }
478
479 template <template<class...> class _IsImpDefault = __is_implicitly_default_constructible,
480 template<class...> class _IsDefault = is_default_constructible, _EnableIf<
481 _And<
482 _IsDefault<_Tp>...,
483 _Not<_Lazy<_And, _IsImpDefault<_Tp>...> > // explicit check
484 >::value
485 , int> = 0>
486 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
487 explicit tuple()
488 _NOEXCEPT_(_And<is_nothrow_default_constructible<_Tp>...>::value)
489 { }
490
491 template <class _Alloc, template<class...> class _IsImpDefault = __is_implicitly_default_constructible, _EnableIf<
492 _And<
493 _IsImpDefault<_Tp>... // explicit check
494 >::value
495 , int> = 0>
496 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
497 tuple(allocator_arg_t, _Alloc const& __a)
675498 : __base_(allocator_arg_t(), __a,
676499 __tuple_indices<>(), __tuple_types<>(),
677500 typename __make_tuple_indices<sizeof...(_Tp), 0>::type(),
678501 __tuple_types<_Tp...>()) {}
679502
680 template <class _AllocArgT, class _Alloc, _EnableIf<
681 _CheckArgsConstructor<_IsSame<allocator_arg_t, _AllocArgT>::value>::__enable_explicit_default()
682 , void*> = nullptr
683 >
684 explicit _LIBCPP_INLINE_VISIBILITY
685 tuple(_AllocArgT, _Alloc const& __a)
503 template <class _Alloc,
504 template<class...> class _IsImpDefault = __is_implicitly_default_constructible,
505 template<class...> class _IsDefault = is_default_constructible, _EnableIf<
506 _And<
507 _IsDefault<_Tp>...,
508 _Not<_Lazy<_And, _IsImpDefault<_Tp>...> > // explicit check
509 >::value
510 , int> = 0>
511 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
512 explicit tuple(allocator_arg_t, _Alloc const& __a)
686513 : __base_(allocator_arg_t(), __a,
687514 __tuple_indices<>(), __tuple_types<>(),
688515 typename __make_tuple_indices<sizeof...(_Tp), 0>::type(),
689516 __tuple_types<_Tp...>()) {}
690517
691 template <bool _Dummy = true,
692 typename enable_if
693 <
694 _CheckArgsConstructor<
695 _Dummy
696 >::template __enable_implicit<_Tp const&...>(),
697 bool
698 >::type = false
699 >
518 // tuple(const T&...) constructors (including allocator_arg_t variants)
519 template <template<class...> class _And = _And, _EnableIf<
520 _And<
521 _BoolConstant<sizeof...(_Tp) >= 1>,
522 is_copy_constructible<_Tp>...,
523 is_convertible<const _Tp&, _Tp>... // explicit check
524 >::value
525 , int> = 0>
700526 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
701 tuple(const _Tp& ... __t) _NOEXCEPT_((__all<is_nothrow_copy_constructible<_Tp>::value...>::value))
527 tuple(const _Tp& ... __t)
528 _NOEXCEPT_(_And<is_nothrow_copy_constructible<_Tp>...>::value)
702529 : __base_(typename __make_tuple_indices<sizeof...(_Tp)>::type(),
703530 typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
704531 typename __make_tuple_indices<0>::type(),
......@@ -706,17 +533,16 @@ public:
706533 __t...
707534 ) {}
708535
709 template <bool _Dummy = true,
710 typename enable_if
711 <
712 _CheckArgsConstructor<
713 _Dummy
714 >::template __enable_explicit<_Tp const&...>(),
715 bool
716 >::type = false
717 >
536 template <template<class...> class _And = _And, _EnableIf<
537 _And<
538 _BoolConstant<sizeof...(_Tp) >= 1>,
539 is_copy_constructible<_Tp>...,
540 _Not<_Lazy<_And, is_convertible<const _Tp&, _Tp>...> > // explicit check
541 >::value
542 , int> = 0>
718543 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
719 explicit tuple(const _Tp& ... __t) _NOEXCEPT_((__all<is_nothrow_copy_constructible<_Tp>::value...>::value))
544 explicit tuple(const _Tp& ... __t)
545 _NOEXCEPT_(_And<is_nothrow_copy_constructible<_Tp>...>::value)
720546 : __base_(typename __make_tuple_indices<sizeof...(_Tp)>::type(),
721547 typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
722548 typename __make_tuple_indices<0>::type(),
......@@ -724,17 +550,15 @@ public:
724550 __t...
725551 ) {}
726552
727 template <class _Alloc, bool _Dummy = true,
728 typename enable_if
729 <
730 _CheckArgsConstructor<
731 _Dummy
732 >::template __enable_implicit<_Tp const&...>(),
733 bool
734 >::type = false
735 >
736 _LIBCPP_INLINE_VISIBILITY
737 tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t)
553 template <class _Alloc, template<class...> class _And = _And, _EnableIf<
554 _And<
555 _BoolConstant<sizeof...(_Tp) >= 1>,
556 is_copy_constructible<_Tp>...,
557 is_convertible<const _Tp&, _Tp>... // explicit check
558 >::value
559 , int> = 0>
560 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
561 tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t)
738562 : __base_(allocator_arg_t(), __a,
739563 typename __make_tuple_indices<sizeof...(_Tp)>::type(),
740564 typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
......@@ -743,18 +567,15 @@ public:
743567 __t...
744568 ) {}
745569
746 template <class _Alloc, bool _Dummy = true,
747 typename enable_if
748 <
749 _CheckArgsConstructor<
750 _Dummy
751 >::template __enable_explicit<_Tp const&...>(),
752 bool
753 >::type = false
754 >
755 _LIBCPP_INLINE_VISIBILITY
756 explicit
757 tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t)
570 template <class _Alloc, template<class...> class _And = _And, _EnableIf<
571 _And<
572 _BoolConstant<sizeof...(_Tp) >= 1>,
573 is_copy_constructible<_Tp>...,
574 _Not<_Lazy<_And, is_convertible<const _Tp&, _Tp>...> > // explicit check
575 >::value
576 , int> = 0>
577 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
578 explicit tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t)
758579 : __base_(allocator_arg_t(), __a,
759580 typename __make_tuple_indices<sizeof...(_Tp)>::type(),
760581 typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
......@@ -763,193 +584,493 @@ public:
763584 __t...
764585 ) {}
765586
766 template <class ..._Up,
767 bool _PackIsTuple = _PackExpandsToThisTuple<_Up...>::value,
768 typename enable_if
769 <
770 _CheckArgsConstructor<
771 sizeof...(_Up) == sizeof...(_Tp)
772 && !_PackIsTuple
773 >::template __enable_implicit<_Up...>() ||
774 _CheckArgsConstructor<
775 _EnableImplicitReducedArityExtension
776 && sizeof...(_Up) < sizeof...(_Tp)
777 && !_PackIsTuple
778 >::template __enable_implicit<_Up...>(),
779 bool
780 >::type = false
781 >
782 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
783 tuple(_Up&&... __u)
784 _NOEXCEPT_((
785 is_nothrow_constructible<_BaseT,
786 typename __make_tuple_indices<sizeof...(_Up)>::type,
787 typename __make_tuple_types<tuple, sizeof...(_Up)>::type,
788 typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type,
789 typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type,
790 _Up...
791 >::value
792 ))
793 : __base_(typename __make_tuple_indices<sizeof...(_Up)>::type(),
587 // tuple(U&& ...) constructors (including allocator_arg_t variants)
588 template <class ..._Up> struct _IsThisTuple : false_type { };
589 template <class _Up> struct _IsThisTuple<_Up> : is_same<__uncvref_t<_Up>, tuple> { };
590
591 template <class ..._Up>
592 struct _EnableUTypesCtor : _And<
593 _BoolConstant<sizeof...(_Tp) >= 1>,
594 _Not<_IsThisTuple<_Up...> >, // extension to allow mis-behaved user constructors
595 is_constructible<_Tp, _Up>...
596 > { };
597
598 template <class ..._Up, _EnableIf<
599 _And<
600 _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
601 _EnableUTypesCtor<_Up...>,
602 is_convertible<_Up, _Tp>... // explicit check
603 >::value
604 , int> = 0>
605 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
606 tuple(_Up&&... __u)
607 _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, _Up>...>::value))
608 : __base_(typename __make_tuple_indices<sizeof...(_Up)>::type(),
794609 typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
795610 typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
796611 typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
797612 _VSTD::forward<_Up>(__u)...) {}
798613
799 template <class ..._Up,
800 typename enable_if
801 <
802 _CheckArgsConstructor<
803 sizeof...(_Up) <= sizeof...(_Tp)
804 && !_PackExpandsToThisTuple<_Up...>::value
805 >::template __enable_explicit<_Up...>() ||
806 _CheckArgsConstructor<
807 !_EnableImplicitReducedArityExtension
808 && sizeof...(_Up) < sizeof...(_Tp)
809 && !_PackExpandsToThisTuple<_Up...>::value
810 >::template __enable_implicit<_Up...>(),
811 bool
812 >::type = false
813 >
814 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
815 explicit
816 tuple(_Up&&... __u)
817 _NOEXCEPT_((
818 is_nothrow_constructible<_BaseT,
819 typename __make_tuple_indices<sizeof...(_Up)>::type,
820 typename __make_tuple_types<tuple, sizeof...(_Up)>::type,
821 typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type,
822 typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type,
823 _Up...
824 >::value
825 ))
826 : __base_(typename __make_tuple_indices<sizeof...(_Up)>::type(),
614 template <class ..._Up, _EnableIf<
615 _And<
616 _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
617 _EnableUTypesCtor<_Up...>,
618 _Not<_Lazy<_And, is_convertible<_Up, _Tp>...> > // explicit check
619 >::value
620 , int> = 0>
621 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
622 explicit tuple(_Up&&... __u)
623 _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, _Up>...>::value))
624 : __base_(typename __make_tuple_indices<sizeof...(_Up)>::type(),
827625 typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
828626 typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
829627 typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
830628 _VSTD::forward<_Up>(__u)...) {}
831629
832 template <class _Alloc, class ..._Up,
833 typename enable_if
834 <
835 _CheckArgsConstructor<
836 sizeof...(_Up) == sizeof...(_Tp) &&
837 !_PackExpandsToThisTuple<_Up...>::value
838 >::template __enable_implicit<_Up...>(),
839 bool
840 >::type = false
841 >
842 _LIBCPP_INLINE_VISIBILITY
843 tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u)
844 : __base_(allocator_arg_t(), __a,
630 template <class _Alloc, class ..._Up, _EnableIf<
631 _And<
632 _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
633 _EnableUTypesCtor<_Up...>,
634 is_convertible<_Up, _Tp>... // explicit check
635 >::value
636 , int> = 0>
637 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
638 tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u)
639 : __base_(allocator_arg_t(), __a,
845640 typename __make_tuple_indices<sizeof...(_Up)>::type(),
846641 typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
847642 typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
848643 typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
849644 _VSTD::forward<_Up>(__u)...) {}
850645
851 template <class _Alloc, class ..._Up,
852 typename enable_if
853 <
854 _CheckArgsConstructor<
855 sizeof...(_Up) == sizeof...(_Tp) &&
856 !_PackExpandsToThisTuple<_Up...>::value
857 >::template __enable_explicit<_Up...>(),
858 bool
859 >::type = false
860 >
861 _LIBCPP_INLINE_VISIBILITY
862 explicit
863 tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u)
864 : __base_(allocator_arg_t(), __a,
646 template <class _Alloc, class ..._Up, _EnableIf<
647 _And<
648 _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
649 _EnableUTypesCtor<_Up...>,
650 _Not<_Lazy<_And, is_convertible<_Up, _Tp>...> > // explicit check
651 >::value
652 , int> = 0>
653 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
654 explicit tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u)
655 : __base_(allocator_arg_t(), __a,
865656 typename __make_tuple_indices<sizeof...(_Up)>::type(),
866657 typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
867658 typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
868659 typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
869660 _VSTD::forward<_Up>(__u)...) {}
870661
871 template <class _Tuple, _EnableImplicitTupleLikeConstructor<_Tuple, true> = false>
872 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
873 tuple(_Tuple&& __t) _NOEXCEPT_((is_nothrow_constructible<_BaseT, _Tuple>::value))
874 : __base_(_VSTD::forward<_Tuple>(__t)) {}
662 // Copy and move constructors (including the allocator_arg_t variants)
663 tuple(const tuple&) = default;
664 tuple(tuple&&) = default;
875665
876 template <class _Tuple, _EnableImplicitTupleLikeConstructor<const _Tuple&, false> = false>
877 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
878 tuple(const _Tuple& __t) _NOEXCEPT_((is_nothrow_constructible<_BaseT, const _Tuple&>::value))
879 : __base_(__t) {}
880 template <class _Tuple, _EnableExplicitTupleLikeConstructor<_Tuple, true> = false>
881 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
882 explicit
883 tuple(_Tuple&& __t) _NOEXCEPT_((is_nothrow_constructible<_BaseT, _Tuple>::value))
884 : __base_(_VSTD::forward<_Tuple>(__t)) {}
666 template <class _Alloc, template<class...> class _And = _And, _EnableIf<
667 _And<is_copy_constructible<_Tp>...>::value
668 , int> = 0>
669 tuple(allocator_arg_t, const _Alloc& __alloc, const tuple& __t)
670 : __base_(allocator_arg_t(), __alloc, __t)
671 { }
672
673 template <class _Alloc, template<class...> class _And = _And, _EnableIf<
674 _And<is_move_constructible<_Tp>...>::value
675 , int> = 0>
676 tuple(allocator_arg_t, const _Alloc& __alloc, tuple&& __t)
677 : __base_(allocator_arg_t(), __alloc, _VSTD::move(__t))
678 { }
679
680 // tuple(const tuple<U...>&) constructors (including allocator_arg_t variants)
681 template <class ..._Up>
682 struct _EnableCopyFromOtherTuple : _And<
683 _Not<is_same<tuple<_Tp...>, tuple<_Up...> > >,
684 _Lazy<_Or,
685 _BoolConstant<sizeof...(_Tp) != 1>,
686 // _Tp and _Up are 1-element packs - the pack expansions look
687 // weird to avoid tripping up the type traits in degenerate cases
688 _Lazy<_And,
689 _Not<is_convertible<const tuple<_Up>&, _Tp> >...,
690 _Not<is_constructible<_Tp, const tuple<_Up>&> >...
691 >
692 >,
693 is_constructible<_Tp, const _Up&>...
694 > { };
695
696 template <class ..._Up, _EnableIf<
697 _And<
698 _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
699 _EnableCopyFromOtherTuple<_Up...>,
700 is_convertible<const _Up&, _Tp>... // explicit check
701 >::value
702 , int> = 0>
703 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
704 tuple(const tuple<_Up...>& __t)
705 _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, const _Up&>...>::value))
706 : __base_(__t)
707 { }
708
709 template <class ..._Up, _EnableIf<
710 _And<
711 _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
712 _EnableCopyFromOtherTuple<_Up...>,
713 _Not<_Lazy<_And, is_convertible<const _Up&, _Tp>...> > // explicit check
714 >::value
715 , int> = 0>
716 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
717 explicit tuple(const tuple<_Up...>& __t)
718 _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, const _Up&>...>::value))
719 : __base_(__t)
720 { }
721
722 template <class ..._Up, class _Alloc, _EnableIf<
723 _And<
724 _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
725 _EnableCopyFromOtherTuple<_Up...>,
726 is_convertible<const _Up&, _Tp>... // explicit check
727 >::value
728 , int> = 0>
729 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
730 tuple(allocator_arg_t, const _Alloc& __a, const tuple<_Up...>& __t)
731 : __base_(allocator_arg_t(), __a, __t)
732 { }
733
734 template <class ..._Up, class _Alloc, _EnableIf<
735 _And<
736 _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
737 _EnableCopyFromOtherTuple<_Up...>,
738 _Not<_Lazy<_And, is_convertible<const _Up&, _Tp>...> > // explicit check
739 >::value
740 , int> = 0>
741 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
742 explicit tuple(allocator_arg_t, const _Alloc& __a, const tuple<_Up...>& __t)
743 : __base_(allocator_arg_t(), __a, __t)
744 { }
745
746 // tuple(tuple<U...>&&) constructors (including allocator_arg_t variants)
747 template <class ..._Up>
748 struct _EnableMoveFromOtherTuple : _And<
749 _Not<is_same<tuple<_Tp...>, tuple<_Up...> > >,
750 _Lazy<_Or,
751 _BoolConstant<sizeof...(_Tp) != 1>,
752 // _Tp and _Up are 1-element packs - the pack expansions look
753 // weird to avoid tripping up the type traits in degenerate cases
754 _Lazy<_And,
755 _Not<is_convertible<tuple<_Up>, _Tp> >...,
756 _Not<is_constructible<_Tp, tuple<_Up> > >...
757 >
758 >,
759 is_constructible<_Tp, _Up>...
760 > { };
761
762 template <class ..._Up, _EnableIf<
763 _And<
764 _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
765 _EnableMoveFromOtherTuple<_Up...>,
766 is_convertible<_Up, _Tp>... // explicit check
767 >::value
768 , int> = 0>
769 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
770 tuple(tuple<_Up...>&& __t)
771 _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, _Up>...>::value))
772 : __base_(_VSTD::move(__t))
773 { }
774
775 template <class ..._Up, _EnableIf<
776 _And<
777 _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
778 _EnableMoveFromOtherTuple<_Up...>,
779 _Not<_Lazy<_And, is_convertible<_Up, _Tp>...> > // explicit check
780 >::value
781 , int> = 0>
782 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
783 explicit tuple(tuple<_Up...>&& __t)
784 _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, _Up>...>::value))
785 : __base_(_VSTD::move(__t))
786 { }
787
788 template <class _Alloc, class ..._Up, _EnableIf<
789 _And<
790 _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
791 _EnableMoveFromOtherTuple<_Up...>,
792 is_convertible<_Up, _Tp>... // explicit check
793 >::value
794 , int> = 0>
795 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
796 tuple(allocator_arg_t, const _Alloc& __a, tuple<_Up...>&& __t)
797 : __base_(allocator_arg_t(), __a, _VSTD::move(__t))
798 { }
799
800 template <class _Alloc, class ..._Up, _EnableIf<
801 _And<
802 _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
803 _EnableMoveFromOtherTuple<_Up...>,
804 _Not<_Lazy<_And, is_convertible<_Up, _Tp>...> > // explicit check
805 >::value
806 , int> = 0>
807 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
808 explicit tuple(allocator_arg_t, const _Alloc& __a, tuple<_Up...>&& __t)
809 : __base_(allocator_arg_t(), __a, _VSTD::move(__t))
810 { }
811
812 // tuple(const pair<U1, U2>&) constructors (including allocator_arg_t variants)
813 template <class _Up1, class _Up2, class ..._DependentTp>
814 struct _EnableImplicitCopyFromPair : _And<
815 is_constructible<_FirstType<_DependentTp...>, const _Up1&>,
816 is_constructible<_SecondType<_DependentTp...>, const _Up2&>,
817 is_convertible<const _Up1&, _FirstType<_DependentTp...> >, // explicit check
818 is_convertible<const _Up2&, _SecondType<_DependentTp...> >
819 > { };
820
821 template <class _Up1, class _Up2, class ..._DependentTp>
822 struct _EnableExplicitCopyFromPair : _And<
823 is_constructible<_FirstType<_DependentTp...>, const _Up1&>,
824 is_constructible<_SecondType<_DependentTp...>, const _Up2&>,
825 _Not<is_convertible<const _Up1&, _FirstType<_DependentTp...> > >, // explicit check
826 _Not<is_convertible<const _Up2&, _SecondType<_DependentTp...> > >
827 > { };
828
829 template <class _Up1, class _Up2, template<class...> class _And = _And, _EnableIf<
830 _And<
831 _BoolConstant<sizeof...(_Tp) == 2>,
832 _EnableImplicitCopyFromPair<_Up1, _Up2, _Tp...>
833 >::value
834 , int> = 0>
835 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
836 tuple(const pair<_Up1, _Up2>& __p)
837 _NOEXCEPT_((_And<
838 is_nothrow_constructible<_FirstType<_Tp...>, const _Up1&>,
839 is_nothrow_constructible<_SecondType<_Tp...>, const _Up2&>
840 >::value))
841 : __base_(__p)
842 { }
843
844 template <class _Up1, class _Up2, template<class...> class _And = _And, _EnableIf<
845 _And<
846 _BoolConstant<sizeof...(_Tp) == 2>,
847 _EnableExplicitCopyFromPair<_Up1, _Up2, _Tp...>
848 >::value
849 , int> = 0>
850 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
851 explicit tuple(const pair<_Up1, _Up2>& __p)
852 _NOEXCEPT_((_And<
853 is_nothrow_constructible<_FirstType<_Tp...>, const _Up1&>,
854 is_nothrow_constructible<_SecondType<_Tp...>, const _Up2&>
855 >::value))
856 : __base_(__p)
857 { }
858
859 template <class _Alloc, class _Up1, class _Up2, template<class...> class _And = _And, _EnableIf<
860 _And<
861 _BoolConstant<sizeof...(_Tp) == 2>,
862 _EnableImplicitCopyFromPair<_Up1, _Up2, _Tp...>
863 >::value
864 , int> = 0>
865 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
866 tuple(allocator_arg_t, const _Alloc& __a, const pair<_Up1, _Up2>& __p)
867 : __base_(allocator_arg_t(), __a, __p)
868 { }
869
870 template <class _Alloc, class _Up1, class _Up2, template<class...> class _And = _And, _EnableIf<
871 _And<
872 _BoolConstant<sizeof...(_Tp) == 2>,
873 _EnableExplicitCopyFromPair<_Up1, _Up2, _Tp...>
874 >::value
875 , int> = 0>
876 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
877 explicit tuple(allocator_arg_t, const _Alloc& __a, const pair<_Up1, _Up2>& __p)
878 : __base_(allocator_arg_t(), __a, __p)
879 { }
880
881 // tuple(pair<U1, U2>&&) constructors (including allocator_arg_t variants)
882 template <class _Up1, class _Up2, class ..._DependentTp>
883 struct _EnableImplicitMoveFromPair : _And<
884 is_constructible<_FirstType<_DependentTp...>, _Up1>,
885 is_constructible<_SecondType<_DependentTp...>, _Up2>,
886 is_convertible<_Up1, _FirstType<_DependentTp...> >, // explicit check
887 is_convertible<_Up2, _SecondType<_DependentTp...> >
888 > { };
889
890 template <class _Up1, class _Up2, class ..._DependentTp>
891 struct _EnableExplicitMoveFromPair : _And<
892 is_constructible<_FirstType<_DependentTp...>, _Up1>,
893 is_constructible<_SecondType<_DependentTp...>, _Up2>,
894 _Not<is_convertible<_Up1, _FirstType<_DependentTp...> > >, // explicit check
895 _Not<is_convertible<_Up2, _SecondType<_DependentTp...> > >
896 > { };
897
898 template <class _Up1, class _Up2, template<class...> class _And = _And, _EnableIf<
899 _And<
900 _BoolConstant<sizeof...(_Tp) == 2>,
901 _EnableImplicitMoveFromPair<_Up1, _Up2, _Tp...>
902 >::value
903 , int> = 0>
904 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
905 tuple(pair<_Up1, _Up2>&& __p)
906 _NOEXCEPT_((_And<
907 is_nothrow_constructible<_FirstType<_Tp...>, _Up1>,
908 is_nothrow_constructible<_SecondType<_Tp...>, _Up2>
909 >::value))
910 : __base_(_VSTD::move(__p))
911 { }
912
913 template <class _Up1, class _Up2, template<class...> class _And = _And, _EnableIf<
914 _And<
915 _BoolConstant<sizeof...(_Tp) == 2>,
916 _EnableExplicitMoveFromPair<_Up1, _Up2, _Tp...>
917 >::value
918 , int> = 0>
919 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
920 explicit tuple(pair<_Up1, _Up2>&& __p)
921 _NOEXCEPT_((_And<
922 is_nothrow_constructible<_FirstType<_Tp...>, _Up1>,
923 is_nothrow_constructible<_SecondType<_Tp...>, _Up2>
924 >::value))
925 : __base_(_VSTD::move(__p))
926 { }
927
928 template <class _Alloc, class _Up1, class _Up2, template<class...> class _And = _And, _EnableIf<
929 _And<
930 _BoolConstant<sizeof...(_Tp) == 2>,
931 _EnableImplicitMoveFromPair<_Up1, _Up2, _Tp...>
932 >::value
933 , int> = 0>
934 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
935 tuple(allocator_arg_t, const _Alloc& __a, pair<_Up1, _Up2>&& __p)
936 : __base_(allocator_arg_t(), __a, _VSTD::move(__p))
937 { }
938
939 template <class _Alloc, class _Up1, class _Up2, template<class...> class _And = _And, _EnableIf<
940 _And<
941 _BoolConstant<sizeof...(_Tp) == 2>,
942 _EnableExplicitMoveFromPair<_Up1, _Up2, _Tp...>
943 >::value
944 , int> = 0>
945 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
946 explicit tuple(allocator_arg_t, const _Alloc& __a, pair<_Up1, _Up2>&& __p)
947 : __base_(allocator_arg_t(), __a, _VSTD::move(__p))
948 { }
949
950 // [tuple.assign]
951 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
952 tuple& operator=(_If<_And<is_copy_assignable<_Tp>...>::value, tuple, __nat> const& __tuple)
953 _NOEXCEPT_((_And<is_nothrow_copy_assignable<_Tp>...>::value))
954 {
955 _VSTD::__memberwise_copy_assign(*this, __tuple,
956 typename __make_tuple_indices<sizeof...(_Tp)>::type());
957 return *this;
958 }
885959
886 template <class _Tuple, _EnableExplicitTupleLikeConstructor<const _Tuple&, false> = false>
887 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
888 explicit
889 tuple(const _Tuple& __t) _NOEXCEPT_((is_nothrow_constructible<_BaseT, const _Tuple&>::value))
890 : __base_(__t) {}
960 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
961 tuple& operator=(_If<_And<is_move_assignable<_Tp>...>::value, tuple, __nat>&& __tuple)
962 _NOEXCEPT_((_And<is_nothrow_move_assignable<_Tp>...>::value))
963 {
964 _VSTD::__memberwise_forward_assign(*this, _VSTD::move(__tuple),
965 __tuple_types<_Tp...>(),
966 typename __make_tuple_indices<sizeof...(_Tp)>::type());
967 return *this;
968 }
891969
892 template <class _Alloc, class _Tuple,
893 typename enable_if
894 <
895 _CheckTupleLikeConstructor<
896 __tuple_like_with_size<_Tuple, sizeof...(_Tp)>::value
897 >::template __enable_implicit<_Tuple>(),
898 bool
899 >::type = false
900 >
901 _LIBCPP_INLINE_VISIBILITY
902 tuple(allocator_arg_t, const _Alloc& __a, _Tuple&& __t)
903 : __base_(allocator_arg_t(), __a, _VSTD::forward<_Tuple>(__t)) {}
970 template<class... _Up, _EnableIf<
971 _And<
972 _BoolConstant<sizeof...(_Tp) == sizeof...(_Up)>,
973 is_assignable<_Tp&, _Up const&>...
974 >::value
975 ,int> = 0>
976 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
977 tuple& operator=(tuple<_Up...> const& __tuple)
978 _NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up const&>...>::value))
979 {
980 _VSTD::__memberwise_copy_assign(*this, __tuple,
981 typename __make_tuple_indices<sizeof...(_Tp)>::type());
982 return *this;
983 }
904984
905 template <class _Alloc, class _Tuple,
906 typename enable_if
907 <
908 _CheckTupleLikeConstructor<
909 __tuple_like_with_size<_Tuple, sizeof...(_Tp)>::value
910 >::template __enable_explicit<_Tuple>(),
911 bool
912 >::type = false
913 >
914 _LIBCPP_INLINE_VISIBILITY
915 explicit
916 tuple(allocator_arg_t, const _Alloc& __a, _Tuple&& __t)
917 : __base_(allocator_arg_t(), __a, _VSTD::forward<_Tuple>(__t)) {}
985 template<class... _Up, _EnableIf<
986 _And<
987 _BoolConstant<sizeof...(_Tp) == sizeof...(_Up)>,
988 is_assignable<_Tp&, _Up>...
989 >::value
990 ,int> = 0>
991 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
992 tuple& operator=(tuple<_Up...>&& __tuple)
993 _NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up>...>::value))
994 {
995 _VSTD::__memberwise_forward_assign(*this, _VSTD::move(__tuple),
996 __tuple_types<_Up...>(),
997 typename __make_tuple_indices<sizeof...(_Tp)>::type());
998 return *this;
999 }
9181000
919 using _CanCopyAssign = __all<is_copy_assignable<_Tp>::value...>;
920 using _CanMoveAssign = __all<is_move_assignable<_Tp>::value...>;
1001 template<class _Up1, class _Up2, class _Dep = true_type, _EnableIf<
1002 _And<_Dep,
1003 _BoolConstant<sizeof...(_Tp) == 2>,
1004 is_assignable<_FirstType<_Tp..., _Dep>&, _Up1 const&>,
1005 is_assignable<_SecondType<_Tp..., _Dep>&, _Up2 const&>
1006 >::value
1007 ,int> = 0>
1008 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1009 tuple& operator=(pair<_Up1, _Up2> const& __pair)
1010 _NOEXCEPT_((_And<
1011 is_nothrow_assignable<_FirstType<_Tp...>&, _Up1 const&>,
1012 is_nothrow_assignable<_SecondType<_Tp...>&, _Up2 const&>
1013 >::value))
1014 {
1015 _VSTD::get<0>(*this) = __pair.first;
1016 _VSTD::get<1>(*this) = __pair.second;
1017 return *this;
1018 }
9211019
922 _LIBCPP_INLINE_VISIBILITY
923 tuple& operator=(typename conditional<_CanCopyAssign::value, tuple, __nat>::type const& __t)
924 _NOEXCEPT_((__all<is_nothrow_copy_assignable<_Tp>::value...>::value))
1020 template<class _Up1, class _Up2, class _Dep = true_type, _EnableIf<
1021 _And<_Dep,
1022 _BoolConstant<sizeof...(_Tp) == 2>,
1023 is_assignable<_FirstType<_Tp..., _Dep>&, _Up1>,
1024 is_assignable<_SecondType<_Tp..., _Dep>&, _Up2>
1025 >::value
1026 ,int> = 0>
1027 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1028 tuple& operator=(pair<_Up1, _Up2>&& __pair)
1029 _NOEXCEPT_((_And<
1030 is_nothrow_assignable<_FirstType<_Tp...>&, _Up1>,
1031 is_nothrow_assignable<_SecondType<_Tp...>&, _Up2>
1032 >::value))
9251033 {
926 __base_.operator=(__t.__base_);
1034 _VSTD::get<0>(*this) = _VSTD::forward<_Up1>(__pair.first);
1035 _VSTD::get<1>(*this) = _VSTD::forward<_Up2>(__pair.second);
9271036 return *this;
9281037 }
9291038
930 _LIBCPP_INLINE_VISIBILITY
931 tuple& operator=(typename conditional<_CanMoveAssign::value, tuple, __nat>::type&& __t)
932 _NOEXCEPT_((__all<is_nothrow_move_assignable<_Tp>::value...>::value))
1039 // EXTENSION
1040 template<class _Up, size_t _Np, class = _EnableIf<
1041 _And<
1042 _BoolConstant<_Np == sizeof...(_Tp)>,
1043 is_assignable<_Tp&, _Up const&>...
1044 >::value
1045 > >
1046 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1047 tuple& operator=(array<_Up, _Np> const& __array)
1048 _NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up const&>...>::value))
9331049 {
934 __base_.operator=(static_cast<_BaseT&&>(__t.__base_));
1050 _VSTD::__memberwise_copy_assign(*this, __array,
1051 typename __make_tuple_indices<sizeof...(_Tp)>::type());
9351052 return *this;
9361053 }
9371054
938 template <class _Tuple,
939 class = typename enable_if
940 <
941 __tuple_assignable<_Tuple, tuple>::value
942 >::type
943 >
944 _LIBCPP_INLINE_VISIBILITY
945 tuple&
946 operator=(_Tuple&& __t) _NOEXCEPT_((is_nothrow_assignable<_BaseT&, _Tuple>::value))
947 {
948 __base_.operator=(_VSTD::forward<_Tuple>(__t));
949 return *this;
950 }
1055 // EXTENSION
1056 template<class _Up, size_t _Np, class = void, class = _EnableIf<
1057 _And<
1058 _BoolConstant<_Np == sizeof...(_Tp)>,
1059 is_assignable<_Tp&, _Up>...
1060 >::value
1061 > >
1062 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1063 tuple& operator=(array<_Up, _Np>&& __array)
1064 _NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up>...>::value))
1065 {
1066 _VSTD::__memberwise_forward_assign(*this, _VSTD::move(__array),
1067 __tuple_types<_If<true, _Up, _Tp>...>(),
1068 typename __make_tuple_indices<sizeof...(_Tp)>::type());
1069 return *this;
1070 }
9511071
952 _LIBCPP_INLINE_VISIBILITY
1072 // [tuple.swap]
1073 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
9531074 void swap(tuple& __t) _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
9541075 {__base_.swap(__t.__base_);}
9551076};
......@@ -958,21 +1079,21 @@ template <>
9581079class _LIBCPP_TEMPLATE_VIS tuple<>
9591080{
9601081public:
961 _LIBCPP_INLINE_VISIBILITY
962 _LIBCPP_CONSTEXPR tuple() _NOEXCEPT = default;
1082 _LIBCPP_INLINE_VISIBILITY constexpr
1083 tuple() _NOEXCEPT = default;
9631084 template <class _Alloc>
964 _LIBCPP_INLINE_VISIBILITY
1085 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
9651086 tuple(allocator_arg_t, const _Alloc&) _NOEXCEPT {}
9661087 template <class _Alloc>
967 _LIBCPP_INLINE_VISIBILITY
1088 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
9681089 tuple(allocator_arg_t, const _Alloc&, const tuple&) _NOEXCEPT {}
9691090 template <class _Up>
970 _LIBCPP_INLINE_VISIBILITY
1091 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
9711092 tuple(array<_Up, 0>) _NOEXCEPT {}
9721093 template <class _Alloc, class _Up>
973 _LIBCPP_INLINE_VISIBILITY
1094 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
9741095 tuple(allocator_arg_t, const _Alloc&, array<_Up, 0>) _NOEXCEPT {}
975 _LIBCPP_INLINE_VISIBILITY
1096 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
9761097 void swap(tuple&) _NOEXCEPT {}
9771098};
9781099
......@@ -990,7 +1111,7 @@ tuple(allocator_arg_t, _Alloc, tuple<_Tp...>) -> tuple<_Tp...>;
9901111#endif
9911112
9921113template <class ..._Tp>
993inline _LIBCPP_INLINE_VISIBILITY
1114inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
9941115typename enable_if
9951116<
9961117 __all<__is_swappable<_Tp>::value...>::value,
......@@ -1044,7 +1165,7 @@ get(const tuple<_Tp...>&& __t) _NOEXCEPT
10441165
10451166namespace __find_detail {
10461167
1047static constexpr size_t __not_found = -1;
1168static constexpr size_t __not_found = static_cast<size_t>(-1);
10481169static constexpr size_t __ambiguous = __not_found - 1;
10491170
10501171inline _LIBCPP_INLINE_VISIBILITY
......@@ -1450,4 +1571,4 @@ _LIBCPP_NOEXCEPT_RETURN(
14501571
14511572_LIBCPP_END_NAMESPACE_STD
14521573
1453#endif // _LIBCPP_TUPLE
1574#endif // _LIBCPP_TUPLE
lib/libcxx/include/type_traits+372-176
......@@ -99,7 +99,7 @@ namespace std
9999 template <class T> struct is_trivial;
100100 template <class T> struct is_trivially_copyable;
101101 template <class T> struct is_standard_layout;
102 template <class T> struct is_literal_type;
102 template <class T> struct is_literal_type; // Deprecated in C++17; removed in C++20
103103 template <class T> struct is_empty;
104104 template <class T> struct is_polymorphic;
105105 template <class T> struct is_abstract;
......@@ -165,8 +165,8 @@ namespace std
165165 template <class T> struct decay;
166166 template <class... T> struct common_type;
167167 template <class T> struct underlying_type;
168 template <class> class result_of; // undefined
169 template <class Fn, class... ArgTypes> class result_of<Fn(ArgTypes...)>;
168 template <class> class result_of; // undefined; deprecated in C++17; removed in C++20
169 template <class Fn, class... ArgTypes> class result_of<Fn(ArgTypes...)>; // deprecated in C++17; removed in C++20
170170 template <class Fn, class... ArgTypes> struct invoke_result; // C++17
171171
172172 // const-volatile modifications:
......@@ -216,9 +216,9 @@ namespace std
216216 using add_pointer_t = typename add_pointer<T>::type; // C++14
217217
218218 // other transformations:
219 template <size_t Len, std::size_t Align=default-alignment>
219 template <size_t Len, size_t Align=default-alignment>
220220 using aligned_storage_t = typename aligned_storage<Len,Align>::type; // C++14
221 template <std::size_t Len, class... Types>
221 template <size_t Len, class... Types>
222222 using aligned_union_t = typename aligned_union<Len,Types...>::type; // C++14
223223 template <class T>
224224 using remove_cvref_t = typename remove_cvref<T>::type; // C++20
......@@ -233,7 +233,7 @@ namespace std
233233 template <class T>
234234 using underlying_type_t = typename underlying_type<T>::type; // C++14
235235 template <class T>
236 using result_of_t = typename result_of<T>::type; // C++14
236 using result_of_t = typename result_of<T>::type; // C++14; deprecated in C++17; removed in C++20
237237 template <class Fn, class... ArgTypes>
238238 using invoke_result_t = typename invoke_result<Fn, ArgTypes...>::type; // C++17
239239
......@@ -302,7 +302,7 @@ namespace std
302302 template <class T> inline constexpr bool is_pod_v
303303 = is_pod<T>::value; // C++17
304304 template <class T> inline constexpr bool is_literal_type_v
305 = is_literal_type<T>::value; // C++17
305 = is_literal_type<T>::value; // C++17; deprecated in C++17; removed in C++20
306306 template <class T> inline constexpr bool is_empty_v
307307 = is_empty<T>::value; // C++17
308308 template <class T> inline constexpr bool is_polymorphic_v
......@@ -476,8 +476,6 @@ struct _MetaBase<true> {
476476 using _EnableIfImpl _LIBCPP_NODEBUG_TYPE = _Tp;
477477 template <class _Result, class _First, class ..._Rest>
478478 using _OrImpl _LIBCPP_NODEBUG_TYPE = typename _MetaBase<_First::value != true && sizeof...(_Rest) != 0>::template _OrImpl<_First, _Rest...>;
479 template <class _Result, class _First, class ..._Rest>
480 using _AndImpl _LIBCPP_NODEBUG_TYPE = typename _MetaBase<_First::value == true && sizeof...(_Rest) != 0>::template _AndImpl<_First, _Rest...>;
481479};
482480
483481template <>
......@@ -488,8 +486,6 @@ struct _MetaBase<false> {
488486 using _SelectApplyImpl _LIBCPP_NODEBUG_TYPE = _SecondFn<_Args...>;
489487 template <class _Result, class ...>
490488 using _OrImpl _LIBCPP_NODEBUG_TYPE = _Result;
491 template <class _Result, class ...>
492 using _AndImpl _LIBCPP_NODEBUG_TYPE = _Result;
493489};
494490template <bool _Cond, class _Ret = void>
495491using _EnableIf _LIBCPP_NODEBUG_TYPE = typename _MetaBase<_Cond>::template _EnableIfImpl<_Ret>;
......@@ -497,8 +493,6 @@ template <bool _Cond, class _IfRes, class _ElseRes>
497493using _If _LIBCPP_NODEBUG_TYPE = typename _MetaBase<_Cond>::template _SelectImpl<_IfRes, _ElseRes>;
498494template <class ..._Rest>
499495using _Or _LIBCPP_NODEBUG_TYPE = typename _MetaBase< sizeof...(_Rest) != 0 >::template _OrImpl<false_type, _Rest...>;
500template <class ..._Rest>
501using _And _LIBCPP_NODEBUG_TYPE = typename _MetaBase< sizeof...(_Rest) != 0 >::template _AndImpl<true_type, _Rest...>;
502496template <class _Pred>
503497struct _Not : _BoolConstant<!_Pred::value> {};
504498template <class ..._Args>
......@@ -506,6 +500,14 @@ using _FirstType _LIBCPP_NODEBUG_TYPE = typename _MetaBase<(sizeof...(_Args) >=
506500template <class ..._Args>
507501using _SecondType _LIBCPP_NODEBUG_TYPE = typename _MetaBase<(sizeof...(_Args) >= 2)>::template _SecondImpl<_Args...>;
508502
503template <class ...> using __expand_to_true = true_type;
504template <class ..._Pred>
505__expand_to_true<_EnableIf<_Pred::value>...> __and_helper(int);
506template <class ...>
507false_type __and_helper(...);
508template <class ..._Pred>
509using _And _LIBCPP_NODEBUG_TYPE = decltype(__and_helper<_Pred...>(0));
510
509511template <template <class...> class _Func, class ..._Args>
510512struct _Lazy : _Func<_Args...> {};
511513
......@@ -525,6 +527,9 @@ struct __void_t { typedef void type; };
525527template <class _Tp>
526528struct __identity { typedef _Tp type; };
527529
530template <class _Tp>
531using __identity_t _LIBCPP_NODEBUG_TYPE = typename __identity<_Tp>::type;
532
528533template <class _Tp, bool>
529534struct _LIBCPP_TEMPLATE_VIS __dependent_type : public _Tp {};
530535
......@@ -575,7 +580,7 @@ using _IsSame = _BoolConstant<
575580#ifdef __clang__
576581 __is_same(_Tp, _Up)
577582#else
578 _VSTD::is_same<_Tp, _Up>::value
583 is_same<_Tp, _Up>::value
579584#endif
580585>;
581586
......@@ -584,7 +589,7 @@ using _IsNotSame = _BoolConstant<
584589#ifdef __clang__
585590 !__is_same(_Tp, _Up)
586591#else
587 !_VSTD::is_same<_Tp, _Up>::value
592 !is_same<_Tp, _Up>::value
588593#endif
589594>;
590595
......@@ -784,6 +789,33 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_integral_v
784789
785790#endif // __has_keyword(__is_integral)
786791
792// __libcpp_is_signed_integer, __libcpp_is_unsigned_integer
793
794// [basic.fundamental] defines five standard signed integer types;
795// __int128_t is an extended signed integer type.
796// The signed and unsigned integer types, plus bool and the
797// five types with "char" in their name, compose the "integral" types.
798
799template <class _Tp> struct __libcpp_is_signed_integer : public false_type {};
800template <> struct __libcpp_is_signed_integer<signed char> : public true_type {};
801template <> struct __libcpp_is_signed_integer<signed short> : public true_type {};
802template <> struct __libcpp_is_signed_integer<signed int> : public true_type {};
803template <> struct __libcpp_is_signed_integer<signed long> : public true_type {};
804template <> struct __libcpp_is_signed_integer<signed long long> : public true_type {};
805#ifndef _LIBCPP_HAS_NO_INT128
806template <> struct __libcpp_is_signed_integer<__int128_t> : public true_type {};
807#endif
808
809template <class _Tp> struct __libcpp_is_unsigned_integer : public false_type {};
810template <> struct __libcpp_is_unsigned_integer<unsigned char> : public true_type {};
811template <> struct __libcpp_is_unsigned_integer<unsigned short> : public true_type {};
812template <> struct __libcpp_is_unsigned_integer<unsigned int> : public true_type {};
813template <> struct __libcpp_is_unsigned_integer<unsigned long> : public true_type {};
814template <> struct __libcpp_is_unsigned_integer<unsigned long long> : public true_type {};
815#ifndef _LIBCPP_HAS_NO_INT128
816template <> struct __libcpp_is_unsigned_integer<__uint128_t> : public true_type {};
817#endif
818
787819// is_floating_point
788820
789821template <class _Tp> struct __libcpp_is_floating_point : public false_type {};
......@@ -831,8 +863,10 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_array_v
831863
832864// is_pointer
833865
834// In clang 10.0.0 and earlier __is_pointer didn't work with Objective-C types.
835#if __has_keyword(__is_pointer) && _LIBCPP_CLANG_VER > 1000
866// Before Clang 11 / AppleClang 12.0.5, __is_pointer didn't work for Objective-C types.
867#if __has_keyword(__is_pointer) && \
868 !(defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER < 1100) && \
869 !(defined(_LIBCPP_APPLE_CLANG_VER) && _LIBCPP_APPLE_CLANG_VER < 1205)
836870
837871template<class _Tp>
838872struct _LIBCPP_TEMPLATE_VIS is_pointer : _BoolConstant<__is_pointer(_Tp)> { };
......@@ -1126,9 +1160,11 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_arithmetic_v
11261160
11271161// is_fundamental
11281162
1129// In clang 9 and lower, this builtin did not work for nullptr_t. Additionally, in C++03 mode,
1130// nullptr isn't defined by the compiler so, this builtin won't work.
1131#if __has_keyword(__is_fundamental) && _LIBCPP_CLANG_VER > 900 && !defined(_LIBCPP_CXX03_LANG)
1163// Before Clang 10, __is_fundamental didn't work for nullptr_t.
1164// In C++03 nullptr_t is library-provided but must still count as "fundamental."
1165#if __has_keyword(__is_fundamental) && \
1166 !(defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER < 1000) && \
1167 !defined(_LIBCPP_CXX03_LANG)
11321168
11331169template<class _Tp>
11341170struct _LIBCPP_TEMPLATE_VIS is_fundamental : _BoolConstant<__is_fundamental(_Tp)> { };
......@@ -1155,7 +1191,7 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_fundamental_v
11551191
11561192// is_scalar
11571193
1158// >= 11 because in C++03 nullptr isn't actually nullptr
1194// In C++03 nullptr_t is library-provided but must still count as "scalar."
11591195#if __has_keyword(__is_scalar) && !defined(_LIBCPP_CXX03_LANG)
11601196
11611197template<class _Tp>
......@@ -1335,7 +1371,7 @@ template <class _Tp> _Tp __declval(long);
13351371_LIBCPP_SUPPRESS_DEPRECATED_POP
13361372
13371373template <class _Tp>
1338decltype(_VSTD::__declval<_Tp>(0))
1374decltype(__declval<_Tp>(0))
13391375declval() _NOEXCEPT;
13401376
13411377// __uncvref
......@@ -1412,8 +1448,9 @@ template<class _Tp> using type_identity_t = typename type_identity<_Tp>::type;
14121448
14131449// is_signed
14141450
1415// In clang 9 and earlier, this builtin did not work for floating points or enums
1416#if __has_keyword(__is_signed) && _LIBCPP_CLANG_VER > 900
1451// Before Clang 10, __is_signed didn't work for floating-point types or enums.
1452#if __has_keyword(__is_signed) && \
1453 !(defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER < 1000)
14171454
14181455template<class _Tp>
14191456struct _LIBCPP_TEMPLATE_VIS is_signed : _BoolConstant<__is_signed(_Tp)> { };
......@@ -1448,7 +1485,11 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_signed_v
14481485
14491486// is_unsigned
14501487
1451#if __has_keyword(__is_unsigned)
1488// Before Clang 13, __is_unsigned returned true for enums with signed underlying type.
1489// No currently-released version of AppleClang contains the fixed intrinsic.
1490#if __has_keyword(__is_unsigned) && \
1491 !(defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER < 1300) && \
1492 !defined(_LIBCPP_APPLE_CLANG_VER)
14521493
14531494template<class _Tp>
14541495struct _LIBCPP_TEMPLATE_VIS is_unsigned : _BoolConstant<__is_unsigned(_Tp)> { };
......@@ -1698,7 +1739,7 @@ struct __is_convertible_test : public false_type {};
16981739
16991740template <class _From, class _To>
17001741struct __is_convertible_test<_From, _To,
1701 decltype(_VSTD::__is_convertible_imp::__test_convert<_To>(_VSTD::declval<_From>()))> : public true_type
1742 decltype(__is_convertible_imp::__test_convert<_To>(declval<_From>()))> : public true_type
17021743{};
17031744
17041745template <class _Tp, bool _IsArray = is_array<_Tp>::value,
......@@ -1754,7 +1795,7 @@ template <class _T1, class _T2> struct _LIBCPP_TEMPLATE_VIS is_convertible
17541795 static const size_t __complete_check2 = __is_convertible_check<_T2>::__v;
17551796};
17561797
1757#endif // __has_feature(is_convertible_to)
1798#endif // __has_feature(is_convertible_to)
17581799
17591800#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
17601801template <class _From, class _To>
......@@ -1817,7 +1858,7 @@ template <class _Tp> struct __libcpp_empty<_Tp, false> : public false_type {};
18171858
18181859template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_empty : public __libcpp_empty<_Tp> {};
18191860
1820#endif // __has_feature(is_empty)
1861#endif // __has_feature(is_empty)
18211862
18221863#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
18231864template <class _Tp>
......@@ -2297,6 +2338,14 @@ struct _LIBCPP_TEMPLATE_VIS make_unsigned
22972338template <class _Tp> using make_unsigned_t = typename make_unsigned<_Tp>::type;
22982339#endif
22992340
2341#ifndef _LIBCPP_CXX03_LANG
2342template <class _Tp>
2343_LIBCPP_NODISCARD_ATTRIBUTE _LIBCPP_INLINE_VISIBILITY constexpr
2344typename make_unsigned<_Tp>::type __to_unsigned_like(_Tp __x) noexcept {
2345 return static_cast<typename make_unsigned<_Tp>::type>(__x);
2346}
2347#endif
2348
23002349#if _LIBCPP_STD_VER > 14
23012350template <class...> using void_t = void;
23022351#endif
......@@ -2304,7 +2353,7 @@ template <class...> using void_t = void;
23042353#if _LIBCPP_STD_VER > 17
23052354// Let COND_RES(X, Y) be:
23062355template <class _Tp, class _Up>
2307using __cond_type = decltype(false ? _VSTD::declval<_Tp>() : _VSTD::declval<_Up>());
2356using __cond_type = decltype(false ? declval<_Tp>() : declval<_Up>());
23082357
23092358template <class _Tp, class _Up, class = void>
23102359struct __common_type3 {};
......@@ -2327,11 +2376,11 @@ struct __common_type2_imp {};
23272376template <class _Tp, class _Up>
23282377struct __common_type2_imp<_Tp, _Up,
23292378 typename __void_t<decltype(
2330 true ? _VSTD::declval<_Tp>() : _VSTD::declval<_Up>()
2379 true ? declval<_Tp>() : declval<_Up>()
23312380 )>::type>
23322381{
23332382 typedef _LIBCPP_NODEBUG_TYPE typename decay<decltype(
2334 true ? _VSTD::declval<_Tp>() : _VSTD::declval<_Up>()
2383 true ? declval<_Tp>() : declval<_Up>()
23352384 )>::type type;
23362385};
23372386
......@@ -2411,6 +2460,216 @@ struct _LIBCPP_TEMPLATE_VIS
24112460template <class ..._Tp> using common_type_t = typename common_type<_Tp...>::type;
24122461#endif
24132462
2463#if _LIBCPP_STD_VER > 11
2464// Let COPYCV(FROM, TO) be an alias for type TO with the addition of FROM's
2465// top-level cv-qualifiers.
2466template <class _From, class _To>
2467struct __copy_cv
2468{
2469 using type = _To;
2470};
2471
2472template <class _From, class _To>
2473struct __copy_cv<const _From, _To>
2474{
2475 using type = add_const_t<_To>;
2476};
2477
2478template <class _From, class _To>
2479struct __copy_cv<volatile _From, _To>
2480{
2481 using type = add_volatile_t<_To>;
2482};
2483
2484template <class _From, class _To>
2485struct __copy_cv<const volatile _From, _To>
2486{
2487 using type = add_cv_t<_To>;
2488};
2489
2490template <class _From, class _To>
2491using __copy_cv_t = typename __copy_cv<_From, _To>::type;
2492
2493template <class _From, class _To>
2494struct __copy_cvref
2495{
2496 using type = __copy_cv_t<_From, _To>;
2497};
2498
2499template <class _From, class _To>
2500struct __copy_cvref<_From&, _To>
2501{
2502 using type = add_lvalue_reference_t<__copy_cv_t<_From, _To>>;
2503};
2504
2505template <class _From, class _To>
2506struct __copy_cvref<_From&&, _To>
2507{
2508 using type = add_rvalue_reference_t<__copy_cv_t<_From, _To>>;
2509};
2510
2511template <class _From, class _To>
2512using __copy_cvref_t = typename __copy_cvref<_From, _To>::type;
2513
2514#endif // _LIBCPP_STD_VER > 11
2515
2516// common_reference
2517#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
2518// Let COND_RES(X, Y) be:
2519template <class _Xp, class _Yp>
2520using __cond_res =
2521 decltype(false ? declval<_Xp(&)()>()() : declval<_Yp(&)()>()());
2522
2523// Let `XREF(A)` denote a unary alias template `T` such that `T<U>` denotes the same type as `U`
2524// with the addition of `A`'s cv and reference qualifiers, for a non-reference cv-unqualified type
2525// `U`.
2526// [Note: `XREF(A)` is `__xref<A>::template __apply`]
2527template <class _Tp>
2528struct __xref {
2529 template<class _Up>
2530 using __apply = __copy_cvref_t<_Tp, _Up>;
2531};
2532
2533// Given types A and B, let X be remove_reference_t<A>, let Y be remove_reference_t<B>,
2534// and let COMMON-REF(A, B) be:
2535template<class _Ap, class _Bp, class _Xp = remove_reference_t<_Ap>, class _Yp = remove_reference_t<_Bp>>
2536struct __common_ref;
2537
2538template<class _Xp, class _Yp>
2539using __common_ref_t = typename __common_ref<_Xp, _Yp>::__type;
2540
2541template<class _Xp, class _Yp>
2542using __cv_cond_res = __cond_res<__copy_cv_t<_Xp, _Yp>&, __copy_cv_t<_Yp, _Xp>&>;
2543
2544
2545// If A and B are both lvalue reference types, COMMON-REF(A, B) is
2546// COND-RES(COPYCV(X, Y)&, COPYCV(Y, X)&) if that type exists and is a reference type.
2547template<class _Ap, class _Bp, class _Xp, class _Yp>
2548requires requires { typename __cv_cond_res<_Xp, _Yp>; } && is_reference_v<__cv_cond_res<_Xp, _Yp>>
2549struct __common_ref<_Ap&, _Bp&, _Xp, _Yp>
2550{
2551 using __type = __cv_cond_res<_Xp, _Yp>;
2552};
2553
2554// Otherwise, let C be remove_reference_t<COMMON-REF(X&, Y&)>&&. ...
2555template <class _Xp, class _Yp>
2556using __common_ref_C = remove_reference_t<__common_ref_t<_Xp&, _Yp&>>&&;
2557
2558
2559// .... If A and B are both rvalue reference types, C is well-formed, and
2560// is_convertible_v<A, C> && is_convertible_v<B, C> is true, then COMMON-REF(A, B) is C.
2561template<class _Ap, class _Bp, class _Xp, class _Yp>
2562requires
2563 requires { typename __common_ref_C<_Xp, _Yp>; } &&
2564 is_convertible_v<_Ap&&, __common_ref_C<_Xp, _Yp>> &&
2565 is_convertible_v<_Bp&&, __common_ref_C<_Xp, _Yp>>
2566struct __common_ref<_Ap&&, _Bp&&, _Xp, _Yp>
2567{
2568 using __type = __common_ref_C<_Xp, _Yp>;
2569};
2570
2571// Otherwise, let D be COMMON-REF(const X&, Y&). ...
2572template <class _Tp, class _Up>
2573using __common_ref_D = __common_ref_t<const _Tp&, _Up&>;
2574
2575// ... If A is an rvalue reference and B is an lvalue reference and D is well-formed and
2576// is_convertible_v<A, D> is true, then COMMON-REF(A, B) is D.
2577template<class _Ap, class _Bp, class _Xp, class _Yp>
2578requires requires { typename __common_ref_D<_Xp, _Yp>; } &&
2579 is_convertible_v<_Ap&&, __common_ref_D<_Xp, _Yp>>
2580struct __common_ref<_Ap&&, _Bp&, _Xp, _Yp>
2581{
2582 using __type = __common_ref_D<_Xp, _Yp>;
2583};
2584
2585// Otherwise, if A is an lvalue reference and B is an rvalue reference, then
2586// COMMON-REF(A, B) is COMMON-REF(B, A).
2587template<class _Ap, class _Bp, class _Xp, class _Yp>
2588struct __common_ref<_Ap&, _Bp&&, _Xp, _Yp> : __common_ref<_Bp&&, _Ap&> {};
2589
2590// Otherwise, COMMON-REF(A, B) is ill-formed.
2591template<class _Ap, class _Bp, class _Xp, class _Yp>
2592struct __common_ref {};
2593
2594// Note C: For the common_reference trait applied to a parameter pack [...]
2595
2596template <class...>
2597struct common_reference;
2598
2599template <class... _Types>
2600using common_reference_t = typename common_reference<_Types...>::type;
2601
2602// bullet 1 - sizeof...(T) == 0
2603template<>
2604struct common_reference<> {};
2605
2606// bullet 2 - sizeof...(T) == 1
2607template <class _Tp>
2608struct common_reference<_Tp>
2609{
2610 using type = _Tp;
2611};
2612
2613// bullet 3 - sizeof...(T) == 2
2614template <class _Tp, class _Up> struct __common_reference_sub_bullet3;
2615template <class _Tp, class _Up> struct __common_reference_sub_bullet2 : __common_reference_sub_bullet3<_Tp, _Up> {};
2616template <class _Tp, class _Up> struct __common_reference_sub_bullet1 : __common_reference_sub_bullet2<_Tp, _Up> {};
2617
2618// sub-bullet 1 - If T1 and T2 are reference types and COMMON-REF(T1, T2) is well-formed, then
2619// the member typedef `type` denotes that type.
2620template <class _Tp, class _Up> struct common_reference<_Tp, _Up> : __common_reference_sub_bullet1<_Tp, _Up> {};
2621
2622template <class _Tp, class _Up>
2623requires is_reference_v<_Tp> && is_reference_v<_Up> && requires { typename __common_ref_t<_Tp, _Up>; }
2624struct __common_reference_sub_bullet1<_Tp, _Up>
2625{
2626 using type = __common_ref_t<_Tp, _Up>;
2627};
2628
2629// sub-bullet 2 - Otherwise, if basic_common_reference<remove_cvref_t<T1>, remove_cvref_t<T2>, XREF(T1), XREF(T2)>::type
2630// is well-formed, then the member typedef `type` denotes that type.
2631template <class, class, template <class> class, template <class> class> struct basic_common_reference {};
2632
2633template <class _Tp, class _Up>
2634using __basic_common_reference_t = typename basic_common_reference<
2635 remove_cvref_t<_Tp>, remove_cvref_t<_Up>,
2636 __xref<_Tp>::template __apply, __xref<_Up>::template __apply>::type;
2637
2638template <class _Tp, class _Up>
2639requires requires { typename __basic_common_reference_t<_Tp, _Up>; }
2640struct __common_reference_sub_bullet2<_Tp, _Up>
2641{
2642 using type = __basic_common_reference_t<_Tp, _Up>;
2643};
2644
2645// sub-bullet 3 - Otherwise, if COND-RES(T1, T2) is well-formed,
2646// then the member typedef `type` denotes that type.
2647template <class _Tp, class _Up>
2648requires requires { typename __cond_res<_Tp, _Up>; }
2649struct __common_reference_sub_bullet3<_Tp, _Up>
2650{
2651 using type = __cond_res<_Tp, _Up>;
2652};
2653
2654
2655// sub-bullet 4 & 5 - Otherwise, if common_type_t<T1, T2> is well-formed,
2656// then the member typedef `type` denotes that type.
2657// - Otherwise, there shall be no member `type`.
2658template <class _Tp, class _Up> struct __common_reference_sub_bullet3 : common_type<_Tp, _Up> {};
2659
2660// bullet 4 - If there is such a type `C`, the member typedef type shall denote the same type, if
2661// any, as `common_reference_t<C, Rest...>`.
2662template <class _Tp, class _Up, class _Vp, class... _Rest>
2663requires requires { typename common_reference_t<_Tp, _Up>; }
2664struct common_reference<_Tp, _Up, _Vp, _Rest...>
2665 : common_reference<common_reference_t<_Tp, _Up>, _Vp, _Rest...>
2666{};
2667
2668// bullet 5 - Otherwise, there shall be no member `type`.
2669template <class...> struct common_reference {};
2670
2671#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
2672
24142673// is_assignable
24152674
24162675template<typename, typename _Tp> struct __select_2nd { typedef _LIBCPP_NODEBUG_TYPE _Tp type; };
......@@ -2428,7 +2687,7 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_assignable_v = __is_assignable(_Tp,
24282687#else // __has_keyword(__is_assignable)
24292688
24302689template <class _Tp, class _Arg>
2431typename __select_2nd<decltype((_VSTD::declval<_Tp>() = _VSTD::declval<_Arg>())), true_type>::type
2690typename __select_2nd<decltype((declval<_Tp>() = declval<_Arg>())), true_type>::type
24322691__is_assignable_test(int);
24332692
24342693template <class, class>
......@@ -2455,7 +2714,7 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_assignable_v
24552714 = is_assignable<_Tp, _Arg>::value;
24562715#endif
24572716
2458#endif // __has_keyword(__is_assignable)
2717#endif // __has_keyword(__is_assignable)
24592718
24602719// is_copy_assignable
24612720
......@@ -2509,7 +2768,7 @@ template <typename _Tp>
25092768struct __is_destructor_wellformed {
25102769 template <typename _Tp1>
25112770 static char __test (
2512 typename __is_destructible_apply<decltype(_VSTD::declval<_Tp1&>().~_Tp1())>::type
2771 typename __is_destructible_apply<decltype(declval<_Tp1&>().~_Tp1())>::type
25132772 );
25142773
25152774 template <typename _Tp1>
......@@ -2523,33 +2782,33 @@ struct __destructible_imp;
25232782
25242783template <class _Tp>
25252784struct __destructible_imp<_Tp, false>
2526 : public _VSTD::integral_constant<bool,
2527 __is_destructor_wellformed<typename _VSTD::remove_all_extents<_Tp>::type>::value> {};
2785 : public integral_constant<bool,
2786 __is_destructor_wellformed<typename remove_all_extents<_Tp>::type>::value> {};
25282787
25292788template <class _Tp>
25302789struct __destructible_imp<_Tp, true>
2531 : public _VSTD::true_type {};
2790 : public true_type {};
25322791
25332792template <class _Tp, bool>
25342793struct __destructible_false;
25352794
25362795template <class _Tp>
2537struct __destructible_false<_Tp, false> : public __destructible_imp<_Tp, _VSTD::is_reference<_Tp>::value> {};
2796struct __destructible_false<_Tp, false> : public __destructible_imp<_Tp, is_reference<_Tp>::value> {};
25382797
25392798template <class _Tp>
2540struct __destructible_false<_Tp, true> : public _VSTD::false_type {};
2799struct __destructible_false<_Tp, true> : public false_type {};
25412800
25422801template <class _Tp>
25432802struct is_destructible
2544 : public __destructible_false<_Tp, _VSTD::is_function<_Tp>::value> {};
2803 : public __destructible_false<_Tp, is_function<_Tp>::value> {};
25452804
25462805template <class _Tp>
25472806struct is_destructible<_Tp[]>
2548 : public _VSTD::false_type {};
2807 : public false_type {};
25492808
25502809template <>
25512810struct is_destructible<void>
2552 : public _VSTD::false_type {};
2811 : public false_type {};
25532812
25542813#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
25552814template <class _Tp>
......@@ -2559,43 +2818,6 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_destructible_v
25592818
25602819#endif // __has_keyword(__is_destructible)
25612820
2562// move
2563
2564template <class _Tp>
2565inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
2566typename remove_reference<_Tp>::type&&
2567move(_Tp&& __t) _NOEXCEPT
2568{
2569 typedef _LIBCPP_NODEBUG_TYPE typename remove_reference<_Tp>::type _Up;
2570 return static_cast<_Up&&>(__t);
2571}
2572
2573template <class _Tp>
2574inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
2575_Tp&&
2576forward(typename remove_reference<_Tp>::type& __t) _NOEXCEPT
2577{
2578 return static_cast<_Tp&&>(__t);
2579}
2580
2581template <class _Tp>
2582inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
2583_Tp&&
2584forward(typename remove_reference<_Tp>::type&& __t) _NOEXCEPT
2585{
2586 static_assert(!is_lvalue_reference<_Tp>::value,
2587 "can not forward an rvalue as an lvalue");
2588 return static_cast<_Tp&&>(__t);
2589}
2590
2591template <class _Tp>
2592inline _LIBCPP_INLINE_VISIBILITY
2593typename decay<_Tp>::type
2594__decay_copy(_Tp&& __t)
2595{
2596 return _VSTD::forward<_Tp>(__t);
2597}
2598
25992821template <class _MP, bool _IsMemberFunctionPtr, bool _IsMemberObjectPtr>
26002822struct __member_pointer_traits_imp
26012823{
......@@ -2795,7 +3017,7 @@ struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const volatil
27953017 typedef _Rp (_FnType) (_Param..., ...);
27963018};
27973019
2798#endif // __has_feature(cxx_reference_qualified_functions) || defined(_LIBCPP_COMPILER_GCC)
3020#endif // __has_feature(cxx_reference_qualified_functions) || defined(_LIBCPP_COMPILER_GCC)
27993021
28003022
28013023template <class _Rp, class _Class>
......@@ -2876,11 +3098,11 @@ struct __is_constructible_helper
28763098 // NOTE: The static_cast implementation below is required to support
28773099 // classes with explicit conversion operators.
28783100 template <class _To, class _From,
2879 class = decltype(__eat<_To>(_VSTD::declval<_From>()))>
3101 class = decltype(__eat<_To>(declval<_From>()))>
28803102 static true_type __test_cast(int);
28813103
28823104 template <class _To, class _From,
2883 class = decltype(static_cast<_To>(_VSTD::declval<_From>()))>
3105 class = decltype(static_cast<_To>(declval<_From>()))>
28843106 static integral_constant<bool,
28853107 !__is_invalid_base_to_derived_cast<_To, _From>::value &&
28863108 !__is_invalid_lvalue_to_rvalue_cast<_To, _From>::value
......@@ -2890,12 +3112,12 @@ struct __is_constructible_helper
28903112 static false_type __test_cast(...);
28913113
28923114 template <class _Tp, class ..._Args,
2893 class = decltype(_Tp(_VSTD::declval<_Args>()...))>
3115 class = decltype(_Tp(declval<_Args>()...))>
28943116 static true_type __test_nary(int);
28953117 template <class _Tp, class...>
28963118 static false_type __test_nary(...);
28973119
2898 template <class _Tp, class _A0, class = decltype(::new _Tp(_VSTD::declval<_A0>()))>
3120 template <class _Tp, class _A0, class = decltype(::new _Tp(declval<_A0>()))>
28993121 static is_destructible<_Tp> __test_unary(int);
29003122 template <class, class>
29013123 static false_type __test_unary(...);
......@@ -2984,18 +3206,18 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_default_constructible_v
29843206template <class _Tp>
29853207void __test_implicit_default_constructible(_Tp);
29863208
2987template <class _Tp, class = void, bool = is_default_constructible<_Tp>::value>
3209template <class _Tp, class = void, class = typename is_default_constructible<_Tp>::type>
29883210struct __is_implicitly_default_constructible
29893211 : false_type
29903212{ };
29913213
29923214template <class _Tp>
2993struct __is_implicitly_default_constructible<_Tp, decltype(__test_implicit_default_constructible<_Tp const&>({})), true>
3215struct __is_implicitly_default_constructible<_Tp, decltype(__test_implicit_default_constructible<_Tp const&>({})), true_type>
29943216 : true_type
29953217{ };
29963218
29973219template <class _Tp>
2998struct __is_implicitly_default_constructible<_Tp, decltype(__test_implicit_default_constructible<_Tp const&>({})), false>
3220struct __is_implicitly_default_constructible<_Tp, decltype(__test_implicit_default_constructible<_Tp const&>({})), false_type>
29993221 : false_type
30003222{ };
30013223#endif // !C++03
......@@ -3072,7 +3294,7 @@ struct _LIBCPP_TEMPLATE_VIS is_trivially_constructible<_Tp, _Tp&>
30723294{
30733295};
30743296
3075#endif // !__has_feature(is_trivially_constructible)
3297#endif // !__has_feature(is_trivially_constructible)
30763298
30773299
30783300#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
......@@ -3149,7 +3371,7 @@ template <class _Tp>
31493371struct is_trivially_assignable<_Tp&, _Tp&&>
31503372 : integral_constant<bool, is_scalar<_Tp>::value> {};
31513373
3152#endif // !__has_feature(is_trivially_assignable)
3374#endif // !__has_feature(is_trivially_assignable)
31533375
31543376#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
31553377template <class _Tp, class _Arg>
......@@ -3259,7 +3481,7 @@ struct _LIBCPP_TEMPLATE_VIS is_nothrow_constructible<_Tp[_Ns]>
32593481{
32603482};
32613483
3262#endif // _LIBCPP_HAS_NO_NOEXCEPT
3484#endif // _LIBCPP_HAS_NO_NOEXCEPT
32633485
32643486
32653487#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
......@@ -3324,7 +3546,7 @@ struct __libcpp_is_nothrow_assignable<false, _Tp, _Arg>
33243546
33253547template <class _Tp, class _Arg>
33263548struct __libcpp_is_nothrow_assignable<true, _Tp, _Arg>
3327 : public integral_constant<bool, noexcept(_VSTD::declval<_Tp>() = _VSTD::declval<_Arg>()) >
3549 : public integral_constant<bool, noexcept(declval<_Tp>() = declval<_Arg>()) >
33283550{
33293551};
33303552
......@@ -3334,7 +3556,7 @@ struct _LIBCPP_TEMPLATE_VIS is_nothrow_assignable
33343556{
33353557};
33363558
3337#endif // _LIBCPP_HAS_NO_NOEXCEPT
3559#endif // _LIBCPP_HAS_NO_NOEXCEPT
33383560
33393561#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
33403562template <class _Tp, class _Arg>
......@@ -3381,7 +3603,7 @@ struct __libcpp_is_nothrow_destructible<false, _Tp>
33813603
33823604template <class _Tp>
33833605struct __libcpp_is_nothrow_destructible<true, _Tp>
3384 : public integral_constant<bool, noexcept(_VSTD::declval<_Tp>().~_Tp()) >
3606 : public integral_constant<bool, noexcept(declval<_Tp>().~_Tp()) >
33853607{
33863608};
33873609
......@@ -3455,15 +3677,17 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_pod_v
34553677
34563678// is_literal_type;
34573679
3458template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_literal_type
3680#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS)
3681template <class _Tp> struct _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 is_literal_type
34593682 : public integral_constant<bool, __is_literal_type(_Tp)>
34603683 {};
34613684
34623685#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
34633686template <class _Tp>
3464_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_literal_type_v
3687_LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_literal_type_v
34653688 = is_literal_type<_Tp>::value;
3466#endif
3689#endif // _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
3690#endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS)
34673691
34683692// is_standard_layout;
34693693
......@@ -3604,42 +3828,42 @@ template <class _Fp, class _A0, class ..._Args,
36043828inline _LIBCPP_INLINE_VISIBILITY
36053829_LIBCPP_CONSTEXPR_AFTER_CXX17 auto
36063830__invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args)
3607_LIBCPP_INVOKE_RETURN((_VSTD::forward<_A0>(__a0).*__f)(_VSTD::forward<_Args>(__args)...))
3831_LIBCPP_INVOKE_RETURN((static_cast<_A0&&>(__a0).*__f)(static_cast<_Args&&>(__args)...))
36083832
36093833template <class _Fp, class _A0, class ..._Args,
36103834 class = __enable_if_bullet1<_Fp, _A0>>
36113835inline _LIBCPP_INLINE_VISIBILITY
36123836_LIBCPP_CONSTEXPR auto
36133837__invoke_constexpr(_Fp&& __f, _A0&& __a0, _Args&& ...__args)
3614_LIBCPP_INVOKE_RETURN((_VSTD::forward<_A0>(__a0).*__f)(_VSTD::forward<_Args>(__args)...))
3838_LIBCPP_INVOKE_RETURN((static_cast<_A0&&>(__a0).*__f)(static_cast<_Args&&>(__args)...))
36153839
36163840template <class _Fp, class _A0, class ..._Args,
36173841 class = __enable_if_bullet2<_Fp, _A0>>
36183842inline _LIBCPP_INLINE_VISIBILITY
36193843_LIBCPP_CONSTEXPR_AFTER_CXX17 auto
36203844__invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args)
3621_LIBCPP_INVOKE_RETURN((__a0.get().*__f)(_VSTD::forward<_Args>(__args)...))
3845_LIBCPP_INVOKE_RETURN((__a0.get().*__f)(static_cast<_Args&&>(__args)...))
36223846
36233847template <class _Fp, class _A0, class ..._Args,
36243848 class = __enable_if_bullet2<_Fp, _A0>>
36253849inline _LIBCPP_INLINE_VISIBILITY
36263850_LIBCPP_CONSTEXPR auto
36273851__invoke_constexpr(_Fp&& __f, _A0&& __a0, _Args&& ...__args)
3628_LIBCPP_INVOKE_RETURN((__a0.get().*__f)(_VSTD::forward<_Args>(__args)...))
3852_LIBCPP_INVOKE_RETURN((__a0.get().*__f)(static_cast<_Args&&>(__args)...))
36293853
36303854template <class _Fp, class _A0, class ..._Args,
36313855 class = __enable_if_bullet3<_Fp, _A0>>
36323856inline _LIBCPP_INLINE_VISIBILITY
36333857_LIBCPP_CONSTEXPR_AFTER_CXX17 auto
36343858__invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args)
3635_LIBCPP_INVOKE_RETURN(((*_VSTD::forward<_A0>(__a0)).*__f)(_VSTD::forward<_Args>(__args)...))
3859_LIBCPP_INVOKE_RETURN(((*static_cast<_A0&&>(__a0)).*__f)(static_cast<_Args&&>(__args)...))
36363860
36373861template <class _Fp, class _A0, class ..._Args,
36383862 class = __enable_if_bullet3<_Fp, _A0>>
36393863inline _LIBCPP_INLINE_VISIBILITY
36403864_LIBCPP_CONSTEXPR auto
36413865__invoke_constexpr(_Fp&& __f, _A0&& __a0, _Args&& ...__args)
3642_LIBCPP_INVOKE_RETURN(((*_VSTD::forward<_A0>(__a0)).*__f)(_VSTD::forward<_Args>(__args)...))
3866_LIBCPP_INVOKE_RETURN(((*static_cast<_A0&&>(__a0)).*__f)(static_cast<_Args&&>(__args)...))
36433867
36443868// bullets 4, 5 and 6
36453869
......@@ -3648,14 +3872,14 @@ template <class _Fp, class _A0,
36483872inline _LIBCPP_INLINE_VISIBILITY
36493873_LIBCPP_CONSTEXPR_AFTER_CXX17 auto
36503874__invoke(_Fp&& __f, _A0&& __a0)
3651_LIBCPP_INVOKE_RETURN(_VSTD::forward<_A0>(__a0).*__f)
3875_LIBCPP_INVOKE_RETURN(static_cast<_A0&&>(__a0).*__f)
36523876
36533877template <class _Fp, class _A0,
36543878 class = __enable_if_bullet4<_Fp, _A0>>
36553879inline _LIBCPP_INLINE_VISIBILITY
36563880_LIBCPP_CONSTEXPR auto
36573881__invoke_constexpr(_Fp&& __f, _A0&& __a0)
3658_LIBCPP_INVOKE_RETURN(_VSTD::forward<_A0>(__a0).*__f)
3882_LIBCPP_INVOKE_RETURN(static_cast<_A0&&>(__a0).*__f)
36593883
36603884template <class _Fp, class _A0,
36613885 class = __enable_if_bullet5<_Fp, _A0>>
......@@ -3676,14 +3900,14 @@ template <class _Fp, class _A0,
36763900inline _LIBCPP_INLINE_VISIBILITY
36773901_LIBCPP_CONSTEXPR_AFTER_CXX17 auto
36783902__invoke(_Fp&& __f, _A0&& __a0)
3679_LIBCPP_INVOKE_RETURN((*_VSTD::forward<_A0>(__a0)).*__f)
3903_LIBCPP_INVOKE_RETURN((*static_cast<_A0&&>(__a0)).*__f)
36803904
36813905template <class _Fp, class _A0,
36823906 class = __enable_if_bullet6<_Fp, _A0>>
36833907inline _LIBCPP_INLINE_VISIBILITY
36843908_LIBCPP_CONSTEXPR auto
36853909__invoke_constexpr(_Fp&& __f, _A0&& __a0)
3686_LIBCPP_INVOKE_RETURN((*_VSTD::forward<_A0>(__a0)).*__f)
3910_LIBCPP_INVOKE_RETURN((*static_cast<_A0&&>(__a0)).*__f)
36873911
36883912// bullet 7
36893913
......@@ -3691,13 +3915,13 @@ template <class _Fp, class ..._Args>
36913915inline _LIBCPP_INLINE_VISIBILITY
36923916_LIBCPP_CONSTEXPR_AFTER_CXX17 auto
36933917__invoke(_Fp&& __f, _Args&& ...__args)
3694_LIBCPP_INVOKE_RETURN(_VSTD::forward<_Fp>(__f)(_VSTD::forward<_Args>(__args)...))
3918_LIBCPP_INVOKE_RETURN(static_cast<_Fp&&>(__f)(static_cast<_Args&&>(__args)...))
36953919
36963920template <class _Fp, class ..._Args>
36973921inline _LIBCPP_INLINE_VISIBILITY
36983922_LIBCPP_CONSTEXPR auto
36993923__invoke_constexpr(_Fp&& __f, _Args&& ...__args)
3700_LIBCPP_INVOKE_RETURN(_VSTD::forward<_Fp>(__f)(_VSTD::forward<_Args>(__args)...))
3924_LIBCPP_INVOKE_RETURN(static_cast<_Fp&&>(__f)(static_cast<_Args&&>(__args)...))
37013925
37023926#undef _LIBCPP_INVOKE_RETURN
37033927
......@@ -3707,7 +3931,7 @@ struct __invokable_r
37073931{
37083932 template <class _XFp, class ..._XArgs>
37093933 static auto __try_call(int) -> decltype(
3710 _VSTD::__invoke(_VSTD::declval<_XFp>(), _VSTD::declval<_XArgs>()...));
3934 _VSTD::__invoke(declval<_XFp>(), declval<_XArgs>()...));
37113935 template <class _XFp, class ..._XArgs>
37123936 static __nat __try_call(...);
37133937
......@@ -3744,14 +3968,14 @@ struct __nothrow_invokable_r_imp<true, false, _Ret, _Fp, _Args...>
37443968 static void __test_noexcept(_Tp) noexcept;
37453969
37463970 static const bool value = noexcept(_ThisT::__test_noexcept<_Ret>(
3747 _VSTD::__invoke(_VSTD::declval<_Fp>(), _VSTD::declval<_Args>()...)));
3971 _VSTD::__invoke(declval<_Fp>(), declval<_Args>()...)));
37483972};
37493973
37503974template <class _Ret, class _Fp, class ..._Args>
37513975struct __nothrow_invokable_r_imp<true, true, _Ret, _Fp, _Args...>
37523976{
37533977 static const bool value = noexcept(
3754 _VSTD::__invoke(_VSTD::declval<_Fp>(), _VSTD::declval<_Args>()...));
3978 _VSTD::__invoke(declval<_Fp>(), declval<_Args>()...));
37553979};
37563980
37573981template <class _Ret, class _Fp, class ..._Args>
......@@ -3781,7 +4005,8 @@ struct __invoke_of
37814005
37824006// result_of
37834007
3784template <class _Callable> class result_of;
4008#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS)
4009template <class _Callable> class _LIBCPP_DEPRECATED_IN_CXX17 result_of;
37854010
37864011#ifndef _LIBCPP_CXX03_LANG
37874012
......@@ -3812,8 +4037,8 @@ struct __result_of_mp;
38124037
38134038template <class _MP, class _Tp>
38144039struct __result_of_mp<_MP, _Tp, true>
3815 : public __identity<typename __member_pointer_traits<_MP>::_ReturnType>
38164040{
4041 using type = typename __member_pointer_traits<_MP>::_ReturnType;
38174042};
38184043
38194044// member data pointer
......@@ -3824,13 +4049,13 @@ struct __result_of_mdp;
38244049template <class _Rp, class _Class, class _Tp>
38254050struct __result_of_mdp<_Rp _Class::*, _Tp, false>
38264051{
3827 typedef typename __apply_cv<decltype(*_VSTD::declval<_Tp>()), _Rp>::type& type;
4052 using type = typename __apply_cv<decltype(*declval<_Tp>()), _Rp>::type&;
38284053};
38294054
38304055template <class _Rp, class _Class, class _Tp>
38314056struct __result_of_mdp<_Rp _Class::*, _Tp, true>
38324057{
3833 typedef typename __apply_cv<_Tp, _Rp>::type& type;
4058 using type = typename __apply_cv<_Tp, _Rp>::type&;
38344059};
38354060
38364061template <class _Rp, class _Class, class _Tp>
......@@ -3866,11 +4091,12 @@ class _LIBCPP_TEMPLATE_VIS result_of<_Fn(_Args...)>
38664091{
38674092};
38684093
3869#endif // C++03
4094#endif // C++03
38704095
38714096#if _LIBCPP_STD_VER > 11
3872template <class _Tp> using result_of_t = typename result_of<_Tp>::type;
3873#endif
4097template <class _Tp> using result_of_t _LIBCPP_DEPRECATED_IN_CXX17 = typename result_of<_Tp>::type;
4098#endif // _LIBCPP_STD_VER > 11
4099#endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS)
38744100
38754101#if _LIBCPP_STD_VER > 14
38764102
......@@ -3923,70 +4149,32 @@ _LIBCPP_INLINE_VAR constexpr bool is_nothrow_invocable_r_v
39234149
39244150#endif // _LIBCPP_STD_VER > 14
39254151
4152// __swappable
4153
39264154template <class _Tp> struct __is_swappable;
39274155template <class _Tp> struct __is_nothrow_swappable;
39284156
3929// swap, swap_ranges
39304157
3931template <class _ForwardIterator1, class _ForwardIterator2>
3932inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
3933_ForwardIterator2
3934swap_ranges(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2);
3935
3936template <class _Tp>
3937inline _LIBCPP_INLINE_VISIBILITY
39384158#ifndef _LIBCPP_CXX03_LANG
3939typename enable_if
3940<
3941 is_move_constructible<_Tp>::value &&
3942 is_move_assignable<_Tp>::value
3943>::type
4159template <class _Tp>
4160using __swap_result_t = typename enable_if<is_move_constructible<_Tp>::value && is_move_assignable<_Tp>::value>::type;
39444161#else
3945void
4162template <class>
4163using __swap_result_t = void;
39464164#endif
3947_LIBCPP_CONSTEXPR_AFTER_CXX17
4165
4166template <class _Tp>
4167inline _LIBCPP_INLINE_VISIBILITY
4168_LIBCPP_CONSTEXPR_AFTER_CXX17 __swap_result_t<_Tp>
39484169swap(_Tp& __x, _Tp& __y) _NOEXCEPT_(is_nothrow_move_constructible<_Tp>::value &&
3949 is_nothrow_move_assignable<_Tp>::value)
3950{
3951 _Tp __t(_VSTD::move(__x));
3952 __x = _VSTD::move(__y);
3953 __y = _VSTD::move(__t);
3954}
4170 is_nothrow_move_assignable<_Tp>::value);
39554171
39564172template<class _Tp, size_t _Np>
39574173inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
39584174typename enable_if<
39594175 __is_swappable<_Tp>::value
39604176>::type
3961swap(_Tp (&__a)[_Np], _Tp (&__b)[_Np]) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value)
3962{
3963 _VSTD::swap_ranges(__a, __a + _Np, __b);
3964}
3965
3966template <class _ForwardIterator1, class _ForwardIterator2>
3967inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
3968_ForwardIterator2
3969swap_ranges(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2)
3970{
3971 for(; __first1 != __last1; ++__first1, (void) ++__first2)
3972 swap(*__first1, *__first2);
3973 return __first2;
3974}
3975
3976// iter_swap
3977
3978template <class _ForwardIterator1, class _ForwardIterator2>
3979inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
3980void
3981iter_swap(_ForwardIterator1 __a, _ForwardIterator2 __b)
3982 // _NOEXCEPT_(_NOEXCEPT_(swap(*__a, *__b)))
3983 _NOEXCEPT_(_NOEXCEPT_(swap(*_VSTD::declval<_ForwardIterator1>(),
3984 *_VSTD::declval<_ForwardIterator2>())))
3985{
3986 swap(*__a, *__b);
3987}
3988
3989// __swappable
4177swap(_Tp (&__a)[_Np], _Tp (&__b)[_Np]) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value);
39904178
39914179namespace __detail
39924180{
......@@ -3997,7 +4185,7 @@ template <class _Tp, class _Up = _Tp,
39974185struct __swappable_with
39984186{
39994187 template <class _LHS, class _RHS>
4000 static decltype(swap(_VSTD::declval<_LHS>(), _VSTD::declval<_RHS>()))
4188 static decltype(swap(declval<_LHS>(), declval<_RHS>()))
40014189 __test_swap(int);
40024190 template <class, class>
40034191 static __nat __test_swap(long);
......@@ -4017,8 +4205,8 @@ template <class _Tp, class _Up = _Tp, bool _Swappable = __swappable_with<_Tp, _U
40174205struct __nothrow_swappable_with {
40184206 static const bool value =
40194207#ifndef _LIBCPP_HAS_NO_NOEXCEPT
4020 noexcept(swap(_VSTD::declval<_Tp>(), _VSTD::declval<_Up>()))
4021 && noexcept(swap(_VSTD::declval<_Up>(), _VSTD::declval<_Tp>()));
4208 noexcept(swap(declval<_Tp>(), declval<_Up>()))
4209 && noexcept(swap(declval<_Up>(), declval<_Tp>()));
40224210#else
40234211 false;
40244212#endif
......@@ -4168,7 +4356,7 @@ struct __has_operator_addressof_member_imp
41684356{
41694357 template <class _Up>
41704358 static auto __test(int)
4171 -> typename __select_2nd<decltype(_VSTD::declval<_Up>().operator&()), true_type>::type;
4359 -> typename __select_2nd<decltype(declval<_Up>().operator&()), true_type>::type;
41724360 template <class>
41734361 static auto __test(long) -> false_type;
41744362
......@@ -4180,7 +4368,7 @@ struct __has_operator_addressof_free_imp
41804368{
41814369 template <class _Up>
41824370 static auto __test(int)
4183 -> typename __select_2nd<decltype(operator&(_VSTD::declval<_Up>())), true_type>::type;
4371 -> typename __select_2nd<decltype(operator&(declval<_Up>())), true_type>::type;
41844372 template <class>
41854373 static auto __test(long) -> false_type;
41864374
......@@ -4193,7 +4381,7 @@ struct __has_operator_addressof
41934381 || __has_operator_addressof_free_imp<_Tp>::value>
41944382{};
41954383
4196#endif // _LIBCPP_CXX03_LANG
4384#endif // _LIBCPP_CXX03_LANG
41974385
41984386// is_scoped_enum [meta.unary.prop]
41994387
......@@ -4233,7 +4421,7 @@ struct negation : _Not<_Tp> {};
42334421template<class _Tp>
42344422_LIBCPP_INLINE_VAR constexpr bool negation_v
42354423 = negation<_Tp>::value;
4236#endif // _LIBCPP_STD_VER > 14
4424#endif // _LIBCPP_STD_VER > 14
42374425
42384426// These traits are used in __tree and __hash_table
42394427struct __extract_key_fail_tag {};
......@@ -4283,6 +4471,14 @@ bool __libcpp_is_constant_evaluated() _NOEXCEPT { return false; }
42834471template <class _CharT>
42844472using _IsCharLikeType = _And<is_standard_layout<_CharT>, is_trivial<_CharT> >;
42854473
4474template<class _Tp>
4475using __make_const_lvalue_ref = const typename remove_reference<_Tp>::type&;
4476
4477#if _LIBCPP_STD_VER > 17
4478template<bool _Const, class _Tp>
4479using __maybe_const = conditional_t<_Const, const _Tp, _Tp>;
4480#endif // _LIBCPP_STD_VER > 17
4481
42864482_LIBCPP_END_NAMESPACE_STD
42874483
42884484#if _LIBCPP_STD_VER > 14
......@@ -4294,4 +4490,4 @@ namespace std // purposefully not versioned
42944490}
42954491#endif
42964492
4297#endif // _LIBCPP_TYPE_TRAITS
4493#endif // _LIBCPP_TYPE_TRAITS
lib/libcxx/include/typeindex+4-2
......@@ -45,8 +45,10 @@ struct hash<type_index>
4545*/
4646
4747#include <__config>
48#include <typeinfo>
48#include <__functional/unary_function.h>
4949#include <__functional_base>
50#include <compare>
51#include <typeinfo>
5052
5153#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
5254#pragma GCC system_header
......@@ -99,4 +101,4 @@ struct _LIBCPP_TEMPLATE_VIS hash<type_index>
99101
100102_LIBCPP_END_NAMESPACE_STD
101103
102#endif // _LIBCPP_TYPEINDEX
104#endif // _LIBCPP_TYPEINDEX
lib/libcxx/include/typeinfo+30-24
......@@ -56,12 +56,13 @@ public:
5656
5757*/
5858
59#include <__config>
6059#include <__availability>
61#include <exception>
60#include <__config>
6261#include <cstddef>
6362#include <cstdint>
63#include <exception>
6464#include <type_traits>
65
6566#ifdef _LIBCPP_NO_EXCEPTIONS
6667#include <cstdlib>
6768#endif
......@@ -125,7 +126,7 @@ public:
125126// (_LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION = 1)
126127// ------------------------------------------------------------------------- //
127128// This implementation of type_info assumes a unique copy of the RTTI for a
128// given type inside a program. This is a valid assumption when abiding to
129// given type inside a program. This is a valid assumption when abiding to the
129130// Itanium ABI (http://itanium-cxx-abi.github.io/cxx-abi/abi.html#vtable-components).
130131// Under this assumption, we can always compare the addresses of the type names
131132// to implement equality-comparison of type_infos instead of having to perform
......@@ -144,22 +145,29 @@ public:
144145// NonUniqueARMRTTIBit
145146// (_LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION = 3)
146147// -------------------------------------------------------------------------- //
148// This implementation is specific to ARM64 on Apple platforms.
149//
147150// This implementation of type_info does not assume always a unique copy of
148// the RTTI for a given type inside a program. It packs the pointer to the
149// type name into a uintptr_t and reserves the high bit of that pointer (which
150// is assumed to be free for use under the ABI in use) to represent whether
151// that specific copy of the RTTI can be assumed unique inside the program.
152// To implement equality-comparison of type_infos, we check whether BOTH
153// type_infos are guaranteed unique, and if so, we simply compare the addresses
154// of their type names instead of doing a deep string comparison, which is
155// faster. If at least one of the type_infos can't guarantee uniqueness, we
156// have no choice but to fall back to a deep string comparison.
151// the RTTI for a given type inside a program. When constructing the type_info,
152// the compiler packs the pointer to the type name into a uintptr_t and reserves
153// the high bit of that pointer, which is assumed to be free for use under that
154// ABI. If that high bit is set, that specific copy of the RTTI can't be assumed
155// to be unique within the program. If the high bit is unset, then the RTTI can
156// be assumed to be unique within the program.
157157//
158// This implementation is specific to ARM64 on Apple platforms.
158// When comparing type_infos, if both RTTIs can be assumed to be unique, it
159// suffices to compare their addresses. If both the RTTIs can't be assumed to
160// be unique, we must perform a deep string comparison of the type names.
161// However, if one of the RTTIs is guaranteed unique and the other one isn't,
162// then both RTTIs are necessarily not to be considered equal.
159163//
160// Note that the compiler is the one setting (or unsetting) the high bit of
161// the pointer when it constructs the type_info, depending on whether it can
162// guarantee uniqueness for that specific type_info.
164// The intent of this design is to remove the need for weak symbols. Specifically,
165// if a type would normally have a default-visibility RTTI emitted as a weak
166// symbol, it is given hidden visibility instead and the non-unique bit is set.
167// Otherwise, types declared with hidden visibility are always considered to have
168// a unique RTTI: the RTTI is emitted with linkonce_odr linkage and is assumed
169// to be deduplicated by the linker within the linked image. Across linked image
170// boundaries, such types are thus considered different types.
163171
164172// This value can be overriden in the __config_site. When it's not overriden,
165173// we pick a default implementation based on the platform here.
......@@ -241,20 +249,22 @@ struct __type_info_implementations {
241249 _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE
242250 static size_t __hash(__type_name_t __v) _NOEXCEPT {
243251 if (__is_type_name_unique(__v))
244 return reinterpret_cast<size_t>(__v);
252 return __v;
245253 return __non_unique_impl::__hash(__type_name_to_string(__v));
246254 }
247255 _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE
248256 static bool __eq(__type_name_t __lhs, __type_name_t __rhs) _NOEXCEPT {
249257 if (__lhs == __rhs)
250258 return true;
251 if (__is_type_name_unique(__lhs, __rhs))
259 if (__is_type_name_unique(__lhs) || __is_type_name_unique(__rhs))
260 // Either both are unique and have a different address, or one of them
261 // is unique and the other one isn't. In both cases they are unequal.
252262 return false;
253263 return __builtin_strcmp(__type_name_to_string(__lhs), __type_name_to_string(__rhs)) == 0;
254264 }
255265 _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE
256266 static bool __lt(__type_name_t __lhs, __type_name_t __rhs) _NOEXCEPT {
257 if (__is_type_name_unique(__lhs, __rhs))
267 if (__is_type_name_unique(__lhs) || __is_type_name_unique(__rhs))
258268 return __lhs < __rhs;
259269 return __builtin_strcmp(__type_name_to_string(__lhs), __type_name_to_string(__rhs)) < 0;
260270 }
......@@ -269,10 +279,6 @@ struct __type_info_implementations {
269279 static bool __is_type_name_unique(__type_name_t __lhs) _NOEXCEPT {
270280 return !(__lhs & __non_unique_rtti_bit::value);
271281 }
272 _LIBCPP_INLINE_VISIBILITY
273 static bool __is_type_name_unique(__type_name_t __lhs, __type_name_t __rhs) _NOEXCEPT {
274 return !((__lhs & __rhs) & __non_unique_rtti_bit::value);
275 }
276282 };
277283
278284 typedef
......@@ -371,4 +377,4 @@ void __throw_bad_cast()
371377}
372378_LIBCPP_END_NAMESPACE_STD
373379
374#endif // __LIBCPP_TYPEINFO
380#endif // __LIBCPP_TYPEINFO
lib/libcxx/include/unordered_map+27-24
......@@ -432,15 +432,18 @@ template <class Key, class T, class Hash, class Pred, class Alloc>
432432*/
433433
434434#include <__config>
435#include <__debug>
436#include <__functional/is_transparent.h>
435437#include <__hash_table>
436438#include <__node_handle>
439#include <__utility/forward.h>
440#include <compare>
437441#include <functional>
442#include <iterator> // __libcpp_erase_if_container
438443#include <stdexcept>
439444#include <tuple>
440445#include <version>
441446
442#include <__debug>
443
444447#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
445448#pragma GCC system_header
446449#endif
......@@ -684,7 +687,7 @@ public:
684687 {
685688 const_cast<bool&>(__x.__value_constructed) = false;
686689 }
687#endif // _LIBCPP_CXX03_LANG
690#endif // _LIBCPP_CXX03_LANG
688691
689692 _LIBCPP_INLINE_VISIBILITY
690693 void operator()(pointer __p) _NOEXCEPT
......@@ -700,7 +703,7 @@ public:
700703
701704#ifndef _LIBCPP_CXX03_LANG
702705template <class _Key, class _Tp>
703struct __hash_value_type
706struct _LIBCPP_STANDALONE_DEBUG __hash_value_type
704707{
705708 typedef _Key key_type;
706709 typedef _Tp mapped_type;
......@@ -920,9 +923,9 @@ public:
920923 // types
921924 typedef _Key key_type;
922925 typedef _Tp mapped_type;
923 typedef typename __identity<_Hash>::type hasher;
924 typedef typename __identity<_Pred>::type key_equal;
925 typedef typename __identity<_Alloc>::type allocator_type;
926 typedef __identity_t<_Hash> hasher;
927 typedef __identity_t<_Pred> key_equal;
928 typedef __identity_t<_Alloc> allocator_type;
926929 typedef pair<const key_type, mapped_type> value_type;
927930 typedef value_type& reference;
928931 typedef const value_type& const_reference;
......@@ -1013,7 +1016,7 @@ public:
10131016 unordered_map(initializer_list<value_type> __il, size_type __n,
10141017 const hasher& __hf, const key_equal& __eql,
10151018 const allocator_type& __a);
1016#endif // _LIBCPP_CXX03_LANG
1019#endif // _LIBCPP_CXX03_LANG
10171020#if _LIBCPP_STD_VER > 11
10181021 _LIBCPP_INLINE_VISIBILITY
10191022 unordered_map(size_type __n, const allocator_type& __a)
......@@ -1066,7 +1069,7 @@ public:
10661069 _NOEXCEPT_(is_nothrow_move_assignable<__table>::value);
10671070 _LIBCPP_INLINE_VISIBILITY
10681071 unordered_map& operator=(initializer_list<value_type> __il);
1069#endif // _LIBCPP_CXX03_LANG
1072#endif // _LIBCPP_CXX03_LANG
10701073
10711074 _LIBCPP_INLINE_VISIBILITY
10721075 allocator_type get_allocator() const _NOEXCEPT
......@@ -1171,7 +1174,7 @@ public:
11711174 return __table_.__emplace_unique(_VSTD::forward<_Args>(__args)...).first;
11721175 }
11731176
1174#endif // _LIBCPP_CXX03_LANG
1177#endif // _LIBCPP_CXX03_LANG
11751178
11761179#if _LIBCPP_STD_VER > 14
11771180 template <class... _Args>
......@@ -1452,7 +1455,7 @@ public:
14521455 bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const
14531456 {return __table_.__addable(&__i->__i_, __n);}
14541457
1455#endif // _LIBCPP_DEBUG_LEVEL == 2
1458#endif // _LIBCPP_DEBUG_LEVEL == 2
14561459
14571460private:
14581461
......@@ -1718,7 +1721,7 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator=(
17181721 return *this;
17191722}
17201723
1721#endif // _LIBCPP_CXX03_LANG
1724#endif // _LIBCPP_CXX03_LANG
17221725
17231726template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
17241727template <class _InputIterator>
......@@ -1778,7 +1781,7 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator[](const key_type& __k)
17781781 return __r.first->second;
17791782}
17801783
1781#endif // _LIBCPP_CXX03_MODE
1784#endif // _LIBCPP_CXX03_LANG
17821785
17831786template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
17841787_Tp&
......@@ -1817,7 +1820,7 @@ inline _LIBCPP_INLINE_VISIBILITY
18171820 typename unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::size_type
18181821 erase_if(unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __c,
18191822 _Predicate __pred) {
1820 return __libcpp_erase_if_container(__c, __pred);
1823 return _VSTD::__libcpp_erase_if_container(__c, __pred);
18211824}
18221825#endif
18231826
......@@ -1857,9 +1860,9 @@ public:
18571860 // types
18581861 typedef _Key key_type;
18591862 typedef _Tp mapped_type;
1860 typedef typename __identity<_Hash>::type hasher;
1861 typedef typename __identity<_Pred>::type key_equal;
1862 typedef typename __identity<_Alloc>::type allocator_type;
1863 typedef __identity_t<_Hash> hasher;
1864 typedef __identity_t<_Pred> key_equal;
1865 typedef __identity_t<_Alloc> allocator_type;
18631866 typedef pair<const key_type, mapped_type> value_type;
18641867 typedef value_type& reference;
18651868 typedef const value_type& const_reference;
......@@ -1948,7 +1951,7 @@ public:
19481951 unordered_multimap(initializer_list<value_type> __il, size_type __n,
19491952 const hasher& __hf, const key_equal& __eql,
19501953 const allocator_type& __a);
1951#endif // _LIBCPP_CXX03_LANG
1954#endif // _LIBCPP_CXX03_LANG
19521955#if _LIBCPP_STD_VER > 11
19531956 _LIBCPP_INLINE_VISIBILITY
19541957 unordered_multimap(size_type __n, const allocator_type& __a)
......@@ -2001,7 +2004,7 @@ public:
20012004 _NOEXCEPT_(is_nothrow_move_assignable<__table>::value);
20022005 _LIBCPP_INLINE_VISIBILITY
20032006 unordered_multimap& operator=(initializer_list<value_type> __il);
2004#endif // _LIBCPP_CXX03_LANG
2007#endif // _LIBCPP_CXX03_LANG
20052008
20062009 _LIBCPP_INLINE_VISIBILITY
20072010 allocator_type get_allocator() const _NOEXCEPT
......@@ -2070,7 +2073,7 @@ public:
20702073 iterator emplace_hint(const_iterator __p, _Args&&... __args) {
20712074 return __table_.__emplace_hint_multi(__p.__i_, _VSTD::forward<_Args>(__args)...);
20722075 }
2073#endif // _LIBCPP_CXX03_LANG
2076#endif // _LIBCPP_CXX03_LANG
20742077
20752078
20762079 _LIBCPP_INLINE_VISIBILITY
......@@ -2255,7 +2258,7 @@ public:
22552258 bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const
22562259 {return __table_.__addable(&__i->__i_, __n);}
22572260
2258#endif // _LIBCPP_DEBUG_LEVEL == 2
2261#endif // _LIBCPP_DEBUG_LEVEL == 2
22592262
22602263
22612264};
......@@ -2518,7 +2521,7 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::operator=(
25182521 return *this;
25192522}
25202523
2521#endif // _LIBCPP_CXX03_LANG
2524#endif // _LIBCPP_CXX03_LANG
25222525
25232526
25242527
......@@ -2550,7 +2553,7 @@ inline _LIBCPP_INLINE_VISIBILITY
25502553 typename unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::size_type
25512554 erase_if(unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __c,
25522555 _Predicate __pred) {
2553 return __libcpp_erase_if_container(__c, __pred);
2556 return _VSTD::__libcpp_erase_if_container(__c, __pred);
25542557}
25552558#endif
25562559
......@@ -2588,4 +2591,4 @@ operator!=(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
25882591
25892592_LIBCPP_END_NAMESPACE_STD
25902593
2591#endif // _LIBCPP_UNORDERED_MAP
2594#endif // _LIBCPP_UNORDERED_MAP
lib/libcxx/include/unordered_set+24-21
......@@ -387,13 +387,16 @@ template <class Value, class Hash, class Pred, class Alloc>
387387*/
388388
389389#include <__config>
390#include <__debug>
391#include <__functional/is_transparent.h>
390392#include <__hash_table>
391393#include <__node_handle>
394#include <__utility/forward.h>
395#include <compare>
392396#include <functional>
397#include <iterator> // __libcpp_erase_if_container
393398#include <version>
394399
395#include <__debug>
396
397400#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
398401#pragma GCC system_header
399402#endif
......@@ -411,9 +414,9 @@ public:
411414 // types
412415 typedef _Value key_type;
413416 typedef key_type value_type;
414 typedef typename __identity<_Hash>::type hasher;
415 typedef typename __identity<_Pred>::type key_equal;
416 typedef typename __identity<_Alloc>::type allocator_type;
417 typedef __identity_t<_Hash> hasher;
418 typedef __identity_t<_Pred> key_equal;
419 typedef __identity_t<_Alloc> allocator_type;
417420 typedef value_type& reference;
418421 typedef const value_type& const_reference;
419422 static_assert((is_same<value_type, typename allocator_type::value_type>::value),
......@@ -512,7 +515,7 @@ public:
512515 const hasher& __hf, const allocator_type& __a)
513516 : unordered_set(__il, __n, __hf, key_equal(), __a) {}
514517#endif
515#endif // _LIBCPP_CXX03_LANG
518#endif // _LIBCPP_CXX03_LANG
516519 _LIBCPP_INLINE_VISIBILITY
517520 ~unordered_set() {
518521 static_assert(sizeof(__diagnose_unordered_container_requirements<_Value, _Hash, _Pred>(0)), "");
......@@ -530,7 +533,7 @@ public:
530533 _NOEXCEPT_(is_nothrow_move_assignable<__table>::value);
531534 _LIBCPP_INLINE_VISIBILITY
532535 unordered_set& operator=(initializer_list<value_type> __il);
533#endif // _LIBCPP_CXX03_LANG
536#endif // _LIBCPP_CXX03_LANG
534537
535538 _LIBCPP_INLINE_VISIBILITY
536539 allocator_type get_allocator() const _NOEXCEPT
......@@ -595,7 +598,7 @@ public:
595598 _LIBCPP_INLINE_VISIBILITY
596599 void insert(initializer_list<value_type> __il)
597600 {insert(__il.begin(), __il.end());}
598#endif // _LIBCPP_CXX03_LANG
601#endif // _LIBCPP_CXX03_LANG
599602 _LIBCPP_INLINE_VISIBILITY
600603 pair<iterator, bool> insert(const value_type& __x)
601604 {return __table_.__insert_unique(__x);}
......@@ -792,7 +795,7 @@ public:
792795 bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const
793796 {return __table_.__addable(__i, __n);}
794797
795#endif // _LIBCPP_DEBUG_LEVEL == 2
798#endif // _LIBCPP_DEBUG_LEVEL == 2
796799
797800};
798801
......@@ -1039,7 +1042,7 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::operator=(
10391042 return *this;
10401043}
10411044
1042#endif // _LIBCPP_CXX03_LANG
1045#endif // _LIBCPP_CXX03_LANG
10431046
10441047template <class _Value, class _Hash, class _Pred, class _Alloc>
10451048template <class _InputIterator>
......@@ -1069,7 +1072,7 @@ inline _LIBCPP_INLINE_VISIBILITY
10691072 typename unordered_set<_Value, _Hash, _Pred, _Alloc>::size_type
10701073 erase_if(unordered_set<_Value, _Hash, _Pred, _Alloc>& __c,
10711074 _Predicate __pred) {
1072 return __libcpp_erase_if_container(__c, __pred);
1075 return _VSTD::__libcpp_erase_if_container(__c, __pred);
10731076}
10741077#endif
10751078
......@@ -1109,9 +1112,9 @@ public:
11091112 // types
11101113 typedef _Value key_type;
11111114 typedef key_type value_type;
1112 typedef typename __identity<_Hash>::type hasher;
1113 typedef typename __identity<_Pred>::type key_equal;
1114 typedef typename __identity<_Alloc>::type allocator_type;
1115 typedef __identity_t<_Hash> hasher;
1116 typedef __identity_t<_Pred> key_equal;
1117 typedef __identity_t<_Alloc> allocator_type;
11151118 typedef value_type& reference;
11161119 typedef const value_type& const_reference;
11171120 static_assert((is_same<value_type, typename allocator_type::value_type>::value),
......@@ -1208,7 +1211,7 @@ public:
12081211 unordered_multiset(initializer_list<value_type> __il, size_type __n, const hasher& __hf, const allocator_type& __a)
12091212 : unordered_multiset(__il, __n, __hf, key_equal(), __a) {}
12101213#endif
1211#endif // _LIBCPP_CXX03_LANG
1214#endif // _LIBCPP_CXX03_LANG
12121215 _LIBCPP_INLINE_VISIBILITY
12131216 ~unordered_multiset() {
12141217 static_assert(sizeof(__diagnose_unordered_container_requirements<_Value, _Hash, _Pred>(0)), "");
......@@ -1225,7 +1228,7 @@ public:
12251228 unordered_multiset& operator=(unordered_multiset&& __u)
12261229 _NOEXCEPT_(is_nothrow_move_assignable<__table>::value);
12271230 unordered_multiset& operator=(initializer_list<value_type> __il);
1228#endif // _LIBCPP_CXX03_LANG
1231#endif // _LIBCPP_CXX03_LANG
12291232
12301233 _LIBCPP_INLINE_VISIBILITY
12311234 allocator_type get_allocator() const _NOEXCEPT
......@@ -1269,7 +1272,7 @@ public:
12691272 _LIBCPP_INLINE_VISIBILITY
12701273 void insert(initializer_list<value_type> __il)
12711274 {insert(__il.begin(), __il.end());}
1272#endif // _LIBCPP_CXX03_LANG
1275#endif // _LIBCPP_CXX03_LANG
12731276
12741277 _LIBCPP_INLINE_VISIBILITY
12751278 iterator insert(const value_type& __x) {return __table_.__insert_multi(__x);}
......@@ -1458,7 +1461,7 @@ public:
14581461 bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const
14591462 {return __table_.__addable(__i, __n);}
14601463
1461#endif // _LIBCPP_DEBUG_LEVEL == 2
1464#endif // _LIBCPP_DEBUG_LEVEL == 2
14621465
14631466};
14641467
......@@ -1705,7 +1708,7 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::operator=(
17051708 return *this;
17061709}
17071710
1708#endif // _LIBCPP_CXX03_LANG
1711#endif // _LIBCPP_CXX03_LANG
17091712
17101713template <class _Value, class _Hash, class _Pred, class _Alloc>
17111714template <class _InputIterator>
......@@ -1735,7 +1738,7 @@ inline _LIBCPP_INLINE_VISIBILITY
17351738 typename unordered_multiset<_Value, _Hash, _Pred, _Alloc>::size_type
17361739 erase_if(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __c,
17371740 _Predicate __pred) {
1738 return __libcpp_erase_if_container(__c, __pred);
1741 return _VSTD::__libcpp_erase_if_container(__c, __pred);
17391742}
17401743#endif
17411744
......@@ -1773,4 +1776,4 @@ operator!=(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
17731776
17741777_LIBCPP_END_NAMESPACE_STD
17751778
1776#endif // _LIBCPP_UNORDERED_SET
1779#endif // _LIBCPP_UNORDERED_SET
lib/libcxx/include/utility+35-1434
......@@ -58,6 +58,14 @@ template <class T> void as_const(const T&&) = delete; // C+
5858
5959template <class T> typename add_rvalue_reference<T>::type declval() noexcept;
6060
61template<class T, class U> constexpr bool cmp_equal(T t, U u) noexcept; // C++20
62template<class T, class U> constexpr bool cmp_not_equal(T t, U u) noexcept; // C++20
63template<class T, class U> constexpr bool cmp_less(T t, U u) noexcept; // C++20
64template<class T, class U> constexpr bool cmp_greater(T t, U u) noexcept; // C++20
65template<class T, class U> constexpr bool cmp_less_equal(T t, U u) noexcept; // C++20
66template<class T, class U> constexpr bool cmp_greater_equal(T t, U u) noexcept; // C++20
67template<class R, class T> constexpr bool in_range(T t) noexcept; // C++20
68
6169template <class T1, class T2>
6270struct pair
6371{
......@@ -76,15 +84,15 @@ struct pair
7684 template <class U, class V> explicit(see-below) pair(pair<U, V>&& p); // constexpr in C++14
7785 template <class... Args1, class... Args2>
7886 pair(piecewise_construct_t, tuple<Args1...> first_args,
79 tuple<Args2...> second_args);
87 tuple<Args2...> second_args); // constexpr in C++20
8088
81 template <class U, class V> pair& operator=(const pair<U, V>& p);
89 template <class U, class V> pair& operator=(const pair<U, V>& p); // constexpr in C++20
8290 pair& operator=(pair&& p) noexcept(is_nothrow_move_assignable<T1>::value &&
83 is_nothrow_move_assignable<T2>::value);
84 template <class U, class V> pair& operator=(pair<U, V>&& p);
91 is_nothrow_move_assignable<T2>::value); // constexpr in C++20
92 template <class U, class V> pair& operator=(pair<U, V>&& p); // constexpr in C++20
8593
8694 void swap(pair& p) noexcept(is_nothrow_swappable_v<T1> &&
87 is_nothrow_swappable_v<T2>);
95 is_nothrow_swappable_v<T2>); // constexpr in C++20
8896};
8997
9098template <class T1, class T2> bool operator==(const pair<T1,T2>&, const pair<T1,T2>&); // constexpr in C++14
......@@ -94,10 +102,10 @@ template <class T1, class T2> bool operator> (const pair<T1,T2>&, const pair<T1,
94102template <class T1, class T2> bool operator>=(const pair<T1,T2>&, const pair<T1,T2>&); // constexpr in C++14
95103template <class T1, class T2> bool operator<=(const pair<T1,T2>&, const pair<T1,T2>&); // constexpr in C++14
96104
97template <class T1, class T2> pair<V1, V2> make_pair(T1&&, T2&&); // constexpr in C++14
105template <class T1, class T2> pair<V1, V2> make_pair(T1&&, T2&&); // constexpr in C++14
98106template <class T1, class T2>
99107void
100swap(pair<T1, T2>& x, pair<T1, T2>& y) noexcept(noexcept(x.swap(y)));
108swap(pair<T1, T2>& x, pair<T1, T2>& y) noexcept(noexcept(x.swap(y))); // constexpr in C++20
101109
102110struct piecewise_construct_t { explicit piecewise_construct_t() = default; };
103111inline constexpr piecewise_construct_t piecewise_construct = piecewise_construct_t();
......@@ -191,1439 +199,32 @@ template <size_t I>
191199template <size_t I>
192200 inline constexpr in_place_index_t<I> in_place_index{};
193201
202// [utility.underlying], to_underlying
203template <class T>
204 constexpr underlying_type_t<T> to_underlying( T value ) noexcept; // C++2b
205
194206} // std
195207
196208*/
197209
198210#include <__config>
211#include <__debug>
199212#include <__tuple>
200#include <type_traits>
213#include <__utility/as_const.h>
214#include <__utility/cmp.h>
215#include <__utility/declval.h>
216#include <__utility/exchange.h>
217#include <__utility/forward.h>
218#include <__utility/in_place.h>
219#include <__utility/integer_sequence.h>
220#include <__utility/move.h>
221#include <__utility/pair.h>
222#include <__utility/piecewise_construct.h>
223#include <__utility/rel_ops.h>
224#include <__utility/swap.h>
225#include <__utility/to_underlying.h>
226#include <compare>
201227#include <initializer_list>
202#include <cstddef>
203#include <cstring>
204#include <cstdint>
205228#include <version>
206#include <__debug>
207
208#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
209#pragma GCC system_header
210#endif
211
212_LIBCPP_BEGIN_NAMESPACE_STD
213
214namespace rel_ops
215{
216
217template<class _Tp>
218inline _LIBCPP_INLINE_VISIBILITY
219bool
220operator!=(const _Tp& __x, const _Tp& __y)
221{
222 return !(__x == __y);
223}
224
225template<class _Tp>
226inline _LIBCPP_INLINE_VISIBILITY
227bool
228operator> (const _Tp& __x, const _Tp& __y)
229{
230 return __y < __x;
231}
232
233template<class _Tp>
234inline _LIBCPP_INLINE_VISIBILITY
235bool
236operator<=(const _Tp& __x, const _Tp& __y)
237{
238 return !(__y < __x);
239}
240
241template<class _Tp>
242inline _LIBCPP_INLINE_VISIBILITY
243bool
244operator>=(const _Tp& __x, const _Tp& __y)
245{
246 return !(__x < __y);
247}
248
249} // rel_ops
250
251// swap_ranges is defined in <type_traits>`
252
253// swap is defined in <type_traits>
254
255// move_if_noexcept
256
257template <class _Tp>
258inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
259#ifndef _LIBCPP_CXX03_LANG
260typename conditional
261<
262 !is_nothrow_move_constructible<_Tp>::value && is_copy_constructible<_Tp>::value,
263 const _Tp&,
264 _Tp&&
265>::type
266#else // _LIBCPP_CXX03_LANG
267const _Tp&
268#endif
269move_if_noexcept(_Tp& __x) _NOEXCEPT
270{
271 return _VSTD::move(__x);
272}
273
274#if _LIBCPP_STD_VER > 14
275template <class _Tp> constexpr add_const_t<_Tp>& as_const(_Tp& __t) noexcept { return __t; }
276template <class _Tp> void as_const(const _Tp&&) = delete;
277#endif
278
279struct _LIBCPP_TEMPLATE_VIS piecewise_construct_t { explicit piecewise_construct_t() = default; };
280#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY)
281extern _LIBCPP_EXPORTED_FROM_ABI const piecewise_construct_t piecewise_construct;// = piecewise_construct_t();
282#else
283/* _LIBCPP_INLINE_VAR */ constexpr piecewise_construct_t piecewise_construct = piecewise_construct_t();
284#endif
285
286#if defined(_LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR)
287template <class, class>
288struct __non_trivially_copyable_base {
289 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
290 __non_trivially_copyable_base() _NOEXCEPT {}
291 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
292 __non_trivially_copyable_base(__non_trivially_copyable_base const&) _NOEXCEPT {}
293};
294#endif
295
296template <class _T1, class _T2>
297struct _LIBCPP_TEMPLATE_VIS pair
298#if defined(_LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR)
299: private __non_trivially_copyable_base<_T1, _T2>
300#endif
301{
302 typedef _T1 first_type;
303 typedef _T2 second_type;
304
305 _T1 first;
306 _T2 second;
307
308#if !defined(_LIBCPP_CXX03_LANG)
309 pair(pair const&) = default;
310 pair(pair&&) = default;
311#else
312 // Use the implicitly declared copy constructor in C++03
313#endif
314
315#ifdef _LIBCPP_CXX03_LANG
316 _LIBCPP_INLINE_VISIBILITY
317 pair() : first(), second() {}
318
319 _LIBCPP_INLINE_VISIBILITY
320 pair(_T1 const& __t1, _T2 const& __t2) : first(__t1), second(__t2) {}
321
322 template <class _U1, class _U2>
323 _LIBCPP_INLINE_VISIBILITY
324 pair(const pair<_U1, _U2>& __p) : first(__p.first), second(__p.second) {}
325
326 _LIBCPP_INLINE_VISIBILITY
327 pair& operator=(pair const& __p) {
328 first = __p.first;
329 second = __p.second;
330 return *this;
331 }
332#else
333 template <bool _Val>
334 using _EnableB _LIBCPP_NODEBUG_TYPE = typename enable_if<_Val, bool>::type;
335
336 struct _CheckArgs {
337 template <int&...>
338 static constexpr bool __enable_explicit_default() {
339 return is_default_constructible<_T1>::value
340 && is_default_constructible<_T2>::value
341 && !__enable_implicit_default<>();
342 }
343
344 template <int&...>
345 static constexpr bool __enable_implicit_default() {
346 return __is_implicitly_default_constructible<_T1>::value
347 && __is_implicitly_default_constructible<_T2>::value;
348 }
349
350 template <class _U1, class _U2>
351 static constexpr bool __enable_explicit() {
352 return is_constructible<first_type, _U1>::value
353 && is_constructible<second_type, _U2>::value
354 && (!is_convertible<_U1, first_type>::value
355 || !is_convertible<_U2, second_type>::value);
356 }
357
358 template <class _U1, class _U2>
359 static constexpr bool __enable_implicit() {
360 return is_constructible<first_type, _U1>::value
361 && is_constructible<second_type, _U2>::value
362 && is_convertible<_U1, first_type>::value
363 && is_convertible<_U2, second_type>::value;
364 }
365 };
366
367 template <bool _MaybeEnable>
368 using _CheckArgsDep _LIBCPP_NODEBUG_TYPE = typename conditional<
369 _MaybeEnable, _CheckArgs, __check_tuple_constructor_fail>::type;
370
371 struct _CheckTupleLikeConstructor {
372 template <class _Tuple>
373 static constexpr bool __enable_implicit() {
374 return __tuple_convertible<_Tuple, pair>::value;
375 }
376
377 template <class _Tuple>
378 static constexpr bool __enable_explicit() {
379 return __tuple_constructible<_Tuple, pair>::value
380 && !__tuple_convertible<_Tuple, pair>::value;
381 }
382
383 template <class _Tuple>
384 static constexpr bool __enable_assign() {
385 return __tuple_assignable<_Tuple, pair>::value;
386 }
387 };
388
389 template <class _Tuple>
390 using _CheckTLC _LIBCPP_NODEBUG_TYPE = typename conditional<
391 __tuple_like_with_size<_Tuple, 2>::value
392 && !is_same<typename decay<_Tuple>::type, pair>::value,
393 _CheckTupleLikeConstructor,
394 __check_tuple_constructor_fail
395 >::type;
396
397 template<bool _Dummy = true, _EnableB<
398 _CheckArgsDep<_Dummy>::__enable_explicit_default()
399 > = false>
400 explicit _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
401 pair() _NOEXCEPT_(is_nothrow_default_constructible<first_type>::value &&
402 is_nothrow_default_constructible<second_type>::value)
403 : first(), second() {}
404
405 template<bool _Dummy = true, _EnableB<
406 _CheckArgsDep<_Dummy>::__enable_implicit_default()
407 > = false>
408 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
409 pair() _NOEXCEPT_(is_nothrow_default_constructible<first_type>::value &&
410 is_nothrow_default_constructible<second_type>::value)
411 : first(), second() {}
412
413 template <bool _Dummy = true, _EnableB<
414 _CheckArgsDep<_Dummy>::template __enable_explicit<_T1 const&, _T2 const&>()
415 > = false>
416 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
417 explicit pair(_T1 const& __t1, _T2 const& __t2)
418 _NOEXCEPT_(is_nothrow_copy_constructible<first_type>::value &&
419 is_nothrow_copy_constructible<second_type>::value)
420 : first(__t1), second(__t2) {}
421
422 template<bool _Dummy = true, _EnableB<
423 _CheckArgsDep<_Dummy>::template __enable_implicit<_T1 const&, _T2 const&>()
424 > = false>
425 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
426 pair(_T1 const& __t1, _T2 const& __t2)
427 _NOEXCEPT_(is_nothrow_copy_constructible<first_type>::value &&
428 is_nothrow_copy_constructible<second_type>::value)
429 : first(__t1), second(__t2) {}
430
431 template<class _U1, class _U2, _EnableB<
432 _CheckArgs::template __enable_explicit<_U1, _U2>()
433 > = false>
434 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
435 explicit pair(_U1&& __u1, _U2&& __u2)
436 _NOEXCEPT_((is_nothrow_constructible<first_type, _U1>::value &&
437 is_nothrow_constructible<second_type, _U2>::value))
438 : first(_VSTD::forward<_U1>(__u1)), second(_VSTD::forward<_U2>(__u2)) {}
439
440 template<class _U1, class _U2, _EnableB<
441 _CheckArgs::template __enable_implicit<_U1, _U2>()
442 > = false>
443 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
444 pair(_U1&& __u1, _U2&& __u2)
445 _NOEXCEPT_((is_nothrow_constructible<first_type, _U1>::value &&
446 is_nothrow_constructible<second_type, _U2>::value))
447 : first(_VSTD::forward<_U1>(__u1)), second(_VSTD::forward<_U2>(__u2)) {}
448
449 template<class _U1, class _U2, _EnableB<
450 _CheckArgs::template __enable_explicit<_U1 const&, _U2 const&>()
451 > = false>
452 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
453 explicit pair(pair<_U1, _U2> const& __p)
454 _NOEXCEPT_((is_nothrow_constructible<first_type, _U1 const&>::value &&
455 is_nothrow_constructible<second_type, _U2 const&>::value))
456 : first(__p.first), second(__p.second) {}
457
458 template<class _U1, class _U2, _EnableB<
459 _CheckArgs::template __enable_implicit<_U1 const&, _U2 const&>()
460 > = false>
461 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
462 pair(pair<_U1, _U2> const& __p)
463 _NOEXCEPT_((is_nothrow_constructible<first_type, _U1 const&>::value &&
464 is_nothrow_constructible<second_type, _U2 const&>::value))
465 : first(__p.first), second(__p.second) {}
466
467 template<class _U1, class _U2, _EnableB<
468 _CheckArgs::template __enable_explicit<_U1, _U2>()
469 > = false>
470 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
471 explicit pair(pair<_U1, _U2>&&__p)
472 _NOEXCEPT_((is_nothrow_constructible<first_type, _U1&&>::value &&
473 is_nothrow_constructible<second_type, _U2&&>::value))
474 : first(_VSTD::forward<_U1>(__p.first)), second(_VSTD::forward<_U2>(__p.second)) {}
475
476 template<class _U1, class _U2, _EnableB<
477 _CheckArgs::template __enable_implicit<_U1, _U2>()
478 > = false>
479 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
480 pair(pair<_U1, _U2>&& __p)
481 _NOEXCEPT_((is_nothrow_constructible<first_type, _U1&&>::value &&
482 is_nothrow_constructible<second_type, _U2&&>::value))
483 : first(_VSTD::forward<_U1>(__p.first)), second(_VSTD::forward<_U2>(__p.second)) {}
484
485 template<class _Tuple, _EnableB<
486 _CheckTLC<_Tuple>::template __enable_explicit<_Tuple>()
487 > = false>
488 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
489 explicit pair(_Tuple&& __p)
490 : first(_VSTD::get<0>(_VSTD::forward<_Tuple>(__p))),
491 second(_VSTD::get<1>(_VSTD::forward<_Tuple>(__p))) {}
492
493 template<class _Tuple, _EnableB<
494 _CheckTLC<_Tuple>::template __enable_implicit<_Tuple>()
495 > = false>
496 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
497 pair(_Tuple&& __p)
498 : first(_VSTD::get<0>(_VSTD::forward<_Tuple>(__p))),
499 second(_VSTD::get<1>(_VSTD::forward<_Tuple>(__p))) {}
500
501 template <class... _Args1, class... _Args2>
502 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
503 pair(piecewise_construct_t __pc,
504 tuple<_Args1...> __first_args, tuple<_Args2...> __second_args)
505 _NOEXCEPT_((is_nothrow_constructible<first_type, _Args1...>::value &&
506 is_nothrow_constructible<second_type, _Args2...>::value))
507 : pair(__pc, __first_args, __second_args,
508 typename __make_tuple_indices<sizeof...(_Args1)>::type(),
509 typename __make_tuple_indices<sizeof...(_Args2) >::type()) {}
510
511 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
512 pair& operator=(typename conditional<
513 is_copy_assignable<first_type>::value &&
514 is_copy_assignable<second_type>::value,
515 pair, __nat>::type const& __p)
516 _NOEXCEPT_(is_nothrow_copy_assignable<first_type>::value &&
517 is_nothrow_copy_assignable<second_type>::value)
518 {
519 first = __p.first;
520 second = __p.second;
521 return *this;
522 }
523
524 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
525 pair& operator=(typename conditional<
526 is_move_assignable<first_type>::value &&
527 is_move_assignable<second_type>::value,
528 pair, __nat>::type&& __p)
529 _NOEXCEPT_(is_nothrow_move_assignable<first_type>::value &&
530 is_nothrow_move_assignable<second_type>::value)
531 {
532 first = _VSTD::forward<first_type>(__p.first);
533 second = _VSTD::forward<second_type>(__p.second);
534 return *this;
535 }
536
537 template <class _Tuple, _EnableB<
538 _CheckTLC<_Tuple>::template __enable_assign<_Tuple>()
539 > = false>
540 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
541 pair& operator=(_Tuple&& __p) {
542 first = _VSTD::get<0>(_VSTD::forward<_Tuple>(__p));
543 second = _VSTD::get<1>(_VSTD::forward<_Tuple>(__p));
544 return *this;
545 }
546#endif
547
548 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
549 void
550 swap(pair& __p) _NOEXCEPT_(__is_nothrow_swappable<first_type>::value &&
551 __is_nothrow_swappable<second_type>::value)
552 {
553 using _VSTD::swap;
554 swap(first, __p.first);
555 swap(second, __p.second);
556 }
557private:
558
559#ifndef _LIBCPP_CXX03_LANG
560 template <class... _Args1, class... _Args2, size_t... _I1, size_t... _I2>
561 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
562 pair(piecewise_construct_t,
563 tuple<_Args1...>& __first_args, tuple<_Args2...>& __second_args,
564 __tuple_indices<_I1...>, __tuple_indices<_I2...>);
565#endif
566};
567
568#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
569template<class _T1, class _T2>
570pair(_T1, _T2) -> pair<_T1, _T2>;
571#endif // _LIBCPP_HAS_NO_DEDUCTION_GUIDES
572
573template <class _T1, class _T2>
574inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
575bool
576operator==(const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y)
577{
578 return __x.first == __y.first && __x.second == __y.second;
579}
580
581template <class _T1, class _T2>
582inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
583bool
584operator!=(const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y)
585{
586 return !(__x == __y);
587}
588
589template <class _T1, class _T2>
590inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
591bool
592operator< (const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y)
593{
594 return __x.first < __y.first || (!(__y.first < __x.first) && __x.second < __y.second);
595}
596
597template <class _T1, class _T2>
598inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
599bool
600operator> (const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y)
601{
602 return __y < __x;
603}
604
605template <class _T1, class _T2>
606inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
607bool
608operator>=(const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y)
609{
610 return !(__x < __y);
611}
612
613template <class _T1, class _T2>
614inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
615bool
616operator<=(const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y)
617{
618 return !(__y < __x);
619}
620
621template <class _T1, class _T2>
622inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
623typename enable_if
624<
625 __is_swappable<_T1>::value &&
626 __is_swappable<_T2>::value,
627 void
628>::type
629swap(pair<_T1, _T2>& __x, pair<_T1, _T2>& __y)
630 _NOEXCEPT_((__is_nothrow_swappable<_T1>::value &&
631 __is_nothrow_swappable<_T2>::value))
632{
633 __x.swap(__y);
634}
635
636template <class _Tp>
637struct __unwrap_reference { typedef _LIBCPP_NODEBUG_TYPE _Tp type; };
638
639template <class _Tp>
640struct __unwrap_reference<reference_wrapper<_Tp> > { typedef _LIBCPP_NODEBUG_TYPE _Tp& type; };
641
642#if _LIBCPP_STD_VER > 17
643template <class _Tp>
644struct unwrap_reference : __unwrap_reference<_Tp> { };
645
646template <class _Tp>
647struct unwrap_ref_decay : unwrap_reference<typename decay<_Tp>::type> { };
648#endif // > C++17
649
650template <class _Tp>
651struct __unwrap_ref_decay
652#if _LIBCPP_STD_VER > 17
653 : unwrap_ref_decay<_Tp>
654#else
655 : __unwrap_reference<typename decay<_Tp>::type>
656#endif
657{ };
658
659#ifndef _LIBCPP_CXX03_LANG
660
661template <class _T1, class _T2>
662inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
663pair<typename __unwrap_ref_decay<_T1>::type, typename __unwrap_ref_decay<_T2>::type>
664make_pair(_T1&& __t1, _T2&& __t2)
665{
666 return pair<typename __unwrap_ref_decay<_T1>::type, typename __unwrap_ref_decay<_T2>::type>
667 (_VSTD::forward<_T1>(__t1), _VSTD::forward<_T2>(__t2));
668}
669
670#else // _LIBCPP_CXX03_LANG
671
672template <class _T1, class _T2>
673inline _LIBCPP_INLINE_VISIBILITY
674pair<_T1,_T2>
675make_pair(_T1 __x, _T2 __y)
676{
677 return pair<_T1, _T2>(__x, __y);
678}
679
680#endif // _LIBCPP_CXX03_LANG
681
682template <class _T1, class _T2>
683 struct _LIBCPP_TEMPLATE_VIS tuple_size<pair<_T1, _T2> >
684 : public integral_constant<size_t, 2> {};
685
686template <size_t _Ip, class _T1, class _T2>
687struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, pair<_T1, _T2> >
688{
689 static_assert(_Ip < 2, "Index out of bounds in std::tuple_element<std::pair<T1, T2>>");
690};
691
692template <class _T1, class _T2>
693struct _LIBCPP_TEMPLATE_VIS tuple_element<0, pair<_T1, _T2> >
694{
695 typedef _LIBCPP_NODEBUG_TYPE _T1 type;
696};
697
698template <class _T1, class _T2>
699struct _LIBCPP_TEMPLATE_VIS tuple_element<1, pair<_T1, _T2> >
700{
701 typedef _LIBCPP_NODEBUG_TYPE _T2 type;
702};
703
704template <size_t _Ip> struct __get_pair;
705
706template <>
707struct __get_pair<0>
708{
709 template <class _T1, class _T2>
710 static
711 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
712 _T1&
713 get(pair<_T1, _T2>& __p) _NOEXCEPT {return __p.first;}
714
715 template <class _T1, class _T2>
716 static
717 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
718 const _T1&
719 get(const pair<_T1, _T2>& __p) _NOEXCEPT {return __p.first;}
720
721#ifndef _LIBCPP_CXX03_LANG
722 template <class _T1, class _T2>
723 static
724 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
725 _T1&&
726 get(pair<_T1, _T2>&& __p) _NOEXCEPT {return _VSTD::forward<_T1>(__p.first);}
727
728 template <class _T1, class _T2>
729 static
730 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
731 const _T1&&
732 get(const pair<_T1, _T2>&& __p) _NOEXCEPT {return _VSTD::forward<const _T1>(__p.first);}
733#endif // _LIBCPP_CXX03_LANG
734};
735
736template <>
737struct __get_pair<1>
738{
739 template <class _T1, class _T2>
740 static
741 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
742 _T2&
743 get(pair<_T1, _T2>& __p) _NOEXCEPT {return __p.second;}
744
745 template <class _T1, class _T2>
746 static
747 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
748 const _T2&
749 get(const pair<_T1, _T2>& __p) _NOEXCEPT {return __p.second;}
750
751#ifndef _LIBCPP_CXX03_LANG
752 template <class _T1, class _T2>
753 static
754 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
755 _T2&&
756 get(pair<_T1, _T2>&& __p) _NOEXCEPT {return _VSTD::forward<_T2>(__p.second);}
757
758 template <class _T1, class _T2>
759 static
760 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
761 const _T2&&
762 get(const pair<_T1, _T2>&& __p) _NOEXCEPT {return _VSTD::forward<const _T2>(__p.second);}
763#endif // _LIBCPP_CXX03_LANG
764};
765
766template <size_t _Ip, class _T1, class _T2>
767inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
768typename tuple_element<_Ip, pair<_T1, _T2> >::type&
769get(pair<_T1, _T2>& __p) _NOEXCEPT
770{
771 return __get_pair<_Ip>::get(__p);
772}
773
774template <size_t _Ip, class _T1, class _T2>
775inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
776const typename tuple_element<_Ip, pair<_T1, _T2> >::type&
777get(const pair<_T1, _T2>& __p) _NOEXCEPT
778{
779 return __get_pair<_Ip>::get(__p);
780}
781
782#ifndef _LIBCPP_CXX03_LANG
783template <size_t _Ip, class _T1, class _T2>
784inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
785typename tuple_element<_Ip, pair<_T1, _T2> >::type&&
786get(pair<_T1, _T2>&& __p) _NOEXCEPT
787{
788 return __get_pair<_Ip>::get(_VSTD::move(__p));
789}
790
791template <size_t _Ip, class _T1, class _T2>
792inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
793const typename tuple_element<_Ip, pair<_T1, _T2> >::type&&
794get(const pair<_T1, _T2>&& __p) _NOEXCEPT
795{
796 return __get_pair<_Ip>::get(_VSTD::move(__p));
797}
798#endif // _LIBCPP_CXX03_LANG
799
800#if _LIBCPP_STD_VER > 11
801template <class _T1, class _T2>
802inline _LIBCPP_INLINE_VISIBILITY
803constexpr _T1 & get(pair<_T1, _T2>& __p) _NOEXCEPT
804{
805 return __get_pair<0>::get(__p);
806}
807
808template <class _T1, class _T2>
809inline _LIBCPP_INLINE_VISIBILITY
810constexpr _T1 const & get(pair<_T1, _T2> const& __p) _NOEXCEPT
811{
812 return __get_pair<0>::get(__p);
813}
814
815template <class _T1, class _T2>
816inline _LIBCPP_INLINE_VISIBILITY
817constexpr _T1 && get(pair<_T1, _T2>&& __p) _NOEXCEPT
818{
819 return __get_pair<0>::get(_VSTD::move(__p));
820}
821
822template <class _T1, class _T2>
823inline _LIBCPP_INLINE_VISIBILITY
824constexpr _T1 const && get(pair<_T1, _T2> const&& __p) _NOEXCEPT
825{
826 return __get_pair<0>::get(_VSTD::move(__p));
827}
828
829template <class _T1, class _T2>
830inline _LIBCPP_INLINE_VISIBILITY
831constexpr _T1 & get(pair<_T2, _T1>& __p) _NOEXCEPT
832{
833 return __get_pair<1>::get(__p);
834}
835
836template <class _T1, class _T2>
837inline _LIBCPP_INLINE_VISIBILITY
838constexpr _T1 const & get(pair<_T2, _T1> const& __p) _NOEXCEPT
839{
840 return __get_pair<1>::get(__p);
841}
842
843template <class _T1, class _T2>
844inline _LIBCPP_INLINE_VISIBILITY
845constexpr _T1 && get(pair<_T2, _T1>&& __p) _NOEXCEPT
846{
847 return __get_pair<1>::get(_VSTD::move(__p));
848}
849
850template <class _T1, class _T2>
851inline _LIBCPP_INLINE_VISIBILITY
852constexpr _T1 const && get(pair<_T2, _T1> const&& __p) _NOEXCEPT
853{
854 return __get_pair<1>::get(_VSTD::move(__p));
855}
856
857#endif
858
859#if _LIBCPP_STD_VER > 11
860
861template<class _Tp, _Tp... _Ip>
862struct _LIBCPP_TEMPLATE_VIS integer_sequence
863{
864 typedef _Tp value_type;
865 static_assert( is_integral<_Tp>::value,
866 "std::integer_sequence can only be instantiated with an integral type" );
867 static
868 _LIBCPP_INLINE_VISIBILITY
869 constexpr
870 size_t
871 size() noexcept { return sizeof...(_Ip); }
872};
873
874template<size_t... _Ip>
875 using index_sequence = integer_sequence<size_t, _Ip...>;
876
877#if __has_builtin(__make_integer_seq) && !defined(_LIBCPP_TESTING_FALLBACK_MAKE_INTEGER_SEQUENCE)
878
879template <class _Tp, _Tp _Ep>
880using __make_integer_sequence _LIBCPP_NODEBUG_TYPE = __make_integer_seq<integer_sequence, _Tp, _Ep>;
881
882#else
883
884template<typename _Tp, _Tp _Np> using __make_integer_sequence_unchecked _LIBCPP_NODEBUG_TYPE =
885 typename __detail::__make<_Np>::type::template __convert<integer_sequence, _Tp>;
886
887template <class _Tp, _Tp _Ep>
888struct __make_integer_sequence_checked
889{
890 static_assert(is_integral<_Tp>::value,
891 "std::make_integer_sequence can only be instantiated with an integral type" );
892 static_assert(0 <= _Ep, "std::make_integer_sequence must have a non-negative sequence length");
893 // Workaround GCC bug by preventing bad installations when 0 <= _Ep
894 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68929
895 typedef _LIBCPP_NODEBUG_TYPE __make_integer_sequence_unchecked<_Tp, 0 <= _Ep ? _Ep : 0> type;
896};
897
898template <class _Tp, _Tp _Ep>
899using __make_integer_sequence _LIBCPP_NODEBUG_TYPE = typename __make_integer_sequence_checked<_Tp, _Ep>::type;
900
901#endif
902
903template<class _Tp, _Tp _Np>
904 using make_integer_sequence = __make_integer_sequence<_Tp, _Np>;
905
906template<size_t _Np>
907 using make_index_sequence = make_integer_sequence<size_t, _Np>;
908
909template<class... _Tp>
910 using index_sequence_for = make_index_sequence<sizeof...(_Tp)>;
911
912#endif // _LIBCPP_STD_VER > 11
913
914#if _LIBCPP_STD_VER > 11
915template<class _T1, class _T2 = _T1>
916inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
917_T1 exchange(_T1& __obj, _T2 && __new_value)
918{
919 _T1 __old_value = _VSTD::move(__obj);
920 __obj = _VSTD::forward<_T2>(__new_value);
921 return __old_value;
922}
923#endif // _LIBCPP_STD_VER > 11
924
925#if _LIBCPP_STD_VER > 14
926
927struct _LIBCPP_TYPE_VIS in_place_t {
928 explicit in_place_t() = default;
929};
930_LIBCPP_INLINE_VAR constexpr in_place_t in_place{};
931
932template <class _Tp>
933struct _LIBCPP_TEMPLATE_VIS in_place_type_t {
934 explicit in_place_type_t() = default;
935};
936template <class _Tp>
937_LIBCPP_INLINE_VAR constexpr in_place_type_t<_Tp> in_place_type{};
938
939template <size_t _Idx>
940struct _LIBCPP_TYPE_VIS in_place_index_t {
941 explicit in_place_index_t() = default;
942};
943template <size_t _Idx>
944_LIBCPP_INLINE_VAR constexpr in_place_index_t<_Idx> in_place_index{};
945
946template <class _Tp> struct __is_inplace_type_imp : false_type {};
947template <class _Tp> struct __is_inplace_type_imp<in_place_type_t<_Tp>> : true_type {};
948
949template <class _Tp>
950using __is_inplace_type = __is_inplace_type_imp<__uncvref_t<_Tp>>;
951
952template <class _Tp> struct __is_inplace_index_imp : false_type {};
953template <size_t _Idx> struct __is_inplace_index_imp<in_place_index_t<_Idx>> : true_type {};
954
955template <class _Tp>
956using __is_inplace_index = __is_inplace_index_imp<__uncvref_t<_Tp>>;
957
958#endif // _LIBCPP_STD_VER > 14
959
960template <class _Arg, class _Result>
961struct _LIBCPP_TEMPLATE_VIS unary_function
962{
963 typedef _Arg argument_type;
964 typedef _Result result_type;
965};
966
967template <class _Size>
968inline _LIBCPP_INLINE_VISIBILITY
969_Size
970__loadword(const void* __p)
971{
972 _Size __r;
973 _VSTD::memcpy(&__r, __p, sizeof(__r));
974 return __r;
975}
976
977// We use murmur2 when size_t is 32 bits, and cityhash64 when size_t
978// is 64 bits. This is because cityhash64 uses 64bit x 64bit
979// multiplication, which can be very slow on 32-bit systems.
980template <class _Size, size_t = sizeof(_Size)*__CHAR_BIT__>
981struct __murmur2_or_cityhash;
982
983template <class _Size>
984struct __murmur2_or_cityhash<_Size, 32>
985{
986 inline _Size operator()(const void* __key, _Size __len)
987 _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK;
988};
989
990// murmur2
991template <class _Size>
992_Size
993__murmur2_or_cityhash<_Size, 32>::operator()(const void* __key, _Size __len)
994{
995 const _Size __m = 0x5bd1e995;
996 const _Size __r = 24;
997 _Size __h = __len;
998 const unsigned char* __data = static_cast<const unsigned char*>(__key);
999 for (; __len >= 4; __data += 4, __len -= 4)
1000 {
1001 _Size __k = __loadword<_Size>(__data);
1002 __k *= __m;
1003 __k ^= __k >> __r;
1004 __k *= __m;
1005 __h *= __m;
1006 __h ^= __k;
1007 }
1008 switch (__len)
1009 {
1010 case 3:
1011 __h ^= __data[2] << 16;
1012 _LIBCPP_FALLTHROUGH();
1013 case 2:
1014 __h ^= __data[1] << 8;
1015 _LIBCPP_FALLTHROUGH();
1016 case 1:
1017 __h ^= __data[0];
1018 __h *= __m;
1019 }
1020 __h ^= __h >> 13;
1021 __h *= __m;
1022 __h ^= __h >> 15;
1023 return __h;
1024}
1025
1026template <class _Size>
1027struct __murmur2_or_cityhash<_Size, 64>
1028{
1029 inline _Size operator()(const void* __key, _Size __len) _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK;
1030
1031 private:
1032 // Some primes between 2^63 and 2^64.
1033 static const _Size __k0 = 0xc3a5c85c97cb3127ULL;
1034 static const _Size __k1 = 0xb492b66fbe98f273ULL;
1035 static const _Size __k2 = 0x9ae16a3b2f90404fULL;
1036 static const _Size __k3 = 0xc949d7c7509e6557ULL;
1037
1038 static _Size __rotate(_Size __val, int __shift) {
1039 return __shift == 0 ? __val : ((__val >> __shift) | (__val << (64 - __shift)));
1040 }
1041
1042 static _Size __rotate_by_at_least_1(_Size __val, int __shift) {
1043 return (__val >> __shift) | (__val << (64 - __shift));
1044 }
1045
1046 static _Size __shift_mix(_Size __val) {
1047 return __val ^ (__val >> 47);
1048 }
1049
1050 static _Size __hash_len_16(_Size __u, _Size __v)
1051 _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
1052 {
1053 const _Size __mul = 0x9ddfea08eb382d69ULL;
1054 _Size __a = (__u ^ __v) * __mul;
1055 __a ^= (__a >> 47);
1056 _Size __b = (__v ^ __a) * __mul;
1057 __b ^= (__b >> 47);
1058 __b *= __mul;
1059 return __b;
1060 }
1061
1062 static _Size __hash_len_0_to_16(const char* __s, _Size __len)
1063 _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
1064 {
1065 if (__len > 8) {
1066 const _Size __a = __loadword<_Size>(__s);
1067 const _Size __b = __loadword<_Size>(__s + __len - 8);
1068 return __hash_len_16(__a, __rotate_by_at_least_1(__b + __len, __len)) ^ __b;
1069 }
1070 if (__len >= 4) {
1071 const uint32_t __a = __loadword<uint32_t>(__s);
1072 const uint32_t __b = __loadword<uint32_t>(__s + __len - 4);
1073 return __hash_len_16(__len + (__a << 3), __b);
1074 }
1075 if (__len > 0) {
1076 const unsigned char __a = __s[0];
1077 const unsigned char __b = __s[__len >> 1];
1078 const unsigned char __c = __s[__len - 1];
1079 const uint32_t __y = static_cast<uint32_t>(__a) +
1080 (static_cast<uint32_t>(__b) << 8);
1081 const uint32_t __z = __len + (static_cast<uint32_t>(__c) << 2);
1082 return __shift_mix(__y * __k2 ^ __z * __k3) * __k2;
1083 }
1084 return __k2;
1085 }
1086
1087 static _Size __hash_len_17_to_32(const char *__s, _Size __len)
1088 _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
1089 {
1090 const _Size __a = __loadword<_Size>(__s) * __k1;
1091 const _Size __b = __loadword<_Size>(__s + 8);
1092 const _Size __c = __loadword<_Size>(__s + __len - 8) * __k2;
1093 const _Size __d = __loadword<_Size>(__s + __len - 16) * __k0;
1094 return __hash_len_16(__rotate(__a - __b, 43) + __rotate(__c, 30) + __d,
1095 __a + __rotate(__b ^ __k3, 20) - __c + __len);
1096 }
1097
1098 // Return a 16-byte hash for 48 bytes. Quick and dirty.
1099 // Callers do best to use "random-looking" values for a and b.
1100 static pair<_Size, _Size> __weak_hash_len_32_with_seeds(
1101 _Size __w, _Size __x, _Size __y, _Size __z, _Size __a, _Size __b)
1102 _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
1103 {
1104 __a += __w;
1105 __b = __rotate(__b + __a + __z, 21);
1106 const _Size __c = __a;
1107 __a += __x;
1108 __a += __y;
1109 __b += __rotate(__a, 44);
1110 return pair<_Size, _Size>(__a + __z, __b + __c);
1111 }
1112
1113 // Return a 16-byte hash for s[0] ... s[31], a, and b. Quick and dirty.
1114 static pair<_Size, _Size> __weak_hash_len_32_with_seeds(
1115 const char* __s, _Size __a, _Size __b)
1116 _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
1117 {
1118 return __weak_hash_len_32_with_seeds(__loadword<_Size>(__s),
1119 __loadword<_Size>(__s + 8),
1120 __loadword<_Size>(__s + 16),
1121 __loadword<_Size>(__s + 24),
1122 __a,
1123 __b);
1124 }
1125
1126 // Return an 8-byte hash for 33 to 64 bytes.
1127 static _Size __hash_len_33_to_64(const char *__s, size_t __len)
1128 _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
1129 {
1130 _Size __z = __loadword<_Size>(__s + 24);
1131 _Size __a = __loadword<_Size>(__s) +
1132 (__len + __loadword<_Size>(__s + __len - 16)) * __k0;
1133 _Size __b = __rotate(__a + __z, 52);
1134 _Size __c = __rotate(__a, 37);
1135 __a += __loadword<_Size>(__s + 8);
1136 __c += __rotate(__a, 7);
1137 __a += __loadword<_Size>(__s + 16);
1138 _Size __vf = __a + __z;
1139 _Size __vs = __b + __rotate(__a, 31) + __c;
1140 __a = __loadword<_Size>(__s + 16) + __loadword<_Size>(__s + __len - 32);
1141 __z += __loadword<_Size>(__s + __len - 8);
1142 __b = __rotate(__a + __z, 52);
1143 __c = __rotate(__a, 37);
1144 __a += __loadword<_Size>(__s + __len - 24);
1145 __c += __rotate(__a, 7);
1146 __a += __loadword<_Size>(__s + __len - 16);
1147 _Size __wf = __a + __z;
1148 _Size __ws = __b + __rotate(__a, 31) + __c;
1149 _Size __r = __shift_mix((__vf + __ws) * __k2 + (__wf + __vs) * __k0);
1150 return __shift_mix(__r * __k0 + __vs) * __k2;
1151 }
1152};
1153
1154// cityhash64
1155template <class _Size>
1156_Size
1157__murmur2_or_cityhash<_Size, 64>::operator()(const void* __key, _Size __len)
1158{
1159 const char* __s = static_cast<const char*>(__key);
1160 if (__len <= 32) {
1161 if (__len <= 16) {
1162 return __hash_len_0_to_16(__s, __len);
1163 } else {
1164 return __hash_len_17_to_32(__s, __len);
1165 }
1166 } else if (__len <= 64) {
1167 return __hash_len_33_to_64(__s, __len);
1168 }
1169
1170 // For strings over 64 bytes we hash the end first, and then as we
1171 // loop we keep 56 bytes of state: v, w, x, y, and z.
1172 _Size __x = __loadword<_Size>(__s + __len - 40);
1173 _Size __y = __loadword<_Size>(__s + __len - 16) +
1174 __loadword<_Size>(__s + __len - 56);
1175 _Size __z = __hash_len_16(__loadword<_Size>(__s + __len - 48) + __len,
1176 __loadword<_Size>(__s + __len - 24));
1177 pair<_Size, _Size> __v = __weak_hash_len_32_with_seeds(__s + __len - 64, __len, __z);
1178 pair<_Size, _Size> __w = __weak_hash_len_32_with_seeds(__s + __len - 32, __y + __k1, __x);
1179 __x = __x * __k1 + __loadword<_Size>(__s);
1180
1181 // Decrease len to the nearest multiple of 64, and operate on 64-byte chunks.
1182 __len = (__len - 1) & ~static_cast<_Size>(63);
1183 do {
1184 __x = __rotate(__x + __y + __v.first + __loadword<_Size>(__s + 8), 37) * __k1;
1185 __y = __rotate(__y + __v.second + __loadword<_Size>(__s + 48), 42) * __k1;
1186 __x ^= __w.second;
1187 __y += __v.first + __loadword<_Size>(__s + 40);
1188 __z = __rotate(__z + __w.first, 33) * __k1;
1189 __v = __weak_hash_len_32_with_seeds(__s, __v.second * __k1, __x + __w.first);
1190 __w = __weak_hash_len_32_with_seeds(__s + 32, __z + __w.second,
1191 __y + __loadword<_Size>(__s + 16));
1192 _VSTD::swap(__z, __x);
1193 __s += 64;
1194 __len -= 64;
1195 } while (__len != 0);
1196 return __hash_len_16(
1197 __hash_len_16(__v.first, __w.first) + __shift_mix(__y) * __k1 + __z,
1198 __hash_len_16(__v.second, __w.second) + __x);
1199}
1200
1201template <class _Tp, size_t = sizeof(_Tp) / sizeof(size_t)>
1202struct __scalar_hash;
1203
1204template <class _Tp>
1205struct __scalar_hash<_Tp, 0>
1206 : public unary_function<_Tp, size_t>
1207{
1208 _LIBCPP_INLINE_VISIBILITY
1209 size_t operator()(_Tp __v) const _NOEXCEPT
1210 {
1211 union
1212 {
1213 _Tp __t;
1214 size_t __a;
1215 } __u;
1216 __u.__a = 0;
1217 __u.__t = __v;
1218 return __u.__a;
1219 }
1220};
1221
1222template <class _Tp>
1223struct __scalar_hash<_Tp, 1>
1224 : public unary_function<_Tp, size_t>
1225{
1226 _LIBCPP_INLINE_VISIBILITY
1227 size_t operator()(_Tp __v) const _NOEXCEPT
1228 {
1229 union
1230 {
1231 _Tp __t;
1232 size_t __a;
1233 } __u;
1234 __u.__t = __v;
1235 return __u.__a;
1236 }
1237};
1238
1239template <class _Tp>
1240struct __scalar_hash<_Tp, 2>
1241 : public unary_function<_Tp, size_t>
1242{
1243 _LIBCPP_INLINE_VISIBILITY
1244 size_t operator()(_Tp __v) const _NOEXCEPT
1245 {
1246 union
1247 {
1248 _Tp __t;
1249 struct
1250 {
1251 size_t __a;
1252 size_t __b;
1253 } __s;
1254 } __u;
1255 __u.__t = __v;
1256 return __murmur2_or_cityhash<size_t>()(&__u, sizeof(__u));
1257 }
1258};
1259
1260template <class _Tp>
1261struct __scalar_hash<_Tp, 3>
1262 : public unary_function<_Tp, size_t>
1263{
1264 _LIBCPP_INLINE_VISIBILITY
1265 size_t operator()(_Tp __v) const _NOEXCEPT
1266 {
1267 union
1268 {
1269 _Tp __t;
1270 struct
1271 {
1272 size_t __a;
1273 size_t __b;
1274 size_t __c;
1275 } __s;
1276 } __u;
1277 __u.__t = __v;
1278 return __murmur2_or_cityhash<size_t>()(&__u, sizeof(__u));
1279 }
1280};
1281
1282template <class _Tp>
1283struct __scalar_hash<_Tp, 4>
1284 : public unary_function<_Tp, size_t>
1285{
1286 _LIBCPP_INLINE_VISIBILITY
1287 size_t operator()(_Tp __v) const _NOEXCEPT
1288 {
1289 union
1290 {
1291 _Tp __t;
1292 struct
1293 {
1294 size_t __a;
1295 size_t __b;
1296 size_t __c;
1297 size_t __d;
1298 } __s;
1299 } __u;
1300 __u.__t = __v;
1301 return __murmur2_or_cityhash<size_t>()(&__u, sizeof(__u));
1302 }
1303};
1304
1305struct _PairT {
1306 size_t first;
1307 size_t second;
1308};
1309
1310_LIBCPP_INLINE_VISIBILITY
1311inline size_t __hash_combine(size_t __lhs, size_t __rhs) _NOEXCEPT {
1312 typedef __scalar_hash<_PairT> _HashT;
1313 const _PairT __p = {__lhs, __rhs};
1314 return _HashT()(__p);
1315}
1316
1317template<class _Tp>
1318struct _LIBCPP_TEMPLATE_VIS hash<_Tp*>
1319 : public unary_function<_Tp*, size_t>
1320{
1321 _LIBCPP_INLINE_VISIBILITY
1322 size_t operator()(_Tp* __v) const _NOEXCEPT
1323 {
1324 union
1325 {
1326 _Tp* __t;
1327 size_t __a;
1328 } __u;
1329 __u.__t = __v;
1330 return __murmur2_or_cityhash<size_t>()(&__u, sizeof(__u));
1331 }
1332};
1333
1334
1335template <>
1336struct _LIBCPP_TEMPLATE_VIS hash<bool>
1337 : public unary_function<bool, size_t>
1338{
1339 _LIBCPP_INLINE_VISIBILITY
1340 size_t operator()(bool __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
1341};
1342
1343template <>
1344struct _LIBCPP_TEMPLATE_VIS hash<char>
1345 : public unary_function<char, size_t>
1346{
1347 _LIBCPP_INLINE_VISIBILITY
1348 size_t operator()(char __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
1349};
1350
1351template <>
1352struct _LIBCPP_TEMPLATE_VIS hash<signed char>
1353 : public unary_function<signed char, size_t>
1354{
1355 _LIBCPP_INLINE_VISIBILITY
1356 size_t operator()(signed char __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
1357};
1358
1359template <>
1360struct _LIBCPP_TEMPLATE_VIS hash<unsigned char>
1361 : public unary_function<unsigned char, size_t>
1362{
1363 _LIBCPP_INLINE_VISIBILITY
1364 size_t operator()(unsigned char __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
1365};
1366
1367#ifndef _LIBCPP_NO_HAS_CHAR8_T
1368template <>
1369struct _LIBCPP_TEMPLATE_VIS hash<char8_t>
1370 : public unary_function<char8_t, size_t>
1371{
1372 _LIBCPP_INLINE_VISIBILITY
1373 size_t operator()(char8_t __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
1374};
1375#endif // !_LIBCPP_NO_HAS_CHAR8_T
1376
1377#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
1378
1379template <>
1380struct _LIBCPP_TEMPLATE_VIS hash<char16_t>
1381 : public unary_function<char16_t, size_t>
1382{
1383 _LIBCPP_INLINE_VISIBILITY
1384 size_t operator()(char16_t __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
1385};
1386
1387template <>
1388struct _LIBCPP_TEMPLATE_VIS hash<char32_t>
1389 : public unary_function<char32_t, size_t>
1390{
1391 _LIBCPP_INLINE_VISIBILITY
1392 size_t operator()(char32_t __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
1393};
1394
1395#endif // _LIBCPP_HAS_NO_UNICODE_CHARS
1396
1397template <>
1398struct _LIBCPP_TEMPLATE_VIS hash<wchar_t>
1399 : public unary_function<wchar_t, size_t>
1400{
1401 _LIBCPP_INLINE_VISIBILITY
1402 size_t operator()(wchar_t __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
1403};
1404
1405template <>
1406struct _LIBCPP_TEMPLATE_VIS hash<short>
1407 : public unary_function<short, size_t>
1408{
1409 _LIBCPP_INLINE_VISIBILITY
1410 size_t operator()(short __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
1411};
1412
1413template <>
1414struct _LIBCPP_TEMPLATE_VIS hash<unsigned short>
1415 : public unary_function<unsigned short, size_t>
1416{
1417 _LIBCPP_INLINE_VISIBILITY
1418 size_t operator()(unsigned short __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
1419};
1420
1421template <>
1422struct _LIBCPP_TEMPLATE_VIS hash<int>
1423 : public unary_function<int, size_t>
1424{
1425 _LIBCPP_INLINE_VISIBILITY
1426 size_t operator()(int __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
1427};
1428
1429template <>
1430struct _LIBCPP_TEMPLATE_VIS hash<unsigned int>
1431 : public unary_function<unsigned int, size_t>
1432{
1433 _LIBCPP_INLINE_VISIBILITY
1434 size_t operator()(unsigned int __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
1435};
1436
1437template <>
1438struct _LIBCPP_TEMPLATE_VIS hash<long>
1439 : public unary_function<long, size_t>
1440{
1441 _LIBCPP_INLINE_VISIBILITY
1442 size_t operator()(long __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
1443};
1444
1445template <>
1446struct _LIBCPP_TEMPLATE_VIS hash<unsigned long>
1447 : public unary_function<unsigned long, size_t>
1448{
1449 _LIBCPP_INLINE_VISIBILITY
1450 size_t operator()(unsigned long __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
1451};
1452
1453template <>
1454struct _LIBCPP_TEMPLATE_VIS hash<long long>
1455 : public __scalar_hash<long long>
1456{
1457};
1458
1459template <>
1460struct _LIBCPP_TEMPLATE_VIS hash<unsigned long long>
1461 : public __scalar_hash<unsigned long long>
1462{
1463};
1464
1465#ifndef _LIBCPP_HAS_NO_INT128
1466
1467template <>
1468struct _LIBCPP_TEMPLATE_VIS hash<__int128_t>
1469 : public __scalar_hash<__int128_t>
1470{
1471};
1472
1473template <>
1474struct _LIBCPP_TEMPLATE_VIS hash<__uint128_t>
1475 : public __scalar_hash<__uint128_t>
1476{
1477};
1478
1479#endif
1480
1481template <>
1482struct _LIBCPP_TEMPLATE_VIS hash<float>
1483 : public __scalar_hash<float>
1484{
1485 _LIBCPP_INLINE_VISIBILITY
1486 size_t operator()(float __v) const _NOEXCEPT
1487 {
1488 // -0.0 and 0.0 should return same hash
1489 if (__v == 0.0f)
1490 return 0;
1491 return __scalar_hash<float>::operator()(__v);
1492 }
1493};
1494
1495template <>
1496struct _LIBCPP_TEMPLATE_VIS hash<double>
1497 : public __scalar_hash<double>
1498{
1499 _LIBCPP_INLINE_VISIBILITY
1500 size_t operator()(double __v) const _NOEXCEPT
1501 {
1502 // -0.0 and 0.0 should return same hash
1503 if (__v == 0.0)
1504 return 0;
1505 return __scalar_hash<double>::operator()(__v);
1506 }
1507};
1508
1509template <>
1510struct _LIBCPP_TEMPLATE_VIS hash<long double>
1511 : public __scalar_hash<long double>
1512{
1513 _LIBCPP_INLINE_VISIBILITY
1514 size_t operator()(long double __v) const _NOEXCEPT
1515 {
1516 // -0.0 and 0.0 should return same hash
1517 if (__v == 0.0L)
1518 return 0;
1519#if defined(__i386__) || (defined(__x86_64__) && defined(__ILP32__))
1520 // Zero out padding bits
1521 union
1522 {
1523 long double __t;
1524 struct
1525 {
1526 size_t __a;
1527 size_t __b;
1528 size_t __c;
1529 size_t __d;
1530 } __s;
1531 } __u;
1532 __u.__s.__a = 0;
1533 __u.__s.__b = 0;
1534 __u.__s.__c = 0;
1535 __u.__s.__d = 0;
1536 __u.__t = __v;
1537 return __u.__s.__a ^ __u.__s.__b ^ __u.__s.__c ^ __u.__s.__d;
1538#elif defined(__x86_64__)
1539 // Zero out padding bits
1540 union
1541 {
1542 long double __t;
1543 struct
1544 {
1545 size_t __a;
1546 size_t __b;
1547 } __s;
1548 } __u;
1549 __u.__s.__a = 0;
1550 __u.__s.__b = 0;
1551 __u.__t = __v;
1552 return __u.__s.__a ^ __u.__s.__b;
1553#else
1554 return __scalar_hash<long double>::operator()(__v);
1555#endif
1556 }
1557};
1558
1559#if _LIBCPP_STD_VER > 11
1560
1561template <class _Tp, bool = is_enum<_Tp>::value>
1562struct _LIBCPP_TEMPLATE_VIS __enum_hash
1563 : public unary_function<_Tp, size_t>
1564{
1565 _LIBCPP_INLINE_VISIBILITY
1566 size_t operator()(_Tp __v) const _NOEXCEPT
1567 {
1568 typedef typename underlying_type<_Tp>::type type;
1569 return hash<type>{}(static_cast<type>(__v));
1570 }
1571};
1572template <class _Tp>
1573struct _LIBCPP_TEMPLATE_VIS __enum_hash<_Tp, false> {
1574 __enum_hash() = delete;
1575 __enum_hash(__enum_hash const&) = delete;
1576 __enum_hash& operator=(__enum_hash const&) = delete;
1577};
1578
1579template <class _Tp>
1580struct _LIBCPP_TEMPLATE_VIS hash : public __enum_hash<_Tp>
1581{
1582};
1583#endif
1584
1585#if _LIBCPP_STD_VER > 14
1586
1587template <>
1588struct _LIBCPP_TEMPLATE_VIS hash<nullptr_t>
1589 : public unary_function<nullptr_t, size_t>
1590{
1591 _LIBCPP_INLINE_VISIBILITY
1592 size_t operator()(nullptr_t) const _NOEXCEPT {
1593 return 662607004ull;
1594 }
1595};
1596#endif
1597
1598#ifndef _LIBCPP_CXX03_LANG
1599template <class _Key, class _Hash>
1600using __check_hash_requirements _LIBCPP_NODEBUG_TYPE = integral_constant<bool,
1601 is_copy_constructible<_Hash>::value &&
1602 is_move_constructible<_Hash>::value &&
1603 __invokable_r<size_t, _Hash, _Key const&>::value
1604>;
1605
1606template <class _Key, class _Hash = hash<_Key> >
1607using __has_enabled_hash _LIBCPP_NODEBUG_TYPE = integral_constant<bool,
1608 __check_hash_requirements<_Key, _Hash>::value &&
1609 is_default_constructible<_Hash>::value
1610>;
1611
1612#if _LIBCPP_STD_VER > 14
1613template <class _Type, class>
1614using __enable_hash_helper_imp _LIBCPP_NODEBUG_TYPE = _Type;
1615
1616template <class _Type, class ..._Keys>
1617using __enable_hash_helper _LIBCPP_NODEBUG_TYPE = __enable_hash_helper_imp<_Type,
1618 typename enable_if<__all<__has_enabled_hash<_Keys>::value...>::value>::type
1619>;
1620#else
1621template <class _Type, class ...>
1622using __enable_hash_helper _LIBCPP_NODEBUG_TYPE = _Type;
1623#endif
1624
1625#endif // !_LIBCPP_CXX03_LANG
1626
1627_LIBCPP_END_NAMESPACE_STD
1628229
1629#endif // _LIBCPP_UTILITY
230#endif // _LIBCPP_UTILITY
lib/libcxx/include/valarray+126-105
......@@ -340,11 +340,11 @@ template <class T> unspecified2 end(const valarray<T>& v);
340340*/
341341
342342#include <__config>
343#include <cstddef>
344#include <cmath>
345#include <initializer_list>
346343#include <algorithm>
344#include <cmath>
345#include <cstddef>
347346#include <functional>
347#include <initializer_list>
348348#include <new>
349349
350350#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
......@@ -354,7 +354,6 @@ template <class T> unspecified2 end(const valarray<T>& v);
354354_LIBCPP_PUSH_MACROS
355355#include <__undef_macros>
356356
357
358357_LIBCPP_BEGIN_NAMESPACE_STD
359358
360359template<class _Tp> class _LIBCPP_TEMPLATE_VIS valarray;
......@@ -413,8 +412,8 @@ end(const valarray<_Tp>& __v);
413412template <class _Op, class _A0>
414413struct _UnaryOp
415414{
416 typedef typename _Op::result_type result_type;
417 typedef typename _A0::value_type value_type;
415 typedef typename _Op::__result_type __result_type;
416 typedef typename decay<__result_type>::type value_type;
418417
419418 _Op __op_;
420419 _A0 __a0_;
......@@ -423,7 +422,7 @@ struct _UnaryOp
423422 _UnaryOp(const _Op& __op, const _A0& __a0) : __op_(__op), __a0_(__a0) {}
424423
425424 _LIBCPP_INLINE_VISIBILITY
426 result_type operator[](size_t __i) const {return __op_(__a0_[__i]);}
425 __result_type operator[](size_t __i) const {return __op_(__a0_[__i]);}
427426
428427 _LIBCPP_INLINE_VISIBILITY
429428 size_t size() const {return __a0_.size();}
......@@ -432,8 +431,8 @@ struct _UnaryOp
432431template <class _Op, class _A0, class _A1>
433432struct _BinaryOp
434433{
435 typedef typename _Op::result_type result_type;
436 typedef typename _A0::value_type value_type;
434 typedef typename _Op::__result_type __result_type;
435 typedef typename decay<__result_type>::type value_type;
437436
438437 _Op __op_;
439438 _A0 __a0_;
......@@ -444,7 +443,7 @@ struct _BinaryOp
444443 : __op_(__op), __a0_(__a0), __a1_(__a1) {}
445444
446445 _LIBCPP_INLINE_VISIBILITY
447 value_type operator[](size_t __i) const {return __op_(__a0_[__i], __a1_[__i]);}
446 __result_type operator[](size_t __i) const {return __op_(__a0_[__i], __a1_[__i]);}
448447
449448 _LIBCPP_INLINE_VISIBILITY
450449 size_t size() const {return __a0_.size();}
......@@ -455,7 +454,7 @@ class __scalar_expr
455454{
456455public:
457456 typedef _Tp value_type;
458 typedef const _Tp& result_type;
457 typedef const _Tp& __result_type;
459458private:
460459 const value_type& __t_;
461460 size_t __s_;
......@@ -464,50 +463,56 @@ public:
464463 explicit __scalar_expr(const value_type& __t, size_t __s) : __t_(__t), __s_(__s) {}
465464
466465 _LIBCPP_INLINE_VISIBILITY
467 result_type operator[](size_t) const {return __t_;}
466 __result_type operator[](size_t) const {return __t_;}
468467
469468 _LIBCPP_INLINE_VISIBILITY
470469 size_t size() const {return __s_;}
471470};
472471
473472template <class _Tp>
474struct __unary_plus : unary_function<_Tp, _Tp>
473struct __unary_plus
475474{
475 typedef _Tp __result_type;
476476 _LIBCPP_INLINE_VISIBILITY
477477 _Tp operator()(const _Tp& __x) const
478478 {return +__x;}
479479};
480480
481481template <class _Tp>
482struct __bit_not : unary_function<_Tp, _Tp>
482struct __bit_not
483483{
484 typedef _Tp __result_type;
484485 _LIBCPP_INLINE_VISIBILITY
485486 _Tp operator()(const _Tp& __x) const
486487 {return ~__x;}
487488};
488489
489490template <class _Tp>
490struct __bit_shift_left : binary_function<_Tp, _Tp, _Tp>
491struct __bit_shift_left
491492{
493 typedef _Tp __result_type;
492494 _LIBCPP_INLINE_VISIBILITY
493495 _Tp operator()(const _Tp& __x, const _Tp& __y) const
494496 {return __x << __y;}
495497};
496498
497499template <class _Tp>
498struct __bit_shift_right : binary_function<_Tp, _Tp, _Tp>
500struct __bit_shift_right
499501{
502 typedef _Tp __result_type;
500503 _LIBCPP_INLINE_VISIBILITY
501504 _Tp operator()(const _Tp& __x, const _Tp& __y) const
502505 {return __x >> __y;}
503506};
504507
505508template <class _Tp, class _Fp>
506struct __apply_expr : unary_function<_Tp, _Tp>
509struct __apply_expr
507510{
508511private:
509512 _Fp __f_;
510513public:
514 typedef _Tp __result_type;
515
511516 _LIBCPP_INLINE_VISIBILITY
512517 explicit __apply_expr(_Fp __f) : __f_(__f) {}
513518
......@@ -517,128 +522,144 @@ public:
517522};
518523
519524template <class _Tp>
520struct __abs_expr : unary_function<_Tp, _Tp>
525struct __abs_expr
521526{
527 typedef _Tp __result_type;
522528 _LIBCPP_INLINE_VISIBILITY
523529 _Tp operator()(const _Tp& __x) const
524530 {return abs(__x);}
525531};
526532
527533template <class _Tp>
528struct __acos_expr : unary_function<_Tp, _Tp>
534struct __acos_expr
529535{
536 typedef _Tp __result_type;
530537 _LIBCPP_INLINE_VISIBILITY
531538 _Tp operator()(const _Tp& __x) const
532539 {return acos(__x);}
533540};
534541
535542template <class _Tp>
536struct __asin_expr : unary_function<_Tp, _Tp>
543struct __asin_expr
537544{
545 typedef _Tp __result_type;
538546 _LIBCPP_INLINE_VISIBILITY
539547 _Tp operator()(const _Tp& __x) const
540548 {return asin(__x);}
541549};
542550
543551template <class _Tp>
544struct __atan_expr : unary_function<_Tp, _Tp>
552struct __atan_expr
545553{
554 typedef _Tp __result_type;
546555 _LIBCPP_INLINE_VISIBILITY
547556 _Tp operator()(const _Tp& __x) const
548557 {return atan(__x);}
549558};
550559
551560template <class _Tp>
552struct __atan2_expr : binary_function<_Tp, _Tp, _Tp>
561struct __atan2_expr
553562{
563 typedef _Tp __result_type;
554564 _LIBCPP_INLINE_VISIBILITY
555565 _Tp operator()(const _Tp& __x, const _Tp& __y) const
556566 {return atan2(__x, __y);}
557567};
558568
559569template <class _Tp>
560struct __cos_expr : unary_function<_Tp, _Tp>
570struct __cos_expr
561571{
572 typedef _Tp __result_type;
562573 _LIBCPP_INLINE_VISIBILITY
563574 _Tp operator()(const _Tp& __x) const
564575 {return cos(__x);}
565576};
566577
567578template <class _Tp>
568struct __cosh_expr : unary_function<_Tp, _Tp>
579struct __cosh_expr
569580{
581 typedef _Tp __result_type;
570582 _LIBCPP_INLINE_VISIBILITY
571583 _Tp operator()(const _Tp& __x) const
572584 {return cosh(__x);}
573585};
574586
575587template <class _Tp>
576struct __exp_expr : unary_function<_Tp, _Tp>
588struct __exp_expr
577589{
590 typedef _Tp __result_type;
578591 _LIBCPP_INLINE_VISIBILITY
579592 _Tp operator()(const _Tp& __x) const
580593 {return exp(__x);}
581594};
582595
583596template <class _Tp>
584struct __log_expr : unary_function<_Tp, _Tp>
597struct __log_expr
585598{
599 typedef _Tp __result_type;
586600 _LIBCPP_INLINE_VISIBILITY
587601 _Tp operator()(const _Tp& __x) const
588602 {return log(__x);}
589603};
590604
591605template <class _Tp>
592struct __log10_expr : unary_function<_Tp, _Tp>
606struct __log10_expr
593607{
608 typedef _Tp __result_type;
594609 _LIBCPP_INLINE_VISIBILITY
595610 _Tp operator()(const _Tp& __x) const
596611 {return log10(__x);}
597612};
598613
599614template <class _Tp>
600struct __pow_expr : binary_function<_Tp, _Tp, _Tp>
615struct __pow_expr
601616{
617 typedef _Tp __result_type;
602618 _LIBCPP_INLINE_VISIBILITY
603619 _Tp operator()(const _Tp& __x, const _Tp& __y) const
604620 {return pow(__x, __y);}
605621};
606622
607623template <class _Tp>
608struct __sin_expr : unary_function<_Tp, _Tp>
624struct __sin_expr
609625{
626 typedef _Tp __result_type;
610627 _LIBCPP_INLINE_VISIBILITY
611628 _Tp operator()(const _Tp& __x) const
612629 {return sin(__x);}
613630};
614631
615632template <class _Tp>
616struct __sinh_expr : unary_function<_Tp, _Tp>
633struct __sinh_expr
617634{
635 typedef _Tp __result_type;
618636 _LIBCPP_INLINE_VISIBILITY
619637 _Tp operator()(const _Tp& __x) const
620638 {return sinh(__x);}
621639};
622640
623641template <class _Tp>
624struct __sqrt_expr : unary_function<_Tp, _Tp>
642struct __sqrt_expr
625643{
644 typedef _Tp __result_type;
626645 _LIBCPP_INLINE_VISIBILITY
627646 _Tp operator()(const _Tp& __x) const
628647 {return sqrt(__x);}
629648};
630649
631650template <class _Tp>
632struct __tan_expr : unary_function<_Tp, _Tp>
651struct __tan_expr
633652{
653 typedef _Tp __result_type;
634654 _LIBCPP_INLINE_VISIBILITY
635655 _Tp operator()(const _Tp& __x) const
636656 {return tan(__x);}
637657};
638658
639659template <class _Tp>
640struct __tanh_expr : unary_function<_Tp, _Tp>
660struct __tanh_expr
641661{
662 typedef _Tp __result_type;
642663 _LIBCPP_INLINE_VISIBILITY
643664 _Tp operator()(const _Tp& __x) const
644665 {return tanh(__x);}
......@@ -650,7 +671,7 @@ class __slice_expr
650671 typedef typename remove_reference<_ValExpr>::type _RmExpr;
651672public:
652673 typedef typename _RmExpr::value_type value_type;
653 typedef value_type result_type;
674 typedef value_type __result_type;
654675
655676private:
656677 _ValExpr __expr_;
......@@ -668,7 +689,7 @@ private:
668689public:
669690
670691 _LIBCPP_INLINE_VISIBILITY
671 result_type operator[](size_t __i) const
692 __result_type operator[](size_t __i) const
672693 {return __expr_[__start_ + __i * __stride_];}
673694
674695 _LIBCPP_INLINE_VISIBILITY
......@@ -690,7 +711,7 @@ class __shift_expr
690711 typedef typename remove_reference<_ValExpr>::type _RmExpr;
691712public:
692713 typedef typename _RmExpr::value_type value_type;
693 typedef value_type result_type;
714 typedef value_type __result_type;
694715
695716private:
696717 _ValExpr __expr_;
......@@ -714,7 +735,7 @@ private:
714735public:
715736
716737 _LIBCPP_INLINE_VISIBILITY
717 result_type operator[](size_t __j) const
738 __result_type operator[](size_t __j) const
718739 {
719740 ptrdiff_t __i = static_cast<ptrdiff_t>(__j);
720741 ptrdiff_t __m = (__sn_ * __i - __ul_) >> _Np;
......@@ -733,7 +754,7 @@ class __cshift_expr
733754 typedef typename remove_reference<_ValExpr>::type _RmExpr;
734755public:
735756 typedef typename _RmExpr::value_type value_type;
736 typedef value_type result_type;
757 typedef value_type __result_type;
737758
738759private:
739760 _ValExpr __expr_;
......@@ -764,7 +785,7 @@ private:
764785public:
765786
766787 _LIBCPP_INLINE_VISIBILITY
767 result_type operator[](size_t __i) const
788 __result_type operator[](size_t __i) const
768789 {
769790 if (__i < __m_)
770791 return __expr_[__i + __o1_];
......@@ -794,7 +815,7 @@ class _LIBCPP_TEMPLATE_VIS valarray
794815{
795816public:
796817 typedef _Tp value_type;
797 typedef _Tp result_type;
818 typedef _Tp __result_type;
798819
799820private:
800821 value_type* __begin_;
......@@ -814,7 +835,7 @@ public:
814835 _LIBCPP_INLINE_VISIBILITY
815836 valarray(valarray&& __v) _NOEXCEPT;
816837 valarray(initializer_list<value_type> __il);
817#endif // _LIBCPP_CXX03_LANG
838#endif // _LIBCPP_CXX03_LANG
818839 valarray(const slice_array<value_type>& __sa);
819840 valarray(const gslice_array<value_type>& __ga);
820841 valarray(const mask_array<value_type>& __ma);
......@@ -829,7 +850,7 @@ public:
829850 valarray& operator=(valarray&& __v) _NOEXCEPT;
830851 _LIBCPP_INLINE_VISIBILITY
831852 valarray& operator=(initializer_list<value_type>);
832#endif // _LIBCPP_CXX03_LANG
853#endif // _LIBCPP_CXX03_LANG
833854 _LIBCPP_INLINE_VISIBILITY
834855 valarray& operator=(const value_type& __x);
835856 _LIBCPP_INLINE_VISIBILITY
......@@ -865,7 +886,7 @@ public:
865886 __val_expr<__indirect_expr<const valarray&> > operator[](gslice&& __gs) const;
866887 _LIBCPP_INLINE_VISIBILITY
867888 gslice_array<value_type> operator[](gslice&& __gs);
868#endif // _LIBCPP_CXX03_LANG
889#endif // _LIBCPP_CXX03_LANG
869890 _LIBCPP_INLINE_VISIBILITY
870891 __val_expr<__mask_expr<const valarray&> > operator[](const valarray<bool>& __vb) const;
871892 _LIBCPP_INLINE_VISIBILITY
......@@ -875,7 +896,7 @@ public:
875896 __val_expr<__mask_expr<const valarray&> > operator[](valarray<bool>&& __vb) const;
876897 _LIBCPP_INLINE_VISIBILITY
877898 mask_array<value_type> operator[](valarray<bool>&& __vb);
878#endif // _LIBCPP_CXX03_LANG
899#endif // _LIBCPP_CXX03_LANG
879900 _LIBCPP_INLINE_VISIBILITY
880901 __val_expr<__indirect_expr<const valarray&> > operator[](const valarray<size_t>& __vs) const;
881902 _LIBCPP_INLINE_VISIBILITY
......@@ -885,7 +906,7 @@ public:
885906 __val_expr<__indirect_expr<const valarray&> > operator[](valarray<size_t>&& __vs) const;
886907 _LIBCPP_INLINE_VISIBILITY
887908 indirect_array<value_type> operator[](valarray<size_t>&& __vs);
888#endif // _LIBCPP_CXX03_LANG
909#endif // _LIBCPP_CXX03_LANG
889910
890911 // unary operators:
891912 valarray operator+() const;
......@@ -1065,8 +1086,8 @@ _LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void valarray<size_t>::resize(size_t, s
10651086template <class _Op, class _Tp>
10661087struct _UnaryOp<_Op, valarray<_Tp> >
10671088{
1068 typedef typename _Op::result_type result_type;
1069 typedef _Tp value_type;
1089 typedef typename _Op::__result_type __result_type;
1090 typedef typename decay<__result_type>::type value_type;
10701091
10711092 _Op __op_;
10721093 const valarray<_Tp>& __a0_;
......@@ -1075,7 +1096,7 @@ struct _UnaryOp<_Op, valarray<_Tp> >
10751096 _UnaryOp(const _Op& __op, const valarray<_Tp>& __a0) : __op_(__op), __a0_(__a0) {}
10761097
10771098 _LIBCPP_INLINE_VISIBILITY
1078 result_type operator[](size_t __i) const {return __op_(__a0_[__i]);}
1099 __result_type operator[](size_t __i) const {return __op_(__a0_[__i]);}
10791100
10801101 _LIBCPP_INLINE_VISIBILITY
10811102 size_t size() const {return __a0_.size();}
......@@ -1084,8 +1105,8 @@ struct _UnaryOp<_Op, valarray<_Tp> >
10841105template <class _Op, class _Tp, class _A1>
10851106struct _BinaryOp<_Op, valarray<_Tp>, _A1>
10861107{
1087 typedef typename _Op::result_type result_type;
1088 typedef _Tp value_type;
1108 typedef typename _Op::__result_type __result_type;
1109 typedef typename decay<__result_type>::type value_type;
10891110
10901111 _Op __op_;
10911112 const valarray<_Tp>& __a0_;
......@@ -1096,7 +1117,7 @@ struct _BinaryOp<_Op, valarray<_Tp>, _A1>
10961117 : __op_(__op), __a0_(__a0), __a1_(__a1) {}
10971118
10981119 _LIBCPP_INLINE_VISIBILITY
1099 value_type operator[](size_t __i) const {return __op_(__a0_[__i], __a1_[__i]);}
1120 __result_type operator[](size_t __i) const {return __op_(__a0_[__i], __a1_[__i]);}
11001121
11011122 _LIBCPP_INLINE_VISIBILITY
11021123 size_t size() const {return __a0_.size();}
......@@ -1105,8 +1126,8 @@ struct _BinaryOp<_Op, valarray<_Tp>, _A1>
11051126template <class _Op, class _A0, class _Tp>
11061127struct _BinaryOp<_Op, _A0, valarray<_Tp> >
11071128{
1108 typedef typename _Op::result_type result_type;
1109 typedef _Tp value_type;
1129 typedef typename _Op::__result_type __result_type;
1130 typedef typename decay<__result_type>::type value_type;
11101131
11111132 _Op __op_;
11121133 _A0 __a0_;
......@@ -1117,7 +1138,7 @@ struct _BinaryOp<_Op, _A0, valarray<_Tp> >
11171138 : __op_(__op), __a0_(__a0), __a1_(__a1) {}
11181139
11191140 _LIBCPP_INLINE_VISIBILITY
1120 value_type operator[](size_t __i) const {return __op_(__a0_[__i], __a1_[__i]);}
1141 __result_type operator[](size_t __i) const {return __op_(__a0_[__i], __a1_[__i]);}
11211142
11221143 _LIBCPP_INLINE_VISIBILITY
11231144 size_t size() const {return __a0_.size();}
......@@ -1126,8 +1147,8 @@ struct _BinaryOp<_Op, _A0, valarray<_Tp> >
11261147template <class _Op, class _Tp>
11271148struct _BinaryOp<_Op, valarray<_Tp>, valarray<_Tp> >
11281149{
1129 typedef typename _Op::result_type result_type;
1130 typedef _Tp value_type;
1150 typedef typename _Op::__result_type __result_type;
1151 typedef typename decay<__result_type>::type value_type;
11311152
11321153 _Op __op_;
11331154 const valarray<_Tp>& __a0_;
......@@ -1138,7 +1159,7 @@ struct _BinaryOp<_Op, valarray<_Tp>, valarray<_Tp> >
11381159 : __op_(__op), __a0_(__a0), __a1_(__a1) {}
11391160
11401161 _LIBCPP_INLINE_VISIBILITY
1141 value_type operator[](size_t __i) const {return __op_(__a0_[__i], __a1_[__i]);}
1162 __result_type operator[](size_t __i) const {return __op_(__a0_[__i], __a1_[__i]);}
11421163
11431164 _LIBCPP_INLINE_VISIBILITY
11441165 size_t size() const {return __a0_.size();}
......@@ -1518,7 +1539,7 @@ public:
15181539 __stride_(move(__stride))
15191540 {__init(__start);}
15201541
1521#endif // _LIBCPP_CXX03_LANG
1542#endif // _LIBCPP_CXX03_LANG
15221543
15231544 _LIBCPP_INLINE_VISIBILITY
15241545 size_t start() const {return __1d_.size() ? __1d_[0] : 0;}
......@@ -1668,7 +1689,7 @@ private:
16681689 : __vp_(const_cast<value_type*>(__v.__begin_)),
16691690 __1d_(move(__gs.__1d_))
16701691 {}
1671#endif // _LIBCPP_CXX03_LANG
1692#endif // _LIBCPP_CXX03_LANG
16721693
16731694 template <class> friend class valarray;
16741695};
......@@ -2199,7 +2220,7 @@ class __mask_expr
21992220 typedef typename remove_reference<_ValExpr>::type _RmExpr;
22002221public:
22012222 typedef typename _RmExpr::value_type value_type;
2202 typedef value_type result_type;
2223 typedef value_type __result_type;
22032224
22042225private:
22052226 _ValExpr __expr_;
......@@ -2218,7 +2239,7 @@ private:
22182239
22192240public:
22202241 _LIBCPP_INLINE_VISIBILITY
2221 result_type operator[](size_t __i) const
2242 __result_type operator[](size_t __i) const
22222243 {return __expr_[__1d_[__i]];}
22232244
22242245 _LIBCPP_INLINE_VISIBILITY
......@@ -2363,7 +2384,7 @@ private:
23632384 __1d_(move(__ia))
23642385 {}
23652386
2366#endif // _LIBCPP_CXX03_LANG
2387#endif // _LIBCPP_CXX03_LANG
23672388
23682389 template <class> friend class valarray;
23692390};
......@@ -2562,7 +2583,7 @@ class __indirect_expr
25622583 typedef typename remove_reference<_ValExpr>::type _RmExpr;
25632584public:
25642585 typedef typename _RmExpr::value_type value_type;
2565 typedef value_type result_type;
2586 typedef value_type __result_type;
25662587
25672588private:
25682589 _ValExpr __expr_;
......@@ -2582,11 +2603,11 @@ private:
25822603 __1d_(move(__ia))
25832604 {}
25842605
2585#endif // _LIBCPP_CXX03_LANG
2606#endif // _LIBCPP_CXX03_LANG
25862607
25872608public:
25882609 _LIBCPP_INLINE_VISIBILITY
2589 result_type operator[](size_t __i) const
2610 __result_type operator[](size_t __i) const
25902611 {return __expr_[__1d_[__i]];}
25912612
25922613 _LIBCPP_INLINE_VISIBILITY
......@@ -2604,13 +2625,13 @@ class __val_expr
26042625 _ValExpr __expr_;
26052626public:
26062627 typedef typename _RmExpr::value_type value_type;
2607 typedef typename _RmExpr::result_type result_type;
2628 typedef typename _RmExpr::__result_type __result_type;
26082629
26092630 _LIBCPP_INLINE_VISIBILITY
26102631 explicit __val_expr(const _RmExpr& __e) : __expr_(__e) {}
26112632
26122633 _LIBCPP_INLINE_VISIBILITY
2613 result_type operator[](size_t __i) const
2634 __result_type operator[](size_t __i) const
26142635 {return __expr_[__i];}
26152636
26162637 _LIBCPP_INLINE_VISIBILITY
......@@ -2673,29 +2694,29 @@ public:
26732694 return __val_expr<_NewExpr>(_NewExpr(logical_not<value_type>(), __expr_));
26742695 }
26752696
2676 operator valarray<result_type>() const;
2697 operator valarray<__result_type>() const;
26772698
26782699 _LIBCPP_INLINE_VISIBILITY
26792700 size_t size() const {return __expr_.size();}
26802701
26812702 _LIBCPP_INLINE_VISIBILITY
2682 result_type sum() const
2703 __result_type sum() const
26832704 {
26842705 size_t __n = __expr_.size();
2685 result_type __r = __n ? __expr_[0] : result_type();
2706 __result_type __r = __n ? __expr_[0] : __result_type();
26862707 for (size_t __i = 1; __i < __n; ++__i)
26872708 __r += __expr_[__i];
26882709 return __r;
26892710 }
26902711
26912712 _LIBCPP_INLINE_VISIBILITY
2692 result_type min() const
2713 __result_type min() const
26932714 {
26942715 size_t __n = size();
2695 result_type __r = __n ? (*this)[0] : result_type();
2716 __result_type __r = __n ? (*this)[0] : __result_type();
26962717 for (size_t __i = 1; __i < __n; ++__i)
26972718 {
2698 result_type __x = __expr_[__i];
2719 __result_type __x = __expr_[__i];
26992720 if (__x < __r)
27002721 __r = __x;
27012722 }
......@@ -2703,13 +2724,13 @@ public:
27032724 }
27042725
27052726 _LIBCPP_INLINE_VISIBILITY
2706 result_type max() const
2727 __result_type max() const
27072728 {
27082729 size_t __n = size();
2709 result_type __r = __n ? (*this)[0] : result_type();
2730 __result_type __r = __n ? (*this)[0] : __result_type();
27102731 for (size_t __i = 1; __i < __n; ++__i)
27112732 {
2712 result_type __x = __expr_[__i];
2733 __result_type __x = __expr_[__i];
27132734 if (__r < __x)
27142735 __r = __x;
27152736 }
......@@ -2744,16 +2765,16 @@ public:
27442765};
27452766
27462767template<class _ValExpr>
2747__val_expr<_ValExpr>::operator valarray<__val_expr::result_type>() const
2768__val_expr<_ValExpr>::operator valarray<__val_expr::__result_type>() const
27482769{
2749 valarray<result_type> __r;
2770 valarray<__result_type> __r;
27502771 size_t __n = __expr_.size();
27512772 if (__n)
27522773 {
27532774 __r.__begin_ =
2754 __r.__end_ = allocator<result_type>().allocate(__n);
2775 __r.__end_ = allocator<__result_type>().allocate(__n);
27552776 for (size_t __i = 0; __i != __n; ++__r.__end_, ++__i)
2756 ::new ((void*)__r.__end_) result_type(__expr_[__i]);
2777 ::new ((void*)__r.__end_) __result_type(__expr_[__i]);
27572778 }
27582779 return __r;
27592780}
......@@ -2772,7 +2793,7 @@ valarray<_Tp>::valarray(size_t __n)
27722793#ifndef _LIBCPP_NO_EXCEPTIONS
27732794 try
27742795 {
2775#endif // _LIBCPP_NO_EXCEPTIONS
2796#endif // _LIBCPP_NO_EXCEPTIONS
27762797 for (size_t __n_left = __n; __n_left; --__n_left, ++__end_)
27772798 ::new ((void*)__end_) value_type();
27782799#ifndef _LIBCPP_NO_EXCEPTIONS
......@@ -2782,7 +2803,7 @@ valarray<_Tp>::valarray(size_t __n)
27822803 __clear(__n);
27832804 throw;
27842805 }
2785#endif // _LIBCPP_NO_EXCEPTIONS
2806#endif // _LIBCPP_NO_EXCEPTIONS
27862807 }
27872808}
27882809
......@@ -2806,7 +2827,7 @@ valarray<_Tp>::valarray(const value_type* __p, size_t __n)
28062827#ifndef _LIBCPP_NO_EXCEPTIONS
28072828 try
28082829 {
2809#endif // _LIBCPP_NO_EXCEPTIONS
2830#endif // _LIBCPP_NO_EXCEPTIONS
28102831 for (size_t __n_left = __n; __n_left; ++__end_, ++__p, --__n_left)
28112832 ::new ((void*)__end_) value_type(*__p);
28122833#ifndef _LIBCPP_NO_EXCEPTIONS
......@@ -2816,7 +2837,7 @@ valarray<_Tp>::valarray(const value_type* __p, size_t __n)
28162837 __clear(__n);
28172838 throw;
28182839 }
2819#endif // _LIBCPP_NO_EXCEPTIONS
2840#endif // _LIBCPP_NO_EXCEPTIONS
28202841 }
28212842}
28222843
......@@ -2831,7 +2852,7 @@ valarray<_Tp>::valarray(const valarray& __v)
28312852#ifndef _LIBCPP_NO_EXCEPTIONS
28322853 try
28332854 {
2834#endif // _LIBCPP_NO_EXCEPTIONS
2855#endif // _LIBCPP_NO_EXCEPTIONS
28352856 for (value_type* __p = __v.__begin_; __p != __v.__end_; ++__end_, ++__p)
28362857 ::new ((void*)__end_) value_type(*__p);
28372858#ifndef _LIBCPP_NO_EXCEPTIONS
......@@ -2841,7 +2862,7 @@ valarray<_Tp>::valarray(const valarray& __v)
28412862 __clear(__v.size());
28422863 throw;
28432864 }
2844#endif // _LIBCPP_NO_EXCEPTIONS
2865#endif // _LIBCPP_NO_EXCEPTIONS
28452866 }
28462867}
28472868
......@@ -2868,7 +2889,7 @@ valarray<_Tp>::valarray(initializer_list<value_type> __il)
28682889#ifndef _LIBCPP_NO_EXCEPTIONS
28692890 try
28702891 {
2871#endif // _LIBCPP_NO_EXCEPTIONS
2892#endif // _LIBCPP_NO_EXCEPTIONS
28722893 size_t __n_left = __n;
28732894 for (const value_type* __p = __il.begin(); __n_left; ++__end_, ++__p, --__n_left)
28742895 ::new ((void*)__end_) value_type(*__p);
......@@ -2879,11 +2900,11 @@ valarray<_Tp>::valarray(initializer_list<value_type> __il)
28792900 __clear(__n);
28802901 throw;
28812902 }
2882#endif // _LIBCPP_NO_EXCEPTIONS
2903#endif // _LIBCPP_NO_EXCEPTIONS
28832904 }
28842905}
28852906
2886#endif // _LIBCPP_CXX03_LANG
2907#endif // _LIBCPP_CXX03_LANG
28872908
28882909template <class _Tp>
28892910valarray<_Tp>::valarray(const slice_array<value_type>& __sa)
......@@ -2897,7 +2918,7 @@ valarray<_Tp>::valarray(const slice_array<value_type>& __sa)
28972918#ifndef _LIBCPP_NO_EXCEPTIONS
28982919 try
28992920 {
2900#endif // _LIBCPP_NO_EXCEPTIONS
2921#endif // _LIBCPP_NO_EXCEPTIONS
29012922 size_t __n_left = __n;
29022923 for (const value_type* __p = __sa.__vp_; __n_left; ++__end_, __p += __sa.__stride_, --__n_left)
29032924 ::new ((void*)__end_) value_type(*__p);
......@@ -2908,7 +2929,7 @@ valarray<_Tp>::valarray(const slice_array<value_type>& __sa)
29082929 __clear(__n);
29092930 throw;
29102931 }
2911#endif // _LIBCPP_NO_EXCEPTIONS
2932#endif // _LIBCPP_NO_EXCEPTIONS
29122933 }
29132934}
29142935
......@@ -2924,7 +2945,7 @@ valarray<_Tp>::valarray(const gslice_array<value_type>& __ga)
29242945#ifndef _LIBCPP_NO_EXCEPTIONS
29252946 try
29262947 {
2927#endif // _LIBCPP_NO_EXCEPTIONS
2948#endif // _LIBCPP_NO_EXCEPTIONS
29282949 typedef const size_t* _Ip;
29292950 const value_type* __s = __ga.__vp_;
29302951 for (_Ip __i = __ga.__1d_.__begin_, __e = __ga.__1d_.__end_;
......@@ -2937,7 +2958,7 @@ valarray<_Tp>::valarray(const gslice_array<value_type>& __ga)
29372958 __clear(__n);
29382959 throw;
29392960 }
2940#endif // _LIBCPP_NO_EXCEPTIONS
2961#endif // _LIBCPP_NO_EXCEPTIONS
29412962 }
29422963}
29432964
......@@ -2953,7 +2974,7 @@ valarray<_Tp>::valarray(const mask_array<value_type>& __ma)
29532974#ifndef _LIBCPP_NO_EXCEPTIONS
29542975 try
29552976 {
2956#endif // _LIBCPP_NO_EXCEPTIONS
2977#endif // _LIBCPP_NO_EXCEPTIONS
29572978 typedef const size_t* _Ip;
29582979 const value_type* __s = __ma.__vp_;
29592980 for (_Ip __i = __ma.__1d_.__begin_, __e = __ma.__1d_.__end_;
......@@ -2966,7 +2987,7 @@ valarray<_Tp>::valarray(const mask_array<value_type>& __ma)
29662987 __clear(__n);
29672988 throw;
29682989 }
2969#endif // _LIBCPP_NO_EXCEPTIONS
2990#endif // _LIBCPP_NO_EXCEPTIONS
29702991 }
29712992}
29722993
......@@ -2982,7 +3003,7 @@ valarray<_Tp>::valarray(const indirect_array<value_type>& __ia)
29823003#ifndef _LIBCPP_NO_EXCEPTIONS
29833004 try
29843005 {
2985#endif // _LIBCPP_NO_EXCEPTIONS
3006#endif // _LIBCPP_NO_EXCEPTIONS
29863007 typedef const size_t* _Ip;
29873008 const value_type* __s = __ia.__vp_;
29883009 for (_Ip __i = __ia.__1d_.__begin_, __e = __ia.__1d_.__end_;
......@@ -2995,7 +3016,7 @@ valarray<_Tp>::valarray(const indirect_array<value_type>& __ia)
29953016 __clear(__n);
29963017 throw;
29973018 }
2998#endif // _LIBCPP_NO_EXCEPTIONS
3019#endif // _LIBCPP_NO_EXCEPTIONS
29993020 }
30003021}
30013022
......@@ -3055,7 +3076,7 @@ valarray<_Tp>::operator=(initializer_list<value_type> __il)
30553076 return __assign_range(__il.begin(), __il.end());
30563077}
30573078
3058#endif // _LIBCPP_CXX03_LANG
3079#endif // _LIBCPP_CXX03_LANG
30593080
30603081template <class _Tp>
30613082inline
......@@ -3131,7 +3152,7 @@ valarray<_Tp>::operator=(const __val_expr<_ValExpr>& __v)
31313152 resize(__n);
31323153 value_type* __t = __begin_;
31333154 for (size_t __i = 0; __i != __n; ++__t, ++__i)
3134 *__t = result_type(__v[__i]);
3155 *__t = __result_type(__v[__i]);
31353156 return *this;
31363157}
31373158
......@@ -3185,7 +3206,7 @@ valarray<_Tp>::operator[](gslice&& __gs)
31853206 return gslice_array<value_type>(move(__gs), *this);
31863207}
31873208
3188#endif // _LIBCPP_CXX03_LANG
3209#endif // _LIBCPP_CXX03_LANG
31893210
31903211template <class _Tp>
31913212inline
......@@ -3221,7 +3242,7 @@ valarray<_Tp>::operator[](valarray<bool>&& __vb)
32213242 return mask_array<value_type>(move(__vb), *this);
32223243}
32233244
3224#endif // _LIBCPP_CXX03_LANG
3245#endif // _LIBCPP_CXX03_LANG
32253246
32263247template <class _Tp>
32273248inline
......@@ -3257,7 +3278,7 @@ valarray<_Tp>::operator[](valarray<size_t>&& __vs)
32573278 return indirect_array<value_type>(move(__vs), *this);
32583279}
32593280
3260#endif // _LIBCPP_CXX03_LANG
3281#endif // _LIBCPP_CXX03_LANG
32613282
32623283template <class _Tp>
32633284valarray<_Tp>
......@@ -3731,7 +3752,7 @@ valarray<_Tp>::resize(size_t __n, value_type __x)
37313752#ifndef _LIBCPP_NO_EXCEPTIONS
37323753 try
37333754 {
3734#endif // _LIBCPP_NO_EXCEPTIONS
3755#endif // _LIBCPP_NO_EXCEPTIONS
37353756 for (size_t __n_left = __n; __n_left; --__n_left, ++__end_)
37363757 ::new ((void*)__end_) value_type(__x);
37373758#ifndef _LIBCPP_NO_EXCEPTIONS
......@@ -3741,7 +3762,7 @@ valarray<_Tp>::resize(size_t __n, value_type __x)
37413762 __clear(__n);
37423763 throw;
37433764 }
3744#endif // _LIBCPP_NO_EXCEPTIONS
3765#endif // _LIBCPP_NO_EXCEPTIONS
37453766 }
37463767}
37473768
......@@ -4905,4 +4926,4 @@ _LIBCPP_END_NAMESPACE_STD
49054926
49064927_LIBCPP_POP_MACROS
49074928
4908#endif // _LIBCPP_VALARRAY
4929#endif // _LIBCPP_VALARRAY
lib/libcxx/include/variant+90-50
......@@ -199,18 +199,20 @@ namespace std {
199199
200200*/
201201
202#include <__config>
203202#include <__availability>
203#include <__config>
204#include <__functional/hash.h>
204205#include <__tuple>
205#include <array>
206#include <__utility/forward.h>
207#include <__variant/monostate.h>
208#include <compare>
206209#include <exception>
207#include <functional>
208210#include <initializer_list>
211#include <limits>
209212#include <new>
210213#include <tuple>
211214#include <type_traits>
212215#include <utility>
213#include <limits>
214216#include <version>
215217
216218#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
......@@ -236,6 +238,19 @@ _LIBCPP_BEGIN_NAMESPACE_STD
236238// Remove this once we drop support for GCC 5.
237239#if _LIBCPP_STD_VER > 14 && !(defined(_LIBCPP_COMPILER_GCC) && _GNUC_VER_NEW < 6000)
238240
241// Light N-dimensional array of function pointers. Used in place of std::array to avoid
242// adding a dependency.
243template<class _Tp, size_t _Size>
244struct __farray {
245 static_assert(_Size > 0, "N-dimensional array should never be empty in std::visit");
246 _Tp __buf_[_Size] = {};
247
248 _LIBCPP_INLINE_VISIBILITY constexpr
249 const _Tp &operator[](size_t __n) const noexcept {
250 return __buf_[__n];
251 }
252};
253
239254_LIBCPP_NORETURN
240255inline _LIBCPP_INLINE_VISIBILITY
241256_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
......@@ -318,6 +333,33 @@ using __variant_index_t =
318333template <class _IndexType>
319334constexpr _IndexType __variant_npos = static_cast<_IndexType>(-1);
320335
336template <class... _Types>
337class _LIBCPP_TEMPLATE_VIS variant;
338
339template <class... _Types>
340_LIBCPP_INLINE_VISIBILITY constexpr variant<_Types...>&
341__as_variant(variant<_Types...>& __vs) noexcept {
342 return __vs;
343}
344
345template <class... _Types>
346_LIBCPP_INLINE_VISIBILITY constexpr const variant<_Types...>&
347__as_variant(const variant<_Types...>& __vs) noexcept {
348 return __vs;
349}
350
351template <class... _Types>
352_LIBCPP_INLINE_VISIBILITY constexpr variant<_Types...>&&
353__as_variant(variant<_Types...>&& __vs) noexcept {
354 return _VSTD::move(__vs);
355}
356
357template <class... _Types>
358_LIBCPP_INLINE_VISIBILITY constexpr const variant<_Types...>&&
359__as_variant(const variant<_Types...>&& __vs) noexcept {
360 return _VSTD::move(__vs);
361}
362
321363namespace __find_detail {
322364
323365template <class _Tp, class... _Types>
......@@ -469,7 +511,7 @@ private:
469511
470512 template <class _Tp, size_t _Np, typename... _Indices>
471513 inline _LIBCPP_INLINE_VISIBILITY
472 static constexpr auto&& __at(const array<_Tp, _Np>& __elems,
514 static constexpr auto&& __at(const __farray<_Tp, _Np>& __elems,
473515 size_t __index, _Indices... __indices) {
474516 return __at(__elems[__index], __indices...);
475517 }
......@@ -485,7 +527,7 @@ private:
485527 inline _LIBCPP_INLINE_VISIBILITY
486528 static constexpr auto __make_farray(_Fs&&... __fs) {
487529 __std_visit_visitor_return_type_check<__uncvref_t<_Fs>...>();
488 using __result = array<common_type_t<__uncvref_t<_Fs>...>, sizeof...(_Fs)>;
530 using __result = __farray<common_type_t<__uncvref_t<_Fs>...>, sizeof...(_Fs)>;
489531 return __result{{_VSTD::forward<_Fs>(__fs)...}};
490532 }
491533
......@@ -564,8 +606,9 @@ struct __variant {
564606 inline _LIBCPP_INLINE_VISIBILITY
565607 static constexpr decltype(auto) __visit_alt(_Visitor&& __visitor,
566608 _Vs&&... __vs) {
567 return __base::__visit_alt(_VSTD::forward<_Visitor>(__visitor),
568 _VSTD::forward<_Vs>(__vs).__impl...);
609 return __base::__visit_alt(
610 _VSTD::forward<_Visitor>(__visitor),
611 _VSTD::__as_variant(_VSTD::forward<_Vs>(__vs)).__impl...);
569612 }
570613
571614 template <class _Visitor, class... _Vs>
......@@ -586,6 +629,7 @@ struct __variant {
586629 __make_value_visitor(_VSTD::forward<_Visitor>(__visitor)),
587630 _VSTD::forward<_Vs>(__vs)...);
588631 }
632
589633#if _LIBCPP_STD_VER > 17
590634 template <class _Rp, class _Visitor, class... _Vs>
591635 inline _LIBCPP_INLINE_VISIBILITY
......@@ -1152,7 +1196,7 @@ struct __narrowing_check {
11521196 template <class _Dest>
11531197 static auto __test_impl(_Dest (&&)[1]) -> __identity<_Dest>;
11541198 template <class _Dest, class _Source>
1155 using _Apply _LIBCPP_NODEBUG_TYPE = decltype(__test_impl<_Dest>({_VSTD::declval<_Source>()}));
1199 using _Apply _LIBCPP_NODEBUG_TYPE = decltype(__test_impl<_Dest>({declval<_Source>()}));
11561200};
11571201
11581202template <class _Dest, class _Source>
......@@ -1637,18 +1681,21 @@ constexpr bool operator>=(const variant<_Types...>& __lhs,
16371681
16381682template <class... _Vs>
16391683inline _LIBCPP_INLINE_VISIBILITY
1640_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
1641constexpr void __throw_if_valueless(_Vs&&... __vs) {
1642 const bool __valueless = (... || __vs.valueless_by_exception());
1684 _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS constexpr void
1685 __throw_if_valueless(_Vs&&... __vs) {
1686 const bool __valueless =
1687 (... || _VSTD::__as_variant(__vs).valueless_by_exception());
16431688 if (__valueless) {
1644 __throw_bad_variant_access();
1689 __throw_bad_variant_access();
16451690 }
16461691}
16471692
1648template <class _Visitor, class... _Vs>
1693template <
1694 class _Visitor, class... _Vs,
1695 typename = void_t<decltype(_VSTD::__as_variant(declval<_Vs>()))...> >
16491696inline _LIBCPP_INLINE_VISIBILITY
1650_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
1651constexpr decltype(auto) visit(_Visitor&& __visitor, _Vs&&... __vs) {
1697 _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS constexpr
1698 decltype(auto) visit(_Visitor&& __visitor, _Vs&&... __vs) {
16521699 using __variant_detail::__visitation::__variant;
16531700 _VSTD::__throw_if_valueless(_VSTD::forward<_Vs>(__vs)...);
16541701 return __variant::__visit_value(_VSTD::forward<_Visitor>(__visitor),
......@@ -1656,10 +1703,12 @@ constexpr decltype(auto) visit(_Visitor&& __visitor, _Vs&&... __vs) {
16561703}
16571704
16581705#if _LIBCPP_STD_VER > 17
1659template <class _Rp, class _Visitor, class... _Vs>
1706template <
1707 class _Rp, class _Visitor, class... _Vs,
1708 typename = void_t<decltype(_VSTD::__as_variant(declval<_Vs>()))...> >
16601709inline _LIBCPP_INLINE_VISIBILITY
1661_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
1662constexpr _Rp visit(_Visitor&& __visitor, _Vs&&... __vs) {
1710 _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS constexpr _Rp
1711 visit(_Visitor&& __visitor, _Vs&&... __vs) {
16631712 using __variant_detail::__visitation::__variant;
16641713 _VSTD::__throw_if_valueless(_VSTD::forward<_Vs>(__vs)...);
16651714 return __variant::__visit_value<_Rp>(_VSTD::forward<_Visitor>(__visitor),
......@@ -1667,26 +1716,6 @@ constexpr _Rp visit(_Visitor&& __visitor, _Vs&&... __vs) {
16671716}
16681717#endif
16691718
1670struct _LIBCPP_TEMPLATE_VIS monostate {};
1671
1672inline _LIBCPP_INLINE_VISIBILITY
1673constexpr bool operator<(monostate, monostate) noexcept { return false; }
1674
1675inline _LIBCPP_INLINE_VISIBILITY
1676constexpr bool operator>(monostate, monostate) noexcept { return false; }
1677
1678inline _LIBCPP_INLINE_VISIBILITY
1679constexpr bool operator<=(monostate, monostate) noexcept { return true; }
1680
1681inline _LIBCPP_INLINE_VISIBILITY
1682constexpr bool operator>=(monostate, monostate) noexcept { return true; }
1683
1684inline _LIBCPP_INLINE_VISIBILITY
1685constexpr bool operator==(monostate, monostate) noexcept { return true; }
1686
1687inline _LIBCPP_INLINE_VISIBILITY
1688constexpr bool operator!=(monostate, monostate) noexcept { return false; }
1689
16901719template <class... _Types>
16911720inline _LIBCPP_INLINE_VISIBILITY
16921721auto swap(variant<_Types...>& __lhs,
......@@ -1719,21 +1748,32 @@ struct _LIBCPP_TEMPLATE_VIS hash<
17191748 }
17201749};
17211750
1722template <>
1723struct _LIBCPP_TEMPLATE_VIS hash<monostate> {
1724 using argument_type = monostate;
1725 using result_type = size_t;
1751// __unchecked_get is the same as std::get, except, it is UB to use it with the wrong
1752// type whereas std::get will throw or returning nullptr. This makes it faster than
1753// std::get.
1754template <size_t _Ip, class _Vp>
1755inline _LIBCPP_INLINE_VISIBILITY
1756constexpr auto&& __unchecked_get(_Vp&& __v) noexcept {
1757 using __variant_detail::__access::__variant;
1758 return __variant::__get_alt<_Ip>(_VSTD::forward<_Vp>(__v)).__value;
1759}
17261760
1727 inline _LIBCPP_INLINE_VISIBILITY
1728 result_type operator()(const argument_type&) const _NOEXCEPT {
1729 return 66740831; // return a fundamentally attractive random value.
1730 }
1731};
1761template <class _Tp, class... _Types>
1762inline _LIBCPP_INLINE_VISIBILITY
1763constexpr auto&& __unchecked_get(const variant<_Types...>& __v) noexcept {
1764 return __unchecked_get<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
1765}
1766
1767template <class _Tp, class... _Types>
1768inline _LIBCPP_INLINE_VISIBILITY
1769constexpr auto&& __unchecked_get(variant<_Types...>& __v) noexcept {
1770 return __unchecked_get<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
1771}
17321772
1733#endif // _LIBCPP_STD_VER > 14
1773#endif // _LIBCPP_STD_VER > 14
17341774
17351775_LIBCPP_END_NAMESPACE_STD
17361776
17371777_LIBCPP_POP_MACROS
17381778
1739#endif // _LIBCPP_VARIANT
1779#endif // _LIBCPP_VARIANT
lib/libcxx/include/vector+53-51
......@@ -144,7 +144,7 @@ public:
144144 public:
145145 reference(const reference&) noexcept;
146146 operator bool() const noexcept;
147 reference& operator=(const bool x) noexcept;
147 reference& operator=(bool x) noexcept;
148148 reference& operator=(const reference& x) noexcept;
149149 iterator operator&() const noexcept;
150150 void flip() noexcept;
......@@ -272,21 +272,23 @@ erase_if(vector<T, Allocator>& c, Predicate pred); // C++20
272272*/
273273
274274#include <__config>
275#include <iosfwd> // for forward declaration of vector
276275#include <__bit_reference>
277#include <type_traits>
276#include <__debug>
277#include <__functional_base>
278#include <__iterator/wrap_iter.h>
279#include <__split_buffer>
280#include <__utility/forward.h>
281#include <algorithm>
278282#include <climits>
279#include <limits>
283#include <compare>
284#include <cstring>
280285#include <initializer_list>
286#include <iosfwd> // for forward declaration of vector
287#include <limits>
281288#include <memory>
282289#include <stdexcept>
283#include <algorithm>
284#include <cstring>
290#include <type_traits>
285291#include <version>
286#include <__split_buffer>
287#include <__functional_base>
288
289#include <__debug>
290292
291293#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
292294#pragma GCC system_header
......@@ -557,7 +559,7 @@ public:
557559 }
558560
559561 vector(const vector& __x);
560 vector(const vector& __x, const allocator_type& __a);
562 vector(const vector& __x, const __identity_t<allocator_type>& __a);
561563 _LIBCPP_INLINE_VISIBILITY
562564 vector& operator=(const vector& __x);
563565
......@@ -577,7 +579,7 @@ public:
577579#endif
578580
579581 _LIBCPP_INLINE_VISIBILITY
580 vector(vector&& __x, const allocator_type& __a);
582 vector(vector&& __x, const __identity_t<allocator_type>& __a);
581583 _LIBCPP_INLINE_VISIBILITY
582584 vector& operator=(vector&& __x)
583585 _NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value));
......@@ -586,7 +588,7 @@ public:
586588 vector& operator=(initializer_list<value_type> __il)
587589 {assign(__il.begin(), __il.end()); return *this;}
588590
589#endif // !_LIBCPP_CXX03_LANG
591#endif // !_LIBCPP_CXX03_LANG
590592
591593 template <class _InputIterator>
592594 typename enable_if
......@@ -673,22 +675,22 @@ public:
673675
674676 _LIBCPP_INLINE_VISIBILITY reference front() _NOEXCEPT
675677 {
676 _LIBCPP_ASSERT(!empty(), "front() called for empty vector");
678 _LIBCPP_ASSERT(!empty(), "front() called on an empty vector");
677679 return *this->__begin_;
678680 }
679681 _LIBCPP_INLINE_VISIBILITY const_reference front() const _NOEXCEPT
680682 {
681 _LIBCPP_ASSERT(!empty(), "front() called for empty vector");
683 _LIBCPP_ASSERT(!empty(), "front() called on an empty vector");
682684 return *this->__begin_;
683685 }
684686 _LIBCPP_INLINE_VISIBILITY reference back() _NOEXCEPT
685687 {
686 _LIBCPP_ASSERT(!empty(), "back() called for empty vector");
688 _LIBCPP_ASSERT(!empty(), "back() called on an empty vector");
687689 return *(this->__end_ - 1);
688690 }
689691 _LIBCPP_INLINE_VISIBILITY const_reference back() const _NOEXCEPT
690692 {
691 _LIBCPP_ASSERT(!empty(), "back() called for empty vector");
693 _LIBCPP_ASSERT(!empty(), "back() called on an empty vector");
692694 return *(this->__end_ - 1);
693695 }
694696
......@@ -733,7 +735,7 @@ public:
733735 iterator insert(const_iterator __position, value_type&& __x);
734736 template <class... _Args>
735737 iterator emplace(const_iterator __position, _Args&&... __args);
736#endif // !_LIBCPP_CXX03_LANG
738#endif // !_LIBCPP_CXX03_LANG
737739
738740 iterator insert(const_iterator __position, size_type __n, const_reference __x);
739741 template <class _InputIterator>
......@@ -796,7 +798,7 @@ public:
796798 bool __addable(const const_iterator* __i, ptrdiff_t __n) const;
797799 bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const;
798800
799#endif // _LIBCPP_DEBUG_LEVEL == 2
801#endif // _LIBCPP_DEBUG_LEVEL == 2
800802
801803private:
802804 _LIBCPP_INLINE_VISIBILITY void __invalidate_all_iterators();
......@@ -931,18 +933,18 @@ private:
931933
932934#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
933935template<class _InputIterator,
934 class _Alloc = allocator<typename iterator_traits<_InputIterator>::value_type>,
935 class = typename enable_if<__is_allocator<_Alloc>::value, void>::type
936 class _Alloc = allocator<__iter_value_type<_InputIterator>>,
937 class = _EnableIf<__is_allocator<_Alloc>::value>
936938 >
937939vector(_InputIterator, _InputIterator)
938 -> vector<typename iterator_traits<_InputIterator>::value_type, _Alloc>;
940 -> vector<__iter_value_type<_InputIterator>, _Alloc>;
939941
940942template<class _InputIterator,
941943 class _Alloc,
942 class = typename enable_if<__is_allocator<_Alloc>::value, void>::type
944 class = _EnableIf<__is_allocator<_Alloc>::value>
943945 >
944946vector(_InputIterator, _InputIterator, _Alloc)
945 -> vector<typename iterator_traits<_InputIterator>::value_type, _Alloc>;
947 -> vector<__iter_value_type<_InputIterator>, _Alloc>;
946948#endif
947949
948950template <class _Tp, class _Allocator>
......@@ -1027,7 +1029,7 @@ vector<_Tp, _Allocator>::__recommend(size_type __new_size) const
10271029 const size_type __cap = capacity();
10281030 if (__cap >= __ms / 2)
10291031 return __ms;
1030 return _VSTD::max<size_type>(2*__cap, __new_size);
1032 return _VSTD::max<size_type>(2 * __cap, __new_size);
10311033}
10321034
10331035// Default constructs __n objects starting at __end_
......@@ -1261,7 +1263,7 @@ vector<_Tp, _Allocator>::vector(const vector& __x)
12611263}
12621264
12631265template <class _Tp, class _Allocator>
1264vector<_Tp, _Allocator>::vector(const vector& __x, const allocator_type& __a)
1266vector<_Tp, _Allocator>::vector(const vector& __x, const __identity_t<allocator_type>& __a)
12651267 : __base(__a)
12661268{
12671269#if _LIBCPP_DEBUG_LEVEL == 2
......@@ -1299,7 +1301,7 @@ vector<_Tp, _Allocator>::vector(vector&& __x)
12991301
13001302template <class _Tp, class _Allocator>
13011303inline _LIBCPP_INLINE_VISIBILITY
1302vector<_Tp, _Allocator>::vector(vector&& __x, const allocator_type& __a)
1304vector<_Tp, _Allocator>::vector(vector&& __x, const __identity_t<allocator_type>& __a)
13031305 : __base(__a)
13041306{
13051307#if _LIBCPP_DEBUG_LEVEL == 2
......@@ -1392,7 +1394,7 @@ vector<_Tp, _Allocator>::__move_assign(vector& __c, true_type)
13921394#endif
13931395}
13941396
1395#endif // !_LIBCPP_CXX03_LANG
1397#endif // !_LIBCPP_CXX03_LANG
13961398
13971399template <class _Tp, class _Allocator>
13981400inline _LIBCPP_INLINE_VISIBILITY
......@@ -1598,7 +1600,7 @@ vector<_Tp, _Allocator>::shrink_to_fit() _NOEXCEPT
15981600#ifndef _LIBCPP_NO_EXCEPTIONS
15991601 try
16001602 {
1601#endif // _LIBCPP_NO_EXCEPTIONS
1603#endif // _LIBCPP_NO_EXCEPTIONS
16021604 allocator_type& __a = this->__alloc();
16031605 __split_buffer<value_type, allocator_type&> __v(size(), size(), __a);
16041606 __swap_out_circular_buffer(__v);
......@@ -1607,7 +1609,7 @@ vector<_Tp, _Allocator>::shrink_to_fit() _NOEXCEPT
16071609 catch (...)
16081610 {
16091611 }
1610#endif // _LIBCPP_NO_EXCEPTIONS
1612#endif // _LIBCPP_NO_EXCEPTIONS
16111613 }
16121614}
16131615
......@@ -1690,14 +1692,14 @@ vector<_Tp, _Allocator>::emplace_back(_Args&&... __args)
16901692#endif
16911693}
16921694
1693#endif // !_LIBCPP_CXX03_LANG
1695#endif // !_LIBCPP_CXX03_LANG
16941696
16951697template <class _Tp, class _Allocator>
16961698inline
16971699void
16981700vector<_Tp, _Allocator>::pop_back()
16991701{
1700 _LIBCPP_ASSERT(!empty(), "vector::pop_back called for empty vector");
1702 _LIBCPP_ASSERT(!empty(), "vector::pop_back called on an empty vector");
17011703 this->__destruct_at_end(this->__end_ - 1);
17021704}
17031705
......@@ -1865,7 +1867,7 @@ vector<_Tp, _Allocator>::emplace(const_iterator __position, _Args&&... __args)
18651867 return __make_iter(__p);
18661868}
18671869
1868#endif // !_LIBCPP_CXX03_LANG
1870#endif // !_LIBCPP_CXX03_LANG
18691871
18701872template <class _Tp, class _Allocator>
18711873typename vector<_Tp, _Allocator>::iterator
......@@ -1941,7 +1943,7 @@ vector<_Tp, _Allocator>::insert(const_iterator __position, _InputIterator __firs
19411943#ifndef _LIBCPP_NO_EXCEPTIONS
19421944 try
19431945 {
1944#endif // _LIBCPP_NO_EXCEPTIONS
1946#endif // _LIBCPP_NO_EXCEPTIONS
19451947 __v.__construct_at_end(__first, __last);
19461948 difference_type __old_size = __old_last - this->__begin_;
19471949 difference_type __old_p = __p - this->__begin_;
......@@ -1955,7 +1957,7 @@ vector<_Tp, _Allocator>::insert(const_iterator __position, _InputIterator __firs
19551957 erase(__make_iter(__old_last), end());
19561958 throw;
19571959 }
1958#endif // _LIBCPP_NO_EXCEPTIONS
1960#endif // _LIBCPP_NO_EXCEPTIONS
19591961 }
19601962 __p = _VSTD::rotate(__p, __old_last, this->__end_);
19611963 insert(__make_iter(__p), _VSTD::make_move_iterator(__v.begin()),
......@@ -2114,7 +2116,7 @@ vector<_Tp, _Allocator>::__subscriptable(const const_iterator* __i, ptrdiff_t __
21142116 return this->__begin_ <= __p && __p < this->__end_;
21152117}
21162118
2117#endif // _LIBCPP_DEBUG_LEVEL == 2
2119#endif // _LIBCPP_DEBUG_LEVEL == 2
21182120
21192121template <class _Tp, class _Allocator>
21202122inline _LIBCPP_INLINE_VISIBILITY
......@@ -2261,7 +2263,7 @@ public:
22612263#else
22622264 _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value);
22632265#endif
2264 vector(vector&& __v, const allocator_type& __a);
2266 vector(vector&& __v, const __identity_t<allocator_type>& __a);
22652267 _LIBCPP_INLINE_VISIBILITY
22662268 vector& operator=(vector&& __v)
22672269 _NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value));
......@@ -2270,7 +2272,7 @@ public:
22702272 vector& operator=(initializer_list<value_type> __il)
22712273 {assign(__il.begin(), __il.end()); return *this;}
22722274
2273#endif // !_LIBCPP_CXX03_LANG
2275#endif // !_LIBCPP_CXX03_LANG
22742276
22752277 template <class _InputIterator>
22762278 typename enable_if
......@@ -2573,7 +2575,7 @@ vector<bool, _Allocator>::__recommend(size_type __new_size) const
25732575 const size_type __cap = capacity();
25742576 if (__cap >= __ms / 2)
25752577 return __ms;
2576 return _VSTD::max(2*__cap, __align_it(__new_size));
2578 return _VSTD::max(2 * __cap, __align_it(__new_size));
25772579}
25782580
25792581// Default constructs __n objects starting at __end_
......@@ -2708,7 +2710,7 @@ vector<bool, _Allocator>::vector(_InputIterator __first, _InputIterator __last,
27082710#ifndef _LIBCPP_NO_EXCEPTIONS
27092711 try
27102712 {
2711#endif // _LIBCPP_NO_EXCEPTIONS
2713#endif // _LIBCPP_NO_EXCEPTIONS
27122714 for (; __first != __last; ++__first)
27132715 push_back(*__first);
27142716#ifndef _LIBCPP_NO_EXCEPTIONS
......@@ -2720,7 +2722,7 @@ vector<bool, _Allocator>::vector(_InputIterator __first, _InputIterator __last,
27202722 __invalidate_all_iterators();
27212723 throw;
27222724 }
2723#endif // _LIBCPP_NO_EXCEPTIONS
2725#endif // _LIBCPP_NO_EXCEPTIONS
27242726}
27252727
27262728template <class _Allocator>
......@@ -2735,7 +2737,7 @@ vector<bool, _Allocator>::vector(_InputIterator __first, _InputIterator __last,
27352737#ifndef _LIBCPP_NO_EXCEPTIONS
27362738 try
27372739 {
2738#endif // _LIBCPP_NO_EXCEPTIONS
2740#endif // _LIBCPP_NO_EXCEPTIONS
27392741 for (; __first != __last; ++__first)
27402742 push_back(*__first);
27412743#ifndef _LIBCPP_NO_EXCEPTIONS
......@@ -2747,7 +2749,7 @@ vector<bool, _Allocator>::vector(_InputIterator __first, _InputIterator __last,
27472749 __invalidate_all_iterators();
27482750 throw;
27492751 }
2750#endif // _LIBCPP_NO_EXCEPTIONS
2752#endif // _LIBCPP_NO_EXCEPTIONS
27512753}
27522754
27532755template <class _Allocator>
......@@ -2812,7 +2814,7 @@ vector<bool, _Allocator>::vector(initializer_list<value_type> __il, const alloca
28122814 }
28132815}
28142816
2815#endif // _LIBCPP_CXX03_LANG
2817#endif // _LIBCPP_CXX03_LANG
28162818
28172819template <class _Allocator>
28182820vector<bool, _Allocator>::~vector()
......@@ -2887,7 +2889,7 @@ inline _LIBCPP_INLINE_VISIBILITY vector<bool, _Allocator>::vector(vector&& __v)
28872889}
28882890
28892891template <class _Allocator>
2890vector<bool, _Allocator>::vector(vector&& __v, const allocator_type& __a)
2892vector<bool, _Allocator>::vector(vector&& __v, const __identity_t<allocator_type>& __a)
28912893 : __begin_(nullptr),
28922894 __size_(0),
28932895 __cap_alloc_(0, __a)
......@@ -2942,7 +2944,7 @@ vector<bool, _Allocator>::__move_assign(vector& __c, true_type)
29422944 __c.__cap() = __c.__size_ = 0;
29432945}
29442946
2945#endif // !_LIBCPP_CXX03_LANG
2947#endif // !_LIBCPP_CXX03_LANG
29462948
29472949template <class _Allocator>
29482950void
......@@ -3028,14 +3030,14 @@ vector<bool, _Allocator>::shrink_to_fit() _NOEXCEPT
30283030#ifndef _LIBCPP_NO_EXCEPTIONS
30293031 try
30303032 {
3031#endif // _LIBCPP_NO_EXCEPTIONS
3033#endif // _LIBCPP_NO_EXCEPTIONS
30323034 vector(*this, allocator_type(__alloc())).swap(*this);
30333035#ifndef _LIBCPP_NO_EXCEPTIONS
30343036 }
30353037 catch (...)
30363038 {
30373039 }
3038#endif // _LIBCPP_NO_EXCEPTIONS
3040#endif // _LIBCPP_NO_EXCEPTIONS
30393041 }
30403042}
30413043
......@@ -3142,7 +3144,7 @@ vector<bool, _Allocator>::insert(const_iterator __position, _InputIterator __fir
31423144#ifndef _LIBCPP_NO_EXCEPTIONS
31433145 try
31443146 {
3145#endif // _LIBCPP_NO_EXCEPTIONS
3147#endif // _LIBCPP_NO_EXCEPTIONS
31463148 __v.assign(__first, __last);
31473149 difference_type __old_size = static_cast<difference_type>(__old_end - begin());
31483150 difference_type __old_p = __p - begin();
......@@ -3156,7 +3158,7 @@ vector<bool, _Allocator>::insert(const_iterator __position, _InputIterator __fir
31563158 erase(__old_end, end());
31573159 throw;
31583160 }
3159#endif // _LIBCPP_NO_EXCEPTIONS
3161#endif // _LIBCPP_NO_EXCEPTIONS
31603162 }
31613163 __p = _VSTD::rotate(__p, __old_end, end());
31623164 insert(__p, __v.begin(), __v.end());
......@@ -3411,4 +3413,4 @@ _LIBCPP_END_NAMESPACE_STD
34113413
34123414_LIBCPP_POP_MACROS
34133415
3414#endif // _LIBCPP_VECTOR
3416#endif // _LIBCPP_VECTOR
lib/libcxx/include/version+36-22
......@@ -56,7 +56,7 @@ __cpp_lib_constexpr_functional 201907L <functional>
5656__cpp_lib_constexpr_iterator 201811L <iterator>
5757__cpp_lib_constexpr_memory 201811L <memory>
5858__cpp_lib_constexpr_numeric 201911L <numeric>
59__cpp_lib_constexpr_string 201907L <string>
59__cpp_lib_constexpr_string 201811L <string>
6060__cpp_lib_constexpr_string_view 201811L <string_view>
6161__cpp_lib_constexpr_tuple 201811L <tuple>
6262__cpp_lib_constexpr_utility 201811L <utility>
......@@ -72,6 +72,7 @@ __cpp_lib_exchange_function 201304L <utility>
7272__cpp_lib_execution 201902L <execution>
7373 201603L // C++17
7474__cpp_lib_filesystem 201703L <filesystem>
75__cpp_lib_format 201907L <format>
7576__cpp_lib_gcd_lcm 201606L <numeric>
7677__cpp_lib_generic_associative_lookup 201304L <map> <set>
7778__cpp_lib_generic_unordered_lookup 201811L <unordered_map> <unordered_set>
......@@ -149,6 +150,7 @@ __cpp_lib_three_way_comparison 201907L <compare>
149150__cpp_lib_to_address 201711L <memory>
150151__cpp_lib_to_array 201907L <array>
151152__cpp_lib_to_chars 201611L <utility>
153__cpp_lib_to_underlying 202102L <utility>
152154__cpp_lib_transformation_trait_aliases 201304L <type_traits>
153155__cpp_lib_transparent_operators 201510L <functional> <memory>
154156 201210L // C++14
......@@ -158,7 +160,7 @@ __cpp_lib_type_trait_variable_templates 201510L <type_traits>
158160__cpp_lib_uncaught_exceptions 201411L <exception>
159161__cpp_lib_unordered_map_try_emplace 201411L <unordered_map>
160162__cpp_lib_unwrap_ref 201811L <functional>
161__cpp_lib_variant 201606L <variant>
163__cpp_lib_variant 202102L <variant>
162164__cpp_lib_void_t 201411L <type_traits>
163165
164166*/
......@@ -169,6 +171,8 @@ __cpp_lib_void_t 201411L <type_traits>
169171#pragma GCC system_header
170172#endif
171173
174// clang-format off
175
172176#if _LIBCPP_STD_VER > 11
173177# define __cpp_lib_chrono_udls 201304L
174178# define __cpp_lib_complex_udls 201309L
......@@ -184,7 +188,7 @@ __cpp_lib_void_t 201411L <type_traits>
184188# define __cpp_lib_quoted_string_io 201304L
185189# define __cpp_lib_result_of_sfinae 201210L
186190# define __cpp_lib_robust_nonmodifying_seq_ops 201304L
187# if !defined(_LIBCPP_HAS_NO_THREADS)
191# if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_timed_mutex)
188192# define __cpp_lib_shared_timed_mutex 201402L
189193# endif
190194# define __cpp_lib_string_udls 201304L
......@@ -213,7 +217,9 @@ __cpp_lib_void_t 201411L <type_traits>
213217# define __cpp_lib_clamp 201603L
214218# define __cpp_lib_enable_shared_from_this 201603L
215219// # define __cpp_lib_execution 201603L
216# define __cpp_lib_filesystem 201703L
220# if !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_filesystem)
221# define __cpp_lib_filesystem 201703L
222# endif
217223# define __cpp_lib_gcd_lcm 201606L
218224// # define __cpp_lib_hardware_interference_size 201703L
219225# if defined(_LIBCPP_HAS_UNIQUE_OBJECT_REPRESENTATIONS)
......@@ -241,7 +247,7 @@ __cpp_lib_void_t 201411L <type_traits>
241247# define __cpp_lib_raw_memory_algorithms 201606L
242248# define __cpp_lib_sample 201603L
243249# define __cpp_lib_scoped_lock 201703L
244# if !defined(_LIBCPP_HAS_NO_THREADS)
250# if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_mutex)
245251# define __cpp_lib_shared_mutex 201505L
246252# endif
247253# define __cpp_lib_shared_ptr_arrays 201611L
......@@ -253,7 +259,7 @@ __cpp_lib_void_t 201411L <type_traits>
253259# define __cpp_lib_type_trait_variable_templates 201510L
254260# define __cpp_lib_uncaught_exceptions 201411L
255261# define __cpp_lib_unordered_map_try_emplace 201411L
256# define __cpp_lib_variant 201606L
262# define __cpp_lib_variant 202102L
257263# define __cpp_lib_void_t 201411L
258264#endif
259265
......@@ -277,32 +283,32 @@ __cpp_lib_void_t 201411L <type_traits>
277283// # define __cpp_lib_atomic_shared_ptr 201711L
278284# endif
279285# if !defined(_LIBCPP_HAS_NO_THREADS)
280// # define __cpp_lib_atomic_value_initialization 201911L
286# define __cpp_lib_atomic_value_initialization 201911L
281287# endif
282# if !defined(_LIBCPP_HAS_NO_THREADS)
288# if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_atomic_wait)
283289# define __cpp_lib_atomic_wait 201907L
284290# endif
285# if !defined(_LIBCPP_HAS_NO_THREADS)
291# if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_barrier)
286292# define __cpp_lib_barrier 201907L
287293# endif
288// # define __cpp_lib_bind_front 201907L
294# define __cpp_lib_bind_front 201907L
289295// # define __cpp_lib_bit_cast 201806L
290296// # define __cpp_lib_bitops 201907L
291297# define __cpp_lib_bounded_array_traits 201902L
292# if !defined(_LIBCPP_NO_HAS_CHAR8_T)
298# if !defined(_LIBCPP_HAS_NO_CHAR8_T)
293299# define __cpp_lib_char8_t 201811L
294300# endif
295// # define __cpp_lib_concepts 202002L
296// # define __cpp_lib_constexpr_algorithms 201806L
301# define __cpp_lib_concepts 202002L
302# define __cpp_lib_constexpr_algorithms 201806L
297303// # define __cpp_lib_constexpr_complex 201711L
298304# define __cpp_lib_constexpr_dynamic_alloc 201907L
299305# define __cpp_lib_constexpr_functional 201907L
300// # define __cpp_lib_constexpr_iterator 201811L
301// # define __cpp_lib_constexpr_memory 201811L
306# define __cpp_lib_constexpr_iterator 201811L
307# define __cpp_lib_constexpr_memory 201811L
302308# define __cpp_lib_constexpr_numeric 201911L
303// # define __cpp_lib_constexpr_string 201907L
304// # define __cpp_lib_constexpr_string_view 201811L
305// # define __cpp_lib_constexpr_tuple 201811L
309# define __cpp_lib_constexpr_string 201811L
310# define __cpp_lib_constexpr_string_view 201811L
311# define __cpp_lib_constexpr_tuple 201811L
306312# define __cpp_lib_constexpr_utility 201811L
307313// # define __cpp_lib_constexpr_vector 201907L
308314// # define __cpp_lib_coroutine 201902L
......@@ -313,9 +319,14 @@ __cpp_lib_void_t 201411L <type_traits>
313319# define __cpp_lib_erase_if 202002L
314320# undef __cpp_lib_execution
315321// # define __cpp_lib_execution 201902L
322# if !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_format)
323// # define __cpp_lib_format 201907L
324# endif
316325# define __cpp_lib_generic_unordered_lookup 201811L
317326# define __cpp_lib_int_pow2 202002L
318// # define __cpp_lib_integer_comparison_functions 202002L
327# if !defined(_LIBCPP_HAS_NO_CONCEPTS)
328# define __cpp_lib_integer_comparison_functions 202002L
329# endif
319330# define __cpp_lib_interpolate 201902L
320331# if !defined(_LIBCPP_HAS_NO_BUILTIN_IS_CONSTANT_EVALUATED)
321332# define __cpp_lib_is_constant_evaluated 201811L
......@@ -326,17 +337,17 @@ __cpp_lib_void_t 201411L <type_traits>
326337# if !defined(_LIBCPP_HAS_NO_THREADS)
327338// # define __cpp_lib_jthread 201911L
328339# endif
329# if !defined(_LIBCPP_HAS_NO_THREADS)
340# if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_latch)
330341# define __cpp_lib_latch 201907L
331342# endif
332343# define __cpp_lib_list_remove_return_type 201806L
333# if defined(__cpp_concepts) && __cpp_concepts >= 201811L
344# if !defined(_LIBCPP_HAS_NO_CONCEPTS)
334345# define __cpp_lib_math_constants 201907L
335346# endif
336347// # define __cpp_lib_polymorphic_allocator 201902L
337348// # define __cpp_lib_ranges 201811L
338349# define __cpp_lib_remove_cvref 201711L
339# if !defined(_LIBCPP_HAS_NO_THREADS)
350# if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_semaphore)
340351# define __cpp_lib_semaphore 201907L
341352# endif
342353# define __cpp_lib_shift 201806L
......@@ -359,6 +370,9 @@ __cpp_lib_void_t 201411L <type_traits>
359370// # define __cpp_lib_stacktrace 202011L
360371// # define __cpp_lib_stdatomic_h 202011L
361372# define __cpp_lib_string_contains 202011L
373# define __cpp_lib_to_underlying 202102L
362374#endif
363375
376// clang-format on
377
364378#endif // _LIBCPP_VERSIONH
lib/libcxx/include/wchar.h+2-2
......@@ -177,6 +177,6 @@ size_t mbsnrtowcs(wchar_t *__restrict dst, const char **__restrict src,
177177size_t wcsnrtombs(char *__restrict dst, const wchar_t **__restrict src,
178178 size_t nwc, size_t len, mbstate_t *__restrict ps);
179179} // extern "C++"
180#endif // __cplusplus && _LIBCPP_MSVCRT
180#endif // __cplusplus && _LIBCPP_MSVCRT
181181
182#endif // _LIBCPP_WCHAR_H
182#endif // _LIBCPP_WCHAR_H
lib/libcxx/include/wctype.h+2-2
......@@ -75,6 +75,6 @@ wctrans_t wctrans(const char* property);
7575#undef towctrans
7676#undef wctrans
7777
78#endif // __cplusplus
78#endif // __cplusplus
7979
80#endif // _LIBCPP_WCTYPE_H
80#endif // _LIBCPP_WCTYPE_H
lib/libcxx/src/any.cpp+3-3
......@@ -9,7 +9,7 @@
99#include "any"
1010
1111namespace std {
12const char* bad_any_cast::what() const _NOEXCEPT {
12const char* bad_any_cast::what() const noexcept {
1313 return "bad any cast";
1414}
1515}
......@@ -24,10 +24,10 @@ _LIBCPP_BEGIN_NAMESPACE_LFTS
2424class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_ANY_CAST bad_any_cast : public bad_cast
2525{
2626public:
27 virtual const char* what() const _NOEXCEPT;
27 virtual const char* what() const noexcept;
2828};
2929
30const char* bad_any_cast::what() const _NOEXCEPT {
30const char* bad_any_cast::what() const noexcept {
3131 return "bad any cast";
3232}
3333
lib/libcxx/src/charconv.cpp+2-2
......@@ -99,7 +99,7 @@ append8_no_zeros(char* buffer, T v) noexcept
9999}
100100
101101char*
102__u32toa(uint32_t value, char* buffer) _NOEXCEPT
102__u32toa(uint32_t value, char* buffer) noexcept
103103{
104104 if (value < 100000000)
105105 {
......@@ -120,7 +120,7 @@ __u32toa(uint32_t value, char* buffer) _NOEXCEPT
120120}
121121
122122char*
123__u64toa(uint64_t value, char* buffer) _NOEXCEPT
123__u64toa(uint64_t value, char* buffer) noexcept
124124{
125125 if (value < 100000000)
126126 {
lib/libcxx/src/chrono.cpp+26-5
......@@ -6,9 +6,20 @@
66//
77//===----------------------------------------------------------------------===//
88
9#if defined(__MVS__)
10// As part of monotonic clock support on z/OS we need macro _LARGE_TIME_API
11// to be defined before any system header to include definition of struct timespec64.
12#define _LARGE_TIME_API
13#endif
14
915#include "chrono"
1016#include "cerrno" // errno
1117#include "system_error" // __throw_system_error
18
19#if defined(__MVS__)
20#include <__support/ibm/gettod_zos.h> // gettimeofdayMonotonic
21#endif
22
1223#include <time.h> // clock_gettime and CLOCK_{MONOTONIC,REALTIME,MONOTONIC_RAW}
1324#include "include/apple_availability.h"
1425
......@@ -20,7 +31,7 @@
2031# include <sys/time.h> // for gettimeofday and timeval
2132#endif
2233
23#if !defined(__APPLE__) && _POSIX_TIMERS > 0
34#if !defined(__APPLE__) && defined(_POSIX_TIMERS) && _POSIX_TIMERS > 0
2435# define _LIBCPP_USE_CLOCK_GETTIME
2536#endif
2637
......@@ -96,19 +107,19 @@ static system_clock::time_point __libcpp_system_clock_now() {
96107const bool system_clock::is_steady;
97108
98109system_clock::time_point
99system_clock::now() _NOEXCEPT
110system_clock::now() noexcept
100111{
101112 return __libcpp_system_clock_now();
102113}
103114
104115time_t
105system_clock::to_time_t(const time_point& t) _NOEXCEPT
116system_clock::to_time_t(const time_point& t) noexcept
106117{
107118 return time_t(duration_cast<seconds>(t.time_since_epoch()).count());
108119}
109120
110121system_clock::time_point
111system_clock::from_time_t(time_t t) _NOEXCEPT
122system_clock::from_time_t(time_t t) noexcept
112123{
113124 return system_clock::time_point(seconds(t));
114125}
......@@ -218,6 +229,16 @@ static steady_clock::time_point __libcpp_steady_clock_now() {
218229 return steady_clock::time_point(steady_clock::duration(dur));
219230}
220231
232#elif defined(__MVS__)
233
234static steady_clock::time_point __libcpp_steady_clock_now() {
235 struct timespec64 ts;
236 if (0 != gettimeofdayMonotonic(&ts))
237 __throw_system_error(errno, "failed to obtain time of day");
238
239 return steady_clock::time_point(seconds(ts.tv_sec) + nanoseconds(ts.tv_nsec));
240}
241
221242#elif defined(CLOCK_MONOTONIC)
222243
223244static steady_clock::time_point __libcpp_steady_clock_now() {
......@@ -234,7 +255,7 @@ static steady_clock::time_point __libcpp_steady_clock_now() {
234255const bool steady_clock::is_steady;
235256
236257steady_clock::time_point
237steady_clock::now() _NOEXCEPT
258steady_clock::now() noexcept
238259{
239260 return __libcpp_steady_clock_now();
240261}
lib/libcxx/src/condition_variable.cpp+4-4
......@@ -24,19 +24,19 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2424// ~condition_variable is defined elsewhere.
2525
2626void
27condition_variable::notify_one() _NOEXCEPT
27condition_variable::notify_one() noexcept
2828{
2929 __libcpp_condvar_signal(&__cv_);
3030}
3131
3232void
33condition_variable::notify_all() _NOEXCEPT
33condition_variable::notify_all() noexcept
3434{
3535 __libcpp_condvar_broadcast(&__cv_);
3636}
3737
3838void
39condition_variable::wait(unique_lock<mutex>& lk) _NOEXCEPT
39condition_variable::wait(unique_lock<mutex>& lk) noexcept
4040{
4141 if (!lk.owns_lock())
4242 __throw_system_error(EPERM,
......@@ -48,7 +48,7 @@ condition_variable::wait(unique_lock<mutex>& lk) _NOEXCEPT
4848
4949void
5050condition_variable::__do_timed_wait(unique_lock<mutex>& lk,
51 chrono::time_point<chrono::system_clock, chrono::nanoseconds> tp) _NOEXCEPT
51 chrono::time_point<chrono::system_clock, chrono::nanoseconds> tp) noexcept
5252{
5353 using namespace chrono;
5454 if (!lk.owns_lock())
lib/libcxx/src/debug.cpp+1-1
......@@ -438,7 +438,7 @@ __libcpp_db::__less_than_comparable(const void* __i, const void* __j) const
438438 __i_node* j = __find_iterator(__j);
439439 __c_node* ci = i != nullptr ? i->__c_ : nullptr;
440440 __c_node* cj = j != nullptr ? j->__c_ : nullptr;
441 return ci != nullptr && ci == cj;
441 return ci == cj;
442442}
443443
444444void
lib/libcxx/src/experimental/memory_resource.cpp+8-13
......@@ -40,7 +40,7 @@ class _LIBCPP_TYPE_VIS __new_delete_memory_resource_imp
4040 _VSTD::__libcpp_deallocate(p, n, align);
4141 }
4242
43 bool do_is_equal(memory_resource const & other) const _NOEXCEPT override
43 bool do_is_equal(memory_resource const & other) const noexcept override
4444 { return &other == this; }
4545
4646public:
......@@ -60,7 +60,7 @@ protected:
6060 __throw_bad_alloc();
6161 }
6262 virtual void do_deallocate(void *, size_t, size_t) {}
63 virtual bool do_is_equal(memory_resource const & __other) const _NOEXCEPT
63 virtual bool do_is_equal(memory_resource const & __other) const noexcept
6464 { return &__other == this; }
6565};
6666
......@@ -76,28 +76,23 @@ union ResourceInitHelper {
7676 ~ResourceInitHelper() {}
7777};
7878
79// When compiled in C++14 this initialization should be a constant expression.
80// Only in C++11 is "init_priority" needed to ensure initialization order.
81#if _LIBCPP_STD_VER > 11
82_LIBCPP_SAFE_STATIC
83#endif
84ResourceInitHelper res_init _LIBCPP_INIT_PRIORITY_MAX;
79_LIBCPP_SAFE_STATIC ResourceInitHelper res_init _LIBCPP_INIT_PRIORITY_MAX;
8580
8681} // end namespace
8782
8883
89memory_resource * new_delete_resource() _NOEXCEPT {
84memory_resource * new_delete_resource() noexcept {
9085 return &res_init.resources.new_delete_res;
9186}
9287
93memory_resource * null_memory_resource() _NOEXCEPT {
88memory_resource * null_memory_resource() noexcept {
9489 return &res_init.resources.null_res;
9590}
9691
9792// default_memory_resource()
9893
9994static memory_resource *
100__default_memory_resource(bool set = false, memory_resource * new_res = nullptr) _NOEXCEPT
95__default_memory_resource(bool set = false, memory_resource * new_res = nullptr) noexcept
10196{
10297#ifndef _LIBCPP_HAS_NO_ATOMIC_HEADER
10398 _LIBCPP_SAFE_STATIC static atomic<memory_resource*> __res =
......@@ -138,12 +133,12 @@ __default_memory_resource(bool set = false, memory_resource * new_res = nullptr)
138133#endif
139134}
140135
141memory_resource * get_default_resource() _NOEXCEPT
136memory_resource * get_default_resource() noexcept
142137{
143138 return __default_memory_resource();
144139}
145140
146memory_resource * set_default_resource(memory_resource * __new_res) _NOEXCEPT
141memory_resource * set_default_resource(memory_resource * __new_res) noexcept
147142{
148143 return __default_memory_resource(true, __new_res);
149144}
lib/libcxx/src/filesystem/directory_iterator.cpp+6-4
......@@ -124,7 +124,8 @@ public:
124124 ec = detail::make_windows_error(GetLastError());
125125 const bool ignore_permission_denied =
126126 bool(opts & directory_options::skip_permission_denied);
127 if (ignore_permission_denied && ec.value() == ERROR_ACCESS_DENIED)
127 if (ignore_permission_denied &&
128 ec.value() == static_cast<int>(errc::permission_denied))
128129 ec.clear();
129130 return;
130131 }
......@@ -272,7 +273,7 @@ directory_iterator& directory_iterator::__increment(error_code* ec) {
272273 path root = move(__imp_->__root_);
273274 __imp_.reset();
274275 if (m_ec)
275 err.report(m_ec, "at root \"%s\"", root);
276 err.report(m_ec, "at root " PATH_CSTR_FMT, root.c_str());
276277 }
277278 return *this;
278279}
......@@ -359,7 +360,7 @@ void recursive_directory_iterator::__advance(error_code* ec) {
359360 if (m_ec) {
360361 path root = move(stack.top().__root_);
361362 __imp_.reset();
362 err.report(m_ec, "at root \"%s\"", root);
363 err.report(m_ec, "at root " PATH_CSTR_FMT, root.c_str());
363364 } else {
364365 __imp_.reset();
365366 }
......@@ -404,7 +405,8 @@ bool recursive_directory_iterator::__try_recursion(error_code* ec) {
404405 } else {
405406 path at_ent = move(curr_it.__entry_.__p_);
406407 __imp_.reset();
407 err.report(m_ec, "attempting recursion into \"%s\"", at_ent);
408 err.report(m_ec, "attempting recursion into " PATH_CSTR_FMT,
409 at_ent.c_str());
408410 }
409411 }
410412 return false;
lib/libcxx/src/filesystem/filesystem_common.h+130-71
......@@ -35,15 +35,17 @@
3535#endif
3636#endif
3737
38#if defined(__GNUC__)
38#if defined(__GNUC__) || defined(__clang__)
3939#pragma GCC diagnostic push
4040#pragma GCC diagnostic ignored "-Wunused-function"
4141#endif
4242
4343#if defined(_LIBCPP_WIN32API)
4444#define PS(x) (L##x)
45#define PATH_CSTR_FMT "\"%ls\""
4546#else
4647#define PS(x) (x)
48#define PATH_CSTR_FMT "\"%s\""
4749#endif
4850
4951_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
......@@ -57,68 +59,47 @@ errc __win_err_to_errc(int err);
5759
5860namespace {
5961
60static string format_string_imp(const char* msg, ...) {
61 // we might need a second shot at this, so pre-emptivly make a copy
62 struct GuardVAList {
63 va_list& target;
64 bool active = true;
65 GuardVAList(va_list& tgt) : target(tgt), active(true) {}
66 void clear() {
67 if (active)
68 va_end(target);
69 active = false;
70 }
71 ~GuardVAList() {
72 if (active)
73 va_end(target);
74 }
75 };
76 va_list args;
77 va_start(args, msg);
78 GuardVAList args_guard(args);
79
80 va_list args_cp;
81 va_copy(args_cp, args);
82 GuardVAList args_copy_guard(args_cp);
83
84 std::string result;
85
86 array<char, 256> local_buff;
87 size_t size_with_null = local_buff.size();
88 auto ret = ::vsnprintf(local_buff.data(), size_with_null, msg, args_cp);
89
90 args_copy_guard.clear();
91
92 // handle empty expansion
93 if (ret == 0)
94 return result;
95 if (static_cast<size_t>(ret) < size_with_null) {
96 result.assign(local_buff.data(), static_cast<size_t>(ret));
97 return result;
62static _LIBCPP_FORMAT_PRINTF(1, 0) string
63format_string_impl(const char* msg, va_list ap) {
64 array<char, 256> buf;
65
66 va_list apcopy;
67 va_copy(apcopy, ap);
68 int ret = ::vsnprintf(buf.data(), buf.size(), msg, apcopy);
69 va_end(apcopy);
70
71 string result;
72 if (static_cast<size_t>(ret) < buf.size()) {
73 result.assign(buf.data(), static_cast<size_t>(ret));
74 } else {
75 // we did not provide a long enough buffer on our first attempt. The
76 // return value is the number of bytes (excluding the null byte) that are
77 // needed for formatting.
78 size_t size_with_null = static_cast<size_t>(ret) + 1;
79 result.__resize_default_init(size_with_null - 1);
80 ret = ::vsnprintf(&result[0], size_with_null, msg, ap);
81 _LIBCPP_ASSERT(static_cast<size_t>(ret) == (size_with_null - 1), "TODO");
9882 }
99
100 // we did not provide a long enough buffer on our first attempt. The
101 // return value is the number of bytes (excluding the null byte) that are
102 // needed for formatting.
103 size_with_null = static_cast<size_t>(ret) + 1;
104 result.__resize_default_init(size_with_null - 1);
105 ret = ::vsnprintf(&result[0], size_with_null, msg, args);
106 _LIBCPP_ASSERT(static_cast<size_t>(ret) == (size_with_null - 1), "TODO");
107
10883 return result;
10984}
11085
111const path::value_type* unwrap(path::string_type const& s) { return s.c_str(); }
112const path::value_type* unwrap(path const& p) { return p.native().c_str(); }
113template <class Arg>
114Arg const& unwrap(Arg const& a) {
115 static_assert(!is_class<Arg>::value, "cannot pass class here");
116 return a;
117}
118
119template <class... Args>
120string format_string(const char* fmt, Args const&... args) {
121 return format_string_imp(fmt, unwrap(args)...);
86static _LIBCPP_FORMAT_PRINTF(1, 2) string
87format_string(const char* msg, ...) {
88 string ret;
89 va_list ap;
90 va_start(ap, msg);
91#ifndef _LIBCPP_NO_EXCEPTIONS
92 try {
93#endif // _LIBCPP_NO_EXCEPTIONS
94 ret = format_string_impl(msg, ap);
95#ifndef _LIBCPP_NO_EXCEPTIONS
96 } catch (...) {
97 va_end(ap);
98 throw;
99 }
100#endif // _LIBCPP_NO_EXCEPTIONS
101 va_end(ap);
102 return ret;
122103}
123104
124105error_code capture_errno() {
......@@ -190,14 +171,14 @@ struct ErrorHandler {
190171 _LIBCPP_UNREACHABLE();
191172 }
192173
193 template <class... Args>
194 T report(const error_code& ec, const char* msg, Args const&... args) const {
174 _LIBCPP_FORMAT_PRINTF(3, 0)
175 void report_impl(const error_code& ec, const char* msg, va_list ap) const {
195176 if (ec_) {
196177 *ec_ = ec;
197 return error_value<T>();
178 return;
198179 }
199180 string what =
200 string("in ") + func_name_ + ": " + format_string(msg, args...);
181 string("in ") + func_name_ + ": " + format_string_impl(msg, ap);
201182 switch (bool(p1_) + bool(p2_)) {
202183 case 0:
203184 __throw_filesystem_error(what, ec);
......@@ -209,11 +190,44 @@ struct ErrorHandler {
209190 _LIBCPP_UNREACHABLE();
210191 }
211192
212 T report(errc const& err) const { return report(make_error_code(err)); }
193 _LIBCPP_FORMAT_PRINTF(3, 4)
194 T report(const error_code& ec, const char* msg, ...) const {
195 va_list ap;
196 va_start(ap, msg);
197#ifndef _LIBCPP_NO_EXCEPTIONS
198 try {
199#endif // _LIBCPP_NO_EXCEPTIONS
200 report_impl(ec, msg, ap);
201#ifndef _LIBCPP_NO_EXCEPTIONS
202 } catch (...) {
203 va_end(ap);
204 throw;
205 }
206#endif // _LIBCPP_NO_EXCEPTIONS
207 va_end(ap);
208 return error_value<T>();
209 }
210
211 T report(errc const& err) const {
212 return report(make_error_code(err));
213 }
213214
214 template <class... Args>
215 T report(errc const& err, const char* msg, Args const&... args) const {
216 return report(make_error_code(err), msg, args...);
215 _LIBCPP_FORMAT_PRINTF(3, 4)
216 T report(errc const& err, const char* msg, ...) const {
217 va_list ap;
218 va_start(ap, msg);
219#ifndef _LIBCPP_NO_EXCEPTIONS
220 try {
221#endif // _LIBCPP_NO_EXCEPTIONS
222 report_impl(make_error_code(err), msg, ap);
223#ifndef _LIBCPP_NO_EXCEPTIONS
224 } catch (...) {
225 va_end(ap);
226 throw;
227 }
228#endif // _LIBCPP_NO_EXCEPTIONS
229 va_end(ap);
230 return error_value<T>();
217231 }
218232
219233private:
......@@ -224,9 +238,41 @@ private:
224238using chrono::duration;
225239using chrono::duration_cast;
226240
241#if defined(_LIBCPP_WIN32API)
242// Various C runtime versions (UCRT, or the legacy msvcrt.dll used by
243// some mingw toolchains) provide different stat function implementations,
244// with a number of limitations with respect to what we want from the
245// stat function. Instead provide our own (in the anonymous detail namespace
246// in posix_compat.h) which does exactly what we want, along with our own
247// stat structure and flag macros.
248
249struct TimeSpec {
250 int64_t tv_sec;
251 int64_t tv_nsec;
252};
253struct StatT {
254 unsigned st_mode;
255 TimeSpec st_atim;
256 TimeSpec st_mtim;
257 uint64_t st_dev; // FILE_ID_INFO::VolumeSerialNumber
258 struct FileIdStruct {
259 unsigned char id[16]; // FILE_ID_INFO::FileId
260 bool operator==(const FileIdStruct &other) const {
261 for (int i = 0; i < 16; i++)
262 if (id[i] != other.id[i])
263 return false;
264 return true;
265 }
266 } st_ino;
267 uint32_t st_nlink;
268 uintmax_t st_size;
269};
270
271#else
227272using TimeSpec = struct timespec;
228273using TimeVal = struct timeval;
229274using StatT = struct stat;
275#endif
230276
231277template <class FileTimeT, class TimeT,
232278 bool IsFloat = is_floating_point<typename FileTimeT::rep>::value>
......@@ -255,8 +301,7 @@ struct time_util_base {
255301 .count();
256302
257303private:
258#if _LIBCPP_STD_VER > 11 && !defined(_LIBCPP_HAS_NO_CXX14_CONSTEXPR)
259 static constexpr fs_duration get_min_nsecs() {
304 static _LIBCPP_CONSTEXPR_AFTER_CXX11 fs_duration get_min_nsecs() {
260305 return duration_cast<fs_duration>(
261306 fs_nanoseconds(min_nsec_timespec) -
262307 duration_cast<fs_nanoseconds>(fs_seconds(1)));
......@@ -266,7 +311,7 @@ private:
266311 FileTimeT::duration::min(),
267312 "value doesn't roundtrip");
268313
269 static constexpr bool check_range() {
314 static _LIBCPP_CONSTEXPR_AFTER_CXX11 bool check_range() {
270315 // This kinda sucks, but it's what happens when we don't have __int128_t.
271316 if (sizeof(TimeT) == sizeof(rep)) {
272317 typedef duration<long long, ratio<3600 * 24 * 365> > Years;
......@@ -277,7 +322,6 @@ private:
277322 min_seconds <= numeric_limits<TimeT>::min();
278323 }
279324 static_assert(check_range(), "the representable range is unacceptable small");
280#endif
281325};
282326
283327template <class FileTimeT, class TimeT>
......@@ -405,7 +449,11 @@ public:
405449 }
406450};
407451
452#if defined(_LIBCPP_WIN32API)
453using fs_time = time_util<file_time_type, int64_t, TimeSpec>;
454#else
408455using fs_time = time_util<file_time_type, time_t, TimeSpec>;
456#endif
409457
410458#if defined(__APPLE__)
411459inline TimeSpec extract_mtime(StatT const& st) { return st.st_mtimespec; }
......@@ -419,11 +467,21 @@ inline TimeSpec extract_atime(StatT const& st) {
419467 TimeSpec TS = {st.st_atime, 0};
420468 return TS;
421469}
470#elif defined(_AIX)
471inline TimeSpec extract_mtime(StatT const& st) {
472 TimeSpec TS = {st.st_mtime, st.st_mtime_n};
473 return TS;
474}
475inline TimeSpec extract_atime(StatT const& st) {
476 TimeSpec TS = {st.st_atime, st.st_atime_n};
477 return TS;
478}
422479#else
423480inline TimeSpec extract_mtime(StatT const& st) { return st.st_mtim; }
424481inline TimeSpec extract_atime(StatT const& st) { return st.st_atim; }
425482#endif
426483
484#if !defined(_LIBCPP_WIN32API)
427485inline TimeVal make_timeval(TimeSpec const& ts) {
428486 using namespace chrono;
429487 auto Convert = [](long nsec) {
......@@ -466,6 +524,7 @@ bool set_file_times(const path& p, std::array<TimeSpec, 2> const& TS,
466524 return posix_utimensat(p, TS, ec);
467525#endif
468526}
527#endif /* !_LIBCPP_WIN32API */
469528
470529} // namespace
471530} // end namespace detail
lib/libcxx/src/filesystem/operations.cpp+232-145
......@@ -17,6 +17,8 @@
1717
1818#include "filesystem_common.h"
1919
20#include "posix_compat.h"
21
2022#if defined(_LIBCPP_WIN32API)
2123# define WIN32_LEAN_AND_MEAN
2224# define NOMINMAX
......@@ -40,7 +42,7 @@
4042# define _LIBCPP_FILESYSTEM_USE_FSTREAM
4143#endif
4244
43#if !defined(CLOCK_REALTIME)
45#if !defined(CLOCK_REALTIME) && !defined(_LIBCPP_WIN32API)
4446# include <sys/time.h> // for gettimeofday and timeval
4547#endif
4648
......@@ -62,6 +64,10 @@ bool isSeparator(path::value_type C) {
6264 return false;
6365}
6466
67bool isDriveLetter(path::value_type C) {
68 return (C >= 'a' && C <= 'z') || (C >= 'A' && C <= 'Z');
69}
70
6571namespace parser {
6672
6773using string_view_t = path::__string_view;
......@@ -118,7 +124,13 @@ public:
118124
119125 switch (State) {
120126 case PS_BeforeBegin: {
121 PosPtr TkEnd = consumeSeparator(Start, End);
127 PosPtr TkEnd = consumeRootName(Start, End);
128 if (TkEnd)
129 return makeState(PS_InRootName, Start, TkEnd);
130 }
131 _LIBCPP_FALLTHROUGH();
132 case PS_InRootName: {
133 PosPtr TkEnd = consumeAllSeparators(Start, End);
122134 if (TkEnd)
123135 return makeState(PS_InRootDir, Start, TkEnd);
124136 else
......@@ -128,7 +140,7 @@ public:
128140 return makeState(PS_InFilenames, Start, consumeName(Start, End));
129141
130142 case PS_InFilenames: {
131 PosPtr SepEnd = consumeSeparator(Start, End);
143 PosPtr SepEnd = consumeAllSeparators(Start, End);
132144 if (SepEnd != End) {
133145 PosPtr TkEnd = consumeName(SepEnd, End);
134146 if (TkEnd)
......@@ -140,7 +152,6 @@ public:
140152 case PS_InTrailingSep:
141153 return makeState(PS_AtEnd);
142154
143 case PS_InRootName:
144155 case PS_AtEnd:
145156 _LIBCPP_UNREACHABLE();
146157 }
......@@ -155,12 +166,18 @@ public:
155166 switch (State) {
156167 case PS_AtEnd: {
157168 // Try to consume a trailing separator or root directory first.
158 if (PosPtr SepEnd = consumeSeparator(RStart, REnd)) {
169 if (PosPtr SepEnd = consumeAllSeparators(RStart, REnd)) {
159170 if (SepEnd == REnd)
160171 return makeState(PS_InRootDir, Path.data(), RStart + 1);
172 PosPtr TkStart = consumeRootName(SepEnd, REnd);
173 if (TkStart == REnd)
174 return makeState(PS_InRootDir, RStart, RStart + 1);
161175 return makeState(PS_InTrailingSep, SepEnd + 1, RStart + 1);
162176 } else {
163 PosPtr TkStart = consumeName(RStart, REnd);
177 PosPtr TkStart = consumeRootName(RStart, REnd);
178 if (TkStart == REnd)
179 return makeState(PS_InRootName, TkStart + 1, RStart + 1);
180 TkStart = consumeName(RStart, REnd);
164181 return makeState(PS_InFilenames, TkStart + 1, RStart + 1);
165182 }
166183 }
......@@ -168,14 +185,20 @@ public:
168185 return makeState(PS_InFilenames, consumeName(RStart, REnd) + 1,
169186 RStart + 1);
170187 case PS_InFilenames: {
171 PosPtr SepEnd = consumeSeparator(RStart, REnd);
188 PosPtr SepEnd = consumeAllSeparators(RStart, REnd);
172189 if (SepEnd == REnd)
173190 return makeState(PS_InRootDir, Path.data(), RStart + 1);
174 PosPtr TkEnd = consumeName(SepEnd, REnd);
175 return makeState(PS_InFilenames, TkEnd + 1, SepEnd + 1);
191 PosPtr TkStart = consumeRootName(SepEnd ? SepEnd : RStart, REnd);
192 if (TkStart == REnd) {
193 if (SepEnd)
194 return makeState(PS_InRootDir, SepEnd + 1, RStart + 1);
195 return makeState(PS_InRootName, TkStart + 1, RStart + 1);
196 }
197 TkStart = consumeName(SepEnd, REnd);
198 return makeState(PS_InFilenames, TkStart + 1, SepEnd + 1);
176199 }
177200 case PS_InRootDir:
178 // return makeState(PS_InRootName, Path.data(), RStart + 1);
201 return makeState(PS_InRootName, Path.data(), RStart + 1);
179202 case PS_InRootName:
180203 case PS_BeforeBegin:
181204 _LIBCPP_UNREACHABLE();
......@@ -281,8 +304,9 @@ private:
281304 _LIBCPP_UNREACHABLE();
282305 }
283306
284 PosPtr consumeSeparator(PosPtr P, PosPtr End) const noexcept {
285 if (P == End || !isSeparator(*P))
307 // Consume all consecutive separators.
308 PosPtr consumeAllSeparators(PosPtr P, PosPtr End) const noexcept {
309 if (P == nullptr || P == End || !isSeparator(*P))
286310 return nullptr;
287311 const int Inc = P < End ? 1 : -1;
288312 P += Inc;
......@@ -291,15 +315,72 @@ private:
291315 return P;
292316 }
293317
318 // Consume exactly N separators, or return nullptr.
319 PosPtr consumeNSeparators(PosPtr P, PosPtr End, int N) const noexcept {
320 PosPtr Ret = consumeAllSeparators(P, End);
321 if (Ret == nullptr)
322 return nullptr;
323 if (P < End) {
324 if (Ret == P + N)
325 return Ret;
326 } else {
327 if (Ret == P - N)
328 return Ret;
329 }
330 return nullptr;
331 }
332
294333 PosPtr consumeName(PosPtr P, PosPtr End) const noexcept {
295 if (P == End || isSeparator(*P))
334 PosPtr Start = P;
335 if (P == nullptr || P == End || isSeparator(*P))
296336 return nullptr;
297337 const int Inc = P < End ? 1 : -1;
298338 P += Inc;
299339 while (P != End && !isSeparator(*P))
300340 P += Inc;
341 if (P == End && Inc < 0) {
342 // Iterating backwards and consumed all the rest of the input.
343 // Check if the start of the string would have been considered
344 // a root name.
345 PosPtr RootEnd = consumeRootName(End + 1, Start);
346 if (RootEnd)
347 return RootEnd - 1;
348 }
301349 return P;
302350 }
351
352 PosPtr consumeDriveLetter(PosPtr P, PosPtr End) const noexcept {
353 if (P == End)
354 return nullptr;
355 if (P < End) {
356 if (P + 1 == End || !isDriveLetter(P[0]) || P[1] != ':')
357 return nullptr;
358 return P + 2;
359 } else {
360 if (P - 1 == End || !isDriveLetter(P[-1]) || P[0] != ':')
361 return nullptr;
362 return P - 2;
363 }
364 }
365
366 PosPtr consumeNetworkRoot(PosPtr P, PosPtr End) const noexcept {
367 if (P == End)
368 return nullptr;
369 if (P < End)
370 return consumeName(consumeNSeparators(P, End, 2), End);
371 else
372 return consumeNSeparators(consumeName(P, End), End, 2);
373 }
374
375 PosPtr consumeRootName(PosPtr P, PosPtr End) const noexcept {
376#if defined(_LIBCPP_WIN32API)
377 if (PosPtr Ret = consumeDriveLetter(P, End))
378 return Ret;
379 if (PosPtr Ret = consumeNetworkRoot(P, End))
380 return Ret;
381#endif
382 return nullptr;
383 }
303384};
304385
305386string_view_pair separate_filename(string_view_t const& s) {
......@@ -331,6 +412,7 @@ errc __win_err_to_errc(int err) {
331412 {ERROR_ACCESS_DENIED, errc::permission_denied},
332413 {ERROR_ALREADY_EXISTS, errc::file_exists},
333414 {ERROR_BAD_NETPATH, errc::no_such_file_or_directory},
415 {ERROR_BAD_PATHNAME, errc::no_such_file_or_directory},
334416 {ERROR_BAD_UNIT, errc::no_such_device},
335417 {ERROR_BROKEN_PIPE, errc::broken_pipe},
336418 {ERROR_BUFFER_OVERFLOW, errc::filename_too_long},
......@@ -403,7 +485,7 @@ struct FileDescriptor {
403485 static FileDescriptor create(const path* p, error_code& ec, Args... args) {
404486 ec.clear();
405487 int fd;
406 if ((fd = ::open(p->c_str(), args...)) == -1) {
488 if ((fd = detail::open(p->c_str(), args...)) == -1) {
407489 ec = capture_errno();
408490 return FileDescriptor{p};
409491 }
......@@ -429,7 +511,7 @@ struct FileDescriptor {
429511
430512 void close() noexcept {
431513 if (fd != -1)
432 ::close(fd);
514 detail::close(fd);
433515 fd = -1;
434516 }
435517
......@@ -453,10 +535,6 @@ perms posix_get_perms(const StatT& st) noexcept {
453535 return static_cast<perms>(st.st_mode) & perms::mask;
454536}
455537
456::mode_t posix_convert_perms(perms prms) {
457 return static_cast< ::mode_t>(prms & perms::mask);
458}
459
460538file_status create_file_status(error_code& m_ec, path const& p,
461539 const StatT& path_stat, error_code* ec) {
462540 if (ec)
......@@ -495,7 +573,7 @@ file_status create_file_status(error_code& m_ec, path const& p,
495573
496574file_status posix_stat(path const& p, StatT& path_stat, error_code* ec) {
497575 error_code m_ec;
498 if (::stat(p.c_str(), &path_stat) == -1)
576 if (detail::stat(p.c_str(), &path_stat) == -1)
499577 m_ec = detail::capture_errno();
500578 return create_file_status(m_ec, p, path_stat, ec);
501579}
......@@ -507,7 +585,7 @@ file_status posix_stat(path const& p, error_code* ec) {
507585
508586file_status posix_lstat(path const& p, StatT& path_stat, error_code* ec) {
509587 error_code m_ec;
510 if (::lstat(p.c_str(), &path_stat) == -1)
588 if (detail::lstat(p.c_str(), &path_stat) == -1)
511589 m_ec = detail::capture_errno();
512590 return create_file_status(m_ec, p, path_stat, ec);
513591}
......@@ -519,7 +597,7 @@ file_status posix_lstat(path const& p, error_code* ec) {
519597
520598// http://pubs.opengroup.org/onlinepubs/9699919799/functions/ftruncate.html
521599bool posix_ftruncate(const FileDescriptor& fd, off_t to_size, error_code& ec) {
522 if (::ftruncate(fd.fd, to_size) == -1) {
600 if (detail::ftruncate(fd.fd, to_size) == -1) {
523601 ec = capture_errno();
524602 return true;
525603 }
......@@ -528,7 +606,7 @@ bool posix_ftruncate(const FileDescriptor& fd, off_t to_size, error_code& ec) {
528606}
529607
530608bool posix_fchmod(const FileDescriptor& fd, const StatT& st, error_code& ec) {
531 if (::fchmod(fd.fd, st.st_mode) == -1) {
609 if (detail::fchmod(fd.fd, st.st_mode) == -1) {
532610 ec = capture_errno();
533611 return true;
534612 }
......@@ -545,7 +623,7 @@ file_status FileDescriptor::refresh_status(error_code& ec) {
545623 m_status = file_status{};
546624 m_stat = {};
547625 error_code m_ec;
548 if (::fstat(fd, &m_stat) == -1)
626 if (detail::fstat(fd, &m_stat) == -1)
549627 m_ec = capture_errno();
550628 m_status = create_file_status(m_ec, name, m_stat, &ec);
551629 return m_status;
......@@ -565,7 +643,14 @@ const bool _FilesystemClock::is_steady;
565643
566644_FilesystemClock::time_point _FilesystemClock::now() noexcept {
567645 typedef chrono::duration<rep> __secs;
568#if defined(CLOCK_REALTIME)
646#if defined(_LIBCPP_WIN32API)
647 typedef chrono::duration<rep, nano> __nsecs;
648 FILETIME time;
649 GetSystemTimeAsFileTime(&time);
650 TimeSpec tp = detail::filetime_to_timespec(time);
651 return time_point(__secs(tp.tv_sec) +
652 chrono::duration_cast<duration>(__nsecs(tp.tv_nsec)));
653#elif defined(CLOCK_REALTIME)
569654 typedef chrono::duration<rep, nano> __nsecs;
570655 struct timespec tp;
571656 if (0 != clock_gettime(CLOCK_REALTIME, &tp))
......@@ -582,27 +667,20 @@ _FilesystemClock::time_point _FilesystemClock::now() noexcept {
582667
583668filesystem_error::~filesystem_error() {}
584669
585#if defined(_LIBCPP_WIN32API)
586#define PS_FMT "%ls"
587#else
588#define PS_FMT "%s"
589#endif
590
591670void filesystem_error::__create_what(int __num_paths) {
592671 const char* derived_what = system_error::what();
593672 __storage_->__what_ = [&]() -> string {
594 const path::value_type* p1 = path1().native().empty() ? PS("\"\"") : path1().c_str();
595 const path::value_type* p2 = path2().native().empty() ? PS("\"\"") : path2().c_str();
596673 switch (__num_paths) {
597 default:
674 case 0:
598675 return detail::format_string("filesystem error: %s", derived_what);
599676 case 1:
600 return detail::format_string("filesystem error: %s [" PS_FMT "]", derived_what,
601 p1);
677 return detail::format_string("filesystem error: %s [" PATH_CSTR_FMT "]",
678 derived_what, path1().c_str());
602679 case 2:
603 return detail::format_string("filesystem error: %s [" PS_FMT "] [" PS_FMT "]",
604 derived_what, p1, p2);
680 return detail::format_string("filesystem error: %s [" PATH_CSTR_FMT "] [" PATH_CSTR_FMT "]",
681 derived_what, path1().c_str(), path2().c_str());
605682 }
683 _LIBCPP_UNREACHABLE();
606684 }();
607685}
608686
......@@ -627,20 +705,20 @@ path __canonical(path const& orig_p, error_code* ec) {
627705 ErrorHandler<path> err("canonical", ec, &orig_p, &cwd);
628706
629707 path p = __do_absolute(orig_p, &cwd, ec);
630#if defined(_POSIX_VERSION) && _POSIX_VERSION >= 200112
631 std::unique_ptr<char, decltype(&::free)>
632 hold(::realpath(p.c_str(), nullptr), &::free);
708#if (defined(_POSIX_VERSION) && _POSIX_VERSION >= 200112) || defined(_LIBCPP_WIN32API)
709 std::unique_ptr<path::value_type, decltype(&::free)>
710 hold(detail::realpath(p.c_str(), nullptr), &::free);
633711 if (hold.get() == nullptr)
634712 return err.report(capture_errno());
635713 return {hold.get()};
636714#else
637715 #if defined(__MVS__) && !defined(PATH_MAX)
638 char buff[ _XOPEN_PATH_MAX + 1 ];
716 path::value_type buff[ _XOPEN_PATH_MAX + 1 ];
639717 #else
640 char buff[PATH_MAX + 1];
718 path::value_type buff[PATH_MAX + 1];
641719 #endif
642 char* ret;
643 if ((ret = ::realpath(p.c_str(), buff)) == nullptr)
720 path::value_type* ret;
721 if ((ret = detail::realpath(p.c_str(), buff)) == nullptr)
644722 return err.report(capture_errno());
645723 return {ret};
646724#endif
......@@ -819,8 +897,8 @@ bool __copy_file(const path& from, const path& to, copy_options options,
819897 ErrorHandler<bool> err("copy_file", ec, &to, &from);
820898
821899 error_code m_ec;
822 FileDescriptor from_fd =
823 FileDescriptor::create_with_status(&from, m_ec, O_RDONLY | O_NONBLOCK);
900 FileDescriptor from_fd = FileDescriptor::create_with_status(
901 &from, m_ec, O_RDONLY | O_NONBLOCK | O_BINARY);
824902 if (m_ec)
825903 return err.report(m_ec);
826904
......@@ -872,7 +950,7 @@ bool __copy_file(const path& from, const path& to, copy_options options,
872950
873951 // Don't truncate right away. We may not be opening the file we originally
874952 // looked at; we'll check this later.
875 int to_open_flags = O_WRONLY;
953 int to_open_flags = O_WRONLY | O_BINARY;
876954 if (!to_exists)
877955 to_open_flags |= O_CREAT;
878956 FileDescriptor to_fd = FileDescriptor::create_with_status(
......@@ -908,10 +986,13 @@ void __copy_symlink(const path& existing_symlink, const path& new_symlink,
908986 if (ec && *ec) {
909987 return;
910988 }
911 // NOTE: proposal says you should detect if you should call
912 // create_symlink or create_directory_symlink. I don't think this
913 // is needed with POSIX
914 __create_symlink(real_path, new_symlink, ec);
989#if defined(_LIBCPP_WIN32API)
990 error_code local_ec;
991 if (is_directory(real_path, local_ec))
992 __create_directory_symlink(real_path, new_symlink, ec);
993 else
994#endif
995 __create_symlink(real_path, new_symlink, ec);
915996}
916997
917998bool __create_directories(const path& p, error_code* ec) {
......@@ -932,31 +1013,34 @@ bool __create_directories(const path& p, error_code* ec) {
9321013 if (not status_known(parent_st))
9331014 return err.report(m_ec);
9341015 if (not exists(parent_st)) {
1016 if (parent == p)
1017 return err.report(errc::invalid_argument);
9351018 __create_directories(parent, ec);
9361019 if (ec && *ec) {
9371020 return false;
9381021 }
939 }
1022 } else if (not is_directory(parent_st))
1023 return err.report(errc::not_a_directory);
9401024 }
941 return __create_directory(p, ec);
1025 bool ret = __create_directory(p, &m_ec);
1026 if (m_ec)
1027 return err.report(m_ec);
1028 return ret;
9421029}
9431030
9441031bool __create_directory(const path& p, error_code* ec) {
9451032 ErrorHandler<bool> err("create_directory", ec, &p);
9461033
947 if (::mkdir(p.c_str(), static_cast<int>(perms::all)) == 0)
1034 if (detail::mkdir(p.c_str(), static_cast<int>(perms::all)) == 0)
9481035 return true;
9491036
950 if (errno == EEXIST) {
951 error_code mec = capture_errno();
952 error_code ignored_ec;
953 const file_status st = status(p, ignored_ec);
954 if (!is_directory(st)) {
955 err.report(mec);
956 }
957 } else {
958 err.report(capture_errno());
959 }
1037 if (errno != EEXIST)
1038 return err.report(capture_errno());
1039 error_code mec = capture_errno();
1040 error_code ignored_ec;
1041 const file_status st = status(p, ignored_ec);
1042 if (!is_directory(st))
1043 return err.report(mec);
9601044 return false;
9611045}
9621046
......@@ -965,65 +1049,80 @@ bool __create_directory(path const& p, path const& attributes, error_code* ec) {
9651049
9661050 StatT attr_stat;
9671051 error_code mec;
968 auto st = detail::posix_stat(attributes, attr_stat, &mec);
1052 file_status st = detail::posix_stat(attributes, attr_stat, &mec);
9691053 if (!status_known(st))
9701054 return err.report(mec);
9711055 if (!is_directory(st))
9721056 return err.report(errc::not_a_directory,
9731057 "the specified attribute path is invalid");
9741058
975 if (::mkdir(p.c_str(), attr_stat.st_mode) == 0)
1059 if (detail::mkdir(p.c_str(), attr_stat.st_mode) == 0)
9761060 return true;
9771061
978 if (errno == EEXIST) {
979 error_code mec = capture_errno();
980 error_code ignored_ec;
981 const file_status st = status(p, ignored_ec);
982 if (!is_directory(st)) {
983 err.report(mec);
984 }
985 } else {
986 err.report(capture_errno());
987 }
1062 if (errno != EEXIST)
1063 return err.report(capture_errno());
1064
1065 mec = capture_errno();
1066 error_code ignored_ec;
1067 st = status(p, ignored_ec);
1068 if (!is_directory(st))
1069 return err.report(mec);
9881070 return false;
9891071}
9901072
9911073void __create_directory_symlink(path const& from, path const& to,
9921074 error_code* ec) {
9931075 ErrorHandler<void> err("create_directory_symlink", ec, &from, &to);
994 if (::symlink(from.c_str(), to.c_str()) != 0)
1076 if (detail::symlink_dir(from.c_str(), to.c_str()) == -1)
9951077 return err.report(capture_errno());
9961078}
9971079
9981080void __create_hard_link(const path& from, const path& to, error_code* ec) {
9991081 ErrorHandler<void> err("create_hard_link", ec, &from, &to);
1000 if (::link(from.c_str(), to.c_str()) == -1)
1082 if (detail::link(from.c_str(), to.c_str()) == -1)
10011083 return err.report(capture_errno());
10021084}
10031085
10041086void __create_symlink(path const& from, path const& to, error_code* ec) {
10051087 ErrorHandler<void> err("create_symlink", ec, &from, &to);
1006 if (::symlink(from.c_str(), to.c_str()) == -1)
1088 if (detail::symlink_file(from.c_str(), to.c_str()) == -1)
10071089 return err.report(capture_errno());
10081090}
10091091
10101092path __current_path(error_code* ec) {
10111093 ErrorHandler<path> err("current_path", ec);
10121094
1095#if defined(_LIBCPP_WIN32API) || defined(__GLIBC__) || defined(__APPLE__)
1096 // Common extension outside of POSIX getcwd() spec, without needing to
1097 // preallocate a buffer. Also supported by a number of other POSIX libcs.
1098 int size = 0;
1099 path::value_type* ptr = nullptr;
1100 typedef decltype(&::free) Deleter;
1101 Deleter deleter = &::free;
1102#else
10131103 auto size = ::pathconf(".", _PC_PATH_MAX);
10141104 _LIBCPP_ASSERT(size >= 0, "pathconf returned a 0 as max size");
10151105
1016 auto buff = unique_ptr<char[]>(new char[size + 1]);
1017 char* ret;
1018 if ((ret = ::getcwd(buff.get(), static_cast<size_t>(size))) == nullptr)
1106 auto buff = unique_ptr<path::value_type[]>(new path::value_type[size + 1]);
1107 path::value_type* ptr = buff.get();
1108
1109 // Preallocated buffer, don't free the buffer in the second unique_ptr
1110 // below.
1111 struct Deleter { void operator()(void*) const {} };
1112 Deleter deleter;
1113#endif
1114
1115 unique_ptr<path::value_type, Deleter> hold(detail::getcwd(ptr, size),
1116 deleter);
1117 if (hold.get() == nullptr)
10191118 return err.report(capture_errno(), "call to getcwd failed");
10201119
1021 return {buff.get()};
1120 return {hold.get()};
10221121}
10231122
10241123void __current_path(const path& p, error_code* ec) {
10251124 ErrorHandler<void> err("current_path", ec, &p);
1026 if (::chdir(p.c_str()) == -1)
1125 if (detail::chdir(p.c_str()) == -1)
10271126 err.report(capture_errno());
10281127}
10291128
......@@ -1119,6 +1218,17 @@ void __last_write_time(const path& p, file_time_type new_time, error_code* ec) {
11191218 using detail::fs_time;
11201219 ErrorHandler<void> err("last_write_time", ec, &p);
11211220
1221#if defined(_LIBCPP_WIN32API)
1222 TimeSpec ts;
1223 if (!fs_time::convert_to_timespec(ts, new_time))
1224 return err.report(errc::value_too_large);
1225 detail::WinHandle h(p.c_str(), FILE_WRITE_ATTRIBUTES, 0);
1226 if (!h)
1227 return err.report(detail::make_windows_error(GetLastError()));
1228 FILETIME last_write = timespec_to_filetime(ts);
1229 if (!SetFileTime(h, nullptr, nullptr, &last_write))
1230 return err.report(detail::make_windows_error(GetLastError()));
1231#else
11221232 error_code m_ec;
11231233 array<TimeSpec, 2> tbuf;
11241234#if !defined(_LIBCPP_USE_UTIMENSAT)
......@@ -1140,6 +1250,7 @@ void __last_write_time(const path& p, file_time_type new_time, error_code* ec) {
11401250 detail::set_file_times(p, tbuf, m_ec);
11411251 if (m_ec)
11421252 return err.report(m_ec);
1253#endif
11431254}
11441255
11451256void __permissions(const path& p, perms prms, perm_options opts,
......@@ -1171,11 +1282,11 @@ void __permissions(const path& p, perms prms, perm_options opts,
11711282 else if (remove_perms)
11721283 prms = st.permissions() & ~prms;
11731284 }
1174 const auto real_perms = detail::posix_convert_perms(prms);
1285 const auto real_perms = static_cast<detail::ModeT>(prms & perms::mask);
11751286
11761287#if defined(AT_SYMLINK_NOFOLLOW) && defined(AT_FDCWD)
11771288 const int flags = set_sym_perms ? AT_SYMLINK_NOFOLLOW : 0;
1178 if (::fchmodat(AT_FDCWD, p.c_str(), real_perms, flags) == -1) {
1289 if (detail::fchmodat(AT_FDCWD, p.c_str(), real_perms, flags) == -1) {
11791290 return err.report(capture_errno());
11801291 }
11811292#else
......@@ -1190,21 +1301,25 @@ void __permissions(const path& p, perms prms, perm_options opts,
11901301path __read_symlink(const path& p, error_code* ec) {
11911302 ErrorHandler<path> err("read_symlink", ec, &p);
11921303
1193#ifdef PATH_MAX
1304#if defined(PATH_MAX) || defined(MAX_SYMLINK_SIZE)
11941305 struct NullDeleter { void operator()(void*) const {} };
1306#ifdef MAX_SYMLINK_SIZE
1307 const size_t size = MAX_SYMLINK_SIZE + 1;
1308#else
11951309 const size_t size = PATH_MAX + 1;
1196 char stack_buff[size];
1197 auto buff = std::unique_ptr<char[], NullDeleter>(stack_buff);
1310#endif
1311 path::value_type stack_buff[size];
1312 auto buff = std::unique_ptr<path::value_type[], NullDeleter>(stack_buff);
11981313#else
11991314 StatT sb;
1200 if (::lstat(p.c_str(), &sb) == -1) {
1315 if (detail::lstat(p.c_str(), &sb) == -1) {
12011316 return err.report(capture_errno());
12021317 }
12031318 const size_t size = sb.st_size + 1;
1204 auto buff = unique_ptr<char[]>(new char[size]);
1319 auto buff = unique_ptr<path::value_type[]>(new path::value_type[size]);
12051320#endif
1206 ::ssize_t ret;
1207 if ((ret = ::readlink(p.c_str(), buff.get(), size)) == -1)
1321 detail::SSizeT ret;
1322 if ((ret = detail::readlink(p.c_str(), buff.get(), size)) == -1)
12081323 return err.report(capture_errno());
12091324 _LIBCPP_ASSERT(ret > 0, "TODO");
12101325 if (static_cast<size_t>(ret) >= size)
......@@ -1215,7 +1330,7 @@ path __read_symlink(const path& p, error_code* ec) {
12151330
12161331bool __remove(const path& p, error_code* ec) {
12171332 ErrorHandler<bool> err("remove", ec, &p);
1218 if (::remove(p.c_str()) == -1) {
1333 if (detail::remove(p.c_str()) == -1) {
12191334 if (errno != ENOENT)
12201335 err.report(capture_errno());
12211336 return false;
......@@ -1264,21 +1379,21 @@ uintmax_t __remove_all(const path& p, error_code* ec) {
12641379
12651380void __rename(const path& from, const path& to, error_code* ec) {
12661381 ErrorHandler<void> err("rename", ec, &from, &to);
1267 if (::rename(from.c_str(), to.c_str()) == -1)
1382 if (detail::rename(from.c_str(), to.c_str()) == -1)
12681383 err.report(capture_errno());
12691384}
12701385
12711386void __resize_file(const path& p, uintmax_t size, error_code* ec) {
12721387 ErrorHandler<void> err("resize_file", ec, &p);
1273 if (::truncate(p.c_str(), static_cast< ::off_t>(size)) == -1)
1388 if (detail::truncate(p.c_str(), static_cast< ::off_t>(size)) == -1)
12741389 return err.report(capture_errno());
12751390}
12761391
12771392space_info __space(const path& p, error_code* ec) {
12781393 ErrorHandler<void> err("space", ec, &p);
12791394 space_info si;
1280 struct statvfs m_svfs = {};
1281 if (::statvfs(p.c_str(), &m_svfs) == -1) {
1395 detail::StatVFS m_svfs = {};
1396 if (detail::statvfs(p.c_str(), &m_svfs) == -1) {
12821397 err.report(capture_errno());
12831398 si.capacity = si.free = si.available = static_cast<uintmax_t>(-1);
12841399 return si;
......@@ -1306,6 +1421,19 @@ file_status __symlink_status(const path& p, error_code* ec) {
13061421path __temp_directory_path(error_code* ec) {
13071422 ErrorHandler<path> err("temp_directory_path", ec);
13081423
1424#if defined(_LIBCPP_WIN32API)
1425 wchar_t buf[MAX_PATH];
1426 DWORD retval = GetTempPathW(MAX_PATH, buf);
1427 if (!retval)
1428 return err.report(detail::make_windows_error(GetLastError()));
1429 if (retval > MAX_PATH)
1430 return err.report(errc::filename_too_long);
1431 // GetTempPathW returns a path with a trailing slash, which we
1432 // shouldn't include for consistency.
1433 if (buf[retval-1] == L'\\')
1434 buf[retval-1] = L'\0';
1435 path p(buf);
1436#else
13091437 const char* env_paths[] = {"TMPDIR", "TMP", "TEMP", "TEMPDIR"};
13101438 const char* ret = nullptr;
13111439
......@@ -1316,14 +1444,15 @@ path __temp_directory_path(error_code* ec) {
13161444 ret = "/tmp";
13171445
13181446 path p(ret);
1447#endif
13191448 error_code m_ec;
13201449 file_status st = detail::posix_stat(p, &m_ec);
13211450 if (!status_known(st))
1322 return err.report(m_ec, "cannot access path \"" PS_FMT "\"", p);
1451 return err.report(m_ec, "cannot access path " PATH_CSTR_FMT, p.c_str());
13231452
13241453 if (!exists(st) || !is_directory(st))
1325 return err.report(errc::not_a_directory, "path \"" PS_FMT "\" is not a directory",
1326 p);
1454 return err.report(errc::not_a_directory,
1455 "path " PATH_CSTR_FMT " is not a directory", p.c_str());
13271456
13281457 return p;
13291458}
......@@ -1586,6 +1715,7 @@ path path::lexically_normal() const {
15861715 if (NeedTrailingSep)
15871716 Result /= PS("");
15881717
1718 Result.make_preferred();
15891719 return Result;
15901720}
15911721
......@@ -1806,7 +1936,6 @@ size_t __char_to_wide(const string &str, wchar_t *out, size_t outlen) {
18061936// directory entry definitions
18071937///////////////////////////////////////////////////////////////////////////////
18081938
1809#ifndef _LIBCPP_WIN32API
18101939error_code directory_entry::__do_refresh() noexcept {
18111940 __data_.__reset();
18121941 error_code failure_ec;
......@@ -1860,47 +1989,5 @@ error_code directory_entry::__do_refresh() noexcept {
18601989
18611990 return failure_ec;
18621991}
1863#else
1864error_code directory_entry::__do_refresh() noexcept {
1865 __data_.__reset();
1866 error_code failure_ec;
1867
1868 file_status st = _VSTD_FS::symlink_status(__p_, failure_ec);
1869 if (!status_known(st)) {
1870 __data_.__reset();
1871 return failure_ec;
1872 }
1873
1874 if (!_VSTD_FS::exists(st) || !_VSTD_FS::is_symlink(st)) {
1875 __data_.__cache_type_ = directory_entry::_RefreshNonSymlink;
1876 __data_.__type_ = st.type();
1877 __data_.__non_sym_perms_ = st.permissions();
1878 } else { // we have a symlink
1879 __data_.__sym_perms_ = st.permissions();
1880 // Get the information about the linked entity.
1881 // Ignore errors from stat, since we don't want errors regarding symlink
1882 // resolution to be reported to the user.
1883 error_code ignored_ec;
1884 st = _VSTD_FS::status(__p_, ignored_ec);
1885
1886 __data_.__type_ = st.type();
1887 __data_.__non_sym_perms_ = st.permissions();
1888
1889 // If we failed to resolve the link, then only partially populate the
1890 // cache.
1891 if (!status_known(st)) {
1892 __data_.__cache_type_ = directory_entry::_RefreshSymlinkUnresolved;
1893 return error_code{};
1894 }
1895 __data_.__cache_type_ = directory_entry::_RefreshSymlink;
1896 }
1897
1898 // FIXME: This is currently broken, and the implementation only a placeholder.
1899 // We need to cache last_write_time, file_size, and hard_link_count here before
1900 // the implementation actually works.
1901
1902 return failure_ec;
1903}
1904#endif
19051992
19061993_LIBCPP_END_NAMESPACE_FILESYSTEM
lib/libcxx/src/filesystem/posix_compat.h created+521
......@@ -0,0 +1,521 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9//
10// POSIX-like portability helper functions.
11//
12// These generally behave like the proper posix functions, with these
13// exceptions:
14// On Windows, they take paths in wchar_t* form, instead of char* form.
15// The symlink() function is split into two frontends, symlink_file()
16// and symlink_dir().
17//
18// These are provided within an anonymous namespace within the detail
19// namespace - callers need to include this header and call them as
20// detail::function(), regardless of platform.
21//
22
23#ifndef POSIX_COMPAT_H
24#define POSIX_COMPAT_H
25
26#include "filesystem"
27
28#include "filesystem_common.h"
29
30#if defined(_LIBCPP_WIN32API)
31# define WIN32_LEAN_AND_MEAN
32# define NOMINMAX
33# include <windows.h>
34# include <io.h>
35# include <winioctl.h>
36#else
37# include <unistd.h>
38# include <sys/stat.h>
39# include <sys/statvfs.h>
40#endif
41#include <time.h>
42
43#if defined(_LIBCPP_WIN32API)
44// This struct isn't defined in the normal Windows SDK, but only in the
45// Windows Driver Kit.
46struct LIBCPP_REPARSE_DATA_BUFFER {
47 unsigned long ReparseTag;
48 unsigned short ReparseDataLength;
49 unsigned short Reserved;
50 union {
51 struct {
52 unsigned short SubstituteNameOffset;
53 unsigned short SubstituteNameLength;
54 unsigned short PrintNameOffset;
55 unsigned short PrintNameLength;
56 unsigned long Flags;
57 wchar_t PathBuffer[1];
58 } SymbolicLinkReparseBuffer;
59 struct {
60 unsigned short SubstituteNameOffset;
61 unsigned short SubstituteNameLength;
62 unsigned short PrintNameOffset;
63 unsigned short PrintNameLength;
64 wchar_t PathBuffer[1];
65 } MountPointReparseBuffer;
66 struct {
67 unsigned char DataBuffer[1];
68 } GenericReparseBuffer;
69 };
70};
71#endif
72
73_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
74
75namespace detail {
76namespace {
77
78#if defined(_LIBCPP_WIN32API)
79
80// Various C runtime header sets provide more or less of these. As we
81// provide our own implementation, undef all potential defines from the
82// C runtime headers and provide a complete set of macros of our own.
83
84#undef _S_IFMT
85#undef _S_IFDIR
86#undef _S_IFCHR
87#undef _S_IFIFO
88#undef _S_IFREG
89#undef _S_IFBLK
90#undef _S_IFLNK
91#undef _S_IFSOCK
92
93#define _S_IFMT 0xF000
94#define _S_IFDIR 0x4000
95#define _S_IFCHR 0x2000
96#define _S_IFIFO 0x1000
97#define _S_IFREG 0x8000
98#define _S_IFBLK 0x6000
99#define _S_IFLNK 0xA000
100#define _S_IFSOCK 0xC000
101
102#undef S_ISDIR
103#undef S_ISFIFO
104#undef S_ISCHR
105#undef S_ISREG
106#undef S_ISLNK
107#undef S_ISBLK
108#undef S_ISSOCK
109
110#define S_ISDIR(m) (((m) & _S_IFMT) == _S_IFDIR)
111#define S_ISCHR(m) (((m) & _S_IFMT) == _S_IFCHR)
112#define S_ISFIFO(m) (((m) & _S_IFMT) == _S_IFIFO)
113#define S_ISREG(m) (((m) & _S_IFMT) == _S_IFREG)
114#define S_ISBLK(m) (((m) & _S_IFMT) == _S_IFBLK)
115#define S_ISLNK(m) (((m) & _S_IFMT) == _S_IFLNK)
116#define S_ISSOCK(m) (((m) & _S_IFMT) == _S_IFSOCK)
117
118#define O_NONBLOCK 0
119
120
121// There were 369 years and 89 leap days from the Windows epoch
122// (1601) to the Unix epoch (1970).
123#define FILE_TIME_OFFSET_SECS (uint64_t(369 * 365 + 89) * (24 * 60 * 60))
124
125TimeSpec filetime_to_timespec(LARGE_INTEGER li) {
126 TimeSpec ret;
127 ret.tv_sec = li.QuadPart / 10000000 - FILE_TIME_OFFSET_SECS;
128 ret.tv_nsec = (li.QuadPart % 10000000) * 100;
129 return ret;
130}
131
132TimeSpec filetime_to_timespec(FILETIME ft) {
133 LARGE_INTEGER li;
134 li.LowPart = ft.dwLowDateTime;
135 li.HighPart = ft.dwHighDateTime;
136 return filetime_to_timespec(li);
137}
138
139FILETIME timespec_to_filetime(TimeSpec ts) {
140 LARGE_INTEGER li;
141 li.QuadPart =
142 ts.tv_nsec / 100 + (ts.tv_sec + FILE_TIME_OFFSET_SECS) * 10000000;
143 FILETIME ft;
144 ft.dwLowDateTime = li.LowPart;
145 ft.dwHighDateTime = li.HighPart;
146 return ft;
147}
148
149int set_errno(int e = GetLastError()) {
150 errno = static_cast<int>(__win_err_to_errc(e));
151 return -1;
152}
153
154class WinHandle {
155public:
156 WinHandle(const wchar_t *p, DWORD access, DWORD flags) {
157 h = CreateFileW(
158 p, access, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
159 nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | flags, nullptr);
160 }
161 ~WinHandle() {
162 if (h != INVALID_HANDLE_VALUE)
163 CloseHandle(h);
164 }
165 operator HANDLE() const { return h; }
166 operator bool() const { return h != INVALID_HANDLE_VALUE; }
167
168private:
169 HANDLE h;
170};
171
172int stat_handle(HANDLE h, StatT *buf) {
173 FILE_BASIC_INFO basic;
174 if (!GetFileInformationByHandleEx(h, FileBasicInfo, &basic, sizeof(basic)))
175 return set_errno();
176 memset(buf, 0, sizeof(*buf));
177 buf->st_mtim = filetime_to_timespec(basic.LastWriteTime);
178 buf->st_atim = filetime_to_timespec(basic.LastAccessTime);
179 buf->st_mode = 0555; // Read-only
180 if (!(basic.FileAttributes & FILE_ATTRIBUTE_READONLY))
181 buf->st_mode |= 0222; // Write
182 if (basic.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
183 buf->st_mode |= _S_IFDIR;
184 } else {
185 buf->st_mode |= _S_IFREG;
186 }
187 if (basic.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
188 FILE_ATTRIBUTE_TAG_INFO tag;
189 if (!GetFileInformationByHandleEx(h, FileAttributeTagInfo, &tag,
190 sizeof(tag)))
191 return set_errno();
192 if (tag.ReparseTag == IO_REPARSE_TAG_SYMLINK)
193 buf->st_mode = (buf->st_mode & ~_S_IFMT) | _S_IFLNK;
194 }
195 FILE_STANDARD_INFO standard;
196 if (!GetFileInformationByHandleEx(h, FileStandardInfo, &standard,
197 sizeof(standard)))
198 return set_errno();
199 buf->st_nlink = standard.NumberOfLinks;
200 buf->st_size = standard.EndOfFile.QuadPart;
201 BY_HANDLE_FILE_INFORMATION info;
202 if (!GetFileInformationByHandle(h, &info))
203 return set_errno();
204 buf->st_dev = info.dwVolumeSerialNumber;
205 memcpy(&buf->st_ino.id[0], &info.nFileIndexHigh, 4);
206 memcpy(&buf->st_ino.id[4], &info.nFileIndexLow, 4);
207 return 0;
208}
209
210int stat_file(const wchar_t *path, StatT *buf, DWORD flags) {
211 WinHandle h(path, FILE_READ_ATTRIBUTES, flags);
212 if (!h)
213 return set_errno();
214 int ret = stat_handle(h, buf);
215 return ret;
216}
217
218int stat(const wchar_t *path, StatT *buf) { return stat_file(path, buf, 0); }
219
220int lstat(const wchar_t *path, StatT *buf) {
221 return stat_file(path, buf, FILE_FLAG_OPEN_REPARSE_POINT);
222}
223
224int fstat(int fd, StatT *buf) {
225 HANDLE h = reinterpret_cast<HANDLE>(_get_osfhandle(fd));
226 return stat_handle(h, buf);
227}
228
229int mkdir(const wchar_t *path, int permissions) {
230 (void)permissions;
231 return _wmkdir(path);
232}
233
234int symlink_file_dir(const wchar_t *oldname, const wchar_t *newname,
235 bool is_dir) {
236 path dest(oldname);
237 dest.make_preferred();
238 oldname = dest.c_str();
239 DWORD flags = is_dir ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0;
240 if (CreateSymbolicLinkW(newname, oldname,
241 flags | SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE))
242 return 0;
243 int e = GetLastError();
244 if (e != ERROR_INVALID_PARAMETER)
245 return set_errno(e);
246 if (CreateSymbolicLinkW(newname, oldname, flags))
247 return 0;
248 return set_errno();
249}
250
251int symlink_file(const wchar_t *oldname, const wchar_t *newname) {
252 return symlink_file_dir(oldname, newname, false);
253}
254
255int symlink_dir(const wchar_t *oldname, const wchar_t *newname) {
256 return symlink_file_dir(oldname, newname, true);
257}
258
259int link(const wchar_t *oldname, const wchar_t *newname) {
260 if (CreateHardLinkW(newname, oldname, nullptr))
261 return 0;
262 return set_errno();
263}
264
265int remove(const wchar_t *path) {
266 detail::WinHandle h(path, DELETE, FILE_FLAG_OPEN_REPARSE_POINT);
267 if (!h)
268 return set_errno();
269 FILE_DISPOSITION_INFO info;
270 info.DeleteFile = TRUE;
271 if (!SetFileInformationByHandle(h, FileDispositionInfo, &info, sizeof(info)))
272 return set_errno();
273 return 0;
274}
275
276int truncate_handle(HANDLE h, off_t length) {
277 LARGE_INTEGER size_param;
278 size_param.QuadPart = length;
279 if (!SetFilePointerEx(h, size_param, 0, FILE_BEGIN))
280 return set_errno();
281 if (!SetEndOfFile(h))
282 return set_errno();
283 return 0;
284}
285
286int ftruncate(int fd, off_t length) {
287 HANDLE h = reinterpret_cast<HANDLE>(_get_osfhandle(fd));
288 return truncate_handle(h, length);
289}
290
291int truncate(const wchar_t *path, off_t length) {
292 detail::WinHandle h(path, GENERIC_WRITE, 0);
293 if (!h)
294 return set_errno();
295 return truncate_handle(h, length);
296}
297
298int rename(const wchar_t *from, const wchar_t *to) {
299 if (!(MoveFileExW(from, to,
300 MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING |
301 MOVEFILE_WRITE_THROUGH)))
302 return set_errno();
303 return 0;
304}
305
306template <class... Args> int open(const wchar_t *filename, Args... args) {
307 return _wopen(filename, args...);
308}
309int close(int fd) { return _close(fd); }
310int chdir(const wchar_t *path) { return _wchdir(path); }
311
312struct StatVFS {
313 uint64_t f_frsize;
314 uint64_t f_blocks;
315 uint64_t f_bfree;
316 uint64_t f_bavail;
317};
318
319int statvfs(const wchar_t *p, StatVFS *buf) {
320 path dir = p;
321 while (true) {
322 error_code local_ec;
323 const file_status st = status(dir, local_ec);
324 if (!exists(st) || is_directory(st))
325 break;
326 path parent = dir.parent_path();
327 if (parent == dir) {
328 errno = ENOENT;
329 return -1;
330 }
331 dir = parent;
332 }
333 ULARGE_INTEGER free_bytes_available_to_caller, total_number_of_bytes,
334 total_number_of_free_bytes;
335 if (!GetDiskFreeSpaceExW(dir.c_str(), &free_bytes_available_to_caller,
336 &total_number_of_bytes, &total_number_of_free_bytes))
337 return set_errno();
338 buf->f_frsize = 1;
339 buf->f_blocks = total_number_of_bytes.QuadPart;
340 buf->f_bfree = total_number_of_free_bytes.QuadPart;
341 buf->f_bavail = free_bytes_available_to_caller.QuadPart;
342 return 0;
343}
344
345wchar_t *getcwd(wchar_t *buff, size_t size) { return _wgetcwd(buff, size); }
346
347wchar_t *realpath(const wchar_t *path, wchar_t *resolved_name) {
348 // Only expected to be used with us allocating the buffer.
349 _LIBCPP_ASSERT(resolved_name == nullptr,
350 "Windows realpath() assumes a null resolved_name");
351
352 WinHandle h(path, FILE_READ_ATTRIBUTES, 0);
353 if (!h) {
354 set_errno();
355 return nullptr;
356 }
357 size_t buff_size = MAX_PATH + 10;
358 std::unique_ptr<wchar_t, decltype(&::free)> buff(
359 static_cast<wchar_t *>(malloc(buff_size * sizeof(wchar_t))), &::free);
360 DWORD retval = GetFinalPathNameByHandleW(
361 h, buff.get(), buff_size, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
362 if (retval > buff_size) {
363 buff_size = retval;
364 buff.reset(static_cast<wchar_t *>(malloc(buff_size * sizeof(wchar_t))));
365 retval = GetFinalPathNameByHandleW(h, buff.get(), buff_size,
366 FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
367 }
368 if (!retval) {
369 set_errno();
370 return nullptr;
371 }
372 wchar_t *ptr = buff.get();
373 if (!wcsncmp(ptr, L"\\\\?\\", 4)) {
374 if (ptr[5] == ':') { // \\?\X: -> X:
375 memmove(&ptr[0], &ptr[4], (wcslen(&ptr[4]) + 1) * sizeof(wchar_t));
376 } else if (!wcsncmp(&ptr[4], L"UNC\\", 4)) { // \\?\UNC\server -> \\server
377 wcscpy(&ptr[0], L"\\\\");
378 memmove(&ptr[2], &ptr[8], (wcslen(&ptr[8]) + 1) * sizeof(wchar_t));
379 }
380 }
381 return buff.release();
382}
383
384#define AT_FDCWD -1
385#define AT_SYMLINK_NOFOLLOW 1
386using ModeT = int;
387
388int fchmod_handle(HANDLE h, int perms) {
389 FILE_BASIC_INFO basic;
390 if (!GetFileInformationByHandleEx(h, FileBasicInfo, &basic, sizeof(basic)))
391 return set_errno();
392 DWORD orig_attributes = basic.FileAttributes;
393 basic.FileAttributes &= ~FILE_ATTRIBUTE_READONLY;
394 if ((perms & 0222) == 0)
395 basic.FileAttributes |= FILE_ATTRIBUTE_READONLY;
396 if (basic.FileAttributes != orig_attributes &&
397 !SetFileInformationByHandle(h, FileBasicInfo, &basic, sizeof(basic)))
398 return set_errno();
399 return 0;
400}
401
402int fchmodat(int fd, const wchar_t *path, int perms, int flag) {
403 DWORD attributes = GetFileAttributesW(path);
404 if (attributes == INVALID_FILE_ATTRIBUTES)
405 return set_errno();
406 if (attributes & FILE_ATTRIBUTE_REPARSE_POINT &&
407 !(flag & AT_SYMLINK_NOFOLLOW)) {
408 // If the file is a symlink, and we are supposed to operate on the target
409 // of the symlink, we need to open a handle to it, without the
410 // FILE_FLAG_OPEN_REPARSE_POINT flag, to open the destination of the
411 // symlink, and operate on it via the handle.
412 detail::WinHandle h(path, FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES, 0);
413 if (!h)
414 return set_errno();
415 return fchmod_handle(h, perms);
416 } else {
417 // For a non-symlink, or if operating on the symlink itself instead of
418 // its target, we can use SetFileAttributesW, saving a few calls.
419 DWORD orig_attributes = attributes;
420 attributes &= ~FILE_ATTRIBUTE_READONLY;
421 if ((perms & 0222) == 0)
422 attributes |= FILE_ATTRIBUTE_READONLY;
423 if (attributes != orig_attributes && !SetFileAttributesW(path, attributes))
424 return set_errno();
425 }
426 return 0;
427}
428
429int fchmod(int fd, int perms) {
430 HANDLE h = reinterpret_cast<HANDLE>(_get_osfhandle(fd));
431 return fchmod_handle(h, perms);
432}
433
434#define MAX_SYMLINK_SIZE MAXIMUM_REPARSE_DATA_BUFFER_SIZE
435using SSizeT = ::int64_t;
436
437SSizeT readlink(const wchar_t *path, wchar_t *ret_buf, size_t bufsize) {
438 uint8_t buf[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
439 detail::WinHandle h(path, FILE_READ_ATTRIBUTES, FILE_FLAG_OPEN_REPARSE_POINT);
440 if (!h)
441 return set_errno();
442 DWORD out;
443 if (!DeviceIoControl(h, FSCTL_GET_REPARSE_POINT, nullptr, 0, buf, sizeof(buf),
444 &out, 0))
445 return set_errno();
446 const auto *reparse = reinterpret_cast<LIBCPP_REPARSE_DATA_BUFFER *>(buf);
447 size_t path_buf_offset = offsetof(LIBCPP_REPARSE_DATA_BUFFER,
448 SymbolicLinkReparseBuffer.PathBuffer[0]);
449 if (out < path_buf_offset) {
450 errno = EINVAL;
451 return -1;
452 }
453 if (reparse->ReparseTag != IO_REPARSE_TAG_SYMLINK) {
454 errno = EINVAL;
455 return -1;
456 }
457 const auto &symlink = reparse->SymbolicLinkReparseBuffer;
458 unsigned short name_offset, name_length;
459 if (symlink.PrintNameLength == 0) {
460 name_offset = symlink.SubstituteNameOffset;
461 name_length = symlink.SubstituteNameLength;
462 } else {
463 name_offset = symlink.PrintNameOffset;
464 name_length = symlink.PrintNameLength;
465 }
466 // name_offset/length are expressed in bytes, not in wchar_t
467 if (path_buf_offset + name_offset + name_length > out) {
468 errno = EINVAL;
469 return -1;
470 }
471 if (name_length / sizeof(wchar_t) > bufsize) {
472 errno = ENOMEM;
473 return -1;
474 }
475 memcpy(ret_buf, &symlink.PathBuffer[name_offset / sizeof(wchar_t)],
476 name_length);
477 return name_length / sizeof(wchar_t);
478}
479
480#else
481int symlink_file(const char *oldname, const char *newname) {
482 return ::symlink(oldname, newname);
483}
484int symlink_dir(const char *oldname, const char *newname) {
485 return ::symlink(oldname, newname);
486}
487using ::chdir;
488using ::close;
489using ::fchmod;
490#if defined(AT_SYMLINK_NOFOLLOW) && defined(AT_FDCWD)
491using ::fchmodat;
492#endif
493using ::fstat;
494using ::ftruncate;
495using ::getcwd;
496using ::link;
497using ::lstat;
498using ::mkdir;
499using ::open;
500using ::readlink;
501using ::realpath;
502using ::remove;
503using ::rename;
504using ::stat;
505using ::statvfs;
506using ::truncate;
507
508#define O_BINARY 0
509
510using StatVFS = struct statvfs;
511using ModeT = ::mode_t;
512using SSizeT = ::ssize_t;
513
514#endif
515
516} // namespace
517} // end namespace detail
518
519_LIBCPP_END_NAMESPACE_FILESYSTEM
520
521#endif // POSIX_COMPAT_H
lib/libcxx/src/format.cpp created+19
......@@ -0,0 +1,19 @@
1//===------------------------- format.cpp ---------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "format"
10
11_LIBCPP_BEGIN_NAMESPACE_STD
12
13#if _LIBCPP_STD_VER > 17
14
15format_error::~format_error() noexcept = default;
16
17#endif //_LIBCPP_STD_VER > 17
18
19_LIBCPP_END_NAMESPACE_STD
lib/libcxx/src/functional.cpp+2-2
......@@ -11,12 +11,12 @@
1111_LIBCPP_BEGIN_NAMESPACE_STD
1212
1313#ifdef _LIBCPP_ABI_BAD_FUNCTION_CALL_KEY_FUNCTION
14bad_function_call::~bad_function_call() _NOEXCEPT
14bad_function_call::~bad_function_call() noexcept
1515{
1616}
1717
1818const char*
19bad_function_call::what() const _NOEXCEPT
19bad_function_call::what() const noexcept
2020{
2121 return "std::bad_function_call";
2222}
lib/libcxx/src/future.cpp+5-5
......@@ -19,12 +19,12 @@ class _LIBCPP_HIDDEN __future_error_category
1919 : public __do_message
2020{
2121public:
22 virtual const char* name() const _NOEXCEPT;
22 virtual const char* name() const noexcept;
2323 virtual string message(int ev) const;
2424};
2525
2626const char*
27__future_error_category::name() const _NOEXCEPT
27__future_error_category::name() const noexcept
2828{
2929 return "future";
3030}
......@@ -65,7 +65,7 @@ __future_error_category::message(int ev) const
6565#endif
6666
6767const error_category&
68future_category() _NOEXCEPT
68future_category() noexcept
6969{
7070 static __future_error_category __f;
7171 return __f;
......@@ -77,12 +77,12 @@ future_error::future_error(error_code __ec)
7777{
7878}
7979
80future_error::~future_error() _NOEXCEPT
80future_error::~future_error() noexcept
8181{
8282}
8383
8484void
85__assoc_sub_state::__on_zero_shared() _NOEXCEPT
85__assoc_sub_state::__on_zero_shared() noexcept
8686{
8787 delete this;
8888}
lib/libcxx/src/include/config_elast.h+4
......@@ -35,8 +35,12 @@
3535// No _LIBCPP_ELAST needed on Apple
3636#elif defined(__sun__)
3737#define _LIBCPP_ELAST ESTALE
38#elif defined(__MVS__)
39#define _LIBCPP_ELAST 1160
3840#elif defined(_LIBCPP_MSVCRT_LIKE)
3941#define _LIBCPP_ELAST (_sys_nerr - 1)
42#elif defined(_AIX)
43#define _LIBCPP_ELAST 127
4044#else
4145// Warn here so that the person doing the libcxx port has an easier time:
4246#warning ELAST for this platform not yet implemented
lib/libcxx/src/include/refstring.h+4-4
......@@ -55,7 +55,7 @@ inline char * data_from_rep(_Rep_base *rep) noexcept {
5555
5656#if defined(_LIBCPP_CHECK_FOR_GCC_EMPTY_STRING_STORAGE)
5757inline
58const char* compute_gcc_empty_string_storage() _NOEXCEPT
58const char* compute_gcc_empty_string_storage() noexcept
5959{
6060 void* handle = dlopen("/usr/lib/libstdc++.6.dylib", RTLD_NOLOAD);
6161 if (handle == nullptr)
......@@ -68,7 +68,7 @@ const char* compute_gcc_empty_string_storage() _NOEXCEPT
6868
6969inline
7070const char*
71get_gcc_empty_string_storage() _NOEXCEPT
71get_gcc_empty_string_storage() noexcept
7272{
7373 static const char* p = compute_gcc_empty_string_storage();
7474 return p;
......@@ -92,7 +92,7 @@ __libcpp_refstring::__libcpp_refstring(const char* msg) {
9292}
9393
9494inline
95__libcpp_refstring::__libcpp_refstring(const __libcpp_refstring &s) _NOEXCEPT
95__libcpp_refstring::__libcpp_refstring(const __libcpp_refstring &s) noexcept
9696 : __imp_(s.__imp_)
9797{
9898 if (__uses_refcount())
......@@ -100,7 +100,7 @@ __libcpp_refstring::__libcpp_refstring(const __libcpp_refstring &s) _NOEXCEPT
100100}
101101
102102inline
103__libcpp_refstring& __libcpp_refstring::operator=(__libcpp_refstring const& s) _NOEXCEPT {
103__libcpp_refstring& __libcpp_refstring::operator=(__libcpp_refstring const& s) noexcept {
104104 bool adjust_old_count = __uses_refcount();
105105 struct _Rep_base *old_rep = rep_from_data(__imp_);
106106 __imp_ = s.__imp_;
lib/libcxx/src/include/sso_allocator.h created+77
......@@ -0,0 +1,77 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP_SSO_ALLOCATOR_H
11#define _LIBCPP_SSO_ALLOCATOR_H
12
13#include <__config>
14#include <memory>
15#include <new>
16#include <type_traits>
17
18#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
19#pragma GCC system_header
20#endif
21
22_LIBCPP_BEGIN_NAMESPACE_STD
23
24template <class _Tp, size_t _Np> class _LIBCPP_HIDDEN __sso_allocator;
25
26template <size_t _Np>
27class _LIBCPP_HIDDEN __sso_allocator<void, _Np>
28{
29public:
30 typedef const void* const_pointer;
31 typedef void value_type;
32};
33
34template <class _Tp, size_t _Np>
35class _LIBCPP_HIDDEN __sso_allocator
36{
37 typename aligned_storage<sizeof(_Tp) * _Np>::type buf_;
38 bool __allocated_;
39public:
40 typedef size_t size_type;
41 typedef _Tp* pointer;
42 typedef _Tp value_type;
43
44 _LIBCPP_INLINE_VISIBILITY __sso_allocator() throw() : __allocated_(false) {}
45 _LIBCPP_INLINE_VISIBILITY __sso_allocator(const __sso_allocator&) throw() : __allocated_(false) {}
46 template <class _Up> _LIBCPP_INLINE_VISIBILITY __sso_allocator(const __sso_allocator<_Up, _Np>&) throw()
47 : __allocated_(false) {}
48private:
49 __sso_allocator& operator=(const __sso_allocator&);
50public:
51 _LIBCPP_INLINE_VISIBILITY pointer allocate(size_type __n, typename __sso_allocator<void, _Np>::const_pointer = nullptr)
52 {
53 if (!__allocated_ && __n <= _Np)
54 {
55 __allocated_ = true;
56 return (pointer)&buf_;
57 }
58 return allocator<_Tp>().allocate(__n);
59 }
60 _LIBCPP_INLINE_VISIBILITY void deallocate(pointer __p, size_type __n)
61 {
62 if (__p == (pointer)&buf_)
63 __allocated_ = false;
64 else
65 allocator<_Tp>().deallocate(__p, __n);
66 }
67 _LIBCPP_INLINE_VISIBILITY size_type max_size() const throw() {return size_type(~0) / sizeof(_Tp);}
68
69 _LIBCPP_INLINE_VISIBILITY
70 bool operator==(const __sso_allocator& __a) const {return &buf_ == &__a.buf_;}
71 _LIBCPP_INLINE_VISIBILITY
72 bool operator!=(const __sso_allocator& __a) const {return &buf_ != &__a.buf_;}
73};
74
75_LIBCPP_END_NAMESPACE_STD
76
77#endif // _LIBCPP_SSO_ALLOCATOR_H
lib/libcxx/src/ios.cpp+7-7
......@@ -27,12 +27,12 @@ class _LIBCPP_HIDDEN __iostream_category
2727 : public __do_message
2828{
2929public:
30 virtual const char* name() const _NOEXCEPT;
30 virtual const char* name() const noexcept;
3131 virtual string message(int ev) const;
3232};
3333
3434const char*
35__iostream_category::name() const _NOEXCEPT
35__iostream_category::name() const noexcept
3636{
3737 return "iostream";
3838}
......@@ -43,14 +43,14 @@ __iostream_category::message(int ev) const
4343 if (ev != static_cast<int>(io_errc::stream)
4444#ifdef _LIBCPP_ELAST
4545 && ev <= _LIBCPP_ELAST
46#endif // _LIBCPP_ELAST
46#endif // _LIBCPP_ELAST
4747 )
4848 return __do_message::message(ev);
4949 return string("unspecified iostream_category error");
5050}
5151
5252const error_category&
53iostream_category() _NOEXCEPT
53iostream_category() noexcept
5454{
5555 static __iostream_category s;
5656 return s;
......@@ -387,7 +387,7 @@ ios_base::move(ios_base& rhs)
387387}
388388
389389void
390ios_base::swap(ios_base& rhs) _NOEXCEPT
390ios_base::swap(ios_base& rhs) noexcept
391391{
392392 _VSTD::swap(__fmtflags_, rhs.__fmtflags_);
393393 _VSTD::swap(__precision_, rhs.__precision_);
......@@ -416,7 +416,7 @@ ios_base::__set_badbit_and_consider_rethrow()
416416#ifndef _LIBCPP_NO_EXCEPTIONS
417417 if (__exceptions_ & badbit)
418418 throw;
419#endif // _LIBCPP_NO_EXCEPTIONS
419#endif // _LIBCPP_NO_EXCEPTIONS
420420}
421421
422422void
......@@ -426,7 +426,7 @@ ios_base::__set_failbit_and_consider_rethrow()
426426#ifndef _LIBCPP_NO_EXCEPTIONS
427427 if (__exceptions_ & failbit)
428428 throw;
429#endif // _LIBCPP_NO_EXCEPTIONS
429#endif // _LIBCPP_NO_EXCEPTIONS
430430}
431431
432432bool
lib/libcxx/src/locale.cpp+85-82
......@@ -27,7 +27,6 @@
2727#define _CTYPE_DISABLE_MACROS
2828#endif
2929#include "cwctype"
30#include "__sso_allocator"
3130#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
3231#include "__support/win32/locale_win32.h"
3332#elif !defined(__BIONIC__) && !defined(__NuttX__)
......@@ -36,6 +35,7 @@
3635#include <stdlib.h>
3736#include <stdio.h>
3837#include "include/atomic_support.h"
38#include "include/sso_allocator.h"
3939#include "__undef_macros"
4040
4141// On Linux, wint_t and wchar_t have different signed-ness, and this causes
......@@ -206,7 +206,7 @@ _LIBCPP_SUPPRESS_DEPRECATED_PUSH
206206 install(&make<codecvt<char16_t, char, mbstate_t> >(1u));
207207 install(&make<codecvt<char32_t, char, mbstate_t> >(1u));
208208_LIBCPP_SUPPRESS_DEPRECATED_POP
209#ifndef _LIBCPP_NO_HAS_CHAR8_T
209#ifndef _LIBCPP_HAS_NO_CHAR8_T
210210 install(&make<codecvt<char16_t, char8_t, mbstate_t> >(1u));
211211 install(&make<codecvt<char32_t, char8_t, mbstate_t> >(1u));
212212#endif
......@@ -240,7 +240,7 @@ locale::__imp::__imp(const string& name, size_t refs)
240240#ifndef _LIBCPP_NO_EXCEPTIONS
241241 try
242242 {
243#endif // _LIBCPP_NO_EXCEPTIONS
243#endif // _LIBCPP_NO_EXCEPTIONS
244244 facets_ = locale::classic().__locale_->facets_;
245245 for (unsigned i = 0; i < facets_.size(); ++i)
246246 if (facets_[i])
......@@ -255,7 +255,7 @@ _LIBCPP_SUPPRESS_DEPRECATED_PUSH
255255 install(new codecvt_byname<char16_t, char, mbstate_t>(name_));
256256 install(new codecvt_byname<char32_t, char, mbstate_t>(name_));
257257_LIBCPP_SUPPRESS_DEPRECATED_POP
258#ifndef _LIBCPP_NO_HAS_CHAR8_T
258#ifndef _LIBCPP_HAS_NO_CHAR8_T
259259 install(new codecvt_byname<char16_t, char8_t, mbstate_t>(name_));
260260 install(new codecvt_byname<char32_t, char8_t, mbstate_t>(name_));
261261#endif
......@@ -280,7 +280,7 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP
280280 facets_[i]->__release_shared();
281281 throw;
282282 }
283#endif // _LIBCPP_NO_EXCEPTIONS
283#endif // _LIBCPP_NO_EXCEPTIONS
284284}
285285
286286// NOTE avoid the `base class should be explicitly initialized in the
......@@ -315,7 +315,7 @@ locale::__imp::__imp(const __imp& other, const string& name, locale::category c)
315315#ifndef _LIBCPP_NO_EXCEPTIONS
316316 try
317317 {
318#endif // _LIBCPP_NO_EXCEPTIONS
318#endif // _LIBCPP_NO_EXCEPTIONS
319319 if (c & locale::collate)
320320 {
321321 install(new collate_byname<char>(name));
......@@ -331,7 +331,7 @@ _LIBCPP_SUPPRESS_DEPRECATED_PUSH
331331 install(new codecvt_byname<char16_t, char, mbstate_t>(name));
332332 install(new codecvt_byname<char32_t, char, mbstate_t>(name));
333333_LIBCPP_SUPPRESS_DEPRECATED_POP
334#ifndef _LIBCPP_NO_HAS_CHAR8_T
334#ifndef _LIBCPP_HAS_NO_CHAR8_T
335335 install(new codecvt_byname<char16_t, char8_t, mbstate_t>(name));
336336 install(new codecvt_byname<char32_t, char8_t, mbstate_t>(name));
337337#endif
......@@ -369,7 +369,7 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP
369369 facets_[i]->__release_shared();
370370 throw;
371371 }
372#endif // _LIBCPP_NO_EXCEPTIONS
372#endif // _LIBCPP_NO_EXCEPTIONS
373373}
374374
375375template<class F>
......@@ -392,7 +392,7 @@ locale::__imp::__imp(const __imp& other, const __imp& one, locale::category c)
392392#ifndef _LIBCPP_NO_EXCEPTIONS
393393 try
394394 {
395#endif // _LIBCPP_NO_EXCEPTIONS
395#endif // _LIBCPP_NO_EXCEPTIONS
396396 if (c & locale::collate)
397397 {
398398 install_from<_VSTD::collate<char> >(one);
......@@ -407,7 +407,7 @@ _LIBCPP_SUPPRESS_DEPRECATED_PUSH
407407 install_from<_VSTD::codecvt<char16_t, char, mbstate_t> >(one);
408408 install_from<_VSTD::codecvt<char32_t, char, mbstate_t> >(one);
409409_LIBCPP_SUPPRESS_DEPRECATED_POP
410#ifndef _LIBCPP_NO_HAS_CHAR8_T
410#ifndef _LIBCPP_HAS_NO_CHAR8_T
411411 install_from<_VSTD::codecvt<char16_t, char8_t, mbstate_t> >(one);
412412 install_from<_VSTD::codecvt<char32_t, char8_t, mbstate_t> >(one);
413413#endif
......@@ -454,7 +454,7 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP
454454 facets_[i]->__release_shared();
455455 throw;
456456 }
457#endif // _LIBCPP_NO_EXCEPTIONS
457#endif // _LIBCPP_NO_EXCEPTIONS
458458}
459459
460460locale::__imp::__imp(const __imp& other, facet* f, long id)
......@@ -532,13 +532,13 @@ locale::__global()
532532 return g;
533533}
534534
535locale::locale() _NOEXCEPT
535locale::locale() noexcept
536536 : __locale_(__global().__locale_)
537537{
538538 __locale_->__add_shared();
539539}
540540
541locale::locale(const locale& l) _NOEXCEPT
541locale::locale(const locale& l) noexcept
542542 : __locale_(l.__locale_)
543543{
544544 __locale_->__add_shared();
......@@ -550,7 +550,7 @@ locale::~locale()
550550}
551551
552552const locale&
553locale::operator=(const locale& other) _NOEXCEPT
553locale::operator=(const locale& other) noexcept
554554{
555555 other.__locale_->__add_shared();
556556 __locale_->__release_shared();
......@@ -643,7 +643,7 @@ locale::facet::~facet()
643643}
644644
645645void
646locale::facet::__on_zero_shared() _NOEXCEPT
646locale::facet::__on_zero_shared() noexcept
647647{
648648 delete this;
649649}
......@@ -1051,7 +1051,7 @@ extern "C" const int ** __ctype_toupper_loc();
10511051
10521052#ifdef _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE
10531053const ctype<char>::mask*
1054ctype<char>::classic_table() _NOEXCEPT
1054ctype<char>::classic_table() noexcept
10551055{
10561056 static _LIBCPP_CONSTEXPR const ctype<char>::mask builtin_table[table_size] = {
10571057 cntrl, cntrl,
......@@ -1131,7 +1131,7 @@ ctype<char>::classic_table() _NOEXCEPT
11311131}
11321132#else
11331133const ctype<char>::mask*
1134ctype<char>::classic_table() _NOEXCEPT
1134ctype<char>::classic_table() noexcept
11351135{
11361136#if defined(__APPLE__) || defined(__FreeBSD__)
11371137 return _DefaultRuneLocale.__runetype;
......@@ -1139,7 +1139,7 @@ ctype<char>::classic_table() _NOEXCEPT
11391139 return _C_ctype_tab_ + 1;
11401140#elif defined(__GLIBC__)
11411141 return _LIBCPP_GET_C_LOCALE->__ctype_b;
1142#elif __sun__
1142#elif defined(__sun__)
11431143 return __ctype_mask;
11441144#elif defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
11451145 return __pctype_func();
......@@ -1163,38 +1163,38 @@ ctype<char>::classic_table() _NOEXCEPT
11631163
11641164#if defined(__GLIBC__)
11651165const int*
1166ctype<char>::__classic_lower_table() _NOEXCEPT
1166ctype<char>::__classic_lower_table() noexcept
11671167{
11681168 return _LIBCPP_GET_C_LOCALE->__ctype_tolower;
11691169}
11701170
11711171const int*
1172ctype<char>::__classic_upper_table() _NOEXCEPT
1172ctype<char>::__classic_upper_table() noexcept
11731173{
11741174 return _LIBCPP_GET_C_LOCALE->__ctype_toupper;
11751175}
11761176#elif defined(__NetBSD__)
11771177const short*
1178ctype<char>::__classic_lower_table() _NOEXCEPT
1178ctype<char>::__classic_lower_table() noexcept
11791179{
11801180 return _C_tolower_tab_ + 1;
11811181}
11821182
11831183const short*
1184ctype<char>::__classic_upper_table() _NOEXCEPT
1184ctype<char>::__classic_upper_table() noexcept
11851185{
11861186 return _C_toupper_tab_ + 1;
11871187}
11881188
11891189#elif defined(__EMSCRIPTEN__)
11901190const int*
1191ctype<char>::__classic_lower_table() _NOEXCEPT
1191ctype<char>::__classic_lower_table() noexcept
11921192{
11931193 return *__ctype_tolower_loc();
11941194}
11951195
11961196const int*
1197ctype<char>::__classic_upper_table() _NOEXCEPT
1197ctype<char>::__classic_upper_table() noexcept
11981198{
11991199 return *__ctype_toupper_loc();
12001200}
......@@ -1492,13 +1492,13 @@ codecvt<char, char, mbstate_t>::do_unshift(state_type&,
14921492}
14931493
14941494int
1495codecvt<char, char, mbstate_t>::do_encoding() const _NOEXCEPT
1495codecvt<char, char, mbstate_t>::do_encoding() const noexcept
14961496{
14971497 return 1;
14981498}
14991499
15001500bool
1501codecvt<char, char, mbstate_t>::do_always_noconv() const _NOEXCEPT
1501codecvt<char, char, mbstate_t>::do_always_noconv() const noexcept
15021502{
15031503 return true;
15041504}
......@@ -1511,7 +1511,7 @@ codecvt<char, char, mbstate_t>::do_length(state_type&,
15111511}
15121512
15131513int
1514codecvt<char, char, mbstate_t>::do_max_length() const _NOEXCEPT
1514codecvt<char, char, mbstate_t>::do_max_length() const noexcept
15151515{
15161516 return 1;
15171517}
......@@ -1682,7 +1682,7 @@ codecvt<wchar_t, char, mbstate_t>::do_unshift(state_type& st,
16821682}
16831683
16841684int
1685codecvt<wchar_t, char, mbstate_t>::do_encoding() const _NOEXCEPT
1685codecvt<wchar_t, char, mbstate_t>::do_encoding() const noexcept
16861686{
16871687 if (__libcpp_mbtowc_l(nullptr, nullptr, MB_LEN_MAX, __l) != 0)
16881688 return -1;
......@@ -1694,7 +1694,7 @@ codecvt<wchar_t, char, mbstate_t>::do_encoding() const _NOEXCEPT
16941694}
16951695
16961696bool
1697codecvt<wchar_t, char, mbstate_t>::do_always_noconv() const _NOEXCEPT
1697codecvt<wchar_t, char, mbstate_t>::do_always_noconv() const noexcept
16981698{
16991699 return false;
17001700}
......@@ -1726,7 +1726,7 @@ codecvt<wchar_t, char, mbstate_t>::do_length(state_type& st,
17261726}
17271727
17281728int
1729codecvt<wchar_t, char, mbstate_t>::do_max_length() const _NOEXCEPT
1729codecvt<wchar_t, char, mbstate_t>::do_max_length() const noexcept
17301730{
17311731 return __l == 0 ? 1 : static_cast<int>(__libcpp_mb_cur_max_l(__l));
17321732}
......@@ -3169,13 +3169,13 @@ codecvt<char16_t, char, mbstate_t>::do_unshift(state_type&,
31693169}
31703170
31713171int
3172codecvt<char16_t, char, mbstate_t>::do_encoding() const _NOEXCEPT
3172codecvt<char16_t, char, mbstate_t>::do_encoding() const noexcept
31733173{
31743174 return 0;
31753175}
31763176
31773177bool
3178codecvt<char16_t, char, mbstate_t>::do_always_noconv() const _NOEXCEPT
3178codecvt<char16_t, char, mbstate_t>::do_always_noconv() const noexcept
31793179{
31803180 return false;
31813181}
......@@ -3190,12 +3190,12 @@ codecvt<char16_t, char, mbstate_t>::do_length(state_type&,
31903190}
31913191
31923192int
3193codecvt<char16_t, char, mbstate_t>::do_max_length() const _NOEXCEPT
3193codecvt<char16_t, char, mbstate_t>::do_max_length() const noexcept
31943194{
31953195 return 4;
31963196}
31973197
3198#ifndef _LIBCPP_NO_HAS_CHAR8_T
3198#ifndef _LIBCPP_HAS_NO_CHAR8_T
31993199
32003200// template <> class codecvt<char16_t, char8_t, mbstate_t>
32013201
......@@ -3248,13 +3248,13 @@ codecvt<char16_t, char8_t, mbstate_t>::do_unshift(state_type&,
32483248}
32493249
32503250int
3251codecvt<char16_t, char8_t, mbstate_t>::do_encoding() const _NOEXCEPT
3251codecvt<char16_t, char8_t, mbstate_t>::do_encoding() const noexcept
32523252{
32533253 return 0;
32543254}
32553255
32563256bool
3257codecvt<char16_t, char8_t, mbstate_t>::do_always_noconv() const _NOEXCEPT
3257codecvt<char16_t, char8_t, mbstate_t>::do_always_noconv() const noexcept
32583258{
32593259 return false;
32603260}
......@@ -3269,7 +3269,7 @@ codecvt<char16_t, char8_t, mbstate_t>::do_length(state_type&,
32693269}
32703270
32713271int
3272codecvt<char16_t, char8_t, mbstate_t>::do_max_length() const _NOEXCEPT
3272codecvt<char16_t, char8_t, mbstate_t>::do_max_length() const noexcept
32733273{
32743274 return 4;
32753275}
......@@ -3327,13 +3327,13 @@ codecvt<char32_t, char, mbstate_t>::do_unshift(state_type&,
33273327}
33283328
33293329int
3330codecvt<char32_t, char, mbstate_t>::do_encoding() const _NOEXCEPT
3330codecvt<char32_t, char, mbstate_t>::do_encoding() const noexcept
33313331{
33323332 return 0;
33333333}
33343334
33353335bool
3336codecvt<char32_t, char, mbstate_t>::do_always_noconv() const _NOEXCEPT
3336codecvt<char32_t, char, mbstate_t>::do_always_noconv() const noexcept
33373337{
33383338 return false;
33393339}
......@@ -3348,12 +3348,12 @@ codecvt<char32_t, char, mbstate_t>::do_length(state_type&,
33483348}
33493349
33503350int
3351codecvt<char32_t, char, mbstate_t>::do_max_length() const _NOEXCEPT
3351codecvt<char32_t, char, mbstate_t>::do_max_length() const noexcept
33523352{
33533353 return 4;
33543354}
33553355
3356#ifndef _LIBCPP_NO_HAS_CHAR8_T
3356#ifndef _LIBCPP_HAS_NO_CHAR8_T
33573357
33583358// template <> class codecvt<char32_t, char8_t, mbstate_t>
33593359
......@@ -3406,13 +3406,13 @@ codecvt<char32_t, char8_t, mbstate_t>::do_unshift(state_type&,
34063406}
34073407
34083408int
3409codecvt<char32_t, char8_t, mbstate_t>::do_encoding() const _NOEXCEPT
3409codecvt<char32_t, char8_t, mbstate_t>::do_encoding() const noexcept
34103410{
34113411 return 0;
34123412}
34133413
34143414bool
3415codecvt<char32_t, char8_t, mbstate_t>::do_always_noconv() const _NOEXCEPT
3415codecvt<char32_t, char8_t, mbstate_t>::do_always_noconv() const noexcept
34163416{
34173417 return false;
34183418}
......@@ -3427,7 +3427,7 @@ codecvt<char32_t, char8_t, mbstate_t>::do_length(state_type&,
34273427}
34283428
34293429int
3430codecvt<char32_t, char8_t, mbstate_t>::do_max_length() const _NOEXCEPT
3430codecvt<char32_t, char8_t, mbstate_t>::do_max_length() const noexcept
34313431{
34323432 return 4;
34333433}
......@@ -3500,13 +3500,13 @@ __codecvt_utf8<wchar_t>::do_unshift(state_type&,
35003500}
35013501
35023502int
3503__codecvt_utf8<wchar_t>::do_encoding() const _NOEXCEPT
3503__codecvt_utf8<wchar_t>::do_encoding() const noexcept
35043504{
35053505 return 0;
35063506}
35073507
35083508bool
3509__codecvt_utf8<wchar_t>::do_always_noconv() const _NOEXCEPT
3509__codecvt_utf8<wchar_t>::do_always_noconv() const noexcept
35103510{
35113511 return false;
35123512}
......@@ -3521,7 +3521,7 @@ __codecvt_utf8<wchar_t>::do_length(state_type&,
35213521}
35223522
35233523int
3524__codecvt_utf8<wchar_t>::do_max_length() const _NOEXCEPT
3524__codecvt_utf8<wchar_t>::do_max_length() const noexcept
35253525{
35263526 if (_Mode_ & consume_header)
35273527 return 7;
......@@ -3575,13 +3575,13 @@ __codecvt_utf8<char16_t>::do_unshift(state_type&,
35753575}
35763576
35773577int
3578__codecvt_utf8<char16_t>::do_encoding() const _NOEXCEPT
3578__codecvt_utf8<char16_t>::do_encoding() const noexcept
35793579{
35803580 return 0;
35813581}
35823582
35833583bool
3584__codecvt_utf8<char16_t>::do_always_noconv() const _NOEXCEPT
3584__codecvt_utf8<char16_t>::do_always_noconv() const noexcept
35853585{
35863586 return false;
35873587}
......@@ -3596,7 +3596,7 @@ __codecvt_utf8<char16_t>::do_length(state_type&,
35963596}
35973597
35983598int
3599__codecvt_utf8<char16_t>::do_max_length() const _NOEXCEPT
3599__codecvt_utf8<char16_t>::do_max_length() const noexcept
36003600{
36013601 if (_Mode_ & consume_header)
36023602 return 6;
......@@ -3650,13 +3650,13 @@ __codecvt_utf8<char32_t>::do_unshift(state_type&,
36503650}
36513651
36523652int
3653__codecvt_utf8<char32_t>::do_encoding() const _NOEXCEPT
3653__codecvt_utf8<char32_t>::do_encoding() const noexcept
36543654{
36553655 return 0;
36563656}
36573657
36583658bool
3659__codecvt_utf8<char32_t>::do_always_noconv() const _NOEXCEPT
3659__codecvt_utf8<char32_t>::do_always_noconv() const noexcept
36603660{
36613661 return false;
36623662}
......@@ -3671,7 +3671,7 @@ __codecvt_utf8<char32_t>::do_length(state_type&,
36713671}
36723672
36733673int
3674__codecvt_utf8<char32_t>::do_max_length() const _NOEXCEPT
3674__codecvt_utf8<char32_t>::do_max_length() const noexcept
36753675{
36763676 if (_Mode_ & consume_header)
36773677 return 7;
......@@ -3725,13 +3725,13 @@ __codecvt_utf16<wchar_t, false>::do_unshift(state_type&,
37253725}
37263726
37273727int
3728__codecvt_utf16<wchar_t, false>::do_encoding() const _NOEXCEPT
3728__codecvt_utf16<wchar_t, false>::do_encoding() const noexcept
37293729{
37303730 return 0;
37313731}
37323732
37333733bool
3734__codecvt_utf16<wchar_t, false>::do_always_noconv() const _NOEXCEPT
3734__codecvt_utf16<wchar_t, false>::do_always_noconv() const noexcept
37353735{
37363736 return false;
37373737}
......@@ -3746,7 +3746,7 @@ __codecvt_utf16<wchar_t, false>::do_length(state_type&,
37463746}
37473747
37483748int
3749__codecvt_utf16<wchar_t, false>::do_max_length() const _NOEXCEPT
3749__codecvt_utf16<wchar_t, false>::do_max_length() const noexcept
37503750{
37513751 if (_Mode_ & consume_header)
37523752 return 6;
......@@ -3800,13 +3800,13 @@ __codecvt_utf16<wchar_t, true>::do_unshift(state_type&,
38003800}
38013801
38023802int
3803__codecvt_utf16<wchar_t, true>::do_encoding() const _NOEXCEPT
3803__codecvt_utf16<wchar_t, true>::do_encoding() const noexcept
38043804{
38053805 return 0;
38063806}
38073807
38083808bool
3809__codecvt_utf16<wchar_t, true>::do_always_noconv() const _NOEXCEPT
3809__codecvt_utf16<wchar_t, true>::do_always_noconv() const noexcept
38103810{
38113811 return false;
38123812}
......@@ -3821,7 +3821,7 @@ __codecvt_utf16<wchar_t, true>::do_length(state_type&,
38213821}
38223822
38233823int
3824__codecvt_utf16<wchar_t, true>::do_max_length() const _NOEXCEPT
3824__codecvt_utf16<wchar_t, true>::do_max_length() const noexcept
38253825{
38263826 if (_Mode_ & consume_header)
38273827 return 6;
......@@ -3875,13 +3875,13 @@ __codecvt_utf16<char16_t, false>::do_unshift(state_type&,
38753875}
38763876
38773877int
3878__codecvt_utf16<char16_t, false>::do_encoding() const _NOEXCEPT
3878__codecvt_utf16<char16_t, false>::do_encoding() const noexcept
38793879{
38803880 return 0;
38813881}
38823882
38833883bool
3884__codecvt_utf16<char16_t, false>::do_always_noconv() const _NOEXCEPT
3884__codecvt_utf16<char16_t, false>::do_always_noconv() const noexcept
38853885{
38863886 return false;
38873887}
......@@ -3896,7 +3896,7 @@ __codecvt_utf16<char16_t, false>::do_length(state_type&,
38963896}
38973897
38983898int
3899__codecvt_utf16<char16_t, false>::do_max_length() const _NOEXCEPT
3899__codecvt_utf16<char16_t, false>::do_max_length() const noexcept
39003900{
39013901 if (_Mode_ & consume_header)
39023902 return 4;
......@@ -3950,13 +3950,13 @@ __codecvt_utf16<char16_t, true>::do_unshift(state_type&,
39503950}
39513951
39523952int
3953__codecvt_utf16<char16_t, true>::do_encoding() const _NOEXCEPT
3953__codecvt_utf16<char16_t, true>::do_encoding() const noexcept
39543954{
39553955 return 0;
39563956}
39573957
39583958bool
3959__codecvt_utf16<char16_t, true>::do_always_noconv() const _NOEXCEPT
3959__codecvt_utf16<char16_t, true>::do_always_noconv() const noexcept
39603960{
39613961 return false;
39623962}
......@@ -3971,7 +3971,7 @@ __codecvt_utf16<char16_t, true>::do_length(state_type&,
39713971}
39723972
39733973int
3974__codecvt_utf16<char16_t, true>::do_max_length() const _NOEXCEPT
3974__codecvt_utf16<char16_t, true>::do_max_length() const noexcept
39753975{
39763976 if (_Mode_ & consume_header)
39773977 return 4;
......@@ -4025,13 +4025,13 @@ __codecvt_utf16<char32_t, false>::do_unshift(state_type&,
40254025}
40264026
40274027int
4028__codecvt_utf16<char32_t, false>::do_encoding() const _NOEXCEPT
4028__codecvt_utf16<char32_t, false>::do_encoding() const noexcept
40294029{
40304030 return 0;
40314031}
40324032
40334033bool
4034__codecvt_utf16<char32_t, false>::do_always_noconv() const _NOEXCEPT
4034__codecvt_utf16<char32_t, false>::do_always_noconv() const noexcept
40354035{
40364036 return false;
40374037}
......@@ -4046,7 +4046,7 @@ __codecvt_utf16<char32_t, false>::do_length(state_type&,
40464046}
40474047
40484048int
4049__codecvt_utf16<char32_t, false>::do_max_length() const _NOEXCEPT
4049__codecvt_utf16<char32_t, false>::do_max_length() const noexcept
40504050{
40514051 if (_Mode_ & consume_header)
40524052 return 6;
......@@ -4100,13 +4100,13 @@ __codecvt_utf16<char32_t, true>::do_unshift(state_type&,
41004100}
41014101
41024102int
4103__codecvt_utf16<char32_t, true>::do_encoding() const _NOEXCEPT
4103__codecvt_utf16<char32_t, true>::do_encoding() const noexcept
41044104{
41054105 return 0;
41064106}
41074107
41084108bool
4109__codecvt_utf16<char32_t, true>::do_always_noconv() const _NOEXCEPT
4109__codecvt_utf16<char32_t, true>::do_always_noconv() const noexcept
41104110{
41114111 return false;
41124112}
......@@ -4121,7 +4121,7 @@ __codecvt_utf16<char32_t, true>::do_length(state_type&,
41214121}
41224122
41234123int
4124__codecvt_utf16<char32_t, true>::do_max_length() const _NOEXCEPT
4124__codecvt_utf16<char32_t, true>::do_max_length() const noexcept
41254125{
41264126 if (_Mode_ & consume_header)
41274127 return 6;
......@@ -4175,13 +4175,13 @@ __codecvt_utf8_utf16<wchar_t>::do_unshift(state_type&,
41754175}
41764176
41774177int
4178__codecvt_utf8_utf16<wchar_t>::do_encoding() const _NOEXCEPT
4178__codecvt_utf8_utf16<wchar_t>::do_encoding() const noexcept
41794179{
41804180 return 0;
41814181}
41824182
41834183bool
4184__codecvt_utf8_utf16<wchar_t>::do_always_noconv() const _NOEXCEPT
4184__codecvt_utf8_utf16<wchar_t>::do_always_noconv() const noexcept
41854185{
41864186 return false;
41874187}
......@@ -4196,7 +4196,7 @@ __codecvt_utf8_utf16<wchar_t>::do_length(state_type&,
41964196}
41974197
41984198int
4199__codecvt_utf8_utf16<wchar_t>::do_max_length() const _NOEXCEPT
4199__codecvt_utf8_utf16<wchar_t>::do_max_length() const noexcept
42004200{
42014201 if (_Mode_ & consume_header)
42024202 return 7;
......@@ -4250,13 +4250,13 @@ __codecvt_utf8_utf16<char16_t>::do_unshift(state_type&,
42504250}
42514251
42524252int
4253__codecvt_utf8_utf16<char16_t>::do_encoding() const _NOEXCEPT
4253__codecvt_utf8_utf16<char16_t>::do_encoding() const noexcept
42544254{
42554255 return 0;
42564256}
42574257
42584258bool
4259__codecvt_utf8_utf16<char16_t>::do_always_noconv() const _NOEXCEPT
4259__codecvt_utf8_utf16<char16_t>::do_always_noconv() const noexcept
42604260{
42614261 return false;
42624262}
......@@ -4271,7 +4271,7 @@ __codecvt_utf8_utf16<char16_t>::do_length(state_type&,
42714271}
42724272
42734273int
4274__codecvt_utf8_utf16<char16_t>::do_max_length() const _NOEXCEPT
4274__codecvt_utf8_utf16<char16_t>::do_max_length() const noexcept
42754275{
42764276 if (_Mode_ & consume_header)
42774277 return 7;
......@@ -4325,13 +4325,13 @@ __codecvt_utf8_utf16<char32_t>::do_unshift(state_type&,
43254325}
43264326
43274327int
4328__codecvt_utf8_utf16<char32_t>::do_encoding() const _NOEXCEPT
4328__codecvt_utf8_utf16<char32_t>::do_encoding() const noexcept
43294329{
43304330 return 0;
43314331}
43324332
43334333bool
4334__codecvt_utf8_utf16<char32_t>::do_always_noconv() const _NOEXCEPT
4334__codecvt_utf8_utf16<char32_t>::do_always_noconv() const noexcept
43354335{
43364336 return false;
43374337}
......@@ -4346,7 +4346,7 @@ __codecvt_utf8_utf16<char32_t>::do_length(state_type&,
43464346}
43474347
43484348int
4349__codecvt_utf8_utf16<char32_t>::do_max_length() const _NOEXCEPT
4349__codecvt_utf8_utf16<char32_t>::do_max_length() const noexcept
43504350{
43514351 if (_Mode_ & consume_header)
43524352 return 7;
......@@ -4597,7 +4597,10 @@ void
45974597__num_put_base::__format_int(char* __fmtp, const char* __len, bool __signd,
45984598 ios_base::fmtflags __flags)
45994599{
4600 if (__flags & ios_base::showpos)
4600 if ((__flags & ios_base::showpos) &&
4601 (__flags & ios_base::basefield) != ios_base::oct &&
4602 (__flags & ios_base::basefield) != ios_base::hex &&
4603 __signd)
46014604 *__fmtp++ = '+';
46024605 if (__flags & ios_base::showbase)
46034606 *__fmtp++ = '#';
......@@ -6336,7 +6339,7 @@ template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char, cha
63366339template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<wchar_t, char, mbstate_t>;
63376340template class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char16_t, char, mbstate_t>;
63386341template class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char32_t, char, mbstate_t>;
6339#ifndef _LIBCPP_NO_HAS_CHAR8_T
6342#ifndef _LIBCPP_HAS_NO_CHAR8_T
63406343template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char16_t, char8_t, mbstate_t>;
63416344template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char32_t, char8_t, mbstate_t>;
63426345#endif
lib/libcxx/src/memory.cpp+13-20
......@@ -20,10 +20,10 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2020
2121const allocator_arg_t allocator_arg = allocator_arg_t();
2222
23bad_weak_ptr::~bad_weak_ptr() _NOEXCEPT {}
23bad_weak_ptr::~bad_weak_ptr() noexcept {}
2424
2525const char*
26bad_weak_ptr::what() const _NOEXCEPT
26bad_weak_ptr::what() const noexcept
2727{
2828 return "bad_weak_ptr";
2929}
......@@ -38,13 +38,13 @@ __shared_weak_count::~__shared_weak_count()
3838
3939#if defined(_LIBCPP_DEPRECATED_ABI_LEGACY_LIBRARY_DEFINITIONS_FOR_INLINE_FUNCTIONS)
4040void
41__shared_count::__add_shared() _NOEXCEPT
41__shared_count::__add_shared() noexcept
4242{
4343 __libcpp_atomic_refcount_increment(__shared_owners_);
4444}
4545
4646bool
47__shared_count::__release_shared() _NOEXCEPT
47__shared_count::__release_shared() noexcept
4848{
4949 if (__libcpp_atomic_refcount_decrement(__shared_owners_) == -1)
5050 {
......@@ -55,19 +55,19 @@ __shared_count::__release_shared() _NOEXCEPT
5555}
5656
5757void
58__shared_weak_count::__add_shared() _NOEXCEPT
58__shared_weak_count::__add_shared() noexcept
5959{
6060 __shared_count::__add_shared();
6161}
6262
6363void
64__shared_weak_count::__add_weak() _NOEXCEPT
64__shared_weak_count::__add_weak() noexcept
6565{
6666 __libcpp_atomic_refcount_increment(__shared_weak_owners_);
6767}
6868
6969void
70__shared_weak_count::__release_shared() _NOEXCEPT
70__shared_weak_count::__release_shared() noexcept
7171{
7272 if (__shared_count::__release_shared())
7373 __release_weak();
......@@ -76,7 +76,7 @@ __shared_weak_count::__release_shared() _NOEXCEPT
7676#endif // _LIBCPP_DEPRECATED_ABI_LEGACY_LIBRARY_DEFINITIONS_FOR_INLINE_FUNCTIONS
7777
7878void
79__shared_weak_count::__release_weak() _NOEXCEPT
79__shared_weak_count::__release_weak() noexcept
8080{
8181 // NOTE: The acquire load here is an optimization of the very
8282 // common case where a shared pointer is being destructed while
......@@ -111,7 +111,7 @@ __shared_weak_count::__release_weak() _NOEXCEPT
111111}
112112
113113__shared_weak_count*
114__shared_weak_count::lock() _NOEXCEPT
114__shared_weak_count::lock() noexcept
115115{
116116 long object_owners = __libcpp_atomic_load(&__shared_owners_);
117117 while (object_owners != -1)
......@@ -125,7 +125,7 @@ __shared_weak_count::lock() _NOEXCEPT
125125}
126126
127127const void*
128__shared_weak_count::__get_deleter(const type_info&) const _NOEXCEPT
128__shared_weak_count::__get_deleter(const type_info&) const noexcept
129129{
130130 return nullptr;
131131}
......@@ -141,13 +141,13 @@ _LIBCPP_SAFE_STATIC static __libcpp_mutex_t mut_back[__sp_mut_count] =
141141 _LIBCPP_MUTEX_INITIALIZER, _LIBCPP_MUTEX_INITIALIZER, _LIBCPP_MUTEX_INITIALIZER, _LIBCPP_MUTEX_INITIALIZER
142142};
143143
144_LIBCPP_CONSTEXPR __sp_mut::__sp_mut(void* p) _NOEXCEPT
144_LIBCPP_CONSTEXPR __sp_mut::__sp_mut(void* p) noexcept
145145 : __lx(p)
146146{
147147}
148148
149149void
150__sp_mut::lock() _NOEXCEPT
150__sp_mut::lock() noexcept
151151{
152152 auto m = static_cast<__libcpp_mutex_t*>(__lx);
153153 unsigned count = 0;
......@@ -163,7 +163,7 @@ __sp_mut::lock() _NOEXCEPT
163163}
164164
165165void
166__sp_mut::unlock() _NOEXCEPT
166__sp_mut::unlock() noexcept
167167{
168168 __libcpp_mutex_unlock(static_cast<__libcpp_mutex_t*>(__lx));
169169}
......@@ -198,13 +198,6 @@ undeclare_no_pointers(char*, size_t)
198198{
199199}
200200
201#if !defined(_LIBCPP_ABI_POINTER_SAFETY_ENUM_TYPE)
202pointer_safety get_pointer_safety() _NOEXCEPT
203{
204 return pointer_safety::relaxed;
205}
206#endif
207
208201void*
209202__undeclare_reachable(void* p)
210203{
lib/libcxx/src/mutex.cpp+12-12
......@@ -36,13 +36,13 @@ mutex::lock()
3636}
3737
3838bool
39mutex::try_lock() _NOEXCEPT
39mutex::try_lock() noexcept
4040{
4141 return __libcpp_mutex_trylock(&__m_);
4242}
4343
4444void
45mutex::unlock() _NOEXCEPT
45mutex::unlock() noexcept
4646{
4747 int ec = __libcpp_mutex_unlock(&__m_);
4848 (void)ec;
......@@ -74,7 +74,7 @@ recursive_mutex::lock()
7474}
7575
7676void
77recursive_mutex::unlock() _NOEXCEPT
77recursive_mutex::unlock() noexcept
7878{
7979 int e = __libcpp_recursive_mutex_unlock(&__m_);
8080 (void)e;
......@@ -82,7 +82,7 @@ recursive_mutex::unlock() _NOEXCEPT
8282}
8383
8484bool
85recursive_mutex::try_lock() _NOEXCEPT
85recursive_mutex::try_lock() noexcept
8686{
8787 return __libcpp_recursive_mutex_trylock(&__m_);
8888}
......@@ -109,7 +109,7 @@ timed_mutex::lock()
109109}
110110
111111bool
112timed_mutex::try_lock() _NOEXCEPT
112timed_mutex::try_lock() noexcept
113113{
114114 unique_lock<mutex> lk(__m_, try_to_lock);
115115 if (lk.owns_lock() && !__locked_)
......@@ -121,7 +121,7 @@ timed_mutex::try_lock() _NOEXCEPT
121121}
122122
123123void
124timed_mutex::unlock() _NOEXCEPT
124timed_mutex::unlock() noexcept
125125{
126126 lock_guard<mutex> _(__m_);
127127 __locked_ = false;
......@@ -160,7 +160,7 @@ recursive_timed_mutex::lock()
160160}
161161
162162bool
163recursive_timed_mutex::try_lock() _NOEXCEPT
163recursive_timed_mutex::try_lock() noexcept
164164{
165165 __thread_id id = this_thread::get_id();
166166 unique_lock<mutex> lk(__m_, try_to_lock);
......@@ -176,7 +176,7 @@ recursive_timed_mutex::try_lock() _NOEXCEPT
176176}
177177
178178void
179recursive_timed_mutex::unlock() _NOEXCEPT
179recursive_timed_mutex::unlock() noexcept
180180{
181181 unique_lock<mutex> lk(__m_);
182182 if (--__count_ == 0)
......@@ -209,7 +209,7 @@ void __call_once(volatile once_flag::_State_type& flag, void* arg,
209209#ifndef _LIBCPP_NO_EXCEPTIONS
210210 try
211211 {
212#endif // _LIBCPP_NO_EXCEPTIONS
212#endif // _LIBCPP_NO_EXCEPTIONS
213213 flag = 1;
214214 func(arg);
215215 flag = ~once_flag::_State_type(0);
......@@ -220,7 +220,7 @@ void __call_once(volatile once_flag::_State_type& flag, void* arg,
220220 flag = 0;
221221 throw;
222222 }
223#endif // _LIBCPP_NO_EXCEPTIONS
223#endif // _LIBCPP_NO_EXCEPTIONS
224224 }
225225#else // !_LIBCPP_HAS_NO_THREADS
226226 __libcpp_mutex_lock(&mut);
......@@ -231,7 +231,7 @@ void __call_once(volatile once_flag::_State_type& flag, void* arg,
231231#ifndef _LIBCPP_NO_EXCEPTIONS
232232 try
233233 {
234#endif // _LIBCPP_NO_EXCEPTIONS
234#endif // _LIBCPP_NO_EXCEPTIONS
235235 __libcpp_relaxed_store(&flag, once_flag::_State_type(1));
236236 __libcpp_mutex_unlock(&mut);
237237 func(arg);
......@@ -250,7 +250,7 @@ void __call_once(volatile once_flag::_State_type& flag, void* arg,
250250 __libcpp_condvar_broadcast(&cv);
251251 throw;
252252 }
253#endif // _LIBCPP_NO_EXCEPTIONS
253#endif // _LIBCPP_NO_EXCEPTIONS
254254 }
255255 else
256256 __libcpp_mutex_unlock(&mut);
lib/libcxx/src/mutex_destructor.cpp+1-1
......@@ -41,7 +41,7 @@ public:
4141};
4242
4343
44mutex::~mutex() _NOEXCEPT
44mutex::~mutex() noexcept
4545{
4646 __libcpp_mutex_destroy(&__m_);
4747}
lib/libcxx/src/new.cpp+24-24
......@@ -83,20 +83,20 @@ operator new(std::size_t size) _THROW_BAD_ALLOC
8383
8484_LIBCPP_WEAK
8585void*
86operator new(size_t size, const std::nothrow_t&) _NOEXCEPT
86operator new(size_t size, const std::nothrow_t&) noexcept
8787{
8888 void* p = nullptr;
8989#ifndef _LIBCPP_NO_EXCEPTIONS
9090 try
9191 {
92#endif // _LIBCPP_NO_EXCEPTIONS
92#endif // _LIBCPP_NO_EXCEPTIONS
9393 p = ::operator new(size);
9494#ifndef _LIBCPP_NO_EXCEPTIONS
9595 }
9696 catch (...)
9797 {
9898 }
99#endif // _LIBCPP_NO_EXCEPTIONS
99#endif // _LIBCPP_NO_EXCEPTIONS
100100 return p;
101101}
102102
......@@ -109,61 +109,61 @@ operator new[](size_t size) _THROW_BAD_ALLOC
109109
110110_LIBCPP_WEAK
111111void*
112operator new[](size_t size, const std::nothrow_t&) _NOEXCEPT
112operator new[](size_t size, const std::nothrow_t&) noexcept
113113{
114114 void* p = nullptr;
115115#ifndef _LIBCPP_NO_EXCEPTIONS
116116 try
117117 {
118#endif // _LIBCPP_NO_EXCEPTIONS
118#endif // _LIBCPP_NO_EXCEPTIONS
119119 p = ::operator new[](size);
120120#ifndef _LIBCPP_NO_EXCEPTIONS
121121 }
122122 catch (...)
123123 {
124124 }
125#endif // _LIBCPP_NO_EXCEPTIONS
125#endif // _LIBCPP_NO_EXCEPTIONS
126126 return p;
127127}
128128
129129_LIBCPP_WEAK
130130void
131operator delete(void* ptr) _NOEXCEPT
131operator delete(void* ptr) noexcept
132132{
133133 ::free(ptr);
134134}
135135
136136_LIBCPP_WEAK
137137void
138operator delete(void* ptr, const std::nothrow_t&) _NOEXCEPT
138operator delete(void* ptr, const std::nothrow_t&) noexcept
139139{
140140 ::operator delete(ptr);
141141}
142142
143143_LIBCPP_WEAK
144144void
145operator delete(void* ptr, size_t) _NOEXCEPT
145operator delete(void* ptr, size_t) noexcept
146146{
147147 ::operator delete(ptr);
148148}
149149
150150_LIBCPP_WEAK
151151void
152operator delete[] (void* ptr) _NOEXCEPT
152operator delete[] (void* ptr) noexcept
153153{
154154 ::operator delete(ptr);
155155}
156156
157157_LIBCPP_WEAK
158158void
159operator delete[] (void* ptr, const std::nothrow_t&) _NOEXCEPT
159operator delete[] (void* ptr, const std::nothrow_t&) noexcept
160160{
161161 ::operator delete[](ptr);
162162}
163163
164164_LIBCPP_WEAK
165165void
166operator delete[] (void* ptr, size_t) _NOEXCEPT
166operator delete[] (void* ptr, size_t) noexcept
167167{
168168 ::operator delete[](ptr);
169169}
......@@ -204,20 +204,20 @@ operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC
204204
205205_LIBCPP_WEAK
206206void*
207operator new(size_t size, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT
207operator new(size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept
208208{
209209 void* p = nullptr;
210210#ifndef _LIBCPP_NO_EXCEPTIONS
211211 try
212212 {
213#endif // _LIBCPP_NO_EXCEPTIONS
213#endif // _LIBCPP_NO_EXCEPTIONS
214214 p = ::operator new(size, alignment);
215215#ifndef _LIBCPP_NO_EXCEPTIONS
216216 }
217217 catch (...)
218218 {
219219 }
220#endif // _LIBCPP_NO_EXCEPTIONS
220#endif // _LIBCPP_NO_EXCEPTIONS
221221 return p;
222222}
223223
......@@ -230,61 +230,61 @@ operator new[](size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC
230230
231231_LIBCPP_WEAK
232232void*
233operator new[](size_t size, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT
233operator new[](size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept
234234{
235235 void* p = nullptr;
236236#ifndef _LIBCPP_NO_EXCEPTIONS
237237 try
238238 {
239#endif // _LIBCPP_NO_EXCEPTIONS
239#endif // _LIBCPP_NO_EXCEPTIONS
240240 p = ::operator new[](size, alignment);
241241#ifndef _LIBCPP_NO_EXCEPTIONS
242242 }
243243 catch (...)
244244 {
245245 }
246#endif // _LIBCPP_NO_EXCEPTIONS
246#endif // _LIBCPP_NO_EXCEPTIONS
247247 return p;
248248}
249249
250250_LIBCPP_WEAK
251251void
252operator delete(void* ptr, std::align_val_t) _NOEXCEPT
252operator delete(void* ptr, std::align_val_t) noexcept
253253{
254254 std::__libcpp_aligned_free(ptr);
255255}
256256
257257_LIBCPP_WEAK
258258void
259operator delete(void* ptr, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT
259operator delete(void* ptr, std::align_val_t alignment, const std::nothrow_t&) noexcept
260260{
261261 ::operator delete(ptr, alignment);
262262}
263263
264264_LIBCPP_WEAK
265265void
266operator delete(void* ptr, size_t, std::align_val_t alignment) _NOEXCEPT
266operator delete(void* ptr, size_t, std::align_val_t alignment) noexcept
267267{
268268 ::operator delete(ptr, alignment);
269269}
270270
271271_LIBCPP_WEAK
272272void
273operator delete[] (void* ptr, std::align_val_t alignment) _NOEXCEPT
273operator delete[] (void* ptr, std::align_val_t alignment) noexcept
274274{
275275 ::operator delete(ptr, alignment);
276276}
277277
278278_LIBCPP_WEAK
279279void
280operator delete[] (void* ptr, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT
280operator delete[] (void* ptr, std::align_val_t alignment, const std::nothrow_t&) noexcept
281281{
282282 ::operator delete[](ptr, alignment);
283283}
284284
285285_LIBCPP_WEAK
286286void
287operator delete[] (void* ptr, size_t, std::align_val_t alignment) _NOEXCEPT
287operator delete[] (void* ptr, size_t, std::align_val_t alignment) noexcept
288288{
289289 ::operator delete[](ptr, alignment);
290290}
lib/libcxx/src/optional.cpp+4-4
......@@ -12,9 +12,9 @@
1212namespace std
1313{
1414
15bad_optional_access::~bad_optional_access() _NOEXCEPT = default;
15bad_optional_access::~bad_optional_access() noexcept = default;
1616
17const char* bad_optional_access::what() const _NOEXCEPT {
17const char* bad_optional_access::what() const noexcept {
1818 return "bad_optional_access";
1919 }
2020
......@@ -34,9 +34,9 @@ public:
3434 bad_optional_access() : std::logic_error("Bad optional Access") {}
3535
3636// Get the key function ~bad_optional_access() into the dylib
37 virtual ~bad_optional_access() _NOEXCEPT;
37 virtual ~bad_optional_access() noexcept;
3838};
3939
40bad_optional_access::~bad_optional_access() _NOEXCEPT = default;
40bad_optional_access::~bad_optional_access() noexcept = default;
4141
4242_LIBCPP_END_NAMESPACE_EXPERIMENTAL
lib/libcxx/src/random.cpp+1-1
......@@ -175,7 +175,7 @@ random_device::operator()()
175175#endif
176176
177177double
178random_device::entropy() const _NOEXCEPT
178random_device::entropy() const noexcept
179179{
180180#if defined(_LIBCPP_USING_DEV_RANDOM) && defined(RNDGETENTCNT)
181181 int ent;
lib/libcxx/src/string.cpp+4-4
......@@ -20,6 +20,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2020
2121template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __basic_string_common<true>;
2222
23#define _LIBCPP_EXTERN_TEMPLATE_DEFINE(...) template __VA_ARGS__;
2324#ifdef _LIBCPP_ABI_STRING_OPTIMIZED_EXTERNAL_INSTANTIATION
2425_LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE_DEFINE, char)
2526_LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE_DEFINE, wchar_t)
......@@ -27,10 +28,9 @@ _LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE_DEFINE, wch
2728_LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE_DEFINE, char)
2829_LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE_DEFINE, wchar_t)
2930#endif
31#undef _LIBCPP_EXTERN_TEMPLATE_DEFINE
3032
31template
32 string
33 operator+<char, char_traits<char>, allocator<char> >(char const*, string const&);
33template string operator+<char, char_traits<char>, allocator<char> >(char const*, string const&);
3434
3535namespace
3636{
......@@ -423,7 +423,7 @@ get_swprintf()
423423}
424424
425425template <typename S, typename V>
426S i_to_string(const V v)
426S i_to_string(V v)
427427{
428428// numeric_limits::digits10 returns value less on 1 than desired for unsigned numbers.
429429// For example, for 1-byte unsigned value digits10 is 2 (999 can not be represented),
lib/libcxx/src/support/ibm/xlocale_zos.cpp created+137
......@@ -0,0 +1,137 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include <__support/ibm/xlocale.h>
10#include <sstream>
11#include <vector>
12
13#ifdef __cplusplus
14extern "C" {
15#endif // __cplusplus
16
17locale_t newlocale(int category_mask, const char* locale, locale_t base) {
18 // Maintain current locale name(s) to restore later.
19 std::string current_loc_name(setlocale(LC_ALL, 0));
20
21 // Check for errors.
22 if (category_mask == LC_ALL_MASK && setlocale(LC_ALL, locale) == NULL) {
23 errno = EINVAL;
24 return (locale_t)0;
25 } else {
26 for (int _Cat = 0; _Cat <= _LC_MAX; ++_Cat) {
27 if ((_CATMASK(_Cat) & category_mask) != 0 && setlocale(_Cat, locale) == NULL) {
28 setlocale(LC_ALL, current_loc_name.c_str());
29 errno = EINVAL;
30 return (locale_t)0;
31 }
32 }
33 }
34
35 // Create new locale.
36 locale_t newloc = new locale_struct();
37
38 if (base) {
39 if (category_mask != LC_ALL_MASK) {
40 // Copy base when it will not be overwritten.
41 memcpy(newloc, base, sizeof (locale_struct));
42 newloc->category_mask = category_mask | base->category_mask;
43 }
44 delete base;
45 } else {
46 newloc->category_mask = category_mask;
47 }
48
49 if (category_mask & LC_COLLATE_MASK)
50 newloc->lc_collate = locale;
51 if (category_mask & LC_CTYPE_MASK)
52 newloc->lc_ctype = locale;
53 if (category_mask & LC_MONETARY_MASK)
54 newloc->lc_monetary = locale;
55 if (category_mask & LC_NUMERIC_MASK)
56 newloc->lc_numeric = locale;
57 if (category_mask & LC_TIME_MASK)
58 newloc->lc_time = locale;
59 if (category_mask & LC_MESSAGES_MASK)
60 newloc->lc_messages = locale;
61
62 // Restore current locale.
63 setlocale(LC_ALL, current_loc_name.c_str());
64 return (locale_t)newloc;
65}
66
67void freelocale(locale_t locobj) {
68 delete locobj;
69}
70
71locale_t uselocale(locale_t newloc) {
72 // Maintain current locale name(s).
73 std::string current_loc_name(setlocale(LC_ALL, 0));
74
75 if (newloc) {
76 // Set locales and check for errors.
77 bool is_error =
78 (newloc->category_mask & LC_COLLATE_MASK &&
79 setlocale(LC_COLLATE, newloc->lc_collate.c_str()) == NULL) ||
80 (newloc->category_mask & LC_CTYPE_MASK &&
81 setlocale(LC_CTYPE, newloc->lc_ctype.c_str()) == NULL) ||
82 (newloc->category_mask & LC_MONETARY_MASK &&
83 setlocale(LC_MONETARY, newloc->lc_monetary.c_str()) == NULL) ||
84 (newloc->category_mask & LC_NUMERIC_MASK &&
85 setlocale(LC_NUMERIC, newloc->lc_numeric.c_str()) == NULL) ||
86 (newloc->category_mask & LC_TIME_MASK &&
87 setlocale(LC_TIME, newloc->lc_time.c_str()) == NULL) ||
88 (newloc->category_mask & LC_MESSAGES_MASK &&
89 setlocale(LC_MESSAGES, newloc->lc_messages.c_str()) == NULL);
90
91 if (is_error) {
92 setlocale(LC_ALL, current_loc_name.c_str());
93 errno = EINVAL;
94 return (locale_t)0;
95 }
96 }
97
98 // Construct and return previous locale.
99 locale_t previous_loc = new locale_struct();
100
101 // current_loc_name might be a comma-separated locale name list.
102 if (current_loc_name.find(',') != std::string::npos) {
103 // Tokenize locale name list.
104 const char delimiter = ',';
105 std::vector<std::string> tokenized;
106 std::stringstream ss(current_loc_name);
107 std::string s;
108
109 while (std::getline(ss, s, delimiter)) {
110 tokenized.push_back(s);
111 }
112
113 _LIBCPP_ASSERT(tokenized.size() >= _NCAT, "locale-name list is too short");
114
115 previous_loc->lc_collate = tokenized[LC_COLLATE];
116 previous_loc->lc_ctype = tokenized[LC_CTYPE];
117 previous_loc->lc_monetary = tokenized[LC_MONETARY];
118 previous_loc->lc_numeric = tokenized[LC_NUMERIC];
119 previous_loc->lc_time = tokenized[LC_TIME];
120 // Skip LC_TOD.
121 previous_loc->lc_messages = tokenized[LC_MESSAGES];
122 } else {
123 previous_loc->lc_collate = current_loc_name;
124 previous_loc->lc_ctype = current_loc_name;
125 previous_loc->lc_monetary = current_loc_name;
126 previous_loc->lc_numeric = current_loc_name;
127 previous_loc->lc_time = current_loc_name;
128 previous_loc->lc_messages = current_loc_name;
129 }
130
131 previous_loc->category_mask = LC_ALL_MASK;
132 return previous_loc;
133}
134
135#ifdef __cplusplus
136}
137#endif // __cplusplus
lib/libcxx/src/support/runtime/exception_fallback.ipp+25-25
......@@ -17,13 +17,13 @@ _LIBCPP_SAFE_STATIC static std::unexpected_handler __unexpected_handler;
1717
1818// libcxxrt provides implementations of these functions itself.
1919unexpected_handler
20set_unexpected(unexpected_handler func) _NOEXCEPT
20set_unexpected(unexpected_handler func) noexcept
2121{
2222 return __libcpp_atomic_exchange(&__unexpected_handler, func);
2323}
2424
2525unexpected_handler
26get_unexpected() _NOEXCEPT
26get_unexpected() noexcept
2727{
2828 return __libcpp_atomic_load(&__unexpected_handler);
2929
......@@ -38,25 +38,25 @@ void unexpected()
3838}
3939
4040terminate_handler
41set_terminate(terminate_handler func) _NOEXCEPT
41set_terminate(terminate_handler func) noexcept
4242{
4343 return __libcpp_atomic_exchange(&__terminate_handler, func);
4444}
4545
4646terminate_handler
47get_terminate() _NOEXCEPT
47get_terminate() noexcept
4848{
4949 return __libcpp_atomic_load(&__terminate_handler);
5050}
5151
5252_LIBCPP_NORETURN
5353void
54terminate() _NOEXCEPT
54terminate() noexcept
5555{
5656#ifndef _LIBCPP_NO_EXCEPTIONS
5757 try
5858 {
59#endif // _LIBCPP_NO_EXCEPTIONS
59#endif // _LIBCPP_NO_EXCEPTIONS
6060 (*get_terminate())();
6161 // handler should not return
6262 fprintf(stderr, "terminate_handler unexpectedly returned\n");
......@@ -69,12 +69,12 @@ terminate() _NOEXCEPT
6969 fprintf(stderr, "terminate_handler unexpectedly threw an exception\n");
7070 ::abort();
7171 }
72#endif // _LIBCPP_NO_EXCEPTIONS
72#endif // _LIBCPP_NO_EXCEPTIONS
7373}
7474
75bool uncaught_exception() _NOEXCEPT { return uncaught_exceptions() > 0; }
75bool uncaught_exception() noexcept { return uncaught_exceptions() > 0; }
7676
77int uncaught_exceptions() _NOEXCEPT
77int uncaught_exceptions() noexcept
7878{
7979#warning uncaught_exception not yet implemented
8080 fprintf(stderr, "uncaught_exceptions not yet implemented\n");
......@@ -82,77 +82,77 @@ int uncaught_exceptions() _NOEXCEPT
8282}
8383
8484
85exception::~exception() _NOEXCEPT
85exception::~exception() noexcept
8686{
8787}
8888
89const char* exception::what() const _NOEXCEPT
89const char* exception::what() const noexcept
9090{
9191 return "std::exception";
9292}
9393
94bad_exception::~bad_exception() _NOEXCEPT
94bad_exception::~bad_exception() noexcept
9595{
9696}
9797
98const char* bad_exception::what() const _NOEXCEPT
98const char* bad_exception::what() const noexcept
9999{
100100 return "std::bad_exception";
101101}
102102
103103
104bad_alloc::bad_alloc() _NOEXCEPT
104bad_alloc::bad_alloc() noexcept
105105{
106106}
107107
108bad_alloc::~bad_alloc() _NOEXCEPT
108bad_alloc::~bad_alloc() noexcept
109109{
110110}
111111
112112const char*
113bad_alloc::what() const _NOEXCEPT
113bad_alloc::what() const noexcept
114114{
115115 return "std::bad_alloc";
116116}
117117
118bad_array_new_length::bad_array_new_length() _NOEXCEPT
118bad_array_new_length::bad_array_new_length() noexcept
119119{
120120}
121121
122bad_array_new_length::~bad_array_new_length() _NOEXCEPT
122bad_array_new_length::~bad_array_new_length() noexcept
123123{
124124}
125125
126126const char*
127bad_array_new_length::what() const _NOEXCEPT
127bad_array_new_length::what() const noexcept
128128{
129129 return "bad_array_new_length";
130130}
131131
132bad_cast::bad_cast() _NOEXCEPT
132bad_cast::bad_cast() noexcept
133133{
134134}
135135
136bad_typeid::bad_typeid() _NOEXCEPT
136bad_typeid::bad_typeid() noexcept
137137{
138138}
139139
140bad_cast::~bad_cast() _NOEXCEPT
140bad_cast::~bad_cast() noexcept
141141{
142142}
143143
144144const char*
145bad_cast::what() const _NOEXCEPT
145bad_cast::what() const noexcept
146146{
147147 return "std::bad_cast";
148148}
149149
150bad_typeid::~bad_typeid() _NOEXCEPT
150bad_typeid::~bad_typeid() noexcept
151151{
152152}
153153
154154const char*
155bad_typeid::what() const _NOEXCEPT
155bad_typeid::what() const noexcept
156156{
157157 return "std::bad_typeid";
158158}
lib/libcxx/src/support/runtime/exception_glibcxx.ipp+4-4
......@@ -13,19 +13,19 @@
1313
1414namespace std {
1515
16bad_alloc::bad_alloc() _NOEXCEPT
16bad_alloc::bad_alloc() noexcept
1717{
1818}
1919
20bad_array_new_length::bad_array_new_length() _NOEXCEPT
20bad_array_new_length::bad_array_new_length() noexcept
2121{
2222}
2323
24bad_cast::bad_cast() _NOEXCEPT
24bad_cast::bad_cast() noexcept
2525{
2626}
2727
28bad_typeid::bad_typeid() _NOEXCEPT
28bad_typeid::bad_typeid() noexcept
2929{
3030}
3131
lib/libcxx/src/support/runtime/exception_libcxxabi.ipp+2-2
......@@ -13,9 +13,9 @@
1313
1414namespace std {
1515
16bool uncaught_exception() _NOEXCEPT { return uncaught_exceptions() > 0; }
16bool uncaught_exception() noexcept { return uncaught_exceptions() > 0; }
1717
18int uncaught_exceptions() _NOEXCEPT
18int uncaught_exceptions() noexcept
1919{
2020# if _LIBCPPABI_VERSION > 1001
2121 return __cxa_uncaught_exceptions();
lib/libcxx/src/support/runtime/exception_libcxxrt.ipp+2-2
......@@ -13,11 +13,11 @@
1313
1414namespace std {
1515
16bad_exception::~bad_exception() _NOEXCEPT
16bad_exception::~bad_exception() noexcept
1717{
1818}
1919
20const char* bad_exception::what() const _NOEXCEPT
20const char* bad_exception::what() const noexcept
2121{
2222 return "std::bad_exception";
2323}
lib/libcxx/src/support/runtime/exception_msvc.ipp+25-25
......@@ -31,11 +31,11 @@ int __cdecl __uncaught_exceptions();
3131namespace std {
3232
3333unexpected_handler
34set_unexpected(unexpected_handler func) _NOEXCEPT {
34set_unexpected(unexpected_handler func) noexcept {
3535 return ::set_unexpected(func);
3636}
3737
38unexpected_handler get_unexpected() _NOEXCEPT {
38unexpected_handler get_unexpected() noexcept {
3939 return ::_get_unexpected();
4040}
4141
......@@ -46,21 +46,21 @@ void unexpected() {
4646 terminate();
4747}
4848
49terminate_handler set_terminate(terminate_handler func) _NOEXCEPT {
49terminate_handler set_terminate(terminate_handler func) noexcept {
5050 return ::set_terminate(func);
5151}
5252
53terminate_handler get_terminate() _NOEXCEPT {
53terminate_handler get_terminate() noexcept {
5454 return ::_get_terminate();
5555}
5656
5757_LIBCPP_NORETURN
58void terminate() _NOEXCEPT
58void terminate() noexcept
5959{
6060#ifndef _LIBCPP_NO_EXCEPTIONS
6161 try
6262 {
63#endif // _LIBCPP_NO_EXCEPTIONS
63#endif // _LIBCPP_NO_EXCEPTIONS
6464 (*get_terminate())();
6565 // handler should not return
6666 fprintf(stderr, "terminate_handler unexpectedly returned\n");
......@@ -73,88 +73,88 @@ void terminate() _NOEXCEPT
7373 fprintf(stderr, "terminate_handler unexpectedly threw an exception\n");
7474 ::abort();
7575 }
76#endif // _LIBCPP_NO_EXCEPTIONS
76#endif // _LIBCPP_NO_EXCEPTIONS
7777}
7878
79bool uncaught_exception() _NOEXCEPT { return uncaught_exceptions() > 0; }
79bool uncaught_exception() noexcept { return uncaught_exceptions() > 0; }
8080
81int uncaught_exceptions() _NOEXCEPT {
81int uncaught_exceptions() noexcept {
8282 return __uncaught_exceptions();
8383}
8484
8585#if !defined(_LIBCPP_ABI_VCRUNTIME)
86bad_cast::bad_cast() _NOEXCEPT
86bad_cast::bad_cast() noexcept
8787{
8888}
8989
90bad_cast::~bad_cast() _NOEXCEPT
90bad_cast::~bad_cast() noexcept
9191{
9292}
9393
9494const char *
95bad_cast::what() const _NOEXCEPT
95bad_cast::what() const noexcept
9696{
9797 return "std::bad_cast";
9898}
9999
100bad_typeid::bad_typeid() _NOEXCEPT
100bad_typeid::bad_typeid() noexcept
101101{
102102}
103103
104bad_typeid::~bad_typeid() _NOEXCEPT
104bad_typeid::~bad_typeid() noexcept
105105{
106106}
107107
108108const char *
109bad_typeid::what() const _NOEXCEPT
109bad_typeid::what() const noexcept
110110{
111111 return "std::bad_typeid";
112112}
113113
114exception::~exception() _NOEXCEPT
114exception::~exception() noexcept
115115{
116116}
117117
118const char* exception::what() const _NOEXCEPT
118const char* exception::what() const noexcept
119119{
120120 return "std::exception";
121121}
122122
123123
124bad_exception::~bad_exception() _NOEXCEPT
124bad_exception::~bad_exception() noexcept
125125{
126126}
127127
128const char* bad_exception::what() const _NOEXCEPT
128const char* bad_exception::what() const noexcept
129129{
130130 return "std::bad_exception";
131131}
132132
133133
134bad_alloc::bad_alloc() _NOEXCEPT
134bad_alloc::bad_alloc() noexcept
135135{
136136}
137137
138bad_alloc::~bad_alloc() _NOEXCEPT
138bad_alloc::~bad_alloc() noexcept
139139{
140140}
141141
142142const char*
143bad_alloc::what() const _NOEXCEPT
143bad_alloc::what() const noexcept
144144{
145145 return "std::bad_alloc";
146146}
147147
148bad_array_new_length::bad_array_new_length() _NOEXCEPT
148bad_array_new_length::bad_array_new_length() noexcept
149149{
150150}
151151
152bad_array_new_length::~bad_array_new_length() _NOEXCEPT
152bad_array_new_length::~bad_array_new_length() noexcept
153153{
154154}
155155
156156const char*
157bad_array_new_length::what() const _NOEXCEPT
157bad_array_new_length::what() const noexcept
158158{
159159 return "bad_array_new_length";
160160}
lib/libcxx/src/support/runtime/exception_pointer_cxxabi.ipp+6-6
......@@ -13,17 +13,17 @@
1313
1414namespace std {
1515
16exception_ptr::~exception_ptr() _NOEXCEPT {
16exception_ptr::~exception_ptr() noexcept {
1717 __cxa_decrement_exception_refcount(__ptr_);
1818}
1919
20exception_ptr::exception_ptr(const exception_ptr& other) _NOEXCEPT
20exception_ptr::exception_ptr(const exception_ptr& other) noexcept
2121 : __ptr_(other.__ptr_)
2222{
2323 __cxa_increment_exception_refcount(__ptr_);
2424}
2525
26exception_ptr& exception_ptr::operator=(const exception_ptr& other) _NOEXCEPT
26exception_ptr& exception_ptr::operator=(const exception_ptr& other) noexcept
2727{
2828 if (__ptr_ != other.__ptr_)
2929 {
......@@ -34,12 +34,12 @@ exception_ptr& exception_ptr::operator=(const exception_ptr& other) _NOEXCEPT
3434 return *this;
3535}
3636
37nested_exception::nested_exception() _NOEXCEPT
37nested_exception::nested_exception() noexcept
3838 : __ptr_(current_exception())
3939{
4040}
4141
42nested_exception::~nested_exception() _NOEXCEPT
42nested_exception::~nested_exception() noexcept
4343{
4444}
4545
......@@ -52,7 +52,7 @@ nested_exception::rethrow_nested() const
5252 rethrow_exception(__ptr_);
5353}
5454
55exception_ptr current_exception() _NOEXCEPT
55exception_ptr current_exception() noexcept
5656{
5757 // be nicer if there was a constructor that took a ptr, then
5858 // this whole function would be just:
lib/libcxx/src/support/runtime/exception_pointer_glibcxx.ipp+7-7
......@@ -25,35 +25,35 @@ struct exception_ptr
2525{
2626 void* __ptr_;
2727
28 exception_ptr(const exception_ptr&) _NOEXCEPT;
29 exception_ptr& operator=(const exception_ptr&) _NOEXCEPT;
30 ~exception_ptr() _NOEXCEPT;
28 exception_ptr(const exception_ptr&) noexcept;
29 exception_ptr& operator=(const exception_ptr&) noexcept;
30 ~exception_ptr() noexcept;
3131};
3232
3333}
3434
3535_LIBCPP_NORETURN void rethrow_exception(__exception_ptr::exception_ptr);
3636
37exception_ptr::~exception_ptr() _NOEXCEPT
37exception_ptr::~exception_ptr() noexcept
3838{
3939 reinterpret_cast<__exception_ptr::exception_ptr*>(this)->~exception_ptr();
4040}
4141
42exception_ptr::exception_ptr(const exception_ptr& other) _NOEXCEPT
42exception_ptr::exception_ptr(const exception_ptr& other) noexcept
4343 : __ptr_(other.__ptr_)
4444{
4545 new (reinterpret_cast<void*>(this)) __exception_ptr::exception_ptr(
4646 reinterpret_cast<const __exception_ptr::exception_ptr&>(other));
4747}
4848
49exception_ptr& exception_ptr::operator=(const exception_ptr& other) _NOEXCEPT
49exception_ptr& exception_ptr::operator=(const exception_ptr& other) noexcept
5050{
5151 *reinterpret_cast<__exception_ptr::exception_ptr*>(this) =
5252 reinterpret_cast<const __exception_ptr::exception_ptr&>(other);
5353 return *this;
5454}
5555
56nested_exception::nested_exception() _NOEXCEPT
56nested_exception::nested_exception() noexcept
5757 : __ptr_(current_exception())
5858{
5959}
lib/libcxx/src/support/runtime/exception_pointer_msvc.ipp+12-12
......@@ -24,35 +24,35 @@ __ExceptionPtrCopyException(void*, const void*, const void*);
2424
2525namespace std {
2626
27exception_ptr::exception_ptr() _NOEXCEPT { __ExceptionPtrCreate(this); }
28exception_ptr::exception_ptr(nullptr_t) _NOEXCEPT { __ExceptionPtrCreate(this); }
27exception_ptr::exception_ptr() noexcept { __ExceptionPtrCreate(this); }
28exception_ptr::exception_ptr(nullptr_t) noexcept { __ExceptionPtrCreate(this); }
2929
30exception_ptr::exception_ptr(const exception_ptr& __other) _NOEXCEPT {
30exception_ptr::exception_ptr(const exception_ptr& __other) noexcept {
3131 __ExceptionPtrCopy(this, &__other);
3232}
33exception_ptr& exception_ptr::operator=(const exception_ptr& __other) _NOEXCEPT {
33exception_ptr& exception_ptr::operator=(const exception_ptr& __other) noexcept {
3434 __ExceptionPtrAssign(this, &__other);
3535 return *this;
3636}
3737
38exception_ptr& exception_ptr::operator=(nullptr_t) _NOEXCEPT {
38exception_ptr& exception_ptr::operator=(nullptr_t) noexcept {
3939 exception_ptr dummy;
4040 __ExceptionPtrAssign(this, &dummy);
4141 return *this;
4242}
4343
44exception_ptr::~exception_ptr() _NOEXCEPT { __ExceptionPtrDestroy(this); }
44exception_ptr::~exception_ptr() noexcept { __ExceptionPtrDestroy(this); }
4545
46exception_ptr::operator bool() const _NOEXCEPT {
46exception_ptr::operator bool() const noexcept {
4747 return __ExceptionPtrToBool(this);
4848}
4949
50bool operator==(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT {
50bool operator==(const exception_ptr& __x, const exception_ptr& __y) noexcept {
5151 return __ExceptionPtrCompare(&__x, &__y);
5252}
5353
5454
55void swap(exception_ptr& lhs, exception_ptr& rhs) _NOEXCEPT {
55void swap(exception_ptr& lhs, exception_ptr& rhs) noexcept {
5656 __ExceptionPtrSwap(&rhs, &lhs);
5757}
5858
......@@ -63,7 +63,7 @@ exception_ptr __copy_exception_ptr(void* __except, const void* __ptr) {
6363 return __ret;
6464}
6565
66exception_ptr current_exception() _NOEXCEPT {
66exception_ptr current_exception() noexcept {
6767 exception_ptr __ret;
6868 __ExceptionPtrCurrentException(&__ret);
6969 return __ret;
......@@ -72,9 +72,9 @@ exception_ptr current_exception() _NOEXCEPT {
7272_LIBCPP_NORETURN
7373void rethrow_exception(exception_ptr p) { __ExceptionPtrRethrow(&p); }
7474
75nested_exception::nested_exception() _NOEXCEPT : __ptr_(current_exception()) {}
75nested_exception::nested_exception() noexcept : __ptr_(current_exception()) {}
7676
77nested_exception::~nested_exception() _NOEXCEPT {}
77nested_exception::~nested_exception() noexcept {}
7878
7979_LIBCPP_NORETURN
8080void nested_exception::rethrow_nested() const {
lib/libcxx/src/support/runtime/exception_pointer_unimplemented.ipp+6-6
......@@ -12,14 +12,14 @@
1212
1313namespace std {
1414
15exception_ptr::~exception_ptr() _NOEXCEPT
15exception_ptr::~exception_ptr() noexcept
1616{
1717# warning exception_ptr not yet implemented
1818 fprintf(stderr, "exception_ptr not yet implemented\n");
1919 ::abort();
2020}
2121
22exception_ptr::exception_ptr(const exception_ptr& other) _NOEXCEPT
22exception_ptr::exception_ptr(const exception_ptr& other) noexcept
2323 : __ptr_(other.__ptr_)
2424{
2525# warning exception_ptr not yet implemented
......@@ -27,21 +27,21 @@ exception_ptr::exception_ptr(const exception_ptr& other) _NOEXCEPT
2727 ::abort();
2828}
2929
30exception_ptr& exception_ptr::operator=(const exception_ptr& other) _NOEXCEPT
30exception_ptr& exception_ptr::operator=(const exception_ptr& other) noexcept
3131{
3232# warning exception_ptr not yet implemented
3333 fprintf(stderr, "exception_ptr not yet implemented\n");
3434 ::abort();
3535}
3636
37nested_exception::nested_exception() _NOEXCEPT
37nested_exception::nested_exception() noexcept
3838 : __ptr_(current_exception())
3939{
4040}
4141
4242#if !defined(__GLIBCXX__)
4343
44nested_exception::~nested_exception() _NOEXCEPT
44nested_exception::~nested_exception() noexcept
4545{
4646}
4747
......@@ -61,7 +61,7 @@ nested_exception::rethrow_nested() const
6161#endif // FIXME
6262}
6363
64exception_ptr current_exception() _NOEXCEPT
64exception_ptr current_exception() noexcept
6565{
6666# warning exception_ptr not yet implemented
6767 fprintf(stderr, "exception_ptr not yet implemented\n");
lib/libcxx/src/support/runtime/new_handler_fallback.ipp+2-2
......@@ -12,13 +12,13 @@ namespace std {
1212_LIBCPP_SAFE_STATIC static std::new_handler __new_handler;
1313
1414new_handler
15set_new_handler(new_handler handler) _NOEXCEPT
15set_new_handler(new_handler handler) noexcept
1616{
1717 return __libcpp_atomic_exchange(&__new_handler, handler);
1818}
1919
2020new_handler
21get_new_handler() _NOEXCEPT
21get_new_handler() noexcept
2222{
2323 return __libcpp_atomic_load(&__new_handler);
2424}
lib/libcxx/src/support/runtime/stdexcept_default.ipp+15-15
......@@ -23,9 +23,9 @@ logic_error::logic_error(const string& msg) : __imp_(msg.c_str()) {}
2323
2424logic_error::logic_error(const char* msg) : __imp_(msg) {}
2525
26logic_error::logic_error(const logic_error& le) _NOEXCEPT : __imp_(le.__imp_) {}
26logic_error::logic_error(const logic_error& le) noexcept : __imp_(le.__imp_) {}
2727
28logic_error& logic_error::operator=(const logic_error& le) _NOEXCEPT {
28logic_error& logic_error::operator=(const logic_error& le) noexcept {
2929 __imp_ = le.__imp_;
3030 return *this;
3131}
......@@ -34,30 +34,30 @@ runtime_error::runtime_error(const string& msg) : __imp_(msg.c_str()) {}
3434
3535runtime_error::runtime_error(const char* msg) : __imp_(msg) {}
3636
37runtime_error::runtime_error(const runtime_error& re) _NOEXCEPT
37runtime_error::runtime_error(const runtime_error& re) noexcept
3838 : __imp_(re.__imp_) {}
3939
40runtime_error& runtime_error::operator=(const runtime_error& re) _NOEXCEPT {
40runtime_error& runtime_error::operator=(const runtime_error& re) noexcept {
4141 __imp_ = re.__imp_;
4242 return *this;
4343}
4444
4545#if !defined(_LIBCPPABI_VERSION) && !defined(LIBSTDCXX)
4646
47const char* logic_error::what() const _NOEXCEPT { return __imp_.c_str(); }
47const char* logic_error::what() const noexcept { return __imp_.c_str(); }
4848
49const char* runtime_error::what() const _NOEXCEPT { return __imp_.c_str(); }
49const char* runtime_error::what() const noexcept { return __imp_.c_str(); }
5050
51logic_error::~logic_error() _NOEXCEPT {}
52domain_error::~domain_error() _NOEXCEPT {}
53invalid_argument::~invalid_argument() _NOEXCEPT {}
54length_error::~length_error() _NOEXCEPT {}
55out_of_range::~out_of_range() _NOEXCEPT {}
51logic_error::~logic_error() noexcept {}
52domain_error::~domain_error() noexcept {}
53invalid_argument::~invalid_argument() noexcept {}
54length_error::~length_error() noexcept {}
55out_of_range::~out_of_range() noexcept {}
5656
57runtime_error::~runtime_error() _NOEXCEPT {}
58range_error::~range_error() _NOEXCEPT {}
59overflow_error::~overflow_error() _NOEXCEPT {}
60underflow_error::~underflow_error() _NOEXCEPT {}
57runtime_error::~runtime_error() noexcept {}
58range_error::~range_error() noexcept {}
59overflow_error::~overflow_error() noexcept {}
60underflow_error::~underflow_error() noexcept {}
6161
6262#endif
6363
lib/libcxx/src/support/win32/support.cpp+4-1
......@@ -22,7 +22,10 @@ int __libcpp_vasprintf( char **sptr, const char *__restrict format, va_list ap )
2222{
2323 *sptr = NULL;
2424 // Query the count required.
25 int count = _vsnprintf( NULL, 0, format, ap );
25 va_list ap_copy;
26 va_copy(ap_copy, ap);
27 int count = _vsnprintf( NULL, 0, format, ap_copy );
28 va_end(ap_copy);
2629 if (count < 0)
2730 return count;
2831 size_t buffer_size = static_cast<size_t>(count) + 1;
lib/libcxx/src/support/win32/thread_win32.cpp+40-4
......@@ -8,6 +8,8 @@
88//===----------------------------------------------------------------------===//
99
1010#include <__threading_support>
11#define NOMINMAX
12#define WIN32_LEAN_AND_MEAN
1113#include <windows.h>
1214#include <process.h>
1315#include <fibersapi.h>
......@@ -37,6 +39,9 @@ static_assert(alignof(__libcpp_thread_t) == alignof(HANDLE), "");
3739static_assert(sizeof(__libcpp_tls_key) == sizeof(DWORD), "");
3840static_assert(alignof(__libcpp_tls_key) == alignof(DWORD), "");
3941
42static_assert(sizeof(__libcpp_semaphore_t) == sizeof(HANDLE), "");
43static_assert(alignof(__libcpp_semaphore_t) == alignof(HANDLE), "");
44
4045// Mutex
4146int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m)
4247{
......@@ -241,10 +246,8 @@ void __libcpp_thread_yield()
241246
242247void __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns)
243248{
244 using namespace chrono;
245 // round-up to the nearest milisecond
246 milliseconds __ms =
247 duration_cast<milliseconds>(__ns + chrono::nanoseconds(999999));
249 // round-up to the nearest millisecond
250 chrono::milliseconds __ms = chrono::ceil<chrono::milliseconds>(__ns);
248251 // FIXME(compnerd) this should be an alertable sleep (WFSO or SleepEx)
249252 Sleep(__ms.count());
250253}
......@@ -272,4 +275,37 @@ int __libcpp_tls_set(__libcpp_tls_key __key, void *__p)
272275 return 0;
273276}
274277
278// Semaphores
279bool __libcpp_semaphore_init(__libcpp_semaphore_t* __sem, int __init)
280{
281 *(PHANDLE)__sem = CreateSemaphoreEx(nullptr, __init, _LIBCPP_SEMAPHORE_MAX,
282 nullptr, 0, SEMAPHORE_ALL_ACCESS);
283 return *__sem != nullptr;
284}
285
286bool __libcpp_semaphore_destroy(__libcpp_semaphore_t* __sem)
287{
288 CloseHandle(*(PHANDLE)__sem);
289 return true;
290}
291
292bool __libcpp_semaphore_post(__libcpp_semaphore_t* __sem)
293{
294 return ReleaseSemaphore(*(PHANDLE)__sem, 1, nullptr);
295}
296
297bool __libcpp_semaphore_wait(__libcpp_semaphore_t* __sem)
298{
299 return WaitForSingleObjectEx(*(PHANDLE)__sem, INFINITE, false) ==
300 WAIT_OBJECT_0;
301}
302
303bool __libcpp_semaphore_wait_timed(__libcpp_semaphore_t* __sem,
304 chrono::nanoseconds const& __ns)
305{
306 chrono::milliseconds __ms = chrono::ceil<chrono::milliseconds>(__ns);
307 return WaitForSingleObjectEx(*(PHANDLE)__sem, __ms.count(), false) ==
308 WAIT_OBJECT_0;
309}
310
275311_LIBCPP_END_NAMESPACE_STD
lib/libcxx/src/system_error.cpp+17-17
......@@ -28,29 +28,29 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2828// class error_category
2929
3030#if defined(_LIBCPP_DEPRECATED_ABI_LEGACY_LIBRARY_DEFINITIONS_FOR_INLINE_FUNCTIONS)
31error_category::error_category() _NOEXCEPT
31error_category::error_category() noexcept
3232{
3333}
3434#endif
3535
36error_category::~error_category() _NOEXCEPT
36error_category::~error_category() noexcept
3737{
3838}
3939
4040error_condition
41error_category::default_error_condition(int ev) const _NOEXCEPT
41error_category::default_error_condition(int ev) const noexcept
4242{
4343 return error_condition(ev, *this);
4444}
4545
4646bool
47error_category::equivalent(int code, const error_condition& condition) const _NOEXCEPT
47error_category::equivalent(int code, const error_condition& condition) const noexcept
4848{
4949 return default_error_condition(code) == condition;
5050}
5151
5252bool
53error_category::equivalent(const error_code& code, int condition) const _NOEXCEPT
53error_category::equivalent(const error_code& code, int condition) const noexcept
5454{
5555 return *this == code.category() && code.value() == condition;
5656}
......@@ -141,12 +141,12 @@ class _LIBCPP_HIDDEN __generic_error_category
141141 : public __do_message
142142{
143143public:
144 virtual const char* name() const _NOEXCEPT;
144 virtual const char* name() const noexcept;
145145 virtual string message(int ev) const;
146146};
147147
148148const char*
149__generic_error_category::name() const _NOEXCEPT
149__generic_error_category::name() const noexcept
150150{
151151 return "generic";
152152}
......@@ -157,12 +157,12 @@ __generic_error_category::message(int ev) const
157157#ifdef _LIBCPP_ELAST
158158 if (ev > _LIBCPP_ELAST)
159159 return string("unspecified generic_category error");
160#endif // _LIBCPP_ELAST
160#endif // _LIBCPP_ELAST
161161 return __do_message::message(ev);
162162}
163163
164164const error_category&
165generic_category() _NOEXCEPT
165generic_category() noexcept
166166{
167167 static __generic_error_category s;
168168 return s;
......@@ -172,13 +172,13 @@ class _LIBCPP_HIDDEN __system_error_category
172172 : public __do_message
173173{
174174public:
175 virtual const char* name() const _NOEXCEPT;
175 virtual const char* name() const noexcept;
176176 virtual string message(int ev) const;
177 virtual error_condition default_error_condition(int ev) const _NOEXCEPT;
177 virtual error_condition default_error_condition(int ev) const noexcept;
178178};
179179
180180const char*
181__system_error_category::name() const _NOEXCEPT
181__system_error_category::name() const noexcept
182182{
183183 return "system";
184184}
......@@ -189,22 +189,22 @@ __system_error_category::message(int ev) const
189189#ifdef _LIBCPP_ELAST
190190 if (ev > _LIBCPP_ELAST)
191191 return string("unspecified system_category error");
192#endif // _LIBCPP_ELAST
192#endif // _LIBCPP_ELAST
193193 return __do_message::message(ev);
194194}
195195
196196error_condition
197__system_error_category::default_error_condition(int ev) const _NOEXCEPT
197__system_error_category::default_error_condition(int ev) const noexcept
198198{
199199#ifdef _LIBCPP_ELAST
200200 if (ev > _LIBCPP_ELAST)
201201 return error_condition(ev, system_category());
202#endif // _LIBCPP_ELAST
202#endif // _LIBCPP_ELAST
203203 return error_condition(ev, generic_category());
204204}
205205
206206const error_category&
207system_category() _NOEXCEPT
207system_category() noexcept
208208{
209209 static __system_error_category s;
210210 return s;
......@@ -276,7 +276,7 @@ system_error::system_error(int ev, const error_category& ecat)
276276{
277277}
278278
279system_error::~system_error() _NOEXCEPT
279system_error::~system_error() noexcept
280280{
281281}
282282
lib/libcxx/src/thread.cpp+2-2
......@@ -70,7 +70,7 @@ thread::detach()
7070}
7171
7272unsigned
73thread::hardware_concurrency() _NOEXCEPT
73thread::hardware_concurrency() noexcept
7474{
7575#if defined(_SC_NPROCESSORS_ONLN)
7676 long result = sysconf(_SC_NPROCESSORS_ONLN);
......@@ -94,7 +94,7 @@ thread::hardware_concurrency() _NOEXCEPT
9494# warning hardware_concurrency not yet implemented
9595# endif
9696 return 0; // Means not computable [thread.thread.static]
97#endif // defined(CTL_HW) && defined(HW_NCPU)
97#endif // defined(CTL_HW) && defined(HW_NCPU)
9898}
9999
100100namespace this_thread
lib/libcxx/src/typeinfo.cpp+3-3
......@@ -11,18 +11,18 @@
1111#if defined(_LIBCPP_ABI_MICROSOFT) && !defined(_LIBCPP_ABI_VCRUNTIME)
1212#include <string.h>
1313
14int std::type_info::__compare(const type_info &__rhs) const _NOEXCEPT {
14int std::type_info::__compare(const type_info &__rhs) const noexcept {
1515 if (&__data == &__rhs.__data)
1616 return 0;
1717 return strcmp(&__data.__decorated_name[1], &__rhs.__data.__decorated_name[1]);
1818}
1919
20const char *std::type_info::name() const _NOEXCEPT {
20const char *std::type_info::name() const noexcept {
2121 // TODO(compnerd) cache demangled &__data.__decorated_name[1]
2222 return &__data.__decorated_name[1];
2323}
2424
25size_t std::type_info::hash_code() const _NOEXCEPT {
25size_t std::type_info::hash_code() const noexcept {
2626#if defined(_WIN64)
2727 constexpr size_t fnv_offset_basis = 14695981039346656037ull;
2828 constexpr size_t fnv_prime = 10995116282110ull;
lib/libcxxabi/src/cxa_default_handlers.cpp+2-2
......@@ -108,7 +108,7 @@ namespace std
108108{
109109
110110unexpected_handler
111set_unexpected(unexpected_handler func) _NOEXCEPT
111set_unexpected(unexpected_handler func) noexcept
112112{
113113 if (func == 0)
114114 func = default_unexpected_handler;
......@@ -117,7 +117,7 @@ set_unexpected(unexpected_handler func) _NOEXCEPT
117117}
118118
119119terminate_handler
120set_terminate(terminate_handler func) _NOEXCEPT
120set_terminate(terminate_handler func) noexcept
121121{
122122 if (func == 0)
123123 func = default_terminate_handler;
lib/libcxxabi/src/cxa_exception.cpp+2-2
......@@ -20,7 +20,7 @@
2020#include "include/atomic_support.h"
2121
2222#if __has_feature(address_sanitizer)
23extern "C" void __asan_handle_no_return(void);
23#include <sanitizer/asan_interface.h>
2424#endif
2525
2626// +---------------------------+-----------------------------+---------------+
......@@ -384,7 +384,7 @@ asm (
384384 " bl abort\n"
385385 " .popsection"
386386);
387#endif // defined(_LIBCXXABI_ARM_EHABI)
387#endif // defined(_LIBCXXABI_ARM_EHABI)
388388
389389/*
390390This routine can catch foreign or native exceptions. If native, the exception
lib/libcxxabi/src/cxa_exception.h+1-1
......@@ -161,4 +161,4 @@ extern "C" _LIBCXXABI_FUNC_VIS void __cxa_free_dependent_exception (void * depen
161161
162162} // namespace __cxxabiv1
163163
164#endif // _CXA_EXCEPTION_H
164#endif // _CXA_EXCEPTION_H
lib/libcxxabi/src/cxa_handlers.cpp+8-8
......@@ -23,7 +23,7 @@ namespace std
2323{
2424
2525unexpected_handler
26get_unexpected() _NOEXCEPT
26get_unexpected() noexcept
2727{
2828 return __libcpp_atomic_load(&__cxa_unexpected_handler, _AO_Acquire);
2929}
......@@ -44,18 +44,18 @@ unexpected()
4444}
4545
4646terminate_handler
47get_terminate() _NOEXCEPT
47get_terminate() noexcept
4848{
4949 return __libcpp_atomic_load(&__cxa_terminate_handler, _AO_Acquire);
5050}
5151
5252void
53__terminate(terminate_handler func) _NOEXCEPT
53__terminate(terminate_handler func) noexcept
5454{
5555#ifndef _LIBCXXABI_NO_EXCEPTIONS
5656 try
5757 {
58#endif // _LIBCXXABI_NO_EXCEPTIONS
58#endif // _LIBCXXABI_NO_EXCEPTIONS
5959 func();
6060 // handler should not return
6161 abort_message("terminate_handler unexpectedly returned");
......@@ -66,12 +66,12 @@ __terminate(terminate_handler func) _NOEXCEPT
6666 // handler should not throw exception
6767 abort_message("terminate_handler unexpectedly threw an exception");
6868 }
69#endif // _LIBCXXABI_NO_EXCEPTIONS
69#endif // _LIBCXXABI_NO_EXCEPTIONS
7070}
7171
7272__attribute__((noreturn))
7373void
74terminate() _NOEXCEPT
74terminate() noexcept
7575{
7676#ifndef _LIBCXXABI_NO_EXCEPTIONS
7777 // If there might be an uncaught exception
......@@ -97,13 +97,13 @@ new_handler __cxa_new_handler = 0;
9797}
9898
9999new_handler
100set_new_handler(new_handler handler) _NOEXCEPT
100set_new_handler(new_handler handler) noexcept
101101{
102102 return __libcpp_atomic_exchange(&__cxa_new_handler, handler, _AO_Acq_Rel);
103103}
104104
105105new_handler
106get_new_handler() _NOEXCEPT
106get_new_handler() noexcept
107107{
108108 return __libcpp_atomic_load(&__cxa_new_handler, _AO_Acquire);
109109}
lib/libcxxabi/src/cxa_handlers.h+2-2
......@@ -25,7 +25,7 @@ __unexpected(unexpected_handler func);
2525
2626_LIBCXXABI_HIDDEN _LIBCXXABI_NORETURN
2727void
28__terminate(terminate_handler func) _NOEXCEPT;
28__terminate(terminate_handler func) noexcept;
2929
3030} // std
3131
......@@ -52,4 +52,4 @@ _LIBCXXABI_DATA_VIS extern void (*__cxa_new_handler)();
5252
5353} // extern "C"
5454
55#endif // _CXA_HANDLERS_H
55#endif // _CXA_HANDLERS_H
lib/libcxxabi/src/cxa_personality.cpp+74-19
......@@ -88,7 +88,7 @@ extern "C" EXCEPTION_DISPOSITION _GCC_specific_handler(PEXCEPTION_RECORD,
8888| +-------------+---------------------------------+------------------------------+ |
8989| ... |
9090+----------------------------------------------------------------------------------+
91#endif // __USING_SJLJ_EXCEPTIONS__
91#endif // __USING_SJLJ_EXCEPTIONS__
9292+---------------------------------------------------------------------+
9393| Beginning of Action Table ttypeIndex == 0 : cleanup |
9494| ... ttypeIndex > 0 : catch |
......@@ -241,10 +241,11 @@ readSLEB128(const uint8_t** data)
241241/// @link http://dwarfstd.org/Dwarf3.pdf @unlink
242242/// @param data reference variable holding memory pointer to decode from
243243/// @param encoding dwarf encoding type
244/// @param base for adding relative offset, default to 0
244245/// @returns decoded value
245246static
246247uintptr_t
247readEncodedPointer(const uint8_t** data, uint8_t encoding)
248readEncodedPointer(const uint8_t** data, uint8_t encoding, uintptr_t base = 0)
248249{
249250 uintptr_t result = 0;
250251 if (encoding == DW_EH_PE_omit)
......@@ -295,8 +296,12 @@ readEncodedPointer(const uint8_t** data, uint8_t encoding)
295296 if (result)
296297 result += (uintptr_t)(*data);
297298 break;
298 case DW_EH_PE_textrel:
299299 case DW_EH_PE_datarel:
300 assert((base != 0) && "DW_EH_PE_datarel is invalid with a base of 0");
301 if (result)
302 result += base;
303 break;
304 case DW_EH_PE_textrel:
300305 case DW_EH_PE_funcrel:
301306 case DW_EH_PE_aligned:
302307 default:
......@@ -348,7 +353,7 @@ static const void* read_target2_value(const void* ptr)
348353static const __shim_type_info*
349354get_shim_type_info(uint64_t ttypeIndex, const uint8_t* classInfo,
350355 uint8_t ttypeEncoding, bool native_exception,
351 _Unwind_Exception* unwind_exception)
356 _Unwind_Exception* unwind_exception, uintptr_t /*base*/ = 0)
352357{
353358 if (classInfo == 0)
354359 {
......@@ -371,7 +376,7 @@ static
371376const __shim_type_info*
372377get_shim_type_info(uint64_t ttypeIndex, const uint8_t* classInfo,
373378 uint8_t ttypeEncoding, bool native_exception,
374 _Unwind_Exception* unwind_exception)
379 _Unwind_Exception* unwind_exception, uintptr_t base = 0)
375380{
376381 if (classInfo == 0)
377382 {
......@@ -400,7 +405,8 @@ get_shim_type_info(uint64_t ttypeIndex, const uint8_t* classInfo,
400405 call_terminate(native_exception, unwind_exception);
401406 }
402407 classInfo -= ttypeIndex;
403 return (const __shim_type_info*)readEncodedPointer(&classInfo, ttypeEncoding);
408 return (const __shim_type_info*)readEncodedPointer(&classInfo,
409 ttypeEncoding, base);
404410}
405411#endif // !defined(_LIBCXXABI_ARM_EHABI)
406412
......@@ -418,7 +424,8 @@ static
418424bool
419425exception_spec_can_catch(int64_t specIndex, const uint8_t* classInfo,
420426 uint8_t ttypeEncoding, const __shim_type_info* excpType,
421 void* adjustedPtr, _Unwind_Exception* unwind_exception)
427 void* adjustedPtr, _Unwind_Exception* unwind_exception,
428 uintptr_t /*base*/ = 0)
422429{
423430 if (classInfo == 0)
424431 {
......@@ -463,7 +470,8 @@ static
463470bool
464471exception_spec_can_catch(int64_t specIndex, const uint8_t* classInfo,
465472 uint8_t ttypeEncoding, const __shim_type_info* excpType,
466 void* adjustedPtr, _Unwind_Exception* unwind_exception)
473 void* adjustedPtr, _Unwind_Exception* unwind_exception,
474 uintptr_t base = 0)
467475{
468476 if (classInfo == 0)
469477 {
......@@ -485,7 +493,8 @@ exception_spec_can_catch(int64_t specIndex, const uint8_t* classInfo,
485493 classInfo,
486494 ttypeEncoding,
487495 true,
488 unwind_exception);
496 unwind_exception,
497 base);
489498 void* tempPtr = adjustedPtr;
490499 if (catchType->can_catch(excpType, tempPtr))
491500 return false;
......@@ -531,6 +540,9 @@ set_registers(_Unwind_Exception* unwind_exception, _Unwind_Context* context,
531540{
532541#if defined(__USING_SJLJ_EXCEPTIONS__)
533542#define __builtin_eh_return_data_regno(regno) regno
543#elif defined(__ibmxl__)
544// IBM xlclang++ compiler does not support __builtin_eh_return_data_regno.
545#define __builtin_eh_return_data_regno(regno) regno + 3
534546#endif
535547 _Unwind_SetGR(context, __builtin_eh_return_data_regno(0),
536548 reinterpret_cast<uintptr_t>(unwind_exception));
......@@ -610,6 +622,11 @@ static void scan_eh_tab(scan_results &results, _Unwind_Action actions,
610622 return;
611623 }
612624 results.languageSpecificData = lsda;
625#if defined(_AIX)
626 uintptr_t base = _Unwind_GetDataRelBase(context);
627#else
628 uintptr_t base = 0;
629#endif
613630 // Get the current instruction pointer and offset it before next
614631 // instruction in the current frame which threw the exception.
615632 uintptr_t ip = _Unwind_GetIP(context) - 1;
......@@ -628,13 +645,14 @@ static void scan_eh_tab(scan_results &results, _Unwind_Action actions,
628645 // ip is 1-based index into call site table
629646#else // !__USING_SJLJ_EXCEPTIONS__
630647 uintptr_t ipOffset = ip - funcStart;
631#endif // !defined(_USING_SLJL_EXCEPTIONS__)
648#endif // !defined(_USING_SLJL_EXCEPTIONS__)
632649 const uint8_t* classInfo = NULL;
633650 // Note: See JITDwarfEmitter::EmitExceptionTable(...) for corresponding
634651 // dwarf emission
635652 // Parse LSDA header.
636653 uint8_t lpStartEncoding = *lsda++;
637 const uint8_t* lpStart = (const uint8_t*)readEncodedPointer(&lsda, lpStartEncoding);
654 const uint8_t* lpStart =
655 (const uint8_t*)readEncodedPointer(&lsda, lpStartEncoding, base);
638656 if (lpStart == 0)
639657 lpStart = (const uint8_t*)funcStart;
640658 uint8_t ttypeEncoding = *lsda++;
......@@ -673,7 +691,7 @@ static void scan_eh_tab(scan_results &results, _Unwind_Action actions,
673691 uintptr_t landingPad = readULEB128(&callSitePtr);
674692 uintptr_t actionEntry = readULEB128(&callSitePtr);
675693 if (--ip == 0)
676#endif // __USING_SJLJ_EXCEPTIONS__
694#endif // __USING_SJLJ_EXCEPTIONS__
677695 {
678696 // Found the call site containing ip.
679697#ifndef __USING_SJLJ_EXCEPTIONS__
......@@ -687,7 +705,7 @@ static void scan_eh_tab(scan_results &results, _Unwind_Action actions,
687705 results.landingPad = landingPad;
688706#else // __USING_SJLJ_EXCEPTIONS__
689707 ++landingPad;
690#endif // __USING_SJLJ_EXCEPTIONS__
708#endif // __USING_SJLJ_EXCEPTIONS__
691709 if (actionEntry == 0)
692710 {
693711 // Found a cleanup
......@@ -711,7 +729,8 @@ static void scan_eh_tab(scan_results &results, _Unwind_Action actions,
711729 const __shim_type_info* catchType =
712730 get_shim_type_info(static_cast<uint64_t>(ttypeIndex),
713731 classInfo, ttypeEncoding,
714 native_exception, unwind_exception);
732 native_exception, unwind_exception,
733 base);
715734 if (catchType == 0)
716735 {
717736 // Found catch (...) catches everything, including
......@@ -772,7 +791,8 @@ static void scan_eh_tab(scan_results &results, _Unwind_Action actions,
772791 }
773792 if (exception_spec_can_catch(ttypeIndex, classInfo,
774793 ttypeEncoding, excpType,
775 adjustedPtr, unwind_exception))
794 adjustedPtr,
795 unwind_exception, base))
776796 {
777797 // Native exception caught by exception
778798 // specification.
......@@ -820,7 +840,7 @@ static void scan_eh_tab(scan_results &results, _Unwind_Action actions,
820840 // Possible stack corruption.
821841 call_terminate(native_exception, unwind_exception);
822842 }
823#endif // !__USING_SJLJ_EXCEPTIONS__
843#endif // !__USING_SJLJ_EXCEPTIONS__
824844 } // there might be some tricky cases which break out of this loop
825845
826846 // It is possible that no eh table entry specify how to handle
......@@ -911,6 +931,15 @@ __gxx_personality_v0
911931
912932 // Jump to the handler.
913933 set_registers(unwind_exception, context, results);
934 // Cache base for calculating the address of ttype in
935 // __cxa_call_unexpected.
936 if (results.ttypeIndex < 0) {
937#if defined(_AIX)
938 exception_header->catchTemp = (void *)_Unwind_GetDataRelBase(context);
939#else
940 exception_header->catchTemp = 0;
941#endif
942 }
914943 return _URC_INSTALL_CONTEXT;
915944 }
916945
......@@ -940,6 +969,16 @@ __gxx_personality_v0
940969 assert(actions & _UA_CLEANUP_PHASE);
941970 assert(results.reason == _URC_HANDLER_FOUND);
942971 set_registers(unwind_exception, context, results);
972 // Cache base for calculating the address of ttype in __cxa_call_unexpected.
973 if (results.ttypeIndex < 0) {
974 __cxa_exception* exception_header =
975 (__cxa_exception*)(unwind_exception + 1) - 1;
976#if defined(_AIX)
977 exception_header->catchTemp = (void *)_Unwind_GetDataRelBase(context);
978#else
979 exception_header->catchTemp = 0;
980#endif
981 }
943982 return _URC_INSTALL_CONTEXT;
944983}
945984
......@@ -1114,6 +1153,8 @@ __cxa_call_unexpected(void* arg)
11141153 __cxa_exception* old_exception_header = 0;
11151154 int64_t ttypeIndex;
11161155 const uint8_t* lsda;
1156 uintptr_t base = 0;
1157
11171158 if (native_old_exception)
11181159 {
11191160 old_exception_header = (__cxa_exception*)(unwind_exception+1) - 1;
......@@ -1127,6 +1168,7 @@ __cxa_call_unexpected(void* arg)
11271168#else
11281169 ttypeIndex = old_exception_header->handlerSwitchValue;
11291170 lsda = old_exception_header->languageSpecificData;
1171 base = (uintptr_t)old_exception_header->catchTemp;
11301172#endif
11311173 }
11321174 else
......@@ -1150,11 +1192,13 @@ __cxa_call_unexpected(void* arg)
11501192 // Have:
11511193 // old_exception_header->languageSpecificData
11521194 // old_exception_header->actionRecord
1195 // old_exception_header->catchTemp, base for calculating ttype
11531196 // Need
11541197 // const uint8_t* classInfo
11551198 // uint8_t ttypeEncoding
11561199 uint8_t lpStartEncoding = *lsda++;
1157 const uint8_t* lpStart = (const uint8_t*)readEncodedPointer(&lsda, lpStartEncoding);
1200 const uint8_t* lpStart =
1201 (const uint8_t*)readEncodedPointer(&lsda, lpStartEncoding, base);
11581202 (void)lpStart; // purposefully unused. Just needed to increment lsda.
11591203 uint8_t ttypeEncoding = *lsda++;
11601204 if (ttypeEncoding == DW_EH_PE_omit)
......@@ -1181,7 +1225,8 @@ __cxa_call_unexpected(void* arg)
11811225 ((__cxa_dependent_exception*)new_exception_header)->primaryException :
11821226 new_exception_header + 1;
11831227 if (!exception_spec_can_catch(ttypeIndex, classInfo, ttypeEncoding,
1184 excpType, adjustedPtr, unwind_exception))
1228 excpType, adjustedPtr,
1229 unwind_exception, base))
11851230 {
11861231 // We need to __cxa_end_catch, but for the old exception,
11871232 // not the new one. This is a little tricky ...
......@@ -1210,7 +1255,8 @@ __cxa_call_unexpected(void* arg)
12101255 std::bad_exception be;
12111256 adjustedPtr = &be;
12121257 if (!exception_spec_can_catch(ttypeIndex, classInfo, ttypeEncoding,
1213 excpType, adjustedPtr, unwind_exception))
1258 excpType, adjustedPtr,
1259 unwind_exception, base))
12141260 {
12151261 // We need to __cxa_end_catch for both the old exception and the
12161262 // new exception. Technically we should do it in that order.
......@@ -1226,6 +1272,15 @@ __cxa_call_unexpected(void* arg)
12261272 std::__terminate(t_handler);
12271273}
12281274
1275#if defined(_AIX)
1276// Personality routine for EH using the range table. Make it an alias of
1277// __gxx_personality_v0().
1278_LIBCXXABI_FUNC_VIS _Unwind_Reason_Code __xlcxx_personality_v1(
1279 int version, _Unwind_Action actions, uint64_t exceptionClass,
1280 _Unwind_Exception* unwind_exception, _Unwind_Context* context)
1281 __attribute__((__alias__("__gxx_personality_v0")));
1282#endif
1283
12291284} // extern "C"
12301285
12311286} // __cxxabiv1
lib/libcxxabi/src/demangle/ItaniumDemangle.h+19-7
......@@ -280,17 +280,20 @@ public:
280280class VendorExtQualType final : public Node {
281281 const Node *Ty;
282282 StringView Ext;
283 const Node *TA;
283284
284285public:
285 VendorExtQualType(const Node *Ty_, StringView Ext_)
286 : Node(KVendorExtQualType), Ty(Ty_), Ext(Ext_) {}
286 VendorExtQualType(const Node *Ty_, StringView Ext_, const Node *TA_)
287 : Node(KVendorExtQualType), Ty(Ty_), Ext(Ext_), TA(TA_) {}
287288
288 template<typename Fn> void match(Fn F) const { F(Ty, Ext); }
289 template <typename Fn> void match(Fn F) const { F(Ty, Ext, TA); }
289290
290291 void printLeft(OutputStream &S) const override {
291292 Ty->print(S);
292293 S += " ";
293294 S += Ext;
295 if (TA != nullptr)
296 TA->print(S);
294297 }
295298};
296299
......@@ -3680,8 +3683,6 @@ Node *AbstractManglingParser<Derived, Alloc>::parseQualifiedType() {
36803683 if (Qual.empty())
36813684 return nullptr;
36823685
3683 // FIXME parse the optional <template-args> here!
3684
36853686 // extension ::= U <objc-name> <objc-type> # objc-type<identifier>
36863687 if (Qual.startsWith("objcproto")) {
36873688 StringView ProtoSourceName = Qual.dropFront(std::strlen("objcproto"));
......@@ -3699,10 +3700,17 @@ Node *AbstractManglingParser<Derived, Alloc>::parseQualifiedType() {
36993700 return make<ObjCProtoName>(Child, Proto);
37003701 }
37013702
3703 Node *TA = nullptr;
3704 if (look() == 'I') {
3705 TA = getDerived().parseTemplateArgs();
3706 if (TA == nullptr)
3707 return nullptr;
3708 }
3709
37023710 Node *Child = getDerived().parseQualifiedType();
37033711 if (Child == nullptr)
37043712 return nullptr;
3705 return make<VendorExtQualType>(Child, Qual);
3713 return make<VendorExtQualType>(Child, Qual, TA);
37063714 }
37073715
37083716 Qualifiers Quals = parseCVQualifiers();
......@@ -3875,7 +3883,7 @@ Node *AbstractManglingParser<Derived, Alloc>::parseType() {
38753883 // ::= Dh # IEEE 754r half-precision floating point (16 bits)
38763884 case 'h':
38773885 First += 2;
3878 return make<NameType>("decimal16");
3886 return make<NameType>("half");
38793887 // ::= Di # char32_t
38803888 case 'i':
38813889 First += 2;
......@@ -5227,14 +5235,18 @@ Node *AbstractManglingParser<Derived, Alloc>::parseEncoding() {
52275235 class SaveTemplateParams {
52285236 AbstractManglingParser *Parser;
52295237 decltype(TemplateParams) OldParams;
5238 decltype(OuterTemplateParams) OldOuterParams;
52305239
52315240 public:
52325241 SaveTemplateParams(AbstractManglingParser *TheParser) : Parser(TheParser) {
52335242 OldParams = std::move(Parser->TemplateParams);
5243 OldOuterParams = std::move(Parser->OuterTemplateParams);
52345244 Parser->TemplateParams.clear();
5245 Parser->OuterTemplateParams.clear();
52355246 }
52365247 ~SaveTemplateParams() {
52375248 Parser->TemplateParams = std::move(OldParams);
5249 Parser->OuterTemplateParams = std::move(OldOuterParams);
52385250 }
52395251 } SaveTemplateParams(this);
52405252
lib/libcxxabi/src/demangle/StringView.h+3-10
......@@ -36,8 +36,9 @@ public:
3636 StringView(const char *Str) : First(Str), Last(Str + std::strlen(Str)) {}
3737 StringView() : First(nullptr), Last(nullptr) {}
3838
39 StringView substr(size_t From) const {
40 return StringView(begin() + From, size() - From);
39 StringView substr(size_t Pos, size_t Len = npos) const {
40 assert(Pos <= size());
41 return StringView(begin() + Pos, std::min(Len, size() - Pos));
4142 }
4243
4344 size_t find(char C, size_t From = 0) const {
......@@ -51,14 +52,6 @@ public:
5152 return npos;
5253 }
5354
54 StringView substr(size_t From, size_t To) const {
55 if (To >= size())
56 To = size() - 1;
57 if (From >= size())
58 From = size() - 1;
59 return StringView(First + From, First + To);
60 }
61
6255 StringView dropFront(size_t N = 1) const {
6356 if (N >= size())
6457 N = size();
lib/libcxxabi/src/private_typeinfo.cpp+2-2
......@@ -679,7 +679,7 @@ __dynamic_cast(const void *static_ptr, const __class_type_info *static_type,
679679 info.number_of_dst_type = 1;
680680 dynamic_type->search_above_dst(&info, dynamic_ptr, dynamic_ptr, public_path, true);
681681 }
682#endif // _LIBCXXABI_FORGIVING_DYNAMIC_CAST
682#endif // _LIBCXXABI_FORGIVING_DYNAMIC_CAST
683683 // Query the search.
684684 if (info.path_dst_ptr_to_static_ptr == public_path)
685685 dst_ptr = dynamic_ptr;
......@@ -707,7 +707,7 @@ __dynamic_cast(const void *static_ptr, const __class_type_info *static_type,
707707 info = {dst_type, static_ptr, static_type, src2dst_offset, 0};
708708 dynamic_type->search_below_dst(&info, dynamic_ptr, public_path, true);
709709 }
710#endif // _LIBCXXABI_FORGIVING_DYNAMIC_CAST
710#endif // _LIBCXXABI_FORGIVING_DYNAMIC_CAST
711711 // Query the search.
712712 switch (info.number_to_static_ptr)
713713 {
lib/libcxxabi/src/private_typeinfo.h+1-1
......@@ -248,4 +248,4 @@ public:
248248
249249} // __cxxabiv1
250250
251#endif // __PRIVATE_TYPEINFO_H_
251#endif // __PRIVATE_TYPEINFO_H_
lib/libcxxabi/src/stdlib_exception.cpp+10-10
......@@ -14,22 +14,22 @@ namespace std
1414
1515// exception
1616
17exception::~exception() _NOEXCEPT
17exception::~exception() noexcept
1818{
1919}
2020
21const char* exception::what() const _NOEXCEPT
21const char* exception::what() const noexcept
2222{
2323 return "std::exception";
2424}
2525
2626// bad_exception
2727
28bad_exception::~bad_exception() _NOEXCEPT
28bad_exception::~bad_exception() noexcept
2929{
3030}
3131
32const char* bad_exception::what() const _NOEXCEPT
32const char* bad_exception::what() const noexcept
3333{
3434 return "std::bad_exception";
3535}
......@@ -37,32 +37,32 @@ const char* bad_exception::what() const _NOEXCEPT
3737
3838// bad_alloc
3939
40bad_alloc::bad_alloc() _NOEXCEPT
40bad_alloc::bad_alloc() noexcept
4141{
4242}
4343
44bad_alloc::~bad_alloc() _NOEXCEPT
44bad_alloc::~bad_alloc() noexcept
4545{
4646}
4747
4848const char*
49bad_alloc::what() const _NOEXCEPT
49bad_alloc::what() const noexcept
5050{
5151 return "std::bad_alloc";
5252}
5353
5454// bad_array_new_length
5555
56bad_array_new_length::bad_array_new_length() _NOEXCEPT
56bad_array_new_length::bad_array_new_length() noexcept
5757{
5858}
5959
60bad_array_new_length::~bad_array_new_length() _NOEXCEPT
60bad_array_new_length::~bad_array_new_length() noexcept
6161{
6262}
6363
6464const char*
65bad_array_new_length::what() const _NOEXCEPT
65bad_array_new_length::what() const noexcept
6666{
6767 return "bad_array_new_length";
6868}
lib/libcxxabi/src/stdlib_new_delete.cpp+26-26
......@@ -12,8 +12,8 @@
1212#include <new>
1313#include <cstdlib>
1414
15#if !defined(_THROW_BAD_ALLOC) || !defined(_NOEXCEPT) || !defined(_LIBCXXABI_WEAK)
16#error The _THROW_BAD_ALLOC, _NOEXCEPT, and _LIBCXXABI_WEAK libc++ macros must \
15#if !defined(_THROW_BAD_ALLOC) || !defined(_LIBCXXABI_WEAK)
16#error The _THROW_BAD_ALLOC and _LIBCXXABI_WEAK libc++ macros must \
1717 already be defined by libc++.
1818#endif
1919// Implement all new and delete operators as weak definitions
......@@ -46,20 +46,20 @@ operator new(std::size_t size) _THROW_BAD_ALLOC
4646
4747_LIBCXXABI_WEAK
4848void*
49operator new(size_t size, const std::nothrow_t&) _NOEXCEPT
49operator new(size_t size, const std::nothrow_t&) noexcept
5050{
5151 void* p = nullptr;
5252#ifndef _LIBCXXABI_NO_EXCEPTIONS
5353 try
5454 {
55#endif // _LIBCXXABI_NO_EXCEPTIONS
55#endif // _LIBCXXABI_NO_EXCEPTIONS
5656 p = ::operator new(size);
5757#ifndef _LIBCXXABI_NO_EXCEPTIONS
5858 }
5959 catch (...)
6060 {
6161 }
62#endif // _LIBCXXABI_NO_EXCEPTIONS
62#endif // _LIBCXXABI_NO_EXCEPTIONS
6363 return p;
6464}
6565
......@@ -72,61 +72,61 @@ operator new[](size_t size) _THROW_BAD_ALLOC
7272
7373_LIBCXXABI_WEAK
7474void*
75operator new[](size_t size, const std::nothrow_t&) _NOEXCEPT
75operator new[](size_t size, const std::nothrow_t&) noexcept
7676{
7777 void* p = nullptr;
7878#ifndef _LIBCXXABI_NO_EXCEPTIONS
7979 try
8080 {
81#endif // _LIBCXXABI_NO_EXCEPTIONS
81#endif // _LIBCXXABI_NO_EXCEPTIONS
8282 p = ::operator new[](size);
8383#ifndef _LIBCXXABI_NO_EXCEPTIONS
8484 }
8585 catch (...)
8686 {
8787 }
88#endif // _LIBCXXABI_NO_EXCEPTIONS
88#endif // _LIBCXXABI_NO_EXCEPTIONS
8989 return p;
9090}
9191
9292_LIBCXXABI_WEAK
9393void
94operator delete(void* ptr) _NOEXCEPT
94operator delete(void* ptr) noexcept
9595{
9696 ::free(ptr);
9797}
9898
9999_LIBCXXABI_WEAK
100100void
101operator delete(void* ptr, const std::nothrow_t&) _NOEXCEPT
101operator delete(void* ptr, const std::nothrow_t&) noexcept
102102{
103103 ::operator delete(ptr);
104104}
105105
106106_LIBCXXABI_WEAK
107107void
108operator delete(void* ptr, size_t) _NOEXCEPT
108operator delete(void* ptr, size_t) noexcept
109109{
110110 ::operator delete(ptr);
111111}
112112
113113_LIBCXXABI_WEAK
114114void
115operator delete[] (void* ptr) _NOEXCEPT
115operator delete[] (void* ptr) noexcept
116116{
117117 ::operator delete(ptr);
118118}
119119
120120_LIBCXXABI_WEAK
121121void
122operator delete[] (void* ptr, const std::nothrow_t&) _NOEXCEPT
122operator delete[] (void* ptr, const std::nothrow_t&) noexcept
123123{
124124 ::operator delete[](ptr);
125125}
126126
127127_LIBCXXABI_WEAK
128128void
129operator delete[] (void* ptr, size_t) _NOEXCEPT
129operator delete[] (void* ptr, size_t) noexcept
130130{
131131 ::operator delete[](ptr);
132132}
......@@ -167,20 +167,20 @@ operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC
167167
168168_LIBCXXABI_WEAK
169169void*
170operator new(size_t size, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT
170operator new(size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept
171171{
172172 void* p = nullptr;
173173#ifndef _LIBCXXABI_NO_EXCEPTIONS
174174 try
175175 {
176#endif // _LIBCXXABI_NO_EXCEPTIONS
176#endif // _LIBCXXABI_NO_EXCEPTIONS
177177 p = ::operator new(size, alignment);
178178#ifndef _LIBCXXABI_NO_EXCEPTIONS
179179 }
180180 catch (...)
181181 {
182182 }
183#endif // _LIBCXXABI_NO_EXCEPTIONS
183#endif // _LIBCXXABI_NO_EXCEPTIONS
184184 return p;
185185}
186186
......@@ -193,61 +193,61 @@ operator new[](size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC
193193
194194_LIBCXXABI_WEAK
195195void*
196operator new[](size_t size, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT
196operator new[](size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept
197197{
198198 void* p = nullptr;
199199#ifndef _LIBCXXABI_NO_EXCEPTIONS
200200 try
201201 {
202#endif // _LIBCXXABI_NO_EXCEPTIONS
202#endif // _LIBCXXABI_NO_EXCEPTIONS
203203 p = ::operator new[](size, alignment);
204204#ifndef _LIBCXXABI_NO_EXCEPTIONS
205205 }
206206 catch (...)
207207 {
208208 }
209#endif // _LIBCXXABI_NO_EXCEPTIONS
209#endif // _LIBCXXABI_NO_EXCEPTIONS
210210 return p;
211211}
212212
213213_LIBCXXABI_WEAK
214214void
215operator delete(void* ptr, std::align_val_t) _NOEXCEPT
215operator delete(void* ptr, std::align_val_t) noexcept
216216{
217217 std::__libcpp_aligned_free(ptr);
218218}
219219
220220_LIBCXXABI_WEAK
221221void
222operator delete(void* ptr, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT
222operator delete(void* ptr, std::align_val_t alignment, const std::nothrow_t&) noexcept
223223{
224224 ::operator delete(ptr, alignment);
225225}
226226
227227_LIBCXXABI_WEAK
228228void
229operator delete(void* ptr, size_t, std::align_val_t alignment) _NOEXCEPT
229operator delete(void* ptr, size_t, std::align_val_t alignment) noexcept
230230{
231231 ::operator delete(ptr, alignment);
232232}
233233
234234_LIBCXXABI_WEAK
235235void
236operator delete[] (void* ptr, std::align_val_t alignment) _NOEXCEPT
236operator delete[] (void* ptr, std::align_val_t alignment) noexcept
237237{
238238 ::operator delete(ptr, alignment);
239239}
240240
241241_LIBCXXABI_WEAK
242242void
243operator delete[] (void* ptr, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT
243operator delete[] (void* ptr, std::align_val_t alignment, const std::nothrow_t&) noexcept
244244{
245245 ::operator delete[](ptr, alignment);
246246}
247247
248248_LIBCXXABI_WEAK
249249void
250operator delete[] (void* ptr, size_t, std::align_val_t alignment) _NOEXCEPT
250operator delete[] (void* ptr, size_t, std::align_val_t alignment) noexcept
251251{
252252 ::operator delete[](ptr, alignment);
253253}
lib/libcxxabi/src/stdlib_stdexcept.cpp+14-12
......@@ -6,7 +6,6 @@
66//
77//===----------------------------------------------------------------------===//
88
9#include "../../libcxx/src/include/refstring.h"
109#include "stdexcept"
1110#include "new"
1211#include <cstdlib>
......@@ -14,34 +13,37 @@
1413#include <cstdint>
1514#include <cstddef>
1615
16// This includes an implementation file from libc++.
17#include "../../libcxx/src/include/refstring.h"
18
1719static_assert(sizeof(std::__libcpp_refstring) == sizeof(const char *), "");
1820
1921namespace std // purposefully not using versioning namespace
2022{
2123
22logic_error::~logic_error() _NOEXCEPT {}
24logic_error::~logic_error() noexcept {}
2325
2426const char*
25logic_error::what() const _NOEXCEPT
27logic_error::what() const noexcept
2628{
2729 return __imp_.c_str();
2830}
2931
30runtime_error::~runtime_error() _NOEXCEPT {}
32runtime_error::~runtime_error() noexcept {}
3133
3234const char*
33runtime_error::what() const _NOEXCEPT
35runtime_error::what() const noexcept
3436{
3537 return __imp_.c_str();
3638}
3739
38domain_error::~domain_error() _NOEXCEPT {}
39invalid_argument::~invalid_argument() _NOEXCEPT {}
40length_error::~length_error() _NOEXCEPT {}
41out_of_range::~out_of_range() _NOEXCEPT {}
40domain_error::~domain_error() noexcept {}
41invalid_argument::~invalid_argument() noexcept {}
42length_error::~length_error() noexcept {}
43out_of_range::~out_of_range() noexcept {}
4244
43range_error::~range_error() _NOEXCEPT {}
44overflow_error::~overflow_error() _NOEXCEPT {}
45underflow_error::~underflow_error() _NOEXCEPT {}
45range_error::~range_error() noexcept {}
46overflow_error::~overflow_error() noexcept {}
47underflow_error::~underflow_error() noexcept {}
4648
4749} // std
lib/libcxxabi/src/stdlib_typeinfo.cpp+6-6
......@@ -19,32 +19,32 @@ type_info::~type_info()
1919
2020// bad_cast
2121
22bad_cast::bad_cast() _NOEXCEPT
22bad_cast::bad_cast() noexcept
2323{
2424}
2525
26bad_cast::~bad_cast() _NOEXCEPT
26bad_cast::~bad_cast() noexcept
2727{
2828}
2929
3030const char*
31bad_cast::what() const _NOEXCEPT
31bad_cast::what() const noexcept
3232{
3333 return "std::bad_cast";
3434}
3535
3636// bad_typeid
3737
38bad_typeid::bad_typeid() _NOEXCEPT
38bad_typeid::bad_typeid() noexcept
3939{
4040}
4141
42bad_typeid::~bad_typeid() _NOEXCEPT
42bad_typeid::~bad_typeid() noexcept
4343{
4444}
4545
4646const char*
47bad_typeid::what() const _NOEXCEPT
47bad_typeid::what() const noexcept
4848{
4949 return "std::bad_typeid";
5050}
lib/libunwind/include/__libunwind_config.h+12-5
......@@ -131,12 +131,19 @@
131131 #define _LIBUNWIND_CONTEXT_SIZE 16
132132 #define _LIBUNWIND_CURSOR_SIZE 23
133133# elif defined(__riscv)
134# if __riscv_xlen == 64
135# define _LIBUNWIND_TARGET_RISCV 1
136# define _LIBUNWIND_CONTEXT_SIZE 64
137# define _LIBUNWIND_CURSOR_SIZE 76
134# define _LIBUNWIND_TARGET_RISCV 1
135# if defined(__riscv_flen)
136# define RISCV_FLEN __riscv_flen
138137# else
139# error "Unsupported RISC-V ABI"
138# define RISCV_FLEN 0
139# endif
140# define _LIBUNWIND_CONTEXT_SIZE (32 * (__riscv_xlen + RISCV_FLEN) / 64)
141# if __riscv_xlen == 32
142# define _LIBUNWIND_CURSOR_SIZE (_LIBUNWIND_CONTEXT_SIZE + 7)
143# elif __riscv_xlen == 64
144# define _LIBUNWIND_CURSOR_SIZE (_LIBUNWIND_CONTEXT_SIZE + 12)
145# else
146# error "Unsupported RISC-V ABI"
140147# endif
141148# define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_RISCV
142149# elif defined(__ve__)
lib/libunwind/include/libunwind.h+24-23
......@@ -493,16 +493,16 @@ enum {
493493
494494// 64-bit ARM64 registers
495495enum {
496 UNW_ARM64_X0 = 0,
497 UNW_ARM64_X1 = 1,
498 UNW_ARM64_X2 = 2,
499 UNW_ARM64_X3 = 3,
500 UNW_ARM64_X4 = 4,
501 UNW_ARM64_X5 = 5,
502 UNW_ARM64_X6 = 6,
503 UNW_ARM64_X7 = 7,
504 UNW_ARM64_X8 = 8,
505 UNW_ARM64_X9 = 9,
496 UNW_ARM64_X0 = 0,
497 UNW_ARM64_X1 = 1,
498 UNW_ARM64_X2 = 2,
499 UNW_ARM64_X3 = 3,
500 UNW_ARM64_X4 = 4,
501 UNW_ARM64_X5 = 5,
502 UNW_ARM64_X6 = 6,
503 UNW_ARM64_X7 = 7,
504 UNW_ARM64_X8 = 8,
505 UNW_ARM64_X9 = 9,
506506 UNW_ARM64_X10 = 10,
507507 UNW_ARM64_X11 = 11,
508508 UNW_ARM64_X12 = 12,
......@@ -523,24 +523,25 @@ enum {
523523 UNW_ARM64_X27 = 27,
524524 UNW_ARM64_X28 = 28,
525525 UNW_ARM64_X29 = 29,
526 UNW_ARM64_FP = 29,
526 UNW_ARM64_FP = 29,
527527 UNW_ARM64_X30 = 30,
528 UNW_ARM64_LR = 30,
528 UNW_ARM64_LR = 30,
529529 UNW_ARM64_X31 = 31,
530 UNW_ARM64_SP = 31,
530 UNW_ARM64_SP = 31,
531 UNW_ARM64_PC = 32,
531532 // reserved block
532533 UNW_ARM64_RA_SIGN_STATE = 34,
533534 // reserved block
534 UNW_ARM64_D0 = 64,
535 UNW_ARM64_D1 = 65,
536 UNW_ARM64_D2 = 66,
537 UNW_ARM64_D3 = 67,
538 UNW_ARM64_D4 = 68,
539 UNW_ARM64_D5 = 69,
540 UNW_ARM64_D6 = 70,
541 UNW_ARM64_D7 = 71,
542 UNW_ARM64_D8 = 72,
543 UNW_ARM64_D9 = 73,
535 UNW_ARM64_D0 = 64,
536 UNW_ARM64_D1 = 65,
537 UNW_ARM64_D2 = 66,
538 UNW_ARM64_D3 = 67,
539 UNW_ARM64_D4 = 68,
540 UNW_ARM64_D5 = 69,
541 UNW_ARM64_D6 = 70,
542 UNW_ARM64_D7 = 71,
543 UNW_ARM64_D8 = 72,
544 UNW_ARM64_D9 = 73,
544545 UNW_ARM64_D10 = 74,
545546 UNW_ARM64_D11 = 75,
546547 UNW_ARM64_D12 = 76,
lib/libunwind/src/DwarfInstructions.hpp+12-5
......@@ -167,6 +167,16 @@ int DwarfInstructions<A, R>::stepWithDwarf(A &addressSpace, pint_t pc,
167167
168168 // restore registers that DWARF says were saved
169169 R newRegisters = registers;
170
171 // Typically, the CFA is the stack pointer at the call site in
172 // the previous frame. However, there are scenarios in which this is not
173 // true. For example, if we switched to a new stack. In that case, the
174 // value of the previous SP might be indicated by a CFI directive.
175 //
176 // We set the SP here to the CFA, allowing for it to be overridden
177 // by a CFI directive later on.
178 newRegisters.setSP(cfa);
179
170180 pint_t returnAddress = 0;
171181 const int lastReg = R::lastDwarfRegNum();
172182 assert(static_cast<int>(CFI_Parser<A>::kMaxRegisterNumber) >= lastReg &&
......@@ -200,10 +210,6 @@ int DwarfInstructions<A, R>::stepWithDwarf(A &addressSpace, pint_t pc,
200210 }
201211 }
202212
203 // By definition, the CFA is the stack pointer at the call site, so
204 // restoring SP means setting it to CFA.
205 newRegisters.setSP(cfa);
206
207213 isSignalFrame = cieInfo.isSignalFrame;
208214
209215#if defined(_LIBUNWIND_TARGET_AARCH64)
......@@ -213,7 +219,8 @@ int DwarfInstructions<A, R>::stepWithDwarf(A &addressSpace, pint_t pc,
213219 // restored. autia1716 is used instead of autia as autia1716 assembles
214220 // to a NOP on pre-v8.3a architectures.
215221 if ((R::getArch() == REGISTERS_ARM64) &&
216 prolog.savedRegisters[UNW_ARM64_RA_SIGN_STATE].value) {
222 prolog.savedRegisters[UNW_ARM64_RA_SIGN_STATE].value &&
223 returnAddress != 0) {
217224#if !defined(_LIBUNWIND_IS_NATIVE_ONLY)
218225 return UNW_ECROSSRASIGNING;
219226#else
lib/libunwind/src/Registers.hpp+92-31
......@@ -1849,31 +1849,39 @@ inline bool Registers_arm64::validRegister(int regNum) const {
18491849 return false;
18501850 if (regNum == UNW_ARM64_RA_SIGN_STATE)
18511851 return true;
1852 if ((regNum > 31) && (regNum < 64))
1852 if ((regNum > 32) && (regNum < 64))
18531853 return false;
18541854 return true;
18551855}
18561856
18571857inline uint64_t Registers_arm64::getRegister(int regNum) const {
1858 if (regNum == UNW_REG_IP)
1858 if (regNum == UNW_REG_IP || regNum == UNW_ARM64_PC)
18591859 return _registers.__pc;
1860 if (regNum == UNW_REG_SP)
1860 if (regNum == UNW_REG_SP || regNum == UNW_ARM64_SP)
18611861 return _registers.__sp;
18621862 if (regNum == UNW_ARM64_RA_SIGN_STATE)
18631863 return _registers.__ra_sign_state;
1864 if ((regNum >= 0) && (regNum < 32))
1864 if (regNum == UNW_ARM64_FP)
1865 return _registers.__fp;
1866 if (regNum == UNW_ARM64_LR)
1867 return _registers.__lr;
1868 if ((regNum >= 0) && (regNum < 29))
18651869 return _registers.__x[regNum];
18661870 _LIBUNWIND_ABORT("unsupported arm64 register");
18671871}
18681872
18691873inline void Registers_arm64::setRegister(int regNum, uint64_t value) {
1870 if (regNum == UNW_REG_IP)
1874 if (regNum == UNW_REG_IP || regNum == UNW_ARM64_PC)
18711875 _registers.__pc = value;
1872 else if (regNum == UNW_REG_SP)
1876 else if (regNum == UNW_REG_SP || regNum == UNW_ARM64_SP)
18731877 _registers.__sp = value;
18741878 else if (regNum == UNW_ARM64_RA_SIGN_STATE)
18751879 _registers.__ra_sign_state = value;
1876 else if ((regNum >= 0) && (regNum < 32))
1880 else if (regNum == UNW_ARM64_FP)
1881 _registers.__fp = value;
1882 else if (regNum == UNW_ARM64_LR)
1883 _registers.__lr = value;
1884 else if ((regNum >= 0) && (regNum < 29))
18771885 _registers.__x[regNum] = value;
18781886 else
18791887 _LIBUNWIND_ABORT("unsupported arm64 register");
......@@ -1943,12 +1951,14 @@ inline const char *Registers_arm64::getRegisterName(int regNum) {
19431951 return "x27";
19441952 case UNW_ARM64_X28:
19451953 return "x28";
1946 case UNW_ARM64_X29:
1954 case UNW_ARM64_FP:
19471955 return "fp";
1948 case UNW_ARM64_X30:
1956 case UNW_ARM64_LR:
19491957 return "lr";
1950 case UNW_ARM64_X31:
1958 case UNW_ARM64_SP:
19511959 return "sp";
1960 case UNW_ARM64_PC:
1961 return "pc";
19521962 case UNW_ARM64_D0:
19531963 return "d0";
19541964 case UNW_ARM64_D1:
......@@ -3718,19 +3728,51 @@ inline const char *Registers_hexagon::getRegisterName(int regNum) {
37183728
37193729
37203730#if defined(_LIBUNWIND_TARGET_RISCV)
3721/// Registers_riscv holds the register state of a thread in a 64-bit RISC-V
3731/// Registers_riscv holds the register state of a thread in a RISC-V
37223732/// process.
3733
3734// This check makes it safe when LIBUNWIND_ENABLE_CROSS_UNWINDING enabled.
3735# ifdef __riscv
3736# if __riscv_xlen == 32
3737typedef uint32_t reg_t;
3738# elif __riscv_xlen == 64
3739typedef uint64_t reg_t;
3740# else
3741# error "Unsupported __riscv_xlen"
3742# endif
3743
3744# if defined(__riscv_flen)
3745# if __riscv_flen == 64
3746typedef double fp_t;
3747# elif __riscv_flen == 32
3748typedef float fp_t;
3749# else
3750# error "Unsupported __riscv_flen"
3751# endif
3752# else
3753// This is just for supressing undeclared error of fp_t.
3754typedef double fp_t;
3755# endif
3756# else
3757// Use Max possible width when cross unwinding
3758typedef uint64_t reg_t;
3759typedef double fp_t;
3760# define __riscv_xlen 64
3761# define __riscv_flen 64
3762#endif
3763
3764/// Registers_riscv holds the register state of a thread.
37233765class _LIBUNWIND_HIDDEN Registers_riscv {
37243766public:
37253767 Registers_riscv();
37263768 Registers_riscv(const void *registers);
37273769
37283770 bool validRegister(int num) const;
3729 uint64_t getRegister(int num) const;
3730 void setRegister(int num, uint64_t value);
3771 reg_t getRegister(int num) const;
3772 void setRegister(int num, reg_t value);
37313773 bool validFloatRegister(int num) const;
3732 double getFloatRegister(int num) const;
3733 void setFloatRegister(int num, double value);
3774 fp_t getFloatRegister(int num) const;
3775 void setFloatRegister(int num, fp_t value);
37343776 bool validVectorRegister(int num) const;
37353777 v128 getVectorRegister(int num) const;
37363778 void setVectorRegister(int num, v128 value);
......@@ -3739,31 +3781,45 @@ public:
37393781 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_RISCV; }
37403782 static int getArch() { return REGISTERS_RISCV; }
37413783
3742 uint64_t getSP() const { return _registers[2]; }
3743 void setSP(uint64_t value) { _registers[2] = value; }
3744 uint64_t getIP() const { return _registers[0]; }
3745 void setIP(uint64_t value) { _registers[0] = value; }
3784 reg_t getSP() const { return _registers[2]; }
3785 void setSP(reg_t value) { _registers[2] = value; }
3786 reg_t getIP() const { return _registers[0]; }
3787 void setIP(reg_t value) { _registers[0] = value; }
37463788
37473789private:
37483790 // _registers[0] holds the pc
3749 uint64_t _registers[32];
3750 double _floats[32];
3791 reg_t _registers[32];
3792# if defined(__riscv_flen)
3793 fp_t _floats[32];
3794# endif
37513795};
37523796
37533797inline Registers_riscv::Registers_riscv(const void *registers) {
37543798 static_assert((check_fit<Registers_riscv, unw_context_t>::does_fit),
37553799 "riscv registers do not fit into unw_context_t");
37563800 memcpy(&_registers, registers, sizeof(_registers));
3801# if __riscv_xlen == 32
3802 static_assert(sizeof(_registers) == 0x80,
3803 "expected float registers to be at offset 128");
3804# elif __riscv_xlen == 64
37573805 static_assert(sizeof(_registers) == 0x100,
37583806 "expected float registers to be at offset 256");
3807# else
3808# error "Unexpected float registers."
3809# endif
3810
3811# if defined(__riscv_flen)
37593812 memcpy(_floats,
37603813 static_cast<const uint8_t *>(registers) + sizeof(_registers),
37613814 sizeof(_floats));
3815# endif
37623816}
37633817
37643818inline Registers_riscv::Registers_riscv() {
37653819 memset(&_registers, 0, sizeof(_registers));
3820# if defined(__riscv_flen)
37663821 memset(&_floats, 0, sizeof(_floats));
3822# endif
37673823}
37683824
37693825inline bool Registers_riscv::validRegister(int regNum) const {
......@@ -3778,7 +3834,7 @@ inline bool Registers_riscv::validRegister(int regNum) const {
37783834 return true;
37793835}
37803836
3781inline uint64_t Registers_riscv::getRegister(int regNum) const {
3837inline reg_t Registers_riscv::getRegister(int regNum) const {
37823838 if (regNum == UNW_REG_IP)
37833839 return _registers[0];
37843840 if (regNum == UNW_REG_SP)
......@@ -3790,7 +3846,7 @@ inline uint64_t Registers_riscv::getRegister(int regNum) const {
37903846 _LIBUNWIND_ABORT("unsupported riscv register");
37913847}
37923848
3793inline void Registers_riscv::setRegister(int regNum, uint64_t value) {
3849inline void Registers_riscv::setRegister(int regNum, reg_t value) {
37943850 if (regNum == UNW_REG_IP)
37953851 _registers[0] = value;
37963852 else if (regNum == UNW_REG_SP)
......@@ -3944,32 +4000,37 @@ inline const char *Registers_riscv::getRegisterName(int regNum) {
39444000}
39454001
39464002inline bool Registers_riscv::validFloatRegister(int regNum) const {
4003# if defined(__riscv_flen)
39474004 if (regNum < UNW_RISCV_F0)
39484005 return false;
39494006 if (regNum > UNW_RISCV_F31)
39504007 return false;
39514008 return true;
4009# else
4010 (void)regNum;
4011 return false;
4012# endif
39524013}
39534014
3954inline double Registers_riscv::getFloatRegister(int regNum) const {
3955#if defined(__riscv_flen) && __riscv_flen == 64
4015inline fp_t Registers_riscv::getFloatRegister(int regNum) const {
4016# if defined(__riscv_flen)
39564017 assert(validFloatRegister(regNum));
39574018 return _floats[regNum - UNW_RISCV_F0];
3958#else
4019# else
39594020 (void)regNum;
39604021 _LIBUNWIND_ABORT("libunwind not built with float support");
3961#endif
4022# endif
39624023}
39634024
3964inline void Registers_riscv::setFloatRegister(int regNum, double value) {
3965#if defined(__riscv_flen) && __riscv_flen == 64
4025inline void Registers_riscv::setFloatRegister(int regNum, fp_t value) {
4026# if defined(__riscv_flen)
39664027 assert(validFloatRegister(regNum));
39674028 _floats[regNum - UNW_RISCV_F0] = value;
3968#else
4029# else
39694030 (void)regNum;
39704031 (void)value;
39714032 _LIBUNWIND_ABORT("libunwind not built with float support");
3972#endif
4033# endif
39734034}
39744035
39754036inline bool Registers_riscv::validVectorRegister(int) const {
lib/libunwind/src/UnwindCursor.hpp+9-7
......@@ -1737,14 +1737,16 @@ bool UnwindCursor<A, R>::getInfoFromCompactEncodingSection(pint_t pc,
17371737 else
17381738 funcEnd = firstLevelNextPageFunctionOffset + sects.dso_base;
17391739 if (pc < funcStart) {
1740 _LIBUNWIND_DEBUG_LOG("malformed __unwind_info, pc=0x%llX not in second "
1741 "level compressed unwind table. funcStart=0x%llX",
1740 _LIBUNWIND_DEBUG_LOG("malformed __unwind_info, pc=0x%llX "
1741 "not in second level compressed unwind table. "
1742 "funcStart=0x%llX",
17421743 (uint64_t) pc, (uint64_t) funcStart);
17431744 return false;
17441745 }
17451746 if (pc > funcEnd) {
1746 _LIBUNWIND_DEBUG_LOG("malformed __unwind_info, pc=0x%llX not in second "
1747 "level compressed unwind table. funcEnd=0x%llX",
1747 _LIBUNWIND_DEBUG_LOG("malformed __unwind_info, pc=0x%llX "
1748 "not in second level compressed unwind table. "
1749 "funcEnd=0x%llX",
17481750 (uint64_t) pc, (uint64_t) funcEnd);
17491751 return false;
17501752 }
......@@ -1764,9 +1766,9 @@ bool UnwindCursor<A, R>::getInfoFromCompactEncodingSection(pint_t pc,
17641766 pageEncodingIndex * sizeof(uint32_t));
17651767 }
17661768 } else {
1767 _LIBUNWIND_DEBUG_LOG("malformed __unwind_info at 0x%0llX bad second "
1768 "level page",
1769 (uint64_t) sects.compact_unwind_section);
1769 _LIBUNWIND_DEBUG_LOG(
1770 "malformed __unwind_info at 0x%0llX bad second level page",
1771 (uint64_t)sects.compact_unwind_section);
17701772 return false;
17711773 }
17721774
lib/libunwind/src/UnwindRegistersRestore.S+192-192
......@@ -134,7 +134,7 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_ppc646jumptoEv)
134134
135135// load register (GPR)
136136#define PPC64_LR(n) \
137 ld %r##n, (8 * (n + 2))(%r3)
137 ld n, (8 * (n + 2))(3)
138138
139139 // restore integral registers
140140 // skip r0 for now
......@@ -176,12 +176,12 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_ppc646jumptoEv)
176176 // (note that this also restores floating point registers and V registers,
177177 // because part of VS is mapped to these registers)
178178
179 addi %r4, %r3, PPC64_OFFS_FP
179 addi 4, 3, PPC64_OFFS_FP
180180
181181// load VS register
182182#define PPC64_LVS(n) \
183 lxvd2x %vs##n, 0, %r4 ;\
184 addi %r4, %r4, 16
183 lxvd2x n, 0, 4 ;\
184 addi 4, 4, 16
185185
186186 // restore the first 32 VS regs (and also all floating point regs)
187187 PPC64_LVS(0)
......@@ -220,23 +220,23 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_ppc646jumptoEv)
220220 // use VRSAVE to conditionally restore the remaining VS regs,
221221 // that are where the V regs are mapped
222222
223 ld %r5, PPC64_OFFS_VRSAVE(%r3) // test VRsave
224 cmpwi %r5, 0
223 ld 5, PPC64_OFFS_VRSAVE(3) // test VRsave
224 cmpwi 5, 0
225225 beq Lnovec
226226
227227// conditionally load VS
228228#define PPC64_CLVS_BOTTOM(n) \
229229 beq Ldone##n ;\
230 addi %r4, %r3, PPC64_OFFS_FP + n * 16 ;\
231 lxvd2x %vs##n, 0, %r4 ;\
230 addi 4, 3, PPC64_OFFS_FP + n * 16 ;\
231 lxvd2x n, 0, 4 ;\
232232Ldone##n:
233233
234#define PPC64_CLVSl(n) \
235 andis. %r0, %r5, (1<<(47-n)) ;\
234#define PPC64_CLVSl(n) \
235 andis. 0, 5, (1 PPC_LEFT_SHIFT(47-n)) ;\
236236PPC64_CLVS_BOTTOM(n)
237237
238#define PPC64_CLVSh(n) \
239 andi. %r0, %r5, (1<<(63-n)) ;\
238#define PPC64_CLVSh(n) \
239 andi. 0, 5, (1 PPC_LEFT_SHIFT(63-n)) ;\
240240PPC64_CLVS_BOTTOM(n)
241241
242242 PPC64_CLVSl(32)
......@@ -276,7 +276,7 @@ PPC64_CLVS_BOTTOM(n)
276276
277277// load FP register
278278#define PPC64_LF(n) \
279 lfd %f##n, (PPC64_OFFS_FP + n * 16)(%r3)
279 lfd n, (PPC64_OFFS_FP + n * 16)(3)
280280
281281 // restore float registers
282282 PPC64_LF(0)
......@@ -314,30 +314,30 @@ PPC64_CLVS_BOTTOM(n)
314314
315315#if defined(__ALTIVEC__)
316316 // restore vector registers if any are in use
317 ld %r5, PPC64_OFFS_VRSAVE(%r3) // test VRsave
318 cmpwi %r5, 0
317 ld 5, PPC64_OFFS_VRSAVE(3) // test VRsave
318 cmpwi 5, 0
319319 beq Lnovec
320320
321 subi %r4, %r1, 16
321 subi 4, 1, 16
322322 // r4 is now a 16-byte aligned pointer into the red zone
323323 // the _vectorScalarRegisters may not be 16-byte aligned
324324 // so copy via red zone temp buffer
325325
326326#define PPC64_CLV_UNALIGNED_BOTTOM(n) \
327327 beq Ldone##n ;\
328 ld %r0, (PPC64_OFFS_V + n * 16)(%r3) ;\
329 std %r0, 0(%r4) ;\
330 ld %r0, (PPC64_OFFS_V + n * 16 + 8)(%r3) ;\
331 std %r0, 8(%r4) ;\
332 lvx %v##n, 0, %r4 ;\
328 ld 0, (PPC64_OFFS_V + n * 16)(3) ;\
329 std 0, 0(4) ;\
330 ld 0, (PPC64_OFFS_V + n * 16 + 8)(3) ;\
331 std 0, 8(4) ;\
332 lvx n, 0, 4 ;\
333333Ldone ## n:
334334
335#define PPC64_CLV_UNALIGNEDl(n) \
336 andis. %r0, %r5, (1<<(15-n)) ;\
335#define PPC64_CLV_UNALIGNEDl(n) \
336 andis. 0, 5, (1 PPC_LEFT_SHIFT(15-n)) ;\
337337PPC64_CLV_UNALIGNED_BOTTOM(n)
338338
339#define PPC64_CLV_UNALIGNEDh(n) \
340 andi. %r0, %r5, (1<<(31-n)) ;\
339#define PPC64_CLV_UNALIGNEDh(n) \
340 andi. 0, 5, (1 PPC_LEFT_SHIFT(31-n)) ;\
341341PPC64_CLV_UNALIGNED_BOTTOM(n)
342342
343343 PPC64_CLV_UNALIGNEDl(0)
......@@ -377,10 +377,10 @@ PPC64_CLV_UNALIGNED_BOTTOM(n)
377377#endif
378378
379379Lnovec:
380 ld %r0, PPC64_OFFS_CR(%r3)
381 mtcr %r0
382 ld %r0, PPC64_OFFS_SRR0(%r3)
383 mtctr %r0
380 ld 0, PPC64_OFFS_CR(3)
381 mtcr 0
382 ld 0, PPC64_OFFS_SRR0(3)
383 mtctr 0
384384
385385 PPC64_LR(0)
386386 PPC64_LR(5)
......@@ -402,111 +402,111 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_ppc6jumptoEv)
402402 // restore integral registerrs
403403 // skip r0 for now
404404 // skip r1 for now
405 lwz %r2, 16(%r3)
405 lwz 2, 16(3)
406406 // skip r3 for now
407407 // skip r4 for now
408408 // skip r5 for now
409 lwz %r6, 32(%r3)
410 lwz %r7, 36(%r3)
411 lwz %r8, 40(%r3)
412 lwz %r9, 44(%r3)
413 lwz %r10, 48(%r3)
414 lwz %r11, 52(%r3)
415 lwz %r12, 56(%r3)
416 lwz %r13, 60(%r3)
417 lwz %r14, 64(%r3)
418 lwz %r15, 68(%r3)
419 lwz %r16, 72(%r3)
420 lwz %r17, 76(%r3)
421 lwz %r18, 80(%r3)
422 lwz %r19, 84(%r3)
423 lwz %r20, 88(%r3)
424 lwz %r21, 92(%r3)
425 lwz %r22, 96(%r3)
426 lwz %r23,100(%r3)
427 lwz %r24,104(%r3)
428 lwz %r25,108(%r3)
429 lwz %r26,112(%r3)
430 lwz %r27,116(%r3)
431 lwz %r28,120(%r3)
432 lwz %r29,124(%r3)
433 lwz %r30,128(%r3)
434 lwz %r31,132(%r3)
409 lwz 6, 32(3)
410 lwz 7, 36(3)
411 lwz 8, 40(3)
412 lwz 9, 44(3)
413 lwz 10, 48(3)
414 lwz 11, 52(3)
415 lwz 12, 56(3)
416 lwz 13, 60(3)
417 lwz 14, 64(3)
418 lwz 15, 68(3)
419 lwz 16, 72(3)
420 lwz 17, 76(3)
421 lwz 18, 80(3)
422 lwz 19, 84(3)
423 lwz 20, 88(3)
424 lwz 21, 92(3)
425 lwz 22, 96(3)
426 lwz 23,100(3)
427 lwz 24,104(3)
428 lwz 25,108(3)
429 lwz 26,112(3)
430 lwz 27,116(3)
431 lwz 28,120(3)
432 lwz 29,124(3)
433 lwz 30,128(3)
434 lwz 31,132(3)
435435
436436#ifndef __NO_FPRS__
437437 // restore float registers
438 lfd %f0, 160(%r3)
439 lfd %f1, 168(%r3)
440 lfd %f2, 176(%r3)
441 lfd %f3, 184(%r3)
442 lfd %f4, 192(%r3)
443 lfd %f5, 200(%r3)
444 lfd %f6, 208(%r3)
445 lfd %f7, 216(%r3)
446 lfd %f8, 224(%r3)
447 lfd %f9, 232(%r3)
448 lfd %f10,240(%r3)
449 lfd %f11,248(%r3)
450 lfd %f12,256(%r3)
451 lfd %f13,264(%r3)
452 lfd %f14,272(%r3)
453 lfd %f15,280(%r3)
454 lfd %f16,288(%r3)
455 lfd %f17,296(%r3)
456 lfd %f18,304(%r3)
457 lfd %f19,312(%r3)
458 lfd %f20,320(%r3)
459 lfd %f21,328(%r3)
460 lfd %f22,336(%r3)
461 lfd %f23,344(%r3)
462 lfd %f24,352(%r3)
463 lfd %f25,360(%r3)
464 lfd %f26,368(%r3)
465 lfd %f27,376(%r3)
466 lfd %f28,384(%r3)
467 lfd %f29,392(%r3)
468 lfd %f30,400(%r3)
469 lfd %f31,408(%r3)
438 lfd 0, 160(3)
439 lfd 1, 168(3)
440 lfd 2, 176(3)
441 lfd 3, 184(3)
442 lfd 4, 192(3)
443 lfd 5, 200(3)
444 lfd 6, 208(3)
445 lfd 7, 216(3)
446 lfd 8, 224(3)
447 lfd 9, 232(3)
448 lfd 10,240(3)
449 lfd 11,248(3)
450 lfd 12,256(3)
451 lfd 13,264(3)
452 lfd 14,272(3)
453 lfd 15,280(3)
454 lfd 16,288(3)
455 lfd 17,296(3)
456 lfd 18,304(3)
457 lfd 19,312(3)
458 lfd 20,320(3)
459 lfd 21,328(3)
460 lfd 22,336(3)
461 lfd 23,344(3)
462 lfd 24,352(3)
463 lfd 25,360(3)
464 lfd 26,368(3)
465 lfd 27,376(3)
466 lfd 28,384(3)
467 lfd 29,392(3)
468 lfd 30,400(3)
469 lfd 31,408(3)
470470#endif
471471
472472#if defined(__ALTIVEC__)
473473 // restore vector registers if any are in use
474 lwz %r5, 156(%r3) // test VRsave
475 cmpwi %r5, 0
474 lwz 5, 156(3) // test VRsave
475 cmpwi 5, 0
476476 beq Lnovec
477477
478 subi %r4, %r1, 16
479 rlwinm %r4, %r4, 0, 0, 27 // mask low 4-bits
478 subi 4, 1, 16
479 rlwinm 4, 4, 0, 0, 27 // mask low 4-bits
480480 // r4 is now a 16-byte aligned pointer into the red zone
481481 // the _vectorRegisters may not be 16-byte aligned so copy via red zone temp buffer
482
483482
484#define LOAD_VECTOR_UNALIGNEDl(_index) \
485 andis. %r0, %r5, (1<<(15-_index)) SEPARATOR \
483
484#define LOAD_VECTOR_UNALIGNEDl(_index) \
485 andis. 0, 5, (1 PPC_LEFT_SHIFT(15-_index)) SEPARATOR \
486486 beq Ldone ## _index SEPARATOR \
487 lwz %r0, 424+_index*16(%r3) SEPARATOR \
488 stw %r0, 0(%r4) SEPARATOR \
489 lwz %r0, 424+_index*16+4(%r3) SEPARATOR \
490 stw %r0, 4(%r4) SEPARATOR \
491 lwz %r0, 424+_index*16+8(%r3) SEPARATOR \
492 stw %r0, 8(%r4) SEPARATOR \
493 lwz %r0, 424+_index*16+12(%r3) SEPARATOR \
494 stw %r0, 12(%r4) SEPARATOR \
495 lvx %v ## _index, 0, %r4 SEPARATOR \
487 lwz 0, 424+_index*16(3) SEPARATOR \
488 stw 0, 0(%r4) SEPARATOR \
489 lwz 0, 424+_index*16+4(%r3) SEPARATOR \
490 stw 0, 4(%r4) SEPARATOR \
491 lwz 0, 424+_index*16+8(%r3) SEPARATOR \
492 stw 0, 8(%r4) SEPARATOR \
493 lwz 0, 424+_index*16+12(%r3) SEPARATOR \
494 stw 0, 12(%r4) SEPARATOR \
495 lvx _index, 0, 4 SEPARATOR \
496496 Ldone ## _index:
497497
498#define LOAD_VECTOR_UNALIGNEDh(_index) \
499 andi. %r0, %r5, (1<<(31-_index)) SEPARATOR \
498#define LOAD_VECTOR_UNALIGNEDh(_index) \
499 andi. 0, 5, (1 PPC_LEFT_SHIFT(31-_index)) SEPARATOR \
500500 beq Ldone ## _index SEPARATOR \
501 lwz %r0, 424+_index*16(%r3) SEPARATOR \
502 stw %r0, 0(%r4) SEPARATOR \
503 lwz %r0, 424+_index*16+4(%r3) SEPARATOR \
504 stw %r0, 4(%r4) SEPARATOR \
505 lwz %r0, 424+_index*16+8(%r3) SEPARATOR \
506 stw %r0, 8(%r4) SEPARATOR \
507 lwz %r0, 424+_index*16+12(%r3) SEPARATOR \
508 stw %r0, 12(%r4) SEPARATOR \
509 lvx %v ## _index, 0, %r4 SEPARATOR \
501 lwz 0, 424+_index*16(3) SEPARATOR \
502 stw 0, 0(4) SEPARATOR \
503 lwz 0, 424+_index*16+4(3) SEPARATOR \
504 stw 0, 4(4) SEPARATOR \
505 lwz 0, 424+_index*16+8(3) SEPARATOR \
506 stw 0, 8(%r4) SEPARATOR \
507 lwz 0, 424+_index*16+12(3) SEPARATOR \
508 stw 0, 12(4) SEPARATOR \
509 lvx _index, 0, 4 SEPARATOR \
510510 Ldone ## _index:
511511
512512
......@@ -545,17 +545,17 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_ppc6jumptoEv)
545545#endif
546546
547547Lnovec:
548 lwz %r0, 136(%r3) // __cr
549 mtcr %r0
550 lwz %r0, 148(%r3) // __ctr
551 mtctr %r0
552 lwz %r0, 0(%r3) // __ssr0
553 mtctr %r0
554 lwz %r0, 8(%r3) // do r0 now
555 lwz %r5, 28(%r3) // do r5 now
556 lwz %r4, 24(%r3) // do r4 now
557 lwz %r1, 12(%r3) // do sp now
558 lwz %r3, 20(%r3) // do r3 last
548 lwz 0, 136(3) // __cr
549 mtcr 0
550 lwz 0, 148(3) // __ctr
551 mtctr 0
552 lwz 0, 0(3) // __ssr0
553 mtctr 0
554 lwz 0, 8(3) // do r0 now
555 lwz 5, 28(3) // do r5 now
556 lwz 4, 24(3) // do r4 now
557 lwz 1, 12(3) // do sp now
558 lwz 3, 20(3) // do r3 last
559559 bctr
560560
561561#elif defined(__aarch64__)
......@@ -1072,7 +1072,7 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_sparc6jumptoEv)
10721072 jmp %o7
10731073 nop
10741074
1075#elif defined(__riscv) && __riscv_xlen == 64
1075#elif defined(__riscv)
10761076
10771077//
10781078// void libunwind::Registers_riscv::jumpto()
......@@ -1082,74 +1082,74 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_sparc6jumptoEv)
10821082//
10831083 .p2align 2
10841084DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_riscv6jumptoEv)
1085#if defined(__riscv_flen) && __riscv_flen == 64
1086 fld f0, (8 * 32 + 8 * 0)(a0)
1087 fld f1, (8 * 32 + 8 * 1)(a0)
1088 fld f2, (8 * 32 + 8 * 2)(a0)
1089 fld f3, (8 * 32 + 8 * 3)(a0)
1090 fld f4, (8 * 32 + 8 * 4)(a0)
1091 fld f5, (8 * 32 + 8 * 5)(a0)
1092 fld f6, (8 * 32 + 8 * 6)(a0)
1093 fld f7, (8 * 32 + 8 * 7)(a0)
1094 fld f8, (8 * 32 + 8 * 8)(a0)
1095 fld f9, (8 * 32 + 8 * 9)(a0)
1096 fld f10, (8 * 32 + 8 * 10)(a0)
1097 fld f11, (8 * 32 + 8 * 11)(a0)
1098 fld f12, (8 * 32 + 8 * 12)(a0)
1099 fld f13, (8 * 32 + 8 * 13)(a0)
1100 fld f14, (8 * 32 + 8 * 14)(a0)
1101 fld f15, (8 * 32 + 8 * 15)(a0)
1102 fld f16, (8 * 32 + 8 * 16)(a0)
1103 fld f17, (8 * 32 + 8 * 17)(a0)
1104 fld f18, (8 * 32 + 8 * 18)(a0)
1105 fld f19, (8 * 32 + 8 * 19)(a0)
1106 fld f20, (8 * 32 + 8 * 20)(a0)
1107 fld f21, (8 * 32 + 8 * 21)(a0)
1108 fld f22, (8 * 32 + 8 * 22)(a0)
1109 fld f23, (8 * 32 + 8 * 23)(a0)
1110 fld f24, (8 * 32 + 8 * 24)(a0)
1111 fld f25, (8 * 32 + 8 * 25)(a0)
1112 fld f26, (8 * 32 + 8 * 26)(a0)
1113 fld f27, (8 * 32 + 8 * 27)(a0)
1114 fld f28, (8 * 32 + 8 * 28)(a0)
1115 fld f29, (8 * 32 + 8 * 29)(a0)
1116 fld f30, (8 * 32 + 8 * 30)(a0)
1117 fld f31, (8 * 32 + 8 * 31)(a0)
1118#endif
1085# if defined(__riscv_flen)
1086 FLOAD f0, (RISCV_FOFFSET + RISCV_FSIZE * 0)(a0)
1087 FLOAD f1, (RISCV_FOFFSET + RISCV_FSIZE * 1)(a0)
1088 FLOAD f2, (RISCV_FOFFSET + RISCV_FSIZE * 2)(a0)
1089 FLOAD f3, (RISCV_FOFFSET + RISCV_FSIZE * 3)(a0)
1090 FLOAD f4, (RISCV_FOFFSET + RISCV_FSIZE * 4)(a0)
1091 FLOAD f5, (RISCV_FOFFSET + RISCV_FSIZE * 5)(a0)
1092 FLOAD f6, (RISCV_FOFFSET + RISCV_FSIZE * 6)(a0)
1093 FLOAD f7, (RISCV_FOFFSET + RISCV_FSIZE * 7)(a0)
1094 FLOAD f8, (RISCV_FOFFSET + RISCV_FSIZE * 8)(a0)
1095 FLOAD f9, (RISCV_FOFFSET + RISCV_FSIZE * 9)(a0)
1096 FLOAD f10, (RISCV_FOFFSET + RISCV_FSIZE * 10)(a0)
1097 FLOAD f11, (RISCV_FOFFSET + RISCV_FSIZE * 11)(a0)
1098 FLOAD f12, (RISCV_FOFFSET + RISCV_FSIZE * 12)(a0)
1099 FLOAD f13, (RISCV_FOFFSET + RISCV_FSIZE * 13)(a0)
1100 FLOAD f14, (RISCV_FOFFSET + RISCV_FSIZE * 14)(a0)
1101 FLOAD f15, (RISCV_FOFFSET + RISCV_FSIZE * 15)(a0)
1102 FLOAD f16, (RISCV_FOFFSET + RISCV_FSIZE * 16)(a0)
1103 FLOAD f17, (RISCV_FOFFSET + RISCV_FSIZE * 17)(a0)
1104 FLOAD f18, (RISCV_FOFFSET + RISCV_FSIZE * 18)(a0)
1105 FLOAD f19, (RISCV_FOFFSET + RISCV_FSIZE * 19)(a0)
1106 FLOAD f20, (RISCV_FOFFSET + RISCV_FSIZE * 20)(a0)
1107 FLOAD f21, (RISCV_FOFFSET + RISCV_FSIZE * 21)(a0)
1108 FLOAD f22, (RISCV_FOFFSET + RISCV_FSIZE * 22)(a0)
1109 FLOAD f23, (RISCV_FOFFSET + RISCV_FSIZE * 23)(a0)
1110 FLOAD f24, (RISCV_FOFFSET + RISCV_FSIZE * 24)(a0)
1111 FLOAD f25, (RISCV_FOFFSET + RISCV_FSIZE * 25)(a0)
1112 FLOAD f26, (RISCV_FOFFSET + RISCV_FSIZE * 26)(a0)
1113 FLOAD f27, (RISCV_FOFFSET + RISCV_FSIZE * 27)(a0)
1114 FLOAD f28, (RISCV_FOFFSET + RISCV_FSIZE * 28)(a0)
1115 FLOAD f29, (RISCV_FOFFSET + RISCV_FSIZE * 29)(a0)
1116 FLOAD f30, (RISCV_FOFFSET + RISCV_FSIZE * 30)(a0)
1117 FLOAD f31, (RISCV_FOFFSET + RISCV_FSIZE * 31)(a0)
1118# endif
11191119
11201120 // x0 is zero
1121 ld x1, (8 * 0)(a0) // restore pc into ra
1122 ld x2, (8 * 2)(a0)
1123 ld x3, (8 * 3)(a0)
1124 ld x4, (8 * 4)(a0)
1125 ld x5, (8 * 5)(a0)
1126 ld x6, (8 * 6)(a0)
1127 ld x7, (8 * 7)(a0)
1128 ld x8, (8 * 8)(a0)
1129 ld x9, (8 * 9)(a0)
1121 ILOAD x1, (RISCV_ISIZE * 0)(a0) // restore pc into ra
1122 ILOAD x2, (RISCV_ISIZE * 2)(a0)
1123 ILOAD x3, (RISCV_ISIZE * 3)(a0)
1124 ILOAD x4, (RISCV_ISIZE * 4)(a0)
1125 ILOAD x5, (RISCV_ISIZE * 5)(a0)
1126 ILOAD x6, (RISCV_ISIZE * 6)(a0)
1127 ILOAD x7, (RISCV_ISIZE * 7)(a0)
1128 ILOAD x8, (RISCV_ISIZE * 8)(a0)
1129 ILOAD x9, (RISCV_ISIZE * 9)(a0)
11301130 // skip a0 for now
1131 ld x11, (8 * 11)(a0)
1132 ld x12, (8 * 12)(a0)
1133 ld x13, (8 * 13)(a0)
1134 ld x14, (8 * 14)(a0)
1135 ld x15, (8 * 15)(a0)
1136 ld x16, (8 * 16)(a0)
1137 ld x17, (8 * 17)(a0)
1138 ld x18, (8 * 18)(a0)
1139 ld x19, (8 * 19)(a0)
1140 ld x20, (8 * 20)(a0)
1141 ld x21, (8 * 21)(a0)
1142 ld x22, (8 * 22)(a0)
1143 ld x23, (8 * 23)(a0)
1144 ld x24, (8 * 24)(a0)
1145 ld x25, (8 * 25)(a0)
1146 ld x26, (8 * 26)(a0)
1147 ld x27, (8 * 27)(a0)
1148 ld x28, (8 * 28)(a0)
1149 ld x29, (8 * 29)(a0)
1150 ld x30, (8 * 30)(a0)
1151 ld x31, (8 * 31)(a0)
1152 ld x10, (8 * 10)(a0) // restore a0
1131 ILOAD x11, (RISCV_ISIZE * 11)(a0)
1132 ILOAD x12, (RISCV_ISIZE * 12)(a0)
1133 ILOAD x13, (RISCV_ISIZE * 13)(a0)
1134 ILOAD x14, (RISCV_ISIZE * 14)(a0)
1135 ILOAD x15, (RISCV_ISIZE * 15)(a0)
1136 ILOAD x16, (RISCV_ISIZE * 16)(a0)
1137 ILOAD x17, (RISCV_ISIZE * 17)(a0)
1138 ILOAD x18, (RISCV_ISIZE * 18)(a0)
1139 ILOAD x19, (RISCV_ISIZE * 19)(a0)
1140 ILOAD x20, (RISCV_ISIZE * 20)(a0)
1141 ILOAD x21, (RISCV_ISIZE * 21)(a0)
1142 ILOAD x22, (RISCV_ISIZE * 22)(a0)
1143 ILOAD x23, (RISCV_ISIZE * 23)(a0)
1144 ILOAD x24, (RISCV_ISIZE * 24)(a0)
1145 ILOAD x25, (RISCV_ISIZE * 25)(a0)
1146 ILOAD x26, (RISCV_ISIZE * 26)(a0)
1147 ILOAD x27, (RISCV_ISIZE * 27)(a0)
1148 ILOAD x28, (RISCV_ISIZE * 28)(a0)
1149 ILOAD x29, (RISCV_ISIZE * 29)(a0)
1150 ILOAD x30, (RISCV_ISIZE * 30)(a0)
1151 ILOAD x31, (RISCV_ISIZE * 31)(a0)
1152 ILOAD x10, (RISCV_ISIZE * 10)(a0) // restore a0
11531153
11541154 ret // jump to ra
11551155
lib/libunwind/src/UnwindRegistersSave.S+210-210
......@@ -335,12 +335,12 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
335335
336336// store register (GPR)
337337#define PPC64_STR(n) \
338 std %r##n, (8 * (n + 2))(%r3)
338 std n, (8 * (n + 2))(3)
339339
340340 // save GPRs
341341 PPC64_STR(0)
342 mflr %r0
343 std %r0, PPC64_OFFS_SRR0(%r3) // store lr as ssr0
342 mflr 0
343 std 0, PPC64_OFFS_SRR0(3) // store lr as ssr0
344344 PPC64_STR(1)
345345 PPC64_STR(2)
346346 PPC64_STR(3)
......@@ -373,28 +373,28 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
373373 PPC64_STR(30)
374374 PPC64_STR(31)
375375
376 mfcr %r0
377 std %r0, PPC64_OFFS_CR(%r3)
378 mfxer %r0
379 std %r0, PPC64_OFFS_XER(%r3)
380 mflr %r0
381 std %r0, PPC64_OFFS_LR(%r3)
382 mfctr %r0
383 std %r0, PPC64_OFFS_CTR(%r3)
384 mfvrsave %r0
385 std %r0, PPC64_OFFS_VRSAVE(%r3)
376 mfcr 0
377 std 0, PPC64_OFFS_CR(3)
378 mfxer 0
379 std 0, PPC64_OFFS_XER(3)
380 mflr 0
381 std 0, PPC64_OFFS_LR(3)
382 mfctr 0
383 std 0, PPC64_OFFS_CTR(3)
384 mfvrsave 0
385 std 0, PPC64_OFFS_VRSAVE(3)
386386
387387#if defined(__VSX__)
388388 // save VS registers
389389 // (note that this also saves floating point registers and V registers,
390390 // because part of VS is mapped to these registers)
391391
392 addi %r4, %r3, PPC64_OFFS_FP
392 addi 4, 3, PPC64_OFFS_FP
393393
394394// store VS register
395395#define PPC64_STVS(n) \
396 stxvd2x %vs##n, 0, %r4 ;\
397 addi %r4, %r4, 16
396 stxvd2x n, 0, 4 ;\
397 addi 4, 4, 16
398398
399399 PPC64_STVS(0)
400400 PPC64_STVS(1)
......@@ -465,7 +465,7 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
465465
466466// store FP register
467467#define PPC64_STF(n) \
468 stfd %f##n, (PPC64_OFFS_FP + n * 16)(%r3)
468 stfd n, (PPC64_OFFS_FP + n * 16)(3)
469469
470470 // save float registers
471471 PPC64_STF(0)
......@@ -507,14 +507,14 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
507507 // Use 16-bytes below the stack pointer as an
508508 // aligned buffer to save each vector register.
509509 // Note that the stack pointer is always 16-byte aligned.
510 subi %r4, %r1, 16
510 subi 4, 1, 16
511511
512#define PPC64_STV_UNALIGNED(n) \
513 stvx %v##n, 0, %r4 ;\
514 ld %r5, 0(%r4) ;\
515 std %r5, (PPC64_OFFS_V + n * 16)(%r3) ;\
516 ld %r5, 8(%r4) ;\
517 std %r5, (PPC64_OFFS_V + n * 16 + 8)(%r3)
512#define PPC64_STV_UNALIGNED(n) \
513 stvx n, 0, 4 ;\
514 ld 5, 0(4) ;\
515 std 5, (PPC64_OFFS_V + n * 16)(3) ;\
516 ld 5, 8(4) ;\
517 std 5, (PPC64_OFFS_V + n * 16 + 8)(3)
518518
519519 PPC64_STV_UNALIGNED(0)
520520 PPC64_STV_UNALIGNED(1)
......@@ -552,7 +552,7 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
552552#endif
553553#endif
554554
555 li %r3, 0 // return UNW_ESUCCESS
555 li 3, 0 // return UNW_ESUCCESS
556556 blr
557557
558558
......@@ -565,140 +565,140 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
565565// thread_state pointer is in r3
566566//
567567DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
568 stw %r0, 8(%r3)
569 mflr %r0
570 stw %r0, 0(%r3) // store lr as ssr0
571 stw %r1, 12(%r3)
572 stw %r2, 16(%r3)
573 stw %r3, 20(%r3)
574 stw %r4, 24(%r3)
575 stw %r5, 28(%r3)
576 stw %r6, 32(%r3)
577 stw %r7, 36(%r3)
578 stw %r8, 40(%r3)
579 stw %r9, 44(%r3)
580 stw %r10, 48(%r3)
581 stw %r11, 52(%r3)
582 stw %r12, 56(%r3)
583 stw %r13, 60(%r3)
584 stw %r14, 64(%r3)
585 stw %r15, 68(%r3)
586 stw %r16, 72(%r3)
587 stw %r17, 76(%r3)
588 stw %r18, 80(%r3)
589 stw %r19, 84(%r3)
590 stw %r20, 88(%r3)
591 stw %r21, 92(%r3)
592 stw %r22, 96(%r3)
593 stw %r23,100(%r3)
594 stw %r24,104(%r3)
595 stw %r25,108(%r3)
596 stw %r26,112(%r3)
597 stw %r27,116(%r3)
598 stw %r28,120(%r3)
599 stw %r29,124(%r3)
600 stw %r30,128(%r3)
601 stw %r31,132(%r3)
568 stw 0, 8(3)
569 mflr 0
570 stw 0, 0(3) // store lr as ssr0
571 stw 1, 12(3)
572 stw 2, 16(3)
573 stw 3, 20(3)
574 stw 4, 24(3)
575 stw 5, 28(3)
576 stw 6, 32(3)
577 stw 7, 36(3)
578 stw 8, 40(3)
579 stw 9, 44(3)
580 stw 10, 48(3)
581 stw 11, 52(3)
582 stw 12, 56(3)
583 stw 13, 60(3)
584 stw 14, 64(3)
585 stw 15, 68(3)
586 stw 16, 72(3)
587 stw 17, 76(3)
588 stw 18, 80(3)
589 stw 19, 84(3)
590 stw 20, 88(3)
591 stw 21, 92(3)
592 stw 22, 96(3)
593 stw 23,100(3)
594 stw 24,104(3)
595 stw 25,108(3)
596 stw 26,112(3)
597 stw 27,116(3)
598 stw 28,120(3)
599 stw 29,124(3)
600 stw 30,128(3)
601 stw 31,132(3)
602602
603603 // save VRSave register
604 mfspr %r0, 256
605 stw %r0, 156(%r3)
604 mfspr 0, 256
605 stw 0, 156(3)
606606 // save CR registers
607 mfcr %r0
608 stw %r0, 136(%r3)
607 mfcr 0
608 stw 0, 136(3)
609609 // save CTR register
610 mfctr %r0
611 stw %r0, 148(%r3)
610 mfctr 0
611 stw 0, 148(3)
612612
613613#if !defined(__NO_FPRS__)
614614 // save float registers
615 stfd %f0, 160(%r3)
616 stfd %f1, 168(%r3)
617 stfd %f2, 176(%r3)
618 stfd %f3, 184(%r3)
619 stfd %f4, 192(%r3)
620 stfd %f5, 200(%r3)
621 stfd %f6, 208(%r3)
622 stfd %f7, 216(%r3)
623 stfd %f8, 224(%r3)
624 stfd %f9, 232(%r3)
625 stfd %f10,240(%r3)
626 stfd %f11,248(%r3)
627 stfd %f12,256(%r3)
628 stfd %f13,264(%r3)
629 stfd %f14,272(%r3)
630 stfd %f15,280(%r3)
631 stfd %f16,288(%r3)
632 stfd %f17,296(%r3)
633 stfd %f18,304(%r3)
634 stfd %f19,312(%r3)
635 stfd %f20,320(%r3)
636 stfd %f21,328(%r3)
637 stfd %f22,336(%r3)
638 stfd %f23,344(%r3)
639 stfd %f24,352(%r3)
640 stfd %f25,360(%r3)
641 stfd %f26,368(%r3)
642 stfd %f27,376(%r3)
643 stfd %f28,384(%r3)
644 stfd %f29,392(%r3)
645 stfd %f30,400(%r3)
646 stfd %f31,408(%r3)
615 stfd 0, 160(3)
616 stfd 1, 168(3)
617 stfd 2, 176(3)
618 stfd 3, 184(3)
619 stfd 4, 192(3)
620 stfd 5, 200(3)
621 stfd 6, 208(3)
622 stfd 7, 216(3)
623 stfd 8, 224(3)
624 stfd 9, 232(3)
625 stfd 10,240(3)
626 stfd 11,248(3)
627 stfd 12,256(3)
628 stfd 13,264(3)
629 stfd 14,272(3)
630 stfd 15,280(3)
631 stfd 16,288(3)
632 stfd 17,296(3)
633 stfd 18,304(3)
634 stfd 19,312(3)
635 stfd 20,320(3)
636 stfd 21,328(3)
637 stfd 22,336(3)
638 stfd 23,344(3)
639 stfd 24,352(3)
640 stfd 25,360(3)
641 stfd 26,368(3)
642 stfd 27,376(3)
643 stfd 28,384(3)
644 stfd 29,392(3)
645 stfd 30,400(3)
646 stfd 31,408(3)
647647#endif
648648
649649#if defined(__ALTIVEC__)
650650 // save vector registers
651651
652 subi %r4, %r1, 16
653 rlwinm %r4, %r4, 0, 0, 27 // mask low 4-bits
652 subi 4, 1, 16
653 rlwinm 4, 4, 0, 0, 27 // mask low 4-bits
654654 // r4 is now a 16-byte aligned pointer into the red zone
655655
656656#define SAVE_VECTOR_UNALIGNED(_vec, _offset) \
657 stvx _vec, 0, %r4 SEPARATOR \
658 lwz %r5, 0(%r4) SEPARATOR \
659 stw %r5, _offset(%r3) SEPARATOR \
660 lwz %r5, 4(%r4) SEPARATOR \
661 stw %r5, _offset+4(%r3) SEPARATOR \
662 lwz %r5, 8(%r4) SEPARATOR \
663 stw %r5, _offset+8(%r3) SEPARATOR \
664 lwz %r5, 12(%r4) SEPARATOR \
665 stw %r5, _offset+12(%r3)
666
667 SAVE_VECTOR_UNALIGNED( %v0, 424+0x000)
668 SAVE_VECTOR_UNALIGNED( %v1, 424+0x010)
669 SAVE_VECTOR_UNALIGNED( %v2, 424+0x020)
670 SAVE_VECTOR_UNALIGNED( %v3, 424+0x030)
671 SAVE_VECTOR_UNALIGNED( %v4, 424+0x040)
672 SAVE_VECTOR_UNALIGNED( %v5, 424+0x050)
673 SAVE_VECTOR_UNALIGNED( %v6, 424+0x060)
674 SAVE_VECTOR_UNALIGNED( %v7, 424+0x070)
675 SAVE_VECTOR_UNALIGNED( %v8, 424+0x080)
676 SAVE_VECTOR_UNALIGNED( %v9, 424+0x090)
677 SAVE_VECTOR_UNALIGNED(%v10, 424+0x0A0)
678 SAVE_VECTOR_UNALIGNED(%v11, 424+0x0B0)
679 SAVE_VECTOR_UNALIGNED(%v12, 424+0x0C0)
680 SAVE_VECTOR_UNALIGNED(%v13, 424+0x0D0)
681 SAVE_VECTOR_UNALIGNED(%v14, 424+0x0E0)
682 SAVE_VECTOR_UNALIGNED(%v15, 424+0x0F0)
683 SAVE_VECTOR_UNALIGNED(%v16, 424+0x100)
684 SAVE_VECTOR_UNALIGNED(%v17, 424+0x110)
685 SAVE_VECTOR_UNALIGNED(%v18, 424+0x120)
686 SAVE_VECTOR_UNALIGNED(%v19, 424+0x130)
687 SAVE_VECTOR_UNALIGNED(%v20, 424+0x140)
688 SAVE_VECTOR_UNALIGNED(%v21, 424+0x150)
689 SAVE_VECTOR_UNALIGNED(%v22, 424+0x160)
690 SAVE_VECTOR_UNALIGNED(%v23, 424+0x170)
691 SAVE_VECTOR_UNALIGNED(%v24, 424+0x180)
692 SAVE_VECTOR_UNALIGNED(%v25, 424+0x190)
693 SAVE_VECTOR_UNALIGNED(%v26, 424+0x1A0)
694 SAVE_VECTOR_UNALIGNED(%v27, 424+0x1B0)
695 SAVE_VECTOR_UNALIGNED(%v28, 424+0x1C0)
696 SAVE_VECTOR_UNALIGNED(%v29, 424+0x1D0)
697 SAVE_VECTOR_UNALIGNED(%v30, 424+0x1E0)
698 SAVE_VECTOR_UNALIGNED(%v31, 424+0x1F0)
657 stvx _vec, 0, 4 SEPARATOR \
658 lwz 5, 0(4) SEPARATOR \
659 stw 5, _offset(3) SEPARATOR \
660 lwz 5, 4(4) SEPARATOR \
661 stw 5, _offset+4(3) SEPARATOR \
662 lwz 5, 8(4) SEPARATOR \
663 stw 5, _offset+8(3) SEPARATOR \
664 lwz 5, 12(4) SEPARATOR \
665 stw 5, _offset+12(3)
666
667 SAVE_VECTOR_UNALIGNED( 0, 424+0x000)
668 SAVE_VECTOR_UNALIGNED( 1, 424+0x010)
669 SAVE_VECTOR_UNALIGNED( 2, 424+0x020)
670 SAVE_VECTOR_UNALIGNED( 3, 424+0x030)
671 SAVE_VECTOR_UNALIGNED( 4, 424+0x040)
672 SAVE_VECTOR_UNALIGNED( 5, 424+0x050)
673 SAVE_VECTOR_UNALIGNED( 6, 424+0x060)
674 SAVE_VECTOR_UNALIGNED( 7, 424+0x070)
675 SAVE_VECTOR_UNALIGNED( 8, 424+0x080)
676 SAVE_VECTOR_UNALIGNED( 9, 424+0x090)
677 SAVE_VECTOR_UNALIGNED(10, 424+0x0A0)
678 SAVE_VECTOR_UNALIGNED(11, 424+0x0B0)
679 SAVE_VECTOR_UNALIGNED(12, 424+0x0C0)
680 SAVE_VECTOR_UNALIGNED(13, 424+0x0D0)
681 SAVE_VECTOR_UNALIGNED(14, 424+0x0E0)
682 SAVE_VECTOR_UNALIGNED(15, 424+0x0F0)
683 SAVE_VECTOR_UNALIGNED(16, 424+0x100)
684 SAVE_VECTOR_UNALIGNED(17, 424+0x110)
685 SAVE_VECTOR_UNALIGNED(18, 424+0x120)
686 SAVE_VECTOR_UNALIGNED(19, 424+0x130)
687 SAVE_VECTOR_UNALIGNED(20, 424+0x140)
688 SAVE_VECTOR_UNALIGNED(21, 424+0x150)
689 SAVE_VECTOR_UNALIGNED(22, 424+0x160)
690 SAVE_VECTOR_UNALIGNED(23, 424+0x170)
691 SAVE_VECTOR_UNALIGNED(24, 424+0x180)
692 SAVE_VECTOR_UNALIGNED(25, 424+0x190)
693 SAVE_VECTOR_UNALIGNED(26, 424+0x1A0)
694 SAVE_VECTOR_UNALIGNED(27, 424+0x1B0)
695 SAVE_VECTOR_UNALIGNED(28, 424+0x1C0)
696 SAVE_VECTOR_UNALIGNED(29, 424+0x1D0)
697 SAVE_VECTOR_UNALIGNED(30, 424+0x1E0)
698 SAVE_VECTOR_UNALIGNED(31, 424+0x1F0)
699699#endif
700700
701 li %r3, 0 // return UNW_ESUCCESS
701 li 3, 0 // return UNW_ESUCCESS
702702 blr
703703
704704
......@@ -1026,7 +1026,7 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
10261026 jmp %o7
10271027 clr %o0 // return UNW_ESUCCESS
10281028
1029#elif defined(__riscv) && __riscv_xlen == 64
1029#elif defined(__riscv)
10301030
10311031#
10321032# extern int __unw_getcontext(unw_context_t* thread_state)
......@@ -1035,73 +1035,73 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
10351035# thread_state pointer is in a0
10361036#
10371037DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
1038 sd x1, (8 * 0)(a0) // store ra as pc
1039 sd x1, (8 * 1)(a0)
1040 sd x2, (8 * 2)(a0)
1041 sd x3, (8 * 3)(a0)
1042 sd x4, (8 * 4)(a0)
1043 sd x5, (8 * 5)(a0)
1044 sd x6, (8 * 6)(a0)
1045 sd x7, (8 * 7)(a0)
1046 sd x8, (8 * 8)(a0)
1047 sd x9, (8 * 9)(a0)
1048 sd x10, (8 * 10)(a0)
1049 sd x11, (8 * 11)(a0)
1050 sd x12, (8 * 12)(a0)
1051 sd x13, (8 * 13)(a0)
1052 sd x14, (8 * 14)(a0)
1053 sd x15, (8 * 15)(a0)
1054 sd x16, (8 * 16)(a0)
1055 sd x17, (8 * 17)(a0)
1056 sd x18, (8 * 18)(a0)
1057 sd x19, (8 * 19)(a0)
1058 sd x20, (8 * 20)(a0)
1059 sd x21, (8 * 21)(a0)
1060 sd x22, (8 * 22)(a0)
1061 sd x23, (8 * 23)(a0)
1062 sd x24, (8 * 24)(a0)
1063 sd x25, (8 * 25)(a0)
1064 sd x26, (8 * 26)(a0)
1065 sd x27, (8 * 27)(a0)
1066 sd x28, (8 * 28)(a0)
1067 sd x29, (8 * 29)(a0)
1068 sd x30, (8 * 30)(a0)
1069 sd x31, (8 * 31)(a0)
1070
1071#if defined(__riscv_flen) && __riscv_flen == 64
1072 fsd f0, (8 * 32 + 8 * 0)(a0)
1073 fsd f1, (8 * 32 + 8 * 1)(a0)
1074 fsd f2, (8 * 32 + 8 * 2)(a0)
1075 fsd f3, (8 * 32 + 8 * 3)(a0)
1076 fsd f4, (8 * 32 + 8 * 4)(a0)
1077 fsd f5, (8 * 32 + 8 * 5)(a0)
1078 fsd f6, (8 * 32 + 8 * 6)(a0)
1079 fsd f7, (8 * 32 + 8 * 7)(a0)
1080 fsd f8, (8 * 32 + 8 * 8)(a0)
1081 fsd f9, (8 * 32 + 8 * 9)(a0)
1082 fsd f10, (8 * 32 + 8 * 10)(a0)
1083 fsd f11, (8 * 32 + 8 * 11)(a0)
1084 fsd f12, (8 * 32 + 8 * 12)(a0)
1085 fsd f13, (8 * 32 + 8 * 13)(a0)
1086 fsd f14, (8 * 32 + 8 * 14)(a0)
1087 fsd f15, (8 * 32 + 8 * 15)(a0)
1088 fsd f16, (8 * 32 + 8 * 16)(a0)
1089 fsd f17, (8 * 32 + 8 * 17)(a0)
1090 fsd f18, (8 * 32 + 8 * 18)(a0)
1091 fsd f19, (8 * 32 + 8 * 19)(a0)
1092 fsd f20, (8 * 32 + 8 * 20)(a0)
1093 fsd f21, (8 * 32 + 8 * 21)(a0)
1094 fsd f22, (8 * 32 + 8 * 22)(a0)
1095 fsd f23, (8 * 32 + 8 * 23)(a0)
1096 fsd f24, (8 * 32 + 8 * 24)(a0)
1097 fsd f25, (8 * 32 + 8 * 25)(a0)
1098 fsd f26, (8 * 32 + 8 * 26)(a0)
1099 fsd f27, (8 * 32 + 8 * 27)(a0)
1100 fsd f28, (8 * 32 + 8 * 28)(a0)
1101 fsd f29, (8 * 32 + 8 * 29)(a0)
1102 fsd f30, (8 * 32 + 8 * 30)(a0)
1103 fsd f31, (8 * 32 + 8 * 31)(a0)
1104#endif
1038 ISTORE x1, (RISCV_ISIZE * 0)(a0) // store ra as pc
1039 ISTORE x1, (RISCV_ISIZE * 1)(a0)
1040 ISTORE x2, (RISCV_ISIZE * 2)(a0)
1041 ISTORE x3, (RISCV_ISIZE * 3)(a0)
1042 ISTORE x4, (RISCV_ISIZE * 4)(a0)
1043 ISTORE x5, (RISCV_ISIZE * 5)(a0)
1044 ISTORE x6, (RISCV_ISIZE * 6)(a0)
1045 ISTORE x7, (RISCV_ISIZE * 7)(a0)
1046 ISTORE x8, (RISCV_ISIZE * 8)(a0)
1047 ISTORE x9, (RISCV_ISIZE * 9)(a0)
1048 ISTORE x10, (RISCV_ISIZE * 10)(a0)
1049 ISTORE x11, (RISCV_ISIZE * 11)(a0)
1050 ISTORE x12, (RISCV_ISIZE * 12)(a0)
1051 ISTORE x13, (RISCV_ISIZE * 13)(a0)
1052 ISTORE x14, (RISCV_ISIZE * 14)(a0)
1053 ISTORE x15, (RISCV_ISIZE * 15)(a0)
1054 ISTORE x16, (RISCV_ISIZE * 16)(a0)
1055 ISTORE x17, (RISCV_ISIZE * 17)(a0)
1056 ISTORE x18, (RISCV_ISIZE * 18)(a0)
1057 ISTORE x19, (RISCV_ISIZE * 19)(a0)
1058 ISTORE x20, (RISCV_ISIZE * 20)(a0)
1059 ISTORE x21, (RISCV_ISIZE * 21)(a0)
1060 ISTORE x22, (RISCV_ISIZE * 22)(a0)
1061 ISTORE x23, (RISCV_ISIZE * 23)(a0)
1062 ISTORE x24, (RISCV_ISIZE * 24)(a0)
1063 ISTORE x25, (RISCV_ISIZE * 25)(a0)
1064 ISTORE x26, (RISCV_ISIZE * 26)(a0)
1065 ISTORE x27, (RISCV_ISIZE * 27)(a0)
1066 ISTORE x28, (RISCV_ISIZE * 28)(a0)
1067 ISTORE x29, (RISCV_ISIZE * 29)(a0)
1068 ISTORE x30, (RISCV_ISIZE * 30)(a0)
1069 ISTORE x31, (RISCV_ISIZE * 31)(a0)
1070
1071# if defined(__riscv_flen)
1072 FSTORE f0, (RISCV_FOFFSET + RISCV_FSIZE * 0)(a0)
1073 FSTORE f1, (RISCV_FOFFSET + RISCV_FSIZE * 1)(a0)
1074 FSTORE f2, (RISCV_FOFFSET + RISCV_FSIZE * 2)(a0)
1075 FSTORE f3, (RISCV_FOFFSET + RISCV_FSIZE * 3)(a0)
1076 FSTORE f4, (RISCV_FOFFSET + RISCV_FSIZE * 4)(a0)
1077 FSTORE f5, (RISCV_FOFFSET + RISCV_FSIZE * 5)(a0)
1078 FSTORE f6, (RISCV_FOFFSET + RISCV_FSIZE * 6)(a0)
1079 FSTORE f7, (RISCV_FOFFSET + RISCV_FSIZE * 7)(a0)
1080 FSTORE f8, (RISCV_FOFFSET + RISCV_FSIZE * 8)(a0)
1081 FSTORE f9, (RISCV_FOFFSET + RISCV_FSIZE * 9)(a0)
1082 FSTORE f10, (RISCV_FOFFSET + RISCV_FSIZE * 10)(a0)
1083 FSTORE f11, (RISCV_FOFFSET + RISCV_FSIZE * 11)(a0)
1084 FSTORE f12, (RISCV_FOFFSET + RISCV_FSIZE * 12)(a0)
1085 FSTORE f13, (RISCV_FOFFSET + RISCV_FSIZE * 13)(a0)
1086 FSTORE f14, (RISCV_FOFFSET + RISCV_FSIZE * 14)(a0)
1087 FSTORE f15, (RISCV_FOFFSET + RISCV_FSIZE * 15)(a0)
1088 FSTORE f16, (RISCV_FOFFSET + RISCV_FSIZE * 16)(a0)
1089 FSTORE f17, (RISCV_FOFFSET + RISCV_FSIZE * 17)(a0)
1090 FSTORE f18, (RISCV_FOFFSET + RISCV_FSIZE * 18)(a0)
1091 FSTORE f19, (RISCV_FOFFSET + RISCV_FSIZE * 19)(a0)
1092 FSTORE f20, (RISCV_FOFFSET + RISCV_FSIZE * 20)(a0)
1093 FSTORE f21, (RISCV_FOFFSET + RISCV_FSIZE * 21)(a0)
1094 FSTORE f22, (RISCV_FOFFSET + RISCV_FSIZE * 22)(a0)
1095 FSTORE f23, (RISCV_FOFFSET + RISCV_FSIZE * 23)(a0)
1096 FSTORE f24, (RISCV_FOFFSET + RISCV_FSIZE * 24)(a0)
1097 FSTORE f25, (RISCV_FOFFSET + RISCV_FSIZE * 25)(a0)
1098 FSTORE f26, (RISCV_FOFFSET + RISCV_FSIZE * 26)(a0)
1099 FSTORE f27, (RISCV_FOFFSET + RISCV_FSIZE * 27)(a0)
1100 FSTORE f28, (RISCV_FOFFSET + RISCV_FSIZE * 28)(a0)
1101 FSTORE f29, (RISCV_FOFFSET + RISCV_FSIZE * 29)(a0)
1102 FSTORE f30, (RISCV_FOFFSET + RISCV_FSIZE * 30)(a0)
1103 FSTORE f31, (RISCV_FOFFSET + RISCV_FSIZE * 31)(a0)
1104# endif
11051105
11061106 li a0, 0 // return UNW_ESUCCESS
11071107 ret // jump to ra
lib/libunwind/src/assembly.h+50-8
......@@ -27,6 +27,35 @@
2727#define PPC64_OFFS_V 824
2828#elif defined(__APPLE__) && defined(__aarch64__)
2929#define SEPARATOR %%
30#elif defined(__riscv)
31# define RISCV_ISIZE (__riscv_xlen / 8)
32# define RISCV_FOFFSET (RISCV_ISIZE * 32)
33# if defined(__riscv_flen)
34# define RISCV_FSIZE (__riscv_flen / 8)
35# endif
36
37# if __riscv_xlen == 64
38# define ILOAD ld
39# define ISTORE sd
40# elif __riscv_xlen == 32
41# define ILOAD lw
42# define ISTORE sw
43# else
44# error "Unsupported __riscv_xlen"
45# endif
46
47# if defined(__riscv_flen)
48# if __riscv_flen == 64
49# define FLOAD fld
50# define FSTORE fsd
51# elif __riscv_flen == 32
52# define FLOAD flw
53# define FSTORE fsw
54# else
55# error "Unsupported __riscv_flen"
56# endif
57# endif
58# define SEPARATOR ;
3059#else
3160#define SEPARATOR ;
3261#endif
......@@ -70,12 +99,15 @@
7099#if defined(__APPLE__)
71100
72101#define SYMBOL_IS_FUNC(name)
73#define EXPORT_SYMBOL(name)
74102#define HIDDEN_SYMBOL(name) .private_extern name
75#define WEAK_SYMBOL(name) .weak_reference name
103#if defined(_LIBUNWIND_HIDE_SYMBOLS)
104#define EXPORT_SYMBOL(name) HIDDEN_SYMBOL(name)
105#else
106#define EXPORT_SYMBOL(name)
107#endif
76108#define WEAK_ALIAS(name, aliasname) \
77109 .globl SYMBOL_NAME(aliasname) SEPARATOR \
78 WEAK_SYMBOL(aliasname) SEPARATOR \
110 EXPORT_SYMBOL(SYMBOL_NAME(aliasname)) SEPARATOR \
79111 SYMBOL_NAME(aliasname) = SYMBOL_NAME(name)
80112
81113#define NO_EXEC_STACK_DIRECTIVE
......@@ -87,17 +119,23 @@
87119#else
88120#define SYMBOL_IS_FUNC(name) .type name,@function
89121#endif
90#define EXPORT_SYMBOL(name)
91122#define HIDDEN_SYMBOL(name) .hidden name
123#if defined(_LIBUNWIND_HIDE_SYMBOLS)
124#define EXPORT_SYMBOL(name) HIDDEN_SYMBOL(name)
125#else
126#define EXPORT_SYMBOL(name)
127#endif
92128#define WEAK_SYMBOL(name) .weak name
93129
94130#if defined(__hexagon__)
95#define WEAK_ALIAS(name, aliasname) \
96 WEAK_SYMBOL(aliasname) SEPARATOR \
131#define WEAK_ALIAS(name, aliasname) \
132 EXPORT_SYMBOL(SYMBOL_NAME(aliasname)) SEPARATOR \
133 WEAK_SYMBOL(SYMBOL_NAME(aliasname)) SEPARATOR \
97134 .equiv SYMBOL_NAME(aliasname), SYMBOL_NAME(name)
98135#else
99136#define WEAK_ALIAS(name, aliasname) \
100 WEAK_SYMBOL(aliasname) SEPARATOR \
137 EXPORT_SYMBOL(SYMBOL_NAME(aliasname)) SEPARATOR \
138 WEAK_SYMBOL(SYMBOL_NAME(aliasname)) SEPARATOR \
101139 SYMBOL_NAME(aliasname) = SYMBOL_NAME(name)
102140#endif
103141
......@@ -119,7 +157,7 @@
119157 .section .drectve,"yn" SEPARATOR \
120158 .ascii "-export:", #name, "\0" SEPARATOR \
121159 .text
122#if defined(_LIBUNWIND_DISABLE_VISIBILITY_ANNOTATIONS)
160#if defined(_LIBUNWIND_HIDE_SYMBOLS)
123161#define EXPORT_SYMBOL(name)
124162#else
125163#define EXPORT_SYMBOL(name) EXPORT_SYMBOL2(name)
......@@ -178,4 +216,8 @@
178216#endif
179217#endif /* __arm__ */
180218
219#if defined(__ppc__) || defined(__powerpc64__)
220#define PPC_LEFT_SHIFT(index) << (index)
221#endif
222
181223#endif /* UNWIND_ASSEMBLY_H */
lib/libunwind/src/config.h+8-3
......@@ -52,7 +52,8 @@
5252 #endif
5353#endif
5454
55#if defined(_LIBUNWIND_DISABLE_VISIBILITY_ANNOTATIONS)
55#if defined(_LIBUNWIND_HIDE_SYMBOLS)
56 // The CMake file passes -fvisibility=hidden to control ELF/Mach-O visibility.
5657 #define _LIBUNWIND_EXPORT
5758 #define _LIBUNWIND_HIDDEN
5859#else
......@@ -70,11 +71,15 @@
7071#define SYMBOL_NAME(name) XSTR(__USER_LABEL_PREFIX__) #name
7172
7273#if defined(__APPLE__)
74#if defined(_LIBUNWIND_HIDE_SYMBOLS)
75#define _LIBUNWIND_ALIAS_VISIBILITY(name) __asm__(".private_extern " name);
76#else
77#define _LIBUNWIND_ALIAS_VISIBILITY(name)
78#endif
7379#define _LIBUNWIND_WEAK_ALIAS(name, aliasname) \
7480 __asm__(".globl " SYMBOL_NAME(aliasname)); \
7581 __asm__(SYMBOL_NAME(aliasname) " = " SYMBOL_NAME(name)); \
76 extern "C" _LIBUNWIND_EXPORT __typeof(name) aliasname \
77 __attribute__((weak_import));
82 _LIBUNWIND_ALIAS_VISIBILITY(SYMBOL_NAME(aliasname))
7883#elif defined(__ELF__)
7984#define _LIBUNWIND_WEAK_ALIAS(name, aliasname) \
8085 extern "C" _LIBUNWIND_EXPORT __typeof(name) aliasname \
lib/libunwind/src/libunwind.cpp+14-1
......@@ -16,6 +16,15 @@
1616
1717#include <stdlib.h>
1818
19// Define the __has_feature extension for compilers that do not support it so
20// that we can later check for the presence of ASan in a compiler-neutral way.
21#if !defined(__has_feature)
22#define __has_feature(feature) 0
23#endif
24
25#if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
26#include <sanitizer/asan_interface.h>
27#endif
1928
2029#if !defined(__USING_SJLJ_EXCEPTIONS__)
2130#include "AddressSpace.hpp"
......@@ -60,7 +69,7 @@ _LIBUNWIND_HIDDEN int __unw_init_local(unw_cursor_t *cursor,
6069# warning The MIPS architecture is not supported with this ABI and environment!
6170#elif defined(__sparc__)
6271# define REGISTER_KIND Registers_sparc
63#elif defined(__riscv) && __riscv_xlen == 64
72#elif defined(__riscv)
6473# define REGISTER_KIND Registers_riscv
6574#elif defined(__ve__)
6675# define REGISTER_KIND Registers_ve
......@@ -184,6 +193,10 @@ _LIBUNWIND_WEAK_ALIAS(__unw_get_proc_info, unw_get_proc_info)
184193/// Resume execution at cursor position (aka longjump).
185194_LIBUNWIND_HIDDEN int __unw_resume(unw_cursor_t *cursor) {
186195 _LIBUNWIND_TRACE_API("__unw_resume(cursor=%p)", static_cast<void *>(cursor));
196#if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
197 // Inform the ASan runtime that now might be a good time to clean stuff up.
198 __asan_handle_no_return();
199#endif
187200 AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
188201 co->jumpto();
189202 return UNW_EUNSPEC;
lib/tsan/interception/interception.h+13-22
......@@ -16,10 +16,10 @@
1616
1717#include "sanitizer_common/sanitizer_internal_defs.h"
1818
19#if !SANITIZER_LINUX && !SANITIZER_FREEBSD && !SANITIZER_MAC && \
20 !SANITIZER_NETBSD && !SANITIZER_OPENBSD && !SANITIZER_WINDOWS && \
21 !SANITIZER_FUCHSIA && !SANITIZER_RTEMS && !SANITIZER_SOLARIS
22# error "Interception doesn't work on this operating system."
19#if !SANITIZER_LINUX && !SANITIZER_FREEBSD && !SANITIZER_MAC && \
20 !SANITIZER_NETBSD && !SANITIZER_WINDOWS && !SANITIZER_FUCHSIA && \
21 !SANITIZER_SOLARIS
22# error "Interception doesn't work on this operating system."
2323#endif
2424
2525// These typedefs should be used only in the interceptor definitions to replace
......@@ -130,11 +130,6 @@ const interpose_substitution substitution_##func_name[] \
130130 extern "C" ret_type func(__VA_ARGS__);
131131# define DECLARE_WRAPPER_WINAPI(ret_type, func, ...) \
132132 extern "C" __declspec(dllimport) ret_type __stdcall func(__VA_ARGS__);
133#elif SANITIZER_RTEMS
134# define WRAP(x) x
135# define WRAPPER_NAME(x) #x
136# define INTERCEPTOR_ATTRIBUTE
137# define DECLARE_WRAPPER(ret_type, func, ...)
138133#elif SANITIZER_FREEBSD || SANITIZER_NETBSD
139134# define WRAP(x) __interceptor_ ## x
140135# define WRAPPER_NAME(x) "__interceptor_" #x
......@@ -162,10 +157,6 @@ const interpose_substitution substitution_##func_name[] \
162157# define INTERCEPTOR_ATTRIBUTE __attribute__((visibility("default")))
163158# define REAL(x) __unsanitized_##x
164159# define DECLARE_REAL(ret_type, func, ...)
165#elif SANITIZER_RTEMS
166# define REAL(x) __real_ ## x
167# define DECLARE_REAL(ret_type, func, ...) \
168 extern "C" ret_type REAL(func)(__VA_ARGS__);
169160#elif !SANITIZER_MAC
170161# define PTR_TO_REAL(x) real_##x
171162# define REAL(x) __interception::PTR_TO_REAL(x)
......@@ -184,10 +175,10 @@ const interpose_substitution substitution_##func_name[] \
184175# define ASSIGN_REAL(x, y)
185176#endif // SANITIZER_MAC
186177
187#if !SANITIZER_FUCHSIA && !SANITIZER_RTEMS
188# define DECLARE_REAL_AND_INTERCEPTOR(ret_type, func, ...) \
189 DECLARE_REAL(ret_type, func, __VA_ARGS__) \
190 extern "C" ret_type WRAP(func)(__VA_ARGS__);
178#if !SANITIZER_FUCHSIA
179# define DECLARE_REAL_AND_INTERCEPTOR(ret_type, func, ...) \
180 DECLARE_REAL(ret_type, func, __VA_ARGS__) \
181 extern "C" ret_type WRAP(func)(__VA_ARGS__);
191182// Declare an interceptor and its wrapper defined in a different translation
192183// unit (ex. asm).
193184# define DECLARE_EXTERN_INTERCEPTOR_AND_WRAPPER(ret_type, func, ...) \
......@@ -202,11 +193,11 @@ const interpose_substitution substitution_##func_name[] \
202193// macros does its job. In exceptional cases you may need to call REAL(foo)
203194// without defining INTERCEPTOR(..., foo, ...). For example, if you override
204195// foo with an interceptor for other function.
205#if !SANITIZER_MAC && !SANITIZER_FUCHSIA && !SANITIZER_RTEMS
206# define DEFINE_REAL(ret_type, func, ...) \
196#if !SANITIZER_MAC && !SANITIZER_FUCHSIA
197# define DEFINE_REAL(ret_type, func, ...) \
207198 typedef ret_type (*FUNC_TYPE(func))(__VA_ARGS__); \
208 namespace __interception { \
209 FUNC_TYPE(func) PTR_TO_REAL(func); \
199 namespace __interception { \
200 FUNC_TYPE(func) PTR_TO_REAL(func); \
210201 }
211202#else
212203# define DEFINE_REAL(ret_type, func, ...)
......@@ -281,7 +272,7 @@ typedef unsigned long uptr;
281272#define INCLUDED_FROM_INTERCEPTION_LIB
282273
283274#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || \
284 SANITIZER_OPENBSD || SANITIZER_SOLARIS
275 SANITIZER_SOLARIS
285276
286277# include "interception_linux.h"
287278# define INTERCEPT_FUNCTION(func) INTERCEPT_FUNCTION_LINUX_OR_FREEBSD(func)
lib/tsan/interception/interception_linux.cpp+5-5
......@@ -14,7 +14,7 @@
1414#include "interception.h"
1515
1616#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || \
17 SANITIZER_OPENBSD || SANITIZER_SOLARIS
17 SANITIZER_SOLARIS
1818
1919#include <dlfcn.h> // for dlsym() and dlvsym()
2020
......@@ -63,8 +63,8 @@ bool InterceptFunction(const char *name, uptr *ptr_to_real, uptr func,
6363 return addr && (func == wrapper);
6464}
6565
66// Android and Solaris do not have dlvsym
67#if !SANITIZER_ANDROID && !SANITIZER_SOLARIS && !SANITIZER_OPENBSD
66// dlvsym is a GNU extension supported by some other platforms.
67#if SANITIZER_GLIBC || SANITIZER_FREEBSD || SANITIZER_NETBSD
6868static void *GetFuncAddr(const char *name, const char *ver) {
6969 return dlvsym(RTLD_NEXT, name, ver);
7070}
......@@ -75,9 +75,9 @@ bool InterceptFunction(const char *name, const char *ver, uptr *ptr_to_real,
7575 *ptr_to_real = (uptr)addr;
7676 return addr && (func == wrapper);
7777}
78#endif // !SANITIZER_ANDROID
78#endif // SANITIZER_GLIBC || SANITIZER_FREEBSD || SANITIZER_NETBSD
7979
8080} // namespace __interception
8181
8282#endif // SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD ||
83 // SANITIZER_OPENBSD || SANITIZER_SOLARIS
83 // SANITIZER_SOLARIS
lib/tsan/interception/interception_linux.h+5-5
......@@ -12,7 +12,7 @@
1212//===----------------------------------------------------------------------===//
1313
1414#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || \
15 SANITIZER_OPENBSD || SANITIZER_SOLARIS
15 SANITIZER_SOLARIS
1616
1717#if !defined(INCLUDED_FROM_INTERCEPTION_LIB)
1818# error "interception_linux.h should be included from interception library only"
......@@ -35,8 +35,8 @@ bool InterceptFunction(const char *name, const char *ver, uptr *ptr_to_real,
3535 (::__interception::uptr) & (func), \
3636 (::__interception::uptr) & WRAP(func))
3737
38// Android, Solaris and OpenBSD do not have dlvsym
39#if !SANITIZER_ANDROID && !SANITIZER_SOLARIS && !SANITIZER_OPENBSD
38// dlvsym is a GNU extension supported by some other platforms.
39#if SANITIZER_GLIBC || SANITIZER_FREEBSD || SANITIZER_NETBSD
4040#define INTERCEPT_FUNCTION_VER_LINUX_OR_FREEBSD(func, symver) \
4141 ::__interception::InterceptFunction( \
4242 #func, symver, \
......@@ -46,8 +46,8 @@ bool InterceptFunction(const char *name, const char *ver, uptr *ptr_to_real,
4646#else
4747#define INTERCEPT_FUNCTION_VER_LINUX_OR_FREEBSD(func, symver) \
4848 INTERCEPT_FUNCTION_LINUX_OR_FREEBSD(func)
49#endif // !SANITIZER_ANDROID && !SANITIZER_SOLARIS
49#endif // SANITIZER_GLIBC || SANITIZER_FREEBSD || SANITIZER_NETBSD
5050
5151#endif // INTERCEPTION_LINUX_H
5252#endif // SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD ||
53 // SANITIZER_OPENBSD || SANITIZER_SOLARIS
53 // SANITIZER_SOLARIS
lib/tsan/interception/interception_win.cpp+3-3
......@@ -136,7 +136,7 @@ namespace __interception {
136136static const int kAddressLength = FIRST_32_SECOND_64(4, 8);
137137static const int kJumpInstructionLength = 5;
138138static const int kShortJumpInstructionLength = 2;
139static const int kIndirectJumpInstructionLength = 6;
139UNUSED static const int kIndirectJumpInstructionLength = 6;
140140static const int kBranchLength =
141141 FIRST_32_SECOND_64(kJumpInstructionLength, kIndirectJumpInstructionLength);
142142static const int kDirectBranchLength = kBranchLength + kAddressLength;
......@@ -165,7 +165,7 @@ static uptr GetMmapGranularity() {
165165 return si.dwAllocationGranularity;
166166}
167167
168static uptr RoundUpTo(uptr size, uptr boundary) {
168UNUSED static uptr RoundUpTo(uptr size, uptr boundary) {
169169 return (size + boundary - 1) & ~(boundary - 1);
170170}
171171
......@@ -309,7 +309,7 @@ struct TrampolineMemoryRegion {
309309 uptr max_size;
310310};
311311
312static const uptr kTrampolineScanLimitRange = 1 << 31; // 2 gig
312UNUSED static const uptr kTrampolineScanLimitRange = 1 << 31; // 2 gig
313313static const int kMaxTrampolineRegion = 1024;
314314static TrampolineMemoryRegion TrampolineRegions[kMaxTrampolineRegion];
315315
lib/tsan/sanitizer_common/sanitizer_addrhashmap.h+53-53
......@@ -162,8 +162,8 @@ AddrHashMap<T, kSize>::AddrHashMap() {
162162 table_ = (Bucket*)MmapOrDie(kSize * sizeof(table_[0]), "AddrHashMap");
163163}
164164
165template<typename T, uptr kSize>
166void AddrHashMap<T, kSize>::acquire(Handle *h) {
165template <typename T, uptr kSize>
166void AddrHashMap<T, kSize>::acquire(Handle *h) NO_THREAD_SAFETY_ANALYSIS {
167167 uptr addr = h->addr_;
168168 uptr hash = calcHash(addr);
169169 Bucket *b = &table_[hash];
......@@ -289,57 +289,57 @@ void AddrHashMap<T, kSize>::acquire(Handle *h) {
289289 CHECK_EQ(atomic_load(&c->addr, memory_order_relaxed), 0);
290290 h->addidx_ = i;
291291 h->cell_ = c;
292}
293
294template<typename T, uptr kSize>
295void AddrHashMap<T, kSize>::release(Handle *h) {
296 if (!h->cell_)
297 return;
298 Bucket *b = h->bucket_;
299 Cell *c = h->cell_;
300 uptr addr1 = atomic_load(&c->addr, memory_order_relaxed);
301 if (h->created_) {
302 // Denote completion of insertion.
303 CHECK_EQ(addr1, 0);
304 // After the following store, the element becomes available
305 // for lock-free reads.
306 atomic_store(&c->addr, h->addr_, memory_order_release);
307 b->mtx.Unlock();
308 } else if (h->remove_) {
309 // Denote that the cell is empty now.
310 CHECK_EQ(addr1, h->addr_);
311 atomic_store(&c->addr, 0, memory_order_release);
312 // See if we need to compact the bucket.
313 AddBucket *add = (AddBucket*)atomic_load(&b->add, memory_order_relaxed);
314 if (h->addidx_ == -1U) {
315 // Removed from embed array, move an add element into the freed cell.
316 if (add && add->size != 0) {
317 uptr last = --add->size;
318 Cell *c1 = &add->cells[last];
319 c->val = c1->val;
320 uptr addr1 = atomic_load(&c1->addr, memory_order_relaxed);
321 atomic_store(&c->addr, addr1, memory_order_release);
322 atomic_store(&c1->addr, 0, memory_order_release);
323 }
324 } else {
325 // Removed from add array, compact it.
326 uptr last = --add->size;
327 Cell *c1 = &add->cells[last];
328 if (c != c1) {
329 *c = *c1;
330 atomic_store(&c1->addr, 0, memory_order_relaxed);
331 }
332 }
333 if (add && add->size == 0) {
334 // FIXME(dvyukov): free add?
335 }
336 b->mtx.Unlock();
337 } else {
338 CHECK_EQ(addr1, h->addr_);
339 if (h->addidx_ != -1U)
340 b->mtx.ReadUnlock();
341 }
342}
292 }
293
294 template <typename T, uptr kSize>
295 void AddrHashMap<T, kSize>::release(Handle *h) NO_THREAD_SAFETY_ANALYSIS {
296 if (!h->cell_)
297 return;
298 Bucket *b = h->bucket_;
299 Cell *c = h->cell_;
300 uptr addr1 = atomic_load(&c->addr, memory_order_relaxed);
301 if (h->created_) {
302 // Denote completion of insertion.
303 CHECK_EQ(addr1, 0);
304 // After the following store, the element becomes available
305 // for lock-free reads.
306 atomic_store(&c->addr, h->addr_, memory_order_release);
307 b->mtx.Unlock();
308 } else if (h->remove_) {
309 // Denote that the cell is empty now.
310 CHECK_EQ(addr1, h->addr_);
311 atomic_store(&c->addr, 0, memory_order_release);
312 // See if we need to compact the bucket.
313 AddBucket *add = (AddBucket *)atomic_load(&b->add, memory_order_relaxed);
314 if (h->addidx_ == -1U) {
315 // Removed from embed array, move an add element into the freed cell.
316 if (add && add->size != 0) {
317 uptr last = --add->size;
318 Cell *c1 = &add->cells[last];
319 c->val = c1->val;
320 uptr addr1 = atomic_load(&c1->addr, memory_order_relaxed);
321 atomic_store(&c->addr, addr1, memory_order_release);
322 atomic_store(&c1->addr, 0, memory_order_release);
323 }
324 } else {
325 // Removed from add array, compact it.
326 uptr last = --add->size;
327 Cell *c1 = &add->cells[last];
328 if (c != c1) {
329 *c = *c1;
330 atomic_store(&c1->addr, 0, memory_order_relaxed);
331 }
332 }
333 if (add && add->size == 0) {
334 // FIXME(dvyukov): free add?
335 }
336 b->mtx.Unlock();
337 } else {
338 CHECK_EQ(addr1, h->addr_);
339 if (h->addidx_ != -1U)
340 b->mtx.ReadUnlock();
341 }
342 }
343343
344344template<typename T, uptr kSize>
345345uptr AddrHashMap<T, kSize>::calcHash(uptr addr) {
lib/tsan/sanitizer_common/sanitizer_allocator.cpp+4-21
......@@ -137,8 +137,6 @@ static void RawInternalFree(void *ptr, InternalAllocatorCache *cache) {
137137
138138#endif // SANITIZER_GO || defined(SANITIZER_USE_MALLOC)
139139
140const u64 kBlockMagic = 0x6A6CB03ABCEBC041ull;
141
142140static void NORETURN ReportInternalAllocatorOutOfMemory(uptr requested_size) {
143141 SetAllocatorOutOfMemory();
144142 Report("FATAL: %s: internal allocator is out of memory trying to allocate "
......@@ -147,27 +145,17 @@ static void NORETURN ReportInternalAllocatorOutOfMemory(uptr requested_size) {
147145}
148146
149147void *InternalAlloc(uptr size, InternalAllocatorCache *cache, uptr alignment) {
150 if (size + sizeof(u64) < size)
151 return nullptr;
152 void *p = RawInternalAlloc(size + sizeof(u64), cache, alignment);
148 void *p = RawInternalAlloc(size, cache, alignment);
153149 if (UNLIKELY(!p))
154 ReportInternalAllocatorOutOfMemory(size + sizeof(u64));
155 ((u64*)p)[0] = kBlockMagic;
156 return (char*)p + sizeof(u64);
150 ReportInternalAllocatorOutOfMemory(size);
151 return p;
157152}
158153
159154void *InternalRealloc(void *addr, uptr size, InternalAllocatorCache *cache) {
160 if (!addr)
161 return InternalAlloc(size, cache);
162 if (size + sizeof(u64) < size)
163 return nullptr;
164 addr = (char*)addr - sizeof(u64);
165 size = size + sizeof(u64);
166 CHECK_EQ(kBlockMagic, ((u64*)addr)[0]);
167155 void *p = RawInternalRealloc(addr, size, cache);
168156 if (UNLIKELY(!p))
169157 ReportInternalAllocatorOutOfMemory(size);
170 return (char*)p + sizeof(u64);
158 return p;
171159}
172160
173161void *InternalReallocArray(void *addr, uptr count, uptr size,
......@@ -196,11 +184,6 @@ void *InternalCalloc(uptr count, uptr size, InternalAllocatorCache *cache) {
196184}
197185
198186void InternalFree(void *addr, InternalAllocatorCache *cache) {
199 if (!addr)
200 return;
201 addr = (char*)addr - sizeof(u64);
202 CHECK_EQ(kBlockMagic, ((u64*)addr)[0]);
203 ((u64*)addr)[0] = 0;
204187 RawInternalFree(addr, cache);
205188}
206189
lib/tsan/sanitizer_common/sanitizer_allocator.h+3-3
......@@ -52,14 +52,14 @@ struct NoOpMapUnmapCallback {
5252// Callback type for iterating over chunks.
5353typedef void (*ForEachChunkCallback)(uptr chunk, void *arg);
5454
55INLINE u32 Rand(u32 *state) { // ANSI C linear congruential PRNG.
55inline u32 Rand(u32 *state) { // ANSI C linear congruential PRNG.
5656 return (*state = *state * 1103515245 + 12345) >> 16;
5757}
5858
59INLINE u32 RandN(u32 *state, u32 n) { return Rand(state) % n; } // [0, n)
59inline u32 RandN(u32 *state, u32 n) { return Rand(state) % n; } // [0, n)
6060
6161template<typename T>
62INLINE void RandomShuffle(T *a, u32 n, u32 *rand_state) {
62inline void RandomShuffle(T *a, u32 n, u32 *rand_state) {
6363 if (n <= 1) return;
6464 u32 state = *rand_state;
6565 for (u32 i = n - 1; i > 0; i--)
lib/tsan/sanitizer_common/sanitizer_allocator_checks.h+5-5
......@@ -27,7 +27,7 @@ namespace __sanitizer {
2727void SetErrnoToENOMEM();
2828
2929// A common errno setting logic shared by almost all sanitizer allocator APIs.
30INLINE void *SetErrnoOnNull(void *ptr) {
30inline void *SetErrnoOnNull(void *ptr) {
3131 if (UNLIKELY(!ptr))
3232 SetErrnoToENOMEM();
3333 return ptr;
......@@ -41,7 +41,7 @@ INLINE void *SetErrnoOnNull(void *ptr) {
4141// two and that the size is a multiple of alignment for POSIX implementation,
4242// and a bit relaxed requirement for non-POSIX ones, that the size is a multiple
4343// of alignment.
44INLINE bool CheckAlignedAllocAlignmentAndSize(uptr alignment, uptr size) {
44inline bool CheckAlignedAllocAlignmentAndSize(uptr alignment, uptr size) {
4545#if SANITIZER_POSIX
4646 return alignment != 0 && IsPowerOfTwo(alignment) &&
4747 (size & (alignment - 1)) == 0;
......@@ -52,13 +52,13 @@ INLINE bool CheckAlignedAllocAlignmentAndSize(uptr alignment, uptr size) {
5252
5353// Checks posix_memalign() parameters, verifies that alignment is a power of two
5454// and a multiple of sizeof(void *).
55INLINE bool CheckPosixMemalignAlignment(uptr alignment) {
55inline bool CheckPosixMemalignAlignment(uptr alignment) {
5656 return alignment != 0 && IsPowerOfTwo(alignment) &&
5757 (alignment % sizeof(void *)) == 0;
5858}
5959
6060// Returns true if calloc(size, n) call overflows on size*n calculation.
61INLINE bool CheckForCallocOverflow(uptr size, uptr n) {
61inline bool CheckForCallocOverflow(uptr size, uptr n) {
6262 if (!size)
6363 return false;
6464 uptr max = (uptr)-1L;
......@@ -67,7 +67,7 @@ INLINE bool CheckForCallocOverflow(uptr size, uptr n) {
6767
6868// Returns true if the size passed to pvalloc overflows when rounded to the next
6969// multiple of page_size.
70INLINE bool CheckForPvallocOverflow(uptr size, uptr page_size) {
70inline bool CheckForPvallocOverflow(uptr size, uptr page_size) {
7171 return RoundUpTo(size, page_size) < size;
7272}
7373
lib/tsan/sanitizer_common/sanitizer_allocator_combined.h+4-4
......@@ -35,9 +35,9 @@ class CombinedAllocator {
3535 secondary_.InitLinkerInitialized();
3636 }
3737
38 void Init(s32 release_to_os_interval_ms) {
38 void Init(s32 release_to_os_interval_ms, uptr heap_start = 0) {
3939 stats_.Init();
40 primary_.Init(release_to_os_interval_ms);
40 primary_.Init(release_to_os_interval_ms, heap_start);
4141 secondary_.Init();
4242 }
4343
......@@ -177,12 +177,12 @@ class CombinedAllocator {
177177
178178 // ForceLock() and ForceUnlock() are needed to implement Darwin malloc zone
179179 // introspection API.
180 void ForceLock() {
180 void ForceLock() NO_THREAD_SAFETY_ANALYSIS {
181181 primary_.ForceLock();
182182 secondary_.ForceLock();
183183 }
184184
185 void ForceUnlock() {
185 void ForceUnlock() NO_THREAD_SAFETY_ANALYSIS {
186186 secondary_.ForceUnlock();
187187 primary_.ForceUnlock();
188188 }
lib/tsan/sanitizer_common/sanitizer_allocator_local_cache.h+13-6
......@@ -17,6 +17,7 @@
1717template <class SizeClassAllocator>
1818struct SizeClassAllocator64LocalCache {
1919 typedef SizeClassAllocator Allocator;
20 typedef MemoryMapper<Allocator> MemoryMapperT;
2021
2122 void Init(AllocatorGlobalStats *s) {
2223 stats_.Init();
......@@ -53,7 +54,7 @@ struct SizeClassAllocator64LocalCache {
5354 PerClass *c = &per_class_[class_id];
5455 InitCache(c);
5556 if (UNLIKELY(c->count == c->max_count))
56 Drain(c, allocator, class_id, c->max_count / 2);
57 DrainHalfMax(c, allocator, class_id);
5758 CompactPtrT chunk = allocator->PointerToCompactPtr(
5859 allocator->GetRegionBeginBySizeClass(class_id),
5960 reinterpret_cast<uptr>(p));
......@@ -62,10 +63,10 @@ struct SizeClassAllocator64LocalCache {
6263 }
6364
6465 void Drain(SizeClassAllocator *allocator) {
66 MemoryMapperT memory_mapper(*allocator);
6567 for (uptr i = 1; i < kNumClasses; i++) {
6668 PerClass *c = &per_class_[i];
67 while (c->count > 0)
68 Drain(c, allocator, i, c->count);
69 while (c->count > 0) Drain(&memory_mapper, c, allocator, i, c->count);
6970 }
7071 }
7172
......@@ -106,12 +107,18 @@ struct SizeClassAllocator64LocalCache {
106107 return true;
107108 }
108109
109 NOINLINE void Drain(PerClass *c, SizeClassAllocator *allocator, uptr class_id,
110 uptr count) {
110 NOINLINE void DrainHalfMax(PerClass *c, SizeClassAllocator *allocator,
111 uptr class_id) {
112 MemoryMapperT memory_mapper(*allocator);
113 Drain(&memory_mapper, c, allocator, class_id, c->max_count / 2);
114 }
115
116 void Drain(MemoryMapperT *memory_mapper, PerClass *c,
117 SizeClassAllocator *allocator, uptr class_id, uptr count) {
111118 CHECK_GE(c->count, count);
112119 const uptr first_idx_to_drain = c->count - count;
113120 c->count -= count;
114 allocator->ReturnToAllocator(&stats_, class_id,
121 allocator->ReturnToAllocator(memory_mapper, &stats_, class_id,
115122 &c->chunks[first_idx_to_drain], count);
116123 }
117124};
lib/tsan/sanitizer_common/sanitizer_allocator_primary32.h+5-3
......@@ -119,7 +119,8 @@ class SizeClassAllocator32 {
119119 typedef SizeClassAllocator32<Params> ThisT;
120120 typedef SizeClassAllocator32LocalCache<ThisT> AllocatorCache;
121121
122 void Init(s32 release_to_os_interval_ms) {
122 void Init(s32 release_to_os_interval_ms, uptr heap_start = 0) {
123 CHECK(!heap_start);
123124 possible_regions.Init();
124125 internal_memset(size_class_info_array, 0, sizeof(size_class_info_array));
125126 }
......@@ -153,6 +154,7 @@ class SizeClassAllocator32 {
153154 }
154155
155156 void *GetMetaData(const void *p) {
157 CHECK(kMetadataSize);
156158 CHECK(PointerIsMine(p));
157159 uptr mem = reinterpret_cast<uptr>(p);
158160 uptr beg = ComputeRegionBeg(mem);
......@@ -235,13 +237,13 @@ class SizeClassAllocator32 {
235237
236238 // ForceLock() and ForceUnlock() are needed to implement Darwin malloc zone
237239 // introspection API.
238 void ForceLock() {
240 void ForceLock() NO_THREAD_SAFETY_ANALYSIS {
239241 for (uptr i = 0; i < kNumClasses; i++) {
240242 GetSizeClassInfo(i)->mutex.Lock();
241243 }
242244 }
243245
244 void ForceUnlock() {
246 void ForceUnlock() NO_THREAD_SAFETY_ANALYSIS {
245247 for (int i = kNumClasses - 1; i >= 0; i--) {
246248 GetSizeClassInfo(i)->mutex.Unlock();
247249 }
lib/tsan/sanitizer_common/sanitizer_allocator_primary64.h+145-111
......@@ -19,7 +19,7 @@ template<class SizeClassAllocator> struct SizeClassAllocator64LocalCache;
1919// The template parameter Params is a class containing the actual parameters.
2020//
2121// Space: a portion of address space of kSpaceSize bytes starting at SpaceBeg.
22// If kSpaceBeg is ~0 then SpaceBeg is chosen dynamically my mmap.
22// If kSpaceBeg is ~0 then SpaceBeg is chosen dynamically by mmap.
2323// Otherwise SpaceBeg=kSpaceBeg (fixed address).
2424// kSpaceSize is a power of two.
2525// At the beginning the entire space is mprotect-ed, then small parts of it
......@@ -42,6 +42,44 @@ struct SizeClassAllocator64FlagMasks { // Bit masks.
4242 };
4343};
4444
45template <typename Allocator>
46class MemoryMapper {
47 public:
48 typedef typename Allocator::CompactPtrT CompactPtrT;
49
50 explicit MemoryMapper(const Allocator &allocator) : allocator_(allocator) {}
51
52 bool GetAndResetStats(uptr &ranges, uptr &bytes) {
53 ranges = released_ranges_count_;
54 released_ranges_count_ = 0;
55 bytes = released_bytes_;
56 released_bytes_ = 0;
57 return ranges != 0;
58 }
59
60 u64 *MapPackedCounterArrayBuffer(uptr count) {
61 buffer_.clear();
62 buffer_.resize(count);
63 return buffer_.data();
64 }
65
66 // Releases [from, to) range of pages back to OS.
67 void ReleasePageRangeToOS(uptr class_id, CompactPtrT from, CompactPtrT to) {
68 const uptr region_base = allocator_.GetRegionBeginBySizeClass(class_id);
69 const uptr from_page = allocator_.CompactPtrToPointer(region_base, from);
70 const uptr to_page = allocator_.CompactPtrToPointer(region_base, to);
71 ReleaseMemoryPagesToOS(from_page, to_page);
72 released_ranges_count_++;
73 released_bytes_ += to_page - from_page;
74 }
75
76 private:
77 const Allocator &allocator_;
78 uptr released_ranges_count_ = 0;
79 uptr released_bytes_ = 0;
80 InternalMmapVector<u64> buffer_;
81};
82
4583template <class Params>
4684class SizeClassAllocator64 {
4785 public:
......@@ -57,6 +95,7 @@ class SizeClassAllocator64 {
5795
5896 typedef SizeClassAllocator64<Params> ThisT;
5997 typedef SizeClassAllocator64LocalCache<ThisT> AllocatorCache;
98 typedef MemoryMapper<ThisT> MemoryMapperT;
6099
61100 // When we know the size class (the region base) we can represent a pointer
62101 // as a 4-byte integer (offset from the region start shifted right by 4).
......@@ -69,25 +108,45 @@ class SizeClassAllocator64 {
69108 return base + (static_cast<uptr>(ptr32) << kCompactPtrScale);
70109 }
71110
72 void Init(s32 release_to_os_interval_ms) {
111 // If heap_start is nonzero, assumes kSpaceSize bytes are already mapped R/W
112 // at heap_start and places the heap there. This mode requires kSpaceBeg ==
113 // ~(uptr)0.
114 void Init(s32 release_to_os_interval_ms, uptr heap_start = 0) {
73115 uptr TotalSpaceSize = kSpaceSize + AdditionalSize();
74 if (kUsingConstantSpaceBeg) {
75 CHECK(IsAligned(kSpaceBeg, SizeClassMap::kMaxSize));
76 CHECK_EQ(kSpaceBeg, address_range.Init(TotalSpaceSize,
77 PrimaryAllocatorName, kSpaceBeg));
116 PremappedHeap = heap_start != 0;
117 if (PremappedHeap) {
118 CHECK(!kUsingConstantSpaceBeg);
119 NonConstSpaceBeg = heap_start;
120 uptr RegionInfoSize = AdditionalSize();
121 RegionInfoSpace =
122 address_range.Init(RegionInfoSize, PrimaryAllocatorName);
123 CHECK_NE(RegionInfoSpace, ~(uptr)0);
124 CHECK_EQ(RegionInfoSpace,
125 address_range.MapOrDie(RegionInfoSpace, RegionInfoSize,
126 "SizeClassAllocator: region info"));
127 MapUnmapCallback().OnMap(RegionInfoSpace, RegionInfoSize);
78128 } else {
79 // Combined allocator expects that an 2^N allocation is always aligned to
80 // 2^N. For this to work, the start of the space needs to be aligned as
81 // high as the largest size class (which also needs to be a power of 2).
82 NonConstSpaceBeg = address_range.InitAligned(
83 TotalSpaceSize, SizeClassMap::kMaxSize, PrimaryAllocatorName);
84 CHECK_NE(NonConstSpaceBeg, ~(uptr)0);
129 if (kUsingConstantSpaceBeg) {
130 CHECK(IsAligned(kSpaceBeg, SizeClassMap::kMaxSize));
131 CHECK_EQ(kSpaceBeg,
132 address_range.Init(TotalSpaceSize, PrimaryAllocatorName,
133 kSpaceBeg));
134 } else {
135 // Combined allocator expects that an 2^N allocation is always aligned
136 // to 2^N. For this to work, the start of the space needs to be aligned
137 // as high as the largest size class (which also needs to be a power of
138 // 2).
139 NonConstSpaceBeg = address_range.InitAligned(
140 TotalSpaceSize, SizeClassMap::kMaxSize, PrimaryAllocatorName);
141 CHECK_NE(NonConstSpaceBeg, ~(uptr)0);
142 }
143 RegionInfoSpace = SpaceEnd();
144 MapWithCallbackOrDie(RegionInfoSpace, AdditionalSize(),
145 "SizeClassAllocator: region info");
85146 }
86147 SetReleaseToOSIntervalMs(release_to_os_interval_ms);
87 MapWithCallbackOrDie(SpaceEnd(), AdditionalSize(),
88 "SizeClassAllocator: region info");
89148 // Check that the RegionInfo array is aligned on the CacheLine size.
90 DCHECK_EQ(SpaceEnd() % kCacheLineSize, 0);
149 DCHECK_EQ(RegionInfoSpace % kCacheLineSize, 0);
91150 }
92151
93152 s32 ReleaseToOSIntervalMs() const {
......@@ -100,9 +159,10 @@ class SizeClassAllocator64 {
100159 }
101160
102161 void ForceReleaseToOS() {
162 MemoryMapperT memory_mapper(*this);
103163 for (uptr class_id = 1; class_id < kNumClasses; class_id++) {
104164 BlockingMutexLock l(&GetRegionInfo(class_id)->mutex);
105 MaybeReleaseToOS(class_id, true /*force*/);
165 MaybeReleaseToOS(&memory_mapper, class_id, true /*force*/);
106166 }
107167 }
108168
......@@ -111,7 +171,8 @@ class SizeClassAllocator64 {
111171 alignment <= SizeClassMap::kMaxSize;
112172 }
113173
114 NOINLINE void ReturnToAllocator(AllocatorStats *stat, uptr class_id,
174 NOINLINE void ReturnToAllocator(MemoryMapperT *memory_mapper,
175 AllocatorStats *stat, uptr class_id,
115176 const CompactPtrT *chunks, uptr n_chunks) {
116177 RegionInfo *region = GetRegionInfo(class_id);
117178 uptr region_beg = GetRegionBeginBySizeClass(class_id);
......@@ -134,7 +195,7 @@ class SizeClassAllocator64 {
134195 region->num_freed_chunks = new_num_freed_chunks;
135196 region->stats.n_freed += n_chunks;
136197
137 MaybeReleaseToOS(class_id, false /*force*/);
198 MaybeReleaseToOS(memory_mapper, class_id, false /*force*/);
138199 }
139200
140201 NOINLINE bool GetFromAllocator(AllocatorStats *stat, uptr class_id,
......@@ -144,6 +205,17 @@ class SizeClassAllocator64 {
144205 CompactPtrT *free_array = GetFreeArray(region_beg);
145206
146207 BlockingMutexLock l(&region->mutex);
208#if SANITIZER_WINDOWS
209 /* On Windows unmapping of memory during __sanitizer_purge_allocator is
210 explicit and immediate, so unmapped regions must be explicitly mapped back
211 in when they are accessed again. */
212 if (region->rtoi.last_released_bytes > 0) {
213 MmapFixedOrDie(region_beg, region->mapped_user,
214 "SizeClassAllocator: region data");
215 region->rtoi.n_freed_at_last_release = 0;
216 region->rtoi.last_released_bytes = 0;
217 }
218#endif
147219 if (UNLIKELY(region->num_freed_chunks < n_chunks)) {
148220 if (UNLIKELY(!PopulateFreeArray(stat, class_id, region,
149221 n_chunks - region->num_freed_chunks)))
......@@ -186,13 +258,13 @@ class SizeClassAllocator64 {
186258
187259 void *GetBlockBegin(const void *p) {
188260 uptr class_id = GetSizeClass(p);
261 if (class_id >= kNumClasses) return nullptr;
189262 uptr size = ClassIdToSize(class_id);
190263 if (!size) return nullptr;
191264 uptr chunk_idx = GetChunkIdx((uptr)p, size);
192265 uptr reg_beg = GetRegionBegin(p);
193266 uptr beg = chunk_idx * size;
194267 uptr next_beg = beg + size;
195 if (class_id >= kNumClasses) return nullptr;
196268 const RegionInfo *region = AddressSpaceView::Load(GetRegionInfo(class_id));
197269 if (region->mapped_user >= next_beg)
198270 return reinterpret_cast<void*>(reg_beg + beg);
......@@ -207,6 +279,7 @@ class SizeClassAllocator64 {
207279 static uptr ClassID(uptr size) { return SizeClassMap::ClassID(size); }
208280
209281 void *GetMetaData(const void *p) {
282 CHECK(kMetadataSize);
210283 uptr class_id = GetSizeClass(p);
211284 uptr size = ClassIdToSize(class_id);
212285 uptr chunk_idx = GetChunkIdx(reinterpret_cast<uptr>(p), size);
......@@ -280,13 +353,13 @@ class SizeClassAllocator64 {
280353
281354 // ForceLock() and ForceUnlock() are needed to implement Darwin malloc zone
282355 // introspection API.
283 void ForceLock() {
356 void ForceLock() NO_THREAD_SAFETY_ANALYSIS {
284357 for (uptr i = 0; i < kNumClasses; i++) {
285358 GetRegionInfo(i)->mutex.Lock();
286359 }
287360 }
288361
289 void ForceUnlock() {
362 void ForceUnlock() NO_THREAD_SAFETY_ANALYSIS {
290363 for (int i = (int)kNumClasses - 1; i >= 0; i--) {
291364 GetRegionInfo(i)->mutex.Unlock();
292365 }
......@@ -330,11 +403,11 @@ class SizeClassAllocator64 {
330403 // For the performance sake, none of the accessors check the validity of the
331404 // arguments, it is assumed that index is always in [0, n) range and the value
332405 // is not incremented past max_value.
333 template<class MemoryMapperT>
334406 class PackedCounterArray {
335407 public:
336 PackedCounterArray(u64 num_counters, u64 max_value, MemoryMapperT *mapper)
337 : n(num_counters), memory_mapper(mapper) {
408 template <typename MemoryMapper>
409 PackedCounterArray(u64 num_counters, u64 max_value, MemoryMapper *mapper)
410 : n(num_counters) {
338411 CHECK_GT(num_counters, 0);
339412 CHECK_GT(max_value, 0);
340413 constexpr u64 kMaxCounterBits = sizeof(*buffer) * 8ULL;
......@@ -351,17 +424,8 @@ class SizeClassAllocator64 {
351424 packing_ratio_log = Log2(packing_ratio);
352425 bit_offset_mask = packing_ratio - 1;
353426
354 buffer_size =
355 (RoundUpTo(n, 1ULL << packing_ratio_log) >> packing_ratio_log) *
356 sizeof(*buffer);
357 buffer = reinterpret_cast<u64*>(
358 memory_mapper->MapPackedCounterArrayBuffer(buffer_size));
359 }
360 ~PackedCounterArray() {
361 if (buffer) {
362 memory_mapper->UnmapPackedCounterArrayBuffer(
363 reinterpret_cast<uptr>(buffer), buffer_size);
364 }
427 buffer = mapper->MapPackedCounterArrayBuffer(
428 RoundUpTo(n, 1ULL << packing_ratio_log) >> packing_ratio_log);
365429 }
366430
367431 bool IsAllocated() const {
......@@ -398,19 +462,16 @@ class SizeClassAllocator64 {
398462 u64 counter_mask;
399463 u64 packing_ratio_log;
400464 u64 bit_offset_mask;
401
402 MemoryMapperT* const memory_mapper;
403 u64 buffer_size;
404465 u64* buffer;
405466 };
406467
407 template<class MemoryMapperT>
468 template <class MemoryMapperT>
408469 class FreePagesRangeTracker {
409470 public:
410 explicit FreePagesRangeTracker(MemoryMapperT* mapper)
471 FreePagesRangeTracker(MemoryMapperT *mapper, uptr class_id)
411472 : memory_mapper(mapper),
412 page_size_scaled_log(Log2(GetPageSizeCached() >> kCompactPtrScale)),
413 in_the_range(false), current_page(0), current_range_start_page(0) {}
473 class_id(class_id),
474 page_size_scaled_log(Log2(GetPageSizeCached() >> kCompactPtrScale)) {}
414475
415476 void NextPage(bool freed) {
416477 if (freed) {
......@@ -432,28 +493,30 @@ class SizeClassAllocator64 {
432493 void CloseOpenedRange() {
433494 if (in_the_range) {
434495 memory_mapper->ReleasePageRangeToOS(
435 current_range_start_page << page_size_scaled_log,
496 class_id, current_range_start_page << page_size_scaled_log,
436497 current_page << page_size_scaled_log);
437498 in_the_range = false;
438499 }
439500 }
440501
441 MemoryMapperT* const memory_mapper;
442 const uptr page_size_scaled_log;
443 bool in_the_range;
444 uptr current_page;
445 uptr current_range_start_page;
502 MemoryMapperT *const memory_mapper = nullptr;
503 const uptr class_id = 0;
504 const uptr page_size_scaled_log = 0;
505 bool in_the_range = false;
506 uptr current_page = 0;
507 uptr current_range_start_page = 0;
446508 };
447509
448510 // Iterates over the free_array to identify memory pages containing freed
449511 // chunks only and returns these pages back to OS.
450512 // allocated_pages_count is the total number of pages allocated for the
451513 // current bucket.
452 template<class MemoryMapperT>
514 template <typename MemoryMapper>
453515 static void ReleaseFreeMemoryToOS(CompactPtrT *free_array,
454516 uptr free_array_count, uptr chunk_size,
455517 uptr allocated_pages_count,
456 MemoryMapperT *memory_mapper) {
518 MemoryMapper *memory_mapper,
519 uptr class_id) {
457520 const uptr page_size = GetPageSizeCached();
458521
459522 // Figure out the number of chunks per page and whether we can take a fast
......@@ -489,9 +552,8 @@ class SizeClassAllocator64 {
489552 UNREACHABLE("All chunk_size/page_size ratios must be handled.");
490553 }
491554
492 PackedCounterArray<MemoryMapperT> counters(allocated_pages_count,
493 full_pages_chunk_count_max,
494 memory_mapper);
555 PackedCounterArray counters(allocated_pages_count,
556 full_pages_chunk_count_max, memory_mapper);
495557 if (!counters.IsAllocated())
496558 return;
497559
......@@ -516,7 +578,7 @@ class SizeClassAllocator64 {
516578
517579 // Iterate over pages detecting ranges of pages with chunk counters equal
518580 // to the expected number of chunks for the particular page.
519 FreePagesRangeTracker<MemoryMapperT> range_tracker(memory_mapper);
581 FreePagesRangeTracker<MemoryMapper> range_tracker(memory_mapper, class_id);
520582 if (same_chunk_count_per_page) {
521583 // Fast path, every page has the same number of chunks affecting it.
522584 for (uptr i = 0; i < counters.GetCount(); i++)
......@@ -555,7 +617,7 @@ class SizeClassAllocator64 {
555617 }
556618
557619 private:
558 friend class MemoryMapper;
620 friend class MemoryMapper<ThisT>;
559621
560622 ReservedAddressRange address_range;
561623
......@@ -585,6 +647,11 @@ class SizeClassAllocator64 {
585647
586648 atomic_sint32_t release_to_os_interval_ms_;
587649
650 uptr RegionInfoSpace;
651
652 // True if the user has already mapped the entire heap R/W.
653 bool PremappedHeap;
654
588655 struct Stats {
589656 uptr n_allocated;
590657 uptr n_freed;
......@@ -614,7 +681,7 @@ class SizeClassAllocator64 {
614681
615682 RegionInfo *GetRegionInfo(uptr class_id) const {
616683 DCHECK_LT(class_id, kNumClasses);
617 RegionInfo *regions = reinterpret_cast<RegionInfo *>(SpaceEnd());
684 RegionInfo *regions = reinterpret_cast<RegionInfo *>(RegionInfoSpace);
618685 return &regions[class_id];
619686 }
620687
......@@ -639,6 +706,9 @@ class SizeClassAllocator64 {
639706 }
640707
641708 bool MapWithCallback(uptr beg, uptr size, const char *name) {
709 if (PremappedHeap)
710 return beg >= NonConstSpaceBeg &&
711 beg + size <= NonConstSpaceBeg + kSpaceSize;
642712 uptr mapped = address_range.Map(beg, size, name);
643713 if (UNLIKELY(!mapped))
644714 return false;
......@@ -648,11 +718,18 @@ class SizeClassAllocator64 {
648718 }
649719
650720 void MapWithCallbackOrDie(uptr beg, uptr size, const char *name) {
721 if (PremappedHeap) {
722 CHECK_GE(beg, NonConstSpaceBeg);
723 CHECK_LE(beg + size, NonConstSpaceBeg + kSpaceSize);
724 return;
725 }
651726 CHECK_EQ(beg, address_range.MapOrDie(beg, size, name));
652727 MapUnmapCallback().OnMap(beg, size);
653728 }
654729
655730 void UnmapWithCallbackOrDie(uptr beg, uptr size) {
731 if (PremappedHeap)
732 return;
656733 MapUnmapCallback().OnUnmap(beg, size);
657734 address_range.Unmap(beg, size);
658735 }
......@@ -774,55 +851,13 @@ class SizeClassAllocator64 {
774851 return true;
775852 }
776853
777 class MemoryMapper {
778 public:
779 MemoryMapper(const ThisT& base_allocator, uptr class_id)
780 : allocator(base_allocator),
781 region_base(base_allocator.GetRegionBeginBySizeClass(class_id)),
782 released_ranges_count(0),
783 released_bytes(0) {
784 }
785
786 uptr GetReleasedRangesCount() const {
787 return released_ranges_count;
788 }
789
790 uptr GetReleasedBytes() const {
791 return released_bytes;
792 }
793
794 uptr MapPackedCounterArrayBuffer(uptr buffer_size) {
795 // TODO(alekseyshl): The idea to explore is to check if we have enough
796 // space between num_freed_chunks*sizeof(CompactPtrT) and
797 // mapped_free_array to fit buffer_size bytes and use that space instead
798 // of mapping a temporary one.
799 return reinterpret_cast<uptr>(
800 MmapOrDieOnFatalError(buffer_size, "ReleaseToOSPageCounters"));
801 }
802
803 void UnmapPackedCounterArrayBuffer(uptr buffer, uptr buffer_size) {
804 UnmapOrDie(reinterpret_cast<void *>(buffer), buffer_size);
805 }
806
807 // Releases [from, to) range of pages back to OS.
808 void ReleasePageRangeToOS(CompactPtrT from, CompactPtrT to) {
809 const uptr from_page = allocator.CompactPtrToPointer(region_base, from);
810 const uptr to_page = allocator.CompactPtrToPointer(region_base, to);
811 ReleaseMemoryPagesToOS(from_page, to_page);
812 released_ranges_count++;
813 released_bytes += to_page - from_page;
814 }
815
816 private:
817 const ThisT& allocator;
818 const uptr region_base;
819 uptr released_ranges_count;
820 uptr released_bytes;
821 };
822
823854 // Attempts to release RAM occupied by freed chunks back to OS. The region is
824855 // expected to be locked.
825 void MaybeReleaseToOS(uptr class_id, bool force) {
856 //
857 // TODO(morehouse): Support a callback on memory release so HWASan can release
858 // aliases as well.
859 void MaybeReleaseToOS(MemoryMapperT *memory_mapper, uptr class_id,
860 bool force) {
826861 RegionInfo *region = GetRegionInfo(class_id);
827862 const uptr chunk_size = ClassIdToSize(class_id);
828863 const uptr page_size = GetPageSizeCached();
......@@ -846,17 +881,16 @@ class SizeClassAllocator64 {
846881 }
847882 }
848883
849 MemoryMapper memory_mapper(*this, class_id);
850
851 ReleaseFreeMemoryToOS<MemoryMapper>(
884 ReleaseFreeMemoryToOS(
852885 GetFreeArray(GetRegionBeginBySizeClass(class_id)), n, chunk_size,
853 RoundUpTo(region->allocated_user, page_size) / page_size,
854 &memory_mapper);
886 RoundUpTo(region->allocated_user, page_size) / page_size, memory_mapper,
887 class_id);
855888
856 if (memory_mapper.GetReleasedRangesCount() > 0) {
889 uptr ranges, bytes;
890 if (memory_mapper->GetAndResetStats(ranges, bytes)) {
857891 region->rtoi.n_freed_at_last_release = region->stats.n_freed;
858 region->rtoi.num_releases += memory_mapper.GetReleasedRangesCount();
859 region->rtoi.last_released_bytes = memory_mapper.GetReleasedBytes();
892 region->rtoi.num_releases += ranges;
893 region->rtoi.last_released_bytes = bytes;
860894 }
861895 region->rtoi.last_release_at_ns = MonotonicNanoTime();
862896 }
lib/tsan/sanitizer_common/sanitizer_allocator_report.cpp+8
......@@ -134,4 +134,12 @@ void NORETURN ReportOutOfMemory(uptr requested_size, const StackTrace *stack) {
134134 Die();
135135}
136136
137void NORETURN ReportRssLimitExceeded(const StackTrace *stack) {
138 {
139 ScopedAllocatorErrorReport report("rss-limit-exceeded", stack);
140 Report("ERROR: %s: allocator exceeded the RSS limit\n", SanitizerToolName);
141 }
142 Die();
143}
144
137145} // namespace __sanitizer
lib/tsan/sanitizer_common/sanitizer_allocator_report.h+1
......@@ -33,6 +33,7 @@ void NORETURN ReportInvalidPosixMemalignAlignment(uptr alignment,
3333void NORETURN ReportAllocationSizeTooBig(uptr user_size, uptr max_size,
3434 const StackTrace *stack);
3535void NORETURN ReportOutOfMemory(uptr requested_size, const StackTrace *stack);
36void NORETURN ReportRssLimitExceeded(const StackTrace *stack);
3637
3738} // namespace __sanitizer
3839
lib/tsan/sanitizer_common/sanitizer_allocator_secondary.h+6-10
......@@ -18,8 +18,8 @@
1818// (currently, 32 bits and internal allocator).
1919class LargeMmapAllocatorPtrArrayStatic {
2020 public:
21 INLINE void *Init() { return &p_[0]; }
22 INLINE void EnsureSpace(uptr n) { CHECK_LT(n, kMaxNumChunks); }
21 inline void *Init() { return &p_[0]; }
22 inline void EnsureSpace(uptr n) { CHECK_LT(n, kMaxNumChunks); }
2323 private:
2424 static const int kMaxNumChunks = 1 << 15;
2525 uptr p_[kMaxNumChunks];
......@@ -31,14 +31,14 @@ class LargeMmapAllocatorPtrArrayStatic {
3131// same functionality in Fuchsia case, which does not support MAP_NORESERVE.
3232class LargeMmapAllocatorPtrArrayDynamic {
3333 public:
34 INLINE void *Init() {
34 inline void *Init() {
3535 uptr p = address_range_.Init(kMaxNumChunks * sizeof(uptr),
3636 SecondaryAllocatorName);
3737 CHECK(p);
3838 return reinterpret_cast<void*>(p);
3939 }
4040
41 INLINE void EnsureSpace(uptr n) {
41 inline void EnsureSpace(uptr n) {
4242 CHECK_LT(n, kMaxNumChunks);
4343 DCHECK(n <= n_reserved_);
4444 if (UNLIKELY(n == n_reserved_)) {
......@@ -267,13 +267,9 @@ class LargeMmapAllocator {
267267
268268 // ForceLock() and ForceUnlock() are needed to implement Darwin malloc zone
269269 // introspection API.
270 void ForceLock() {
271 mutex_.Lock();
272 }
270 void ForceLock() ACQUIRE(mutex_) { mutex_.Lock(); }
273271
274 void ForceUnlock() {
275 mutex_.Unlock();
276 }
272 void ForceUnlock() RELEASE(mutex_) { mutex_.Unlock(); }
277273
278274 // Iterate over all existing chunks.
279275 // The allocator must be locked when calling this function.
lib/tsan/sanitizer_common/sanitizer_allocator_size_class_map.h+1-1
......@@ -24,7 +24,7 @@
2424// E.g. with kNumBits==3 all size classes after 2^kMidSizeLog
2525// look like 0b1xx0..0, where x is either 0 or 1.
2626//
27// Example: kNumBits=3, kMidSizeLog=4, kMidSizeLog=8, kMaxSizeLog=17:
27// Example: kNumBits=3, kMinSizeLog=4, kMidSizeLog=8, kMaxSizeLog=17:
2828//
2929// Classes 1 - 16 correspond to sizes 16 to 256 (size = class_id * 16).
3030// Next 4 classes: 256 + i * 64 (i = 1 to 4).
lib/tsan/sanitizer_common/sanitizer_atomic.h+2-2
......@@ -72,12 +72,12 @@ namespace __sanitizer {
7272// Clutter-reducing helpers.
7373
7474template<typename T>
75INLINE typename T::Type atomic_load_relaxed(const volatile T *a) {
75inline typename T::Type atomic_load_relaxed(const volatile T *a) {
7676 return atomic_load(a, memory_order_relaxed);
7777}
7878
7979template<typename T>
80INLINE void atomic_store_relaxed(volatile T *a, typename T::Type v) {
80inline void atomic_store_relaxed(volatile T *a, typename T::Type v) {
8181 atomic_store(a, v, memory_order_relaxed);
8282}
8383
lib/tsan/sanitizer_common/sanitizer_atomic_clang.h+7-7
......@@ -34,16 +34,16 @@ namespace __sanitizer {
3434// See http://www.cl.cam.ac.uk/~pes20/cpp/cpp0xmappings.html
3535// for mappings of the memory model to different processors.
3636
37INLINE void atomic_signal_fence(memory_order) {
37inline void atomic_signal_fence(memory_order) {
3838 __asm__ __volatile__("" ::: "memory");
3939}
4040
41INLINE void atomic_thread_fence(memory_order) {
41inline void atomic_thread_fence(memory_order) {
4242 __sync_synchronize();
4343}
4444
4545template<typename T>
46INLINE typename T::Type atomic_fetch_add(volatile T *a,
46inline typename T::Type atomic_fetch_add(volatile T *a,
4747 typename T::Type v, memory_order mo) {
4848 (void)mo;
4949 DCHECK(!((uptr)a % sizeof(*a)));
......@@ -51,7 +51,7 @@ INLINE typename T::Type atomic_fetch_add(volatile T *a,
5151}
5252
5353template<typename T>
54INLINE typename T::Type atomic_fetch_sub(volatile T *a,
54inline typename T::Type atomic_fetch_sub(volatile T *a,
5555 typename T::Type v, memory_order mo) {
5656 (void)mo;
5757 DCHECK(!((uptr)a % sizeof(*a)));
......@@ -59,7 +59,7 @@ INLINE typename T::Type atomic_fetch_sub(volatile T *a,
5959}
6060
6161template<typename T>
62INLINE typename T::Type atomic_exchange(volatile T *a,
62inline typename T::Type atomic_exchange(volatile T *a,
6363 typename T::Type v, memory_order mo) {
6464 DCHECK(!((uptr)a % sizeof(*a)));
6565 if (mo & (memory_order_release | memory_order_acq_rel | memory_order_seq_cst))
......@@ -71,7 +71,7 @@ INLINE typename T::Type atomic_exchange(volatile T *a,
7171}
7272
7373template <typename T>
74INLINE bool atomic_compare_exchange_strong(volatile T *a, typename T::Type *cmp,
74inline bool atomic_compare_exchange_strong(volatile T *a, typename T::Type *cmp,
7575 typename T::Type xchg,
7676 memory_order mo) {
7777 typedef typename T::Type Type;
......@@ -84,7 +84,7 @@ INLINE bool atomic_compare_exchange_strong(volatile T *a, typename T::Type *cmp,
8484}
8585
8686template<typename T>
87INLINE bool atomic_compare_exchange_weak(volatile T *a,
87inline bool atomic_compare_exchange_weak(volatile T *a,
8888 typename T::Type *cmp,
8989 typename T::Type xchg,
9090 memory_order mo) {
lib/tsan/sanitizer_common/sanitizer_atomic_clang_mips.h+9-9
......@@ -37,11 +37,11 @@ static struct {
3737} __attribute__((aligned(32))) lock = {0, {0}};
3838
3939template <>
40INLINE atomic_uint64_t::Type atomic_fetch_add(volatile atomic_uint64_t *ptr,
40inline atomic_uint64_t::Type atomic_fetch_add(volatile atomic_uint64_t *ptr,
4141 atomic_uint64_t::Type val,
4242 memory_order mo) {
4343 DCHECK(mo &
44 (memory_order_relaxed | memory_order_releasae | memory_order_seq_cst));
44 (memory_order_relaxed | memory_order_release | memory_order_seq_cst));
4545 DCHECK(!((uptr)ptr % sizeof(*ptr)));
4646
4747 atomic_uint64_t::Type ret;
......@@ -55,19 +55,19 @@ INLINE atomic_uint64_t::Type atomic_fetch_add(volatile atomic_uint64_t *ptr,
5555}
5656
5757template <>
58INLINE atomic_uint64_t::Type atomic_fetch_sub(volatile atomic_uint64_t *ptr,
58inline atomic_uint64_t::Type atomic_fetch_sub(volatile atomic_uint64_t *ptr,
5959 atomic_uint64_t::Type val,
6060 memory_order mo) {
6161 return atomic_fetch_add(ptr, -val, mo);
6262}
6363
6464template <>
65INLINE bool atomic_compare_exchange_strong(volatile atomic_uint64_t *ptr,
65inline bool atomic_compare_exchange_strong(volatile atomic_uint64_t *ptr,
6666 atomic_uint64_t::Type *cmp,
6767 atomic_uint64_t::Type xchg,
6868 memory_order mo) {
6969 DCHECK(mo &
70 (memory_order_relaxed | memory_order_releasae | memory_order_seq_cst));
70 (memory_order_relaxed | memory_order_release | memory_order_seq_cst));
7171 DCHECK(!((uptr)ptr % sizeof(*ptr)));
7272
7373 typedef atomic_uint64_t::Type Type;
......@@ -87,10 +87,10 @@ INLINE bool atomic_compare_exchange_strong(volatile atomic_uint64_t *ptr,
8787}
8888
8989template <>
90INLINE atomic_uint64_t::Type atomic_load(const volatile atomic_uint64_t *ptr,
90inline atomic_uint64_t::Type atomic_load(const volatile atomic_uint64_t *ptr,
9191 memory_order mo) {
9292 DCHECK(mo &
93 (memory_order_relaxed | memory_order_releasae | memory_order_seq_cst));
93 (memory_order_relaxed | memory_order_release | memory_order_seq_cst));
9494 DCHECK(!((uptr)ptr % sizeof(*ptr)));
9595
9696 atomic_uint64_t::Type zero = 0;
......@@ -100,10 +100,10 @@ INLINE atomic_uint64_t::Type atomic_load(const volatile atomic_uint64_t *ptr,
100100}
101101
102102template <>
103INLINE void atomic_store(volatile atomic_uint64_t *ptr, atomic_uint64_t::Type v,
103inline void atomic_store(volatile atomic_uint64_t *ptr, atomic_uint64_t::Type v,
104104 memory_order mo) {
105105 DCHECK(mo &
106 (memory_order_relaxed | memory_order_releasae | memory_order_seq_cst));
106 (memory_order_relaxed | memory_order_release | memory_order_seq_cst));
107107 DCHECK(!((uptr)ptr % sizeof(*ptr)));
108108
109109 __spin_lock(&lock.lock);
lib/tsan/sanitizer_common/sanitizer_atomic_clang_other.h+6-18
......@@ -17,12 +17,12 @@
1717namespace __sanitizer {
1818
1919
20INLINE void proc_yield(int cnt) {
20inline void proc_yield(int cnt) {
2121 __asm__ __volatile__("" ::: "memory");
2222}
2323
2424template<typename T>
25INLINE typename T::Type atomic_load(
25inline typename T::Type atomic_load(
2626 const volatile T *a, memory_order mo) {
2727 DCHECK(mo & (memory_order_relaxed | memory_order_consume
2828 | memory_order_acquire | memory_order_seq_cst));
......@@ -50,17 +50,14 @@ INLINE typename T::Type atomic_load(
5050 __sync_synchronize();
5151 }
5252 } else {
53 // 64-bit load on 32-bit platform.
54 // Gross, but simple and reliable.
55 // Assume that it is not in read-only memory.
56 v = __sync_fetch_and_add(
57 const_cast<typename T::Type volatile *>(&a->val_dont_use), 0);
53 __atomic_load(const_cast<typename T::Type volatile *>(&a->val_dont_use), &v,
54 __ATOMIC_SEQ_CST);
5855 }
5956 return v;
6057}
6158
6259template<typename T>
63INLINE void atomic_store(volatile T *a, typename T::Type v, memory_order mo) {
60inline void atomic_store(volatile T *a, typename T::Type v, memory_order mo) {
6461 DCHECK(mo & (memory_order_relaxed | memory_order_release
6562 | memory_order_seq_cst));
6663 DCHECK(!((uptr)a % sizeof(*a)));
......@@ -79,16 +76,7 @@ INLINE void atomic_store(volatile T *a, typename T::Type v, memory_order mo) {
7976 __sync_synchronize();
8077 }
8178 } else {
82 // 64-bit store on 32-bit platform.
83 // Gross, but simple and reliable.
84 typename T::Type cmp = a->val_dont_use;
85 typename T::Type cur;
86 for (;;) {
87 cur = __sync_val_compare_and_swap(&a->val_dont_use, cmp, v);
88 if (cur == cmp || cur == v)
89 break;
90 cmp = cur;
91 }
79 __atomic_store(&a->val_dont_use, &v, __ATOMIC_SEQ_CST);
9280 }
9381}
9482
lib/tsan/sanitizer_common/sanitizer_atomic_clang_x86.h+3-3
......@@ -16,7 +16,7 @@
1616
1717namespace __sanitizer {
1818
19INLINE void proc_yield(int cnt) {
19inline void proc_yield(int cnt) {
2020 __asm__ __volatile__("" ::: "memory");
2121 for (int i = 0; i < cnt; i++)
2222 __asm__ __volatile__("pause");
......@@ -24,7 +24,7 @@ INLINE void proc_yield(int cnt) {
2424}
2525
2626template<typename T>
27INLINE typename T::Type atomic_load(
27inline typename T::Type atomic_load(
2828 const volatile T *a, memory_order mo) {
2929 DCHECK(mo & (memory_order_relaxed | memory_order_consume
3030 | memory_order_acquire | memory_order_seq_cst));
......@@ -70,7 +70,7 @@ INLINE typename T::Type atomic_load(
7070}
7171
7272template<typename T>
73INLINE void atomic_store(volatile T *a, typename T::Type v, memory_order mo) {
73inline void atomic_store(volatile T *a, typename T::Type v, memory_order mo) {
7474 DCHECK(mo & (memory_order_relaxed | memory_order_release
7575 | memory_order_seq_cst));
7676 DCHECK(!((uptr)a % sizeof(*a)));
lib/tsan/sanitizer_common/sanitizer_atomic_msvc.h+18-18
......@@ -54,21 +54,21 @@ extern "C" long long _InterlockedExchangeAdd64(long long volatile *Addend,
5454
5555namespace __sanitizer {
5656
57INLINE void atomic_signal_fence(memory_order) {
57inline void atomic_signal_fence(memory_order) {
5858 _ReadWriteBarrier();
5959}
6060
61INLINE void atomic_thread_fence(memory_order) {
61inline void atomic_thread_fence(memory_order) {
6262 _mm_mfence();
6363}
6464
65INLINE void proc_yield(int cnt) {
65inline void proc_yield(int cnt) {
6666 for (int i = 0; i < cnt; i++)
6767 _mm_pause();
6868}
6969
7070template<typename T>
71INLINE typename T::Type atomic_load(
71inline typename T::Type atomic_load(
7272 const volatile T *a, memory_order mo) {
7373 DCHECK(mo & (memory_order_relaxed | memory_order_consume
7474 | memory_order_acquire | memory_order_seq_cst));
......@@ -86,7 +86,7 @@ INLINE typename T::Type atomic_load(
8686}
8787
8888template<typename T>
89INLINE void atomic_store(volatile T *a, typename T::Type v, memory_order mo) {
89inline void atomic_store(volatile T *a, typename T::Type v, memory_order mo) {
9090 DCHECK(mo & (memory_order_relaxed | memory_order_release
9191 | memory_order_seq_cst));
9292 DCHECK(!((uptr)a % sizeof(*a)));
......@@ -102,7 +102,7 @@ INLINE void atomic_store(volatile T *a, typename T::Type v, memory_order mo) {
102102 atomic_thread_fence(memory_order_seq_cst);
103103}
104104
105INLINE u32 atomic_fetch_add(volatile atomic_uint32_t *a,
105inline u32 atomic_fetch_add(volatile atomic_uint32_t *a,
106106 u32 v, memory_order mo) {
107107 (void)mo;
108108 DCHECK(!((uptr)a % sizeof(*a)));
......@@ -110,7 +110,7 @@ INLINE u32 atomic_fetch_add(volatile atomic_uint32_t *a,
110110 (long)v);
111111}
112112
113INLINE uptr atomic_fetch_add(volatile atomic_uintptr_t *a,
113inline uptr atomic_fetch_add(volatile atomic_uintptr_t *a,
114114 uptr v, memory_order mo) {
115115 (void)mo;
116116 DCHECK(!((uptr)a % sizeof(*a)));
......@@ -123,7 +123,7 @@ INLINE uptr atomic_fetch_add(volatile atomic_uintptr_t *a,
123123#endif
124124}
125125
126INLINE u32 atomic_fetch_sub(volatile atomic_uint32_t *a,
126inline u32 atomic_fetch_sub(volatile atomic_uint32_t *a,
127127 u32 v, memory_order mo) {
128128 (void)mo;
129129 DCHECK(!((uptr)a % sizeof(*a)));
......@@ -131,7 +131,7 @@ INLINE u32 atomic_fetch_sub(volatile atomic_uint32_t *a,
131131 -(long)v);
132132}
133133
134INLINE uptr atomic_fetch_sub(volatile atomic_uintptr_t *a,
134inline uptr atomic_fetch_sub(volatile atomic_uintptr_t *a,
135135 uptr v, memory_order mo) {
136136 (void)mo;
137137 DCHECK(!((uptr)a % sizeof(*a)));
......@@ -144,28 +144,28 @@ INLINE uptr atomic_fetch_sub(volatile atomic_uintptr_t *a,
144144#endif
145145}
146146
147INLINE u8 atomic_exchange(volatile atomic_uint8_t *a,
147inline u8 atomic_exchange(volatile atomic_uint8_t *a,
148148 u8 v, memory_order mo) {
149149 (void)mo;
150150 DCHECK(!((uptr)a % sizeof(*a)));
151151 return (u8)_InterlockedExchange8((volatile char*)&a->val_dont_use, v);
152152}
153153
154INLINE u16 atomic_exchange(volatile atomic_uint16_t *a,
154inline u16 atomic_exchange(volatile atomic_uint16_t *a,
155155 u16 v, memory_order mo) {
156156 (void)mo;
157157 DCHECK(!((uptr)a % sizeof(*a)));
158158 return (u16)_InterlockedExchange16((volatile short*)&a->val_dont_use, v);
159159}
160160
161INLINE u32 atomic_exchange(volatile atomic_uint32_t *a,
161inline u32 atomic_exchange(volatile atomic_uint32_t *a,
162162 u32 v, memory_order mo) {
163163 (void)mo;
164164 DCHECK(!((uptr)a % sizeof(*a)));
165165 return (u32)_InterlockedExchange((volatile long*)&a->val_dont_use, v);
166166}
167167
168INLINE bool atomic_compare_exchange_strong(volatile atomic_uint8_t *a,
168inline bool atomic_compare_exchange_strong(volatile atomic_uint8_t *a,
169169 u8 *cmp,
170170 u8 xchgv,
171171 memory_order mo) {
......@@ -191,7 +191,7 @@ INLINE bool atomic_compare_exchange_strong(volatile atomic_uint8_t *a,
191191 return false;
192192}
193193
194INLINE bool atomic_compare_exchange_strong(volatile atomic_uintptr_t *a,
194inline bool atomic_compare_exchange_strong(volatile atomic_uintptr_t *a,
195195 uptr *cmp,
196196 uptr xchg,
197197 memory_order mo) {
......@@ -204,7 +204,7 @@ INLINE bool atomic_compare_exchange_strong(volatile atomic_uintptr_t *a,
204204 return false;
205205}
206206
207INLINE bool atomic_compare_exchange_strong(volatile atomic_uint16_t *a,
207inline bool atomic_compare_exchange_strong(volatile atomic_uint16_t *a,
208208 u16 *cmp,
209209 u16 xchg,
210210 memory_order mo) {
......@@ -217,7 +217,7 @@ INLINE bool atomic_compare_exchange_strong(volatile atomic_uint16_t *a,
217217 return false;
218218}
219219
220INLINE bool atomic_compare_exchange_strong(volatile atomic_uint32_t *a,
220inline bool atomic_compare_exchange_strong(volatile atomic_uint32_t *a,
221221 u32 *cmp,
222222 u32 xchg,
223223 memory_order mo) {
......@@ -230,7 +230,7 @@ INLINE bool atomic_compare_exchange_strong(volatile atomic_uint32_t *a,
230230 return false;
231231}
232232
233INLINE bool atomic_compare_exchange_strong(volatile atomic_uint64_t *a,
233inline bool atomic_compare_exchange_strong(volatile atomic_uint64_t *a,
234234 u64 *cmp,
235235 u64 xchg,
236236 memory_order mo) {
......@@ -244,7 +244,7 @@ INLINE bool atomic_compare_exchange_strong(volatile atomic_uint64_t *a,
244244}
245245
246246template<typename T>
247INLINE bool atomic_compare_exchange_weak(volatile T *a,
247inline bool atomic_compare_exchange_weak(volatile T *a,
248248 typename T::Type *cmp,
249249 typename T::Type xchg,
250250 memory_order mo) {
lib/tsan/sanitizer_common/sanitizer_common.cpp+20-5
......@@ -37,10 +37,9 @@ void NORETURN ReportMmapFailureAndDie(uptr size, const char *mem_type,
3737 const char *mmap_type, error_t err,
3838 bool raw_report) {
3939 static int recursion_count;
40 if (SANITIZER_RTEMS || raw_report || recursion_count) {
41 // If we are on RTEMS or raw report is requested or we went into recursion,
42 // just die. The Report() and CHECK calls below may call mmap recursively
43 // and fail.
40 if (raw_report || recursion_count) {
41 // If raw report is requested or we went into recursion just die. The
42 // Report() and CHECK calls below may call mmap recursively and fail.
4443 RawWrite("ERROR: Failed to mmap\n");
4544 Die();
4645 }
......@@ -87,7 +86,7 @@ const char *StripModuleName(const char *module) {
8786void ReportErrorSummary(const char *error_message, const char *alt_tool_name) {
8887 if (!common_flags()->print_summary)
8988 return;
90 InternalScopedString buff(kMaxSummaryLength);
89 InternalScopedString buff;
9190 buff.append("SUMMARY: %s: %s",
9291 alt_tool_name ? alt_tool_name : SanitizerToolName, error_message);
9392 __sanitizer_report_error_summary(buff.data());
......@@ -274,6 +273,14 @@ uptr ReadBinaryNameCached(/*out*/char *buf, uptr buf_len) {
274273 return name_len;
275274}
276275
276uptr ReadBinaryDir(/*out*/ char *buf, uptr buf_len) {
277 ReadBinaryNameCached(buf, buf_len);
278 const char *exec_name_pos = StripModuleName(buf);
279 uptr name_len = exec_name_pos - buf;
280 buf[name_len] = '\0';
281 return name_len;
282}
283
277284#if !SANITIZER_GO
278285void PrintCmdline() {
279286 char **argv = GetArgv();
......@@ -323,6 +330,14 @@ static int InstallMallocFreeHooks(void (*malloc_hook)(const void *, uptr),
323330 return 0;
324331}
325332
333void internal_sleep(unsigned seconds) {
334 internal_usleep((u64)seconds * 1000 * 1000);
335}
336void SleepForSeconds(unsigned seconds) {
337 internal_usleep((u64)seconds * 1000 * 1000);
338}
339void SleepForMillis(unsigned millis) { internal_usleep((u64)millis * 1000); }
340
326341} // namespace __sanitizer
327342
328343using namespace __sanitizer;
lib/tsan/sanitizer_common/sanitizer_common.h+135-57
......@@ -44,7 +44,7 @@ const uptr kMaxPathLength = 4096;
4444
4545const uptr kMaxThreadStackSize = 1 << 30; // 1Gb
4646
47static const uptr kErrorMessageBufferSize = 1 << 16;
47const uptr kErrorMessageBufferSize = 1 << 16;
4848
4949// Denotes fake PC values that come from JIT/JAVA/etc.
5050// For such PC values __tsan_symbolize_external_ex() will be called.
......@@ -53,25 +53,25 @@ const u64 kExternalPCBit = 1ULL << 60;
5353extern const char *SanitizerToolName; // Can be changed by the tool.
5454
5555extern atomic_uint32_t current_verbosity;
56INLINE void SetVerbosity(int verbosity) {
56inline void SetVerbosity(int verbosity) {
5757 atomic_store(&current_verbosity, verbosity, memory_order_relaxed);
5858}
59INLINE int Verbosity() {
59inline int Verbosity() {
6060 return atomic_load(&current_verbosity, memory_order_relaxed);
6161}
6262
6363#if SANITIZER_ANDROID
64INLINE uptr GetPageSize() {
64inline uptr GetPageSize() {
6565// Android post-M sysconf(_SC_PAGESIZE) crashes if called from .preinit_array.
6666 return 4096;
6767}
68INLINE uptr GetPageSizeCached() {
68inline uptr GetPageSizeCached() {
6969 return 4096;
7070}
7171#else
7272uptr GetPageSize();
7373extern uptr PageSizeCached;
74INLINE uptr GetPageSizeCached() {
74inline uptr GetPageSizeCached() {
7575 if (!PageSizeCached)
7676 PageSizeCached = GetPageSize();
7777 return PageSizeCached;
......@@ -91,7 +91,7 @@ void GetThreadStackAndTls(bool main, uptr *stk_addr, uptr *stk_size,
9191
9292// Memory management
9393void *MmapOrDie(uptr size, const char *mem_type, bool raw_report = false);
94INLINE void *MmapOrDieQuietly(uptr size, const char *mem_type) {
94inline void *MmapOrDieQuietly(uptr size, const char *mem_type) {
9595 return MmapOrDie(size, mem_type, /*raw_report*/ true);
9696}
9797void UnmapOrDie(void *addr, uptr size);
......@@ -121,6 +121,40 @@ bool MprotectReadOnly(uptr addr, uptr size);
121121
122122void MprotectMallocZones(void *addr, int prot);
123123
124#if SANITIZER_LINUX
125// Unmap memory. Currently only used on Linux.
126void UnmapFromTo(uptr from, uptr to);
127#endif
128
129// Maps shadow_size_bytes of shadow memory and returns shadow address. It will
130// be aligned to the mmap granularity * 2^shadow_scale, or to
131// 2^min_shadow_base_alignment if that is larger. The returned address will
132// have max(2^min_shadow_base_alignment, mmap granularity) on the left, and
133// shadow_size_bytes bytes on the right, which on linux is mapped no access.
134// The high_mem_end may be updated if the original shadow size doesn't fit.
135uptr MapDynamicShadow(uptr shadow_size_bytes, uptr shadow_scale,
136 uptr min_shadow_base_alignment, uptr &high_mem_end);
137
138// Let S = max(shadow_size, num_aliases * alias_size, ring_buffer_size).
139// Reserves 2*S bytes of address space to the right of the returned address and
140// ring_buffer_size bytes to the left. The returned address is aligned to 2*S.
141// Also creates num_aliases regions of accessible memory starting at offset S
142// from the returned address. Each region has size alias_size and is backed by
143// the same physical memory.
144uptr MapDynamicShadowAndAliases(uptr shadow_size, uptr alias_size,
145 uptr num_aliases, uptr ring_buffer_size);
146
147// Reserve memory range [beg, end]. If madvise_shadow is true then apply
148// madvise (e.g. hugepages, core dumping) requested by options.
149void ReserveShadowMemoryRange(uptr beg, uptr end, const char *name,
150 bool madvise_shadow = true);
151
152// Protect size bytes of memory starting at addr. Also try to protect
153// several pages at the start of the address space as specified by
154// zero_base_shadow_start, at most up to the size or zero_base_max_shadow_start.
155void ProtectGap(uptr addr, uptr size, uptr zero_base_shadow_start,
156 uptr zero_base_max_shadow_start);
157
124158// Find an available address space.
125159uptr FindAvailableMemoryRange(uptr size, uptr alignment, uptr left_padding,
126160 uptr *largest_gap_found, uptr *max_occupied_addr);
......@@ -203,10 +237,16 @@ void SetPrintfAndReportCallback(void (*callback)(const char *));
203237// Lock sanitizer error reporting and protects against nested errors.
204238class ScopedErrorReportLock {
205239 public:
206 ScopedErrorReportLock();
207 ~ScopedErrorReportLock();
240 ScopedErrorReportLock() ACQUIRE(mutex_) { Lock(); }
241 ~ScopedErrorReportLock() RELEASE(mutex_) { Unlock(); }
208242
209 static void CheckLocked();
243 static void Lock() ACQUIRE(mutex_);
244 static void Unlock() RELEASE(mutex_);
245 static void CheckLocked() CHECK_LOCKED(mutex_);
246
247 private:
248 static atomic_uintptr_t reporting_thread_;
249 static StaticSpinMutex mutex_;
210250};
211251
212252extern uptr stoptheworld_tracer_pid;
......@@ -223,13 +263,13 @@ const char *StripModuleName(const char *module);
223263// OS
224264uptr ReadBinaryName(/*out*/char *buf, uptr buf_len);
225265uptr ReadBinaryNameCached(/*out*/char *buf, uptr buf_len);
266uptr ReadBinaryDir(/*out*/ char *buf, uptr buf_len);
226267uptr ReadLongProcessName(/*out*/ char *buf, uptr buf_len);
227268const char *GetProcessName();
228269void UpdateProcessName();
229270void CacheBinaryName();
230271void DisableCoreDumperIfNecessary();
231272void DumpProcessMap();
232void PrintModuleMap();
233273const char *GetEnv(const char *name);
234274bool SetEnv(const char *name, const char *value);
235275
......@@ -254,8 +294,8 @@ void InitTlsSize();
254294uptr GetTlsSize();
255295
256296// Other
257void SleepForSeconds(int seconds);
258void SleepForMillis(int millis);
297void SleepForSeconds(unsigned seconds);
298void SleepForMillis(unsigned millis);
259299u64 NanoTime();
260300u64 MonotonicNanoTime();
261301int Atexit(void (*function)(void));
......@@ -270,8 +310,8 @@ void NORETURN ReportMmapFailureAndDie(uptr size, const char *mem_type,
270310 const char *mmap_type, error_t err,
271311 bool raw_report = false);
272312
273// Specific tools may override behavior of "Die" and "CheckFailed" functions
274// to do tool-specific job.
313// Specific tools may override behavior of "Die" function to do tool-specific
314// job.
275315typedef void (*DieCallbackType)(void);
276316
277317// It's possible to add several callbacks that would be run when "Die" is
......@@ -283,9 +323,7 @@ bool RemoveDieCallback(DieCallbackType callback);
283323
284324void SetUserDieCallback(DieCallbackType callback);
285325
286typedef void (*CheckFailedCallbackType)(const char *, int, const char *,
287 u64, u64);
288void SetCheckFailedCallback(CheckFailedCallbackType callback);
326void SetCheckUnwindCallback(void (*callback)());
289327
290328// Callback will be called if soft_rss_limit_mb is given and the limit is
291329// exceeded (exceeded==true) or if rss went down below the limit
......@@ -319,8 +357,6 @@ void ReportDeadlySignal(const SignalContext &sig, u32 tid,
319357void SetAlternateSignalStack();
320358void UnsetAlternateSignalStack();
321359
322// We don't want a summary too long.
323const int kMaxSummaryLength = 1024;
324360// Construct a one-line string:
325361// SUMMARY: SanitizerToolName: error_message
326362// and pass it to __sanitizer_report_error_summary.
......@@ -349,7 +385,7 @@ unsigned char _BitScanReverse64(unsigned long *index, unsigned __int64 mask);
349385}
350386#endif
351387
352INLINE uptr MostSignificantSetBitIndex(uptr x) {
388inline uptr MostSignificantSetBitIndex(uptr x) {
353389 CHECK_NE(x, 0U);
354390 unsigned long up;
355391#if !SANITIZER_WINDOWS || defined(__clang__) || defined(__GNUC__)
......@@ -366,7 +402,7 @@ INLINE uptr MostSignificantSetBitIndex(uptr x) {
366402 return up;
367403}
368404
369INLINE uptr LeastSignificantSetBitIndex(uptr x) {
405inline uptr LeastSignificantSetBitIndex(uptr x) {
370406 CHECK_NE(x, 0U);
371407 unsigned long up;
372408#if !SANITIZER_WINDOWS || defined(__clang__) || defined(__GNUC__)
......@@ -383,11 +419,11 @@ INLINE uptr LeastSignificantSetBitIndex(uptr x) {
383419 return up;
384420}
385421
386INLINE bool IsPowerOfTwo(uptr x) {
422inline bool IsPowerOfTwo(uptr x) {
387423 return (x & (x - 1)) == 0;
388424}
389425
390INLINE uptr RoundUpToPowerOfTwo(uptr size) {
426inline uptr RoundUpToPowerOfTwo(uptr size) {
391427 CHECK(size);
392428 if (IsPowerOfTwo(size)) return size;
393429
......@@ -397,28 +433,34 @@ INLINE uptr RoundUpToPowerOfTwo(uptr size) {
397433 return 1ULL << (up + 1);
398434}
399435
400INLINE uptr RoundUpTo(uptr size, uptr boundary) {
436inline uptr RoundUpTo(uptr size, uptr boundary) {
401437 RAW_CHECK(IsPowerOfTwo(boundary));
402438 return (size + boundary - 1) & ~(boundary - 1);
403439}
404440
405INLINE uptr RoundDownTo(uptr x, uptr boundary) {
441inline uptr RoundDownTo(uptr x, uptr boundary) {
406442 return x & ~(boundary - 1);
407443}
408444
409INLINE bool IsAligned(uptr a, uptr alignment) {
445inline bool IsAligned(uptr a, uptr alignment) {
410446 return (a & (alignment - 1)) == 0;
411447}
412448
413INLINE uptr Log2(uptr x) {
449inline uptr Log2(uptr x) {
414450 CHECK(IsPowerOfTwo(x));
415451 return LeastSignificantSetBitIndex(x);
416452}
417453
418454// Don't use std::min, std::max or std::swap, to minimize dependency
419455// on libstdc++.
420template<class T> T Min(T a, T b) { return a < b ? a : b; }
421template<class T> T Max(T a, T b) { return a > b ? a : b; }
456template <class T>
457constexpr T Min(T a, T b) {
458 return a < b ? a : b;
459}
460template <class T>
461constexpr T Max(T a, T b) {
462 return a > b ? a : b;
463}
422464template<class T> void Swap(T& a, T& b) {
423465 T tmp = a;
424466 a = b;
......@@ -426,14 +468,14 @@ template<class T> void Swap(T& a, T& b) {
426468}
427469
428470// Char handling
429INLINE bool IsSpace(int c) {
471inline bool IsSpace(int c) {
430472 return (c == ' ') || (c == '\n') || (c == '\t') ||
431473 (c == '\f') || (c == '\r') || (c == '\v');
432474}
433INLINE bool IsDigit(int c) {
475inline bool IsDigit(int c) {
434476 return (c >= '0') && (c <= '9');
435477}
436INLINE int ToLower(int c) {
478inline int ToLower(int c) {
437479 return (c >= 'A' && c <= 'Z') ? (c + 'a' - 'A') : c;
438480}
439481
......@@ -443,6 +485,7 @@ INLINE int ToLower(int c) {
443485template<typename T>
444486class InternalMmapVectorNoCtor {
445487 public:
488 using value_type = T;
446489 void Initialize(uptr initial_capacity) {
447490 capacity_bytes_ = 0;
448491 size_ = 0;
......@@ -566,21 +609,21 @@ class InternalMmapVector : public InternalMmapVectorNoCtor<T> {
566609 InternalMmapVector &operator=(InternalMmapVector &&) = delete;
567610};
568611
569class InternalScopedString : public InternalMmapVector<char> {
612class InternalScopedString {
570613 public:
571 explicit InternalScopedString(uptr max_length)
572 : InternalMmapVector<char>(max_length), length_(0) {
573 (*this)[0] = '\0';
574 }
575 uptr length() { return length_; }
614 InternalScopedString() : buffer_(1) { buffer_[0] = '\0'; }
615
616 uptr length() const { return buffer_.size() - 1; }
576617 void clear() {
577 (*this)[0] = '\0';
578 length_ = 0;
618 buffer_.resize(1);
619 buffer_[0] = '\0';
579620 }
580621 void append(const char *format, ...);
622 const char *data() const { return buffer_.data(); }
623 char *data() { return buffer_.data(); }
581624
582625 private:
583 uptr length_;
626 InternalMmapVector<char> buffer_;
584627};
585628
586629template <class T>
......@@ -627,9 +670,13 @@ void Sort(T *v, uptr size, Compare comp = {}) {
627670
628671// Works like std::lower_bound: finds the first element that is not less
629672// than the val.
630template <class Container, class Value, class Compare>
631uptr InternalLowerBound(const Container &v, uptr first, uptr last,
632 const Value &val, Compare comp) {
673template <class Container,
674 class Compare = CompareLess<typename Container::value_type>>
675uptr InternalLowerBound(const Container &v,
676 const typename Container::value_type &val,
677 Compare comp = {}) {
678 uptr first = 0;
679 uptr last = v.size();
633680 while (last > first) {
634681 uptr mid = (first + last) / 2;
635682 if (comp(v[mid], val))
......@@ -649,9 +696,31 @@ enum ModuleArch {
649696 kModuleArchARMV7,
650697 kModuleArchARMV7S,
651698 kModuleArchARMV7K,
652 kModuleArchARM64
699 kModuleArchARM64,
700 kModuleArchRISCV64
653701};
654702
703// Sorts and removes duplicates from the container.
704template <class Container,
705 class Compare = CompareLess<typename Container::value_type>>
706void SortAndDedup(Container &v, Compare comp = {}) {
707 Sort(v.data(), v.size(), comp);
708 uptr size = v.size();
709 if (size < 2)
710 return;
711 uptr last = 0;
712 for (uptr i = 1; i < size; ++i) {
713 if (comp(v[last], v[i])) {
714 ++last;
715 if (last != i)
716 v[last] = v[i];
717 } else {
718 CHECK(!comp(v[i], v[last]));
719 }
720 }
721 v.resize(last + 1);
722}
723
655724// Opens the file 'file_name" and reads up to 'max_len' bytes.
656725// The resulting buffer is mmaped and stored in '*buff'.
657726// Returns true if file was successfully opened and read.
......@@ -693,6 +762,8 @@ inline const char *ModuleArchToString(ModuleArch arch) {
693762 return "armv7k";
694763 case kModuleArchARM64:
695764 return "arm64";
765 case kModuleArchRISCV64:
766 return "riscv64";
696767 }
697768 CHECK(0 && "Invalid module arch");
698769 return "";
......@@ -815,15 +886,15 @@ void WriteToSyslog(const char *buffer);
815886#if SANITIZER_MAC || SANITIZER_WIN_TRACE
816887void LogFullErrorReport(const char *buffer);
817888#else
818INLINE void LogFullErrorReport(const char *buffer) {}
889inline void LogFullErrorReport(const char *buffer) {}
819890#endif
820891
821892#if SANITIZER_LINUX || SANITIZER_MAC
822893void WriteOneLineToSyslog(const char *s);
823894void LogMessageOnPrintf(const char *str);
824895#else
825INLINE void WriteOneLineToSyslog(const char *s) {}
826INLINE void LogMessageOnPrintf(const char *str) {}
896inline void WriteOneLineToSyslog(const char *s) {}
897inline void LogMessageOnPrintf(const char *str) {}
827898#endif
828899
829900#if SANITIZER_LINUX || SANITIZER_WIN_TRACE
......@@ -831,21 +902,21 @@ INLINE void LogMessageOnPrintf(const char *str) {}
831902void AndroidLogInit();
832903void SetAbortMessage(const char *);
833904#else
834INLINE void AndroidLogInit() {}
905inline void AndroidLogInit() {}
835906// FIXME: MacOS implementation could use CRSetCrashLogMessage.
836INLINE void SetAbortMessage(const char *) {}
907inline void SetAbortMessage(const char *) {}
837908#endif
838909
839910#if SANITIZER_ANDROID
840911void SanitizerInitializeUnwinder();
841912AndroidApiLevel AndroidGetApiLevel();
842913#else
843INLINE void AndroidLogWrite(const char *buffer_unused) {}
844INLINE void SanitizerInitializeUnwinder() {}
845INLINE AndroidApiLevel AndroidGetApiLevel() { return ANDROID_NOT_ANDROID; }
914inline void AndroidLogWrite(const char *buffer_unused) {}
915inline void SanitizerInitializeUnwinder() {}
916inline AndroidApiLevel AndroidGetApiLevel() { return ANDROID_NOT_ANDROID; }
846917#endif
847918
848INLINE uptr GetPthreadDestructorIterations() {
919inline uptr GetPthreadDestructorIterations() {
849920#if SANITIZER_ANDROID
850921 return (AndroidGetApiLevel() == ANDROID_LOLLIPOP_MR1) ? 8 : 4;
851922#elif SANITIZER_POSIX
......@@ -951,7 +1022,7 @@ RunOnDestruction<Fn> at_scope_exit(Fn fn) {
9511022#if SANITIZER_LINUX && SANITIZER_S390_64
9521023void AvoidCVE_2016_2143();
9531024#else
954INLINE void AvoidCVE_2016_2143() {}
1025inline void AvoidCVE_2016_2143() {}
9551026#endif
9561027
9571028struct StackDepotStats {
......@@ -972,7 +1043,7 @@ bool GetRandom(void *buffer, uptr length, bool blocking = true);
9721043// Returns the number of logical processors on the system.
9731044u32 GetNumberOfCPUs();
9741045extern u32 NumberOfCPUsCached;
975INLINE u32 GetNumberOfCPUsCached() {
1046inline u32 GetNumberOfCPUsCached() {
9761047 if (!NumberOfCPUsCached)
9771048 NumberOfCPUsCached = GetNumberOfCPUs();
9781049 return NumberOfCPUsCached;
......@@ -992,6 +1063,13 @@ class ArrayRef {
9921063 T *end_ = nullptr;
9931064};
9941065
1066#define PRINTF_128(v) \
1067 (*((u8 *)&v + 0)), (*((u8 *)&v + 1)), (*((u8 *)&v + 2)), (*((u8 *)&v + 3)), \
1068 (*((u8 *)&v + 4)), (*((u8 *)&v + 5)), (*((u8 *)&v + 6)), \
1069 (*((u8 *)&v + 7)), (*((u8 *)&v + 8)), (*((u8 *)&v + 9)), \
1070 (*((u8 *)&v + 10)), (*((u8 *)&v + 11)), (*((u8 *)&v + 12)), \
1071 (*((u8 *)&v + 13)), (*((u8 *)&v + 14)), (*((u8 *)&v + 15))
1072
9951073} // namespace __sanitizer
9961074
9971075inline void *operator new(__sanitizer::operator_new_size_type size,
lib/tsan/sanitizer_common/sanitizer_common_interceptors.inc+273-39
......@@ -134,11 +134,11 @@ extern const short *_tolower_tab_;
134134
135135// Platform-specific options.
136136#if SANITIZER_MAC
137#define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE false
137#define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE 0
138138#elif SANITIZER_WINDOWS64
139#define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE false
139#define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE 0
140140#else
141#define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE true
141#define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE 1
142142#endif // SANITIZER_MAC
143143
144144#ifndef COMMON_INTERCEPTOR_INITIALIZE_RANGE
......@@ -239,6 +239,23 @@ extern const short *_tolower_tab_;
239239 COMMON_INTERCEPT_FUNCTION(fn)
240240#endif
241241
242#if SANITIZER_GLIBC
243// If we could not find the versioned symbol, fall back to an unversioned
244// lookup. This is needed to work around a GLibc bug that causes dlsym
245// with RTLD_NEXT to return the oldest versioned symbol.
246// See https://sourceware.org/bugzilla/show_bug.cgi?id=14932.
247// For certain symbols (e.g. regexec) we have to perform a versioned lookup,
248// but that versioned symbol will only exist for architectures where the
249// oldest Glibc version pre-dates support for that architecture.
250// For example, regexec@GLIBC_2.3.4 exists on x86_64, but not RISC-V.
251// See also https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98920.
252#define COMMON_INTERCEPT_FUNCTION_GLIBC_VER_MIN(fn, ver) \
253 COMMON_INTERCEPT_FUNCTION_VER_UNVERSIONED_FALLBACK(fn, ver)
254#else
255#define COMMON_INTERCEPT_FUNCTION_GLIBC_VER_MIN(fn, ver) \
256 COMMON_INTERCEPT_FUNCTION(fn)
257#endif
258
242259#ifndef COMMON_INTERCEPTOR_MEMSET_IMPL
243260#define COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, dst, v, size) \
244261 { \
......@@ -445,8 +462,10 @@ INTERCEPTOR(int, strcmp, const char *s1, const char *s2) {
445462 c2 = (unsigned char)s2[i];
446463 if (c1 != c2 || c1 == '\0') break;
447464 }
448 COMMON_INTERCEPTOR_READ_STRING(ctx, s1, i + 1);
449 COMMON_INTERCEPTOR_READ_STRING(ctx, s2, i + 1);
465 if (common_flags()->intercept_strcmp) {
466 COMMON_INTERCEPTOR_READ_STRING(ctx, s1, i + 1);
467 COMMON_INTERCEPTOR_READ_STRING(ctx, s2, i + 1);
468 }
450469 int result = CharCmpX(c1, c2);
451470 CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcmp, GET_CALLER_PC(), s1,
452471 s2, result);
......@@ -804,11 +823,11 @@ INTERCEPTOR(void *, memcpy, void *dst, const void *src, uptr size) {
804823 // N.B.: If we switch this to internal_ we'll have to use internal_memmove
805824 // due to memcpy being an alias of memmove on OS X.
806825 void *ctx;
807 if (PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE) {
826#if PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE
808827 COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, dst, src, size);
809 } else {
828#else
810829 COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, dst, src, size);
811 }
830#endif
812831}
813832
814833#define INIT_MEMCPY \
......@@ -938,6 +957,7 @@ INTERCEPTOR(double, frexp, double x, int *exp) {
938957 // Assuming frexp() always writes to |exp|.
939958 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));
940959 double res = REAL(frexp)(x, exp);
960 COMMON_INTERCEPTOR_INITIALIZE_RANGE(exp, sizeof(*exp));
941961 return res;
942962}
943963
......@@ -950,22 +970,18 @@ INTERCEPTOR(double, frexp, double x, int *exp) {
950970INTERCEPTOR(float, frexpf, float x, int *exp) {
951971 void *ctx;
952972 COMMON_INTERCEPTOR_ENTER(ctx, frexpf, x, exp);
953 // FIXME: under ASan the call below may write to freed memory and corrupt
954 // its metadata. See
955 // https://github.com/google/sanitizers/issues/321.
956 float res = REAL(frexpf)(x, exp);
957973 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));
974 float res = REAL(frexpf)(x, exp);
975 COMMON_INTERCEPTOR_INITIALIZE_RANGE(exp, sizeof(*exp));
958976 return res;
959977}
960978
961979INTERCEPTOR(long double, frexpl, long double x, int *exp) {
962980 void *ctx;
963981 COMMON_INTERCEPTOR_ENTER(ctx, frexpl, x, exp);
964 // FIXME: under ASan the call below may write to freed memory and corrupt
965 // its metadata. See
966 // https://github.com/google/sanitizers/issues/321.
967 long double res = REAL(frexpl)(x, exp);
968982 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));
983 long double res = REAL(frexpl)(x, exp);
984 COMMON_INTERCEPTOR_INITIALIZE_RANGE(exp, sizeof(*exp));
969985 return res;
970986}
971987
......@@ -1862,7 +1878,7 @@ UNUSED static void unpoison_passwd(void *ctx, __sanitizer_passwd *pwd) {
18621878 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd->pw_gecos,
18631879 REAL(strlen)(pwd->pw_gecos) + 1);
18641880#endif
1865#if SANITIZER_MAC || SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_OPENBSD
1881#if SANITIZER_MAC || SANITIZER_FREEBSD || SANITIZER_NETBSD
18661882 if (pwd->pw_class)
18671883 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd->pw_class,
18681884 REAL(strlen)(pwd->pw_class) + 1);
......@@ -2176,6 +2192,7 @@ INTERCEPTOR(int, clock_gettime, u32 clk_id, void *tp) {
21762192 }
21772193 return res;
21782194}
2195#if SANITIZER_GLIBC
21792196namespace __sanitizer {
21802197extern "C" {
21812198int real_clock_gettime(u32 clk_id, void *tp) {
......@@ -2185,6 +2202,7 @@ int real_clock_gettime(u32 clk_id, void *tp) {
21852202}
21862203} // extern "C"
21872204} // namespace __sanitizer
2205#endif
21882206INTERCEPTOR(int, clock_settime, u32 clk_id, const void *tp) {
21892207 void *ctx;
21902208 COMMON_INTERCEPTOR_ENTER(ctx, clock_settime, clk_id, tp);
......@@ -3336,7 +3354,7 @@ INTERCEPTOR(char *, setlocale, int category, char *locale) {
33363354 COMMON_INTERCEPTOR_READ_RANGE(ctx, locale, REAL(strlen)(locale) + 1);
33373355 char *res = REAL(setlocale)(category, locale);
33383356 if (res) {
3339 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
3357 COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1);
33403358 unpoison_ctype_arrays(ctx);
33413359 }
33423360 return res;
......@@ -3748,7 +3766,7 @@ INTERCEPTOR(char *, strerror, int errnum) {
37483766// static storage.
37493767#if ((_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && !_GNU_SOURCE) || \
37503768 SANITIZER_MAC || SANITIZER_ANDROID || SANITIZER_NETBSD || \
3751 SANITIZER_FREEBSD || SANITIZER_OPENBSD
3769 SANITIZER_FREEBSD
37523770// POSIX version. Spec is not clear on whether buf is NULL-terminated.
37533771// At least on OSX, buf contents are valid even when the call fails.
37543772INTERCEPTOR(int, strerror_r, int errnum, char *buf, SIZE_T buflen) {
......@@ -4011,7 +4029,7 @@ INTERCEPTOR(int, sigwait, __sanitizer_sigset_t *set, int *sig) {
40114029 // FIXME: under ASan the call below may write to freed memory and corrupt
40124030 // its metadata. See
40134031 // https://github.com/google/sanitizers/issues/321.
4014 int res = REAL(sigwait)(set, sig);
4032 int res = COMMON_INTERCEPTOR_BLOCK_REAL(sigwait)(set, sig);
40154033 if (!res && sig) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sig, sizeof(*sig));
40164034 return res;
40174035}
......@@ -4028,7 +4046,7 @@ INTERCEPTOR(int, sigwaitinfo, __sanitizer_sigset_t *set, void *info) {
40284046 // FIXME: under ASan the call below may write to freed memory and corrupt
40294047 // its metadata. See
40304048 // https://github.com/google/sanitizers/issues/321.
4031 int res = REAL(sigwaitinfo)(set, info);
4049 int res = COMMON_INTERCEPTOR_BLOCK_REAL(sigwaitinfo)(set, info);
40324050 if (res > 0 && info) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, siginfo_t_sz);
40334051 return res;
40344052}
......@@ -4047,7 +4065,7 @@ INTERCEPTOR(int, sigtimedwait, __sanitizer_sigset_t *set, void *info,
40474065 // FIXME: under ASan the call below may write to freed memory and corrupt
40484066 // its metadata. See
40494067 // https://github.com/google/sanitizers/issues/321.
4050 int res = REAL(sigtimedwait)(set, info, timeout);
4068 int res = COMMON_INTERCEPTOR_BLOCK_REAL(sigtimedwait)(set, info, timeout);
40514069 if (res > 0 && info) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, siginfo_t_sz);
40524070 return res;
40534071}
......@@ -4085,6 +4103,41 @@ INTERCEPTOR(int, sigfillset, __sanitizer_sigset_t *set) {
40854103#define INIT_SIGSETOPS
40864104#endif
40874105
4106#if SANITIZER_INTERCEPT_SIGSET_LOGICOPS
4107INTERCEPTOR(int, sigandset, __sanitizer_sigset_t *dst,
4108 __sanitizer_sigset_t *src1, __sanitizer_sigset_t *src2) {
4109 void *ctx;
4110 COMMON_INTERCEPTOR_ENTER(ctx, sigandset, dst, src1, src2);
4111 if (src1)
4112 COMMON_INTERCEPTOR_READ_RANGE(ctx, src1, sizeof(*src1));
4113 if (src2)
4114 COMMON_INTERCEPTOR_READ_RANGE(ctx, src2, sizeof(*src2));
4115 int res = REAL(sigandset)(dst, src1, src2);
4116 if (!res && dst)
4117 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sizeof(*dst));
4118 return res;
4119}
4120
4121INTERCEPTOR(int, sigorset, __sanitizer_sigset_t *dst,
4122 __sanitizer_sigset_t *src1, __sanitizer_sigset_t *src2) {
4123 void *ctx;
4124 COMMON_INTERCEPTOR_ENTER(ctx, sigorset, dst, src1, src2);
4125 if (src1)
4126 COMMON_INTERCEPTOR_READ_RANGE(ctx, src1, sizeof(*src1));
4127 if (src2)
4128 COMMON_INTERCEPTOR_READ_RANGE(ctx, src2, sizeof(*src2));
4129 int res = REAL(sigorset)(dst, src1, src2);
4130 if (!res && dst)
4131 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sizeof(*dst));
4132 return res;
4133}
4134#define INIT_SIGSET_LOGICOPS \
4135 COMMON_INTERCEPT_FUNCTION(sigandset); \
4136 COMMON_INTERCEPT_FUNCTION(sigorset);
4137#else
4138#define INIT_SIGSET_LOGICOPS
4139#endif
4140
40884141#if SANITIZER_INTERCEPT_SIGPENDING
40894142INTERCEPTOR(int, sigpending, __sanitizer_sigset_t *set) {
40904143 void *ctx;
......@@ -4838,6 +4891,34 @@ INTERCEPTOR(char *, tmpnam_r, char *s) {
48384891#define INIT_TMPNAM_R
48394892#endif
48404893
4894#if SANITIZER_INTERCEPT_PTSNAME
4895INTERCEPTOR(char *, ptsname, int fd) {
4896 void *ctx;
4897 COMMON_INTERCEPTOR_ENTER(ctx, ptsname, fd);
4898 char *res = REAL(ptsname)(fd);
4899 if (res != nullptr)
4900 COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1);
4901 return res;
4902}
4903#define INIT_PTSNAME COMMON_INTERCEPT_FUNCTION(ptsname);
4904#else
4905#define INIT_PTSNAME
4906#endif
4907
4908#if SANITIZER_INTERCEPT_PTSNAME_R
4909INTERCEPTOR(int, ptsname_r, int fd, char *name, SIZE_T namesize) {
4910 void *ctx;
4911 COMMON_INTERCEPTOR_ENTER(ctx, ptsname_r, fd, name, namesize);
4912 int res = REAL(ptsname_r)(fd, name, namesize);
4913 if (res == 0)
4914 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, REAL(strlen)(name) + 1);
4915 return res;
4916}
4917#define INIT_PTSNAME_R COMMON_INTERCEPT_FUNCTION(ptsname_r);
4918#else
4919#define INIT_PTSNAME_R
4920#endif
4921
48414922#if SANITIZER_INTERCEPT_TTYNAME
48424923INTERCEPTOR(char *, ttyname, int fd) {
48434924 void *ctx;
......@@ -5219,6 +5300,12 @@ INTERCEPTOR(__sanitizer_clock_t, times, void *tms) {
52195300#define INIT_TIMES
52205301#endif
52215302
5303#if SANITIZER_S390 && \
5304 (SANITIZER_INTERCEPT_TLS_GET_ADDR || SANITIZER_INTERCEPT_TLS_GET_OFFSET)
5305extern "C" uptr __tls_get_offset_wrapper(void *arg, uptr (*fn)(void *arg));
5306DEFINE_REAL(uptr, __tls_get_offset, void *arg)
5307#endif
5308
52225309#if SANITIZER_INTERCEPT_TLS_GET_ADDR
52235310#if !SANITIZER_S390
52245311#define INIT_TLS_GET_ADDR COMMON_INTERCEPT_FUNCTION(__tls_get_addr)
......@@ -5258,11 +5345,7 @@ void *__tls_get_addr_opt(void *arg);
52585345// descriptor offset as an argument instead of a pointer. GOT address
52595346// is passed in r12, so it's necessary to write it in assembly. This is
52605347// the function used by the compiler.
5261extern "C" uptr __tls_get_offset_wrapper(void *arg, uptr (*fn)(void *arg));
52625348#define INIT_TLS_GET_ADDR COMMON_INTERCEPT_FUNCTION(__tls_get_offset)
5263DEFINE_REAL(uptr, __tls_get_offset, void *arg)
5264extern "C" uptr __tls_get_offset(void *arg);
5265extern "C" uptr __interceptor___tls_get_offset(void *arg);
52665349INTERCEPTOR(uptr, __tls_get_addr_internal, void *arg) {
52675350 void *ctx;
52685351 COMMON_INTERCEPTOR_ENTER(ctx, __tls_get_addr_internal, arg);
......@@ -5278,6 +5361,15 @@ INTERCEPTOR(uptr, __tls_get_addr_internal, void *arg) {
52785361 }
52795362 return res;
52805363}
5364#endif // SANITIZER_S390
5365#else
5366#define INIT_TLS_GET_ADDR
5367#endif
5368
5369#if SANITIZER_S390 && \
5370 (SANITIZER_INTERCEPT_TLS_GET_ADDR || SANITIZER_INTERCEPT_TLS_GET_OFFSET)
5371extern "C" uptr __tls_get_offset(void *arg);
5372extern "C" uptr __interceptor___tls_get_offset(void *arg);
52815373// We need a hidden symbol aliasing the above, so that we can jump
52825374// directly to it from the assembly below.
52835375extern "C" __attribute__((alias("__interceptor___tls_get_addr_internal"),
......@@ -5316,9 +5408,6 @@ asm(
53165408 "br %r3\n"
53175409 ".size __tls_get_offset_wrapper, .-__tls_get_offset_wrapper\n"
53185410);
5319#endif // SANITIZER_S390
5320#else
5321#define INIT_TLS_GET_ADDR
53225411#endif
53235412
53245413#if SANITIZER_INTERCEPT_LISTXATTR
......@@ -5809,6 +5898,79 @@ INTERCEPTOR(int, xdr_string, __sanitizer_XDR *xdrs, char **p,
58095898#define INIT_XDR
58105899#endif // SANITIZER_INTERCEPT_XDR
58115900
5901#if SANITIZER_INTERCEPT_XDRREC
5902typedef int (*xdrrec_cb)(char*, char*, int);
5903struct XdrRecWrapper {
5904 char *handle;
5905 xdrrec_cb rd, wr;
5906};
5907typedef AddrHashMap<XdrRecWrapper *, 11> XdrRecWrapMap;
5908static XdrRecWrapMap *xdrrec_wrap_map;
5909
5910static int xdrrec_wr_wrap(char *handle, char *buf, int count) {
5911 COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
5912 COMMON_INTERCEPTOR_INITIALIZE_RANGE(buf, count);
5913 XdrRecWrapper *wrap = (XdrRecWrapper *)handle;
5914 return wrap->wr(wrap->handle, buf, count);
5915}
5916
5917static int xdrrec_rd_wrap(char *handle, char *buf, int count) {
5918 COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
5919 XdrRecWrapper *wrap = (XdrRecWrapper *)handle;
5920 return wrap->rd(wrap->handle, buf, count);
5921}
5922
5923// This doesn't apply to the solaris version as it has a different function
5924// signature.
5925INTERCEPTOR(void, xdrrec_create, __sanitizer_XDR *xdr, unsigned sndsize,
5926 unsigned rcvsize, char *handle, int (*rd)(char*, char*, int),
5927 int (*wr)(char*, char*, int)) {
5928 void *ctx;
5929 COMMON_INTERCEPTOR_ENTER(ctx, xdrrec_create, xdr, sndsize, rcvsize,
5930 handle, rd, wr);
5931 COMMON_INTERCEPTOR_READ_RANGE(ctx, &xdr->x_op, sizeof xdr->x_op);
5932
5933 // We can't allocate a wrapper on the stack, as the handle is used outside
5934 // this stack frame. So we put it on the heap, and keep track of it with
5935 // the HashMap (keyed by x_private). When we later need to xdr_destroy,
5936 // we can index the map, free the wrapper, and then clean the map entry.
5937 XdrRecWrapper *wrap_data =
5938 (XdrRecWrapper *)InternalAlloc(sizeof(XdrRecWrapper));
5939 wrap_data->handle = handle;
5940 wrap_data->rd = rd;
5941 wrap_data->wr = wr;
5942 if (wr)
5943 wr = xdrrec_wr_wrap;
5944 if (rd)
5945 rd = xdrrec_rd_wrap;
5946 handle = (char *)wrap_data;
5947
5948 REAL(xdrrec_create)(xdr, sndsize, rcvsize, handle, rd, wr);
5949 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, xdr, sizeof *xdr);
5950
5951 XdrRecWrapMap::Handle wrap(xdrrec_wrap_map, xdr->x_private, false, true);
5952 *wrap = wrap_data;
5953}
5954
5955// We have to intercept this to be able to free wrapper memory;
5956// otherwise it's not necessary.
5957INTERCEPTOR(void, xdr_destroy, __sanitizer_XDR *xdr) {
5958 void *ctx;
5959 COMMON_INTERCEPTOR_ENTER(ctx, xdr_destroy, xdr);
5960
5961 XdrRecWrapMap::Handle wrap(xdrrec_wrap_map, xdr->x_private, true);
5962 InternalFree(*wrap);
5963 REAL(xdr_destroy)(xdr);
5964}
5965#define INIT_XDRREC_LINUX \
5966 static u64 xdrrec_wrap_mem[sizeof(XdrRecWrapMap) / sizeof(u64) + 1]; \
5967 xdrrec_wrap_map = new ((void *)&xdrrec_wrap_mem) XdrRecWrapMap(); \
5968 COMMON_INTERCEPT_FUNCTION(xdrrec_create); \
5969 COMMON_INTERCEPT_FUNCTION(xdr_destroy);
5970#else
5971#define INIT_XDRREC_LINUX
5972#endif
5973
58125974#if SANITIZER_INTERCEPT_TSEARCH
58135975INTERCEPTOR(void *, tsearch, void *key, void **rootp,
58145976 int (*compar)(const void *, const void *)) {
......@@ -5840,6 +6002,9 @@ void unpoison_file(__sanitizer_FILE *fp) {
58406002 if (fp->_IO_read_base && fp->_IO_read_base < fp->_IO_read_end)
58416003 COMMON_INTERCEPTOR_INITIALIZE_RANGE(fp->_IO_read_base,
58426004 fp->_IO_read_end - fp->_IO_read_base);
6005 if (fp->_IO_write_base && fp->_IO_write_base < fp->_IO_write_end)
6006 COMMON_INTERCEPTOR_INITIALIZE_RANGE(fp->_IO_write_base,
6007 fp->_IO_write_end - fp->_IO_write_base);
58436008#endif
58446009#endif // SANITIZER_HAS_STRUCT_FILE
58456010}
......@@ -5939,6 +6104,40 @@ INTERCEPTOR(__sanitizer_FILE *, freopen, const char *path, const char *mode,
59396104#define INIT_FOPEN
59406105#endif
59416106
6107#if SANITIZER_INTERCEPT_FLOPEN
6108INTERCEPTOR(int, flopen, const char *path, int flags, ...) {
6109 void *ctx;
6110 va_list ap;
6111 va_start(ap, flags);
6112 u16 mode = static_cast<u16>(va_arg(ap, u32));
6113 va_end(ap);
6114 COMMON_INTERCEPTOR_ENTER(ctx, flopen, path, flags, mode);
6115 if (path) {
6116 COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
6117 }
6118 return REAL(flopen)(path, flags, mode);
6119}
6120
6121INTERCEPTOR(int, flopenat, int dirfd, const char *path, int flags, ...) {
6122 void *ctx;
6123 va_list ap;
6124 va_start(ap, flags);
6125 u16 mode = static_cast<u16>(va_arg(ap, u32));
6126 va_end(ap);
6127 COMMON_INTERCEPTOR_ENTER(ctx, flopen, path, flags, mode);
6128 if (path) {
6129 COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
6130 }
6131 return REAL(flopenat)(dirfd, path, flags, mode);
6132}
6133
6134#define INIT_FLOPEN \
6135 COMMON_INTERCEPT_FUNCTION(flopen); \
6136 COMMON_INTERCEPT_FUNCTION(flopenat);
6137#else
6138#define INIT_FLOPEN
6139#endif
6140
59426141#if SANITIZER_INTERCEPT_FOPEN64
59436142INTERCEPTOR(__sanitizer_FILE *, fopen64, const char *path, const char *mode) {
59446143 void *ctx;
......@@ -6066,6 +6265,8 @@ INTERCEPTOR(void, _obstack_newchunk, __sanitizer_obstack *obstack, int length) {
60666265INTERCEPTOR(int, fflush, __sanitizer_FILE *fp) {
60676266 void *ctx;
60686267 COMMON_INTERCEPTOR_ENTER(ctx, fflush, fp);
6268 if (fp)
6269 unpoison_file(fp);
60696270 int res = REAL(fflush)(fp);
60706271 // FIXME: handle fp == NULL
60716272 if (fp) {
......@@ -6085,6 +6286,8 @@ INTERCEPTOR(int, fclose, __sanitizer_FILE *fp) {
60856286 COMMON_INTERCEPTOR_ENTER(ctx, fclose, fp);
60866287 COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp);
60876288 const FileMetadata *m = GetInterceptorMetadata(fp);
6289 if (fp)
6290 unpoison_file(fp);
60886291 int res = REAL(fclose)(fp);
60896292 if (m) {
60906293 COMMON_INTERCEPTOR_INITIALIZE_RANGE(*m->addr, *m->size);
......@@ -6299,7 +6502,7 @@ INTERCEPTOR(int, sem_wait, __sanitizer_sem_t *s) {
62996502INTERCEPTOR(int, sem_trywait, __sanitizer_sem_t *s) {
63006503 void *ctx;
63016504 COMMON_INTERCEPTOR_ENTER(ctx, sem_trywait, s);
6302 int res = COMMON_INTERCEPTOR_BLOCK_REAL(sem_trywait)(s);
6505 int res = REAL(sem_trywait)(s);
63036506 if (res == 0) {
63046507 COMMON_INTERCEPTOR_ACQUIRE(ctx, (uptr)s);
63056508 }
......@@ -7634,7 +7837,7 @@ INTERCEPTOR(void, regfree, const void *preg) {
76347837}
76357838#define INIT_REGEX \
76367839 COMMON_INTERCEPT_FUNCTION(regcomp); \
7637 COMMON_INTERCEPT_FUNCTION(regexec); \
7840 COMMON_INTERCEPT_FUNCTION_GLIBC_VER_MIN(regexec, "GLIBC_2.3.4"); \
76387841 COMMON_INTERCEPT_FUNCTION(regerror); \
76397842 COMMON_INTERCEPT_FUNCTION(regfree);
76407843#else
......@@ -9755,12 +9958,25 @@ INTERCEPTOR(void, qsort, void *base, SIZE_T nmemb, SIZE_T size,
97559958 }
97569959 }
97579960 qsort_compar_f old_compar = qsort_compar;
9758 qsort_compar = compar;
97599961 SIZE_T old_size = qsort_size;
9760 qsort_size = size;
9962 // Handle qsort() implementations that recurse using an
9963 // interposable function call:
9964 bool already_wrapped = compar == wrapped_qsort_compar;
9965 if (already_wrapped) {
9966 // This case should only happen if the qsort() implementation calls itself
9967 // using a preemptible function call (e.g. the FreeBSD libc version).
9968 // Check that the size and comparator arguments are as expected.
9969 CHECK_NE(compar, qsort_compar);
9970 CHECK_EQ(qsort_size, size);
9971 } else {
9972 qsort_compar = compar;
9973 qsort_size = size;
9974 }
97619975 REAL(qsort)(base, nmemb, size, wrapped_qsort_compar);
9762 qsort_compar = old_compar;
9763 qsort_size = old_size;
9976 if (!already_wrapped) {
9977 qsort_compar = old_compar;
9978 qsort_size = old_size;
9979 }
97649980 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, base, nmemb * size);
97659981}
97669982#define INIT_QSORT COMMON_INTERCEPT_FUNCTION(qsort)
......@@ -9793,12 +10009,25 @@ INTERCEPTOR(void, qsort_r, void *base, SIZE_T nmemb, SIZE_T size,
979310009 }
979410010 }
979510011 qsort_r_compar_f old_compar = qsort_r_compar;
9796 qsort_r_compar = compar;
979710012 SIZE_T old_size = qsort_r_size;
9798 qsort_r_size = size;
10013 // Handle qsort_r() implementations that recurse using an
10014 // interposable function call:
10015 bool already_wrapped = compar == wrapped_qsort_r_compar;
10016 if (already_wrapped) {
10017 // This case should only happen if the qsort() implementation calls itself
10018 // using a preemptible function call (e.g. the FreeBSD libc version).
10019 // Check that the size and comparator arguments are as expected.
10020 CHECK_NE(compar, qsort_r_compar);
10021 CHECK_EQ(qsort_r_size, size);
10022 } else {
10023 qsort_r_compar = compar;
10024 qsort_r_size = size;
10025 }
979910026 REAL(qsort_r)(base, nmemb, size, wrapped_qsort_r_compar, arg);
9800 qsort_r_compar = old_compar;
9801 qsort_r_size = old_size;
10027 if (!already_wrapped) {
10028 qsort_r_compar = old_compar;
10029 qsort_r_size = old_size;
10030 }
980210031 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, base, nmemb * size);
980310032}
980410033#define INIT_QSORT_R COMMON_INTERCEPT_FUNCTION(qsort_r)
......@@ -9996,6 +10225,7 @@ static void InitializeCommonInterceptors() {
999610225 INIT_SIGWAITINFO;
999710226 INIT_SIGTIMEDWAIT;
999810227 INIT_SIGSETOPS;
10228 INIT_SIGSET_LOGICOPS;
999910229 INIT_SIGPENDING;
1000010230 INIT_SIGPROCMASK;
1000110231 INIT_PTHREAD_SIGMASK;
......@@ -10037,6 +10267,8 @@ static void InitializeCommonInterceptors() {
1003710267 INIT_PTHREAD_BARRIERATTR_GETPSHARED;
1003810268 INIT_TMPNAM;
1003910269 INIT_TMPNAM_R;
10270 INIT_PTSNAME;
10271 INIT_PTSNAME_R;
1004010272 INIT_TTYNAME;
1004110273 INIT_TTYNAME_R;
1004210274 INIT_TEMPNAM;
......@@ -10066,10 +10298,12 @@ static void InitializeCommonInterceptors() {
1006610298 INIT_BZERO;
1006710299 INIT_FTIME;
1006810300 INIT_XDR;
10301 INIT_XDRREC_LINUX;
1006910302 INIT_TSEARCH;
1007010303 INIT_LIBIO_INTERNALS;
1007110304 INIT_FOPEN;
1007210305 INIT_FOPEN64;
10306 INIT_FLOPEN;
1007310307 INIT_OPEN_MEMSTREAM;
1007410308 INIT_OBSTACK;
1007510309 INIT_FFLUSH;
lib/tsan/sanitizer_common/sanitizer_common_interceptors_format.inc+6
......@@ -340,6 +340,12 @@ static void scanf_common(void *ctx, int n_inputs, bool allowGnuMalloc,
340340 size = 0;
341341 }
342342 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, argp, size);
343 // For %ms/%mc, write the allocated output buffer as well.
344 if (dir.allocate) {
345 char *buf = *(char **)argp;
346 if (buf)
347 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, internal_strlen(buf) + 1);
348 }
343349 }
344350}
345351
lib/tsan/sanitizer_common/sanitizer_common_interceptors_ioctl.inc+5-10
......@@ -330,13 +330,17 @@ static void ioctl_table_fill() {
330330 _(SOUND_PCM_WRITE_CHANNELS, WRITE, sizeof(int));
331331 _(SOUND_PCM_WRITE_FILTER, WRITE, sizeof(int));
332332 _(TCFLSH, NONE, 0);
333#if SANITIZER_GLIBC
333334 _(TCGETA, WRITE, struct_termio_sz);
335#endif
334336 _(TCGETS, WRITE, struct_termios_sz);
335337 _(TCSBRK, NONE, 0);
336338 _(TCSBRKP, NONE, 0);
339#if SANITIZER_GLIBC
337340 _(TCSETA, READ, struct_termio_sz);
338341 _(TCSETAF, READ, struct_termio_sz);
339342 _(TCSETAW, READ, struct_termio_sz);
343#endif
340344 _(TCSETS, READ, struct_termios_sz);
341345 _(TCSETSF, READ, struct_termios_sz);
342346 _(TCSETSW, READ, struct_termios_sz);
......@@ -364,17 +368,8 @@ static void ioctl_table_fill() {
364368 _(VT_WAITACTIVE, NONE, 0);
365369#endif
366370
367#if SANITIZER_LINUX && !SANITIZER_ANDROID
371#if SANITIZER_GLIBC
368372 // _(SIOCDEVPLIP, WRITE, struct_ifreq_sz); // the same as EQL_ENSLAVE
369 _(CYGETDEFTHRESH, WRITE, sizeof(int));
370 _(CYGETDEFTIMEOUT, WRITE, sizeof(int));
371 _(CYGETMON, WRITE, struct_cyclades_monitor_sz);
372 _(CYGETTHRESH, WRITE, sizeof(int));
373 _(CYGETTIMEOUT, WRITE, sizeof(int));
374 _(CYSETDEFTHRESH, NONE, 0);
375 _(CYSETDEFTIMEOUT, NONE, 0);
376 _(CYSETTHRESH, NONE, 0);
377 _(CYSETTIMEOUT, NONE, 0);
378373 _(EQL_EMANCIPATE, WRITE, struct_ifreq_sz);
379374 _(EQL_ENSLAVE, WRITE, struct_ifreq_sz);
380375 _(EQL_GETMASTRCFG, WRITE, struct_ifreq_sz);
lib/tsan/sanitizer_common/sanitizer_common_interface.inc+1
......@@ -13,6 +13,7 @@ INTERFACE_FUNCTION(__sanitizer_contiguous_container_find_bad_address)
1313INTERFACE_FUNCTION(__sanitizer_set_death_callback)
1414INTERFACE_FUNCTION(__sanitizer_set_report_path)
1515INTERFACE_FUNCTION(__sanitizer_set_report_fd)
16INTERFACE_FUNCTION(__sanitizer_get_report_path)
1617INTERFACE_FUNCTION(__sanitizer_verify_contiguous_container)
1718INTERFACE_WEAK_FUNCTION(__sanitizer_on_print)
1819INTERFACE_WEAK_FUNCTION(__sanitizer_report_error_summary)
lib/tsan/sanitizer_common/sanitizer_common_libcdep.cpp+56-4
......@@ -92,14 +92,13 @@ void *BackgroundThread(void *arg) {
9292#endif
9393
9494void WriteToSyslog(const char *msg) {
95 InternalScopedString msg_copy(kErrorMessageBufferSize);
95 InternalScopedString msg_copy;
9696 msg_copy.append("%s", msg);
97 char *p = msg_copy.data();
98 char *q;
97 const char *p = msg_copy.data();
9998
10099 // Print one line at a time.
101100 // syslog, at least on Android, has an implicit message length limit.
102 while ((q = internal_strchr(p, '\n'))) {
101 while (char* q = internal_strchr(p, '\n')) {
103102 *q = '\0';
104103 WriteOneLineToSyslog(p);
105104 p = q + 1;
......@@ -139,6 +138,59 @@ uptr ReservedAddressRange::InitAligned(uptr size, uptr align,
139138 return start;
140139}
141140
141#if !SANITIZER_FUCHSIA
142
143// Reserve memory range [beg, end].
144// We need to use inclusive range because end+1 may not be representable.
145void ReserveShadowMemoryRange(uptr beg, uptr end, const char *name,
146 bool madvise_shadow) {
147 CHECK_EQ((beg % GetMmapGranularity()), 0);
148 CHECK_EQ(((end + 1) % GetMmapGranularity()), 0);
149 uptr size = end - beg + 1;
150 DecreaseTotalMmap(size); // Don't count the shadow against mmap_limit_mb.
151 if (madvise_shadow ? !MmapFixedSuperNoReserve(beg, size, name)
152 : !MmapFixedNoReserve(beg, size, name)) {
153 Report(
154 "ReserveShadowMemoryRange failed while trying to map 0x%zx bytes. "
155 "Perhaps you're using ulimit -v\n",
156 size);
157 Abort();
158 }
159 if (madvise_shadow && common_flags()->use_madv_dontdump)
160 DontDumpShadowMemory(beg, size);
161}
162
163void ProtectGap(uptr addr, uptr size, uptr zero_base_shadow_start,
164 uptr zero_base_max_shadow_start) {
165 if (!size)
166 return;
167 void *res = MmapFixedNoAccess(addr, size, "shadow gap");
168 if (addr == (uptr)res)
169 return;
170 // A few pages at the start of the address space can not be protected.
171 // But we really want to protect as much as possible, to prevent this memory
172 // being returned as a result of a non-FIXED mmap().
173 if (addr == zero_base_shadow_start) {
174 uptr step = GetMmapGranularity();
175 while (size > step && addr < zero_base_max_shadow_start) {
176 addr += step;
177 size -= step;
178 void *res = MmapFixedNoAccess(addr, size, "shadow gap");
179 if (addr == (uptr)res)
180 return;
181 }
182 }
183
184 Report(
185 "ERROR: Failed to protect the shadow gap. "
186 "%s cannot proceed correctly. ABORTING.\n",
187 SanitizerToolName);
188 DumpProcessMap();
189 Die();
190}
191
192#endif // !SANITIZER_FUCHSIA
193
142194} // namespace __sanitizer
143195
144196SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_sandbox_on_notify,
lib/tsan/sanitizer_common/sanitizer_common_nolibc.cpp+3-2
......@@ -10,9 +10,10 @@
1010// libc in no-libcdep sources.
1111//===----------------------------------------------------------------------===//
1212
13#include "sanitizer_platform.h"
1413#include "sanitizer_common.h"
14#include "sanitizer_flags.h"
1515#include "sanitizer_libc.h"
16#include "sanitizer_platform.h"
1617
1718namespace __sanitizer {
1819
......@@ -24,11 +25,11 @@ void LogMessageOnPrintf(const char *str) {}
2425#endif
2526void WriteToSyslog(const char *buffer) {}
2627void Abort() { internal__exit(1); }
27void SleepForSeconds(int seconds) { internal_sleep(seconds); }
2828#endif // !SANITIZER_WINDOWS
2929
3030#if !SANITIZER_WINDOWS && !SANITIZER_MAC
3131void ListOfModules::init() {}
32void InitializePlatformCommonFlags(CommonFlags *cf) {}
3233#endif
3334
3435} // namespace __sanitizer
lib/tsan/sanitizer_common/sanitizer_common_syscalls.inc+8-6
......@@ -2294,9 +2294,10 @@ PRE_SYSCALL(ni_syscall)() {}
22942294POST_SYSCALL(ni_syscall)(long res) {}
22952295
22962296PRE_SYSCALL(ptrace)(long request, long pid, long addr, long data) {
2297#if !SANITIZER_ANDROID && \
2298 (defined(__i386) || defined(__x86_64) || defined(__mips64) || \
2299 defined(__powerpc64__) || defined(__aarch64__) || defined(__s390__))
2297#if !SANITIZER_ANDROID && \
2298 (defined(__i386) || defined(__x86_64) || defined(__mips64) || \
2299 defined(__powerpc64__) || defined(__aarch64__) || defined(__s390__) || \
2300 SANITIZER_RISCV64)
23002301 if (data) {
23012302 if (request == ptrace_setregs) {
23022303 PRE_READ((void *)data, struct_user_regs_struct_sz);
......@@ -2315,9 +2316,10 @@ PRE_SYSCALL(ptrace)(long request, long pid, long addr, long data) {
23152316}
23162317
23172318POST_SYSCALL(ptrace)(long res, long request, long pid, long addr, long data) {
2318#if !SANITIZER_ANDROID && \
2319 (defined(__i386) || defined(__x86_64) || defined(__mips64) || \
2320 defined(__powerpc64__) || defined(__aarch64__) || defined(__s390__))
2319#if !SANITIZER_ANDROID && \
2320 (defined(__i386) || defined(__x86_64) || defined(__mips64) || \
2321 defined(__powerpc64__) || defined(__aarch64__) || defined(__s390__) || \
2322 SANITIZER_RISCV64)
23212323 if (res >= 0 && data) {
23222324 // Note that this is different from the interceptor in
23232325 // sanitizer_common_interceptors.inc.
lib/tsan/sanitizer_common/sanitizer_deadlock_detector1.cpp+2-2
......@@ -32,7 +32,7 @@ struct DDLogicalThread {
3232 bool report_pending;
3333};
3434
35struct DD : public DDetector {
35struct DD final : public DDetector {
3636 SpinMutex mtx;
3737 DeadlockDetector<DDBV> dd;
3838 DDFlags flags;
......@@ -136,7 +136,7 @@ void DD::ReportDeadlock(DDCallback *cb, DDMutex *m) {
136136 DDMutex *m0 = (DDMutex*)dd.getData(from);
137137 DDMutex *m1 = (DDMutex*)dd.getData(to);
138138
139 u32 stk_from = -1U, stk_to = -1U;
139 u32 stk_from = 0, stk_to = 0;
140140 int unique_tid = 0;
141141 dd.findEdge(from, to, &stk_from, &stk_to, &unique_tid);
142142 // Printf("Edge: %zd=>%zd: %u/%u T%d\n", from, to, stk_from, stk_to,
lib/tsan/sanitizer_common/sanitizer_deadlock_detector2.cpp+16-18
......@@ -73,14 +73,14 @@ struct DDLogicalThread {
7373 int nlocked;
7474};
7575
76struct Mutex {
76struct MutexState {
7777 StaticSpinMutex mtx;
7878 u32 seq;
7979 int nlink;
8080 Link link[kMaxLink];
8181};
8282
83struct DD : public DDetector {
83struct DD final : public DDetector {
8484 explicit DD(const DDFlags *flags);
8585
8686 DDPhysicalThread* CreatePhysicalThread();
......@@ -101,12 +101,12 @@ struct DD : public DDetector {
101101 void CycleCheck(DDPhysicalThread *pt, DDLogicalThread *lt, DDMutex *mtx);
102102 void Report(DDPhysicalThread *pt, DDLogicalThread *lt, int npath);
103103 u32 allocateId(DDCallback *cb);
104 Mutex *getMutex(u32 id);
105 u32 getMutexId(Mutex *m);
104 MutexState *getMutex(u32 id);
105 u32 getMutexId(MutexState *m);
106106
107107 DDFlags flags;
108108
109 Mutex* mutex[kL1Size];
109 MutexState *mutex[kL1Size];
110110
111111 SpinMutex mtx;
112112 InternalMmapVector<u32> free_id;
......@@ -152,13 +152,11 @@ void DD::MutexInit(DDCallback *cb, DDMutex *m) {
152152 atomic_store(&m->owner, 0, memory_order_relaxed);
153153}
154154
155Mutex *DD::getMutex(u32 id) {
156 return &mutex[id / kL2Size][id % kL2Size];
157}
155MutexState *DD::getMutex(u32 id) { return &mutex[id / kL2Size][id % kL2Size]; }
158156
159u32 DD::getMutexId(Mutex *m) {
157u32 DD::getMutexId(MutexState *m) {
160158 for (int i = 0; i < kL1Size; i++) {
161 Mutex *tab = mutex[i];
159 MutexState *tab = mutex[i];
162160 if (tab == 0)
163161 break;
164162 if (m >= tab && m < tab + kL2Size)
......@@ -176,8 +174,8 @@ u32 DD::allocateId(DDCallback *cb) {
176174 } else {
177175 CHECK_LT(id_gen, kMaxMutex);
178176 if ((id_gen % kL2Size) == 0) {
179 mutex[id_gen / kL2Size] = (Mutex*)MmapOrDie(kL2Size * sizeof(Mutex),
180 "deadlock detector (mutex table)");
177 mutex[id_gen / kL2Size] = (MutexState *)MmapOrDie(
178 kL2Size * sizeof(MutexState), "deadlock detector (mutex table)");
181179 }
182180 id = id_gen++;
183181 }
......@@ -216,11 +214,11 @@ void DD::MutexBeforeLock(DDCallback *cb, DDMutex *m, bool wlock) {
216214 }
217215
218216 bool added = false;
219 Mutex *mtx = getMutex(m->id);
217 MutexState *mtx = getMutex(m->id);
220218 for (int i = 0; i < lt->nlocked - 1; i++) {
221219 u32 id1 = lt->locked[i].id;
222220 u32 stk1 = lt->locked[i].stk;
223 Mutex *mtx1 = getMutex(id1);
221 MutexState *mtx1 = getMutex(id1);
224222 SpinMutexLock l(&mtx1->mtx);
225223 if (mtx1->nlink == kMaxLink) {
226224 // FIXME(dvyukov): check stale links
......@@ -342,7 +340,7 @@ void DD::MutexDestroy(DDCallback *cb, DDMutex *m) {
342340
343341 // Clear and invalidate the mutex descriptor.
344342 {
345 Mutex *mtx = getMutex(m->id);
343 MutexState *mtx = getMutex(m->id);
346344 SpinMutexLock l(&mtx->mtx);
347345 mtx->seq++;
348346 mtx->nlink = 0;
......@@ -361,7 +359,7 @@ void DD::CycleCheck(DDPhysicalThread *pt, DDLogicalThread *lt,
361359 int npath = 0;
362360 int npending = 0;
363361 {
364 Mutex *mtx = getMutex(m->id);
362 MutexState *mtx = getMutex(m->id);
365363 SpinMutexLock l(&mtx->mtx);
366364 for (int li = 0; li < mtx->nlink; li++)
367365 pt->pending[npending++] = mtx->link[li];
......@@ -374,7 +372,7 @@ void DD::CycleCheck(DDPhysicalThread *pt, DDLogicalThread *lt,
374372 }
375373 if (pt->visited[link.id])
376374 continue;
377 Mutex *mtx1 = getMutex(link.id);
375 MutexState *mtx1 = getMutex(link.id);
378376 SpinMutexLock l(&mtx1->mtx);
379377 if (mtx1->seq != link.seq)
380378 continue;
......@@ -387,7 +385,7 @@ void DD::CycleCheck(DDPhysicalThread *pt, DDLogicalThread *lt,
387385 return Report(pt, lt, npath); // Bingo!
388386 for (int li = 0; li < mtx1->nlink; li++) {
389387 Link *link1 = &mtx1->link[li];
390 // Mutex *mtx2 = getMutex(link->id);
388 // MutexState *mtx2 = getMutex(link->id);
391389 // FIXME(dvyukov): fast seq check
392390 // FIXME(dvyukov): fast nlink != 0 check
393391 // FIXME(dvyukov): fast pending check?
lib/tsan/sanitizer_common/sanitizer_deadlock_detector_interface.h+6
......@@ -66,6 +66,9 @@ struct DDCallback {
6666
6767 virtual u32 Unwind() { return 0; }
6868 virtual int UniqueTid() { return 0; }
69
70 protected:
71 ~DDCallback() {}
6972};
7073
7174struct DDetector {
......@@ -85,6 +88,9 @@ struct DDetector {
8588 virtual void MutexDestroy(DDCallback *cb, DDMutex *m) {}
8689
8790 virtual DDReport *GetReport(DDCallback *cb) { return nullptr; }
91
92 protected:
93 ~DDetector() {}
8894};
8995
9096} // namespace __sanitizer
lib/tsan/sanitizer_common/sanitizer_errno.h+1-2
......@@ -23,8 +23,7 @@
2323
2424#if SANITIZER_FREEBSD || SANITIZER_MAC
2525# define __errno_location __error
26#elif SANITIZER_ANDROID || SANITIZER_NETBSD || SANITIZER_OPENBSD || \
27 SANITIZER_RTEMS
26#elif SANITIZER_ANDROID || SANITIZER_NETBSD
2827# define __errno_location __errno
2928#elif SANITIZER_SOLARIS
3029# define __errno_location ___errno
lib/tsan/sanitizer_common/sanitizer_errno_codes.h+1
......@@ -24,6 +24,7 @@ namespace __sanitizer {
2424#define errno_ENOMEM 12
2525#define errno_EBUSY 16
2626#define errno_EINVAL 22
27#define errno_ENAMETOOLONG 36
2728
2829// Those might not present or their value differ on different platforms.
2930extern const int errno_EOWNERDEAD;
lib/tsan/sanitizer_common/sanitizer_file.cpp+28-12
......@@ -58,40 +58,52 @@ void ReportFile::ReopenIfNecessary() {
5858 } else {
5959 internal_snprintf(full_path, kMaxPathLength, "%s.%zu", path_prefix, pid);
6060 }
61 fd = OpenFile(full_path, WrOnly);
61 if (common_flags()->log_suffix) {
62 internal_strlcat(full_path, common_flags()->log_suffix, kMaxPathLength);
63 }
64 error_t err;
65 fd = OpenFile(full_path, WrOnly, &err);
6266 if (fd == kInvalidFd) {
6367 const char *ErrorMsgPrefix = "ERROR: Can't open file: ";
6468 WriteToFile(kStderrFd, ErrorMsgPrefix, internal_strlen(ErrorMsgPrefix));
6569 WriteToFile(kStderrFd, full_path, internal_strlen(full_path));
70 char errmsg[100];
71 internal_snprintf(errmsg, sizeof(errmsg), " (reason: %d)", err);
72 WriteToFile(kStderrFd, errmsg, internal_strlen(errmsg));
6673 Die();
6774 }
6875 fd_pid = pid;
6976}
7077
7178void ReportFile::SetReportPath(const char *path) {
72 if (!path)
73 return;
74 uptr len = internal_strlen(path);
75 if (len > sizeof(path_prefix) - 100) {
76 Report("ERROR: Path is too long: %c%c%c%c%c%c%c%c...\n",
77 path[0], path[1], path[2], path[3],
78 path[4], path[5], path[6], path[7]);
79 Die();
79 if (path) {
80 uptr len = internal_strlen(path);
81 if (len > sizeof(path_prefix) - 100) {
82 Report("ERROR: Path is too long: %c%c%c%c%c%c%c%c...\n", path[0], path[1],
83 path[2], path[3], path[4], path[5], path[6], path[7]);
84 Die();
85 }
8086 }
8187
8288 SpinMutexLock l(mu);
8389 if (fd != kStdoutFd && fd != kStderrFd && fd != kInvalidFd)
8490 CloseFile(fd);
8591 fd = kInvalidFd;
86 if (internal_strcmp(path, "stdout") == 0) {
87 fd = kStdoutFd;
88 } else if (internal_strcmp(path, "stderr") == 0) {
92 if (!path || internal_strcmp(path, "stderr") == 0) {
8993 fd = kStderrFd;
94 } else if (internal_strcmp(path, "stdout") == 0) {
95 fd = kStdoutFd;
9096 } else {
9197 internal_snprintf(path_prefix, kMaxPathLength, "%s", path);
9298 }
9399}
94100
101const char *ReportFile::GetReportPath() {
102 SpinMutexLock l(mu);
103 ReopenIfNecessary();
104 return full_path;
105}
106
95107bool ReadFileToBuffer(const char *file_name, char **buff, uptr *buff_size,
96108 uptr *read_len, uptr max_len, error_t *errno_p) {
97109 *buff = nullptr;
......@@ -210,6 +222,10 @@ void __sanitizer_set_report_fd(void *fd) {
210222 report_file.fd = (fd_t)reinterpret_cast<uptr>(fd);
211223 report_file.fd_pid = internal_getpid();
212224}
225
226const char *__sanitizer_get_report_path() {
227 return report_file.GetReportPath();
228}
213229} // extern "C"
214230
215231#endif // !SANITIZER_FUCHSIA
lib/tsan/sanitizer_common/sanitizer_file.h+1
......@@ -26,6 +26,7 @@ struct ReportFile {
2626 void Write(const char *buffer, uptr length);
2727 bool SupportsColors();
2828 void SetReportPath(const char *path);
29 const char *GetReportPath();
2930
3031 // Don't use fields directly. They are only declared public to allow
3132 // aggregate initialization.
lib/tsan/sanitizer_common/sanitizer_flag_parser.h+1-1
......@@ -42,7 +42,7 @@ class FlagHandlerBase {
4242};
4343
4444template <typename T>
45class FlagHandler : public FlagHandlerBase {
45class FlagHandler final : public FlagHandlerBase {
4646 T *t_;
4747
4848 public:
lib/tsan/sanitizer_common/sanitizer_flags.cpp+13-3
......@@ -13,9 +13,10 @@
1313#include "sanitizer_flags.h"
1414
1515#include "sanitizer_common.h"
16#include "sanitizer_flag_parser.h"
1617#include "sanitizer_libc.h"
18#include "sanitizer_linux.h"
1719#include "sanitizer_list.h"
18#include "sanitizer_flag_parser.h"
1920
2021namespace __sanitizer {
2122
......@@ -34,6 +35,7 @@ void CommonFlags::CopyFrom(const CommonFlags &other) {
3435// Copy the string from "s" to "out", making the following substitutions:
3536// %b = binary basename
3637// %p = pid
38// %d = binary directory
3739void SubstituteForFlagValue(const char *s, char *out, uptr out_size) {
3840 char *out_end = out + out_size;
3941 while (*s && out < out_end - 1) {
......@@ -63,6 +65,12 @@ void SubstituteForFlagValue(const char *s, char *out, uptr out_size) {
6365 s += 2; // skip "%p"
6466 break;
6567 }
68 case 'd': {
69 uptr len = ReadBinaryDir(out, out_end - out);
70 out += len;
71 s += 2; // skip "%d"
72 break;
73 }
6674 default:
6775 *out++ = *s++;
6876 break;
......@@ -72,7 +80,7 @@ void SubstituteForFlagValue(const char *s, char *out, uptr out_size) {
7280 *out = '\0';
7381}
7482
75class FlagHandlerInclude : public FlagHandlerBase {
83class FlagHandlerInclude final : public FlagHandlerBase {
7684 FlagParser *parser_;
7785 bool ignore_missing_;
7886 const char *original_path_;
......@@ -91,7 +99,7 @@ class FlagHandlerInclude : public FlagHandlerBase {
9199 }
92100 return parser_->ParseFile(value, ignore_missing_);
93101 }
94 bool Format(char *buffer, uptr size) {
102 bool Format(char *buffer, uptr size) override {
95103 // Note `original_path_` isn't actually what's parsed due to `%`
96104 // substitutions. Printing the substituted path would require holding onto
97105 // mmap'ed memory.
......@@ -124,6 +132,8 @@ void InitializeCommonFlags(CommonFlags *cf) {
124132 // need to record coverage to generate coverage report.
125133 cf->coverage |= cf->html_cov_report;
126134 SetVerbosity(cf->verbosity);
135
136 InitializePlatformCommonFlags(cf);
127137}
128138
129139} // namespace __sanitizer
lib/tsan/sanitizer_common/sanitizer_flags.h+4
......@@ -62,6 +62,10 @@ void RegisterIncludeFlags(FlagParser *parser, CommonFlags *cf);
6262// and perform initializations common to all sanitizers (e.g. setting
6363// verbosity).
6464void InitializeCommonFlags(CommonFlags *cf = &common_flags_dont_use);
65
66// Platform specific flags initialization.
67void InitializePlatformCommonFlags(CommonFlags *cf);
68
6569} // namespace __sanitizer
6670
6771#endif // SANITIZER_FLAGS_H
lib/tsan/sanitizer_common/sanitizer_flags.inc+16-5
......@@ -40,20 +40,27 @@ COMMON_FLAG(bool, fast_unwind_on_check, false,
4040COMMON_FLAG(bool, fast_unwind_on_fatal, false,
4141 "If available, use the fast frame-pointer-based unwinder on fatal "
4242 "errors.")
43COMMON_FLAG(bool, fast_unwind_on_malloc, true,
43// ARM thumb/thumb2 frame pointer is inconsistent on GCC and Clang [1]
44// and fast-unwider is also unreliable with mixing arm and thumb code [2].
45// [1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92172
46// [2] https://bugs.llvm.org/show_bug.cgi?id=44158
47COMMON_FLAG(bool, fast_unwind_on_malloc,
48 !(SANITIZER_LINUX && !SANITIZER_ANDROID && SANITIZER_ARM),
4449 "If available, use the fast frame-pointer-based unwinder on "
4550 "malloc/free.")
4651COMMON_FLAG(bool, handle_ioctl, false, "Intercept and handle ioctl requests.")
4752COMMON_FLAG(int, malloc_context_size, 1,
4853 "Max number of stack frames kept for each allocation/deallocation.")
4954COMMON_FLAG(
50 const char *, log_path, "stderr",
55 const char *, log_path, nullptr,
5156 "Write logs to \"log_path.pid\". The special values are \"stdout\" and "
52 "\"stderr\". The default is \"stderr\".")
57 "\"stderr\". If unspecified, defaults to \"stderr\".")
5358COMMON_FLAG(
5459 bool, log_exe_name, false,
5560 "Mention name of executable when reporting error and "
5661 "append executable name to logs (as in \"log_path.exe_name.pid\").")
62COMMON_FLAG(const char *, log_suffix, nullptr,
63 "String to append to log file name, e.g. \".txt\".")
5764COMMON_FLAG(
5865 bool, log_to_syslog, (bool)SANITIZER_ANDROID || (bool)SANITIZER_MAC,
5966 "Write all sanitizer output to syslog in addition to other means of "
......@@ -77,8 +84,9 @@ COMMON_FLAG(bool, print_summary, true,
7784 "If false, disable printing error summaries in addition to error "
7885 "reports.")
7986COMMON_FLAG(int, print_module_map, 0,
80 "OS X only (0 - don't print, 1 - print only once before process "
81 "exits, 2 - print after each report).")
87 "Print the process module map where supported (0 - don't print, "
88 "1 - print only once before process exits, 2 - print after each "
89 "report).")
8290COMMON_FLAG(bool, check_printf, true, "Check printf arguments.")
8391#define COMMON_FLAG_HANDLE_SIGNAL_HELP(signal) \
8492 "Controls custom tool's " #signal " handler (0 - do not registers the " \
......@@ -195,6 +203,9 @@ COMMON_FLAG(bool, intercept_strtok, true,
195203COMMON_FLAG(bool, intercept_strpbrk, true,
196204 "If set, uses custom wrappers for strpbrk function "
197205 "to find more errors.")
206COMMON_FLAG(
207 bool, intercept_strcmp, true,
208 "If set, uses custom wrappers for strcmp functions to find more errors.")
198209COMMON_FLAG(bool, intercept_strlen, true,
199210 "If set, uses custom wrappers for strlen and strnlen functions "
200211 "to find more errors.")
lib/tsan/sanitizer_common/sanitizer_fuchsia.cpp+70-52
......@@ -14,17 +14,17 @@
1414#include "sanitizer_fuchsia.h"
1515#if SANITIZER_FUCHSIA
1616
17#include "sanitizer_common.h"
18#include "sanitizer_libc.h"
19#include "sanitizer_mutex.h"
20
21#include <limits.h>
2217#include <pthread.h>
2318#include <stdlib.h>
2419#include <unistd.h>
2520#include <zircon/errors.h>
2621#include <zircon/process.h>
2722#include <zircon/syscalls.h>
23#include <zircon/utc.h>
24
25#include "sanitizer_common.h"
26#include "sanitizer_libc.h"
27#include "sanitizer_mutex.h"
2828
2929namespace __sanitizer {
3030
......@@ -36,19 +36,16 @@ uptr internal_sched_yield() {
3636 return 0; // Why doesn't this return void?
3737}
3838
39static void internal_nanosleep(zx_time_t ns) {
40 zx_status_t status = _zx_nanosleep(_zx_deadline_after(ns));
39void internal_usleep(u64 useconds) {
40 zx_status_t status = _zx_nanosleep(_zx_deadline_after(ZX_USEC(useconds)));
4141 CHECK_EQ(status, ZX_OK);
4242}
4343
44unsigned int internal_sleep(unsigned int seconds) {
45 internal_nanosleep(ZX_SEC(seconds));
46 return 0;
47}
48
4944u64 NanoTime() {
45 zx_handle_t utc_clock = _zx_utc_reference_get();
46 CHECK_NE(utc_clock, ZX_HANDLE_INVALID);
5047 zx_time_t time;
51 zx_status_t status = _zx_clock_get(ZX_CLOCK_UTC, &time);
48 zx_status_t status = _zx_clock_read(utc_clock, &time);
5249 CHECK_EQ(status, ZX_OK);
5350 return time;
5451}
......@@ -66,9 +63,7 @@ uptr internal_getpid() {
6663 return pid;
6764}
6865
69int internal_dlinfo(void *handle, int request, void *p) {
70 UNIMPLEMENTED();
71}
66int internal_dlinfo(void *handle, int request, void *p) { UNIMPLEMENTED(); }
7267
7368uptr GetThreadSelf() { return reinterpret_cast<uptr>(thrd_current()); }
7469
......@@ -78,10 +73,6 @@ void Abort() { abort(); }
7873
7974int Atexit(void (*function)(void)) { return atexit(function); }
8075
81void SleepForSeconds(int seconds) { internal_sleep(seconds); }
82
83void SleepForMillis(int millis) { internal_nanosleep(ZX_MSEC(millis)); }
84
8576void GetThreadStackTopAndBottom(bool, uptr *stack_top, uptr *stack_bottom) {
8677 pthread_attr_t attr;
8778 CHECK_EQ(pthread_getattr_np(pthread_self(), &attr), 0);
......@@ -105,12 +96,22 @@ void SetAlternateSignalStack() {}
10596void UnsetAlternateSignalStack() {}
10697void InitTlsSize() {}
10798
108void PrintModuleMap() {}
109
11099bool SignalContext::IsStackOverflow() const { return false; }
111100void SignalContext::DumpAllRegisters(void *context) { UNIMPLEMENTED(); }
112101const char *SignalContext::Describe() const { UNIMPLEMENTED(); }
113102
103void FutexWait(atomic_uint32_t *p, u32 cmp) {
104 zx_status_t status = _zx_futex_wait(reinterpret_cast<zx_futex_t *>(p), cmp,
105 ZX_HANDLE_INVALID, ZX_TIME_INFINITE);
106 if (status != ZX_ERR_BAD_STATE) // Normal race.
107 CHECK_EQ(status, ZX_OK);
108}
109
110void FutexWake(atomic_uint32_t *p, u32 count) {
111 zx_status_t status = _zx_futex_wake(reinterpret_cast<zx_futex_t *>(p), count);
112 CHECK_EQ(status, ZX_OK);
113}
114
114115enum MutexState : int { MtxUnlocked = 0, MtxLocked = 1, MtxSleeping = 2 };
115116
116117BlockingMutex::BlockingMutex() {
......@@ -147,19 +148,21 @@ void BlockingMutex::Unlock() {
147148 }
148149}
149150
150void BlockingMutex::CheckLocked() {
151 atomic_uint32_t *m = reinterpret_cast<atomic_uint32_t *>(&opaque_storage_);
151void BlockingMutex::CheckLocked() const {
152 auto m = reinterpret_cast<atomic_uint32_t const *>(&opaque_storage_);
152153 CHECK_NE(MtxUnlocked, atomic_load(m, memory_order_relaxed));
153154}
154155
155uptr GetPageSize() { return PAGE_SIZE; }
156uptr GetPageSize() { return _zx_system_get_page_size(); }
156157
157uptr GetMmapGranularity() { return PAGE_SIZE; }
158uptr GetMmapGranularity() { return _zx_system_get_page_size(); }
158159
159160sanitizer_shadow_bounds_t ShadowBounds;
160161
162void InitShadowBounds() { ShadowBounds = __sanitizer_shadow_bounds(); }
163
161164uptr GetMaxUserVirtualAddress() {
162 ShadowBounds = __sanitizer_shadow_bounds();
165 InitShadowBounds();
163166 return ShadowBounds.memory_limit - 1;
164167}
165168
......@@ -167,7 +170,7 @@ uptr GetMaxVirtualAddress() { return GetMaxUserVirtualAddress(); }
167170
168171static void *DoAnonymousMmapOrDie(uptr size, const char *mem_type,
169172 bool raw_report, bool die_for_nomem) {
170 size = RoundUpTo(size, PAGE_SIZE);
173 size = RoundUpTo(size, GetPageSize());
171174
172175 zx_handle_t vmo;
173176 zx_status_t status = _zx_vmo_create(size, 0, &vmo);
......@@ -213,15 +216,14 @@ void *MmapOrDieOnFatalError(uptr size, const char *mem_type) {
213216
214217uptr ReservedAddressRange::Init(uptr init_size, const char *name,
215218 uptr fixed_addr) {
216 init_size = RoundUpTo(init_size, PAGE_SIZE);
219 init_size = RoundUpTo(init_size, GetPageSize());
217220 DCHECK_EQ(os_handle_, ZX_HANDLE_INVALID);
218221 uintptr_t base;
219222 zx_handle_t vmar;
220 zx_status_t status =
221 _zx_vmar_allocate(
222 _zx_vmar_root_self(),
223 ZX_VM_CAN_MAP_READ | ZX_VM_CAN_MAP_WRITE | ZX_VM_CAN_MAP_SPECIFIC,
224 0, init_size, &vmar, &base);
223 zx_status_t status = _zx_vmar_allocate(
224 _zx_vmar_root_self(),
225 ZX_VM_CAN_MAP_READ | ZX_VM_CAN_MAP_WRITE | ZX_VM_CAN_MAP_SPECIFIC, 0,
226 init_size, &vmar, &base);
225227 if (status != ZX_OK)
226228 ReportMmapFailureAndDie(init_size, name, "zx_vmar_allocate", status);
227229 base_ = reinterpret_cast<void *>(base);
......@@ -235,7 +237,7 @@ uptr ReservedAddressRange::Init(uptr init_size, const char *name,
235237static uptr DoMmapFixedOrDie(zx_handle_t vmar, uptr fixed_addr, uptr map_size,
236238 void *base, const char *name, bool die_for_nomem) {
237239 uptr offset = fixed_addr - reinterpret_cast<uptr>(base);
238 map_size = RoundUpTo(map_size, PAGE_SIZE);
240 map_size = RoundUpTo(map_size, GetPageSize());
239241 zx_handle_t vmo;
240242 zx_status_t status = _zx_vmo_create(map_size, 0, &vmo);
241243 if (status != ZX_OK) {
......@@ -263,19 +265,19 @@ static uptr DoMmapFixedOrDie(zx_handle_t vmar, uptr fixed_addr, uptr map_size,
263265
264266uptr ReservedAddressRange::Map(uptr fixed_addr, uptr map_size,
265267 const char *name) {
266 return DoMmapFixedOrDie(os_handle_, fixed_addr, map_size, base_,
267 name_, false);
268 return DoMmapFixedOrDie(os_handle_, fixed_addr, map_size, base_, name_,
269 false);
268270}
269271
270272uptr ReservedAddressRange::MapOrDie(uptr fixed_addr, uptr map_size,
271273 const char *name) {
272 return DoMmapFixedOrDie(os_handle_, fixed_addr, map_size, base_,
273 name_, true);
274 return DoMmapFixedOrDie(os_handle_, fixed_addr, map_size, base_, name_, true);
274275}
275276
276277void UnmapOrDieVmar(void *addr, uptr size, zx_handle_t target_vmar) {
277 if (!addr || !size) return;
278 size = RoundUpTo(size, PAGE_SIZE);
278 if (!addr || !size)
279 return;
280 size = RoundUpTo(size, GetPageSize());
279281
280282 zx_status_t status =
281283 _zx_vmar_unmap(target_vmar, reinterpret_cast<uintptr_t>(addr), size);
......@@ -315,7 +317,7 @@ void *MmapFixedNoAccess(uptr fixed_addr, uptr size, const char *name) {
315317
316318void *MmapAlignedOrDieOnFatalError(uptr size, uptr alignment,
317319 const char *mem_type) {
318 CHECK_GE(size, PAGE_SIZE);
320 CHECK_GE(size, GetPageSize());
319321 CHECK(IsPowerOfTwo(size));
320322 CHECK(IsPowerOfTwo(alignment));
321323
......@@ -355,7 +357,8 @@ void *MmapAlignedOrDieOnFatalError(uptr size, uptr alignment,
355357 _zx_vmar_root_self(),
356358 ZX_VM_PERM_READ | ZX_VM_PERM_WRITE | ZX_VM_SPECIFIC_OVERWRITE,
357359 addr - info.base, vmo, 0, size, &new_addr);
358 if (status == ZX_OK) CHECK_EQ(new_addr, addr);
360 if (status == ZX_OK)
361 CHECK_EQ(new_addr, addr);
359362 }
360363 }
361364 if (status == ZX_OK && addr != map_addr)
......@@ -380,9 +383,18 @@ void UnmapOrDie(void *addr, uptr size) {
380383 UnmapOrDieVmar(addr, size, _zx_vmar_root_self());
381384}
382385
383// This is used on the shadow mapping, which cannot be changed.
384// Zircon doesn't have anything like MADV_DONTNEED.
385void ReleaseMemoryPagesToOS(uptr beg, uptr end) {}
386void ReleaseMemoryPagesToOS(uptr beg, uptr end) {
387 uptr beg_aligned = RoundUpTo(beg, GetPageSize());
388 uptr end_aligned = RoundDownTo(end, GetPageSize());
389 if (beg_aligned < end_aligned) {
390 zx_handle_t root_vmar = _zx_vmar_root_self();
391 CHECK_NE(root_vmar, ZX_HANDLE_INVALID);
392 zx_status_t status =
393 _zx_vmar_op_range(root_vmar, ZX_VMAR_OP_DECOMMIT, beg_aligned,
394 end_aligned - beg_aligned, nullptr, 0);
395 CHECK_EQ(status, ZX_OK);
396 }
397}
386398
387399void DumpProcessMap() {
388400 // TODO(mcgrathr): write it
......@@ -411,8 +423,9 @@ bool ReadFileToBuffer(const char *file_name, char **buff, uptr *buff_size,
411423 uint64_t vmo_size;
412424 status = _zx_vmo_get_size(vmo, &vmo_size);
413425 if (status == ZX_OK) {
414 if (vmo_size < max_len) max_len = vmo_size;
415 size_t map_size = RoundUpTo(max_len, PAGE_SIZE);
426 if (vmo_size < max_len)
427 max_len = vmo_size;
428 size_t map_size = RoundUpTo(max_len, GetPageSize());
416429 uintptr_t addr;
417430 status = _zx_vmar_map(_zx_vmar_root_self(), ZX_VM_PERM_READ, 0, vmo, 0,
418431 map_size, &addr);
......@@ -424,7 +437,8 @@ bool ReadFileToBuffer(const char *file_name, char **buff, uptr *buff_size,
424437 }
425438 _zx_handle_close(vmo);
426439 }
427 if (status != ZX_OK && errno_p) *errno_p = status;
440 if (status != ZX_OK && errno_p)
441 *errno_p = status;
428442 return status == ZX_OK;
429443}
430444
......@@ -498,12 +512,12 @@ bool GetRandom(void *buffer, uptr length, bool blocking) {
498512 return true;
499513}
500514
501u32 GetNumberOfCPUs() {
502 return zx_system_get_num_cpus();
503}
515u32 GetNumberOfCPUs() { return zx_system_get_num_cpus(); }
504516
505517uptr GetRSS() { UNIMPLEMENTED(); }
506518
519void InitializePlatformCommonFlags(CommonFlags *cf) {}
520
507521} // namespace __sanitizer
508522
509523using namespace __sanitizer;
......@@ -526,6 +540,10 @@ void __sanitizer_set_report_path(const char *path) {
526540void __sanitizer_set_report_fd(void *fd) {
527541 UNREACHABLE("not available on Fuchsia");
528542}
543
544const char *__sanitizer_get_report_path() {
545 UNREACHABLE("not available on Fuchsia");
546}
529547} // extern "C"
530548
531549#endif // SANITIZER_FUCHSIA
lib/tsan/sanitizer_common/sanitizer_fuchsia.h+2
......@@ -30,6 +30,8 @@ struct MemoryMappingLayoutData {
3030 size_t current; // Current index into the vector.
3131};
3232
33void InitShadowBounds();
34
3335} // namespace __sanitizer
3436
3537#endif // SANITIZER_FUCHSIA
lib/tsan/sanitizer_common/sanitizer_getauxval.h+3-2
......@@ -21,8 +21,9 @@
2121
2222#if SANITIZER_LINUX || SANITIZER_FUCHSIA
2323
24# if __GLIBC_PREREQ(2, 16) || (SANITIZER_ANDROID && __ANDROID_API__ >= 21) || \
25 SANITIZER_FUCHSIA
24# if (__GLIBC_PREREQ(2, 16) || (SANITIZER_ANDROID && __ANDROID_API__ >= 21) || \
25 SANITIZER_FUCHSIA) && \
26 !SANITIZER_GO
2627# define SANITIZER_USE_GETAUXVAL 1
2728# else
2829# define SANITIZER_USE_GETAUXVAL 0
lib/tsan/sanitizer_common/sanitizer_interface_internal.h+4
......@@ -28,6 +28,10 @@ extern "C" {
2828 // (casted to void *).
2929 SANITIZER_INTERFACE_ATTRIBUTE
3030 void __sanitizer_set_report_fd(void *fd);
31 // Get the current full report file path, if a path was specified by
32 // an earlier call to __sanitizer_set_report_path. Returns null otherwise.
33 SANITIZER_INTERFACE_ATTRIBUTE
34 const char *__sanitizer_get_report_path();
3135
3236 typedef struct {
3337 int coverage_sandboxed;
lib/tsan/sanitizer_common/sanitizer_internal_defs.h+11-13
......@@ -39,7 +39,7 @@
3939
4040// TLS is handled differently on different platforms
4141#if SANITIZER_LINUX || SANITIZER_NETBSD || \
42 SANITIZER_FREEBSD || SANITIZER_OPENBSD
42 SANITIZER_FREEBSD
4343# define SANITIZER_TLS_INITIAL_EXEC_ATTRIBUTE \
4444 __attribute__((tls_model("initial-exec"))) thread_local
4545#else
......@@ -104,8 +104,7 @@
104104//
105105// FIXME: do we have anything like this on Mac?
106106#ifndef SANITIZER_CAN_USE_PREINIT_ARRAY
107#if ((SANITIZER_LINUX && !SANITIZER_ANDROID) || SANITIZER_OPENBSD || \
108 SANITIZER_FUCHSIA || SANITIZER_NETBSD) && !defined(PIC)
107#if (SANITIZER_LINUX || SANITIZER_FUCHSIA || SANITIZER_NETBSD) && !defined(PIC)
109108#define SANITIZER_CAN_USE_PREINIT_ARRAY 1
110109// Before Solaris 11.4, .preinit_array is fully supported only with GNU ld.
111110// FIXME: Check for those conditions.
......@@ -170,7 +169,7 @@ typedef int pid_t;
170169#endif
171170
172171#if SANITIZER_FREEBSD || SANITIZER_NETBSD || \
173 SANITIZER_OPENBSD || SANITIZER_MAC || \
172 SANITIZER_MAC || \
174173 (SANITIZER_SOLARIS && (defined(_LP64) || _FILE_OFFSET_BITS == 64)) || \
175174 (SANITIZER_LINUX && defined(__x86_64__))
176175typedef u64 OFF_T;
......@@ -182,7 +181,7 @@ typedef u64 OFF64_T;
182181#if (SANITIZER_WORDSIZE == 64) || SANITIZER_MAC
183182typedef uptr operator_new_size_type;
184183#else
185# if SANITIZER_OPENBSD || defined(__s390__) && !defined(__s390x__)
184# if defined(__s390__) && !defined(__s390x__)
186185// Special case: 31-bit s390 has unsigned long as size_t.
187186typedef unsigned long operator_new_size_type;
188187# else
......@@ -196,9 +195,6 @@ typedef u64 tid_t;
196195// This header should NOT include any other headers to avoid portability issues.
197196
198197// Common defs.
199#ifndef INLINE
200#define INLINE inline
201#endif
202198#define INTERFACE_ATTRIBUTE SANITIZER_INTERFACE_ATTRIBUTE
203199#define SANITIZER_WEAK_DEFAULT_IMPL \
204200 extern "C" SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE NOINLINE
......@@ -333,14 +329,10 @@ void NORETURN CheckFailed(const char *file, int line, const char *cond,
333329
334330#define UNIMPLEMENTED() UNREACHABLE("unimplemented")
335331
336#define COMPILER_CHECK(pred) IMPL_COMPILER_ASSERT(pred, __LINE__)
332#define COMPILER_CHECK(pred) static_assert(pred, "")
337333
338334#define ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0]))
339335
340#define IMPL_PASTE(a, b) a##b
341#define IMPL_COMPILER_ASSERT(pred, line) \
342 typedef char IMPL_PASTE(assertion_failed_##_, line)[2*(int)(pred)-1]
343
344336// Limits for integral types. We have to redefine it in case we don't
345337// have stdint.h (like in Visual Studio 9).
346338#undef __INT64_C
......@@ -417,6 +409,9 @@ inline void Trap() {
417409 (void)enable_fp; \
418410 } while (0)
419411
412constexpr u32 kInvalidTid = -1;
413constexpr u32 kMainTid = 0;
414
420415} // namespace __sanitizer
421416
422417namespace __asan {
......@@ -455,5 +450,8 @@ using namespace __sanitizer;
455450namespace __hwasan {
456451using namespace __sanitizer;
457452}
453namespace __memprof {
454using namespace __sanitizer;
455}
458456
459457#endif // SANITIZER_DEFS_H
lib/tsan/sanitizer_common/sanitizer_libc.h+2-1
......@@ -67,7 +67,8 @@ uptr internal_ftruncate(fd_t fd, uptr size);
6767
6868// OS
6969void NORETURN internal__exit(int exitcode);
70unsigned int internal_sleep(unsigned int seconds);
70void internal_sleep(unsigned seconds);
71void internal_usleep(u64 useconds);
7172
7273uptr internal_getpid();
7374uptr internal_getppid();
lib/tsan/sanitizer_common/sanitizer_libignore.cpp+2-2
......@@ -9,7 +9,7 @@
99#include "sanitizer_platform.h"
1010
1111#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_MAC || \
12 SANITIZER_NETBSD || SANITIZER_OPENBSD
12 SANITIZER_NETBSD
1313
1414#include "sanitizer_libignore.h"
1515#include "sanitizer_flags.h"
......@@ -38,7 +38,7 @@ void LibIgnore::AddIgnoredLibrary(const char *name_templ) {
3838void LibIgnore::OnLibraryLoaded(const char *name) {
3939 BlockingMutexLock lock(&mutex_);
4040 // Try to match suppressions with symlink target.
41 InternalScopedString buf(kMaxPathLength);
41 InternalMmapVector<char> buf(kMaxPathLength);
4242 if (name && internal_readlink(name, buf.data(), buf.size() - 1) > 0 &&
4343 buf[0]) {
4444 for (uptr i = 0; i < count_; i++) {
lib/tsan/sanitizer_common/sanitizer_linux.cpp+165-126
......@@ -14,7 +14,7 @@
1414#include "sanitizer_platform.h"
1515
1616#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \
17 SANITIZER_OPENBSD || SANITIZER_SOLARIS
17 SANITIZER_SOLARIS
1818
1919#include "sanitizer_common.h"
2020#include "sanitizer_flags.h"
......@@ -38,6 +38,14 @@
3838#include <asm/unistd.h>
3939#include <sys/types.h>
4040#define stat kernel_stat
41#if SANITIZER_GO
42#undef st_atime
43#undef st_mtime
44#undef st_ctime
45#define st_atime st_atim
46#define st_mtime st_mtim
47#define st_ctime st_ctim
48#endif
4149#include <asm/stat.h>
4250#undef stat
4351#endif
......@@ -59,13 +67,7 @@
5967#include <sys/syscall.h>
6068#include <sys/time.h>
6169#include <sys/types.h>
62#if !SANITIZER_OPENBSD
6370#include <ucontext.h>
64#endif
65#if SANITIZER_OPENBSD
66#include <sys/futex.h>
67#include <sys/sysctl.h>
68#endif
6971#include <unistd.h>
7072
7173#if SANITIZER_LINUX
......@@ -129,7 +131,7 @@ const int FUTEX_WAKE_PRIVATE = FUTEX_WAKE | FUTEX_PRIVATE_FLAG;
129131#endif
130132
131133// Note : FreeBSD had implemented both
132// Linux and OpenBSD apis, available from
134// Linux apis, available from
133135// future 12.x version most likely
134136#if SANITIZER_LINUX && defined(__NR_getrandom)
135137# if !defined(GRND_NONBLOCK)
......@@ -140,20 +142,18 @@ const int FUTEX_WAKE_PRIVATE = FUTEX_WAKE | FUTEX_PRIVATE_FLAG;
140142# define SANITIZER_USE_GETRANDOM 0
141143#endif // SANITIZER_LINUX && defined(__NR_getrandom)
142144
143#if SANITIZER_OPENBSD
144# define SANITIZER_USE_GETENTROPY 1
145#if SANITIZER_FREEBSD && __FreeBSD_version >= 1200000
146# define SANITIZER_USE_GETENTROPY 1
145147#else
146# if SANITIZER_FREEBSD && __FreeBSD_version >= 1200000
147# define SANITIZER_USE_GETENTROPY 1
148# else
149# define SANITIZER_USE_GETENTROPY 0
150# endif
151#endif // SANITIZER_USE_GETENTROPY
148# define SANITIZER_USE_GETENTROPY 0
149#endif
152150
153151namespace __sanitizer {
154152
155153#if SANITIZER_LINUX && defined(__x86_64__)
156154#include "sanitizer_syscall_linux_x86_64.inc"
155#elif SANITIZER_LINUX && SANITIZER_RISCV64
156#include "sanitizer_syscall_linux_riscv64.inc"
157157#elif SANITIZER_LINUX && defined(__aarch64__)
158158#include "sanitizer_syscall_linux_aarch64.inc"
159159#elif SANITIZER_LINUX && defined(__arm__)
......@@ -164,7 +164,7 @@ namespace __sanitizer {
164164
165165// --------------- sanitizer_libc.h
166166#if !SANITIZER_SOLARIS && !SANITIZER_NETBSD
167#if !SANITIZER_S390 && !SANITIZER_OPENBSD
167#if !SANITIZER_S390
168168uptr internal_mmap(void *addr, uptr length, int prot, int flags, int fd,
169169 u64 offset) {
170170#if SANITIZER_FREEBSD || SANITIZER_LINUX_USES_64BIT_SYSCALLS
......@@ -177,17 +177,27 @@ uptr internal_mmap(void *addr, uptr length, int prot, int flags, int fd,
177177 offset / 4096);
178178#endif
179179}
180#endif // !SANITIZER_S390 && !SANITIZER_OPENBSD
180#endif // !SANITIZER_S390
181181
182#if !SANITIZER_OPENBSD
183182uptr internal_munmap(void *addr, uptr length) {
184183 return internal_syscall(SYSCALL(munmap), (uptr)addr, length);
185184}
186185
186#if SANITIZER_LINUX
187uptr internal_mremap(void *old_address, uptr old_size, uptr new_size, int flags,
188 void *new_address) {
189 return internal_syscall(SYSCALL(mremap), (uptr)old_address, old_size,
190 new_size, flags, (uptr)new_address);
191}
192#endif
193
187194int internal_mprotect(void *addr, uptr length, int prot) {
188195 return internal_syscall(SYSCALL(mprotect), (uptr)addr, length, prot);
189196}
190#endif
197
198int internal_madvise(uptr addr, uptr length, int advice) {
199 return internal_syscall(SYSCALL(madvise), addr, length, advice);
200}
191201
192202uptr internal_close(fd_t fd) {
193203 return internal_syscall(SYSCALL(close), fd);
......@@ -254,9 +264,11 @@ static void stat64_to_stat(struct stat64 *in, struct stat *out) {
254264// Undefine compatibility macros from <sys/stat.h>
255265// so that they would not clash with the kernel_stat
256266// st_[a|m|c]time fields
267#if !SANITIZER_GO
257268#undef st_atime
258269#undef st_mtime
259270#undef st_ctime
271#endif
260272#if defined(SANITIZER_ANDROID)
261273// Bionic sys/stat.h defines additional macros
262274// for compatibility with the old NDKs and
......@@ -299,7 +311,7 @@ static void kernel_stat_to_stat(struct kernel_stat *in, struct stat *out) {
299311#endif
300312
301313uptr internal_stat(const char *path, void *buf) {
302#if SANITIZER_FREEBSD || SANITIZER_OPENBSD
314#if SANITIZER_FREEBSD
303315 return internal_syscall(SYSCALL(fstatat), AT_FDCWD, (uptr)path, (uptr)buf, 0);
304316#elif SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
305317 return internal_syscall(SYSCALL(newfstatat), AT_FDCWD, (uptr)path, (uptr)buf,
......@@ -323,7 +335,7 @@ uptr internal_stat(const char *path, void *buf) {
323335}
324336
325337uptr internal_lstat(const char *path, void *buf) {
326#if SANITIZER_FREEBSD || SANITIZER_OPENBSD
338#if SANITIZER_FREEBSD
327339 return internal_syscall(SYSCALL(fstatat), AT_FDCWD, (uptr)path, (uptr)buf,
328340 AT_SYMLINK_NOFOLLOW);
329341#elif SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
......@@ -348,9 +360,8 @@ uptr internal_lstat(const char *path, void *buf) {
348360}
349361
350362uptr internal_fstat(fd_t fd, void *buf) {
351#if SANITIZER_FREEBSD || SANITIZER_OPENBSD || \
352 SANITIZER_LINUX_USES_64BIT_SYSCALLS
353#if SANITIZER_MIPS64 && !SANITIZER_OPENBSD
363#if SANITIZER_FREEBSD || SANITIZER_LINUX_USES_64BIT_SYSCALLS
364#if SANITIZER_MIPS64
354365 // For mips64, fstat syscall fills buffer in the format of kernel_stat
355366 struct kernel_stat kbuf;
356367 int res = internal_syscall(SYSCALL(fstat), fd, &kbuf);
......@@ -390,16 +401,13 @@ uptr internal_readlink(const char *path, char *buf, uptr bufsize) {
390401#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
391402 return internal_syscall(SYSCALL(readlinkat), AT_FDCWD, (uptr)path, (uptr)buf,
392403 bufsize);
393#elif SANITIZER_OPENBSD
394 return internal_syscall(SYSCALL(readlinkat), AT_FDCWD, (uptr)path, (uptr)buf,
395 bufsize);
396404#else
397405 return internal_syscall(SYSCALL(readlink), (uptr)path, (uptr)buf, bufsize);
398406#endif
399407}
400408
401409uptr internal_unlink(const char *path) {
402#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS || SANITIZER_OPENBSD
410#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
403411 return internal_syscall(SYSCALL(unlinkat), AT_FDCWD, (uptr)path, 0);
404412#else
405413 return internal_syscall(SYSCALL(unlink), (uptr)path);
......@@ -410,7 +418,7 @@ uptr internal_rename(const char *oldpath, const char *newpath) {
410418#if defined(__riscv)
411419 return internal_syscall(SYSCALL(renameat2), AT_FDCWD, (uptr)oldpath, AT_FDCWD,
412420 (uptr)newpath, 0);
413#elif SANITIZER_USES_CANONICAL_LINUX_SYSCALLS || SANITIZER_OPENBSD
421#elif SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
414422 return internal_syscall(SYSCALL(renameat), AT_FDCWD, (uptr)oldpath, AT_FDCWD,
415423 (uptr)newpath);
416424#else
......@@ -422,22 +430,11 @@ uptr internal_sched_yield() {
422430 return internal_syscall(SYSCALL(sched_yield));
423431}
424432
425void internal__exit(int exitcode) {
426#if SANITIZER_FREEBSD || SANITIZER_OPENBSD
427 internal_syscall(SYSCALL(exit), exitcode);
428#else
429 internal_syscall(SYSCALL(exit_group), exitcode);
430#endif
431 Die(); // Unreachable.
432}
433
434unsigned int internal_sleep(unsigned int seconds) {
433void internal_usleep(u64 useconds) {
435434 struct timespec ts;
436 ts.tv_sec = seconds;
437 ts.tv_nsec = 0;
438 int res = internal_syscall(SYSCALL(nanosleep), &ts, &ts);
439 if (res) return ts.tv_sec;
440 return 0;
435 ts.tv_sec = useconds / 1000000;
436 ts.tv_nsec = (useconds % 1000000) * 1000;
437 internal_syscall(SYSCALL(nanosleep), &ts, &ts);
441438}
442439
443440uptr internal_execve(const char *filename, char *const argv[],
......@@ -447,6 +444,17 @@ uptr internal_execve(const char *filename, char *const argv[],
447444}
448445#endif // !SANITIZER_SOLARIS && !SANITIZER_NETBSD
449446
447#if !SANITIZER_NETBSD
448void internal__exit(int exitcode) {
449#if SANITIZER_FREEBSD || SANITIZER_SOLARIS
450 internal_syscall(SYSCALL(exit), exitcode);
451#else
452 internal_syscall(SYSCALL(exit_group), exitcode);
453#endif
454 Die(); // Unreachable.
455}
456#endif // !SANITIZER_NETBSD
457
450458// ----------------- sanitizer_common.h
451459bool FileExists(const char *filename) {
452460 if (ShouldMockFailureToOpen(filename))
......@@ -468,8 +476,6 @@ tid_t GetTid() {
468476 long Tid;
469477 thr_self(&Tid);
470478 return Tid;
471#elif SANITIZER_OPENBSD
472 return internal_syscall(SYSCALL(getthrid));
473479#elif SANITIZER_SOLARIS
474480 return thr_self();
475481#else
......@@ -482,9 +488,6 @@ int TgKill(pid_t pid, tid_t tid, int sig) {
482488 return internal_syscall(SYSCALL(tgkill), pid, tid, sig);
483489#elif SANITIZER_FREEBSD
484490 return internal_syscall(SYSCALL(thr_kill2), pid, tid, sig);
485#elif SANITIZER_OPENBSD
486 (void)pid;
487 return internal_syscall(SYSCALL(thrkill), tid, sig, nullptr);
488491#elif SANITIZER_SOLARIS
489492 (void)pid;
490493 return thr_kill(tid, sig);
......@@ -492,29 +495,30 @@ int TgKill(pid_t pid, tid_t tid, int sig) {
492495}
493496#endif
494497
495#if !SANITIZER_SOLARIS && !SANITIZER_NETBSD
498#if SANITIZER_GLIBC
496499u64 NanoTime() {
497#if SANITIZER_FREEBSD || SANITIZER_OPENBSD
498 timeval tv;
499#else
500500 kernel_timeval tv;
501#endif
502501 internal_memset(&tv, 0, sizeof(tv));
503502 internal_syscall(SYSCALL(gettimeofday), &tv, 0);
504 return (u64)tv.tv_sec * 1000*1000*1000 + tv.tv_usec * 1000;
503 return (u64)tv.tv_sec * 1000 * 1000 * 1000 + tv.tv_usec * 1000;
505504}
506
505// Used by real_clock_gettime.
507506uptr internal_clock_gettime(__sanitizer_clockid_t clk_id, void *tp) {
508507 return internal_syscall(SYSCALL(clock_gettime), clk_id, tp);
509508}
510#endif // !SANITIZER_SOLARIS && !SANITIZER_NETBSD
509#elif !SANITIZER_SOLARIS && !SANITIZER_NETBSD
510u64 NanoTime() {
511 struct timespec ts;
512 clock_gettime(CLOCK_REALTIME, &ts);
513 return (u64)ts.tv_sec * 1000 * 1000 * 1000 + ts.tv_nsec;
514}
515#endif
511516
512517// Like getenv, but reads env directly from /proc (on Linux) or parses the
513518// 'environ' array (on some others) and does not use libc. This function
514519// should be called first inside __asan_init.
515520const char *GetEnv(const char *name) {
516#if SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_OPENBSD || \
517 SANITIZER_SOLARIS
521#if SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_SOLARIS
518522 if (::environ != 0) {
519523 uptr NameLen = internal_strlen(name);
520524 for (char **Env = ::environ; *Env != 0; Env++) {
......@@ -552,15 +556,13 @@ const char *GetEnv(const char *name) {
552556#endif
553557}
554558
555#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD && !SANITIZER_OPENBSD && \
556 !SANITIZER_GO
559#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD && !SANITIZER_GO
557560extern "C" {
558561SANITIZER_WEAK_ATTRIBUTE extern void *__libc_stack_end;
559562}
560563#endif
561564
562#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD && \
563 !SANITIZER_OPENBSD
565#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
564566static void ReadNullSepFileToArray(const char *path, char ***arr,
565567 int arr_size) {
566568 char *buff;
......@@ -585,7 +587,6 @@ static void ReadNullSepFileToArray(const char *path, char ***arr,
585587}
586588#endif
587589
588#if !SANITIZER_OPENBSD
589590static void GetArgsAndEnv(char ***argv, char ***envp) {
590591#if SANITIZER_FREEBSD
591592 // On FreeBSD, retrieving the argument and environment arrays is done via the
......@@ -637,14 +638,28 @@ char **GetEnviron() {
637638 return envp;
638639}
639640
640#endif // !SANITIZER_OPENBSD
641
642641#if !SANITIZER_SOLARIS
643enum MutexState {
644 MtxUnlocked = 0,
645 MtxLocked = 1,
646 MtxSleeping = 2
647};
642void FutexWait(atomic_uint32_t *p, u32 cmp) {
643# if SANITIZER_FREEBSD
644 _umtx_op(p, UMTX_OP_WAIT_UINT, cmp, 0, 0);
645# elif SANITIZER_NETBSD
646 sched_yield(); /* No userspace futex-like synchronization */
647# else
648 internal_syscall(SYSCALL(futex), (uptr)p, FUTEX_WAIT_PRIVATE, cmp, 0, 0, 0);
649# endif
650}
651
652void FutexWake(atomic_uint32_t *p, u32 count) {
653# if SANITIZER_FREEBSD
654 _umtx_op(p, UMTX_OP_WAKE, count, 0, 0);
655# elif SANITIZER_NETBSD
656 /* No userspace futex-like synchronization */
657# else
658 internal_syscall(SYSCALL(futex), (uptr)p, FUTEX_WAKE_PRIVATE, count, 0, 0, 0);
659# endif
660}
661
662enum { MtxUnlocked = 0, MtxLocked = 1, MtxSleeping = 2 };
648663
649664BlockingMutex::BlockingMutex() {
650665 internal_memset(this, 0, sizeof(*this));
......@@ -682,11 +697,11 @@ void BlockingMutex::Unlock() {
682697 }
683698}
684699
685void BlockingMutex::CheckLocked() {
686 atomic_uint32_t *m = reinterpret_cast<atomic_uint32_t *>(&opaque_storage_);
700void BlockingMutex::CheckLocked() const {
701 auto m = reinterpret_cast<atomic_uint32_t const *>(&opaque_storage_);
687702 CHECK_NE(MtxUnlocked, atomic_load(m, memory_order_relaxed));
688703}
689#endif // !SANITIZER_SOLARIS
704# endif // !SANITIZER_SOLARIS
690705
691706// ----------------- sanitizer_linux.h
692707// The actual size of this structure is specified by d_reclen.
......@@ -694,19 +709,9 @@ void BlockingMutex::CheckLocked() {
694709// 32-bit syscall here.
695710#if SANITIZER_NETBSD
696711// Not used
697#elif SANITIZER_OPENBSD
698// struct dirent is different for Linux and us. At this moment, we use only
699// d_fileno (Linux call this d_ino), d_reclen, and d_name.
700struct linux_dirent {
701 u64 d_ino; // d_fileno
702 u16 d_reclen;
703 u16 d_namlen; // not used
704 u8 d_type; // not used
705 char d_name[NAME_MAX + 1];
706};
707712#else
708713struct linux_dirent {
709#if SANITIZER_X32 || defined(__aarch64__)
714#if SANITIZER_X32 || defined(__aarch64__) || SANITIZER_RISCV64
710715 u64 d_ino;
711716 u64 d_off;
712717#else
......@@ -714,7 +719,7 @@ struct linux_dirent {
714719 unsigned long d_off;
715720#endif
716721 unsigned short d_reclen;
717#ifdef __aarch64__
722#if defined(__aarch64__) || SANITIZER_RISCV64
718723 unsigned char d_type;
719724#endif
720725 char d_name[256];
......@@ -781,28 +786,39 @@ int internal_fork() {
781786#endif
782787}
783788
784#if SANITIZER_FREEBSD || SANITIZER_OPENBSD
789#if SANITIZER_FREEBSD
785790int internal_sysctl(const int *name, unsigned int namelen, void *oldp,
786791 uptr *oldlenp, const void *newp, uptr newlen) {
787#if SANITIZER_OPENBSD
788 return sysctl(name, namelen, oldp, (size_t *)oldlenp, (void *)newp,
789 (size_t)newlen);
790#else
791792 return internal_syscall(SYSCALL(__sysctl), name, namelen, oldp,
792793 (size_t *)oldlenp, newp, (size_t)newlen);
793#endif
794794}
795795
796#if SANITIZER_FREEBSD
797796int internal_sysctlbyname(const char *sname, void *oldp, uptr *oldlenp,
798797 const void *newp, uptr newlen) {
799 static decltype(sysctlbyname) *real = nullptr;
800 if (!real)
801 real = (decltype(sysctlbyname) *)dlsym(RTLD_NEXT, "sysctlbyname");
802 CHECK(real);
803 return real(sname, oldp, (size_t *)oldlenp, newp, (size_t)newlen);
804}
798 // Note: this function can be called during startup, so we need to avoid
799 // calling any interceptable functions. On FreeBSD >= 1300045 sysctlbyname()
800 // is a real syscall, but for older versions it calls sysctlnametomib()
801 // followed by sysctl(). To avoid calling the intercepted version and
802 // asserting if this happens during startup, call the real sysctlnametomib()
803 // followed by internal_sysctl() if the syscall is not available.
804#ifdef SYS___sysctlbyname
805 return internal_syscall(SYSCALL(__sysctlbyname), sname,
806 internal_strlen(sname), oldp, (size_t *)oldlenp, newp,
807 (size_t)newlen);
808#else
809 static decltype(sysctlnametomib) *real_sysctlnametomib = nullptr;
810 if (!real_sysctlnametomib)
811 real_sysctlnametomib =
812 (decltype(sysctlnametomib) *)dlsym(RTLD_NEXT, "sysctlnametomib");
813 CHECK(real_sysctlnametomib);
814
815 int oid[CTL_MAXNAME];
816 size_t len = CTL_MAXNAME;
817 if (real_sysctlnametomib(sname, oid, &len) == -1)
818 return (-1);
819 return internal_sysctl(oid, len, oldp, oldlenp, newp, newlen);
805820#endif
821}
806822#endif
807823
808824#if SANITIZER_LINUX
......@@ -856,7 +872,7 @@ int internal_sigaction_norestorer(int signum, const void *act, void *oldact) {
856872
857873uptr internal_sigprocmask(int how, __sanitizer_sigset_t *set,
858874 __sanitizer_sigset_t *oldset) {
859#if SANITIZER_FREEBSD || SANITIZER_OPENBSD
875#if SANITIZER_FREEBSD
860876 return internal_syscall(SYSCALL(sigprocmask), how, set, oldset);
861877#else
862878 __sanitizer_kernel_sigset_t *k_set = (__sanitizer_kernel_sigset_t *)set;
......@@ -882,7 +898,7 @@ void internal_sigdelset(__sanitizer_sigset_t *set, int signum) {
882898 __sanitizer_kernel_sigset_t *k_set = (__sanitizer_kernel_sigset_t *)set;
883899 const uptr idx = signum / (sizeof(k_set->sig[0]) * 8);
884900 const uptr bit = signum % (sizeof(k_set->sig[0]) * 8);
885 k_set->sig[idx] &= ~(1 << bit);
901 k_set->sig[idx] &= ~((uptr)1 << bit);
886902}
887903
888904bool internal_sigismember(__sanitizer_sigset_t *set, int signum) {
......@@ -892,7 +908,7 @@ bool internal_sigismember(__sanitizer_sigset_t *set, int signum) {
892908 __sanitizer_kernel_sigset_t *k_set = (__sanitizer_kernel_sigset_t *)set;
893909 const uptr idx = signum / (sizeof(k_set->sig[0]) * 8);
894910 const uptr bit = signum % (sizeof(k_set->sig[0]) * 8);
895 return k_set->sig[idx] & (1 << bit);
911 return k_set->sig[idx] & ((uptr)1 << bit);
896912}
897913#elif SANITIZER_FREEBSD
898914void internal_sigdelset(__sanitizer_sigset_t *set, int signum) {
......@@ -1033,7 +1049,7 @@ static uptr GetKernelAreaSize() {
10331049#endif // SANITIZER_WORDSIZE == 32
10341050
10351051uptr GetMaxVirtualAddress() {
1036#if (SANITIZER_NETBSD || SANITIZER_OPENBSD) && defined(__x86_64__)
1052#if SANITIZER_NETBSD && defined(__x86_64__)
10371053 return 0x7f7ffffff000ULL; // (0x00007f8000000000 - PAGE_SIZE)
10381054#elif SANITIZER_WORDSIZE == 64
10391055# if defined(__powerpc64__) || defined(__aarch64__)
......@@ -1045,6 +1061,8 @@ uptr GetMaxVirtualAddress() {
10451061 // This should (does) work for both PowerPC64 Endian modes.
10461062 // Similarly, aarch64 has multiple address space layouts: 39, 42 and 47-bit.
10471063 return (1ULL << (MostSignificantSetBitIndex(GET_CURRENT_FRAME()) + 1)) - 1;
1064#elif SANITIZER_RISCV64
1065 return (1ULL << 38) - 1;
10481066# elif defined(__mips64)
10491067 return (1ULL << 40) - 1; // 0x000000ffffffffffUL;
10501068# elif defined(__s390x__)
......@@ -1094,7 +1112,6 @@ uptr GetPageSize() {
10941112}
10951113#endif // !SANITIZER_ANDROID
10961114
1097#if !SANITIZER_OPENBSD
10981115uptr ReadBinaryName(/*out*/char *buf, uptr buf_len) {
10991116#if SANITIZER_SOLARIS
11001117 const char *default_module_name = getexecname();
......@@ -1131,7 +1148,6 @@ uptr ReadBinaryName(/*out*/char *buf, uptr buf_len) {
11311148 return module_name_len;
11321149#endif
11331150}
1134#endif // !SANITIZER_OPENBSD
11351151
11361152uptr ReadLongProcessName(/*out*/ char *buf, uptr buf_len) {
11371153#if SANITIZER_LINUX
......@@ -1164,10 +1180,10 @@ bool LibraryNameIs(const char *full_name, const char *base_name) {
11641180// Call cb for each region mapped by map.
11651181void ForEachMappedRegion(link_map *map, void (*cb)(const void *, uptr)) {
11661182 CHECK_NE(map, nullptr);
1167#if !SANITIZER_FREEBSD && !SANITIZER_OPENBSD
1183#if !SANITIZER_FREEBSD
11681184 typedef ElfW(Phdr) Elf_Phdr;
11691185 typedef ElfW(Ehdr) Elf_Ehdr;
1170#endif // !SANITIZER_FREEBSD && !SANITIZER_OPENBSD
1186#endif // !SANITIZER_FREEBSD
11711187 char *base = (char *)map->l_addr;
11721188 Elf_Ehdr *ehdr = (Elf_Ehdr *)base;
11731189 char *phdrs = base + ehdr->e_phoff;
......@@ -1339,6 +1355,47 @@ uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg,
13391355 : "memory", "$29" );
13401356 return res;
13411357}
1358#elif SANITIZER_RISCV64
1359uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg,
1360 int *parent_tidptr, void *newtls, int *child_tidptr) {
1361 if (!fn || !child_stack)
1362 return -EINVAL;
1363
1364 CHECK_EQ(0, (uptr)child_stack % 16);
1365
1366 register int res __asm__("a0");
1367 register int __flags __asm__("a0") = flags;
1368 register void *__stack __asm__("a1") = child_stack;
1369 register int *__ptid __asm__("a2") = parent_tidptr;
1370 register void *__tls __asm__("a3") = newtls;
1371 register int *__ctid __asm__("a4") = child_tidptr;
1372 register int (*__fn)(void *) __asm__("a5") = fn;
1373 register void *__arg __asm__("a6") = arg;
1374 register int nr_clone __asm__("a7") = __NR_clone;
1375
1376 __asm__ __volatile__(
1377 "ecall\n"
1378
1379 /* if (a0 != 0)
1380 * return a0;
1381 */
1382 "bnez a0, 1f\n"
1383
1384 // In the child, now. Call "fn(arg)".
1385 "mv a0, a6\n"
1386 "jalr a5\n"
1387
1388 // Call _exit(a0).
1389 "addi a7, zero, %9\n"
1390 "ecall\n"
1391 "1:\n"
1392
1393 : "=r"(res)
1394 : "0"(__flags), "r"(__stack), "r"(__ptid), "r"(__tls), "r"(__ctid),
1395 "r"(__fn), "r"(__arg), "r"(nr_clone), "i"(__NR_exit)
1396 : "memory");
1397 return res;
1398}
13421399#elif defined(__aarch64__)
13431400uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg,
13441401 int *parent_tidptr, void *newtls, int *child_tidptr) {
......@@ -1768,11 +1825,7 @@ static bool Aarch64GetESR(ucontext_t *ucontext, u64 *esr) {
17681825}
17691826#endif
17701827
1771#if SANITIZER_OPENBSD
1772using Context = sigcontext;
1773#else
17741828using Context = ucontext_t;
1775#endif
17761829
17771830SignalContext::WriteFlag SignalContext::GetWriteFlag() const {
17781831 Context *ucontext = (Context *)context;
......@@ -1782,8 +1835,6 @@ SignalContext::WriteFlag SignalContext::GetWriteFlag() const {
17821835 uptr err = ucontext->uc_mcontext.mc_err;
17831836#elif SANITIZER_NETBSD
17841837 uptr err = ucontext->uc_mcontext.__gregs[_REG_ERR];
1785#elif SANITIZER_OPENBSD
1786 uptr err = ucontext->sc_err;
17871838#elif SANITIZER_SOLARIS && defined(__i386__)
17881839 const int Err = 13;
17891840 uptr err = ucontext->uc_mcontext.gregs[Err];
......@@ -2009,11 +2060,6 @@ static void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) {
20092060 *pc = ucontext->uc_mcontext.mc_rip;
20102061 *bp = ucontext->uc_mcontext.mc_rbp;
20112062 *sp = ucontext->uc_mcontext.mc_rsp;
2012#elif SANITIZER_OPENBSD
2013 sigcontext *ucontext = (sigcontext *)context;
2014 *pc = ucontext->sc_rip;
2015 *bp = ucontext->sc_rbp;
2016 *sp = ucontext->sc_rsp;
20172063# else
20182064 ucontext_t *ucontext = (ucontext_t*)context;
20192065 *pc = ucontext->uc_mcontext.gregs[REG_RIP];
......@@ -2026,11 +2072,6 @@ static void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) {
20262072 *pc = ucontext->uc_mcontext.mc_eip;
20272073 *bp = ucontext->uc_mcontext.mc_ebp;
20282074 *sp = ucontext->uc_mcontext.mc_esp;
2029#elif SANITIZER_OPENBSD
2030 sigcontext *ucontext = (sigcontext *)context;
2031 *pc = ucontext->sc_eip;
2032 *bp = ucontext->sc_ebp;
2033 *sp = ucontext->sc_esp;
20342075# else
20352076 ucontext_t *ucontext = (ucontext_t*)context;
20362077# if SANITIZER_SOLARIS
......@@ -2203,8 +2244,6 @@ void CheckMPROTECT() {
22032244#endif
22042245}
22052246
2206void PrintModuleMap() { }
2207
22082247void CheckNoDeepBind(const char *filename, int flag) {
22092248#ifdef RTLD_DEEPBIND
22102249 if (flag & RTLD_DEEPBIND) {
lib/tsan/sanitizer_common/sanitizer_linux.h+7-7
......@@ -14,12 +14,11 @@
1414
1515#include "sanitizer_platform.h"
1616#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \
17 SANITIZER_OPENBSD || SANITIZER_SOLARIS
17 SANITIZER_SOLARIS
1818#include "sanitizer_common.h"
1919#include "sanitizer_internal_defs.h"
2020#include "sanitizer_platform_limits_freebsd.h"
2121#include "sanitizer_platform_limits_netbsd.h"
22#include "sanitizer_platform_limits_openbsd.h"
2322#include "sanitizer_platform_limits_posix.h"
2423#include "sanitizer_platform_limits_solaris.h"
2524#include "sanitizer_posix.h"
......@@ -50,7 +49,9 @@ uptr internal_getdents(fd_t fd, struct linux_dirent *dirp, unsigned int count);
5049uptr internal_sigaltstack(const void* ss, void* oss);
5150uptr internal_sigprocmask(int how, __sanitizer_sigset_t *set,
5251 __sanitizer_sigset_t *oldset);
52#if SANITIZER_GLIBC
5353uptr internal_clock_gettime(__sanitizer_clockid_t clk_id, void *tp);
54#endif
5455
5556// Linux-only syscalls.
5657#if SANITIZER_LINUX
......@@ -60,9 +61,9 @@ uptr internal_prctl(int option, uptr arg2, uptr arg3, uptr arg4, uptr arg5);
6061// internal_sigaction instead.
6162int internal_sigaction_norestorer(int signum, const void *act, void *oldact);
6263void internal_sigdelset(__sanitizer_sigset_t *set, int signum);
63#if defined(__x86_64__) || defined(__mips__) || defined(__aarch64__) \
64 || defined(__powerpc64__) || defined(__s390__) || defined(__i386__) \
65 || defined(__arm__)
64#if defined(__x86_64__) || defined(__mips__) || defined(__aarch64__) || \
65 defined(__powerpc64__) || defined(__s390__) || defined(__i386__) || \
66 defined(__arm__) || SANITIZER_RISCV64
6667uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg,
6768 int *parent_tidptr, void *newtls, int *child_tidptr);
6869#endif
......@@ -97,7 +98,6 @@ class ThreadLister {
9798// Exposed for testing.
9899uptr ThreadDescriptorSize();
99100uptr ThreadSelf();
100uptr ThreadSelfOffset();
101101
102102// Matches a library's file name against a base name (stripping path and version
103103// information).
......@@ -109,7 +109,7 @@ void ForEachMappedRegion(link_map *map, void (*cb)(const void *, uptr));
109109// Releases memory pages entirely within the [beg, end] address range.
110110// The pages no longer count toward RSS; reads are guaranteed to return 0.
111111// Requires (but does not verify!) that pages are MAP_PRIVATE.
112INLINE void ReleaseMemoryPagesToOSAndZeroFill(uptr beg, uptr end) {
112inline void ReleaseMemoryPagesToOSAndZeroFill(uptr beg, uptr end) {
113113 // man madvise on Linux promises zero-fill for anonymous private pages.
114114 // Testing shows the same behaviour for private (but not anonymous) mappings
115115 // of shm_open() files, as long as the underlying file is untouched.
lib/tsan/sanitizer_common/sanitizer_linux_libcdep.cpp+383-229
......@@ -13,8 +13,8 @@
1313
1414#include "sanitizer_platform.h"
1515
16#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \
17 SANITIZER_OPENBSD || SANITIZER_SOLARIS
16#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \
17 SANITIZER_SOLARIS
1818
1919#include "sanitizer_allocator_internal.h"
2020#include "sanitizer_atomic.h"
......@@ -28,10 +28,15 @@
2828#include "sanitizer_placement_new.h"
2929#include "sanitizer_procmaps.h"
3030
31#if SANITIZER_NETBSD
32#define _RTLD_SOURCE // for __lwp_gettcb_fast() / __lwp_getprivate_fast()
33#endif
34
3135#include <dlfcn.h> // for dlsym()
3236#include <link.h>
3337#include <pthread.h>
3438#include <signal.h>
39#include <sys/mman.h>
3540#include <sys/resource.h>
3641#include <syslog.h>
3742
......@@ -44,11 +49,10 @@
4449#include <osreldate.h>
4550#include <sys/sysctl.h>
4651#define pthread_getattr_np pthread_attr_get_np
47#endif
48
49#if SANITIZER_OPENBSD
50#include <pthread_np.h>
51#include <sys/sysctl.h>
52// The MAP_NORESERVE define has been removed in FreeBSD 11.x, and even before
53// that, it was never implemented. So just define it to zero.
54#undef MAP_NORESERVE
55#define MAP_NORESERVE 0
5256#endif
5357
5458#if SANITIZER_NETBSD
......@@ -138,18 +142,13 @@ void GetThreadStackTopAndBottom(bool at_initialization, uptr *stack_top,
138142 CHECK_EQ(thr_stksegment(&ss), 0);
139143 stacksize = ss.ss_size;
140144 stackaddr = (char *)ss.ss_sp - stacksize;
141#elif SANITIZER_OPENBSD
142 stack_t sattr;
143 CHECK_EQ(pthread_stackseg_np(pthread_self(), &sattr), 0);
144 stackaddr = sattr.ss_sp;
145 stacksize = sattr.ss_size;
146145#else // !SANITIZER_SOLARIS
147146 pthread_attr_t attr;
148147 pthread_attr_init(&attr);
149148 CHECK_EQ(pthread_getattr_np(pthread_self(), &attr), 0);
150149 my_pthread_attr_getstack(&attr, &stackaddr, &stacksize);
151150 pthread_attr_destroy(&attr);
152#endif // SANITIZER_SOLARIS
151#endif // SANITIZER_SOLARIS
153152
154153 *stack_top = (uptr)stackaddr + stacksize;
155154 *stack_bottom = (uptr)stackaddr;
......@@ -189,86 +188,35 @@ __attribute__((unused)) static bool GetLibcVersion(int *major, int *minor,
189188#endif
190189}
191190
192#if !SANITIZER_FREEBSD && !SANITIZER_ANDROID && !SANITIZER_GO && \
193 !SANITIZER_NETBSD && !SANITIZER_OPENBSD && !SANITIZER_SOLARIS
194static uptr g_tls_size;
195
196#ifdef __i386__
197# define CHECK_GET_TLS_STATIC_INFO_VERSION (!__GLIBC_PREREQ(2, 27))
198#else
199# define CHECK_GET_TLS_STATIC_INFO_VERSION 0
200#endif
201
202#if CHECK_GET_TLS_STATIC_INFO_VERSION
203# define DL_INTERNAL_FUNCTION __attribute__((regparm(3), stdcall))
204#else
205# define DL_INTERNAL_FUNCTION
206#endif
207
208namespace {
209struct GetTlsStaticInfoCall {
210 typedef void (*get_tls_func)(size_t*, size_t*);
211};
212struct GetTlsStaticInfoRegparmCall {
213 typedef void (*get_tls_func)(size_t*, size_t*) DL_INTERNAL_FUNCTION;
214};
215
216template <typename T>
217void CallGetTls(void* ptr, size_t* size, size_t* align) {
218 typename T::get_tls_func get_tls;
219 CHECK_EQ(sizeof(get_tls), sizeof(ptr));
220 internal_memcpy(&get_tls, &ptr, sizeof(ptr));
221 CHECK_NE(get_tls, 0);
222 get_tls(size, align);
223}
224
225bool CmpLibcVersion(int major, int minor, int patch) {
226 int ma;
227 int mi;
228 int pa;
229 if (!GetLibcVersion(&ma, &mi, &pa))
230 return false;
231 if (ma > major)
232 return true;
233 if (ma < major)
234 return false;
235 if (mi > minor)
236 return true;
237 if (mi < minor)
238 return false;
239 return pa >= patch;
240}
241
242} // namespace
191// True if we can use dlpi_tls_data. glibc before 2.25 may leave NULL (BZ
192// #19826) so dlpi_tls_data cannot be used.
193//
194// musl before 1.2.3 and FreeBSD as of 12.2 incorrectly set dlpi_tls_data to
195// the TLS initialization image
196// https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=254774
197__attribute__((unused)) static int g_use_dlpi_tls_data;
243198
199#if SANITIZER_GLIBC && !SANITIZER_GO
200__attribute__((unused)) static size_t g_tls_size;
244201void InitTlsSize() {
245 // all current supported platforms have 16 bytes stack alignment
246 const size_t kStackAlign = 16;
247 void *get_tls_static_info_ptr = dlsym(RTLD_NEXT, "_dl_get_tls_static_info");
248 size_t tls_size = 0;
249 size_t tls_align = 0;
250 // On i?86, _dl_get_tls_static_info used to be internal_function, i.e.
251 // __attribute__((regparm(3), stdcall)) before glibc 2.27 and is normal
252 // function in 2.27 and later.
253 if (CHECK_GET_TLS_STATIC_INFO_VERSION && !CmpLibcVersion(2, 27, 0))
254 CallGetTls<GetTlsStaticInfoRegparmCall>(get_tls_static_info_ptr,
255 &tls_size, &tls_align);
256 else
257 CallGetTls<GetTlsStaticInfoCall>(get_tls_static_info_ptr,
258 &tls_size, &tls_align);
259 if (tls_align < kStackAlign)
260 tls_align = kStackAlign;
261 g_tls_size = RoundUpTo(tls_size, tls_align);
202 int major, minor, patch;
203 g_use_dlpi_tls_data =
204 GetLibcVersion(&major, &minor, &patch) && major == 2 && minor >= 25;
205
206#if defined(__aarch64__) || defined(__x86_64__) || defined(__powerpc64__)
207 void *get_tls_static_info = dlsym(RTLD_NEXT, "_dl_get_tls_static_info");
208 size_t tls_align;
209 ((void (*)(size_t *, size_t *))get_tls_static_info)(&g_tls_size, &tls_align);
210#endif
262211}
263212#else
264213void InitTlsSize() { }
265#endif // !SANITIZER_FREEBSD && !SANITIZER_ANDROID && !SANITIZER_GO &&
266 // !SANITIZER_NETBSD && !SANITIZER_SOLARIS
214#endif // SANITIZER_GLIBC && !SANITIZER_GO
267215
268#if (defined(__x86_64__) || defined(__i386__) || defined(__mips__) || \
269 defined(__aarch64__) || defined(__powerpc64__) || defined(__s390__) || \
270 defined(__arm__)) && \
271 SANITIZER_LINUX && !SANITIZER_ANDROID
216// On glibc x86_64, ThreadDescriptorSize() needs to be precise due to the usage
217// of g_tls_size. On other targets, ThreadDescriptorSize() is only used by lsan
218// to get the pointer to thread-specific data keys in the thread control block.
219#if (SANITIZER_FREEBSD || SANITIZER_LINUX) && !SANITIZER_ANDROID
272220// sizeof(struct pthread) from glibc.
273221static atomic_uintptr_t thread_descriptor_size;
274222
......@@ -301,41 +249,58 @@ uptr ThreadDescriptorSize() {
301249 val = FIRST_32_SECOND_64(1168, 2288);
302250 else if (minor <= 14)
303251 val = FIRST_32_SECOND_64(1168, 2304);
304 else
252 else if (minor < 32) // Unknown version
305253 val = FIRST_32_SECOND_64(1216, 2304);
254 else // minor == 32
255 val = FIRST_32_SECOND_64(1344, 2496);
306256 }
257#elif defined(__s390__) || defined(__sparc__)
258 // The size of a prefix of TCB including pthread::{specific_1stblock,specific}
259 // suffices. Just return offsetof(struct pthread, specific_used), which hasn't
260 // changed since 2007-05. Technically this applies to i386/x86_64 as well but
261 // we call _dl_get_tls_static_info and need the precise size of struct
262 // pthread.
263 return FIRST_32_SECOND_64(524, 1552);
307264#elif defined(__mips__)
308265 // TODO(sagarthakur): add more values as per different glibc versions.
309266 val = FIRST_32_SECOND_64(1152, 1776);
267#elif SANITIZER_RISCV64
268 int major;
269 int minor;
270 int patch;
271 if (GetLibcVersion(&major, &minor, &patch) && major == 2) {
272 // TODO: consider adding an optional runtime check for an unknown (untested)
273 // glibc version
274 if (minor <= 28) // WARNING: the highest tested version is 2.29
275 val = 1772; // no guarantees for this one
276 else if (minor <= 31)
277 val = 1772; // tested against glibc 2.29, 2.31
278 else
279 val = 1936; // tested against glibc 2.32
280 }
281
310282#elif defined(__aarch64__)
311283 // The sizeof (struct pthread) is the same from GLIBC 2.17 to 2.22.
312284 val = 1776;
313285#elif defined(__powerpc64__)
314286 val = 1776; // from glibc.ppc64le 2.20-8.fc21
315#elif defined(__s390__)
316 val = FIRST_32_SECOND_64(1152, 1776); // valid for glibc 2.22
317287#endif
318288 if (val)
319289 atomic_store_relaxed(&thread_descriptor_size, val);
320290 return val;
321291}
322292
323// The offset at which pointer to self is located in the thread descriptor.
324const uptr kThreadSelfOffset = FIRST_32_SECOND_64(8, 16);
325
326uptr ThreadSelfOffset() {
327 return kThreadSelfOffset;
328}
329
330#if defined(__mips__) || defined(__powerpc64__)
293#if defined(__mips__) || defined(__powerpc64__) || SANITIZER_RISCV64
331294// TlsPreTcbSize includes size of struct pthread_descr and size of tcb
332295// head structure. It lies before the static tls blocks.
333296static uptr TlsPreTcbSize() {
334# if defined(__mips__)
297#if defined(__mips__)
335298 const uptr kTcbHead = 16; // sizeof (tcbhead_t)
336# elif defined(__powerpc64__)
299#elif defined(__powerpc64__)
337300 const uptr kTcbHead = 88; // sizeof (tcbhead_t)
338# endif
301#elif SANITIZER_RISCV64
302 const uptr kTcbHead = 16; // sizeof (tcbhead_t)
303#endif
339304 const uptr kTlsAlign = 16;
340305 const uptr kTlsPreTcbSize =
341306 RoundUpTo(ThreadDescriptorSize() + kTcbHead, kTlsAlign);
......@@ -343,68 +308,107 @@ static uptr TlsPreTcbSize() {
343308}
344309#endif
345310
346uptr ThreadSelf() {
347 uptr descr_addr;
348# if defined(__i386__)
349 asm("mov %%gs:%c1,%0" : "=r"(descr_addr) : "i"(kThreadSelfOffset));
350# elif defined(__x86_64__)
351 asm("mov %%fs:%c1,%0" : "=r"(descr_addr) : "i"(kThreadSelfOffset));
352# elif defined(__mips__)
353 // MIPS uses TLS variant I. The thread pointer (in hardware register $29)
354 // points to the end of the TCB + 0x7000. The pthread_descr structure is
355 // immediately in front of the TCB. TlsPreTcbSize() includes the size of the
356 // TCB and the size of pthread_descr.
357 const uptr kTlsTcbOffset = 0x7000;
358 uptr thread_pointer;
359 asm volatile(".set push;\
360 .set mips64r2;\
361 rdhwr %0,$29;\
362 .set pop" : "=r" (thread_pointer));
363 descr_addr = thread_pointer - kTlsTcbOffset - TlsPreTcbSize();
364# elif defined(__aarch64__) || defined(__arm__)
365 descr_addr = reinterpret_cast<uptr>(__builtin_thread_pointer()) -
366 ThreadDescriptorSize();
367# elif defined(__s390__)
368 descr_addr = reinterpret_cast<uptr>(__builtin_thread_pointer());
369# elif defined(__powerpc64__)
370 // PPC64LE uses TLS variant I. The thread pointer (in GPR 13)
371 // points to the end of the TCB + 0x7000. The pthread_descr structure is
372 // immediately in front of the TCB. TlsPreTcbSize() includes the size of the
373 // TCB and the size of pthread_descr.
374 const uptr kTlsTcbOffset = 0x7000;
375 uptr thread_pointer;
376 asm("addi %0,13,%1" : "=r"(thread_pointer) : "I"(-kTlsTcbOffset));
377 descr_addr = thread_pointer - TlsPreTcbSize();
378# else
379# error "unsupported CPU arch"
380# endif
381 return descr_addr;
382}
383#endif // (x86_64 || i386 || MIPS) && SANITIZER_LINUX
311#if !SANITIZER_GO
312namespace {
313struct TlsBlock {
314 uptr begin, end, align;
315 size_t tls_modid;
316 bool operator<(const TlsBlock &rhs) const { return begin < rhs.begin; }
317};
318} // namespace
384319
385#if SANITIZER_FREEBSD
386static void **ThreadSelfSegbase() {
387 void **segbase = 0;
388# if defined(__i386__)
389 // sysarch(I386_GET_GSBASE, segbase);
390 __asm __volatile("mov %%gs:0, %0" : "=r" (segbase));
391# elif defined(__x86_64__)
392 // sysarch(AMD64_GET_FSBASE, segbase);
393 __asm __volatile("movq %%fs:0, %0" : "=r" (segbase));
394# else
395# error "unsupported CPU arch"
396# endif
397 return segbase;
320#ifdef __s390__
321extern "C" uptr __tls_get_offset(void *arg);
322
323static uptr TlsGetOffset(uptr ti_module, uptr ti_offset) {
324 // The __tls_get_offset ABI requires %r12 to point to GOT and %r2 to be an
325 // offset of a struct tls_index inside GOT. We don't possess either of the
326 // two, so violate the letter of the "ELF Handling For Thread-Local
327 // Storage" document and assume that the implementation just dereferences
328 // %r2 + %r12.
329 uptr tls_index[2] = {ti_module, ti_offset};
330 register uptr r2 asm("2") = 0;
331 register void *r12 asm("12") = tls_index;
332 asm("basr %%r14, %[__tls_get_offset]"
333 : "+r"(r2)
334 : [__tls_get_offset] "r"(__tls_get_offset), "r"(r12)
335 : "memory", "cc", "0", "1", "3", "4", "5", "14");
336 return r2;
398337}
338#else
339extern "C" void *__tls_get_addr(size_t *);
340#endif
399341
400uptr ThreadSelf() {
401 return (uptr)ThreadSelfSegbase()[2];
342static int CollectStaticTlsBlocks(struct dl_phdr_info *info, size_t size,
343 void *data) {
344 if (!info->dlpi_tls_modid)
345 return 0;
346 uptr begin = (uptr)info->dlpi_tls_data;
347 if (!g_use_dlpi_tls_data) {
348 // Call __tls_get_addr as a fallback. This forces TLS allocation on glibc
349 // and FreeBSD.
350#ifdef __s390__
351 begin = (uptr)__builtin_thread_pointer() +
352 TlsGetOffset(info->dlpi_tls_modid, 0);
353#else
354 size_t mod_and_off[2] = {info->dlpi_tls_modid, 0};
355 begin = (uptr)__tls_get_addr(mod_and_off);
356#endif
357 }
358 for (unsigned i = 0; i != info->dlpi_phnum; ++i)
359 if (info->dlpi_phdr[i].p_type == PT_TLS) {
360 static_cast<InternalMmapVector<TlsBlock> *>(data)->push_back(
361 TlsBlock{begin, begin + info->dlpi_phdr[i].p_memsz,
362 info->dlpi_phdr[i].p_align, info->dlpi_tls_modid});
363 break;
364 }
365 return 0;
402366}
403#endif // SANITIZER_FREEBSD
367
368__attribute__((unused)) static void GetStaticTlsBoundary(uptr *addr, uptr *size,
369 uptr *align) {
370 InternalMmapVector<TlsBlock> ranges;
371 dl_iterate_phdr(CollectStaticTlsBlocks, &ranges);
372 uptr len = ranges.size();
373 Sort(ranges.begin(), len);
374 // Find the range with tls_modid=1. For glibc, because libc.so uses PT_TLS,
375 // this module is guaranteed to exist and is one of the initially loaded
376 // modules.
377 uptr one = 0;
378 while (one != len && ranges[one].tls_modid != 1) ++one;
379 if (one == len) {
380 // This may happen with musl if no module uses PT_TLS.
381 *addr = 0;
382 *size = 0;
383 *align = 1;
384 return;
385 }
386 // Find the maximum consecutive ranges. We consider two modules consecutive if
387 // the gap is smaller than the alignment. The dynamic loader places static TLS
388 // blocks this way not to waste space.
389 uptr l = one;
390 *align = ranges[l].align;
391 while (l != 0 && ranges[l].begin < ranges[l - 1].end + ranges[l - 1].align)
392 *align = Max(*align, ranges[--l].align);
393 uptr r = one + 1;
394 while (r != len && ranges[r].begin < ranges[r - 1].end + ranges[r - 1].align)
395 *align = Max(*align, ranges[r++].align);
396 *addr = ranges[l].begin;
397 *size = ranges[r - 1].end - ranges[l].begin;
398}
399#endif // !SANITIZER_GO
400#endif // (x86_64 || i386 || mips || ...) && (SANITIZER_FREEBSD ||
401 // SANITIZER_LINUX) && !SANITIZER_ANDROID
404402
405403#if SANITIZER_NETBSD
406404static struct tls_tcb * ThreadSelfTlsTcb() {
407 return (struct tls_tcb *)_lwp_getprivate();
405 struct tls_tcb *tcb = nullptr;
406#ifdef __HAVE___LWP_GETTCB_FAST
407 tcb = (struct tls_tcb *)__lwp_gettcb_fast();
408#elif defined(__HAVE___LWP_GETPRIVATE_FAST)
409 tcb = (struct tls_tcb *)__lwp_getprivate_fast();
410#endif
411 return tcb;
408412}
409413
410414uptr ThreadSelf() {
......@@ -425,35 +429,91 @@ int GetSizeFromHdr(struct dl_phdr_info *info, size_t size, void *data) {
425429}
426430#endif // SANITIZER_NETBSD
427431
432#if SANITIZER_ANDROID
433// Bionic provides this API since S.
434extern "C" SANITIZER_WEAK_ATTRIBUTE void __libc_get_static_tls_bounds(void **,
435 void **);
436#endif
437
428438#if !SANITIZER_GO
429439static void GetTls(uptr *addr, uptr *size) {
430#if SANITIZER_LINUX && !SANITIZER_ANDROID
431# if defined(__x86_64__) || defined(__i386__) || defined(__s390__)
432 *addr = ThreadSelf();
433 *size = GetTlsSize();
440#if SANITIZER_ANDROID
441 if (&__libc_get_static_tls_bounds) {
442 void *start_addr;
443 void *end_addr;
444 __libc_get_static_tls_bounds(&start_addr, &end_addr);
445 *addr = reinterpret_cast<uptr>(start_addr);
446 *size =
447 reinterpret_cast<uptr>(end_addr) - reinterpret_cast<uptr>(start_addr);
448 } else {
449 *addr = 0;
450 *size = 0;
451 }
452#elif SANITIZER_GLIBC && defined(__x86_64__)
453 // For aarch64 and x86-64, use an O(1) approach which requires relatively
454 // precise ThreadDescriptorSize. g_tls_size was initialized in InitTlsSize.
455 asm("mov %%fs:16,%0" : "=r"(*addr));
456 *size = g_tls_size;
434457 *addr -= *size;
435458 *addr += ThreadDescriptorSize();
436# elif defined(__mips__) || defined(__aarch64__) || defined(__powerpc64__) \
437 || defined(__arm__)
438 *addr = ThreadSelf();
439 *size = GetTlsSize();
440# else
441 *addr = 0;
442 *size = 0;
443# endif
444#elif SANITIZER_FREEBSD
445 void** segbase = ThreadSelfSegbase();
446 *addr = 0;
447 *size = 0;
448 if (segbase != 0) {
449 // tcbalign = 16
450 // tls_size = round(tls_static_space, tcbalign);
451 // dtv = segbase[1];
452 // dtv[2] = segbase - tls_static_space;
453 void **dtv = (void**) segbase[1];
454 *addr = (uptr) dtv[2];
455 *size = (*addr == 0) ? 0 : ((uptr) segbase[0] - (uptr) dtv[2]);
459#elif SANITIZER_GLIBC && defined(__aarch64__)
460 *addr = reinterpret_cast<uptr>(__builtin_thread_pointer()) -
461 ThreadDescriptorSize();
462 *size = g_tls_size + ThreadDescriptorSize();
463#elif SANITIZER_GLIBC && defined(__powerpc64__)
464 // Workaround for glibc<2.25(?). 2.27 is known to not need this.
465 uptr tp;
466 asm("addi %0,13,-0x7000" : "=r"(tp));
467 const uptr pre_tcb_size = TlsPreTcbSize();
468 *addr = tp - pre_tcb_size;
469 *size = g_tls_size + pre_tcb_size;
470#elif SANITIZER_FREEBSD || SANITIZER_LINUX
471 uptr align;
472 GetStaticTlsBoundary(addr, size, &align);
473#if defined(__x86_64__) || defined(__i386__) || defined(__s390__) || \
474 defined(__sparc__)
475 if (SANITIZER_GLIBC) {
476#if defined(__x86_64__) || defined(__i386__)
477 align = Max<uptr>(align, 64);
478#else
479 align = Max<uptr>(align, 16);
480#endif
456481 }
482 const uptr tp = RoundUpTo(*addr + *size, align);
483
484 // lsan requires the range to additionally cover the static TLS surplus
485 // (elf/dl-tls.c defines 1664). Otherwise there may be false positives for
486 // allocations only referenced by tls in dynamically loaded modules.
487 if (SANITIZER_GLIBC)
488 *size += 1644;
489 else if (SANITIZER_FREEBSD)
490 *size += 128; // RTLD_STATIC_TLS_EXTRA
491
492 // Extend the range to include the thread control block. On glibc, lsan needs
493 // the range to include pthread::{specific_1stblock,specific} so that
494 // allocations only referenced by pthread_setspecific can be scanned. This may
495 // underestimate by at most TLS_TCB_ALIGN-1 bytes but it should be fine
496 // because the number of bytes after pthread::specific is larger.
497 *addr = tp - RoundUpTo(*size, align);
498 *size = tp - *addr + ThreadDescriptorSize();
499#else
500 if (SANITIZER_GLIBC)
501 *size += 1664;
502 else if (SANITIZER_FREEBSD)
503 *size += 128; // RTLD_STATIC_TLS_EXTRA
504#if defined(__mips__) || defined(__powerpc64__) || SANITIZER_RISCV64
505 const uptr pre_tcb_size = TlsPreTcbSize();
506 *addr -= pre_tcb_size;
507 *size += pre_tcb_size;
508#else
509 // arm and aarch64 reserve two words at TP, so this underestimates the range.
510 // However, this is sufficient for the purpose of finding the pointers to
511 // thread-specific data keys.
512 const uptr tcb_size = ThreadDescriptorSize();
513 *addr -= tcb_size;
514 *size += tcb_size;
515#endif
516#endif
457517#elif SANITIZER_NETBSD
458518 struct tls_tcb * const tcb = ThreadSelfTlsTcb();
459519 *addr = 0;
......@@ -468,33 +528,25 @@ static void GetTls(uptr *addr, uptr *size) {
468528 *addr = (uptr)tcb->tcb_dtv[1];
469529 }
470530 }
471#elif SANITIZER_OPENBSD
472 *addr = 0;
473 *size = 0;
474#elif SANITIZER_ANDROID
475 *addr = 0;
476 *size = 0;
477531#elif SANITIZER_SOLARIS
478532 // FIXME
479533 *addr = 0;
480534 *size = 0;
481535#else
482# error "Unknown OS"
536#error "Unknown OS"
483537#endif
484538}
485539#endif
486540
487541#if !SANITIZER_GO
488542uptr GetTlsSize() {
489#if SANITIZER_FREEBSD || SANITIZER_ANDROID || SANITIZER_NETBSD || \
490 SANITIZER_OPENBSD || SANITIZER_SOLARIS
543#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \
544 SANITIZER_SOLARIS
491545 uptr addr, size;
492546 GetTls(&addr, &size);
493547 return size;
494#elif defined(__mips__) || defined(__powerpc64__)
495 return RoundUpTo(g_tls_size + TlsPreTcbSize(), 16);
496548#else
497 return g_tls_size;
549 return 0;
498550#endif
499551}
500552#endif
......@@ -515,42 +567,33 @@ void GetThreadStackAndTls(bool main, uptr *stk_addr, uptr *stk_size,
515567 if (!main) {
516568 // If stack and tls intersect, make them non-intersecting.
517569 if (*tls_addr > *stk_addr && *tls_addr < *stk_addr + *stk_size) {
518 CHECK_GT(*tls_addr + *tls_size, *stk_addr);
519 CHECK_LE(*tls_addr + *tls_size, *stk_addr + *stk_size);
520 *stk_size -= *tls_size;
521 *tls_addr = *stk_addr + *stk_size;
570 if (*stk_addr + *stk_size < *tls_addr + *tls_size)
571 *tls_size = *stk_addr + *stk_size - *tls_addr;
572 *stk_size = *tls_addr - *stk_addr;
522573 }
523574 }
524575#endif
525576}
526577
527#if !SANITIZER_FREEBSD && !SANITIZER_OPENBSD
578#if !SANITIZER_FREEBSD
528579typedef ElfW(Phdr) Elf_Phdr;
529#elif SANITIZER_WORDSIZE == 32 && __FreeBSD_version <= 902001 // v9.2
580#elif SANITIZER_WORDSIZE == 32 && __FreeBSD_version <= 902001 // v9.2
530581#define Elf_Phdr XElf32_Phdr
531582#define dl_phdr_info xdl_phdr_info
532583#define dl_iterate_phdr(c, b) xdl_iterate_phdr((c), (b))
533#endif // !SANITIZER_FREEBSD && !SANITIZER_OPENBSD
584#endif // !SANITIZER_FREEBSD
534585
535586struct DlIteratePhdrData {
536587 InternalMmapVectorNoCtor<LoadedModule> *modules;
537588 bool first;
538589};
539590
540static int dl_iterate_phdr_cb(dl_phdr_info *info, size_t size, void *arg) {
541 DlIteratePhdrData *data = (DlIteratePhdrData*)arg;
542 InternalScopedString module_name(kMaxPathLength);
543 if (data->first) {
544 data->first = false;
545 // First module is the binary itself.
546 ReadBinaryNameCached(module_name.data(), module_name.size());
547 } else if (info->dlpi_name) {
548 module_name.append("%s", info->dlpi_name);
549 }
591static int AddModuleSegments(const char *module_name, dl_phdr_info *info,
592 InternalMmapVectorNoCtor<LoadedModule> *modules) {
550593 if (module_name[0] == '\0')
551594 return 0;
552595 LoadedModule cur_module;
553 cur_module.set(module_name.data(), info->dlpi_addr);
596 cur_module.set(module_name, info->dlpi_addr);
554597 for (int i = 0; i < (int)info->dlpi_phnum; i++) {
555598 const Elf_Phdr *phdr = &info->dlpi_phdr[i];
556599 if (phdr->p_type == PT_LOAD) {
......@@ -562,7 +605,26 @@ static int dl_iterate_phdr_cb(dl_phdr_info *info, size_t size, void *arg) {
562605 writable);
563606 }
564607 }
565 data->modules->push_back(cur_module);
608 modules->push_back(cur_module);
609 return 0;
610}
611
612static int dl_iterate_phdr_cb(dl_phdr_info *info, size_t size, void *arg) {
613 DlIteratePhdrData *data = (DlIteratePhdrData *)arg;
614 if (data->first) {
615 InternalMmapVector<char> module_name(kMaxPathLength);
616 data->first = false;
617 // First module is the binary itself.
618 ReadBinaryNameCached(module_name.data(), module_name.size());
619 return AddModuleSegments(module_name.data(), info, data->modules);
620 }
621
622 if (info->dlpi_name) {
623 InternalScopedString module_name;
624 module_name.append("%s", info->dlpi_name);
625 return AddModuleSegments(module_name.data(), info, data->modules);
626 }
627
566628 return 0;
567629}
568630
......@@ -650,7 +712,7 @@ uptr GetRSS() {
650712// sysconf(_SC_NPROCESSORS_{CONF,ONLN}) cannot be used on most platforms as
651713// they allocate memory.
652714u32 GetNumberOfCPUs() {
653#if SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_OPENBSD
715#if SANITIZER_FREEBSD || SANITIZER_NETBSD
654716 u32 ncpu;
655717 int req[2];
656718 uptr len = sizeof(ncpu);
......@@ -705,7 +767,7 @@ u32 GetNumberOfCPUs() {
705767
706768#if SANITIZER_LINUX
707769
708# if SANITIZER_ANDROID
770#if SANITIZER_ANDROID
709771static atomic_uint8_t android_log_initialized;
710772
711773void AndroidLogInit() {
......@@ -749,7 +811,7 @@ void SetAbortMessage(const char *str) {
749811 if (&android_set_abort_message)
750812 android_set_abort_message(str);
751813}
752# else
814#else
753815void AndroidLogInit() {}
754816
755817static bool ShouldLogAfterPrintf() { return true; }
......@@ -757,7 +819,7 @@ static bool ShouldLogAfterPrintf() { return true; }
757819void WriteOneLineToSyslog(const char *s) { syslog(LOG_INFO, "%s", s); }
758820
759821void SetAbortMessage(const char *str) {}
760# endif // SANITIZER_ANDROID
822#endif // SANITIZER_ANDROID
761823
762824void LogMessageOnPrintf(const char *str) {
763825 if (common_flags()->log_to_syslog && ShouldLogAfterPrintf())
......@@ -766,20 +828,13 @@ void LogMessageOnPrintf(const char *str) {
766828
767829#endif // SANITIZER_LINUX
768830
769#if SANITIZER_LINUX && !SANITIZER_GO
831#if SANITIZER_GLIBC && !SANITIZER_GO
770832// glibc crashes when using clock_gettime from a preinit_array function as the
771833// vDSO function pointers haven't been initialized yet. __progname is
772834// initialized after the vDSO function pointers, so if it exists, is not null
773835// and is not empty, we can use clock_gettime.
774836extern "C" SANITIZER_WEAK_ATTRIBUTE char *__progname;
775INLINE bool CanUseVDSO() {
776 // Bionic is safe, it checks for the vDSO function pointers to be initialized.
777 if (SANITIZER_ANDROID)
778 return true;
779 if (&__progname && __progname && *__progname)
780 return true;
781 return false;
782}
837inline bool CanUseVDSO() { return &__progname && __progname && *__progname; }
783838
784839// MonotonicNanoTime is a timing function that can leverage the vDSO by calling
785840// clock_gettime. real_clock_gettime only exists if clock_gettime is
......@@ -799,15 +854,14 @@ u64 MonotonicNanoTime() {
799854 return (u64)ts.tv_sec * (1000ULL * 1000 * 1000) + ts.tv_nsec;
800855}
801856#else
802// Non-Linux & Go always use the syscall.
857// Non-glibc & Go always use the regular function.
803858u64 MonotonicNanoTime() {
804859 timespec ts;
805 internal_clock_gettime(CLOCK_MONOTONIC, &ts);
860 clock_gettime(CLOCK_MONOTONIC, &ts);
806861 return (u64)ts.tv_sec * (1000ULL * 1000 * 1000) + ts.tv_nsec;
807862}
808#endif // SANITIZER_LINUX && !SANITIZER_GO
863#endif // SANITIZER_GLIBC && !SANITIZER_GO
809864
810#if !SANITIZER_OPENBSD
811865void ReExec() {
812866 const char *pathname = "/proc/self/exe";
813867
......@@ -839,7 +893,107 @@ void ReExec() {
839893 Printf("execve failed, errno %d\n", rverrno);
840894 Die();
841895}
842#endif // !SANITIZER_OPENBSD
896
897void UnmapFromTo(uptr from, uptr to) {
898 if (to == from)
899 return;
900 CHECK(to >= from);
901 uptr res = internal_munmap(reinterpret_cast<void *>(from), to - from);
902 if (UNLIKELY(internal_iserror(res))) {
903 Report("ERROR: %s failed to unmap 0x%zx (%zd) bytes at address %p\n",
904 SanitizerToolName, to - from, to - from, (void *)from);
905 CHECK("unable to unmap" && 0);
906 }
907}
908
909uptr MapDynamicShadow(uptr shadow_size_bytes, uptr shadow_scale,
910 uptr min_shadow_base_alignment,
911 UNUSED uptr &high_mem_end) {
912 const uptr granularity = GetMmapGranularity();
913 const uptr alignment =
914 Max<uptr>(granularity << shadow_scale, 1ULL << min_shadow_base_alignment);
915 const uptr left_padding =
916 Max<uptr>(granularity, 1ULL << min_shadow_base_alignment);
917
918 const uptr shadow_size = RoundUpTo(shadow_size_bytes, granularity);
919 const uptr map_size = shadow_size + left_padding + alignment;
920
921 const uptr map_start = (uptr)MmapNoAccess(map_size);
922 CHECK_NE(map_start, ~(uptr)0);
923
924 const uptr shadow_start = RoundUpTo(map_start + left_padding, alignment);
925
926 UnmapFromTo(map_start, shadow_start - left_padding);
927 UnmapFromTo(shadow_start + shadow_size, map_start + map_size);
928
929 return shadow_start;
930}
931
932static uptr MmapSharedNoReserve(uptr addr, uptr size) {
933 return internal_mmap(
934 reinterpret_cast<void *>(addr), size, PROT_READ | PROT_WRITE,
935 MAP_FIXED | MAP_SHARED | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0);
936}
937
938static uptr MremapCreateAlias(uptr base_addr, uptr alias_addr,
939 uptr alias_size) {
940#if SANITIZER_LINUX
941 return internal_mremap(reinterpret_cast<void *>(base_addr), 0, alias_size,
942 MREMAP_MAYMOVE | MREMAP_FIXED,
943 reinterpret_cast<void *>(alias_addr));
944#else
945 CHECK(false && "mremap is not supported outside of Linux");
946 return 0;
947#endif
948}
949
950static void CreateAliases(uptr start_addr, uptr alias_size, uptr num_aliases) {
951 uptr total_size = alias_size * num_aliases;
952 uptr mapped = MmapSharedNoReserve(start_addr, total_size);
953 CHECK_EQ(mapped, start_addr);
954
955 for (uptr i = 1; i < num_aliases; ++i) {
956 uptr alias_addr = start_addr + i * alias_size;
957 CHECK_EQ(MremapCreateAlias(start_addr, alias_addr, alias_size), alias_addr);
958 }
959}
960
961uptr MapDynamicShadowAndAliases(uptr shadow_size, uptr alias_size,
962 uptr num_aliases, uptr ring_buffer_size) {
963 CHECK_EQ(alias_size & (alias_size - 1), 0);
964 CHECK_EQ(num_aliases & (num_aliases - 1), 0);
965 CHECK_EQ(ring_buffer_size & (ring_buffer_size - 1), 0);
966
967 const uptr granularity = GetMmapGranularity();
968 shadow_size = RoundUpTo(shadow_size, granularity);
969 CHECK_EQ(shadow_size & (shadow_size - 1), 0);
970
971 const uptr alias_region_size = alias_size * num_aliases;
972 const uptr alignment =
973 2 * Max(Max(shadow_size, alias_region_size), ring_buffer_size);
974 const uptr left_padding = ring_buffer_size;
975
976 const uptr right_size = alignment;
977 const uptr map_size = left_padding + 2 * alignment;
978
979 const uptr map_start = reinterpret_cast<uptr>(MmapNoAccess(map_size));
980 CHECK_NE(map_start, static_cast<uptr>(-1));
981 const uptr right_start = RoundUpTo(map_start + left_padding, alignment);
982
983 UnmapFromTo(map_start, right_start - left_padding);
984 UnmapFromTo(right_start + right_size, map_start + map_size);
985
986 CreateAliases(right_start + right_size / 2, alias_size, num_aliases);
987
988 return right_start;
989}
990
991void InitializePlatformCommonFlags(CommonFlags *cf) {
992#if SANITIZER_ANDROID
993 if (&__libc_get_static_tls_bounds == nullptr)
994 cf->detect_leaks = false;
995#endif
996}
843997
844998} // namespace __sanitizer
845999
lib/tsan/sanitizer_common/sanitizer_local_address_space_view.h+1-1
......@@ -7,7 +7,7 @@
77//===----------------------------------------------------------------------===//
88//
99// `LocalAddressSpaceView` provides the local (i.e. target and current address
10// space are the same) implementation of the `AddressSpaveView` interface which
10// space are the same) implementation of the `AddressSpaceView` interface which
1111// provides a simple interface to load memory from another process (i.e.
1212// out-of-process)
1313//
lib/tsan/sanitizer_common/sanitizer_mac.cpp+265-55
......@@ -44,6 +44,14 @@ extern char **environ;
4444#define SANITIZER_OS_TRACE 0
4545#endif
4646
47// import new crash reporting api
48#if defined(__has_include) && __has_include(<CrashReporterClient.h>)
49#define HAVE_CRASHREPORTERCLIENT_H 1
50#include <CrashReporterClient.h>
51#else
52#define HAVE_CRASHREPORTERCLIENT_H 0
53#endif
54
4755#if !SANITIZER_IOS
4856#include <crt_externs.h> // for _NSGetArgv and _NSGetEnviron
4957#else
......@@ -62,6 +70,7 @@ extern "C" {
6270#include <mach/mach_time.h>
6371#include <mach/vm_statistics.h>
6472#include <malloc/malloc.h>
73#include <os/log.h>
6574#include <pthread.h>
6675#include <sched.h>
6776#include <signal.h>
......@@ -133,10 +142,20 @@ uptr internal_munmap(void *addr, uptr length) {
133142 return munmap(addr, length);
134143}
135144
145uptr internal_mremap(void *old_address, uptr old_size, uptr new_size, int flags,
146 void *new_address) {
147 CHECK(false && "internal_mremap is unimplemented on Mac");
148 return 0;
149}
150
136151int internal_mprotect(void *addr, uptr length, int prot) {
137152 return mprotect(addr, length, prot);
138153}
139154
155int internal_madvise(uptr addr, uptr length, int advice) {
156 return madvise((void *)addr, length, advice);
157}
158
140159uptr internal_close(fd_t fd) {
141160 return close(fd);
142161}
......@@ -200,9 +219,7 @@ void internal__exit(int exitcode) {
200219 _exit(exitcode);
201220}
202221
203unsigned int internal_sleep(unsigned int seconds) {
204 return sleep(seconds);
205}
222void internal_usleep(u64 useconds) { usleep(useconds); }
206223
207224uptr internal_getpid() {
208225 return getpid();
......@@ -440,7 +457,7 @@ uptr ReadBinaryName(/*out*/char *buf, uptr buf_len) {
440457 // On OS X the executable path is saved to the stack by dyld. Reading it
441458 // from there is much faster than calling dladdr, especially for large
442459 // binaries with symbols.
443 InternalScopedString exe_path(kMaxPathLength);
460 InternalMmapVector<char> exe_path(kMaxPathLength);
444461 uint32_t size = exe_path.size();
445462 if (_NSGetExecutablePath(exe_path.data(), &size) == 0 &&
446463 realpath(exe_path.data(), buf) != 0) {
......@@ -492,6 +509,13 @@ void MprotectMallocZones(void *addr, int prot) {
492509 }
493510}
494511
512void FutexWait(atomic_uint32_t *p, u32 cmp) {
513 // FIXME: implement actual blocking.
514 sched_yield();
515}
516
517void FutexWake(atomic_uint32_t *p, u32 count) {}
518
495519BlockingMutex::BlockingMutex() {
496520 internal_memset(this, 0, sizeof(*this));
497521}
......@@ -507,8 +531,8 @@ void BlockingMutex::Unlock() {
507531 OSSpinLockUnlock((OSSpinLock*)&opaque_storage_);
508532}
509533
510void BlockingMutex::CheckLocked() {
511 CHECK_NE(*(OSSpinLock*)&opaque_storage_, 0);
534void BlockingMutex::CheckLocked() const {
535 CHECK_NE(*(const OSSpinLock*)&opaque_storage_, 0);
512536}
513537
514538u64 NanoTime() {
......@@ -606,21 +630,103 @@ HandleSignalMode GetHandleSignalMode(int signum) {
606630 return result;
607631}
608632
609// This corresponds to Triple::getMacOSXVersion() in the Clang driver.
610static MacosVersion GetMacosAlignedVersionInternal() {
633// Offset example:
634// XNU 17 -- macOS 10.13 -- iOS 11 -- tvOS 11 -- watchOS 4
635constexpr u16 GetOSMajorKernelOffset() {
636 if (TARGET_OS_OSX) return 4;
637 if (TARGET_OS_IOS || TARGET_OS_TV) return 6;
638 if (TARGET_OS_WATCH) return 13;
639}
640
641using VersStr = char[64];
642
643static uptr ApproximateOSVersionViaKernelVersion(VersStr vers) {
611644 u16 kernel_major = GetDarwinKernelVersion().major;
612 // Darwin 0-3 -> unsupported
613 // Darwin 4-19 -> macOS 10.x
614 // Darwin 20+ -> macOS 11+
615 CHECK_GE(kernel_major, 4);
616 u16 major, minor;
617 if (kernel_major < 20) {
618 major = 10;
619 minor = kernel_major - 4;
645 u16 offset = GetOSMajorKernelOffset();
646 CHECK_GE(kernel_major, offset);
647 u16 os_major = kernel_major - offset;
648
649 const char *format = "%d.0";
650 if (TARGET_OS_OSX) {
651 if (os_major >= 16) { // macOS 11+
652 os_major -= 5;
653 } else { // macOS 10.15 and below
654 format = "10.%d";
655 }
656 }
657 return internal_snprintf(vers, sizeof(VersStr), format, os_major);
658}
659
660static void GetOSVersion(VersStr vers) {
661 uptr len = sizeof(VersStr);
662 if (SANITIZER_IOSSIM) {
663 const char *vers_env = GetEnv("SIMULATOR_RUNTIME_VERSION");
664 if (!vers_env) {
665 Report("ERROR: Running in simulator but SIMULATOR_RUNTIME_VERSION env "
666 "var is not set.\n");
667 Die();
668 }
669 len = internal_strlcpy(vers, vers_env, len);
620670 } else {
621 major = 11 + kernel_major - 20;
622 minor = 0;
671 int res =
672 internal_sysctlbyname("kern.osproductversion", vers, &len, nullptr, 0);
673
674 // XNU 17 (macOS 10.13) and below do not provide the sysctl
675 // `kern.osproductversion` entry (res != 0).
676 bool no_os_version = res != 0;
677
678 // For launchd, sanitizer initialization runs before sysctl is setup
679 // (res == 0 && len != strlen(vers), vers is not a valid version). However,
680 // the kernel version `kern.osrelease` is available.
681 bool launchd = (res == 0 && internal_strlen(vers) < 3);
682 if (launchd) CHECK_EQ(internal_getpid(), 1);
683
684 if (no_os_version || launchd) {
685 len = ApproximateOSVersionViaKernelVersion(vers);
686 }
687 }
688 CHECK_LT(len, sizeof(VersStr));
689}
690
691void ParseVersion(const char *vers, u16 *major, u16 *minor) {
692 // Format: <major>.<minor>[.<patch>]\0
693 CHECK_GE(internal_strlen(vers), 3);
694 const char *p = vers;
695 *major = internal_simple_strtoll(p, &p, /*base=*/10);
696 CHECK_EQ(*p, '.');
697 p += 1;
698 *minor = internal_simple_strtoll(p, &p, /*base=*/10);
699}
700
701// Aligned versions example:
702// macOS 10.15 -- iOS 13 -- tvOS 13 -- watchOS 6
703static void MapToMacos(u16 *major, u16 *minor) {
704 if (TARGET_OS_OSX)
705 return;
706
707 if (TARGET_OS_IOS || TARGET_OS_TV)
708 *major += 2;
709 else if (TARGET_OS_WATCH)
710 *major += 9;
711 else
712 UNREACHABLE("unsupported platform");
713
714 if (*major >= 16) { // macOS 11+
715 *major -= 5;
716 } else { // macOS 10.15 and below
717 *minor = *major;
718 *major = 10;
623719 }
720}
721
722static MacosVersion GetMacosAlignedVersionInternal() {
723 VersStr vers = {};
724 GetOSVersion(vers);
725
726 u16 major, minor;
727 ParseVersion(vers, &major, &minor);
728 MapToMacos(&major, &minor);
729
624730 return MacosVersion(major, minor);
625731}
626732
......@@ -639,24 +745,15 @@ MacosVersion GetMacosAlignedVersion() {
639745 return *reinterpret_cast<MacosVersion *>(&result);
640746}
641747
642void ParseVersion(const char *vers, u16 *major, u16 *minor) {
643 // Format: <major>.<minor>.<patch>\0
644 CHECK_GE(internal_strlen(vers), 5);
645 const char *p = vers;
646 *major = internal_simple_strtoll(p, &p, /*base=*/10);
647 CHECK_EQ(*p, '.');
648 p += 1;
649 *minor = internal_simple_strtoll(p, &p, /*base=*/10);
650}
651
652748DarwinKernelVersion GetDarwinKernelVersion() {
653 char buf[100];
654 size_t len = sizeof(buf);
655 int res = internal_sysctlbyname("kern.osrelease", buf, &len, nullptr, 0);
749 VersStr vers = {};
750 uptr len = sizeof(VersStr);
751 int res = internal_sysctlbyname("kern.osrelease", vers, &len, nullptr, 0);
656752 CHECK_EQ(res, 0);
753 CHECK_LT(len, sizeof(VersStr));
657754
658755 u16 major, minor;
659 ParseVersion(buf, &major, &minor);
756 ParseVersion(vers, &major, &minor);
660757
661758 return DarwinKernelVersion(major, minor);
662759}
......@@ -693,7 +790,51 @@ static BlockingMutex syslog_lock(LINKER_INITIALIZED);
693790void WriteOneLineToSyslog(const char *s) {
694791#if !SANITIZER_GO
695792 syslog_lock.CheckLocked();
696 asl_log(nullptr, nullptr, ASL_LEVEL_ERR, "%s", s);
793 if (GetMacosAlignedVersion() >= MacosVersion(10, 12)) {
794 os_log_error(OS_LOG_DEFAULT, "%{public}s", s);
795 } else {
796 asl_log(nullptr, nullptr, ASL_LEVEL_ERR, "%s", s);
797 }
798#endif
799}
800
801// buffer to store crash report application information
802static char crashreporter_info_buff[__sanitizer::kErrorMessageBufferSize] = {};
803static BlockingMutex crashreporter_info_mutex(LINKER_INITIALIZED);
804
805extern "C" {
806// Integrate with crash reporter libraries.
807#if HAVE_CRASHREPORTERCLIENT_H
808CRASH_REPORTER_CLIENT_HIDDEN
809struct crashreporter_annotations_t gCRAnnotations
810 __attribute__((section("__DATA," CRASHREPORTER_ANNOTATIONS_SECTION))) = {
811 CRASHREPORTER_ANNOTATIONS_VERSION,
812 0,
813 0,
814 0,
815 0,
816 0,
817 0,
818#if CRASHREPORTER_ANNOTATIONS_VERSION > 4
819 0,
820#endif
821};
822
823#else
824// fall back to old crashreporter api
825static const char *__crashreporter_info__ __attribute__((__used__)) =
826 &crashreporter_info_buff[0];
827asm(".desc ___crashreporter_info__, 0x10");
828#endif
829
830} // extern "C"
831
832static void CRAppendCrashLogMessage(const char *msg) {
833 BlockingMutexLock l(&crashreporter_info_mutex);
834 internal_strlcat(crashreporter_info_buff, msg,
835 sizeof(crashreporter_info_buff));
836#if HAVE_CRASHREPORTERCLIENT_H
837 (void)CRSetCrashLogMessage(crashreporter_info_buff);
697838#endif
698839}
699840
......@@ -796,6 +937,19 @@ void SignalContext::InitPcSpBp() {
796937 GetPcSpBp(context, &pc, &sp, &bp);
797938}
798939
940// ASan/TSan use mmap in a way that creates “deallocation gaps” which triggers
941// EXC_GUARD exceptions on macOS 10.15+ (XNU 19.0+).
942static void DisableMmapExcGuardExceptions() {
943 using task_exc_guard_behavior_t = uint32_t;
944 using task_set_exc_guard_behavior_t =
945 kern_return_t(task_t task, task_exc_guard_behavior_t behavior);
946 auto *set_behavior = (task_set_exc_guard_behavior_t *)dlsym(
947 RTLD_DEFAULT, "task_set_exc_guard_behavior");
948 if (set_behavior == nullptr) return;
949 const task_exc_guard_behavior_t task_exc_guard_none = 0;
950 set_behavior(mach_task_self(), task_exc_guard_none);
951}
952
799953void InitializePlatformEarly() {
800954 // Only use xnu_fast_mmap when on x86_64 and the kernel supports it.
801955 use_xnu_fast_mmap =
......@@ -804,6 +958,8 @@ void InitializePlatformEarly() {
804958#else
805959 false;
806960#endif
961 if (GetDarwinKernelVersion() >= DarwinKernelVersion(19, 0))
962 DisableMmapExcGuardExceptions();
807963}
808964
809965#if !SANITIZER_GO
......@@ -844,20 +1000,10 @@ bool ReexecDisabled() {
8441000 return false;
8451001}
8461002
847extern "C" SANITIZER_WEAK_ATTRIBUTE double dyldVersionNumber;
848static const double kMinDyldVersionWithAutoInterposition = 360.0;
849
850bool DyldNeedsEnvVariable() {
851 // Although sanitizer support was added to LLVM on OS X 10.7+, GCC users
852 // still may want use them on older systems. On older Darwin platforms, dyld
853 // doesn't export dyldVersionNumber symbol and we simply return true.
854 if (!&dyldVersionNumber) return true;
1003static bool DyldNeedsEnvVariable() {
8551004 // If running on OS X 10.11+ or iOS 9.0+, dyld will interpose even if
856 // DYLD_INSERT_LIBRARIES is not set. However, checking OS version via
857 // GetMacosAlignedVersion() doesn't work for the simulator. Let's instead
858 // check `dyldVersionNumber`, which is exported by dyld, against a known
859 // version number from the first OS release where this appeared.
860 return dyldVersionNumber < kMinDyldVersionWithAutoInterposition;
1005 // DYLD_INSERT_LIBRARIES is not set.
1006 return GetMacosAlignedVersion() < MacosVersion(10, 11);
8611007}
8621008
8631009void MaybeReexec() {
......@@ -884,7 +1030,7 @@ void MaybeReexec() {
8841030 if (DyldNeedsEnvVariable() && !lib_is_in_env) {
8851031 // DYLD_INSERT_LIBRARIES is not set or does not contain the runtime
8861032 // library.
887 InternalScopedString program_name(1024);
1033 InternalMmapVector<char> program_name(1024);
8881034 uint32_t buf_size = program_name.size();
8891035 _NSGetExecutablePath(program_name.data(), &buf_size);
8901036 char *new_env = const_cast<char*>(info.dli_fname);
......@@ -1003,7 +1149,7 @@ char **GetArgv() {
10031149 return *_NSGetArgv();
10041150}
10051151
1006#if SANITIZER_IOS
1152#if SANITIZER_IOS && !SANITIZER_IOSSIM
10071153// The task_vm_info struct is normally provided by the macOS SDK, but we need
10081154// fields only available in 10.12+. Declare the struct manually to be able to
10091155// build against older SDKs.
......@@ -1043,26 +1189,35 @@ static uptr GetTaskInfoMaxAddress() {
10431189
10441190uptr GetMaxUserVirtualAddress() {
10451191 static uptr max_vm = GetTaskInfoMaxAddress();
1046 if (max_vm != 0)
1047 return max_vm - 1;
1192 if (max_vm != 0) {
1193 const uptr ret_value = max_vm - 1;
1194 CHECK_LE(ret_value, SANITIZER_MMAP_RANGE_SIZE);
1195 return ret_value;
1196 }
10481197
10491198 // xnu cannot provide vm address limit
10501199# if SANITIZER_WORDSIZE == 32
1051 return 0xffe00000 - 1;
1200 constexpr uptr fallback_max_vm = 0xffe00000 - 1;
10521201# else
1053 return 0x200000000 - 1;
1202 constexpr uptr fallback_max_vm = 0x200000000 - 1;
10541203# endif
1204 static_assert(fallback_max_vm <= SANITIZER_MMAP_RANGE_SIZE,
1205 "Max virtual address must be less than mmap range size.");
1206 return fallback_max_vm;
10551207}
10561208
10571209#else // !SANITIZER_IOS
10581210
10591211uptr GetMaxUserVirtualAddress() {
10601212# if SANITIZER_WORDSIZE == 64
1061 return (1ULL << 47) - 1; // 0x00007fffffffffffUL;
1213 constexpr uptr max_vm = (1ULL << 47) - 1; // 0x00007fffffffffffUL;
10621214# else // SANITIZER_WORDSIZE == 32
10631215 static_assert(SANITIZER_WORDSIZE == 32, "Wrong wordsize");
1064 return (1ULL << 32) - 1; // 0xffffffff;
1216 constexpr uptr max_vm = (1ULL << 32) - 1; // 0xffffffff;
10651217# endif
1218 static_assert(max_vm <= SANITIZER_MMAP_RANGE_SIZE,
1219 "Max virtual address must be less than mmap range size.");
1220 return max_vm;
10661221}
10671222#endif
10681223
......@@ -1070,6 +1225,59 @@ uptr GetMaxVirtualAddress() {
10701225 return GetMaxUserVirtualAddress();
10711226}
10721227
1228uptr MapDynamicShadow(uptr shadow_size_bytes, uptr shadow_scale,
1229 uptr min_shadow_base_alignment, uptr &high_mem_end) {
1230 const uptr granularity = GetMmapGranularity();
1231 const uptr alignment =
1232 Max<uptr>(granularity << shadow_scale, 1ULL << min_shadow_base_alignment);
1233 const uptr left_padding =
1234 Max<uptr>(granularity, 1ULL << min_shadow_base_alignment);
1235
1236 uptr space_size = shadow_size_bytes + left_padding;
1237
1238 uptr largest_gap_found = 0;
1239 uptr max_occupied_addr = 0;
1240 VReport(2, "FindDynamicShadowStart, space_size = %p\n", space_size);
1241 uptr shadow_start =
1242 FindAvailableMemoryRange(space_size, alignment, granularity,
1243 &largest_gap_found, &max_occupied_addr);
1244 // If the shadow doesn't fit, restrict the address space to make it fit.
1245 if (shadow_start == 0) {
1246 VReport(
1247 2,
1248 "Shadow doesn't fit, largest_gap_found = %p, max_occupied_addr = %p\n",
1249 largest_gap_found, max_occupied_addr);
1250 uptr new_max_vm = RoundDownTo(largest_gap_found << shadow_scale, alignment);
1251 if (new_max_vm < max_occupied_addr) {
1252 Report("Unable to find a memory range for dynamic shadow.\n");
1253 Report(
1254 "space_size = %p, largest_gap_found = %p, max_occupied_addr = %p, "
1255 "new_max_vm = %p\n",
1256 space_size, largest_gap_found, max_occupied_addr, new_max_vm);
1257 CHECK(0 && "cannot place shadow");
1258 }
1259 RestrictMemoryToMaxAddress(new_max_vm);
1260 high_mem_end = new_max_vm - 1;
1261 space_size = (high_mem_end >> shadow_scale) + left_padding;
1262 VReport(2, "FindDynamicShadowStart, space_size = %p\n", space_size);
1263 shadow_start = FindAvailableMemoryRange(space_size, alignment, granularity,
1264 nullptr, nullptr);
1265 if (shadow_start == 0) {
1266 Report("Unable to find a memory range after restricting VM.\n");
1267 CHECK(0 && "cannot place shadow after restricting vm");
1268 }
1269 }
1270 CHECK_NE((uptr)0, shadow_start);
1271 CHECK(IsAligned(shadow_start, alignment));
1272 return shadow_start;
1273}
1274
1275uptr MapDynamicShadowAndAliases(uptr shadow_size, uptr alias_size,
1276 uptr num_aliases, uptr ring_buffer_size) {
1277 CHECK(false && "HWASan aliasing is unimplemented on Mac");
1278 return 0;
1279}
1280
10731281uptr FindAvailableMemoryRange(uptr size, uptr alignment, uptr left_padding,
10741282 uptr *largest_gap_found,
10751283 uptr *max_occupied_addr) {
......@@ -1190,7 +1398,7 @@ void FormatUUID(char *out, uptr size, const u8 *uuid) {
11901398 uuid[12], uuid[13], uuid[14], uuid[15]);
11911399}
11921400
1193void PrintModuleMap() {
1401void DumpProcessMap() {
11941402 Printf("Process module map:\n");
11951403 MemoryMappingLayout memory_mapping(false);
11961404 InternalMmapVector<LoadedModule> modules;
......@@ -1223,6 +1431,8 @@ u32 GetNumberOfCPUs() {
12231431 return (u32)sysconf(_SC_NPROCESSORS_ONLN);
12241432}
12251433
1434void InitializePlatformCommonFlags(CommonFlags *cf) {}
1435
12261436} // namespace __sanitizer
12271437
12281438#endif // SANITIZER_MAC
lib/tsan/sanitizer_common/sanitizer_mac.h+1-17
......@@ -44,6 +44,7 @@ struct VersionBase {
4444 return major > other.major ||
4545 (major == other.major && minor >= other.minor);
4646 }
47 bool operator<(const VersionType &other) const { return !(*this >= other); }
4748};
4849
4950struct MacosVersion : VersionBase<MacosVersion> {
......@@ -63,22 +64,5 @@ void RestrictMemoryToMaxAddress(uptr max_address);
6364
6465} // namespace __sanitizer
6566
66extern "C" {
67static char __crashreporter_info_buff__[__sanitizer::kErrorMessageBufferSize] =
68 {};
69static const char *__crashreporter_info__ __attribute__((__used__)) =
70 &__crashreporter_info_buff__[0];
71asm(".desc ___crashreporter_info__, 0x10");
72} // extern "C"
73
74namespace __sanitizer {
75static BlockingMutex crashreporter_info_mutex(LINKER_INITIALIZED);
76
77INLINE void CRAppendCrashLogMessage(const char *msg) {
78 BlockingMutexLock l(&crashreporter_info_mutex);
79 internal_strlcat(__crashreporter_info_buff__, msg,
80 sizeof(__crashreporter_info_buff__)); }
81} // namespace __sanitizer
82
8367#endif // SANITIZER_MAC
8468#endif // SANITIZER_MAC_H
lib/tsan/sanitizer_common/sanitizer_malloc_mac.inc+1-5
......@@ -120,11 +120,7 @@ INTERCEPTOR(int, malloc_make_nonpurgeable, void *ptr) {
120120
121121INTERCEPTOR(void, malloc_set_zone_name, malloc_zone_t *zone, const char *name) {
122122 COMMON_MALLOC_ENTER();
123 // Allocate |sizeof(COMMON_MALLOC_ZONE_NAME "-") + internal_strlen(name)|
124 // bytes.
125 size_t buflen =
126 sizeof(COMMON_MALLOC_ZONE_NAME "-") + (name ? internal_strlen(name) : 0);
127 InternalScopedString new_name(buflen);
123 InternalScopedString new_name;
128124 if (name && zone->introspect == sanitizer_zone.introspect) {
129125 new_name.append(COMMON_MALLOC_ZONE_NAME "-%s", name);
130126 name = new_name.data();
lib/tsan/sanitizer_common/sanitizer_mutex.cpp created+225
......@@ -0,0 +1,225 @@
1//===-- sanitizer_mutex.cpp -----------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file is shared between AddressSanitizer and ThreadSanitizer
10// run-time libraries.
11//===----------------------------------------------------------------------===//
12
13#include "sanitizer_mutex.h"
14
15#include "sanitizer_common.h"
16
17namespace __sanitizer {
18
19void StaticSpinMutex::LockSlow() {
20 for (int i = 0;; i++) {
21 if (i < 100)
22 proc_yield(1);
23 else
24 internal_sched_yield();
25 if (atomic_load(&state_, memory_order_relaxed) == 0 &&
26 atomic_exchange(&state_, 1, memory_order_acquire) == 0)
27 return;
28 }
29}
30
31void Semaphore::Wait() {
32 u32 count = atomic_load(&state_, memory_order_relaxed);
33 for (;;) {
34 if (count == 0) {
35 FutexWait(&state_, 0);
36 count = atomic_load(&state_, memory_order_relaxed);
37 continue;
38 }
39 if (atomic_compare_exchange_weak(&state_, &count, count - 1,
40 memory_order_acquire))
41 break;
42 }
43}
44
45void Semaphore::Post(u32 count) {
46 CHECK_NE(count, 0);
47 atomic_fetch_add(&state_, count, memory_order_release);
48 FutexWake(&state_, count);
49}
50
51#if SANITIZER_CHECK_DEADLOCKS
52// An empty mutex meta table, it effectively disables deadlock detection.
53// Each tool can override the table to define own mutex hierarchy and
54// enable deadlock detection.
55// The table defines a static mutex type hierarchy (what mutex types can be locked
56// under what mutex types). This table is checked to be acyclic and then
57// actual mutex lock/unlock operations are checked to adhere to this hierarchy.
58// The checking happens on mutex types rather than on individual mutex instances
59// because doing it on mutex instances will both significantly complicate
60// the implementation, worsen performance and memory overhead and is mostly
61// unnecessary (we almost never lock multiple mutexes of the same type recursively).
62static constexpr int kMutexTypeMax = 20;
63SANITIZER_WEAK_ATTRIBUTE MutexMeta mutex_meta[kMutexTypeMax] = {};
64SANITIZER_WEAK_ATTRIBUTE void PrintMutexPC(uptr pc) {}
65static StaticSpinMutex mutex_meta_mtx;
66static int mutex_type_count = -1;
67// Adjacency matrix of what mutexes can be locked under what mutexes.
68static bool mutex_can_lock[kMutexTypeMax][kMutexTypeMax];
69// Mutex types with MutexMulti mark.
70static bool mutex_multi[kMutexTypeMax];
71
72void DebugMutexInit() {
73 // Build adjacency matrix.
74 bool leaf[kMutexTypeMax];
75 internal_memset(&leaf, 0, sizeof(leaf));
76 int cnt[kMutexTypeMax] = {};
77 internal_memset(&cnt, 0, sizeof(cnt));
78 for (int t = 0; t < kMutexTypeMax; t++) {
79 mutex_type_count = t;
80 if (!mutex_meta[t].name)
81 break;
82 CHECK_EQ(t, mutex_meta[t].type);
83 for (uptr j = 0; j < ARRAY_SIZE(mutex_meta[t].can_lock); j++) {
84 MutexType z = mutex_meta[t].can_lock[j];
85 if (z == MutexInvalid)
86 break;
87 if (z == MutexLeaf) {
88 CHECK(!leaf[t]);
89 leaf[t] = true;
90 continue;
91 }
92 if (z == MutexMulti) {
93 mutex_multi[t] = true;
94 continue;
95 }
96 CHECK_LT(z, kMutexTypeMax);
97 CHECK(!mutex_can_lock[t][z]);
98 mutex_can_lock[t][z] = true;
99 cnt[t]++;
100 }
101 }
102 // Indicates the array is not properly terminated.
103 CHECK_LT(mutex_type_count, kMutexTypeMax);
104 // Add leaf mutexes.
105 for (int t = 0; t < mutex_type_count; t++) {
106 if (!leaf[t])
107 continue;
108 CHECK_EQ(cnt[t], 0);
109 for (int z = 0; z < mutex_type_count; z++) {
110 if (z == MutexInvalid || t == z || leaf[z])
111 continue;
112 CHECK(!mutex_can_lock[z][t]);
113 mutex_can_lock[z][t] = true;
114 }
115 }
116 // Build the transitive closure and check that the graphs is acyclic.
117 u32 trans[kMutexTypeMax];
118 static_assert(sizeof(trans[0]) * 8 >= kMutexTypeMax,
119 "kMutexTypeMax does not fit into u32, switch to u64");
120 internal_memset(&trans, 0, sizeof(trans));
121 for (int i = 0; i < mutex_type_count; i++) {
122 for (int j = 0; j < mutex_type_count; j++)
123 if (mutex_can_lock[i][j])
124 trans[i] |= 1 << j;
125 }
126 for (int k = 0; k < mutex_type_count; k++) {
127 for (int i = 0; i < mutex_type_count; i++) {
128 if (trans[i] & (1 << k))
129 trans[i] |= trans[k];
130 }
131 }
132 for (int i = 0; i < mutex_type_count; i++) {
133 if (trans[i] & (1 << i)) {
134 Printf("Mutex %s participates in a cycle\n", mutex_meta[i].name);
135 Die();
136 }
137 }
138}
139
140struct InternalDeadlockDetector {
141 struct LockDesc {
142 u64 seq;
143 uptr pc;
144 int recursion;
145 };
146 int initialized;
147 u64 sequence;
148 LockDesc locked[kMutexTypeMax];
149
150 void Lock(MutexType type, uptr pc) {
151 if (!Initialize(type))
152 return;
153 CHECK_LT(type, mutex_type_count);
154 // Find the last locked mutex type.
155 // This is the type we will use for hierarchy checks.
156 u64 max_seq = 0;
157 MutexType max_idx = MutexInvalid;
158 for (int i = 0; i != mutex_type_count; i++) {
159 if (locked[i].seq == 0)
160 continue;
161 CHECK_NE(locked[i].seq, max_seq);
162 if (max_seq < locked[i].seq) {
163 max_seq = locked[i].seq;
164 max_idx = (MutexType)i;
165 }
166 }
167 if (max_idx == type && mutex_multi[type]) {
168 // Recursive lock of the same type.
169 CHECK_EQ(locked[type].seq, max_seq);
170 CHECK(locked[type].pc);
171 locked[type].recursion++;
172 return;
173 }
174 if (max_idx != MutexInvalid && !mutex_can_lock[max_idx][type]) {
175 Printf("%s: internal deadlock: can't lock %s under %s mutex\n", SanitizerToolName,
176 mutex_meta[type].name, mutex_meta[max_idx].name);
177 PrintMutexPC(pc);
178 CHECK(0);
179 }
180 locked[type].seq = ++sequence;
181 locked[type].pc = pc;
182 locked[type].recursion = 1;
183 }
184
185 void Unlock(MutexType type) {
186 if (!Initialize(type))
187 return;
188 CHECK_LT(type, mutex_type_count);
189 CHECK(locked[type].seq);
190 CHECK_GT(locked[type].recursion, 0);
191 if (--locked[type].recursion)
192 return;
193 locked[type].seq = 0;
194 locked[type].pc = 0;
195 }
196
197 void CheckNoLocks() {
198 for (int i = 0; i < mutex_type_count; i++) CHECK_EQ(locked[i].recursion, 0);
199 }
200
201 bool Initialize(MutexType type) {
202 if (type == MutexUnchecked || type == MutexInvalid)
203 return false;
204 CHECK_GT(type, MutexInvalid);
205 if (initialized != 0)
206 return initialized > 0;
207 initialized = -1;
208 SpinMutexLock lock(&mutex_meta_mtx);
209 if (mutex_type_count < 0)
210 DebugMutexInit();
211 initialized = mutex_type_count ? 1 : -1;
212 return initialized > 0;
213 }
214};
215
216static THREADLOCAL InternalDeadlockDetector deadlock_detector;
217
218void CheckedMutex::LockImpl(uptr pc) { deadlock_detector.Lock(type_, pc); }
219
220void CheckedMutex::UnlockImpl() { deadlock_detector.Unlock(type_); }
221
222void CheckedMutex::CheckNoLocksImpl() { deadlock_detector.CheckNoLocks(); }
223#endif
224
225} // namespace __sanitizer
lib/tsan/sanitizer_common/sanitizer_mutex.h+316-52
......@@ -16,67 +16,335 @@
1616#include "sanitizer_atomic.h"
1717#include "sanitizer_internal_defs.h"
1818#include "sanitizer_libc.h"
19#include "sanitizer_thread_safety.h"
1920
2021namespace __sanitizer {
2122
22class StaticSpinMutex {
23class MUTEX StaticSpinMutex {
2324 public:
2425 void Init() {
2526 atomic_store(&state_, 0, memory_order_relaxed);
2627 }
2728
28 void Lock() {
29 if (TryLock())
29 void Lock() ACQUIRE() {
30 if (LIKELY(TryLock()))
3031 return;
3132 LockSlow();
3233 }
3334
34 bool TryLock() {
35 bool TryLock() TRY_ACQUIRE(true) {
3536 return atomic_exchange(&state_, 1, memory_order_acquire) == 0;
3637 }
3738
38 void Unlock() {
39 atomic_store(&state_, 0, memory_order_release);
40 }
39 void Unlock() RELEASE() { atomic_store(&state_, 0, memory_order_release); }
4140
42 void CheckLocked() {
41 void CheckLocked() const CHECK_LOCKED() {
4342 CHECK_EQ(atomic_load(&state_, memory_order_relaxed), 1);
4443 }
4544
4645 private:
4746 atomic_uint8_t state_;
4847
49 void NOINLINE LockSlow() {
50 for (int i = 0;; i++) {
51 if (i < 10)
52 proc_yield(10);
53 else
54 internal_sched_yield();
55 if (atomic_load(&state_, memory_order_relaxed) == 0
56 && atomic_exchange(&state_, 1, memory_order_acquire) == 0)
57 return;
58 }
59 }
48 void LockSlow();
6049};
6150
62class SpinMutex : public StaticSpinMutex {
51class MUTEX SpinMutex : public StaticSpinMutex {
6352 public:
6453 SpinMutex() {
6554 Init();
6655 }
6756
57 SpinMutex(const SpinMutex &) = delete;
58 void operator=(const SpinMutex &) = delete;
59};
60
61// Semaphore provides an OS-dependent way to park/unpark threads.
62// The last thread returned from Wait can destroy the object
63// (destruction-safety).
64class Semaphore {
65 public:
66 constexpr Semaphore() {}
67 Semaphore(const Semaphore &) = delete;
68 void operator=(const Semaphore &) = delete;
69
70 void Wait();
71 void Post(u32 count = 1);
72
6873 private:
69 SpinMutex(const SpinMutex&);
70 void operator=(const SpinMutex&);
74 atomic_uint32_t state_ = {0};
7175};
7276
73class BlockingMutex {
77typedef int MutexType;
78
79enum {
80 // Used as sentinel and to catch unassigned types
81 // (should not be used as real Mutex type).
82 MutexInvalid = 0,
83 MutexThreadRegistry,
84 // Each tool own mutexes must start at this number.
85 MutexLastCommon,
86 // Type for legacy mutexes that are not checked for deadlocks.
87 MutexUnchecked = -1,
88 // Special marks that can be used in MutexMeta::can_lock table.
89 // The leaf mutexes can be locked under any other non-leaf mutex,
90 // but no other mutex can be locked while under a leaf mutex.
91 MutexLeaf = -1,
92 // Multiple mutexes of this type can be locked at the same time.
93 MutexMulti = -3,
94};
95
96// Go linker does not support THREADLOCAL variables,
97// so we can't use per-thread state.
98#define SANITIZER_CHECK_DEADLOCKS (SANITIZER_DEBUG && !SANITIZER_GO)
99
100#if SANITIZER_CHECK_DEADLOCKS
101struct MutexMeta {
102 MutexType type;
103 const char *name;
104 // The table fixes what mutexes can be locked under what mutexes.
105 // If the entry for MutexTypeFoo contains MutexTypeBar,
106 // then Bar mutex can be locked while under Foo mutex.
107 // Can also contain the special MutexLeaf/MutexMulti marks.
108 MutexType can_lock[10];
109};
110#endif
111
112class CheckedMutex {
113 public:
114 constexpr CheckedMutex(MutexType type)
115#if SANITIZER_CHECK_DEADLOCKS
116 : type_(type)
117#endif
118 {
119 }
120
121 ALWAYS_INLINE void Lock() {
122#if SANITIZER_CHECK_DEADLOCKS
123 LockImpl(GET_CALLER_PC());
124#endif
125 }
126
127 ALWAYS_INLINE void Unlock() {
128#if SANITIZER_CHECK_DEADLOCKS
129 UnlockImpl();
130#endif
131 }
132
133 // Checks that the current thread does not hold any mutexes
134 // (e.g. when returning from a runtime function to user code).
135 static void CheckNoLocks() {
136#if SANITIZER_CHECK_DEADLOCKS
137 CheckNoLocksImpl();
138#endif
139 }
140
141 private:
142#if SANITIZER_CHECK_DEADLOCKS
143 const MutexType type_;
144
145 void LockImpl(uptr pc);
146 void UnlockImpl();
147 static void CheckNoLocksImpl();
148#endif
149};
150
151// Reader-writer mutex.
152// Derive from CheckedMutex for the purposes of EBO.
153// We could make it a field marked with [[no_unique_address]],
154// but this attribute is not supported by some older compilers.
155class MUTEX Mutex : CheckedMutex {
156 public:
157 constexpr Mutex(MutexType type = MutexUnchecked) : CheckedMutex(type) {}
158
159 void Lock() ACQUIRE() {
160 CheckedMutex::Lock();
161 u64 reset_mask = ~0ull;
162 u64 state = atomic_load_relaxed(&state_);
163 const uptr kMaxSpinIters = 1500;
164 for (uptr spin_iters = 0;; spin_iters++) {
165 u64 new_state;
166 bool locked = (state & (kWriterLock | kReaderLockMask)) != 0;
167 if (LIKELY(!locked)) {
168 // The mutex is not read-/write-locked, try to lock.
169 new_state = (state | kWriterLock) & reset_mask;
170 } else if (spin_iters > kMaxSpinIters) {
171 // We've spun enough, increment waiting writers count and block.
172 // The counter will be decremented by whoever wakes us.
173 new_state = (state + kWaitingWriterInc) & reset_mask;
174 } else if ((state & kWriterSpinWait) == 0) {
175 // Active spinning, but denote our presence so that unlocking
176 // thread does not wake up other threads.
177 new_state = state | kWriterSpinWait;
178 } else {
179 // Active spinning.
180 state = atomic_load(&state_, memory_order_relaxed);
181 continue;
182 }
183 if (UNLIKELY(!atomic_compare_exchange_weak(&state_, &state, new_state,
184 memory_order_acquire)))
185 continue;
186 if (LIKELY(!locked))
187 return; // We've locked the mutex.
188 if (spin_iters > kMaxSpinIters) {
189 // We've incremented waiting writers, so now block.
190 writers_.Wait();
191 spin_iters = 0;
192 state = atomic_load(&state_, memory_order_relaxed);
193 DCHECK_NE(state & kWriterSpinWait, 0);
194 } else {
195 // We've set kWriterSpinWait, but we are still in active spinning.
196 }
197 // We either blocked and were unblocked,
198 // or we just spun but set kWriterSpinWait.
199 // Either way we need to reset kWriterSpinWait
200 // next time we take the lock or block again.
201 reset_mask = ~kWriterSpinWait;
202 }
203 }
204
205 void Unlock() RELEASE() {
206 CheckedMutex::Unlock();
207 bool wake_writer;
208 u64 wake_readers;
209 u64 new_state;
210 u64 state = atomic_load_relaxed(&state_);
211 do {
212 DCHECK_NE(state & kWriterLock, 0);
213 DCHECK_EQ(state & kReaderLockMask, 0);
214 new_state = state & ~kWriterLock;
215 wake_writer =
216 (state & kWriterSpinWait) == 0 && (state & kWaitingWriterMask) != 0;
217 if (wake_writer)
218 new_state = (new_state - kWaitingWriterInc) | kWriterSpinWait;
219 wake_readers =
220 (state & (kWriterSpinWait | kWaitingWriterMask)) != 0
221 ? 0
222 : ((state & kWaitingReaderMask) >> kWaitingReaderShift);
223 if (wake_readers)
224 new_state = (new_state & ~kWaitingReaderMask) +
225 (wake_readers << kReaderLockShift);
226 } while (UNLIKELY(!atomic_compare_exchange_weak(&state_, &state, new_state,
227 memory_order_release)));
228 if (UNLIKELY(wake_writer))
229 writers_.Post();
230 else if (UNLIKELY(wake_readers))
231 readers_.Post(wake_readers);
232 }
233
234 void ReadLock() ACQUIRE_SHARED() {
235 CheckedMutex::Lock();
236 bool locked;
237 u64 new_state;
238 u64 state = atomic_load_relaxed(&state_);
239 do {
240 locked =
241 (state & kReaderLockMask) == 0 &&
242 (state & (kWriterLock | kWriterSpinWait | kWaitingWriterMask)) != 0;
243 if (LIKELY(!locked))
244 new_state = state + kReaderLockInc;
245 else
246 new_state = state + kWaitingReaderInc;
247 } while (UNLIKELY(!atomic_compare_exchange_weak(&state_, &state, new_state,
248 memory_order_acquire)));
249 if (UNLIKELY(locked))
250 readers_.Wait();
251 DCHECK_EQ(atomic_load_relaxed(&state_) & kWriterLock, 0);
252 DCHECK_NE(atomic_load_relaxed(&state_) & kReaderLockMask, 0);
253 }
254
255 void ReadUnlock() RELEASE_SHARED() {
256 CheckedMutex::Unlock();
257 bool wake;
258 u64 new_state;
259 u64 state = atomic_load_relaxed(&state_);
260 do {
261 DCHECK_NE(state & kReaderLockMask, 0);
262 DCHECK_EQ(state & (kWaitingReaderMask | kWriterLock), 0);
263 new_state = state - kReaderLockInc;
264 wake = (new_state & (kReaderLockMask | kWriterSpinWait)) == 0 &&
265 (new_state & kWaitingWriterMask) != 0;
266 if (wake)
267 new_state = (new_state - kWaitingWriterInc) | kWriterSpinWait;
268 } while (UNLIKELY(!atomic_compare_exchange_weak(&state_, &state, new_state,
269 memory_order_release)));
270 if (UNLIKELY(wake))
271 writers_.Post();
272 }
273
274 // This function does not guarantee an explicit check that the calling thread
275 // is the thread which owns the mutex. This behavior, while more strictly
276 // correct, causes problems in cases like StopTheWorld, where a parent thread
277 // owns the mutex but a child checks that it is locked. Rather than
278 // maintaining complex state to work around those situations, the check only
279 // checks that the mutex is owned.
280 void CheckWriteLocked() const CHECK_LOCKED() {
281 CHECK(atomic_load(&state_, memory_order_relaxed) & kWriterLock);
282 }
283
284 void CheckLocked() const CHECK_LOCKED() { CheckWriteLocked(); }
285
286 void CheckReadLocked() const CHECK_LOCKED() {
287 CHECK(atomic_load(&state_, memory_order_relaxed) & kReaderLockMask);
288 }
289
290 private:
291 atomic_uint64_t state_ = {0};
292 Semaphore writers_;
293 Semaphore readers_;
294
295 // The state has 3 counters:
296 // - number of readers holding the lock,
297 // if non zero, the mutex is read-locked
298 // - number of waiting readers,
299 // if not zero, the mutex is write-locked
300 // - number of waiting writers,
301 // if non zero, the mutex is read- or write-locked
302 // And 2 flags:
303 // - writer lock
304 // if set, the mutex is write-locked
305 // - a writer is awake and spin-waiting
306 // the flag is used to prevent thundering herd problem
307 // (new writers are not woken if this flag is set)
308 //
309 // Writer support active spinning, readers does not.
310 // But readers are more aggressive and always take the mutex
311 // if there are any other readers.
312 // Writers hand off the mutex to readers: after wake up readers
313 // already assume ownership of the mutex (don't need to do any
314 // state updates). But the mutex is not handed off to writers,
315 // after wake up writers compete to lock the mutex again.
316 // This is needed to allow repeated write locks even in presence
317 // of other blocked writers.
318 static constexpr u64 kCounterWidth = 20;
319 static constexpr u64 kReaderLockShift = 0;
320 static constexpr u64 kReaderLockInc = 1ull << kReaderLockShift;
321 static constexpr u64 kReaderLockMask = ((1ull << kCounterWidth) - 1)
322 << kReaderLockShift;
323 static constexpr u64 kWaitingReaderShift = kCounterWidth;
324 static constexpr u64 kWaitingReaderInc = 1ull << kWaitingReaderShift;
325 static constexpr u64 kWaitingReaderMask = ((1ull << kCounterWidth) - 1)
326 << kWaitingReaderShift;
327 static constexpr u64 kWaitingWriterShift = 2 * kCounterWidth;
328 static constexpr u64 kWaitingWriterInc = 1ull << kWaitingWriterShift;
329 static constexpr u64 kWaitingWriterMask = ((1ull << kCounterWidth) - 1)
330 << kWaitingWriterShift;
331 static constexpr u64 kWriterLock = 1ull << (3 * kCounterWidth);
332 static constexpr u64 kWriterSpinWait = 1ull << (3 * kCounterWidth + 1);
333
334 Mutex(const Mutex &) = delete;
335 void operator=(const Mutex &) = delete;
336};
337
338void FutexWait(atomic_uint32_t *p, u32 cmp);
339void FutexWake(atomic_uint32_t *p, u32 count);
340
341class MUTEX BlockingMutex {
74342 public:
75343 explicit constexpr BlockingMutex(LinkerInitialized)
76344 : opaque_storage_ {0, }, owner_ {0} {}
77345 BlockingMutex();
78 void Lock();
79 void Unlock();
346 void Lock() ACQUIRE();
347 void Unlock() RELEASE();
80348
81349 // This function does not guarantee an explicit check that the calling thread
82350 // is the thread which owns the mutex. This behavior, while more strictly
......@@ -85,7 +353,7 @@ class BlockingMutex {
85353 // maintaining complex state to work around those situations, the check only
86354 // checks that the mutex is owned, and assumes callers to be generally
87355 // well-behaved.
88 void CheckLocked();
356 void CheckLocked() const CHECK_LOCKED();
89357
90358 private:
91359 // Solaris mutex_t has a member that requires 64-bit alignment.
......@@ -94,7 +362,7 @@ class BlockingMutex {
94362};
95363
96364// Reader-writer spin mutex.
97class RWMutex {
365class MUTEX RWMutex {
98366 public:
99367 RWMutex() {
100368 atomic_store(&state_, kUnlocked, memory_order_relaxed);
......@@ -104,7 +372,7 @@ class RWMutex {
104372 CHECK_EQ(atomic_load(&state_, memory_order_relaxed), kUnlocked);
105373 }
106374
107 void Lock() {
375 void Lock() ACQUIRE() {
108376 u32 cmp = kUnlocked;
109377 if (atomic_compare_exchange_strong(&state_, &cmp, kWriteLock,
110378 memory_order_acquire))
......@@ -112,27 +380,27 @@ class RWMutex {
112380 LockSlow();
113381 }
114382
115 void Unlock() {
383 void Unlock() RELEASE() {
116384 u32 prev = atomic_fetch_sub(&state_, kWriteLock, memory_order_release);
117385 DCHECK_NE(prev & kWriteLock, 0);
118386 (void)prev;
119387 }
120388
121 void ReadLock() {
389 void ReadLock() ACQUIRE_SHARED() {
122390 u32 prev = atomic_fetch_add(&state_, kReadLock, memory_order_acquire);
123391 if ((prev & kWriteLock) == 0)
124392 return;
125393 ReadLockSlow();
126394 }
127395
128 void ReadUnlock() {
396 void ReadUnlock() RELEASE_SHARED() {
129397 u32 prev = atomic_fetch_sub(&state_, kReadLock, memory_order_release);
130398 DCHECK_EQ(prev & kWriteLock, 0);
131399 DCHECK_GT(prev & ~kWriteLock, 0);
132400 (void)prev;
133401 }
134402
135 void CheckLocked() {
403 void CheckLocked() const CHECK_LOCKED() {
136404 CHECK_NE(atomic_load(&state_, memory_order_relaxed), kUnlocked);
137405 }
138406
......@@ -171,52 +439,48 @@ class RWMutex {
171439 }
172440 }
173441
174 RWMutex(const RWMutex&);
175 void operator = (const RWMutex&);
442 RWMutex(const RWMutex &) = delete;
443 void operator=(const RWMutex &) = delete;
176444};
177445
178template<typename MutexType>
179class GenericScopedLock {
446template <typename MutexType>
447class SCOPED_LOCK GenericScopedLock {
180448 public:
181 explicit GenericScopedLock(MutexType *mu)
182 : mu_(mu) {
449 explicit GenericScopedLock(MutexType *mu) ACQUIRE(mu) : mu_(mu) {
183450 mu_->Lock();
184451 }
185452
186 ~GenericScopedLock() {
187 mu_->Unlock();
188 }
453 ~GenericScopedLock() RELEASE() { mu_->Unlock(); }
189454
190455 private:
191456 MutexType *mu_;
192457
193 GenericScopedLock(const GenericScopedLock&);
194 void operator=(const GenericScopedLock&);
458 GenericScopedLock(const GenericScopedLock &) = delete;
459 void operator=(const GenericScopedLock &) = delete;
195460};
196461
197template<typename MutexType>
198class GenericScopedReadLock {
462template <typename MutexType>
463class SCOPED_LOCK GenericScopedReadLock {
199464 public:
200 explicit GenericScopedReadLock(MutexType *mu)
201 : mu_(mu) {
465 explicit GenericScopedReadLock(MutexType *mu) ACQUIRE(mu) : mu_(mu) {
202466 mu_->ReadLock();
203467 }
204468
205 ~GenericScopedReadLock() {
206 mu_->ReadUnlock();
207 }
469 ~GenericScopedReadLock() RELEASE() { mu_->ReadUnlock(); }
208470
209471 private:
210472 MutexType *mu_;
211473
212 GenericScopedReadLock(const GenericScopedReadLock&);
213 void operator=(const GenericScopedReadLock&);
474 GenericScopedReadLock(const GenericScopedReadLock &) = delete;
475 void operator=(const GenericScopedReadLock &) = delete;
214476};
215477
216478typedef GenericScopedLock<StaticSpinMutex> SpinMutexLock;
217479typedef GenericScopedLock<BlockingMutex> BlockingMutexLock;
218480typedef GenericScopedLock<RWMutex> RWMutexLock;
219481typedef GenericScopedReadLock<RWMutex> RWMutexReadLock;
482typedef GenericScopedLock<Mutex> Lock;
483typedef GenericScopedReadLock<Mutex> ReadLock;
220484
221485} // namespace __sanitizer
222486
lib/tsan/sanitizer_common/sanitizer_netbsd.cpp+15-7
......@@ -105,11 +105,22 @@ uptr internal_munmap(void *addr, uptr length) {
105105 return _REAL(munmap, addr, length);
106106}
107107
108uptr internal_mremap(void *old_address, uptr old_size, uptr new_size, int flags,
109 void *new_address) {
110 CHECK(false && "internal_mremap is unimplemented on NetBSD");
111 return 0;
112}
113
108114int internal_mprotect(void *addr, uptr length, int prot) {
109115 DEFINE__REAL(int, mprotect, void *a, uptr b, int c);
110116 return _REAL(mprotect, addr, length, prot);
111117}
112118
119int internal_madvise(uptr addr, uptr length, int advice) {
120 DEFINE__REAL(int, madvise, void *a, uptr b, int c);
121 return _REAL(madvise, (void *)addr, length, advice);
122}
123
113124uptr internal_close(fd_t fd) {
114125 CHECK(&_sys_close);
115126 return _sys_close(fd);
......@@ -204,15 +215,12 @@ void internal__exit(int exitcode) {
204215 Die(); // Unreachable.
205216}
206217
207unsigned int internal_sleep(unsigned int seconds) {
218void internal_usleep(u64 useconds) {
208219 struct timespec ts;
209 ts.tv_sec = seconds;
210 ts.tv_nsec = 0;
220 ts.tv_sec = useconds / 1000000;
221 ts.tv_nsec = (useconds % 1000000) * 1000;
211222 CHECK(&_sys___nanosleep50);
212 int res = _sys___nanosleep50(&ts, &ts);
213 if (res)
214 return ts.tv_sec;
215 return 0;
223 _sys___nanosleep50(&ts, &ts);
216224}
217225
218226uptr internal_execve(const char *filename, char *const argv[],
lib/tsan/sanitizer_common/sanitizer_openbsd.cpp-115
......@@ -1,115 +0,0 @@
1//===-- sanitizer_openbsd.cpp ---------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file is shared between various sanitizers' runtime libraries and
10// implements Solaris-specific functions.
11//===----------------------------------------------------------------------===//
12
13#include "sanitizer_platform.h"
14#if SANITIZER_OPENBSD
15
16#include <stdio.h>
17
18#include "sanitizer_common.h"
19#include "sanitizer_flags.h"
20#include "sanitizer_internal_defs.h"
21#include "sanitizer_libc.h"
22#include "sanitizer_placement_new.h"
23#include "sanitizer_platform_limits_posix.h"
24#include "sanitizer_procmaps.h"
25
26#include <errno.h>
27#include <fcntl.h>
28#include <limits.h>
29#include <pthread.h>
30#include <sched.h>
31#include <signal.h>
32#include <stdio.h>
33#include <stdlib.h>
34#include <sys/mman.h>
35#include <sys/shm.h>
36#include <sys/sysctl.h>
37#include <sys/types.h>
38#include <unistd.h>
39
40extern char **environ;
41
42namespace __sanitizer {
43
44uptr internal_mmap(void *addr, size_t length, int prot, int flags, int fd,
45 u64 offset) {
46 return (uptr)mmap(addr, length, prot, flags, fd, offset);
47}
48
49uptr internal_munmap(void *addr, uptr length) { return munmap(addr, length); }
50
51int internal_mprotect(void *addr, uptr length, int prot) {
52 return mprotect(addr, length, prot);
53}
54
55int internal_sysctlbyname(const char *sname, void *oldp, uptr *oldlenp,
56 const void *newp, uptr newlen) {
57 Printf("internal_sysctlbyname not implemented for OpenBSD");
58 Die();
59 return 0;
60}
61
62uptr ReadBinaryName(/*out*/char *buf, uptr buf_len) {
63 // On OpenBSD we cannot get the full path
64 struct kinfo_proc kp;
65 uptr kl;
66 const int Mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid()};
67 if (internal_sysctl(Mib, ARRAY_SIZE(Mib), &kp, &kl, NULL, 0) != -1)
68 return internal_snprintf(buf,
69 (KI_MAXCOMLEN < buf_len ? KI_MAXCOMLEN : buf_len),
70 "%s", kp.p_comm);
71 return (uptr)0;
72}
73
74static void GetArgsAndEnv(char ***argv, char ***envp) {
75 uptr nargv;
76 uptr nenv;
77 int argvmib[4] = {CTL_KERN, KERN_PROC_ARGS, getpid(), KERN_PROC_ARGV};
78 int envmib[4] = {CTL_KERN, KERN_PROC_ARGS, getpid(), KERN_PROC_ENV};
79 if (internal_sysctl(argvmib, 4, NULL, &nargv, NULL, 0) == -1) {
80 Printf("sysctl KERN_PROC_NARGV failed\n");
81 Die();
82 }
83 if (internal_sysctl(envmib, 4, NULL, &nenv, NULL, 0) == -1) {
84 Printf("sysctl KERN_PROC_NENV failed\n");
85 Die();
86 }
87 if (internal_sysctl(argvmib, 4, &argv, &nargv, NULL, 0) == -1) {
88 Printf("sysctl KERN_PROC_ARGV failed\n");
89 Die();
90 }
91 if (internal_sysctl(envmib, 4, &envp, &nenv, NULL, 0) == -1) {
92 Printf("sysctl KERN_PROC_ENV failed\n");
93 Die();
94 }
95}
96
97char **GetArgv() {
98 char **argv, **envp;
99 GetArgsAndEnv(&argv, &envp);
100 return argv;
101}
102
103char **GetEnviron() {
104 char **argv, **envp;
105 GetArgsAndEnv(&argv, &envp);
106 return envp;
107}
108
109void ReExec() {
110 UNIMPLEMENTED();
111}
112
113} // namespace __sanitizer
114
115#endif // SANITIZER_OPENBSD
lib/tsan/sanitizer_common/sanitizer_platform.h+42-26
......@@ -13,10 +13,16 @@
1313#define SANITIZER_PLATFORM_H
1414
1515#if !defined(__linux__) && !defined(__FreeBSD__) && !defined(__NetBSD__) && \
16 !defined(__OpenBSD__) && !defined(__APPLE__) && !defined(_WIN32) && \
17 !defined(__Fuchsia__) && !defined(__rtems__) && \
18 !(defined(__sun__) && defined(__svr4__))
19# error "This operating system is not supported"
16 !defined(__APPLE__) && !defined(_WIN32) && !defined(__Fuchsia__) && \
17 !(defined(__sun__) && defined(__svr4__))
18# error "This operating system is not supported"
19#endif
20
21// Get __GLIBC__ on a glibc platform. Exclude Android: features.h includes C
22// function declarations into a .S file which doesn't compile.
23// https://crbug.com/1162741
24#if __has_include(<features.h>) && !defined(__ANDROID__)
25#include <features.h>
2026#endif
2127
2228#if defined(__linux__)
......@@ -25,6 +31,12 @@
2531# define SANITIZER_LINUX 0
2632#endif
2733
34#if defined(__GLIBC__)
35# define SANITIZER_GLIBC 1
36#else
37# define SANITIZER_GLIBC 0
38#endif
39
2840#if defined(__FreeBSD__)
2941# define SANITIZER_FREEBSD 1
3042#else
......@@ -37,12 +49,6 @@
3749# define SANITIZER_NETBSD 0
3850#endif
3951
40#if defined(__OpenBSD__)
41# define SANITIZER_OPENBSD 1
42#else
43# define SANITIZER_OPENBSD 0
44#endif
45
4652#if defined(__sun__) && defined(__svr4__)
4753# define SANITIZER_SOLARIS 1
4854#else
......@@ -52,6 +58,11 @@
5258#if defined(__APPLE__)
5359# define SANITIZER_MAC 1
5460# include <TargetConditionals.h>
61# if TARGET_OS_OSX
62# define SANITIZER_OSX 1
63# else
64# define SANITIZER_OSX 0
65# endif
5566# if TARGET_OS_IPHONE
5667# define SANITIZER_IOS 1
5768# else
......@@ -66,6 +77,7 @@
6677# define SANITIZER_MAC 0
6778# define SANITIZER_IOS 0
6879# define SANITIZER_IOSSIM 0
80# define SANITIZER_OSX 0
6981#endif
7082
7183#if defined(__APPLE__) && TARGET_OS_IPHONE && TARGET_OS_WATCH
......@@ -104,15 +116,9 @@
104116# define SANITIZER_FUCHSIA 0
105117#endif
106118
107#if defined(__rtems__)
108# define SANITIZER_RTEMS 1
109#else
110# define SANITIZER_RTEMS 0
111#endif
112
113119#define SANITIZER_POSIX \
114120 (SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_MAC || \
115 SANITIZER_NETBSD || SANITIZER_OPENBSD || SANITIZER_SOLARIS)
121 SANITIZER_NETBSD || SANITIZER_SOLARIS)
116122
117123#if __LP64__ || defined(_WIN64)
118124# define SANITIZER_WORDSIZE 64
......@@ -213,10 +219,10 @@
213219# define SANITIZER_SOLARIS32 0
214220#endif
215221
216#if defined(__myriad2__)
217# define SANITIZER_MYRIAD2 1
222#if defined(__riscv) && (__riscv_xlen == 64)
223#define SANITIZER_RISCV64 1
218224#else
219# define SANITIZER_MYRIAD2 0
225#define SANITIZER_RISCV64 0
220226#endif
221227
222228// By default we allow to use SizeClassAllocator64 on 64-bit platform.
......@@ -238,11 +244,21 @@
238244// FIXME: this value should be different on different platforms. Larger values
239245// will still work but will consume more memory for TwoLevelByteMap.
240246#if defined(__mips__)
247#if SANITIZER_GO && defined(__mips64)
248#define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 47)
249#else
241250# define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 40)
251#endif
252#elif SANITIZER_RISCV64
253#define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 38)
242254#elif defined(__aarch64__)
243255# if SANITIZER_MAC
244// Darwin iOS/ARM64 has a 36-bit VMA, 64GiB VM
245# define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 36)
256# if SANITIZER_OSX || SANITIZER_IOSSIM
257# define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 47)
258# else
259 // Darwin iOS/ARM64 has a 36-bit VMA, 64GiB VM
260# define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 36)
261# endif
246262# else
247263# define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 48)
248264# endif
......@@ -331,7 +347,7 @@
331347#endif
332348
333349#if SANITIZER_FREEBSD || SANITIZER_MAC || SANITIZER_NETBSD || \
334 SANITIZER_OPENBSD || SANITIZER_SOLARIS
350 SANITIZER_SOLARIS
335351# define SANITIZER_MADVISE_DONTNEED MADV_FREE
336352#else
337353# define SANITIZER_MADVISE_DONTNEED MADV_DONTNEED
......@@ -345,9 +361,9 @@
345361# define SANITIZER_CACHE_LINE_SIZE 64
346362#endif
347363
348// Enable offline markup symbolizer for Fuchsia and RTEMS.
349#if SANITIZER_FUCHSIA || SANITIZER_RTEMS
350#define SANITIZER_SYMBOLIZER_MARKUP 1
364// Enable offline markup symbolizer for Fuchsia.
365#if SANITIZER_FUCHSIA
366# define SANITIZER_SYMBOLIZER_MARKUP 1
351367#else
352368#define SANITIZER_SYMBOLIZER_MARKUP 0
353369#endif
lib/tsan/sanitizer_common/sanitizer_platform_interceptors.h+184-190
......@@ -15,133 +15,127 @@
1515
1616#include "sanitizer_glibc_version.h"
1717#include "sanitizer_internal_defs.h"
18#include "sanitizer_platform.h"
1819
1920#if SANITIZER_POSIX
20# define SI_POSIX 1
21#define SI_POSIX 1
2122#else
22# define SI_POSIX 0
23#define SI_POSIX 0
2324#endif
2425
2526#if !SANITIZER_WINDOWS
26# define SI_WINDOWS 0
27#define SI_WINDOWS 0
2728#else
28# define SI_WINDOWS 1
29#define SI_WINDOWS 1
2930#endif
3031
3132#if SI_WINDOWS && SI_POSIX
32# error "Windows is not POSIX!"
33#error "Windows is not POSIX!"
3334#endif
3435
3536#if SI_POSIX
36# include "sanitizer_platform_limits_freebsd.h"
37# include "sanitizer_platform_limits_netbsd.h"
38# include "sanitizer_platform_limits_openbsd.h"
39# include "sanitizer_platform_limits_posix.h"
40# include "sanitizer_platform_limits_solaris.h"
37#include "sanitizer_platform_limits_freebsd.h"
38#include "sanitizer_platform_limits_netbsd.h"
39#include "sanitizer_platform_limits_posix.h"
40#include "sanitizer_platform_limits_solaris.h"
4141#endif
4242
4343#if SANITIZER_LINUX && !SANITIZER_ANDROID
44# define SI_LINUX_NOT_ANDROID 1
44#define SI_LINUX_NOT_ANDROID 1
4545#else
46# define SI_LINUX_NOT_ANDROID 0
46#define SI_LINUX_NOT_ANDROID 0
4747#endif
4848
49#if SANITIZER_ANDROID
50# define SI_ANDROID 1
49#if SANITIZER_GLIBC
50#define SI_GLIBC 1
5151#else
52# define SI_ANDROID 0
52#define SI_GLIBC 0
5353#endif
5454
55#if SANITIZER_FREEBSD
56# define SI_FREEBSD 1
55#if SANITIZER_ANDROID
56#define SI_ANDROID 1
5757#else
58# define SI_FREEBSD 0
58#define SI_ANDROID 0
5959#endif
6060
61#if SANITIZER_NETBSD
62# define SI_NETBSD 1
61#if SANITIZER_FREEBSD
62#define SI_FREEBSD 1
6363#else
64# define SI_NETBSD 0
64#define SI_FREEBSD 0
6565#endif
6666
67#if SANITIZER_OPENBSD
68#define SI_OPENBSD 1
67#if SANITIZER_NETBSD
68#define SI_NETBSD 1
6969#else
70#define SI_OPENBSD 0
70#define SI_NETBSD 0
7171#endif
7272
7373#if SANITIZER_LINUX
74# define SI_LINUX 1
74#define SI_LINUX 1
7575#else
76# define SI_LINUX 0
76#define SI_LINUX 0
7777#endif
7878
7979#if SANITIZER_MAC
80# define SI_MAC 1
81# define SI_NOT_MAC 0
80#define SI_MAC 1
81#define SI_NOT_MAC 0
8282#else
83# define SI_MAC 0
84# define SI_NOT_MAC 1
83#define SI_MAC 0
84#define SI_NOT_MAC 1
8585#endif
8686
8787#if SANITIZER_IOS
88# define SI_IOS 1
88#define SI_IOS 1
8989#else
90# define SI_IOS 0
90#define SI_IOS 0
9191#endif
9292
9393#if SANITIZER_IOSSIM
94# define SI_IOSSIM 1
94#define SI_IOSSIM 1
9595#else
96# define SI_IOSSIM 0
96#define SI_IOSSIM 0
9797#endif
9898
9999#if SANITIZER_WATCHOS
100# define SI_WATCHOS 1
100#define SI_WATCHOS 1
101101#else
102# define SI_WATCHOS 0
102#define SI_WATCHOS 0
103103#endif
104104
105105#if SANITIZER_TVOS
106# define SI_TVOS 1
106#define SI_TVOS 1
107107#else
108# define SI_TVOS 0
108#define SI_TVOS 0
109109#endif
110110
111111#if SANITIZER_FUCHSIA
112# define SI_NOT_FUCHSIA 0
113#else
114# define SI_NOT_FUCHSIA 1
115#endif
116
117#if SANITIZER_RTEMS
118# define SI_NOT_RTEMS 0
112#define SI_NOT_FUCHSIA 0
119113#else
120# define SI_NOT_RTEMS 1
114#define SI_NOT_FUCHSIA 1
121115#endif
122116
123117#if SANITIZER_SOLARIS
124# define SI_SOLARIS 1
118#define SI_SOLARIS 1
125119#else
126# define SI_SOLARIS 0
120#define SI_SOLARIS 0
127121#endif
128122
129123#if SANITIZER_SOLARIS32
130# define SI_SOLARIS32 1
124#define SI_SOLARIS32 1
131125#else
132# define SI_SOLARIS32 0
126#define SI_SOLARIS32 0
133127#endif
134128
135129#if SANITIZER_POSIX && !SANITIZER_MAC
136# define SI_POSIX_NOT_MAC 1
130#define SI_POSIX_NOT_MAC 1
137131#else
138# define SI_POSIX_NOT_MAC 0
132#define SI_POSIX_NOT_MAC 0
139133#endif
140134
141135#if SANITIZER_LINUX && !SANITIZER_FREEBSD
142# define SI_LINUX_NOT_FREEBSD 1
143# else
144# define SI_LINUX_NOT_FREEBSD 0
136#define SI_LINUX_NOT_FREEBSD 1
137#else
138#define SI_LINUX_NOT_FREEBSD 0
145139#endif
146140
147141#define SANITIZER_INTERCEPT_STRLEN SI_NOT_FUCHSIA
......@@ -163,21 +157,20 @@
163157#define SANITIZER_INTERCEPT_MEMCMP SI_NOT_FUCHSIA
164158#define SANITIZER_INTERCEPT_BCMP \
165159 SANITIZER_INTERCEPT_MEMCMP && \
166 ((SI_POSIX && _GNU_SOURCE) || SI_NETBSD || SI_OPENBSD || SI_FREEBSD)
160 ((SI_POSIX && _GNU_SOURCE) || SI_NETBSD || SI_FREEBSD)
167161#define SANITIZER_INTERCEPT_STRNDUP SI_POSIX
168#define SANITIZER_INTERCEPT___STRNDUP SI_LINUX_NOT_FREEBSD
162#define SANITIZER_INTERCEPT___STRNDUP SI_GLIBC
169163#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && \
170164 __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1070
171# define SI_MAC_DEPLOYMENT_BELOW_10_7 1
165#define SI_MAC_DEPLOYMENT_BELOW_10_7 1
172166#else
173# define SI_MAC_DEPLOYMENT_BELOW_10_7 0
167#define SI_MAC_DEPLOYMENT_BELOW_10_7 0
174168#endif
175169// memmem on Darwin doesn't exist on 10.6
176170// FIXME: enable memmem on Windows.
177171#define SANITIZER_INTERCEPT_MEMMEM (SI_POSIX && !SI_MAC_DEPLOYMENT_BELOW_10_7)
178172#define SANITIZER_INTERCEPT_MEMCHR SI_NOT_FUCHSIA
179#define SANITIZER_INTERCEPT_MEMRCHR \
180 (SI_FREEBSD || SI_LINUX || SI_NETBSD || SI_OPENBSD)
173#define SANITIZER_INTERCEPT_MEMRCHR (SI_FREEBSD || SI_LINUX || SI_NETBSD)
181174
182175#define SANITIZER_INTERCEPT_READ SI_POSIX
183176#define SANITIZER_INTERCEPT_PREAD SI_POSIX
......@@ -190,64 +183,60 @@
190183#define SANITIZER_INTERCEPT_FPUTS SI_POSIX
191184#define SANITIZER_INTERCEPT_PUTS SI_POSIX
192185
193#define SANITIZER_INTERCEPT_PREAD64 SI_LINUX_NOT_ANDROID || SI_SOLARIS32
194#define SANITIZER_INTERCEPT_PWRITE64 SI_LINUX_NOT_ANDROID || SI_SOLARIS32
186#define SANITIZER_INTERCEPT_PREAD64 (SI_GLIBC || SI_SOLARIS32)
187#define SANITIZER_INTERCEPT_PWRITE64 (SI_GLIBC || SI_SOLARIS32)
195188
196189#define SANITIZER_INTERCEPT_READV SI_POSIX
197190#define SANITIZER_INTERCEPT_WRITEV SI_POSIX
198191
199192#define SANITIZER_INTERCEPT_PREADV \
200 (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_LINUX_NOT_ANDROID)
193 (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID)
201194#define SANITIZER_INTERCEPT_PWRITEV SI_LINUX_NOT_ANDROID
202#define SANITIZER_INTERCEPT_PREADV64 SI_LINUX_NOT_ANDROID
203#define SANITIZER_INTERCEPT_PWRITEV64 SI_LINUX_NOT_ANDROID
195#define SANITIZER_INTERCEPT_PREADV64 SI_GLIBC
196#define SANITIZER_INTERCEPT_PWRITEV64 SI_GLIBC
204197
205#define SANITIZER_INTERCEPT_PRCTL SI_LINUX
198#define SANITIZER_INTERCEPT_PRCTL SI_LINUX
206199
207200#define SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS SI_POSIX
208201#define SANITIZER_INTERCEPT_STRPTIME SI_POSIX
209202
210203#define SANITIZER_INTERCEPT_SCANF SI_POSIX
211#define SANITIZER_INTERCEPT_ISOC99_SCANF SI_LINUX_NOT_ANDROID
204#define SANITIZER_INTERCEPT_ISOC99_SCANF SI_GLIBC
212205
213206#ifndef SANITIZER_INTERCEPT_PRINTF
214# define SANITIZER_INTERCEPT_PRINTF SI_POSIX
215# define SANITIZER_INTERCEPT_PRINTF_L (SI_FREEBSD || SI_NETBSD)
216# define SANITIZER_INTERCEPT_ISOC99_PRINTF SI_LINUX_NOT_ANDROID
207#define SANITIZER_INTERCEPT_PRINTF SI_POSIX
208#define SANITIZER_INTERCEPT_PRINTF_L (SI_FREEBSD || SI_NETBSD)
209#define SANITIZER_INTERCEPT_ISOC99_PRINTF SI_GLIBC
217210#endif
218211
219212#define SANITIZER_INTERCEPT___PRINTF_CHK \
220 (SANITIZER_INTERCEPT_PRINTF && SI_LINUX_NOT_ANDROID)
213 (SANITIZER_INTERCEPT_PRINTF && SI_GLIBC)
221214
222215#define SANITIZER_INTERCEPT_FREXP SI_NOT_FUCHSIA
223216#define SANITIZER_INTERCEPT_FREXPF_FREXPL SI_POSIX
224217
225218#define SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS SI_POSIX
226#define SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS \
227 (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_MAC || SI_LINUX_NOT_ANDROID || \
228 SI_SOLARIS)
229#define SANITIZER_INTERCEPT_GETPWENT \
230 (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_MAC || SI_LINUX_NOT_ANDROID || \
231 SI_SOLARIS)
232#define SANITIZER_INTERCEPT_FGETGRENT_R \
233 (SI_FREEBSD || SI_OPENBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
219#define SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS \
220 (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
221#define SANITIZER_INTERCEPT_GETPWENT \
222 (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
223#define SANITIZER_INTERCEPT_FGETGRENT_R (SI_GLIBC || SI_SOLARIS)
234224#define SANITIZER_INTERCEPT_FGETPWENT SI_LINUX_NOT_ANDROID || SI_SOLARIS
235225#define SANITIZER_INTERCEPT_GETPWENT_R \
236 (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
237#define SANITIZER_INTERCEPT_FGETPWENT_R \
238 (SI_FREEBSD || SI_OPENBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
226 (SI_FREEBSD || SI_NETBSD || SI_GLIBC || SI_SOLARIS)
227#define SANITIZER_INTERCEPT_FGETPWENT_R (SI_FREEBSD || SI_GLIBC || SI_SOLARIS)
239228#define SANITIZER_INTERCEPT_SETPWENT \
240229 (SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
241230#define SANITIZER_INTERCEPT_CLOCK_GETTIME \
242 (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_LINUX || SI_SOLARIS)
231 (SI_FREEBSD || SI_NETBSD || SI_LINUX || SI_SOLARIS)
243232#define SANITIZER_INTERCEPT_CLOCK_GETCPUCLOCKID SI_LINUX
244233#define SANITIZER_INTERCEPT_GETITIMER SI_POSIX
245234#define SANITIZER_INTERCEPT_TIME SI_POSIX
246#define SANITIZER_INTERCEPT_GLOB SI_LINUX_NOT_ANDROID || SI_SOLARIS
247#define SANITIZER_INTERCEPT_GLOB64 SI_LINUX_NOT_ANDROID
235#define SANITIZER_INTERCEPT_GLOB (SI_GLIBC || SI_SOLARIS)
236#define SANITIZER_INTERCEPT_GLOB64 SI_GLIBC
248237#define SANITIZER_INTERCEPT_WAIT SI_POSIX
249238#define SANITIZER_INTERCEPT_INET SI_POSIX
250#define SANITIZER_INTERCEPT_PTHREAD_GETSCHEDPARAM (SI_POSIX && !SI_OPENBSD)
239#define SANITIZER_INTERCEPT_PTHREAD_GETSCHEDPARAM SI_POSIX
251240#define SANITIZER_INTERCEPT_GETADDRINFO SI_POSIX
252241#define SANITIZER_INTERCEPT_GETNAMEINFO SI_POSIX
253242#define SANITIZER_INTERCEPT_GETSOCKNAME SI_POSIX
......@@ -259,12 +248,10 @@
259248 (SI_FREEBSD || SI_LINUX_NOT_ANDROID)
260249#define SANITIZER_INTERCEPT_GETHOSTBYADDR_R \
261250 (SI_FREEBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
262#define SANITIZER_INTERCEPT_GETHOSTENT_R \
263 (SI_FREEBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
251#define SANITIZER_INTERCEPT_GETHOSTENT_R (SI_FREEBSD || SI_GLIBC || SI_SOLARIS)
264252#define SANITIZER_INTERCEPT_GETSOCKOPT SI_POSIX
265253#define SANITIZER_INTERCEPT_ACCEPT SI_POSIX
266#define SANITIZER_INTERCEPT_ACCEPT4 \
267 (SI_LINUX_NOT_ANDROID || SI_NETBSD || SI_OPENBSD)
254#define SANITIZER_INTERCEPT_ACCEPT4 (SI_LINUX_NOT_ANDROID || SI_NETBSD)
268255#define SANITIZER_INTERCEPT_PACCEPT SI_NETBSD
269256#define SANITIZER_INTERCEPT_MODF SI_POSIX
270257#define SANITIZER_INTERCEPT_RECVMSG SI_POSIX
......@@ -278,10 +265,10 @@
278265#define SANITIZER_INTERCEPT_SYSINFO SI_LINUX
279266#define SANITIZER_INTERCEPT_READDIR SI_POSIX
280267#define SANITIZER_INTERCEPT_READDIR64 SI_LINUX_NOT_ANDROID || SI_SOLARIS32
281#if SI_LINUX_NOT_ANDROID && \
282 (defined(__i386) || defined(__x86_64) || defined(__mips64) || \
283 defined(__powerpc64__) || defined(__aarch64__) || defined(__arm__) || \
284 defined(__s390__))
268#if SI_LINUX_NOT_ANDROID && \
269 (defined(__i386) || defined(__x86_64) || defined(__mips64) || \
270 defined(__powerpc64__) || defined(__aarch64__) || defined(__arm__) || \
271 defined(__s390__) || SANITIZER_RISCV64)
285272#define SANITIZER_INTERCEPT_PTRACE 1
286273#else
287274#define SANITIZER_INTERCEPT_PTRACE 0
......@@ -298,46 +285,42 @@
298285#define SANITIZER_INTERCEPT___STRXFRM_L SI_LINUX
299286#define SANITIZER_INTERCEPT_WCSXFRM SI_POSIX
300287#define SANITIZER_INTERCEPT___WCSXFRM_L SI_LINUX
301#define SANITIZER_INTERCEPT_WCSNRTOMBS \
302 (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_MAC || SI_LINUX_NOT_ANDROID || \
303 SI_SOLARIS)
304#define SANITIZER_INTERCEPT_WCRTOMB \
305 (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_MAC || SI_LINUX_NOT_ANDROID || \
306 SI_SOLARIS)
307#define SANITIZER_INTERCEPT_WCTOMB \
308 (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_MAC || SI_LINUX_NOT_ANDROID || \
309 SI_SOLARIS)
288#define SANITIZER_INTERCEPT_WCSNRTOMBS \
289 (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
290#define SANITIZER_INTERCEPT_WCRTOMB \
291 (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
292#define SANITIZER_INTERCEPT_WCTOMB \
293 (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
310294#define SANITIZER_INTERCEPT_TCGETATTR SI_LINUX_NOT_ANDROID || SI_SOLARIS
311295#define SANITIZER_INTERCEPT_REALPATH SI_POSIX
312#define SANITIZER_INTERCEPT_CANONICALIZE_FILE_NAME \
313 (SI_LINUX_NOT_ANDROID || SI_SOLARIS)
314#define SANITIZER_INTERCEPT_CONFSTR \
315 (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_MAC || SI_LINUX_NOT_ANDROID || \
316 SI_SOLARIS)
296#define SANITIZER_INTERCEPT_CANONICALIZE_FILE_NAME (SI_GLIBC || SI_SOLARIS)
297#define SANITIZER_INTERCEPT_CONFSTR \
298 (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
317299#define SANITIZER_INTERCEPT_SCHED_GETAFFINITY SI_LINUX_NOT_ANDROID
318300#define SANITIZER_INTERCEPT_SCHED_GETPARAM SI_LINUX_NOT_ANDROID || SI_SOLARIS
319301#define SANITIZER_INTERCEPT_STRERROR SI_POSIX
320302#define SANITIZER_INTERCEPT_STRERROR_R SI_POSIX
321303#define SANITIZER_INTERCEPT_XPG_STRERROR_R SI_LINUX_NOT_ANDROID
322304#define SANITIZER_INTERCEPT_SCANDIR \
323 (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
305 (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
324306#define SANITIZER_INTERCEPT_SCANDIR64 SI_LINUX_NOT_ANDROID || SI_SOLARIS32
325307#define SANITIZER_INTERCEPT_GETGROUPS SI_POSIX
326308#define SANITIZER_INTERCEPT_POLL SI_POSIX
327309#define SANITIZER_INTERCEPT_PPOLL SI_LINUX_NOT_ANDROID || SI_SOLARIS
328#define SANITIZER_INTERCEPT_WORDEXP \
310#define SANITIZER_INTERCEPT_WORDEXP \
329311 (SI_FREEBSD || SI_NETBSD || (SI_MAC && !SI_IOS) || SI_LINUX_NOT_ANDROID || \
330 SI_SOLARIS)
312 SI_SOLARIS) // NOLINT
331313#define SANITIZER_INTERCEPT_SIGWAIT SI_POSIX
332314#define SANITIZER_INTERCEPT_SIGWAITINFO SI_LINUX_NOT_ANDROID || SI_SOLARIS
333315#define SANITIZER_INTERCEPT_SIGTIMEDWAIT SI_LINUX_NOT_ANDROID || SI_SOLARIS
334316#define SANITIZER_INTERCEPT_SIGSETOPS \
335317 (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
318#define SANITIZER_INTERCEPT_SIGSET_LOGICOPS SI_LINUX_NOT_ANDROID
336319#define SANITIZER_INTERCEPT_SIGPENDING SI_POSIX
337320#define SANITIZER_INTERCEPT_SIGPROCMASK SI_POSIX
338321#define SANITIZER_INTERCEPT_PTHREAD_SIGMASK SI_POSIX
339322#define SANITIZER_INTERCEPT_BACKTRACE \
340 (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
323 (SI_FREEBSD || SI_NETBSD || SI_GLIBC || SI_SOLARIS)
341324#define SANITIZER_INTERCEPT_GETMNTENT SI_LINUX
342325#define SANITIZER_INTERCEPT_GETMNTENT_R SI_LINUX_NOT_ANDROID
343326#define SANITIZER_INTERCEPT_STATFS \
......@@ -345,25 +328,25 @@
345328#define SANITIZER_INTERCEPT_STATFS64 \
346329 (((SI_MAC && !TARGET_CPU_ARM64) && !SI_IOS) || SI_LINUX_NOT_ANDROID)
347330#define SANITIZER_INTERCEPT_STATVFS \
348 (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_LINUX_NOT_ANDROID)
331 (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID)
349332#define SANITIZER_INTERCEPT_STATVFS64 SI_LINUX_NOT_ANDROID
350333#define SANITIZER_INTERCEPT_INITGROUPS SI_POSIX
351#define SANITIZER_INTERCEPT_ETHER_NTOA_ATON (SI_POSIX && !SI_OPENBSD)
334#define SANITIZER_INTERCEPT_ETHER_NTOA_ATON SI_POSIX
352335#define SANITIZER_INTERCEPT_ETHER_HOST \
353336 (SI_FREEBSD || SI_MAC || SI_LINUX_NOT_ANDROID)
354337#define SANITIZER_INTERCEPT_ETHER_R (SI_FREEBSD || SI_LINUX_NOT_ANDROID)
355338#define SANITIZER_INTERCEPT_SHMCTL \
356339 (((SI_FREEBSD || SI_LINUX_NOT_ANDROID) && SANITIZER_WORDSIZE == 64) || \
357 SI_NETBSD || SI_OPENBSD || SI_SOLARIS) // NOLINT
358#define SANITIZER_INTERCEPT_RANDOM_R SI_LINUX_NOT_ANDROID
340 SI_NETBSD || SI_SOLARIS) // NOLINT
341#define SANITIZER_INTERCEPT_RANDOM_R SI_GLIBC
359342#define SANITIZER_INTERCEPT_PTHREAD_ATTR_GET SI_POSIX
360343#define SANITIZER_INTERCEPT_PTHREAD_ATTR_GETINHERITSCHED \
361344 (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
362#define SANITIZER_INTERCEPT_PTHREAD_ATTR_GETAFFINITY_NP SI_LINUX_NOT_ANDROID
363#define SANITIZER_INTERCEPT_PTHREAD_ATTR_GET_SCHED (SI_POSIX && !SI_OPENBSD)
345#define SANITIZER_INTERCEPT_PTHREAD_ATTR_GETAFFINITY_NP SI_GLIBC
346#define SANITIZER_INTERCEPT_PTHREAD_ATTR_GET_SCHED SI_POSIX
364347#define SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPSHARED \
365 (SI_POSIX && !SI_NETBSD && !SI_OPENBSD)
366#define SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETTYPE (SI_POSIX && !SI_OPENBSD)
348 (SI_POSIX && !SI_NETBSD)
349#define SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETTYPE SI_POSIX
367350#define SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPROTOCOL \
368351 (SI_MAC || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
369352#define SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPRIOCEILING \
......@@ -372,17 +355,18 @@
372355 (SI_LINUX_NOT_ANDROID || SI_SOLARIS)
373356#define SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETROBUST_NP SI_LINUX_NOT_ANDROID
374357#define SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GETPSHARED \
375 (SI_POSIX && !SI_NETBSD && !SI_OPENBSD)
376#define SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GETKIND_NP SI_LINUX_NOT_ANDROID
377#define SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GETPSHARED \
378 (SI_POSIX && !SI_NETBSD && !SI_OPENBSD)
358 (SI_POSIX && !SI_NETBSD)
359#define SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GETKIND_NP SI_GLIBC
360#define SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GETPSHARED (SI_POSIX && !SI_NETBSD)
379361#define SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GETCLOCK \
380362 (SI_LINUX_NOT_ANDROID || SI_SOLARIS)
381363#define SANITIZER_INTERCEPT_PTHREAD_BARRIERATTR_GETPSHARED \
382 (SI_LINUX_NOT_ANDROID && !SI_NETBSD && !SI_OPENBSD)
364 (SI_LINUX_NOT_ANDROID && !SI_NETBSD)
383365#define SANITIZER_INTERCEPT_THR_EXIT SI_FREEBSD
384366#define SANITIZER_INTERCEPT_TMPNAM SI_POSIX
385#define SANITIZER_INTERCEPT_TMPNAM_R SI_LINUX_NOT_ANDROID || SI_SOLARIS
367#define SANITIZER_INTERCEPT_TMPNAM_R (SI_GLIBC || SI_SOLARIS)
368#define SANITIZER_INTERCEPT_PTSNAME SI_LINUX
369#define SANITIZER_INTERCEPT_PTSNAME_R SI_LINUX
386370#define SANITIZER_INTERCEPT_TTYNAME SI_POSIX
387371#define SANITIZER_INTERCEPT_TTYNAME_R SI_POSIX
388372#define SANITIZER_INTERCEPT_TEMPNAM SI_POSIX
......@@ -393,71 +377,67 @@
393377#define SANITIZER_INTERCEPT_LGAMMAL (SI_POSIX && !SI_NETBSD)
394378#define SANITIZER_INTERCEPT_LGAMMA_R (SI_FREEBSD || SI_LINUX || SI_SOLARIS)
395379#define SANITIZER_INTERCEPT_LGAMMAL_R SI_LINUX_NOT_ANDROID || SI_SOLARIS
396#define SANITIZER_INTERCEPT_DRAND48_R SI_LINUX_NOT_ANDROID
397#define SANITIZER_INTERCEPT_RAND_R \
398 (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_MAC || SI_LINUX_NOT_ANDROID || \
399 SI_SOLARIS)
380#define SANITIZER_INTERCEPT_DRAND48_R SI_GLIBC
381#define SANITIZER_INTERCEPT_RAND_R \
382 (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
400383#define SANITIZER_INTERCEPT_ICONV \
401 (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
384 (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
402385#define SANITIZER_INTERCEPT_TIMES SI_POSIX
403386
404387// FIXME: getline seems to be available on OSX 10.7
405388#define SANITIZER_INTERCEPT_GETLINE \
406 (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
389 (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
407390
408391#define SANITIZER_INTERCEPT__EXIT \
409 (SI_LINUX || SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_MAC || SI_SOLARIS)
392 (SI_LINUX || SI_FREEBSD || SI_NETBSD || SI_MAC || SI_SOLARIS)
410393
411394#define SANITIZER_INTERCEPT_PTHREAD_MUTEX SI_POSIX
412#define SANITIZER_INTERCEPT___PTHREAD_MUTEX SI_LINUX_NOT_ANDROID
395#define SANITIZER_INTERCEPT___PTHREAD_MUTEX SI_GLIBC
413396#define SANITIZER_INTERCEPT___LIBC_MUTEX SI_NETBSD
414397#define SANITIZER_INTERCEPT_PTHREAD_SETNAME_NP \
415 (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
398 (SI_FREEBSD || SI_NETBSD || SI_GLIBC || SI_SOLARIS)
416399#define SANITIZER_INTERCEPT_PTHREAD_GETNAME_NP \
417 (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
400 (SI_FREEBSD || SI_NETBSD || SI_GLIBC || SI_SOLARIS)
418401
419402#define SANITIZER_INTERCEPT_TLS_GET_ADDR \
420 (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
403 (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
421404
422405#define SANITIZER_INTERCEPT_LISTXATTR SI_LINUX
423406#define SANITIZER_INTERCEPT_GETXATTR SI_LINUX
424407#define SANITIZER_INTERCEPT_GETRESID SI_LINUX
425#define SANITIZER_INTERCEPT_GETIFADDRS \
426 (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_LINUX_NOT_ANDROID || SI_MAC || \
427 SI_SOLARIS)
428#define SANITIZER_INTERCEPT_IF_INDEXTONAME \
429 (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_LINUX_NOT_ANDROID || SI_MAC || \
430 SI_SOLARIS)
408#define SANITIZER_INTERCEPT_GETIFADDRS \
409 (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_MAC || SI_SOLARIS)
410#define SANITIZER_INTERCEPT_IF_INDEXTONAME \
411 (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_MAC || SI_SOLARIS)
431412#define SANITIZER_INTERCEPT_CAPGET SI_LINUX_NOT_ANDROID
432413#if SI_LINUX && defined(__arm__)
433414#define SANITIZER_INTERCEPT_AEABI_MEM 1
434415#else
435416#define SANITIZER_INTERCEPT_AEABI_MEM 0
436417#endif
437#define SANITIZER_INTERCEPT___BZERO SI_MAC || SI_LINUX_NOT_ANDROID
418#define SANITIZER_INTERCEPT___BZERO SI_MAC || SI_GLIBC
438419#define SANITIZER_INTERCEPT_BZERO SI_LINUX_NOT_ANDROID
439#define SANITIZER_INTERCEPT_FTIME \
440 (!SI_FREEBSD && !SI_NETBSD && !SI_OPENBSD && SI_POSIX)
441#define SANITIZER_INTERCEPT_XDR SI_LINUX_NOT_ANDROID || SI_SOLARIS
420#define SANITIZER_INTERCEPT_FTIME (!SI_FREEBSD && !SI_NETBSD && SI_POSIX)
421#define SANITIZER_INTERCEPT_XDR (SI_GLIBC || SI_SOLARIS)
422#define SANITIZER_INTERCEPT_XDRREC SI_GLIBC
442423#define SANITIZER_INTERCEPT_TSEARCH \
443 (SI_LINUX_NOT_ANDROID || SI_MAC || SI_NETBSD || SI_OPENBSD || SI_SOLARIS)
444#define SANITIZER_INTERCEPT_LIBIO_INTERNALS SI_LINUX_NOT_ANDROID
424 (SI_LINUX_NOT_ANDROID || SI_MAC || SI_NETBSD || SI_SOLARIS)
425#define SANITIZER_INTERCEPT_LIBIO_INTERNALS SI_GLIBC
445426#define SANITIZER_INTERCEPT_FOPEN SI_POSIX
446#define SANITIZER_INTERCEPT_FOPEN64 SI_LINUX_NOT_ANDROID || SI_SOLARIS32
427#define SANITIZER_INTERCEPT_FOPEN64 (SI_GLIBC || SI_SOLARIS32)
447428#define SANITIZER_INTERCEPT_OPEN_MEMSTREAM \
448 (SI_LINUX_NOT_ANDROID || SI_NETBSD || SI_OPENBSD || SI_SOLARIS)
449#define SANITIZER_INTERCEPT_OBSTACK SI_LINUX_NOT_ANDROID
429 (SI_LINUX_NOT_ANDROID || SI_NETBSD || SI_SOLARIS)
430#define SANITIZER_INTERCEPT_OBSTACK SI_GLIBC
450431#define SANITIZER_INTERCEPT_FFLUSH SI_POSIX
451432#define SANITIZER_INTERCEPT_FCLOSE SI_POSIX
452433
453434#ifndef SANITIZER_INTERCEPT_DLOPEN_DLCLOSE
454#define SANITIZER_INTERCEPT_DLOPEN_DLCLOSE \
455 (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_LINUX_NOT_ANDROID || SI_MAC || \
456 SI_SOLARIS)
435#define SANITIZER_INTERCEPT_DLOPEN_DLCLOSE \
436 (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_MAC || SI_SOLARIS)
457437#endif
458438
459439#define SANITIZER_INTERCEPT_GETPASS \
460 (SI_LINUX_NOT_ANDROID || SI_MAC || SI_NETBSD || SI_OPENBSD)
440 (SI_LINUX_NOT_ANDROID || SI_MAC || SI_NETBSD)
461441#define SANITIZER_INTERCEPT_TIMERFD SI_LINUX_NOT_ANDROID
462442
463443#define SANITIZER_INTERCEPT_MLOCKX SI_POSIX
......@@ -465,21 +445,20 @@
465445#define SANITIZER_INTERCEPT_SEM \
466446 (SI_LINUX || SI_FREEBSD || SI_NETBSD || SI_SOLARIS)
467447#define SANITIZER_INTERCEPT_PTHREAD_SETCANCEL SI_POSIX
468#define SANITIZER_INTERCEPT_MINCORE \
469 (SI_LINUX || SI_NETBSD || SI_OPENBSD || SI_SOLARIS)
448#define SANITIZER_INTERCEPT_MINCORE (SI_LINUX || SI_NETBSD || SI_SOLARIS)
470449#define SANITIZER_INTERCEPT_PROCESS_VM_READV SI_LINUX
471450#define SANITIZER_INTERCEPT_CTERMID \
472 (SI_LINUX || SI_MAC || SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_SOLARIS)
451 (SI_LINUX || SI_MAC || SI_FREEBSD || SI_NETBSD || SI_SOLARIS)
473452#define SANITIZER_INTERCEPT_CTERMID_R (SI_MAC || SI_FREEBSD || SI_SOLARIS)
474453
475454#define SANITIZER_INTERCEPTOR_HOOKS \
476 (SI_LINUX || SI_MAC || SI_WINDOWS || SI_NETBSD)
455 (SI_LINUX || SI_MAC || SI_WINDOWS || SI_FREEBSD || SI_NETBSD || SI_SOLARIS)
477456#define SANITIZER_INTERCEPT_RECV_RECVFROM SI_POSIX
478457#define SANITIZER_INTERCEPT_SEND_SENDTO SI_POSIX
479458#define SANITIZER_INTERCEPT_EVENTFD_READ_WRITE SI_LINUX
480459
481460#define SANITIZER_INTERCEPT_STAT \
482 (SI_FREEBSD || SI_MAC || SI_ANDROID || SI_NETBSD || SI_OPENBSD || SI_SOLARIS)
461 (SI_FREEBSD || SI_MAC || SI_ANDROID || SI_NETBSD || SI_SOLARIS)
483462#define SANITIZER_INTERCEPT_LSTAT (SI_NETBSD || SI_FREEBSD)
484463#define SANITIZER_INTERCEPT___XSTAT (!SANITIZER_INTERCEPT_STAT && SI_POSIX)
485464#define SANITIZER_INTERCEPT___XSTAT64 SI_LINUX_NOT_ANDROID
......@@ -492,41 +471,34 @@
492471 (SI_LINUX_NOT_ANDROID || SI_MAC || SI_FREEBSD || SI_NETBSD)
493472
494473#define SANITIZER_INTERCEPT_GETLOADAVG \
495 (SI_LINUX_NOT_ANDROID || SI_MAC || SI_FREEBSD || SI_NETBSD || SI_OPENBSD)
474 (SI_LINUX_NOT_ANDROID || SI_MAC || SI_FREEBSD || SI_NETBSD)
496475
497476#define SANITIZER_INTERCEPT_MMAP SI_POSIX
498477#define SANITIZER_INTERCEPT_MMAP64 SI_LINUX_NOT_ANDROID
499#define SANITIZER_INTERCEPT_MALLOPT_AND_MALLINFO \
500 (!SI_FREEBSD && !SI_MAC && !SI_NETBSD && !SI_OPENBSD && SI_NOT_FUCHSIA && \
501 SI_NOT_RTEMS)
502#define SANITIZER_INTERCEPT_MEMALIGN \
503 (!SI_FREEBSD && !SI_MAC && !SI_NETBSD && !SI_OPENBSD && SI_NOT_RTEMS)
504#define SANITIZER_INTERCEPT_PVALLOC \
505 (!SI_FREEBSD && !SI_MAC && !SI_NETBSD && !SI_OPENBSD && SI_NOT_FUCHSIA && \
506 SI_NOT_RTEMS)
507#define SANITIZER_INTERCEPT_CFREE \
508 (!SI_FREEBSD && !SI_MAC && !SI_NETBSD && !SI_OPENBSD && SI_NOT_FUCHSIA && \
509 SI_NOT_RTEMS)
478#define SANITIZER_INTERCEPT_MALLOPT_AND_MALLINFO (SI_GLIBC || SI_ANDROID)
479#define SANITIZER_INTERCEPT_MEMALIGN (!SI_FREEBSD && !SI_MAC && !SI_NETBSD)
480#define SANITIZER_INTERCEPT___LIBC_MEMALIGN SI_GLIBC
481#define SANITIZER_INTERCEPT_PVALLOC (SI_GLIBC || SI_ANDROID)
482#define SANITIZER_INTERCEPT_CFREE (SI_GLIBC && !SANITIZER_RISCV64)
510483#define SANITIZER_INTERCEPT_REALLOCARRAY SI_POSIX
511#define SANITIZER_INTERCEPT_ALIGNED_ALLOC (!SI_MAC && SI_NOT_RTEMS)
512#define SANITIZER_INTERCEPT_MALLOC_USABLE_SIZE \
513 (!SI_MAC && !SI_OPENBSD && !SI_NETBSD)
484#define SANITIZER_INTERCEPT_ALIGNED_ALLOC (!SI_MAC)
485#define SANITIZER_INTERCEPT_MALLOC_USABLE_SIZE (!SI_MAC && !SI_NETBSD)
514486#define SANITIZER_INTERCEPT_MCHECK_MPROBE SI_LINUX_NOT_ANDROID
515487#define SANITIZER_INTERCEPT_WCSCAT SI_POSIX
516488#define SANITIZER_INTERCEPT_WCSDUP SI_POSIX
517489#define SANITIZER_INTERCEPT_SIGNAL_AND_SIGACTION (!SI_WINDOWS && SI_NOT_FUCHSIA)
518490#define SANITIZER_INTERCEPT_BSD_SIGNAL SI_ANDROID
519491
520#define SANITIZER_INTERCEPT_ACCT (SI_NETBSD || SI_OPENBSD || SI_FREEBSD)
492#define SANITIZER_INTERCEPT_ACCT (SI_NETBSD || SI_FREEBSD)
521493#define SANITIZER_INTERCEPT_USER_FROM_UID SI_NETBSD
522494#define SANITIZER_INTERCEPT_UID_FROM_USER SI_NETBSD
523495#define SANITIZER_INTERCEPT_GROUP_FROM_GID SI_NETBSD
524496#define SANITIZER_INTERCEPT_GID_FROM_GROUP SI_NETBSD
525#define SANITIZER_INTERCEPT_ACCESS (SI_NETBSD || SI_OPENBSD || SI_FREEBSD)
526#define SANITIZER_INTERCEPT_FACCESSAT (SI_NETBSD || SI_OPENBSD || SI_FREEBSD)
527#define SANITIZER_INTERCEPT_GETGROUPLIST (SI_NETBSD || SI_OPENBSD)
528#define SANITIZER_INTERCEPT_STRLCPY \
529 (SI_NETBSD || SI_FREEBSD || SI_OPENBSD || SI_MAC || SI_ANDROID)
497#define SANITIZER_INTERCEPT_ACCESS (SI_NETBSD || SI_FREEBSD)
498#define SANITIZER_INTERCEPT_FACCESSAT (SI_NETBSD || SI_FREEBSD)
499#define SANITIZER_INTERCEPT_GETGROUPLIST SI_NETBSD
500#define SANITIZER_INTERCEPT_STRLCPY \
501 (SI_NETBSD || SI_FREEBSD || SI_MAC || SI_ANDROID)
530502
531503#define SANITIZER_INTERCEPT_NAME_TO_HANDLE_AT SI_LINUX_NOT_ANDROID
532504#define SANITIZER_INTERCEPT_OPEN_BY_HANDLE_AT SI_LINUX_NOT_ANDROID
......@@ -534,23 +506,23 @@
534506#define SANITIZER_INTERCEPT_READLINK SI_POSIX
535507#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && \
536508 __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101000
537# define SI_MAC_DEPLOYMENT_BELOW_10_10 1
509#define SI_MAC_DEPLOYMENT_BELOW_10_10 1
538510#else
539# define SI_MAC_DEPLOYMENT_BELOW_10_10 0
511#define SI_MAC_DEPLOYMENT_BELOW_10_10 0
540512#endif
541513#define SANITIZER_INTERCEPT_READLINKAT \
542514 (SI_POSIX && !SI_MAC_DEPLOYMENT_BELOW_10_10)
543515
544#define SANITIZER_INTERCEPT_DEVNAME (SI_NETBSD || SI_OPENBSD || SI_FREEBSD)
516#define SANITIZER_INTERCEPT_DEVNAME (SI_NETBSD || SI_FREEBSD)
545517#define SANITIZER_INTERCEPT_DEVNAME_R (SI_NETBSD || SI_FREEBSD)
546518#define SANITIZER_INTERCEPT_FGETLN (SI_NETBSD || SI_FREEBSD)
547519#define SANITIZER_INTERCEPT_STRMODE (SI_NETBSD || SI_FREEBSD)
548520#define SANITIZER_INTERCEPT_TTYENT SI_NETBSD
549521#define SANITIZER_INTERCEPT_PROTOENT (SI_NETBSD || SI_LINUX)
550#define SANITIZER_INTERCEPT_PROTOENT_R (SI_LINUX_NOT_ANDROID)
522#define SANITIZER_INTERCEPT_PROTOENT_R SI_GLIBC
551523#define SANITIZER_INTERCEPT_NETENT SI_NETBSD
552#define SANITIZER_INTERCEPT_SETVBUF (SI_NETBSD || SI_FREEBSD || \
553 SI_LINUX || SI_MAC)
524#define SANITIZER_INTERCEPT_SETVBUF \
525 (SI_NETBSD || SI_FREEBSD || SI_LINUX || SI_MAC)
554526#define SANITIZER_INTERCEPT_GETMNTINFO (SI_NETBSD || SI_FREEBSD || SI_MAC)
555527#define SANITIZER_INTERCEPT_MI_VECTOR_HASH SI_NETBSD
556528#define SANITIZER_INTERCEPT_GETVFSSTAT SI_NETBSD
......@@ -598,12 +570,34 @@
598570#define SANITIZER_INTERCEPT_GETENTROPY SI_FREEBSD
599571#define SANITIZER_INTERCEPT_QSORT \
600572 (SI_POSIX && !SI_IOSSIM && !SI_WATCHOS && !SI_TVOS && !SI_ANDROID)
601#define SANITIZER_INTERCEPT_QSORT_R (SI_LINUX && !SI_ANDROID)
573#define SANITIZER_INTERCEPT_QSORT_R SI_GLIBC
602574// sigaltstack on i386 macOS cannot be intercepted due to setjmp()
603575// calling it and assuming that it does not clobber registers.
604576#define SANITIZER_INTERCEPT_SIGALTSTACK \
605577 (SI_POSIX && !(SANITIZER_MAC && SANITIZER_I386))
606578#define SANITIZER_INTERCEPT_UNAME (SI_POSIX && !SI_FREEBSD)
607579#define SANITIZER_INTERCEPT___XUNAME SI_FREEBSD
580#define SANITIZER_INTERCEPT_FLOPEN SI_FREEBSD
581
582// This macro gives a way for downstream users to override the above
583// interceptor macros irrespective of the platform they are on. They have
584// to do two things:
585// 1. Build compiler-rt with -DSANITIZER_OVERRIDE_INTERCEPTORS.
586// 2. Provide a header file named sanitizer_intercept_overriders.h in the
587// include path for their compiler-rt build.
588// An example of an overrider for strlen interceptor that one can list in
589// sanitizer_intercept_overriders.h is as follows:
590//
591// #ifdef SANITIZER_INTERCEPT_STRLEN
592// #undef SANITIZER_INTERCEPT_STRLEN
593// #define SANITIZER_INTERCEPT_STRLEN <value of choice>
594// #endif
595//
596// This "feature" is useful for downstream users who do not want some of
597// their libc funtions to be intercepted. They can selectively disable
598// interception of those functions.
599#ifdef SANITIZER_OVERRIDE_INTERCEPTORS
600#include <sanitizer_intercept_overriders.h>
601#endif
608602
609603#endif // #ifndef SANITIZER_PLATFORM_INTERCEPTORS_H
lib/tsan/sanitizer_common/sanitizer_platform_limits_freebsd.cpp+3-2
......@@ -35,7 +35,10 @@
3535#include <sys/stat.h>
3636#include <sys/statvfs.h>
3737#include <sys/time.h>
38#pragma clang diagnostic push
39#pragma clang diagnostic ignored "-W#warnings"
3840#include <sys/timeb.h>
41#pragma clang diagnostic pop
3942#include <sys/times.h>
4043#include <sys/timespec.h>
4144#include <sys/types.h>
......@@ -81,8 +84,6 @@
8184#include <sys/shm.h>
8285#undef _KERNEL
8386
84#undef INLINE // to avoid clashes with sanitizers' definitions
85
8687#undef IOC_DIRMASK
8788
8889// Include these after system headers to avoid name clashes and ambiguities.
lib/tsan/sanitizer_common/sanitizer_platform_limits_netbsd.cpp+154-1
......@@ -34,6 +34,7 @@
3434#include <sys/chio.h>
3535#include <sys/clockctl.h>
3636#include <sys/cpuio.h>
37#include <sys/dkbad.h>
3738#include <sys/dkio.h>
3839#include <sys/drvctlio.h>
3940#include <sys/dvdio.h>
......@@ -83,6 +84,7 @@
8384
8485#include <sys/resource.h>
8586#include <sys/sem.h>
87#include <sys/scsiio.h>
8688#include <sys/sha1.h>
8789#include <sys/sha2.h>
8890#include <sys/shm.h>
......@@ -139,7 +141,158 @@
139141#include <dev/ir/irdaio.h>
140142#include <dev/isa/isvio.h>
141143#include <dev/isa/wtreg.h>
144#if __has_include(<dev/iscsi/iscsi_ioctl.h>)
142145#include <dev/iscsi/iscsi_ioctl.h>
146#else
147/* Fallback for MKISCSI=no */
148
149typedef struct {
150 uint32_t status;
151 uint32_t session_id;
152 uint32_t connection_id;
153} iscsi_conn_status_parameters_t;
154
155typedef struct {
156 uint32_t status;
157 uint16_t interface_version;
158 uint16_t major;
159 uint16_t minor;
160 uint8_t version_string[224];
161} iscsi_get_version_parameters_t;
162
163typedef struct {
164 uint32_t status;
165 uint32_t session_id;
166 uint32_t connection_id;
167 struct {
168 unsigned int immediate : 1;
169 } options;
170 uint64_t lun;
171 scsireq_t req; /* from <sys/scsiio.h> */
172} iscsi_iocommand_parameters_t;
173
174typedef enum {
175 ISCSI_AUTH_None = 0,
176 ISCSI_AUTH_CHAP = 1,
177 ISCSI_AUTH_KRB5 = 2,
178 ISCSI_AUTH_SRP = 3
179} iscsi_auth_types_t;
180
181typedef enum {
182 ISCSI_LOGINTYPE_DISCOVERY = 0,
183 ISCSI_LOGINTYPE_NOMAP = 1,
184 ISCSI_LOGINTYPE_MAP = 2
185} iscsi_login_session_type_t;
186
187typedef enum { ISCSI_DIGEST_None = 0, ISCSI_DIGEST_CRC32C = 1 } iscsi_digest_t;
188
189typedef enum {
190 ISCSI_SESSION_TERMINATED = 1,
191 ISCSI_CONNECTION_TERMINATED,
192 ISCSI_RECOVER_CONNECTION,
193 ISCSI_DRIVER_TERMINATING
194} iscsi_event_t;
195
196typedef struct {
197 unsigned int mutual_auth : 1;
198 unsigned int is_secure : 1;
199 unsigned int auth_number : 4;
200 iscsi_auth_types_t auth_type[4];
201} iscsi_auth_info_t;
202
203typedef struct {
204 uint32_t status;
205 int socket;
206 struct {
207 unsigned int HeaderDigest : 1;
208 unsigned int DataDigest : 1;
209 unsigned int MaxConnections : 1;
210 unsigned int DefaultTime2Wait : 1;
211 unsigned int DefaultTime2Retain : 1;
212 unsigned int MaxRecvDataSegmentLength : 1;
213 unsigned int auth_info : 1;
214 unsigned int user_name : 1;
215 unsigned int password : 1;
216 unsigned int target_password : 1;
217 unsigned int TargetName : 1;
218 unsigned int TargetAlias : 1;
219 unsigned int ErrorRecoveryLevel : 1;
220 } is_present;
221 iscsi_auth_info_t auth_info;
222 iscsi_login_session_type_t login_type;
223 iscsi_digest_t HeaderDigest;
224 iscsi_digest_t DataDigest;
225 uint32_t session_id;
226 uint32_t connection_id;
227 uint32_t MaxRecvDataSegmentLength;
228 uint16_t MaxConnections;
229 uint16_t DefaultTime2Wait;
230 uint16_t DefaultTime2Retain;
231 uint16_t ErrorRecoveryLevel;
232 void *user_name;
233 void *password;
234 void *target_password;
235 void *TargetName;
236 void *TargetAlias;
237} iscsi_login_parameters_t;
238
239typedef struct {
240 uint32_t status;
241 uint32_t session_id;
242} iscsi_logout_parameters_t;
243
244typedef struct {
245 uint32_t status;
246 uint32_t event_id;
247} iscsi_register_event_parameters_t;
248
249typedef struct {
250 uint32_t status;
251 uint32_t session_id;
252 uint32_t connection_id;
253} iscsi_remove_parameters_t;
254
255typedef struct {
256 uint32_t status;
257 uint32_t session_id;
258 void *response_buffer;
259 uint32_t response_size;
260 uint32_t response_used;
261 uint32_t response_total;
262 uint8_t key[224];
263} iscsi_send_targets_parameters_t;
264
265typedef struct {
266 uint32_t status;
267 uint8_t InitiatorName[224];
268 uint8_t InitiatorAlias[224];
269 uint8_t ISID[6];
270} iscsi_set_node_name_parameters_t;
271
272typedef struct {
273 uint32_t status;
274 uint32_t event_id;
275 iscsi_event_t event_kind;
276 uint32_t session_id;
277 uint32_t connection_id;
278 uint32_t reason;
279} iscsi_wait_event_parameters_t;
280
281#define ISCSI_GET_VERSION _IOWR(0, 1, iscsi_get_version_parameters_t)
282#define ISCSI_LOGIN _IOWR(0, 2, iscsi_login_parameters_t)
283#define ISCSI_LOGOUT _IOWR(0, 3, iscsi_logout_parameters_t)
284#define ISCSI_ADD_CONNECTION _IOWR(0, 4, iscsi_login_parameters_t)
285#define ISCSI_RESTORE_CONNECTION _IOWR(0, 5, iscsi_login_parameters_t)
286#define ISCSI_REMOVE_CONNECTION _IOWR(0, 6, iscsi_remove_parameters_t)
287#define ISCSI_CONNECTION_STATUS _IOWR(0, 7, iscsi_conn_status_parameters_t)
288#define ISCSI_SEND_TARGETS _IOWR(0, 8, iscsi_send_targets_parameters_t)
289#define ISCSI_SET_NODE_NAME _IOWR(0, 9, iscsi_set_node_name_parameters_t)
290#define ISCSI_IO_COMMAND _IOWR(0, 10, iscsi_iocommand_parameters_t)
291#define ISCSI_REGISTER_EVENT _IOWR(0, 11, iscsi_register_event_parameters_t)
292#define ISCSI_DEREGISTER_EVENT _IOWR(0, 12, iscsi_register_event_parameters_t)
293#define ISCSI_WAIT_EVENT _IOWR(0, 13, iscsi_wait_event_parameters_t)
294#define ISCSI_POLL_EVENT _IOWR(0, 14, iscsi_wait_event_parameters_t)
295#endif
143296#include <dev/ofw/openfirmio.h>
144297#include <dev/pci/amrio.h>
145298#include <dev/pci/mlyreg.h>
......@@ -372,7 +525,7 @@ struct urio_command {
372525#include "sanitizer_platform_limits_netbsd.h"
373526
374527namespace __sanitizer {
375void *__sanitizer_get_link_map_by_dlopen_handle(void* handle) {
528void *__sanitizer_get_link_map_by_dlopen_handle(void *handle) {
376529 void *p = nullptr;
377530 return internal_dlinfo(handle, RTLD_DI_LINKMAP, &p) == 0 ? p : nullptr;
378531}
lib/tsan/sanitizer_common/sanitizer_platform_limits_netbsd.h+2-4
......@@ -21,8 +21,8 @@
2121
2222namespace __sanitizer {
2323void *__sanitizer_get_link_map_by_dlopen_handle(void *handle);
24# define GET_LINK_MAP_BY_DLOPEN_HANDLE(handle) \
25 (link_map *)__sanitizer_get_link_map_by_dlopen_handle(handle)
24#define GET_LINK_MAP_BY_DLOPEN_HANDLE(handle) \
25 (link_map *)__sanitizer_get_link_map_by_dlopen_handle(handle)
2626
2727extern unsigned struct_utsname_sz;
2828extern unsigned struct_stat_sz;
......@@ -1024,12 +1024,10 @@ extern unsigned struct_RF_ProgressInfo_sz;
10241024extern unsigned struct_nvlist_ref_sz;
10251025extern unsigned struct_StringList_sz;
10261026
1027
10281027// A special value to mark ioctls that are not present on the target platform,
10291028// when it can not be determined without including any system headers.
10301029extern const unsigned IOCTL_NOT_PRESENT;
10311030
1032
10331031extern unsigned IOCTL_AFM_ADDFMAP;
10341032extern unsigned IOCTL_AFM_DELFMAP;
10351033extern unsigned IOCTL_AFM_CLEANFMAP;
lib/tsan/sanitizer_common/sanitizer_platform_limits_openbsd.cpp-279
......@@ -1,279 +0,0 @@
1//===-- sanitizer_platform_limits_openbsd.cpp -----------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file is a part of Sanitizer common code.
10//
11// Sizes and layouts of platform-specific NetBSD data structures.
12//===----------------------------------------------------------------------===//
13
14#include "sanitizer_platform.h"
15
16#if SANITIZER_OPENBSD
17#include <arpa/inet.h>
18#include <dirent.h>
19#include <glob.h>
20#include <grp.h>
21#include <ifaddrs.h>
22#include <limits.h>
23#include <link_elf.h>
24#include <sys/socket.h>
25#include <net/if.h>
26#include <net/ppp_defs.h>
27#include <net/route.h>
28#include <netdb.h>
29#include <netinet/in.h>
30#include <netinet/ip_mroute.h>
31#include <poll.h>
32#include <pthread.h>
33#include <pwd.h>
34#include <semaphore.h>
35#include <signal.h>
36#include <soundcard.h>
37#include <stddef.h>
38#include <stdint.h>
39#include <sys/filio.h>
40#include <sys/ipc.h>
41#include <sys/mman.h>
42#include <sys/mount.h>
43#include <sys/msg.h>
44#include <sys/mtio.h>
45#include <sys/ptrace.h>
46#include <sys/resource.h>
47#include <sys/shm.h>
48#include <sys/signal.h>
49#include <sys/sockio.h>
50#include <sys/stat.h>
51#include <sys/statvfs.h>
52#include <sys/time.h>
53#include <sys/times.h>
54#include <sys/types.h>
55#include <sys/utsname.h>
56#include <term.h>
57#include <time.h>
58#include <utime.h>
59#include <utmp.h>
60#include <wchar.h>
61
62// Include these after system headers to avoid name clashes and ambiguities.
63#include "sanitizer_internal_defs.h"
64#include "sanitizer_platform_limits_openbsd.h"
65
66namespace __sanitizer {
67unsigned struct_utsname_sz = sizeof(struct utsname);
68unsigned struct_stat_sz = sizeof(struct stat);
69unsigned struct_rusage_sz = sizeof(struct rusage);
70unsigned struct_tm_sz = sizeof(struct tm);
71unsigned struct_passwd_sz = sizeof(struct passwd);
72unsigned struct_group_sz = sizeof(struct group);
73unsigned siginfo_t_sz = sizeof(siginfo_t);
74unsigned struct_sigaction_sz = sizeof(struct sigaction);
75unsigned struct_stack_t_sz = sizeof(stack_t);
76unsigned struct_itimerval_sz = sizeof(struct itimerval);
77unsigned pthread_t_sz = sizeof(pthread_t);
78unsigned pthread_mutex_t_sz = sizeof(pthread_mutex_t);
79unsigned pthread_cond_t_sz = sizeof(pthread_cond_t);
80unsigned pid_t_sz = sizeof(pid_t);
81unsigned timeval_sz = sizeof(timeval);
82unsigned uid_t_sz = sizeof(uid_t);
83unsigned gid_t_sz = sizeof(gid_t);
84unsigned mbstate_t_sz = sizeof(mbstate_t);
85unsigned sigset_t_sz = sizeof(sigset_t);
86unsigned struct_timezone_sz = sizeof(struct timezone);
87unsigned struct_tms_sz = sizeof(struct tms);
88unsigned struct_sched_param_sz = sizeof(struct sched_param);
89unsigned struct_sockaddr_sz = sizeof(struct sockaddr);
90unsigned struct_rlimit_sz = sizeof(struct rlimit);
91unsigned struct_timespec_sz = sizeof(struct timespec);
92unsigned struct_utimbuf_sz = sizeof(struct utimbuf);
93unsigned struct_itimerspec_sz = sizeof(struct itimerspec);
94unsigned struct_msqid_ds_sz = sizeof(struct msqid_ds);
95unsigned struct_statvfs_sz = sizeof(struct statvfs);
96
97const uptr sig_ign = (uptr)SIG_IGN;
98const uptr sig_dfl = (uptr)SIG_DFL;
99const uptr sig_err = (uptr)SIG_ERR;
100const uptr sa_siginfo = (uptr)SA_SIGINFO;
101
102int shmctl_ipc_stat = (int)IPC_STAT;
103
104unsigned struct_utmp_sz = sizeof(struct utmp);
105
106int map_fixed = MAP_FIXED;
107
108int af_inet = (int)AF_INET;
109int af_inet6 = (int)AF_INET6;
110
111uptr __sanitizer_in_addr_sz(int af) {
112 if (af == AF_INET)
113 return sizeof(struct in_addr);
114 else if (af == AF_INET6)
115 return sizeof(struct in6_addr);
116 else
117 return 0;
118}
119
120unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr);
121
122int glob_nomatch = GLOB_NOMATCH;
123int glob_altdirfunc = GLOB_ALTDIRFUNC;
124
125unsigned path_max = PATH_MAX;
126
127const int si_SEGV_MAPERR = SEGV_MAPERR;
128const int si_SEGV_ACCERR = SEGV_ACCERR;
129} // namespace __sanitizer
130
131using namespace __sanitizer;
132
133COMPILER_CHECK(sizeof(__sanitizer_pthread_attr_t) >= sizeof(pthread_attr_t));
134
135COMPILER_CHECK(sizeof(socklen_t) == sizeof(unsigned));
136CHECK_TYPE_SIZE(pthread_key_t);
137
138CHECK_TYPE_SIZE(dl_phdr_info);
139CHECK_SIZE_AND_OFFSET(dl_phdr_info, dlpi_addr);
140CHECK_SIZE_AND_OFFSET(dl_phdr_info, dlpi_name);
141CHECK_SIZE_AND_OFFSET(dl_phdr_info, dlpi_phdr);
142CHECK_SIZE_AND_OFFSET(dl_phdr_info, dlpi_phnum);
143
144CHECK_TYPE_SIZE(glob_t);
145CHECK_SIZE_AND_OFFSET(glob_t, gl_pathc);
146CHECK_SIZE_AND_OFFSET(glob_t, gl_pathv);
147CHECK_SIZE_AND_OFFSET(glob_t, gl_offs);
148CHECK_SIZE_AND_OFFSET(glob_t, gl_flags);
149CHECK_SIZE_AND_OFFSET(glob_t, gl_closedir);
150CHECK_SIZE_AND_OFFSET(glob_t, gl_readdir);
151CHECK_SIZE_AND_OFFSET(glob_t, gl_opendir);
152CHECK_SIZE_AND_OFFSET(glob_t, gl_lstat);
153CHECK_SIZE_AND_OFFSET(glob_t, gl_stat);
154
155CHECK_TYPE_SIZE(addrinfo);
156CHECK_SIZE_AND_OFFSET(addrinfo, ai_flags);
157CHECK_SIZE_AND_OFFSET(addrinfo, ai_family);
158CHECK_SIZE_AND_OFFSET(addrinfo, ai_socktype);
159CHECK_SIZE_AND_OFFSET(addrinfo, ai_protocol);
160CHECK_SIZE_AND_OFFSET(addrinfo, ai_addrlen);
161CHECK_SIZE_AND_OFFSET(addrinfo, ai_addr);
162CHECK_SIZE_AND_OFFSET(addrinfo, ai_canonname);
163CHECK_SIZE_AND_OFFSET(addrinfo, ai_next);
164
165CHECK_TYPE_SIZE(hostent);
166CHECK_SIZE_AND_OFFSET(hostent, h_name);
167CHECK_SIZE_AND_OFFSET(hostent, h_aliases);
168CHECK_SIZE_AND_OFFSET(hostent, h_addrtype);
169CHECK_SIZE_AND_OFFSET(hostent, h_length);
170CHECK_SIZE_AND_OFFSET(hostent, h_addr_list);
171
172CHECK_TYPE_SIZE(iovec);
173CHECK_SIZE_AND_OFFSET(iovec, iov_base);
174CHECK_SIZE_AND_OFFSET(iovec, iov_len);
175
176CHECK_TYPE_SIZE(msghdr);
177CHECK_SIZE_AND_OFFSET(msghdr, msg_name);
178CHECK_SIZE_AND_OFFSET(msghdr, msg_namelen);
179CHECK_SIZE_AND_OFFSET(msghdr, msg_iov);
180CHECK_SIZE_AND_OFFSET(msghdr, msg_iovlen);
181CHECK_SIZE_AND_OFFSET(msghdr, msg_control);
182CHECK_SIZE_AND_OFFSET(msghdr, msg_controllen);
183CHECK_SIZE_AND_OFFSET(msghdr, msg_flags);
184
185CHECK_TYPE_SIZE(cmsghdr);
186CHECK_SIZE_AND_OFFSET(cmsghdr, cmsg_len);
187CHECK_SIZE_AND_OFFSET(cmsghdr, cmsg_level);
188CHECK_SIZE_AND_OFFSET(cmsghdr, cmsg_type);
189
190COMPILER_CHECK(sizeof(__sanitizer_dirent) <= sizeof(dirent));
191CHECK_SIZE_AND_OFFSET(dirent, d_fileno);
192CHECK_SIZE_AND_OFFSET(dirent, d_off);
193CHECK_SIZE_AND_OFFSET(dirent, d_reclen);
194
195CHECK_TYPE_SIZE(ifconf);
196CHECK_SIZE_AND_OFFSET(ifconf, ifc_len);
197CHECK_SIZE_AND_OFFSET(ifconf, ifc_ifcu);
198
199CHECK_TYPE_SIZE(pollfd);
200CHECK_SIZE_AND_OFFSET(pollfd, fd);
201CHECK_SIZE_AND_OFFSET(pollfd, events);
202CHECK_SIZE_AND_OFFSET(pollfd, revents);
203
204CHECK_TYPE_SIZE(nfds_t);
205
206CHECK_TYPE_SIZE(sigset_t);
207
208COMPILER_CHECK(sizeof(__sanitizer_sigaction) == sizeof(struct sigaction));
209// Can't write checks for sa_handler and sa_sigaction due to them being
210// preprocessor macros.
211CHECK_STRUCT_SIZE_AND_OFFSET(sigaction, sa_mask);
212
213CHECK_TYPE_SIZE(tm);
214CHECK_SIZE_AND_OFFSET(tm, tm_sec);
215CHECK_SIZE_AND_OFFSET(tm, tm_min);
216CHECK_SIZE_AND_OFFSET(tm, tm_hour);
217CHECK_SIZE_AND_OFFSET(tm, tm_mday);
218CHECK_SIZE_AND_OFFSET(tm, tm_mon);
219CHECK_SIZE_AND_OFFSET(tm, tm_year);
220CHECK_SIZE_AND_OFFSET(tm, tm_wday);
221CHECK_SIZE_AND_OFFSET(tm, tm_yday);
222CHECK_SIZE_AND_OFFSET(tm, tm_isdst);
223CHECK_SIZE_AND_OFFSET(tm, tm_gmtoff);
224CHECK_SIZE_AND_OFFSET(tm, tm_zone);
225
226CHECK_TYPE_SIZE(ipc_perm);
227CHECK_SIZE_AND_OFFSET(ipc_perm, cuid);
228CHECK_SIZE_AND_OFFSET(ipc_perm, cgid);
229CHECK_SIZE_AND_OFFSET(ipc_perm, uid);
230CHECK_SIZE_AND_OFFSET(ipc_perm, gid);
231CHECK_SIZE_AND_OFFSET(ipc_perm, mode);
232CHECK_SIZE_AND_OFFSET(ipc_perm, seq);
233CHECK_SIZE_AND_OFFSET(ipc_perm, key);
234
235CHECK_TYPE_SIZE(shmid_ds);
236CHECK_SIZE_AND_OFFSET(shmid_ds, shm_perm);
237CHECK_SIZE_AND_OFFSET(shmid_ds, shm_segsz);
238CHECK_SIZE_AND_OFFSET(shmid_ds, shm_atime);
239CHECK_SIZE_AND_OFFSET(shmid_ds, __shm_atimensec);
240CHECK_SIZE_AND_OFFSET(shmid_ds, shm_dtime);
241CHECK_SIZE_AND_OFFSET(shmid_ds, __shm_dtimensec);
242CHECK_SIZE_AND_OFFSET(shmid_ds, shm_ctime);
243CHECK_SIZE_AND_OFFSET(shmid_ds, __shm_ctimensec);
244CHECK_SIZE_AND_OFFSET(shmid_ds, shm_cpid);
245CHECK_SIZE_AND_OFFSET(shmid_ds, shm_lpid);
246CHECK_SIZE_AND_OFFSET(shmid_ds, shm_nattch);
247
248CHECK_TYPE_SIZE(clock_t);
249
250CHECK_TYPE_SIZE(ifaddrs);
251CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_next);
252CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_name);
253CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_addr);
254CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_netmask);
255// Compare against the union, because we can't reach into the union in a
256// compliant way.
257#ifdef ifa_dstaddr
258#undef ifa_dstaddr
259#endif
260CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_dstaddr);
261CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_data);
262
263CHECK_TYPE_SIZE(passwd);
264CHECK_SIZE_AND_OFFSET(passwd, pw_name);
265CHECK_SIZE_AND_OFFSET(passwd, pw_passwd);
266CHECK_SIZE_AND_OFFSET(passwd, pw_uid);
267CHECK_SIZE_AND_OFFSET(passwd, pw_gid);
268CHECK_SIZE_AND_OFFSET(passwd, pw_dir);
269CHECK_SIZE_AND_OFFSET(passwd, pw_shell);
270
271CHECK_SIZE_AND_OFFSET(passwd, pw_gecos);
272
273CHECK_TYPE_SIZE(group);
274CHECK_SIZE_AND_OFFSET(group, gr_name);
275CHECK_SIZE_AND_OFFSET(group, gr_passwd);
276CHECK_SIZE_AND_OFFSET(group, gr_gid);
277CHECK_SIZE_AND_OFFSET(group, gr_mem);
278
279#endif // SANITIZER_OPENBSD
lib/tsan/sanitizer_common/sanitizer_platform_limits_openbsd.h-382
......@@ -1,382 +0,0 @@
1//===-- sanitizer_platform_limits_openbsd.h -------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file is a part of Sanitizer common code.
10//
11// Sizes and layouts of platform-specific OpenBSD data structures.
12//===----------------------------------------------------------------------===//
13
14#ifndef SANITIZER_PLATFORM_LIMITS_OPENBSD_H
15#define SANITIZER_PLATFORM_LIMITS_OPENBSD_H
16
17#if SANITIZER_OPENBSD
18
19#include "sanitizer_internal_defs.h"
20#include "sanitizer_platform.h"
21
22#define _GET_LINK_MAP_BY_DLOPEN_HANDLE(handle, shift) \
23 ((link_map *)((handle) == nullptr ? nullptr : ((char *)(handle) + (shift))))
24
25#if defined(__x86_64__)
26#define GET_LINK_MAP_BY_DLOPEN_HANDLE(handle) \
27 _GET_LINK_MAP_BY_DLOPEN_HANDLE(handle, 312)
28#elif defined(__i386__)
29#define GET_LINK_MAP_BY_DLOPEN_HANDLE(handle) \
30 _GET_LINK_MAP_BY_DLOPEN_HANDLE(handle, 164)
31#endif
32
33#define RLIMIT_AS RLIMIT_DATA
34
35namespace __sanitizer {
36extern unsigned struct_utsname_sz;
37extern unsigned struct_stat_sz;
38extern unsigned struct_rusage_sz;
39extern unsigned siginfo_t_sz;
40extern unsigned struct_itimerval_sz;
41extern unsigned pthread_t_sz;
42extern unsigned pthread_mutex_t_sz;
43extern unsigned pthread_cond_t_sz;
44extern unsigned pid_t_sz;
45extern unsigned timeval_sz;
46extern unsigned uid_t_sz;
47extern unsigned gid_t_sz;
48extern unsigned mbstate_t_sz;
49extern unsigned struct_timezone_sz;
50extern unsigned struct_tms_sz;
51extern unsigned struct_itimerspec_sz;
52extern unsigned struct_sigevent_sz;
53extern unsigned struct_stack_t_sz;
54extern unsigned struct_statfs_sz;
55extern unsigned struct_sockaddr_sz;
56
57extern unsigned struct_rlimit_sz;
58extern unsigned struct_utimbuf_sz;
59extern unsigned struct_timespec_sz;
60
61struct __sanitizer_iocb {
62 u64 aio_offset;
63 uptr aio_buf;
64 long aio_nbytes;
65 u32 aio_fildes;
66 u32 aio_lio_opcode;
67 long aio_reqprio;
68#if SANITIZER_WORDSIZE == 64
69 u8 aio_sigevent[32];
70#else
71 u8 aio_sigevent[20];
72#endif
73 u32 _state;
74 u32 _errno;
75 long _retval;
76};
77
78struct __sanitizer___sysctl_args {
79 int *name;
80 int nlen;
81 void *oldval;
82 uptr *oldlenp;
83 void *newval;
84 uptr newlen;
85};
86
87struct __sanitizer_sem_t {
88 uptr data[5];
89};
90
91struct __sanitizer_ipc_perm {
92 u32 cuid;
93 u32 cgid;
94 u32 uid;
95 u32 gid;
96 u32 mode;
97 unsigned short seq;
98 long key;
99};
100
101struct __sanitizer_shmid_ds {
102 __sanitizer_ipc_perm shm_perm;
103 int shm_segsz;
104 u32 shm_lpid;
105 u32 shm_cpid;
106 short shm_nattch;
107 u64 shm_atime;
108 long __shm_atimensec;
109 u64 shm_dtime;
110 long __shm_dtimensec;
111 u64 shm_ctime;
112 long __shm_ctimensec;
113 void *_shm_internal;
114};
115
116extern unsigned struct_msqid_ds_sz;
117extern unsigned struct_mq_attr_sz;
118extern unsigned struct_timex_sz;
119extern unsigned struct_statvfs_sz;
120
121struct __sanitizer_iovec {
122 void *iov_base;
123 uptr iov_len;
124};
125
126struct __sanitizer_ifaddrs {
127 struct __sanitizer_ifaddrs *ifa_next;
128 char *ifa_name;
129 unsigned int ifa_flags;
130 struct __sanitizer_sockaddr *ifa_addr; // (struct sockaddr *)
131 struct __sanitizer_sockaddr *ifa_netmask; // (struct sockaddr *)
132 struct __sanitizer_sockaddr *ifa_dstaddr; // (struct sockaddr *)
133 void *ifa_data;
134};
135
136typedef unsigned __sanitizer_pthread_key_t;
137
138typedef long long __sanitizer_time_t;
139typedef int __sanitizer_suseconds_t;
140
141struct __sanitizer_timeval {
142 __sanitizer_time_t tv_sec;
143 __sanitizer_suseconds_t tv_usec;
144};
145
146struct __sanitizer_itimerval {
147 struct __sanitizer_timeval it_interval;
148 struct __sanitizer_timeval it_value;
149};
150
151struct __sanitizer_passwd {
152 char *pw_name;
153 char *pw_passwd;
154 int pw_uid;
155 int pw_gid;
156 __sanitizer_time_t pw_change;
157 char *pw_class;
158 char *pw_gecos;
159 char *pw_dir;
160 char *pw_shell;
161 __sanitizer_time_t pw_expire;
162};
163
164struct __sanitizer_group {
165 char *gr_name;
166 char *gr_passwd;
167 int gr_gid;
168 char **gr_mem;
169};
170
171struct __sanitizer_ether_addr {
172 u8 octet[6];
173};
174
175struct __sanitizer_tm {
176 int tm_sec;
177 int tm_min;
178 int tm_hour;
179 int tm_mday;
180 int tm_mon;
181 int tm_year;
182 int tm_wday;
183 int tm_yday;
184 int tm_isdst;
185 long int tm_gmtoff;
186 const char *tm_zone;
187};
188
189struct __sanitizer_msghdr {
190 void *msg_name;
191 unsigned msg_namelen;
192 struct __sanitizer_iovec *msg_iov;
193 unsigned msg_iovlen;
194 void *msg_control;
195 unsigned msg_controllen;
196 int msg_flags;
197};
198struct __sanitizer_cmsghdr {
199 unsigned cmsg_len;
200 int cmsg_level;
201 int cmsg_type;
202};
203
204struct __sanitizer_dirent {
205 u64 d_fileno;
206 u64 d_off;
207 u16 d_reclen;
208};
209
210typedef u64 __sanitizer_clock_t;
211typedef u32 __sanitizer_clockid_t;
212
213typedef u32 __sanitizer___kernel_uid_t;
214typedef u32 __sanitizer___kernel_gid_t;
215typedef u64 __sanitizer___kernel_off_t;
216typedef struct {
217 u32 fds_bits[8];
218} __sanitizer___kernel_fd_set;
219
220typedef struct {
221 unsigned int pta_magic;
222 int pta_flags;
223 void *pta_private;
224} __sanitizer_pthread_attr_t;
225
226typedef unsigned int __sanitizer_sigset_t;
227
228struct __sanitizer_siginfo {
229 // The size is determined by looking at sizeof of real siginfo_t on linux.
230 u64 opaque[128 / sizeof(u64)];
231};
232
233using __sanitizer_sighandler_ptr = void (*)(int sig);
234using __sanitizer_sigactionhandler_ptr = void (*)(int sig,
235 __sanitizer_siginfo *siginfo,
236 void *uctx);
237
238struct __sanitizer_sigaction {
239 union {
240 __sanitizer_sighandler_ptr handler;
241 __sanitizer_sigactionhandler_ptr sigaction;
242 };
243 __sanitizer_sigset_t sa_mask;
244 int sa_flags;
245};
246
247typedef __sanitizer_sigset_t __sanitizer_kernel_sigset_t;
248
249struct __sanitizer_kernel_sigaction_t {
250 union {
251 void (*handler)(int signo);
252 void (*sigaction)(int signo, void *info, void *ctx);
253 };
254 unsigned long sa_flags;
255 void (*sa_restorer)(void);
256 __sanitizer_kernel_sigset_t sa_mask;
257};
258
259extern const uptr sig_ign;
260extern const uptr sig_dfl;
261extern const uptr sig_err;
262extern const uptr sa_siginfo;
263
264extern int af_inet;
265extern int af_inet6;
266uptr __sanitizer_in_addr_sz(int af);
267
268struct __sanitizer_dl_phdr_info {
269#if SANITIZER_WORDSIZE == 64
270 u64 dlpi_addr;
271#else
272 u32 dlpi_addr;
273#endif
274 const char *dlpi_name;
275 const void *dlpi_phdr;
276#if SANITIZER_WORDSIZE == 64
277 u32 dlpi_phnum;
278#else
279 u16 dlpi_phnum;
280#endif
281};
282
283extern unsigned struct_ElfW_Phdr_sz;
284
285struct __sanitizer_addrinfo {
286 int ai_flags;
287 int ai_family;
288 int ai_socktype;
289 int ai_protocol;
290 unsigned ai_addrlen;
291 struct __sanitizer_sockaddr *ai_addr;
292 char *ai_canonname;
293 struct __sanitizer_addrinfo *ai_next;
294};
295
296struct __sanitizer_hostent {
297 char *h_name;
298 char **h_aliases;
299 int h_addrtype;
300 int h_length;
301 char **h_addr_list;
302};
303
304struct __sanitizer_pollfd {
305 int fd;
306 short events;
307 short revents;
308};
309
310typedef unsigned __sanitizer_nfds_t;
311
312struct __sanitizer_glob_t {
313 int gl_pathc;
314 int gl_matchc;
315 int gl_offs;
316 int gl_flags;
317 char **gl_pathv;
318 void **gl_statv;
319 int (*gl_errfunc)(const char *, int);
320 void (*gl_closedir)(void *dirp);
321 struct dirent *(*gl_readdir)(void *dirp);
322 void *(*gl_opendir)(const char *);
323 int (*gl_lstat)(const char *, void * /* struct stat* */);
324 int (*gl_stat)(const char *, void * /* struct stat* */);
325};
326
327extern int glob_nomatch;
328extern int glob_altdirfunc;
329
330extern unsigned path_max;
331
332typedef char __sanitizer_FILE;
333#define SANITIZER_HAS_STRUCT_FILE 0
334
335extern int shmctl_ipc_stat;
336
337// This simplifies generic code
338#define struct_shminfo_sz -1
339#define struct_shm_info_sz -1
340#define shmctl_shm_stat -1
341#define shmctl_ipc_info -1
342#define shmctl_shm_info -1
343
344extern unsigned struct_utmp_sz;
345extern unsigned struct_utmpx_sz;
346
347extern int map_fixed;
348
349// ioctl arguments
350struct __sanitizer_ifconf {
351 int ifc_len;
352 union {
353 void *ifcu_req;
354 } ifc_ifcu;
355};
356
357extern const int si_SEGV_MAPERR;
358extern const int si_SEGV_ACCERR;
359} // namespace __sanitizer
360
361#define CHECK_TYPE_SIZE(TYPE) \
362 COMPILER_CHECK(sizeof(__sanitizer_##TYPE) == sizeof(TYPE))
363
364#define CHECK_SIZE_AND_OFFSET(CLASS, MEMBER) \
365 COMPILER_CHECK(sizeof(((__sanitizer_##CLASS *)NULL)->MEMBER) == \
366 sizeof(((CLASS *)NULL)->MEMBER)); \
367 COMPILER_CHECK(offsetof(__sanitizer_##CLASS, MEMBER) == \
368 offsetof(CLASS, MEMBER))
369
370// For sigaction, which is a function and struct at the same time,
371// and thus requires explicit "struct" in sizeof() expression.
372#define CHECK_STRUCT_SIZE_AND_OFFSET(CLASS, MEMBER) \
373 COMPILER_CHECK(sizeof(((struct __sanitizer_##CLASS *)NULL)->MEMBER) == \
374 sizeof(((struct CLASS *)NULL)->MEMBER)); \
375 COMPILER_CHECK(offsetof(struct __sanitizer_##CLASS, MEMBER) == \
376 offsetof(struct CLASS, MEMBER))
377
378#define SIGACTION_SYMNAME __sigaction14
379
380#endif // SANITIZER_OPENBSD
381
382#endif
lib/tsan/sanitizer_common/sanitizer_platform_limits_posix.cpp+66-53
......@@ -11,18 +11,19 @@
1111// Sizes and layouts of platform-specific POSIX data structures.
1212//===----------------------------------------------------------------------===//
1313
14#include "sanitizer_platform.h"
15
16#if SANITIZER_LINUX || SANITIZER_MAC
14#if defined(__linux__) || defined(__APPLE__)
1715// Tests in this file assume that off_t-dependent data structures match the
1816// libc ABI. For example, struct dirent here is what readdir() function (as
1917// exported from libc) returns, and not the user-facing "dirent", which
2018// depends on _FILE_OFFSET_BITS setting.
2119// To get this "true" dirent definition, we undefine _FILE_OFFSET_BITS below.
22#ifdef _FILE_OFFSET_BITS
2320#undef _FILE_OFFSET_BITS
2421#endif
2522
23// Must go after undef _FILE_OFFSET_BITS.
24#include "sanitizer_platform.h"
25
26#if SANITIZER_LINUX || SANITIZER_MAC
2627// Must go after undef _FILE_OFFSET_BITS.
2728#include "sanitizer_glibc_version.h"
2829
......@@ -37,6 +38,7 @@
3738#include <pwd.h>
3839#include <signal.h>
3940#include <stddef.h>
41#include <stdio.h>
4042#include <sys/mman.h>
4143#include <sys/resource.h>
4244#include <sys/socket.h>
......@@ -58,7 +60,6 @@
5860#endif
5961
6062#if !SANITIZER_ANDROID
61#include <fstab.h>
6263#include <sys/mount.h>
6364#include <sys/timeb.h>
6465#include <utmpx.h>
......@@ -90,7 +91,8 @@
9091#if SANITIZER_LINUX
9192# include <utime.h>
9293# include <sys/ptrace.h>
93# if defined(__mips64) || defined(__aarch64__) || defined(__arm__)
94#if defined(__mips64) || defined(__aarch64__) || defined(__arm__) || \
95 SANITIZER_RISCV64
9496# include <asm/ptrace.h>
9597# ifdef __arm__
9698typedef struct user_fpregs elf_fpregset_t;
......@@ -109,20 +111,31 @@ typedef struct user_fpregs elf_fpregset_t;
109111#include <wordexp.h>
110112#endif
111113
112#if SANITIZER_LINUX && !SANITIZER_ANDROID
113#include <glob.h>
114#include <obstack.h>
115#include <mqueue.h>
114#if SANITIZER_LINUX
115#if SANITIZER_GLIBC
116#include <fstab.h>
116117#include <net/if_ppp.h>
117118#include <netax25/ax25.h>
118119#include <netipx/ipx.h>
119120#include <netrom/netrom.h>
121#include <obstack.h>
120122#if HAVE_RPC_XDR_H
121123# include <rpc/xdr.h>
122124#endif
123125#include <scsi/scsi.h>
124#include <sys/mtio.h>
126#else
127#include <linux/if_ppp.h>
128#include <linux/kd.h>
129#include <linux/ppp_defs.h>
130#endif // SANITIZER_GLIBC
131
132#if SANITIZER_ANDROID
133#include <linux/mtio.h>
134#else
135#include <glob.h>
136#include <mqueue.h>
125137#include <sys/kd.h>
138#include <sys/mtio.h>
126139#include <sys/shm.h>
127140#include <sys/statvfs.h>
128141#include <sys/timex.h>
......@@ -130,7 +143,6 @@ typedef struct user_fpregs elf_fpregset_t;
130143# include <sys/procfs.h>
131144#endif
132145#include <sys/user.h>
133#include <linux/cyclades.h>
134146#include <linux/if_eql.h>
135147#include <linux/if_plip.h>
136148#include <linux/lp.h>
......@@ -141,20 +153,14 @@ typedef struct user_fpregs elf_fpregset_t;
141153#include <sys/msg.h>
142154#include <sys/ipc.h>
143155#include <crypt.h>
144#endif // SANITIZER_LINUX && !SANITIZER_ANDROID
156#endif // SANITIZER_ANDROID
145157
146#if SANITIZER_ANDROID
147#include <linux/kd.h>
148#include <linux/mtio.h>
149#include <linux/ppp_defs.h>
150#include <linux/if_ppp.h>
151#endif
152
153#if SANITIZER_LINUX
154158#include <link.h>
155159#include <sys/vfs.h>
156160#include <sys/epoll.h>
157161#include <linux/capability.h>
162#else
163#include <fstab.h>
158164#endif // SANITIZER_LINUX
159165
160166#if SANITIZER_MAC
......@@ -201,8 +207,11 @@ namespace __sanitizer {
201207 unsigned struct_statfs64_sz = sizeof(struct statfs64);
202208#endif // (SANITIZER_MAC && !TARGET_CPU_ARM64) && !SANITIZER_IOS
203209
204#if !SANITIZER_ANDROID
210#if SANITIZER_GLIBC || SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_MAC
205211 unsigned struct_fstab_sz = sizeof(struct fstab);
212#endif // SANITIZER_GLIBC || SANITIZER_FREEBSD || SANITIZER_NETBSD ||
213 // SANITIZER_MAC
214#if !SANITIZER_ANDROID
206215 unsigned struct_statfs_sz = sizeof(struct statfs);
207216 unsigned struct_sockaddr_sz = sizeof(struct sockaddr);
208217 unsigned ucontext_t_sz = sizeof(ucontext_t);
......@@ -229,9 +238,9 @@ namespace __sanitizer {
229238#if SANITIZER_LINUX && !SANITIZER_ANDROID
230239 // Use pre-computed size of struct ustat to avoid <sys/ustat.h> which
231240 // has been removed from glibc 2.28.
232#if defined(__aarch64__) || defined(__s390x__) || defined (__mips64) \
233 || defined(__powerpc64__) || defined(__arch64__) || defined(__sparcv9) \
234 || defined(__x86_64__) || (defined(__riscv) && __riscv_xlen == 64)
241#if defined(__aarch64__) || defined(__s390x__) || defined(__mips64) || \
242 defined(__powerpc64__) || defined(__arch64__) || defined(__sparcv9) || \
243 defined(__x86_64__) || SANITIZER_RISCV64
235244#define SIZEOF_STRUCT_USTAT 32
236245#elif defined(__arm__) || defined(__i386__) || defined(__mips__) \
237246 || defined(__powerpc__) || defined(__s390__) || defined(__sparc__)
......@@ -298,18 +307,21 @@ unsigned struct_ElfW_Phdr_sz = sizeof(ElfW(Phdr));
298307unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr);
299308#endif
300309
301#if SANITIZER_LINUX && !SANITIZER_ANDROID
310#if SANITIZER_GLIBC
302311 int glob_nomatch = GLOB_NOMATCH;
303312 int glob_altdirfunc = GLOB_ALTDIRFUNC;
304313#endif
305314
306#if SANITIZER_LINUX && !SANITIZER_ANDROID && \
307 (defined(__i386) || defined(__x86_64) || defined(__mips64) || \
308 defined(__powerpc64__) || defined(__aarch64__) || defined(__arm__) || \
309 defined(__s390__))
315#if SANITIZER_LINUX && !SANITIZER_ANDROID && \
316 (defined(__i386) || defined(__x86_64) || defined(__mips64) || \
317 defined(__powerpc64__) || defined(__aarch64__) || defined(__arm__) || \
318 defined(__s390__) || SANITIZER_RISCV64)
310319#if defined(__mips64) || defined(__powerpc64__) || defined(__arm__)
311320 unsigned struct_user_regs_struct_sz = sizeof(struct pt_regs);
312321 unsigned struct_user_fpregs_struct_sz = sizeof(elf_fpregset_t);
322#elif SANITIZER_RISCV64
323 unsigned struct_user_regs_struct_sz = sizeof(struct user_regs_struct);
324 unsigned struct_user_fpregs_struct_sz = sizeof(struct __riscv_q_ext_state);
313325#elif defined(__aarch64__)
314326 unsigned struct_user_regs_struct_sz = sizeof(struct user_pt_regs);
315327 unsigned struct_user_fpregs_struct_sz = sizeof(struct user_fpsimd_state);
......@@ -321,7 +333,8 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr);
321333 unsigned struct_user_fpregs_struct_sz = sizeof(struct user_fpregs_struct);
322334#endif // __mips64 || __powerpc64__ || __aarch64__
323335#if defined(__x86_64) || defined(__mips64) || defined(__powerpc64__) || \
324 defined(__aarch64__) || defined(__arm__) || defined(__s390__)
336 defined(__aarch64__) || defined(__arm__) || defined(__s390__) || \
337 SANITIZER_RISCV64
325338 unsigned struct_user_fpxregs_struct_sz = 0;
326339#else
327340 unsigned struct_user_fpxregs_struct_sz = sizeof(struct user_fpxregs_struct);
......@@ -417,7 +430,9 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr);
417430 unsigned struct_input_id_sz = sizeof(struct input_id);
418431 unsigned struct_mtpos_sz = sizeof(struct mtpos);
419432 unsigned struct_rtentry_sz = sizeof(struct rtentry);
433#if SANITIZER_GLIBC || SANITIZER_ANDROID
420434 unsigned struct_termio_sz = sizeof(struct termio);
435#endif
421436 unsigned struct_vt_consize_sz = sizeof(struct vt_consize);
422437 unsigned struct_vt_sizes_sz = sizeof(struct vt_sizes);
423438 unsigned struct_vt_stat_sz = sizeof(struct vt_stat);
......@@ -442,9 +457,8 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr);
442457 unsigned struct_vt_mode_sz = sizeof(struct vt_mode);
443458#endif // SANITIZER_LINUX
444459
445#if SANITIZER_LINUX && !SANITIZER_ANDROID
460#if SANITIZER_GLIBC
446461 unsigned struct_ax25_parms_struct_sz = sizeof(struct ax25_parms_struct);
447 unsigned struct_cyclades_monitor_sz = sizeof(struct cyclades_monitor);
448462#if EV_VERSION > (0x010000)
449463 unsigned struct_input_keymap_entry_sz = sizeof(struct input_keymap_entry);
450464#else
......@@ -465,12 +479,10 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr);
465479 unsigned struct_sockaddr_ax25_sz = sizeof(struct sockaddr_ax25);
466480 unsigned struct_unimapdesc_sz = sizeof(struct unimapdesc);
467481 unsigned struct_unimapinit_sz = sizeof(struct unimapinit);
468#endif // SANITIZER_LINUX && !SANITIZER_ANDROID
469482
470#if SANITIZER_LINUX && !SANITIZER_ANDROID
471483 unsigned struct_audio_buf_info_sz = sizeof(struct audio_buf_info);
472484 unsigned struct_ppp_stats_sz = sizeof(struct ppp_stats);
473#endif // (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID
485#endif // SANITIZER_GLIBC
474486
475487#if !SANITIZER_ANDROID && !SANITIZER_MAC
476488 unsigned struct_sioc_sg_req_sz = sizeof(struct sioc_sg_req);
......@@ -810,15 +822,6 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr);
810822#endif // SANITIZER_LINUX
811823
812824#if SANITIZER_LINUX && !SANITIZER_ANDROID
813 unsigned IOCTL_CYGETDEFTHRESH = CYGETDEFTHRESH;
814 unsigned IOCTL_CYGETDEFTIMEOUT = CYGETDEFTIMEOUT;
815 unsigned IOCTL_CYGETMON = CYGETMON;
816 unsigned IOCTL_CYGETTHRESH = CYGETTHRESH;
817 unsigned IOCTL_CYGETTIMEOUT = CYGETTIMEOUT;
818 unsigned IOCTL_CYSETDEFTHRESH = CYSETDEFTHRESH;
819 unsigned IOCTL_CYSETDEFTIMEOUT = CYSETDEFTIMEOUT;
820 unsigned IOCTL_CYSETTHRESH = CYSETTHRESH;
821 unsigned IOCTL_CYSETTIMEOUT = CYSETTIMEOUT;
822825 unsigned IOCTL_EQL_EMANCIPATE = EQL_EMANCIPATE;
823826 unsigned IOCTL_EQL_ENSLAVE = EQL_ENSLAVE;
824827 unsigned IOCTL_EQL_GETMASTRCFG = EQL_GETMASTRCFG;
......@@ -876,6 +879,7 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr);
876879 unsigned IOCTL_PIO_UNIMAP = PIO_UNIMAP;
877880 unsigned IOCTL_PIO_UNIMAPCLR = PIO_UNIMAPCLR;
878881 unsigned IOCTL_PIO_UNISCRNMAP = PIO_UNISCRNMAP;
882#if SANITIZER_GLIBC
879883 unsigned IOCTL_SCSI_IOCTL_GET_IDLUN = SCSI_IOCTL_GET_IDLUN;
880884 unsigned IOCTL_SCSI_IOCTL_PROBE_HOST = SCSI_IOCTL_PROBE_HOST;
881885 unsigned IOCTL_SCSI_IOCTL_TAGGED_DISABLE = SCSI_IOCTL_TAGGED_DISABLE;
......@@ -894,6 +898,7 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr);
894898 unsigned IOCTL_SIOCNRGETPARMS = SIOCNRGETPARMS;
895899 unsigned IOCTL_SIOCNRRTCTL = SIOCNRRTCTL;
896900 unsigned IOCTL_SIOCNRSETPARMS = SIOCNRSETPARMS;
901#endif
897902 unsigned IOCTL_TIOCGSERIAL = TIOCGSERIAL;
898903 unsigned IOCTL_TIOCSERGETMULTI = TIOCSERGETMULTI;
899904 unsigned IOCTL_TIOCSERSETMULTI = TIOCSERSETMULTI;
......@@ -964,7 +969,7 @@ CHECK_SIZE_AND_OFFSET(dl_phdr_info, dlpi_phdr);
964969CHECK_SIZE_AND_OFFSET(dl_phdr_info, dlpi_phnum);
965970#endif // SANITIZER_LINUX || SANITIZER_FREEBSD
966971
967#if (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID
972#if SANITIZER_GLIBC || SANITIZER_FREEBSD
968973CHECK_TYPE_SIZE(glob_t);
969974CHECK_SIZE_AND_OFFSET(glob_t, gl_pathc);
970975CHECK_SIZE_AND_OFFSET(glob_t, gl_pathv);
......@@ -975,7 +980,7 @@ CHECK_SIZE_AND_OFFSET(glob_t, gl_readdir);
975980CHECK_SIZE_AND_OFFSET(glob_t, gl_opendir);
976981CHECK_SIZE_AND_OFFSET(glob_t, gl_lstat);
977982CHECK_SIZE_AND_OFFSET(glob_t, gl_stat);
978#endif
983#endif // SANITIZER_GLIBC || SANITIZER_FREEBSD
979984
980985CHECK_TYPE_SIZE(addrinfo);
981986CHECK_SIZE_AND_OFFSET(addrinfo, ai_flags);
......@@ -998,17 +1003,27 @@ CHECK_TYPE_SIZE(iovec);
9981003CHECK_SIZE_AND_OFFSET(iovec, iov_base);
9991004CHECK_SIZE_AND_OFFSET(iovec, iov_len);
10001005
1006// In POSIX, int msg_iovlen; socklen_t msg_controllen; socklen_t cmsg_len; but
1007// many implementations don't conform to the standard. Since we pick the
1008// non-conforming glibc definition, exclude the checks for musl (incompatible
1009// sizes but compatible offsets).
10011010CHECK_TYPE_SIZE(msghdr);
10021011CHECK_SIZE_AND_OFFSET(msghdr, msg_name);
10031012CHECK_SIZE_AND_OFFSET(msghdr, msg_namelen);
10041013CHECK_SIZE_AND_OFFSET(msghdr, msg_iov);
1014#if SANITIZER_GLIBC || SANITIZER_ANDROID
10051015CHECK_SIZE_AND_OFFSET(msghdr, msg_iovlen);
1016#endif
10061017CHECK_SIZE_AND_OFFSET(msghdr, msg_control);
1018#if SANITIZER_GLIBC || SANITIZER_ANDROID
10071019CHECK_SIZE_AND_OFFSET(msghdr, msg_controllen);
1020#endif
10081021CHECK_SIZE_AND_OFFSET(msghdr, msg_flags);
10091022
10101023CHECK_TYPE_SIZE(cmsghdr);
1024#if SANITIZER_GLIBC || SANITIZER_ANDROID
10111025CHECK_SIZE_AND_OFFSET(cmsghdr, cmsg_len);
1026#endif
10121027CHECK_SIZE_AND_OFFSET(cmsghdr, cmsg_level);
10131028CHECK_SIZE_AND_OFFSET(cmsghdr, cmsg_type);
10141029
......@@ -1116,7 +1131,7 @@ CHECK_SIZE_AND_OFFSET(mntent, mnt_passno);
11161131
11171132CHECK_TYPE_SIZE(ether_addr);
11181133
1119#if (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID
1134#if SANITIZER_GLIBC || SANITIZER_FREEBSD
11201135CHECK_TYPE_SIZE(ipc_perm);
11211136# if SANITIZER_FREEBSD
11221137CHECK_SIZE_AND_OFFSET(ipc_perm, key);
......@@ -1178,7 +1193,7 @@ CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_dstaddr);
11781193CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_data);
11791194#endif
11801195
1181#if SANITIZER_LINUX
1196#if SANITIZER_GLIBC || SANITIZER_ANDROID
11821197COMPILER_CHECK(sizeof(__sanitizer_struct_mallinfo) == sizeof(struct mallinfo));
11831198#endif
11841199
......@@ -1228,7 +1243,7 @@ COMPILER_CHECK(__sanitizer_XDR_DECODE == XDR_DECODE);
12281243COMPILER_CHECK(__sanitizer_XDR_FREE == XDR_FREE);
12291244#endif
12301245
1231#if SANITIZER_LINUX && !SANITIZER_ANDROID
1246#if SANITIZER_GLIBC
12321247COMPILER_CHECK(sizeof(__sanitizer_FILE) <= sizeof(FILE));
12331248CHECK_SIZE_AND_OFFSET(FILE, _flags);
12341249CHECK_SIZE_AND_OFFSET(FILE, _IO_read_ptr);
......@@ -1245,9 +1260,7 @@ CHECK_SIZE_AND_OFFSET(FILE, _IO_save_end);
12451260CHECK_SIZE_AND_OFFSET(FILE, _markers);
12461261CHECK_SIZE_AND_OFFSET(FILE, _chain);
12471262CHECK_SIZE_AND_OFFSET(FILE, _fileno);
1248#endif
12491263
1250#if SANITIZER_LINUX && !SANITIZER_ANDROID
12511264COMPILER_CHECK(sizeof(__sanitizer__obstack_chunk) <= sizeof(_obstack_chunk));
12521265CHECK_SIZE_AND_OFFSET(_obstack_chunk, limit);
12531266CHECK_SIZE_AND_OFFSET(_obstack_chunk, prev);
......@@ -1262,7 +1275,7 @@ CHECK_SIZE_AND_OFFSET(cookie_io_functions_t, read);
12621275CHECK_SIZE_AND_OFFSET(cookie_io_functions_t, write);
12631276CHECK_SIZE_AND_OFFSET(cookie_io_functions_t, seek);
12641277CHECK_SIZE_AND_OFFSET(cookie_io_functions_t, close);
1265#endif
1278#endif // SANITIZER_GLIBC
12661279
12671280#if SANITIZER_LINUX || SANITIZER_FREEBSD
12681281CHECK_TYPE_SIZE(sem_t);
lib/tsan/sanitizer_common/sanitizer_platform_limits_posix.h+10-18
......@@ -99,9 +99,9 @@ const unsigned struct_kernel_stat64_sz = 144;
9999const unsigned struct___old_kernel_stat_sz = 0;
100100const unsigned struct_kernel_stat_sz = 64;
101101const unsigned struct_kernel_stat64_sz = 104;
102#elif defined(__riscv) && __riscv_xlen == 64
102#elif SANITIZER_RISCV64
103103const unsigned struct_kernel_stat_sz = 128;
104const unsigned struct_kernel_stat64_sz = 104;
104const unsigned struct_kernel_stat64_sz = 0; // RISCV64 does not use stat64
105105#endif
106106struct __sanitizer_perf_event_attr {
107107 unsigned type;
......@@ -443,6 +443,8 @@ struct __sanitizer_cmsghdr {
443443 int cmsg_type;
444444};
445445#else
446// In POSIX, int msg_iovlen; socklen_t msg_controllen; socklen_t cmsg_len; but
447// many implementations don't conform to the standard.
446448struct __sanitizer_msghdr {
447449 void *msg_name;
448450 unsigned msg_namelen;
......@@ -648,14 +650,14 @@ struct __sanitizer_sigaction {
648650#endif // !SANITIZER_ANDROID
649651
650652#if defined(__mips__)
651struct __sanitizer_kernel_sigset_t {
652 uptr sig[2];
653};
653#define __SANITIZER_KERNEL_NSIG 128
654654#else
655#define __SANITIZER_KERNEL_NSIG 64
656#endif
657
655658struct __sanitizer_kernel_sigset_t {
656 u8 sig[8];
659 uptr sig[__SANITIZER_KERNEL_NSIG / (sizeof(uptr) * 8)];
657660};
658#endif
659661
660662// Linux system headers define the 'sa_handler' and 'sa_sigaction' macros.
661663#if SANITIZER_MIPS
......@@ -804,7 +806,7 @@ typedef void __sanitizer_FILE;
804806#if SANITIZER_LINUX && !SANITIZER_ANDROID && \
805807 (defined(__i386) || defined(__x86_64) || defined(__mips64) || \
806808 defined(__powerpc64__) || defined(__aarch64__) || defined(__arm__) || \
807 defined(__s390__))
809 defined(__s390__) || SANITIZER_RISCV64)
808810extern unsigned struct_user_regs_struct_sz;
809811extern unsigned struct_user_fpregs_struct_sz;
810812extern unsigned struct_user_fpxregs_struct_sz;
......@@ -981,7 +983,6 @@ extern unsigned struct_vt_mode_sz;
981983
982984#if SANITIZER_LINUX && !SANITIZER_ANDROID
983985extern unsigned struct_ax25_parms_struct_sz;
984extern unsigned struct_cyclades_monitor_sz;
985986extern unsigned struct_input_keymap_entry_sz;
986987extern unsigned struct_ipx_config_data_sz;
987988extern unsigned struct_kbdiacrs_sz;
......@@ -1326,15 +1327,6 @@ extern unsigned IOCTL_VT_WAITACTIVE;
13261327#endif // SANITIZER_LINUX
13271328
13281329#if SANITIZER_LINUX && !SANITIZER_ANDROID
1329extern unsigned IOCTL_CYGETDEFTHRESH;
1330extern unsigned IOCTL_CYGETDEFTIMEOUT;
1331extern unsigned IOCTL_CYGETMON;
1332extern unsigned IOCTL_CYGETTHRESH;
1333extern unsigned IOCTL_CYGETTIMEOUT;
1334extern unsigned IOCTL_CYSETDEFTHRESH;
1335extern unsigned IOCTL_CYSETDEFTIMEOUT;
1336extern unsigned IOCTL_CYSETTHRESH;
1337extern unsigned IOCTL_CYSETTIMEOUT;
13381330extern unsigned IOCTL_EQL_EMANCIPATE;
13391331extern unsigned IOCTL_EQL_ENSLAVE;
13401332extern unsigned IOCTL_EQL_GETMASTRCFG;
lib/tsan/sanitizer_common/sanitizer_platform_limits_solaris.cpp+2-1
......@@ -202,7 +202,8 @@ CHECK_SIZE_AND_OFFSET(dl_phdr_info, dlpi_name);
202202CHECK_SIZE_AND_OFFSET(dl_phdr_info, dlpi_phdr);
203203CHECK_SIZE_AND_OFFSET(dl_phdr_info, dlpi_phnum);
204204
205CHECK_TYPE_SIZE(glob_t);
205// There are additional fields we are not interested in.
206COMPILER_CHECK(sizeof(__sanitizer_glob_t) <= sizeof(glob_t));
206207CHECK_SIZE_AND_OFFSET(glob_t, gl_pathc);
207208CHECK_SIZE_AND_OFFSET(glob_t, gl_pathv);
208209CHECK_SIZE_AND_OFFSET(glob_t, gl_offs);
lib/tsan/sanitizer_common/sanitizer_posix.cpp+9-7
......@@ -239,6 +239,7 @@ bool MemoryRangeIsAvailable(uptr range_start, uptr range_end) {
239239 return true;
240240}
241241
242#if !SANITIZER_MAC
242243void DumpProcessMap() {
243244 MemoryMappingLayout proc_maps(/*cache_enabled*/true);
244245 const sptr kBufSize = 4095;
......@@ -252,6 +253,7 @@ void DumpProcessMap() {
252253 Report("End of process memory map.\n");
253254 UnmapOrDie(filename, kBufSize);
254255}
256#endif
255257
256258const char *GetPwd() {
257259 return GetEnv("PWD");
......@@ -273,8 +275,8 @@ void ReportFile::Write(const char *buffer, uptr length) {
273275
274276bool GetCodeRangeForFile(const char *module, uptr *start, uptr *end) {
275277 MemoryMappingLayout proc_maps(/*cache_enabled*/false);
276 InternalScopedString buff(kMaxPathLength);
277 MemoryMappedSegment segment(buff.data(), kMaxPathLength);
278 InternalMmapVector<char> buff(kMaxPathLength);
279 MemoryMappedSegment segment(buff.data(), buff.size());
278280 while (proc_maps.Next(&segment)) {
279281 if (segment.IsExecutable() &&
280282 internal_strcmp(module, segment.filename) == 0) {
......@@ -293,7 +295,7 @@ uptr SignalContext::GetAddress() const {
293295
294296bool SignalContext::IsMemoryAccess() const {
295297 auto si = static_cast<const siginfo_t *>(siginfo);
296 return si->si_signo == SIGSEGV;
298 return si->si_signo == SIGSEGV || si->si_signo == SIGBUS;
297299}
298300
299301int SignalContext::GetType() const {
......@@ -354,11 +356,11 @@ int GetNamedMappingFd(const char *name, uptr size, int *flags) {
354356 int fd = ReserveStandardFds(
355357 internal_open(shmname, O_RDWR | O_CREAT | O_TRUNC | o_cloexec, S_IRWXU));
356358 CHECK_GE(fd, 0);
357 if (!o_cloexec) {
358 int res = fcntl(fd, F_SETFD, FD_CLOEXEC);
359 CHECK_EQ(0, res);
360 }
361359 int res = internal_ftruncate(fd, size);
360#if !defined(O_CLOEXEC)
361 res = fcntl(fd, F_SETFD, FD_CLOEXEC);
362 CHECK_EQ(0, res);
363#endif
362364 CHECK_EQ(0, res);
363365 res = internal_unlink(shmname);
364366 CHECK_EQ(0, res);
lib/tsan/sanitizer_common/sanitizer_posix.h+5-1
......@@ -17,7 +17,6 @@
1717#include "sanitizer_internal_defs.h"
1818#include "sanitizer_platform_limits_freebsd.h"
1919#include "sanitizer_platform_limits_netbsd.h"
20#include "sanitizer_platform_limits_openbsd.h"
2120#include "sanitizer_platform_limits_posix.h"
2221#include "sanitizer_platform_limits_solaris.h"
2322
......@@ -41,7 +40,12 @@ uptr internal_write(fd_t fd, const void *buf, uptr count);
4140uptr internal_mmap(void *addr, uptr length, int prot, int flags,
4241 int fd, u64 offset);
4342uptr internal_munmap(void *addr, uptr length);
43#if SANITIZER_LINUX
44uptr internal_mremap(void *old_address, uptr old_size, uptr new_size, int flags,
45 void *new_address);
46#endif
4447int internal_mprotect(void *addr, uptr length, int prot);
48int internal_madvise(uptr addr, uptr length, int advice);
4549
4650// OS
4751uptr internal_filesize(fd_t fd); // -1 on error.
lib/tsan/sanitizer_common/sanitizer_posix_libcdep.cpp+16-24
......@@ -18,7 +18,6 @@
1818#include "sanitizer_common.h"
1919#include "sanitizer_flags.h"
2020#include "sanitizer_platform_limits_netbsd.h"
21#include "sanitizer_platform_limits_openbsd.h"
2221#include "sanitizer_platform_limits_posix.h"
2322#include "sanitizer_platform_limits_solaris.h"
2423#include "sanitizer_posix.h"
......@@ -61,27 +60,24 @@ void ReleaseMemoryPagesToOS(uptr beg, uptr end) {
6160 uptr beg_aligned = RoundUpTo(beg, page_size);
6261 uptr end_aligned = RoundDownTo(end, page_size);
6362 if (beg_aligned < end_aligned)
64 // In the default Solaris compilation environment, madvise() is declared
65 // to take a caddr_t arg; casting it to void * results in an invalid
66 // conversion error, so use char * instead.
67 madvise((char *)beg_aligned, end_aligned - beg_aligned,
68 SANITIZER_MADVISE_DONTNEED);
63 internal_madvise(beg_aligned, end_aligned - beg_aligned,
64 SANITIZER_MADVISE_DONTNEED);
6965}
7066
7167void SetShadowRegionHugePageMode(uptr addr, uptr size) {
7268#ifdef MADV_NOHUGEPAGE // May not be defined on old systems.
7369 if (common_flags()->no_huge_pages_for_shadow)
74 madvise((char *)addr, size, MADV_NOHUGEPAGE);
70 internal_madvise(addr, size, MADV_NOHUGEPAGE);
7571 else
76 madvise((char *)addr, size, MADV_HUGEPAGE);
72 internal_madvise(addr, size, MADV_HUGEPAGE);
7773#endif // MADV_NOHUGEPAGE
7874}
7975
8076bool DontDumpShadowMemory(uptr addr, uptr length) {
8177#if defined(MADV_DONTDUMP)
82 return madvise((char *)addr, length, MADV_DONTDUMP) == 0;
78 return internal_madvise(addr, length, MADV_DONTDUMP) == 0;
8379#elif defined(MADV_NOCORE)
84 return madvise((char *)addr, length, MADV_NOCORE) == 0;
80 return internal_madvise(addr, length, MADV_NOCORE) == 0;
8581#else
8682 return true;
8783#endif // MADV_DONTDUMP
......@@ -132,14 +128,6 @@ void SetAddressSpaceUnlimited() {
132128 CHECK(AddressSpaceIsUnlimited());
133129}
134130
135void SleepForSeconds(int seconds) {
136 sleep(seconds);
137}
138
139void SleepForMillis(int millis) {
140 usleep(millis * 1000);
141}
142
143131void Abort() {
144132#if !SANITIZER_GO
145133 // If we are handling SIGABRT, unhandle it first.
......@@ -147,7 +135,7 @@ void Abort() {
147135 if (GetHandleSignalMode(SIGABRT) != kHandleSignalNo) {
148136 struct sigaction sigact;
149137 internal_memset(&sigact, 0, sizeof(sigact));
150 sigact.sa_sigaction = (sa_sigaction_t)SIG_DFL;
138 sigact.sa_handler = SIG_DFL;
151139 internal_sigaction(SIGABRT, &sigact, nullptr);
152140 }
153141#endif
......@@ -169,7 +157,12 @@ bool SupportsColoredOutput(fd_t fd) {
169157
170158#if !SANITIZER_GO
171159// TODO(glider): different tools may require different altstack size.
172static const uptr kAltStackSize = SIGSTKSZ * 4; // SIGSTKSZ is not enough.
160static uptr GetAltStackSize() {
161 // Note: since GLIBC_2.31, SIGSTKSZ may be a function call, so this may be
162 // more costly that you think. However GetAltStackSize is only call 2-3 times
163 // per thread so don't cache the evaluation.
164 return SIGSTKSZ * 4;
165}
173166
174167void SetAlternateSignalStack() {
175168 stack_t altstack, oldstack;
......@@ -180,10 +173,9 @@ void SetAlternateSignalStack() {
180173 // TODO(glider): the mapped stack should have the MAP_STACK flag in the
181174 // future. It is not required by man 2 sigaltstack now (they're using
182175 // malloc()).
183 void* base = MmapOrDie(kAltStackSize, __func__);
184 altstack.ss_sp = (char*) base;
176 altstack.ss_size = GetAltStackSize();
177 altstack.ss_sp = (char *)MmapOrDie(altstack.ss_size, __func__);
185178 altstack.ss_flags = 0;
186 altstack.ss_size = kAltStackSize;
187179 CHECK_EQ(0, sigaltstack(&altstack, nullptr));
188180}
189181
......@@ -191,7 +183,7 @@ void UnsetAlternateSignalStack() {
191183 stack_t altstack, oldstack;
192184 altstack.ss_sp = nullptr;
193185 altstack.ss_flags = SS_DISABLE;
194 altstack.ss_size = kAltStackSize; // Some sane value required on Darwin.
186 altstack.ss_size = GetAltStackSize(); // Some sane value required on Darwin.
195187 CHECK_EQ(0, sigaltstack(&altstack, &oldstack));
196188 UnmapOrDie(oldstack.ss_sp, oldstack.ss_size);
197189}
lib/tsan/sanitizer_common/sanitizer_printf.cpp+49-35
......@@ -20,6 +20,10 @@
2020#include <stdio.h>
2121#include <stdarg.h>
2222
23#if defined(__x86_64__)
24# include <emmintrin.h>
25#endif
26
2327#if SANITIZER_WINDOWS && defined(_MSC_VER) && _MSC_VER < 1800 && \
2428 !defined(va_copy)
2529# define va_copy(dst, src) ((dst) = (src))
......@@ -128,7 +132,7 @@ static int AppendPointer(char **buff, const char *buff_end, u64 ptr_value) {
128132int VSNPrintf(char *buff, int buff_length,
129133 const char *format, va_list args) {
130134 static const char *kPrintfFormatsHelp =
131 "Supported Printf formats: %([0-9]*)?(z|ll)?{d,u,x,X}; %p; "
135 "Supported Printf formats: %([0-9]*)?(z|ll)?{d,u,x,X,V}; %p; "
132136 "%[-]([0-9]*)?(\\.\\*)?s; %c\n";
133137 RAW_CHECK(format);
134138 RAW_CHECK(buff_length > 0);
......@@ -162,17 +166,15 @@ int VSNPrintf(char *buff, int buff_length,
162166 cur += have_z;
163167 bool have_ll = !have_z && (cur[0] == 'l' && cur[1] == 'l');
164168 cur += have_ll * 2;
165 s64 dval;
166 u64 uval;
167169 const bool have_length = have_z || have_ll;
168170 const bool have_flags = have_width || have_length;
169171 // At the moment only %s supports precision and left-justification.
170172 CHECK(!((precision >= 0 || left_justified) && *cur != 's'));
171173 switch (*cur) {
172174 case 'd': {
173 dval = have_ll ? va_arg(args, s64)
174 : have_z ? va_arg(args, sptr)
175 : va_arg(args, int);
175 s64 dval = have_ll ? va_arg(args, s64)
176 : have_z ? va_arg(args, sptr)
177 : va_arg(args, int);
176178 result += AppendSignedDecimal(&buff, buff_end, dval, width,
177179 pad_with_zero);
178180 break;
......@@ -180,14 +182,21 @@ int VSNPrintf(char *buff, int buff_length,
180182 case 'u':
181183 case 'x':
182184 case 'X': {
183 uval = have_ll ? va_arg(args, u64)
184 : have_z ? va_arg(args, uptr)
185 : va_arg(args, unsigned);
185 u64 uval = have_ll ? va_arg(args, u64)
186 : have_z ? va_arg(args, uptr)
187 : va_arg(args, unsigned);
186188 bool uppercase = (*cur == 'X');
187189 result += AppendUnsigned(&buff, buff_end, uval, (*cur == 'u') ? 10 : 16,
188190 width, pad_with_zero, uppercase);
189191 break;
190192 }
193 case 'V': {
194 for (uptr i = 0; i < 16; i++) {
195 unsigned x = va_arg(args, unsigned);
196 result += AppendUnsigned(&buff, buff_end, x, 16, 2, true, false);
197 }
198 break;
199 }
191200 case 'p': {
192201 RAW_CHECK_MSG(!have_flags, kPrintfFormatsHelp);
193202 result += AppendPointer(&buff, buff_end, va_arg(args, uptr));
......@@ -249,26 +258,21 @@ static void NOINLINE SharedPrintfCodeNoBuffer(bool append_pid,
249258 va_list args) {
250259 va_list args2;
251260 va_copy(args2, args);
252 const int kLen = 16 * 1024;
253 int needed_length;
261 InternalMmapVector<char> v;
262 int needed_length = 0;
254263 char *buffer = local_buffer;
255264 // First try to print a message using a local buffer, and then fall back to
256265 // mmaped buffer.
257 for (int use_mmap = 0; use_mmap < 2; use_mmap++) {
266 for (int use_mmap = 0;; use_mmap++) {
258267 if (use_mmap) {
259268 va_end(args);
260269 va_copy(args, args2);
261 buffer = (char*)MmapOrDie(kLen, "Report");
262 buffer_size = kLen;
270 v.resize(needed_length + 1);
271 buffer_size = v.capacity();
272 v.resize(buffer_size);
273 buffer = &v[0];
263274 }
264275 needed_length = 0;
265 // Check that data fits into the current buffer.
266# define CHECK_NEEDED_LENGTH \
267 if (needed_length >= buffer_size) { \
268 if (!use_mmap) continue; \
269 RAW_CHECK_MSG(needed_length < kLen, \
270 "Buffer in Report is too short!\n"); \
271 }
272276 // Fuchsia's logging infrastructure always keeps track of the logging
273277 // process, thread, and timestamp, so never prepend such information.
274278 if (!SANITIZER_FUCHSIA && append_pid) {
......@@ -277,18 +281,20 @@ static void NOINLINE SharedPrintfCodeNoBuffer(bool append_pid,
277281 if (common_flags()->log_exe_name && exe_name) {
278282 needed_length += internal_snprintf(buffer, buffer_size,
279283 "==%s", exe_name);
280 CHECK_NEEDED_LENGTH
284 if (needed_length >= buffer_size)
285 continue;
281286 }
282287 needed_length += internal_snprintf(
283288 buffer + needed_length, buffer_size - needed_length, "==%d==", pid);
284 CHECK_NEEDED_LENGTH
289 if (needed_length >= buffer_size)
290 continue;
285291 }
286292 needed_length += VSNPrintf(buffer + needed_length,
287293 buffer_size - needed_length, format, args);
288 CHECK_NEEDED_LENGTH
294 if (needed_length >= buffer_size)
295 continue;
289296 // If the message fit into the buffer, print it and exit.
290297 break;
291# undef CHECK_NEEDED_LENGTH
292298 }
293299 RawWrite(buffer);
294300
......@@ -297,9 +303,6 @@ static void NOINLINE SharedPrintfCodeNoBuffer(bool append_pid,
297303 CallPrintfAndReportCallback(buffer);
298304 LogMessageOnPrintf(buffer);
299305
300 // If we had mapped any memory, clean up.
301 if (buffer != local_buffer)
302 UnmapOrDie((void *)buffer, buffer_size);
303306 va_end(args2);
304307}
305308
......@@ -346,13 +349,24 @@ int internal_snprintf(char *buffer, uptr length, const char *format, ...) {
346349
347350FORMAT(2, 3)
348351void InternalScopedString::append(const char *format, ...) {
349 CHECK_LT(length_, size());
350 va_list args;
351 va_start(args, format);
352 VSNPrintf(data() + length_, size() - length_, format, args);
353 va_end(args);
354 length_ += internal_strlen(data() + length_);
355 CHECK_LT(length_, size());
352 uptr prev_len = length();
353
354 while (true) {
355 buffer_.resize(buffer_.capacity());
356
357 va_list args;
358 va_start(args, format);
359 uptr sz = VSNPrintf(buffer_.data() + prev_len, buffer_.size() - prev_len,
360 format, args);
361 va_end(args);
362 if (sz < buffer_.size() - prev_len) {
363 buffer_.resize(prev_len + sz + 1);
364 break;
365 }
366
367 buffer_.reserve(buffer_.capacity() * 2);
368 }
369 CHECK_EQ(buffer_[length()], '\0');
356370}
357371
358372} // namespace __sanitizer
lib/tsan/sanitizer_common/sanitizer_procmaps.h+1-1
......@@ -16,7 +16,7 @@
1616#include "sanitizer_platform.h"
1717
1818#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || \
19 SANITIZER_OPENBSD || SANITIZER_MAC || SANITIZER_SOLARIS || \
19 SANITIZER_MAC || SANITIZER_SOLARIS || \
2020 SANITIZER_FUCHSIA
2121
2222#include "sanitizer_common.h"
lib/tsan/sanitizer_common/sanitizer_procmaps_bsd.cpp+2-29
......@@ -7,11 +7,11 @@
77//===----------------------------------------------------------------------===//
88//
99// Information about the process mappings
10// (FreeBSD, OpenBSD and NetBSD-specific parts).
10// (FreeBSD and NetBSD-specific parts).
1111//===----------------------------------------------------------------------===//
1212
1313#include "sanitizer_platform.h"
14#if SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_OPENBSD
14#if SANITIZER_FREEBSD || SANITIZER_NETBSD
1515#include "sanitizer_common.h"
1616#if SANITIZER_FREEBSD
1717#include "sanitizer_freebsd.h"
......@@ -28,11 +28,6 @@
2828#endif
2929
3030#include <limits.h>
31#if SANITIZER_OPENBSD
32#define KVME_PROT_READ KVE_PROT_READ
33#define KVME_PROT_WRITE KVE_PROT_WRITE
34#define KVME_PROT_EXEC KVE_PROT_EXEC
35#endif
3631
3732// Fix 'kinfo_vmentry' definition on FreeBSD prior v9.2 in 32-bit mode.
3833#if SANITIZER_FREEBSD && (SANITIZER_WORDSIZE == 32)
......@@ -51,10 +46,6 @@ void ReadProcMaps(ProcSelfMapsBuff *proc_maps) {
5146 KERN_PROC,
5247 KERN_PROC_VMMAP,
5348 getpid()
54#elif SANITIZER_OPENBSD
55 CTL_KERN,
56 KERN_PROC_VMMAP,
57 getpid()
5849#elif SANITIZER_NETBSD
5950 CTL_VM,
6051 VM_PROC,
......@@ -71,28 +62,12 @@ void ReadProcMaps(ProcSelfMapsBuff *proc_maps) {
7162 CHECK_EQ(Err, 0);
7263 CHECK_GT(Size, 0);
7364
74#if !SANITIZER_OPENBSD
7565 size_t MmapedSize = Size * 4 / 3;
7666 void *VmMap = MmapOrDie(MmapedSize, "ReadProcMaps()");
7767 Size = MmapedSize;
7868 Err = internal_sysctl(Mib, ARRAY_SIZE(Mib), VmMap, &Size, NULL, 0);
7969 CHECK_EQ(Err, 0);
8070 proc_maps->data = (char *)VmMap;
81#else
82 size_t PageSize = GetPageSize();
83 size_t MmapedSize = Size;
84 MmapedSize = ((MmapedSize - 1) / PageSize + 1) * PageSize;
85 char *Mem = (char *)MmapOrDie(MmapedSize, "ReadProcMaps()");
86 Size = 2 * Size + 10 * sizeof(struct kinfo_vmentry);
87 if (Size > 0x10000)
88 Size = 0x10000;
89 Size = (Size / sizeof(struct kinfo_vmentry)) * sizeof(struct kinfo_vmentry);
90 Err = internal_sysctl(Mib, ARRAY_SIZE(Mib), Mem, &Size, NULL, 0);
91 CHECK_EQ(Err, 0);
92 MmapedSize = Size;
93 proc_maps->data = Mem;
94#endif
95
9671 proc_maps->mmaped_size = MmapedSize;
9772 proc_maps->len = Size;
9873}
......@@ -117,13 +92,11 @@ bool MemoryMappingLayout::Next(MemoryMappedSegment *segment) {
11792 if ((VmEntry->kve_protection & KVME_PROT_EXEC) != 0)
11893 segment->protection |= kProtectionExecute;
11994
120#if !SANITIZER_OPENBSD
12195 if (segment->filename != NULL && segment->filename_size > 0) {
12296 internal_snprintf(segment->filename,
12397 Min(segment->filename_size, (uptr)PATH_MAX), "%s",
12498 VmEntry->kve_path);
12599 }
126#endif
127100
128101#if SANITIZER_FREEBSD
129102 data_.current += VmEntry->kve_structsize;
lib/tsan/sanitizer_common/sanitizer_procmaps_common.cpp+2-2
......@@ -12,7 +12,7 @@
1212#include "sanitizer_platform.h"
1313
1414#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \
15 SANITIZER_OPENBSD || SANITIZER_SOLARIS
15 SANITIZER_SOLARIS
1616
1717#include "sanitizer_common.h"
1818#include "sanitizer_placement_new.h"
......@@ -120,7 +120,7 @@ void MemoryMappingLayout::LoadFromCache() {
120120void MemoryMappingLayout::DumpListOfModules(
121121 InternalMmapVectorNoCtor<LoadedModule> *modules) {
122122 Reset();
123 InternalScopedString module_name(kMaxPathLength);
123 InternalMmapVector<char> module_name(kMaxPathLength);
124124 MemoryMappedSegment segment(module_name.data(), module_name.size());
125125 for (uptr i = 0; Next(&segment); i++) {
126126 const char *cur_name = segment.filename;
lib/tsan/sanitizer_common/sanitizer_procmaps_mac.cpp+2-2
......@@ -354,8 +354,8 @@ bool MemoryMappingLayout::Next(MemoryMappedSegment *segment) {
354354void MemoryMappingLayout::DumpListOfModules(
355355 InternalMmapVectorNoCtor<LoadedModule> *modules) {
356356 Reset();
357 InternalScopedString module_name(kMaxPathLength);
358 MemoryMappedSegment segment(module_name.data(), kMaxPathLength);
357 InternalMmapVector<char> module_name(kMaxPathLength);
358 MemoryMappedSegment segment(module_name.data(), module_name.size());
359359 MemoryMappedSegmentData data;
360360 segment.data_ = &data;
361361 while (Next(&segment)) {
lib/tsan/sanitizer_common/sanitizer_procmaps_solaris.cpp+4-3
......@@ -9,13 +9,13 @@
99// Information about the process mappings (Solaris-specific parts).
1010//===----------------------------------------------------------------------===//
1111
12// Before Solaris 11.4, <procfs.h> doesn't work in a largefile environment.
13#undef _FILE_OFFSET_BITS
1214#include "sanitizer_platform.h"
1315#if SANITIZER_SOLARIS
1416#include "sanitizer_common.h"
1517#include "sanitizer_procmaps.h"
1618
17// Before Solaris 11.4, <procfs.h> doesn't work in a largefile environment.
18#undef _FILE_OFFSET_BITS
1919#include <procfs.h>
2020#include <limits.h>
2121
......@@ -35,7 +35,8 @@ bool MemoryMappingLayout::Next(MemoryMappedSegment *segment) {
3535 char *last = data_.proc_self_maps.data + data_.proc_self_maps.len;
3636 if (data_.current >= last) return false;
3737
38 prxmap_t *xmapentry = (prxmap_t*)data_.current;
38 prxmap_t *xmapentry =
39 const_cast<prxmap_t *>(reinterpret_cast<const prxmap_t *>(data_.current));
3940
4041 segment->start = (uptr)xmapentry->pr_vaddr;
4142 segment->end = (uptr)(xmapentry->pr_vaddr + xmapentry->pr_size);
lib/tsan/sanitizer_common/sanitizer_ptrauth.h+20
......@@ -11,6 +11,24 @@
1111
1212#if __has_feature(ptrauth_calls)
1313#include <ptrauth.h>
14#elif defined(__ARM_FEATURE_PAC_DEFAULT) && !defined(__APPLE__)
15inline unsigned long ptrauth_strip(void* __value, unsigned int __key) {
16 // On the stack the link register is protected with Pointer
17 // Authentication Code when compiled with -mbranch-protection.
18 // Let's stripping the PAC unconditionally because xpaclri is in
19 // the NOP space so will do nothing when it is not enabled or not available.
20 unsigned long ret;
21 asm volatile(
22 "mov x30, %1\n\t"
23 "hint #7\n\t" // xpaclri
24 "mov %0, x30\n\t"
25 : "=r"(ret)
26 : "r"(__value)
27 : "x30");
28 return ret;
29}
30#define ptrauth_auth_data(__value, __old_key, __old_data) __value
31#define ptrauth_string_discriminator(__string) ((int)0)
1432#else
1533// Copied from <ptrauth.h>
1634#define ptrauth_strip(__value, __key) __value
......@@ -18,4 +36,6 @@
1836#define ptrauth_string_discriminator(__string) ((int)0)
1937#endif
2038
39#define STRIP_PAC_PC(pc) ((uptr)ptrauth_strip(pc, 0))
40
2141#endif // SANITIZER_PTRAUTH_H
lib/tsan/sanitizer_common/sanitizer_quarantine.h+2-1
......@@ -149,7 +149,8 @@ class Quarantine {
149149 Cache cache_;
150150 char pad2_[kCacheLineSize];
151151
152 void NOINLINE Recycle(uptr min_size, Callback cb) {
152 void NOINLINE Recycle(uptr min_size, Callback cb) REQUIRES(recycle_mutex_)
153 RELEASE(recycle_mutex_) {
153154 Cache tmp;
154155 {
155156 SpinMutexLock l(&cache_mutex_);
lib/tsan/sanitizer_common/sanitizer_rtems.cpp deleted-283
......@@ -1,283 +0,0 @@
1//===-- sanitizer_rtems.cpp -----------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file is shared between various sanitizers' runtime libraries and
10// implements RTEMS-specific functions.
11//===----------------------------------------------------------------------===//
12
13#include "sanitizer_rtems.h"
14#if SANITIZER_RTEMS
15
16#define posix_memalign __real_posix_memalign
17#define free __real_free
18#define memset __real_memset
19
20#include "sanitizer_file.h"
21#include "sanitizer_symbolizer.h"
22#include <errno.h>
23#include <fcntl.h>
24#include <pthread.h>
25#include <sched.h>
26#include <stdio.h>
27#include <stdlib.h>
28#include <string.h>
29#include <unistd.h>
30
31// There is no mmap on RTEMS. Use memalign, etc.
32#define __mmap_alloc_aligned posix_memalign
33#define __mmap_free free
34#define __mmap_memset memset
35
36namespace __sanitizer {
37
38#include "sanitizer_syscall_generic.inc"
39
40void NORETURN internal__exit(int exitcode) {
41 _exit(exitcode);
42}
43
44uptr internal_sched_yield() {
45 return sched_yield();
46}
47
48uptr internal_getpid() {
49 return getpid();
50}
51
52int internal_dlinfo(void *handle, int request, void *p) {
53 UNIMPLEMENTED();
54}
55
56bool FileExists(const char *filename) {
57 struct stat st;
58 if (stat(filename, &st))
59 return false;
60 // Sanity check: filename is a regular file.
61 return S_ISREG(st.st_mode);
62}
63
64uptr GetThreadSelf() { return static_cast<uptr>(pthread_self()); }
65
66tid_t GetTid() { return GetThreadSelf(); }
67
68void Abort() { abort(); }
69
70int Atexit(void (*function)(void)) { return atexit(function); }
71
72void SleepForSeconds(int seconds) { sleep(seconds); }
73
74void SleepForMillis(int millis) { usleep(millis * 1000); }
75
76bool SupportsColoredOutput(fd_t fd) { return false; }
77
78void GetThreadStackTopAndBottom(bool at_initialization,
79 uptr *stack_top, uptr *stack_bottom) {
80 pthread_attr_t attr;
81 pthread_attr_init(&attr);
82 CHECK_EQ(pthread_getattr_np(pthread_self(), &attr), 0);
83 void *base = nullptr;
84 size_t size = 0;
85 CHECK_EQ(pthread_attr_getstack(&attr, &base, &size), 0);
86 CHECK_EQ(pthread_attr_destroy(&attr), 0);
87
88 *stack_bottom = reinterpret_cast<uptr>(base);
89 *stack_top = *stack_bottom + size;
90}
91
92void GetThreadStackAndTls(bool main, uptr *stk_addr, uptr *stk_size,
93 uptr *tls_addr, uptr *tls_size) {
94 uptr stack_top, stack_bottom;
95 GetThreadStackTopAndBottom(main, &stack_top, &stack_bottom);
96 *stk_addr = stack_bottom;
97 *stk_size = stack_top - stack_bottom;
98 *tls_addr = *tls_size = 0;
99}
100
101void InitializePlatformEarly() {}
102void MaybeReexec() {}
103void CheckASLR() {}
104void CheckMPROTECT() {}
105void DisableCoreDumperIfNecessary() {}
106void InstallDeadlySignalHandlers(SignalHandlerType handler) {}
107void SetAlternateSignalStack() {}
108void UnsetAlternateSignalStack() {}
109void InitTlsSize() {}
110
111void PrintModuleMap() {}
112
113void SignalContext::DumpAllRegisters(void *context) {}
114const char *DescribeSignalOrException(int signo) { UNIMPLEMENTED(); }
115
116enum MutexState { MtxUnlocked = 0, MtxLocked = 1, MtxSleeping = 2 };
117
118BlockingMutex::BlockingMutex() {
119 internal_memset(this, 0, sizeof(*this));
120}
121
122void BlockingMutex::Lock() {
123 CHECK_EQ(owner_, 0);
124 atomic_uint32_t *m = reinterpret_cast<atomic_uint32_t *>(&opaque_storage_);
125 if (atomic_exchange(m, MtxLocked, memory_order_acquire) == MtxUnlocked)
126 return;
127 while (atomic_exchange(m, MtxSleeping, memory_order_acquire) != MtxUnlocked) {
128 internal_sched_yield();
129 }
130}
131
132void BlockingMutex::Unlock() {
133 atomic_uint32_t *m = reinterpret_cast<atomic_uint32_t *>(&opaque_storage_);
134 u32 v = atomic_exchange(m, MtxUnlocked, memory_order_release);
135 CHECK_NE(v, MtxUnlocked);
136}
137
138void BlockingMutex::CheckLocked() {
139 atomic_uint32_t *m = reinterpret_cast<atomic_uint32_t *>(&opaque_storage_);
140 CHECK_NE(MtxUnlocked, atomic_load(m, memory_order_relaxed));
141}
142
143uptr GetPageSize() { return getpagesize(); }
144
145uptr GetMmapGranularity() { return GetPageSize(); }
146
147uptr GetMaxVirtualAddress() {
148 return (1ULL << 32) - 1; // 0xffffffff
149}
150
151void *MmapOrDie(uptr size, const char *mem_type, bool raw_report) {
152 void* ptr = 0;
153 int res = __mmap_alloc_aligned(&ptr, GetPageSize(), size);
154 if (UNLIKELY(res))
155 ReportMmapFailureAndDie(size, mem_type, "allocate", res, raw_report);
156 __mmap_memset(ptr, 0, size);
157 IncreaseTotalMmap(size);
158 return ptr;
159}
160
161void *MmapOrDieOnFatalError(uptr size, const char *mem_type) {
162 void* ptr = 0;
163 int res = __mmap_alloc_aligned(&ptr, GetPageSize(), size);
164 if (UNLIKELY(res)) {
165 if (res == ENOMEM)
166 return nullptr;
167 ReportMmapFailureAndDie(size, mem_type, "allocate", false);
168 }
169 __mmap_memset(ptr, 0, size);
170 IncreaseTotalMmap(size);
171 return ptr;
172}
173
174void *MmapAlignedOrDieOnFatalError(uptr size, uptr alignment,
175 const char *mem_type) {
176 CHECK(IsPowerOfTwo(size));
177 CHECK(IsPowerOfTwo(alignment));
178 void* ptr = 0;
179 int res = __mmap_alloc_aligned(&ptr, alignment, size);
180 if (res)
181 ReportMmapFailureAndDie(size, mem_type, "align allocate", res, false);
182 __mmap_memset(ptr, 0, size);
183 IncreaseTotalMmap(size);
184 return ptr;
185}
186
187void *MmapNoReserveOrDie(uptr size, const char *mem_type) {
188 return MmapOrDie(size, mem_type, false);
189}
190
191void UnmapOrDie(void *addr, uptr size) {
192 if (!addr || !size) return;
193 __mmap_free(addr);
194 DecreaseTotalMmap(size);
195}
196
197fd_t OpenFile(const char *filename, FileAccessMode mode, error_t *errno_p) {
198 int flags;
199 switch (mode) {
200 case RdOnly: flags = O_RDONLY; break;
201 case WrOnly: flags = O_WRONLY | O_CREAT | O_TRUNC; break;
202 case RdWr: flags = O_RDWR | O_CREAT; break;
203 }
204 fd_t res = open(filename, flags, 0660);
205 if (internal_iserror(res, errno_p))
206 return kInvalidFd;
207 return res;
208}
209
210void CloseFile(fd_t fd) {
211 close(fd);
212}
213
214bool ReadFromFile(fd_t fd, void *buff, uptr buff_size, uptr *bytes_read,
215 error_t *error_p) {
216 uptr res = read(fd, buff, buff_size);
217 if (internal_iserror(res, error_p))
218 return false;
219 if (bytes_read)
220 *bytes_read = res;
221 return true;
222}
223
224bool WriteToFile(fd_t fd, const void *buff, uptr buff_size, uptr *bytes_written,
225 error_t *error_p) {
226 uptr res = write(fd, buff, buff_size);
227 if (internal_iserror(res, error_p))
228 return false;
229 if (bytes_written)
230 *bytes_written = res;
231 return true;
232}
233
234void ReleaseMemoryPagesToOS(uptr beg, uptr end) {}
235void DumpProcessMap() {}
236
237// There is no page protection so everything is "accessible."
238bool IsAccessibleMemoryRange(uptr beg, uptr size) {
239 return true;
240}
241
242char **GetArgv() { return nullptr; }
243char **GetEnviron() { return nullptr; }
244
245const char *GetEnv(const char *name) {
246 return getenv(name);
247}
248
249uptr ReadBinaryName(/*out*/char *buf, uptr buf_len) {
250 internal_strncpy(buf, "StubBinaryName", buf_len);
251 return internal_strlen(buf);
252}
253
254uptr ReadLongProcessName(/*out*/ char *buf, uptr buf_len) {
255 internal_strncpy(buf, "StubProcessName", buf_len);
256 return internal_strlen(buf);
257}
258
259bool IsPathSeparator(const char c) {
260 return c == '/';
261}
262
263bool IsAbsolutePath(const char *path) {
264 return path != nullptr && IsPathSeparator(path[0]);
265}
266
267void ReportFile::Write(const char *buffer, uptr length) {
268 SpinMutexLock l(mu);
269 static const char *kWriteError =
270 "ReportFile::Write() can't output requested buffer!\n";
271 ReopenIfNecessary();
272 if (length != write(fd, buffer, length)) {
273 write(fd, kWriteError, internal_strlen(kWriteError));
274 Die();
275 }
276}
277
278uptr MainThreadStackBase, MainThreadStackSize;
279uptr MainThreadTlsBase, MainThreadTlsSize;
280
281} // namespace __sanitizer
282
283#endif // SANITIZER_RTEMS
lib/tsan/sanitizer_common/sanitizer_rtems.h deleted-20
......@@ -1,20 +0,0 @@
1//===-- sanitizer_rtems.h ---------------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file is shared between various sanitizers' runtime libraries and
10// provides definitions for RTEMS-specific functions.
11//===----------------------------------------------------------------------===//
12#ifndef SANITIZER_RTEMS_H
13#define SANITIZER_RTEMS_H
14
15#include "sanitizer_platform.h"
16#if SANITIZER_RTEMS
17#include "sanitizer_common.h"
18
19#endif // SANITIZER_RTEMS
20#endif // SANITIZER_RTEMS_H
lib/tsan/sanitizer_common/sanitizer_signal_interceptors.inc+4-1
......@@ -53,7 +53,10 @@ INTERCEPTOR(uptr, signal, int signum, uptr handler) {
5353
5454INTERCEPTOR(int, sigaction_symname, int signum,
5555 const __sanitizer_sigaction *act, __sanitizer_sigaction *oldact) {
56 if (GetHandleSignalMode(signum) == kHandleSignalExclusive) return 0;
56 if (GetHandleSignalMode(signum) == kHandleSignalExclusive) {
57 if (!oldact) return 0;
58 act = nullptr;
59 }
5760 SIGNAL_INTERCEPTOR_SIGACTION_IMPL(signum, act, oldact);
5861}
5962#define INIT_SIGACTION COMMON_INTERCEPT_FUNCTION(sigaction_symname)
lib/tsan/sanitizer_common/sanitizer_solaris.cpp+27-5
......@@ -74,6 +74,20 @@ DECLARE__REAL_AND_INTERNAL(int, mprotect, void *addr, uptr length, int prot) {
7474 return _REAL(mprotect)(addr, length, prot);
7575}
7676
77// Illumos' declaration of madvise cannot be made visible if _XOPEN_SOURCE
78// is defined as g++ does on Solaris.
79//
80// This declaration is consistent with Solaris 11.4. Both Illumos and Solaris
81// versions older than 11.4 declared madvise with a caddr_t as the first
82// argument, but we don't currently support Solaris versions older than 11.4,
83// and as mentioned above the declaration is not visible on Illumos so we can
84// use any declaration we like on Illumos.
85extern "C" int madvise(void *, size_t, int);
86
87int internal_madvise(uptr addr, uptr length, int advice) {
88 return madvise((void *)addr, length, advice);
89}
90
7791DECLARE__REAL_AND_INTERNAL(uptr, close, fd_t fd) {
7892 return _REAL(close)(fd);
7993}
......@@ -146,8 +160,11 @@ DECLARE__REAL_AND_INTERNAL(uptr, sched_yield, void) {
146160 return sched_yield();
147161}
148162
149DECLARE__REAL_AND_INTERNAL(void, _exit, int exitcode) {
150 _exit(exitcode);
163DECLARE__REAL_AND_INTERNAL(void, usleep, u64 useconds) {
164 struct timespec ts;
165 ts.tv_sec = useconds / 1000000;
166 ts.tv_nsec = (useconds % 1000000) * 1000;
167 nanosleep(&ts, nullptr);
151168}
152169
153170DECLARE__REAL_AND_INTERNAL(uptr, execve, const char *filename,
......@@ -201,6 +218,13 @@ uptr internal_clock_gettime(__sanitizer_clockid_t clk_id, void *tp) {
201218}
202219
203220// ----------------- sanitizer_common.h
221void FutexWait(atomic_uint32_t *p, u32 cmp) {
222 // FIXME: implement actual blocking.
223 sched_yield();
224}
225
226void FutexWake(atomic_uint32_t *p, u32 count) {}
227
204228BlockingMutex::BlockingMutex() {
205229 CHECK(sizeof(mutex_t) <= sizeof(opaque_storage_));
206230 internal_memset(this, 0, sizeof(*this));
......@@ -221,9 +245,7 @@ void BlockingMutex::Unlock() {
221245 CHECK_EQ(mutex_unlock((mutex_t *)&opaque_storage_), 0);
222246}
223247
224void BlockingMutex::CheckLocked() {
225 CHECK_EQ((uptr)thr_self(), owner_);
226}
248void BlockingMutex::CheckLocked() const { CHECK_EQ((uptr)thr_self(), owner_); }
227249
228250} // namespace __sanitizer
229251
lib/tsan/sanitizer_common/sanitizer_stackdepot.cpp+7-2
......@@ -115,6 +115,12 @@ void StackDepotUnlockAll() {
115115 theDepot.UnlockAll();
116116}
117117
118void StackDepotPrintAll() {
119#if !SANITIZER_GO
120 theDepot.PrintAll();
121#endif
122}
123
118124bool StackDepotReverseMap::IdDescPair::IdComparator(
119125 const StackDepotReverseMap::IdDescPair &a,
120126 const StackDepotReverseMap::IdDescPair &b) {
......@@ -139,8 +145,7 @@ StackTrace StackDepotReverseMap::Get(u32 id) {
139145 if (!map_.size())
140146 return StackTrace();
141147 IdDescPair pair = {id, nullptr};
142 uptr idx =
143 InternalLowerBound(map_, 0, map_.size(), pair, IdDescPair::IdComparator);
148 uptr idx = InternalLowerBound(map_, pair, IdDescPair::IdComparator);
144149 if (idx > map_.size() || map_[idx].id != id)
145150 return StackTrace();
146151 return map_[idx].desc->load();
lib/tsan/sanitizer_common/sanitizer_stackdepot.h+1
......@@ -41,6 +41,7 @@ StackTrace StackDepotGet(u32 id);
4141
4242void StackDepotLockAll();
4343void StackDepotUnlockAll();
44void StackDepotPrintAll();
4445
4546// Instantiating this class creates a snapshot of StackDepot which can be
4647// efficiently queried with StackDepotGet(). You can use it concurrently with
lib/tsan/sanitizer_common/sanitizer_stackdepotbase.h+19-1
......@@ -13,9 +13,11 @@
1313#ifndef SANITIZER_STACKDEPOTBASE_H
1414#define SANITIZER_STACKDEPOTBASE_H
1515
16#include <stdio.h>
17
18#include "sanitizer_atomic.h"
1619#include "sanitizer_internal_defs.h"
1720#include "sanitizer_mutex.h"
18#include "sanitizer_atomic.h"
1921#include "sanitizer_persistent_allocator.h"
2022
2123namespace __sanitizer {
......@@ -34,6 +36,7 @@ class StackDepotBase {
3436
3537 void LockAll();
3638 void UnlockAll();
39 void PrintAll();
3740
3841 private:
3942 static Node *find(Node *s, args_type args, u32 hash);
......@@ -172,6 +175,21 @@ void StackDepotBase<Node, kReservedBits, kTabSizeLog>::UnlockAll() {
172175 }
173176}
174177
178template <class Node, int kReservedBits, int kTabSizeLog>
179void StackDepotBase<Node, kReservedBits, kTabSizeLog>::PrintAll() {
180 for (int i = 0; i < kTabSize; ++i) {
181 atomic_uintptr_t *p = &tab[i];
182 lock(p);
183 uptr v = atomic_load(p, memory_order_relaxed);
184 Node *s = (Node *)(v & ~1UL);
185 for (; s; s = s->link) {
186 Printf("Stack for id %u:\n", s->id);
187 s->load().Print();
188 }
189 unlock(p, s);
190 }
191}
192
175193} // namespace __sanitizer
176194
177195#endif // SANITIZER_STACKDEPOTBASE_H
lib/tsan/sanitizer_common/sanitizer_stacktrace.cpp+37-3
......@@ -10,9 +10,12 @@
1010// run-time libraries.
1111//===----------------------------------------------------------------------===//
1212
13#include "sanitizer_stacktrace.h"
14
1315#include "sanitizer_common.h"
1416#include "sanitizer_flags.h"
15#include "sanitizer_stacktrace.h"
17#include "sanitizer_platform.h"
18#include "sanitizer_ptrauth.h"
1619
1720namespace __sanitizer {
1821
......@@ -21,6 +24,28 @@ uptr StackTrace::GetNextInstructionPc(uptr pc) {
2124 return pc + 8;
2225#elif defined(__powerpc__) || defined(__arm__) || defined(__aarch64__)
2326 return pc + 4;
27#elif SANITIZER_RISCV64
28 // Current check order is 4 -> 2 -> 6 -> 8
29 u8 InsnByte = *(u8 *)(pc);
30 if (((InsnByte & 0x3) == 0x3) && ((InsnByte & 0x1c) != 0x1c)) {
31 // xxxxxxxxxxxbbb11 | 32 bit | bbb != 111
32 return pc + 4;
33 }
34 if ((InsnByte & 0x3) != 0x3) {
35 // xxxxxxxxxxxxxxaa | 16 bit | aa != 11
36 return pc + 2;
37 }
38 // RISC-V encoding allows instructions to be up to 8 bytes long
39 if ((InsnByte & 0x3f) == 0x1f) {
40 // xxxxxxxxxx011111 | 48 bit |
41 return pc + 6;
42 }
43 if ((InsnByte & 0x7f) == 0x3f) {
44 // xxxxxxxxx0111111 | 64 bit |
45 return pc + 8;
46 }
47 // bail-out if could not figure out the instruction size
48 return 0;
2449#else
2550 return pc + 1;
2651#endif
......@@ -94,8 +119,11 @@ void BufferedStackTrace::UnwindFast(uptr pc, uptr bp, uptr stack_top,
94119 uhwptr pc1 = caller_frame[2];
95120#elif defined(__s390__)
96121 uhwptr pc1 = frame[14];
122#elif defined(__riscv)
123 // frame[-1] contains the return address
124 uhwptr pc1 = frame[-1];
97125#else
98 uhwptr pc1 = frame[1];
126 uhwptr pc1 = STRIP_PAC_PC((void *)frame[1]);
99127#endif
100128 // Let's assume that any pointer in the 0th page (i.e. <0x1000 on i386 and
101129 // x86_64) is invalid and stop unwinding here. If we're adding support for
......@@ -106,7 +134,13 @@ void BufferedStackTrace::UnwindFast(uptr pc, uptr bp, uptr stack_top,
106134 trace_buffer[size++] = (uptr) pc1;
107135 }
108136 bottom = (uptr)frame;
109 frame = GetCanonicFrame((uptr)frame[0], stack_top, bottom);
137#if defined(__riscv)
138 // frame[-2] contain fp of the previous frame
139 uptr new_bp = (uptr)frame[-2];
140#else
141 uptr new_bp = (uptr)frame[0];
142#endif
143 frame = GetCanonicFrame(new_bp, stack_top, bottom);
110144 }
111145}
112146
lib/tsan/sanitizer_common/sanitizer_stacktrace.h+52-7
......@@ -12,7 +12,9 @@
1212#ifndef SANITIZER_STACKTRACE_H
1313#define SANITIZER_STACKTRACE_H
1414
15#include "sanitizer_common.h"
1516#include "sanitizer_internal_defs.h"
17#include "sanitizer_platform.h"
1618
1719namespace __sanitizer {
1820
......@@ -24,8 +26,6 @@ static const u32 kStackTraceMax = 256;
2426# define SANITIZER_CAN_FAST_UNWIND 0
2527#elif SANITIZER_WINDOWS
2628# define SANITIZER_CAN_FAST_UNWIND 0
27#elif SANITIZER_OPENBSD
28# define SANITIZER_CAN_FAST_UNWIND 0
2929#else
3030# define SANITIZER_CAN_FAST_UNWIND 1
3131#endif
......@@ -33,8 +33,8 @@ static const u32 kStackTraceMax = 256;
3333// Fast unwind is the only option on Mac for now; we will need to
3434// revisit this macro when slow unwind works on Mac, see
3535// https://github.com/google/sanitizers/issues/137
36#if SANITIZER_MAC || SANITIZER_OPENBSD || SANITIZER_RTEMS
37# define SANITIZER_CAN_SLOW_UNWIND 0
36#if SANITIZER_MAC
37# define SANITIZER_CAN_SLOW_UNWIND 0
3838#else
3939# define SANITIZER_CAN_SLOW_UNWIND 1
4040#endif
......@@ -57,6 +57,16 @@ struct StackTrace {
5757 // Prints a symbolized stacktrace, followed by an empty line.
5858 void Print() const;
5959
60 // Prints a symbolized stacktrace to the output string, followed by an empty
61 // line.
62 void PrintTo(InternalScopedString *output) const;
63
64 // Prints a symbolized stacktrace to the output buffer, followed by an empty
65 // line. Returns the number of symbols that should have been written to buffer
66 // (not including trailing '\0'). Thus, the string is truncated iff return
67 // value is not less than "out_buf_size".
68 uptr PrintTo(char *out_buf, uptr out_buf_size) const;
69
6070 static bool WillUseFastUnwind(bool request_fast_unwind) {
6171 if (!SANITIZER_CAN_FAST_UNWIND)
6272 return false;
......@@ -68,8 +78,6 @@ struct StackTrace {
6878 static uptr GetCurrentPc();
6979 static inline uptr GetPreviousInstructionPc(uptr pc);
7080 static uptr GetNextInstructionPc(uptr pc);
71 typedef bool (*SymbolizeCallback)(const void *pc, char *out_buffer,
72 int out_size);
7381};
7482
7583// Performance-critical, must be in the header.
......@@ -85,6 +93,14 @@ uptr StackTrace::GetPreviousInstructionPc(uptr pc) {
8593 return pc - 4;
8694#elif defined(__sparc__) || defined(__mips__)
8795 return pc - 8;
96#elif SANITIZER_RISCV64
97 // RV-64 has variable instruciton length...
98 // C extentions gives us 2-byte instructoins
99 // RV-64 has 4-byte instructions
100 // + RISCV architecture allows instructions up to 8 bytes
101 // It seems difficult to figure out the exact instruction length -
102 // pc - 2 seems like a safe option for the purposes of stack tracing
103 return pc - 2;
88104#else
89105 return pc - 1;
90106#endif
......@@ -143,9 +159,17 @@ struct BufferedStackTrace : public StackTrace {
143159 friend class FastUnwindTest;
144160};
145161
162#if defined(__s390x__)
163static const uptr kFrameSize = 160;
164#elif defined(__s390__)
165static const uptr kFrameSize = 96;
166#else
167static const uptr kFrameSize = 2 * sizeof(uhwptr);
168#endif
169
146170// Check if given pointer points into allocated stack area.
147171static inline bool IsValidFrame(uptr frame, uptr stack_top, uptr stack_bottom) {
148 return frame > stack_bottom && frame < stack_top - 2 * sizeof (uhwptr);
172 return frame > stack_bottom && frame < stack_top - kFrameSize;
149173}
150174
151175} // namespace __sanitizer
......@@ -172,5 +196,26 @@ static inline bool IsValidFrame(uptr frame, uptr stack_top, uptr stack_bottom) {
172196 uptr local_stack; \
173197 uptr sp = (uptr)&local_stack
174198
199// GET_CURRENT_PC() is equivalent to StackTrace::GetCurrentPc().
200// Optimized x86 version is faster than GetCurrentPc because
201// it does not involve a function call, instead it reads RIP register.
202// Reads of RIP by an instruction return RIP pointing to the next
203// instruction, which is exactly what we want here, thus 0 offset.
204// It needs to be a macro because otherwise we will get the name
205// of this function on the top of most stacks. Attribute artificial
206// does not do what it claims to do, unfortunatley. And attribute
207// __nodebug__ is clang-only. If we would have an attribute that
208// would remove this function from debug info, we could simply make
209// StackTrace::GetCurrentPc() faster.
210#if defined(__x86_64__)
211# define GET_CURRENT_PC() \
212 ({ \
213 uptr pc; \
214 asm("lea 0(%%rip), %0" : "=r"(pc)); \
215 pc; \
216 })
217#else
218# define GET_CURRENT_PC() StackTrace::GetCurrentPc()
219#endif
175220
176221#endif // SANITIZER_STACKTRACE_H
lib/tsan/sanitizer_common/sanitizer_stacktrace_libcdep.cpp+120-54
......@@ -18,40 +18,119 @@
1818
1919namespace __sanitizer {
2020
21void StackTrace::Print() const {
21namespace {
22
23class StackTraceTextPrinter {
24 public:
25 StackTraceTextPrinter(const char *stack_trace_fmt, char frame_delimiter,
26 InternalScopedString *output,
27 InternalScopedString *dedup_token)
28 : stack_trace_fmt_(stack_trace_fmt),
29 frame_delimiter_(frame_delimiter),
30 output_(output),
31 dedup_token_(dedup_token),
32 symbolize_(RenderNeedsSymbolization(stack_trace_fmt)) {}
33
34 bool ProcessAddressFrames(uptr pc) {
35 SymbolizedStack *frames = symbolize_
36 ? Symbolizer::GetOrInit()->SymbolizePC(pc)
37 : SymbolizedStack::New(pc);
38 if (!frames)
39 return false;
40
41 for (SymbolizedStack *cur = frames; cur; cur = cur->next) {
42 uptr prev_len = output_->length();
43 RenderFrame(output_, stack_trace_fmt_, frame_num_++, cur->info.address,
44 symbolize_ ? &cur->info : nullptr,
45 common_flags()->symbolize_vs_style,
46 common_flags()->strip_path_prefix);
47
48 if (prev_len != output_->length())
49 output_->append("%c", frame_delimiter_);
50
51 ExtendDedupToken(cur);
52 }
53 frames->ClearAll();
54 return true;
55 }
56
57 private:
58 // Extend the dedup token by appending a new frame.
59 void ExtendDedupToken(SymbolizedStack *stack) {
60 if (!dedup_token_)
61 return;
62
63 if (dedup_frames_-- > 0) {
64 if (dedup_token_->length())
65 dedup_token_->append("--");
66 if (stack->info.function != nullptr)
67 dedup_token_->append(stack->info.function);
68 }
69 }
70
71 const char *stack_trace_fmt_;
72 const char frame_delimiter_;
73 int dedup_frames_ = common_flags()->dedup_token_length;
74 uptr frame_num_ = 0;
75 InternalScopedString *output_;
76 InternalScopedString *dedup_token_;
77 const bool symbolize_ = false;
78};
79
80static void CopyStringToBuffer(const InternalScopedString &str, char *out_buf,
81 uptr out_buf_size) {
82 if (!out_buf_size)
83 return;
84
85 CHECK_GT(out_buf_size, 0);
86 uptr copy_size = Min(str.length(), out_buf_size - 1);
87 internal_memcpy(out_buf, str.data(), copy_size);
88 out_buf[copy_size] = '\0';
89}
90
91} // namespace
92
93void StackTrace::PrintTo(InternalScopedString *output) const {
94 CHECK(output);
95
96 InternalScopedString dedup_token;
97 StackTraceTextPrinter printer(common_flags()->stack_trace_format, '\n',
98 output, &dedup_token);
99
22100 if (trace == nullptr || size == 0) {
23 Printf(" <empty stack>\n\n");
101 output->append(" <empty stack>\n\n");
24102 return;
25103 }
26 InternalScopedString frame_desc(GetPageSizeCached() * 2);
27 InternalScopedString dedup_token(GetPageSizeCached());
28 int dedup_frames = common_flags()->dedup_token_length;
29 uptr frame_num = 0;
104
30105 for (uptr i = 0; i < size && trace[i]; i++) {
31106 // PCs in stack traces are actually the return addresses, that is,
32107 // addresses of the next instructions after the call.
33108 uptr pc = GetPreviousInstructionPc(trace[i]);
34 SymbolizedStack *frames = Symbolizer::GetOrInit()->SymbolizePC(pc);
35 CHECK(frames);
36 for (SymbolizedStack *cur = frames; cur; cur = cur->next) {
37 frame_desc.clear();
38 RenderFrame(&frame_desc, common_flags()->stack_trace_format, frame_num++,
39 cur->info, common_flags()->symbolize_vs_style,
40 common_flags()->strip_path_prefix);
41 Printf("%s\n", frame_desc.data());
42 if (dedup_frames-- > 0) {
43 if (dedup_token.length())
44 dedup_token.append("--");
45 if (cur->info.function != nullptr)
46 dedup_token.append(cur->info.function);
47 }
48 }
49 frames->ClearAll();
109 CHECK(printer.ProcessAddressFrames(pc));
50110 }
51 // Always print a trailing empty line after stack trace.
52 Printf("\n");
111
112 // Always add a trailing empty line after stack trace.
113 output->append("\n");
114
115 // Append deduplication token, if non-empty.
53116 if (dedup_token.length())
54 Printf("DEDUP_TOKEN: %s\n", dedup_token.data());
117 output->append("DEDUP_TOKEN: %s\n", dedup_token.data());
118}
119
120uptr StackTrace::PrintTo(char *out_buf, uptr out_buf_size) const {
121 CHECK(out_buf);
122
123 InternalScopedString output;
124 PrintTo(&output);
125 CopyStringToBuffer(output, out_buf, out_buf_size);
126
127 return output.length();
128}
129
130void StackTrace::Print() const {
131 InternalScopedString output;
132 PrintTo(&output);
133 Printf("%s", output.data());
55134}
56135
57136void BufferedStackTrace::Unwind(u32 max_depth, uptr pc, uptr bp, void *context,
......@@ -76,12 +155,15 @@ void BufferedStackTrace::Unwind(u32 max_depth, uptr pc, uptr bp, void *context,
76155 UnwindSlow(pc, context, max_depth);
77156 else
78157 UnwindSlow(pc, max_depth);
158 // If there are too few frames, the program may be built with
159 // -fno-asynchronous-unwind-tables. Fall back to fast unwinder below.
160 if (size > 2 || size >= max_depth)
161 return;
79162#else
80163 UNREACHABLE("slow unwind requested but not available");
81164#endif
82 } else {
83 UnwindFast(pc, bp, stack_top, stack_bottom, max_depth);
84165 }
166 UnwindFast(pc, bp, stack_top, stack_bottom, max_depth);
85167}
86168
87169static int GetModuleAndOffsetForPc(uptr pc, char *module_name,
......@@ -106,34 +188,18 @@ extern "C" {
106188SANITIZER_INTERFACE_ATTRIBUTE
107189void __sanitizer_symbolize_pc(uptr pc, const char *fmt, char *out_buf,
108190 uptr out_buf_size) {
109 if (!out_buf_size) return;
110 pc = StackTrace::GetPreviousInstructionPc(pc);
111 SymbolizedStack *frame = Symbolizer::GetOrInit()->SymbolizePC(pc);
112 if (!frame) {
113 internal_strncpy(out_buf, "<can't symbolize>", out_buf_size);
114 out_buf[out_buf_size - 1] = 0;
191 if (!out_buf_size)
115192 return;
193
194 pc = StackTrace::GetPreviousInstructionPc(pc);
195
196 InternalScopedString output;
197 StackTraceTextPrinter printer(fmt, '\0', &output, nullptr);
198 if (!printer.ProcessAddressFrames(pc)) {
199 output.clear();
200 output.append("<can't symbolize>");
116201 }
117 InternalScopedString frame_desc(GetPageSizeCached());
118 uptr frame_num = 0;
119 // Reserve one byte for the final 0.
120 char *out_end = out_buf + out_buf_size - 1;
121 for (SymbolizedStack *cur = frame; cur && out_buf < out_end;
122 cur = cur->next) {
123 frame_desc.clear();
124 RenderFrame(&frame_desc, fmt, frame_num++, cur->info,
125 common_flags()->symbolize_vs_style,
126 common_flags()->strip_path_prefix);
127 if (!frame_desc.length())
128 continue;
129 // Reserve one byte for the terminating 0.
130 uptr n = out_end - out_buf - 1;
131 internal_strncpy(out_buf, frame_desc.data(), n);
132 out_buf += __sanitizer::Min<uptr>(n, frame_desc.length());
133 *out_buf++ = 0;
134 }
135 CHECK(out_buf <= out_end);
136 *out_buf = 0;
202 CopyStringToBuffer(output, out_buf, out_buf_size);
137203}
138204
139205SANITIZER_INTERFACE_ATTRIBUTE
......@@ -143,7 +209,7 @@ void __sanitizer_symbolize_global(uptr data_addr, const char *fmt,
143209 out_buf[0] = 0;
144210 DataInfo DI;
145211 if (!Symbolizer::GetOrInit()->SymbolizeData(data_addr, &DI)) return;
146 InternalScopedString data_desc(GetPageSizeCached());
212 InternalScopedString data_desc;
147213 RenderData(&data_desc, fmt, &DI, common_flags()->strip_path_prefix);
148214 internal_strncpy(out_buf, data_desc.data(), out_buf_size);
149215 out_buf[out_buf_size - 1] = 0;
lib/tsan/sanitizer_common/sanitizer_stacktrace_printer.cpp+60-32
......@@ -107,8 +107,14 @@ static const char *DemangleFunctionName(const char *function) {
107107static const char kDefaultFormat[] = " #%n %p %F %L";
108108
109109void RenderFrame(InternalScopedString *buffer, const char *format, int frame_no,
110 const AddressInfo &info, bool vs_style,
110 uptr address, const AddressInfo *info, bool vs_style,
111111 const char *strip_path_prefix, const char *strip_func_prefix) {
112 // info will be null in the case where symbolization is not needed for the
113 // given format. This ensures that the code below will get a hard failure
114 // rather than print incorrect information in case RenderNeedsSymbolization
115 // ever ends up out of sync with this function. If non-null, the addresses
116 // should match.
117 CHECK(!info || address == info->address);
112118 if (0 == internal_strcmp(format, "DEFAULT"))
113119 format = kDefaultFormat;
114120 for (const char *p = format; *p != '\0'; p++) {
......@@ -126,71 +132,70 @@ void RenderFrame(InternalScopedString *buffer, const char *format, int frame_no,
126132 buffer->append("%zu", frame_no);
127133 break;
128134 case 'p':
129 buffer->append("0x%zx", info.address);
135 buffer->append("0x%zx", address);
130136 break;
131137 case 'm':
132 buffer->append("%s", StripPathPrefix(info.module, strip_path_prefix));
138 buffer->append("%s", StripPathPrefix(info->module, strip_path_prefix));
133139 break;
134140 case 'o':
135 buffer->append("0x%zx", info.module_offset);
141 buffer->append("0x%zx", info->module_offset);
136142 break;
137143 case 'f':
138 buffer->append("%s",
139 DemangleFunctionName(
140 StripFunctionName(info.function, strip_func_prefix)));
144 buffer->append("%s", DemangleFunctionName(StripFunctionName(
145 info->function, strip_func_prefix)));
141146 break;
142147 case 'q':
143 buffer->append("0x%zx", info.function_offset != AddressInfo::kUnknown
144 ? info.function_offset
148 buffer->append("0x%zx", info->function_offset != AddressInfo::kUnknown
149 ? info->function_offset
145150 : 0x0);
146151 break;
147152 case 's':
148 buffer->append("%s", StripPathPrefix(info.file, strip_path_prefix));
153 buffer->append("%s", StripPathPrefix(info->file, strip_path_prefix));
149154 break;
150155 case 'l':
151 buffer->append("%d", info.line);
156 buffer->append("%d", info->line);
152157 break;
153158 case 'c':
154 buffer->append("%d", info.column);
159 buffer->append("%d", info->column);
155160 break;
156161 // Smarter special cases.
157162 case 'F':
158163 // Function name and offset, if file is unknown.
159 if (info.function) {
160 buffer->append("in %s",
161 DemangleFunctionName(
162 StripFunctionName(info.function, strip_func_prefix)));
163 if (!info.file && info.function_offset != AddressInfo::kUnknown)
164 buffer->append("+0x%zx", info.function_offset);
164 if (info->function) {
165 buffer->append("in %s", DemangleFunctionName(StripFunctionName(
166 info->function, strip_func_prefix)));
167 if (!info->file && info->function_offset != AddressInfo::kUnknown)
168 buffer->append("+0x%zx", info->function_offset);
165169 }
166170 break;
167171 case 'S':
168172 // File/line information.
169 RenderSourceLocation(buffer, info.file, info.line, info.column, vs_style,
170 strip_path_prefix);
173 RenderSourceLocation(buffer, info->file, info->line, info->column,
174 vs_style, strip_path_prefix);
171175 break;
172176 case 'L':
173177 // Source location, or module location.
174 if (info.file) {
175 RenderSourceLocation(buffer, info.file, info.line, info.column,
178 if (info->file) {
179 RenderSourceLocation(buffer, info->file, info->line, info->column,
176180 vs_style, strip_path_prefix);
177 } else if (info.module) {
178 RenderModuleLocation(buffer, info.module, info.module_offset,
179 info.module_arch, strip_path_prefix);
181 } else if (info->module) {
182 RenderModuleLocation(buffer, info->module, info->module_offset,
183 info->module_arch, strip_path_prefix);
180184 } else {
181185 buffer->append("(<unknown module>)");
182186 }
183187 break;
184188 case 'M':
185189 // Module basename and offset, or PC.
186 if (info.address & kExternalPCBit)
187 {} // There PCs are not meaningful.
188 else if (info.module)
190 if (address & kExternalPCBit) {
191 // There PCs are not meaningful.
192 } else if (info->module) {
189193 // Always strip the module name for %M.
190 RenderModuleLocation(buffer, StripModuleName(info.module),
191 info.module_offset, info.module_arch, "");
192 else
193 buffer->append("(%p)", (void *)info.address);
194 RenderModuleLocation(buffer, StripModuleName(info->module),
195 info->module_offset, info->module_arch, "");
196 } else {
197 buffer->append("(%p)", (void *)address);
198 }
194199 break;
195200 default:
196201 Report("Unsupported specifier in stack frame format: %c (0x%zx)!\n", *p,
......@@ -200,6 +205,29 @@ void RenderFrame(InternalScopedString *buffer, const char *format, int frame_no,
200205 }
201206}
202207
208bool RenderNeedsSymbolization(const char *format) {
209 if (0 == internal_strcmp(format, "DEFAULT"))
210 format = kDefaultFormat;
211 for (const char *p = format; *p != '\0'; p++) {
212 if (*p != '%')
213 continue;
214 p++;
215 switch (*p) {
216 case '%':
217 break;
218 case 'n':
219 // frame_no
220 break;
221 case 'p':
222 // address
223 break;
224 default:
225 return true;
226 }
227 }
228 return false;
229}
230
203231void RenderData(InternalScopedString *buffer, const char *format,
204232 const DataInfo *DI, const char *strip_path_prefix) {
205233 for (const char *p = format; *p != '\0'; p++) {
lib/tsan/sanitizer_common/sanitizer_stacktrace_printer.h+3-1
......@@ -47,10 +47,12 @@ namespace __sanitizer {
4747// module+offset if it is known, or (<unknown module>) string.
4848// %M - prints module basename and offset, if it is known, or PC.
4949void RenderFrame(InternalScopedString *buffer, const char *format, int frame_no,
50 const AddressInfo &info, bool vs_style,
50 uptr address, const AddressInfo *info, bool vs_style,
5151 const char *strip_path_prefix = "",
5252 const char *strip_func_prefix = "");
5353
54bool RenderNeedsSymbolization(const char *format);
55
5456void RenderSourceLocation(InternalScopedString *buffer, const char *file,
5557 int line, int column, bool vs_style,
5658 const char *strip_path_prefix);
lib/tsan/sanitizer_common/sanitizer_stoptheworld.h+7-6
......@@ -32,20 +32,21 @@ class SuspendedThreadsList {
3232
3333 // Can't declare pure virtual functions in sanitizer runtimes:
3434 // __cxa_pure_virtual might be unavailable. Use UNIMPLEMENTED() instead.
35 virtual PtraceRegistersStatus GetRegistersAndSP(uptr index, uptr *buffer,
36 uptr *sp) const {
35 virtual PtraceRegistersStatus GetRegistersAndSP(
36 uptr index, InternalMmapVector<uptr> *buffer, uptr *sp) const {
3737 UNIMPLEMENTED();
3838 }
3939
40 // The buffer in GetRegistersAndSP should be at least this big.
41 virtual uptr RegisterCount() const { UNIMPLEMENTED(); }
4240 virtual uptr ThreadCount() const { UNIMPLEMENTED(); }
4341 virtual tid_t GetThreadID(uptr index) const { UNIMPLEMENTED(); }
4442
43 protected:
44 ~SuspendedThreadsList() {}
45
4546 private:
4647 // Prohibit copy and assign.
47 SuspendedThreadsList(const SuspendedThreadsList&);
48 void operator=(const SuspendedThreadsList&);
48 SuspendedThreadsList(const SuspendedThreadsList &) = delete;
49 void operator=(const SuspendedThreadsList &) = delete;
4950};
5051
5152typedef void (*StopTheWorldCallback)(
lib/tsan/sanitizer_common/sanitizer_stoptheworld_fuchsia.cpp+2-1
......@@ -17,6 +17,7 @@
1717#include <zircon/sanitizer.h>
1818
1919#include "sanitizer_stoptheworld.h"
20#include "sanitizer_stoptheworld_fuchsia.h"
2021
2122namespace __sanitizer {
2223
......@@ -32,7 +33,7 @@ void StopTheWorld(StopTheWorldCallback callback, void *argument) {
3233 nullptr, nullptr, nullptr, nullptr,
3334 [](zx_status_t, void *data) {
3435 auto params = reinterpret_cast<Params *>(data);
35 params->callback({}, params->argument);
36 params->callback(SuspendedThreadsListFuchsia(), params->argument);
3637 },
3738 &params);
3839}
lib/tsan/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp+78-28
......@@ -13,10 +13,10 @@
1313
1414#include "sanitizer_platform.h"
1515
16#if SANITIZER_LINUX && (defined(__x86_64__) || defined(__mips__) || \
17 defined(__aarch64__) || defined(__powerpc64__) || \
18 defined(__s390__) || defined(__i386__) || \
19 defined(__arm__))
16#if SANITIZER_LINUX && \
17 (defined(__x86_64__) || defined(__mips__) || defined(__aarch64__) || \
18 defined(__powerpc64__) || defined(__s390__) || defined(__i386__) || \
19 defined(__arm__) || SANITIZER_RISCV64)
2020
2121#include "sanitizer_stoptheworld.h"
2222
......@@ -31,7 +31,7 @@
3131#include <sys/types.h> // for pid_t
3232#include <sys/uio.h> // for iovec
3333#include <elf.h> // for NT_PRSTATUS
34#if defined(__aarch64__) && !SANITIZER_ANDROID
34#if (defined(__aarch64__) || SANITIZER_RISCV64) && !SANITIZER_ANDROID
3535// GLIBC 2.20+ sys/user does not include asm/ptrace.h
3636# include <asm/ptrace.h>
3737#endif
......@@ -85,18 +85,18 @@
8585
8686namespace __sanitizer {
8787
88class SuspendedThreadsListLinux : public SuspendedThreadsList {
88class SuspendedThreadsListLinux final : public SuspendedThreadsList {
8989 public:
9090 SuspendedThreadsListLinux() { thread_ids_.reserve(1024); }
9191
92 tid_t GetThreadID(uptr index) const;
93 uptr ThreadCount() const;
92 tid_t GetThreadID(uptr index) const override;
93 uptr ThreadCount() const override;
9494 bool ContainsTid(tid_t thread_id) const;
9595 void Append(tid_t tid);
9696
97 PtraceRegistersStatus GetRegistersAndSP(uptr index, uptr *buffer,
98 uptr *sp) const;
99 uptr RegisterCount() const;
97 PtraceRegistersStatus GetRegistersAndSP(uptr index,
98 InternalMmapVector<uptr> *buffer,
99 uptr *sp) const override;
100100
101101 private:
102102 InternalMmapVector<tid_t> thread_ids_;
......@@ -485,6 +485,16 @@ typedef user_regs_struct regs_struct;
485485#else
486486#define REG_SP rsp
487487#endif
488#define ARCH_IOVEC_FOR_GETREGSET
489// Support ptrace extensions even when compiled without required kernel support
490#ifndef NT_X86_XSTATE
491#define NT_X86_XSTATE 0x202
492#endif
493#ifndef PTRACE_GETREGSET
494#define PTRACE_GETREGSET 0x4204
495#endif
496// Compiler may use FP registers to store pointers.
497static constexpr uptr kExtraRegs[] = {NT_X86_XSTATE, NT_FPREGSET};
488498
489499#elif defined(__powerpc__) || defined(__powerpc64__)
490500typedef pt_regs regs_struct;
......@@ -501,11 +511,21 @@ typedef struct user regs_struct;
501511#elif defined(__aarch64__)
502512typedef struct user_pt_regs regs_struct;
503513#define REG_SP sp
514static constexpr uptr kExtraRegs[] = {0};
515#define ARCH_IOVEC_FOR_GETREGSET
516
517#elif SANITIZER_RISCV64
518typedef struct user_regs_struct regs_struct;
519// sys/ucontext.h already defines REG_SP as 2. Undefine it first.
520#undef REG_SP
521#define REG_SP sp
522static constexpr uptr kExtraRegs[] = {0};
504523#define ARCH_IOVEC_FOR_GETREGSET
505524
506525#elif defined(__s390__)
507526typedef _user_regs_struct regs_struct;
508527#define REG_SP gprs[15]
528static constexpr uptr kExtraRegs[] = {0};
509529#define ARCH_IOVEC_FOR_GETREGSET
510530
511531#else
......@@ -533,24 +553,58 @@ void SuspendedThreadsListLinux::Append(tid_t tid) {
533553}
534554
535555PtraceRegistersStatus SuspendedThreadsListLinux::GetRegistersAndSP(
536 uptr index, uptr *buffer, uptr *sp) const {
556 uptr index, InternalMmapVector<uptr> *buffer, uptr *sp) const {
537557 pid_t tid = GetThreadID(index);
538 regs_struct regs;
558 constexpr uptr uptr_sz = sizeof(uptr);
539559 int pterrno;
540560#ifdef ARCH_IOVEC_FOR_GETREGSET
541 struct iovec regset_io;
542 regset_io.iov_base = &regs;
543 regset_io.iov_len = sizeof(regs_struct);
544 bool isErr = internal_iserror(internal_ptrace(PTRACE_GETREGSET, tid,
545 (void*)NT_PRSTATUS, (void*)&regset_io),
546 &pterrno);
561 auto append = [&](uptr regset) {
562 uptr size = buffer->size();
563 // NT_X86_XSTATE requires 64bit alignment.
564 uptr size_up = RoundUpTo(size, 8 / uptr_sz);
565 buffer->reserve(Max<uptr>(1024, size_up));
566 struct iovec regset_io;
567 for (;; buffer->resize(buffer->capacity() * 2)) {
568 buffer->resize(buffer->capacity());
569 uptr available_bytes = (buffer->size() - size_up) * uptr_sz;
570 regset_io.iov_base = buffer->data() + size_up;
571 regset_io.iov_len = available_bytes;
572 bool fail =
573 internal_iserror(internal_ptrace(PTRACE_GETREGSET, tid,
574 (void *)regset, (void *)&regset_io),
575 &pterrno);
576 if (fail) {
577 VReport(1, "Could not get regset %p from thread %d (errno %d).\n",
578 (void *)regset, tid, pterrno);
579 buffer->resize(size);
580 return false;
581 }
582
583 // Far enough from the buffer size, no need to resize and repeat.
584 if (regset_io.iov_len + 64 < available_bytes)
585 break;
586 }
587 buffer->resize(size_up + RoundUpTo(regset_io.iov_len, uptr_sz) / uptr_sz);
588 return true;
589 };
590
591 buffer->clear();
592 bool fail = !append(NT_PRSTATUS);
593 if (!fail) {
594 // Accept the first available and do not report errors.
595 for (uptr regs : kExtraRegs)
596 if (regs && append(regs))
597 break;
598 }
547599#else
548 bool isErr = internal_iserror(internal_ptrace(PTRACE_GETREGS, tid, nullptr,
549 &regs), &pterrno);
550#endif
551 if (isErr) {
600 buffer->resize(RoundUpTo(sizeof(regs_struct), uptr_sz) / uptr_sz);
601 bool fail = internal_iserror(
602 internal_ptrace(PTRACE_GETREGS, tid, nullptr, buffer->data()), &pterrno);
603 if (fail)
552604 VReport(1, "Could not get registers from thread %d (errno %d).\n", tid,
553605 pterrno);
606#endif
607 if (fail) {
554608 // ESRCH means that the given thread is not suspended or already dead.
555609 // Therefore it's unsafe to inspect its data (e.g. walk through stack) and
556610 // we should notify caller about this.
......@@ -558,14 +612,10 @@ PtraceRegistersStatus SuspendedThreadsListLinux::GetRegistersAndSP(
558612 : REGISTERS_UNAVAILABLE;
559613 }
560614
561 *sp = regs.REG_SP;
562 internal_memcpy(buffer, &regs, sizeof(regs));
615 *sp = reinterpret_cast<regs_struct *>(buffer->data())[0].REG_SP;
563616 return REGISTERS_AVAILABLE;
564617}
565618
566uptr SuspendedThreadsListLinux::RegisterCount() const {
567 return sizeof(regs_struct) / sizeof(uptr);
568}
569619} // namespace __sanitizer
570620
571621#endif // SANITIZER_LINUX && (defined(__x86_64__) || defined(__mips__)
lib/tsan/sanitizer_common/sanitizer_stoptheworld_mac.cpp+9-11
......@@ -27,19 +27,19 @@ typedef struct {
2727 thread_t thread;
2828} SuspendedThreadInfo;
2929
30class SuspendedThreadsListMac : public SuspendedThreadsList {
30class SuspendedThreadsListMac final : public SuspendedThreadsList {
3131 public:
3232 SuspendedThreadsListMac() : threads_(1024) {}
3333
34 tid_t GetThreadID(uptr index) const;
34 tid_t GetThreadID(uptr index) const override;
3535 thread_t GetThread(uptr index) const;
36 uptr ThreadCount() const;
36 uptr ThreadCount() const override;
3737 bool ContainsThread(thread_t thread) const;
3838 void Append(thread_t thread);
3939
40 PtraceRegistersStatus GetRegistersAndSP(uptr index, uptr *buffer,
41 uptr *sp) const;
42 uptr RegisterCount() const;
40 PtraceRegistersStatus GetRegistersAndSP(uptr index,
41 InternalMmapVector<uptr> *buffer,
42 uptr *sp) const override;
4343
4444 private:
4545 InternalMmapVector<SuspendedThreadInfo> threads_;
......@@ -142,7 +142,7 @@ void SuspendedThreadsListMac::Append(thread_t thread) {
142142}
143143
144144PtraceRegistersStatus SuspendedThreadsListMac::GetRegistersAndSP(
145 uptr index, uptr *buffer, uptr *sp) const {
145 uptr index, InternalMmapVector<uptr> *buffer, uptr *sp) const {
146146 thread_t thread = GetThread(index);
147147 regs_struct regs;
148148 int err;
......@@ -159,7 +159,8 @@ PtraceRegistersStatus SuspendedThreadsListMac::GetRegistersAndSP(
159159 : REGISTERS_UNAVAILABLE;
160160 }
161161
162 internal_memcpy(buffer, &regs, sizeof(regs));
162 buffer->resize(RoundUpTo(sizeof(regs), sizeof(uptr)) / sizeof(uptr));
163 internal_memcpy(buffer->data(), &regs, sizeof(regs));
163164#if defined(__aarch64__) && defined(arm_thread_state64_get_sp)
164165 *sp = arm_thread_state64_get_sp(regs);
165166#else
......@@ -173,9 +174,6 @@ PtraceRegistersStatus SuspendedThreadsListMac::GetRegistersAndSP(
173174 return REGISTERS_AVAILABLE;
174175}
175176
176uptr SuspendedThreadsListMac::RegisterCount() const {
177 return MACHINE_THREAD_STATE_COUNT;
178}
179177} // namespace __sanitizer
180178
181179#endif // SANITIZER_MAC && (defined(__x86_64__) || defined(__aarch64__)) ||
lib/tsan/sanitizer_common/sanitizer_stoptheworld_netbsd_libcdep.cpp+7-9
......@@ -48,7 +48,7 @@
4848
4949namespace __sanitizer {
5050
51class SuspendedThreadsListNetBSD : public SuspendedThreadsList {
51class SuspendedThreadsListNetBSD final : public SuspendedThreadsList {
5252 public:
5353 SuspendedThreadsListNetBSD() { thread_ids_.reserve(1024); }
5454
......@@ -57,9 +57,9 @@ class SuspendedThreadsListNetBSD : public SuspendedThreadsList {
5757 bool ContainsTid(tid_t thread_id) const;
5858 void Append(tid_t tid);
5959
60 PtraceRegistersStatus GetRegistersAndSP(uptr index, uptr *buffer,
60 PtraceRegistersStatus GetRegistersAndSP(uptr index,
61 InternalMmapVector<uptr> *buffer,
6162 uptr *sp) const;
62 uptr RegisterCount() const;
6363
6464 private:
6565 InternalMmapVector<tid_t> thread_ids_;
......@@ -131,7 +131,7 @@ bool ThreadSuspender::SuspendAllThreads() {
131131 pl.pl_lwpid = 0;
132132
133133 int val;
134 while ((val = ptrace(op, pid_, (void *)&pl, sizeof(pl))) != -1 &&
134 while ((val = internal_ptrace(op, pid_, (void *)&pl, sizeof(pl))) != -1 &&
135135 pl.pl_lwpid != 0) {
136136 suspended_threads_list_.Append(pl.pl_lwpid);
137137 VReport(2, "Appended thread %d in process %d.\n", pl.pl_lwpid, pid_);
......@@ -335,7 +335,7 @@ void SuspendedThreadsListNetBSD::Append(tid_t tid) {
335335}
336336
337337PtraceRegistersStatus SuspendedThreadsListNetBSD::GetRegistersAndSP(
338 uptr index, uptr *buffer, uptr *sp) const {
338 uptr index, InternalMmapVector<uptr> *buffer, uptr *sp) const {
339339 lwpid_t tid = GetThreadID(index);
340340 pid_t ppid = internal_getppid();
341341 struct reg regs;
......@@ -351,14 +351,12 @@ PtraceRegistersStatus SuspendedThreadsListNetBSD::GetRegistersAndSP(
351351 }
352352
353353 *sp = PTRACE_REG_SP(&regs);
354 internal_memcpy(buffer, &regs, sizeof(regs));
354 buffer->resize(RoundUpTo(sizeof(regs), sizeof(uptr)) / sizeof(uptr));
355 internal_memcpy(buffer->data(), &regs, sizeof(regs));
355356
356357 return REGISTERS_AVAILABLE;
357358}
358359
359uptr SuspendedThreadsListNetBSD::RegisterCount() const {
360 return sizeof(struct reg) / sizeof(uptr);
361}
362360} // namespace __sanitizer
363361
364362#endif
lib/tsan/sanitizer_common/sanitizer_suppressions.cpp+2-2
......@@ -34,7 +34,7 @@ SuppressionContext::SuppressionContext(const char *suppression_types[],
3434static bool GetPathAssumingFileIsRelativeToExec(const char *file_path,
3535 /*out*/char *new_file_path,
3636 uptr new_file_path_size) {
37 InternalScopedString exec(kMaxPathLength);
37 InternalMmapVector<char> exec(kMaxPathLength);
3838 if (ReadBinaryNameCached(exec.data(), exec.size())) {
3939 const char *file_name_pos = StripModuleName(exec.data());
4040 uptr path_to_exec_len = file_name_pos - exec.data();
......@@ -69,7 +69,7 @@ void SuppressionContext::ParseFromFile(const char *filename) {
6969 if (filename[0] == '\0')
7070 return;
7171
72 InternalScopedString new_file_path(kMaxPathLength);
72 InternalMmapVector<char> new_file_path(kMaxPathLength);
7373 filename = FindFile(filename, new_file_path.data(), new_file_path.size());
7474
7575 // Read the file.
lib/tsan/sanitizer_common/sanitizer_symbolizer_internal.h+6-1
......@@ -74,6 +74,9 @@ class SymbolizerTool {
7474 // Usually this is a safe place to call code that might need to use user
7575 // memory allocators.
7676 virtual void LateInitialize() {}
77
78 protected:
79 ~SymbolizerTool() {}
7780};
7881
7982// SymbolizerProcess encapsulates communication between the tool and
......@@ -85,6 +88,8 @@ class SymbolizerProcess {
8588 const char *SendCommand(const char *command);
8689
8790 protected:
91 ~SymbolizerProcess() {}
92
8893 /// The maximum number of arguments required to invoke a tool process.
8994 static const unsigned kArgVMax = 6;
9095
......@@ -128,7 +133,7 @@ class LLVMSymbolizerProcess;
128133
129134// This tool invokes llvm-symbolizer in a subprocess. It should be as portable
130135// as the llvm-symbolizer tool is.
131class LLVMSymbolizer : public SymbolizerTool {
136class LLVMSymbolizer final : public SymbolizerTool {
132137 public:
133138 explicit LLVMSymbolizer(const char *path, LowLevelAllocator *allocator);
134139
lib/tsan/sanitizer_common/sanitizer_symbolizer_libbacktrace.h+1-1
......@@ -28,7 +28,7 @@
2828
2929namespace __sanitizer {
3030
31class LibbacktraceSymbolizer : public SymbolizerTool {
31class LibbacktraceSymbolizer final : public SymbolizerTool {
3232 public:
3333 static LibbacktraceSymbolizer *get(LowLevelAllocator *alloc);
3434
lib/tsan/sanitizer_common/sanitizer_symbolizer_libcdep.cpp+7-4
......@@ -12,6 +12,7 @@
1212
1313#include "sanitizer_allocator_internal.h"
1414#include "sanitizer_internal_defs.h"
15#include "sanitizer_platform.h"
1516#include "sanitizer_symbolizer_internal.h"
1617
1718namespace __sanitizer {
......@@ -236,7 +237,7 @@ const LoadedModule *Symbolizer::FindModuleForAddress(uptr address) {
236237// <file_name>:<line_number>:<column_number>
237238// ...
238239// <empty line>
239class LLVMSymbolizerProcess : public SymbolizerProcess {
240class LLVMSymbolizerProcess final : public SymbolizerProcess {
240241 public:
241242 explicit LLVMSymbolizerProcess(const char *path)
242243 : SymbolizerProcess(path, /*use_posix_spawn=*/SANITIZER_MAC) {}
......@@ -258,6 +259,8 @@ class LLVMSymbolizerProcess : public SymbolizerProcess {
258259 const char* const kSymbolizerArch = "--default-arch=x86_64";
259260#elif defined(__i386__)
260261 const char* const kSymbolizerArch = "--default-arch=i386";
262#elif SANITIZER_RISCV64
263 const char *const kSymbolizerArch = "--default-arch=riscv64";
261264#elif defined(__aarch64__)
262265 const char* const kSymbolizerArch = "--default-arch=arm64";
263266#elif defined(__arm__)
......@@ -275,8 +278,8 @@ class LLVMSymbolizerProcess : public SymbolizerProcess {
275278#endif
276279
277280 const char *const inline_flag = common_flags()->symbolize_inline_frames
278 ? "--inlining=true"
279 : "--inlining=false";
281 ? "--inlines"
282 : "--no-inlines";
280283 int i = 0;
281284 argv[i++] = path_to_binary;
282285 argv[i++] = inline_flag;
......@@ -353,7 +356,7 @@ void ParseSymbolizePCOutput(const char *str, SymbolizedStack *res) {
353356 InternalFree(info->function);
354357 info->function = 0;
355358 }
356 if (0 == internal_strcmp(info->file, "??")) {
359 if (info->file && 0 == internal_strcmp(info->file, "??")) {
357360 InternalFree(info->file);
358361 info->file = 0;
359362 }
lib/tsan/sanitizer_common/sanitizer_symbolizer_mac.cpp+14-7
......@@ -33,8 +33,15 @@ bool DlAddrSymbolizer::SymbolizePC(uptr addr, SymbolizedStack *stack) {
3333 int result = dladdr((const void *)addr, &info);
3434 if (!result) return false;
3535
36 CHECK(addr >= reinterpret_cast<uptr>(info.dli_saddr));
37 stack->info.function_offset = addr - reinterpret_cast<uptr>(info.dli_saddr);
36 // Compute offset if possible. `dladdr()` doesn't always ensure that `addr >=
37 // sym_addr` so only compute the offset when this holds. Failure to find the
38 // function offset is not treated as a failure because it might still be
39 // possible to get the symbol name.
40 uptr sym_addr = reinterpret_cast<uptr>(info.dli_saddr);
41 if (addr >= sym_addr) {
42 stack->info.function_offset = addr - sym_addr;
43 }
44
3845 const char *demangled = DemangleSwiftAndCXX(info.dli_sname);
3946 if (!demangled) return false;
4047 stack->info.function = internal_strdup(demangled);
......@@ -58,7 +65,7 @@ bool DlAddrSymbolizer::SymbolizeData(uptr addr, DataInfo *datainfo) {
5865// kAsanInternalHeapMagic.
5966static char kAtosMachPortEnvEntry[] = K_ATOS_ENV_VAR "=000000000000000";
6067
61class AtosSymbolizerProcess : public SymbolizerProcess {
68class AtosSymbolizerProcess final : public SymbolizerProcess {
6269 public:
6370 explicit AtosSymbolizerProcess(const char *path)
6471 : SymbolizerProcess(path, /*use_posix_spawn*/ true) {
......@@ -219,10 +226,10 @@ bool AtosSymbolizer::SymbolizePC(uptr addr, SymbolizedStack *stack) {
219226 start_address = reinterpret_cast<uptr>(info.dli_saddr);
220227 }
221228
222 // Only assig to `function_offset` if we were able to get the function's
223 // start address.
224 if (start_address != AddressInfo::kUnknown) {
225 CHECK(addr >= start_address);
229 // Only assign to `function_offset` if we were able to get the function's
230 // start address and we got a sensible `start_address` (dladdr doesn't always
231 // ensure that `addr >= sym_addr`).
232 if (start_address != AddressInfo::kUnknown && addr >= start_address) {
226233 stack->info.function_offset = addr - start_address;
227234 }
228235 return true;
lib/tsan/sanitizer_common/sanitizer_symbolizer_mac.h+2-2
......@@ -21,7 +21,7 @@
2121
2222namespace __sanitizer {
2323
24class DlAddrSymbolizer : public SymbolizerTool {
24class DlAddrSymbolizer final : public SymbolizerTool {
2525 public:
2626 bool SymbolizePC(uptr addr, SymbolizedStack *stack) override;
2727 bool SymbolizeData(uptr addr, DataInfo *info) override;
......@@ -29,7 +29,7 @@ class DlAddrSymbolizer : public SymbolizerTool {
2929
3030class AtosSymbolizerProcess;
3131
32class AtosSymbolizer : public SymbolizerTool {
32class AtosSymbolizer final : public SymbolizerTool {
3333 public:
3434 explicit AtosSymbolizer(const char *path, LowLevelAllocator *allocator);
3535
lib/tsan/sanitizer_common/sanitizer_symbolizer_markup.cpp+15-9
......@@ -16,14 +16,13 @@
1616
1717#if SANITIZER_FUCHSIA
1818#include "sanitizer_symbolizer_fuchsia.h"
19#elif SANITIZER_RTEMS
20#include "sanitizer_symbolizer_rtems.h"
21#endif
22#include "sanitizer_stacktrace.h"
23#include "sanitizer_symbolizer.h"
19# endif
2420
25#include <limits.h>
26#include <unwind.h>
21# include <limits.h>
22# include <unwind.h>
23
24# include "sanitizer_stacktrace.h"
25# include "sanitizer_symbolizer.h"
2726
2827namespace __sanitizer {
2928
......@@ -54,6 +53,10 @@ bool Symbolizer::GetModuleNameAndOffsetForPC(uptr pc, const char **module_name,
5453 return false;
5554}
5655
56// This is mainly used by hwasan for online symbolization. This isn't needed
57// since hwasan can always just dump stack frames for offline symbolization.
58bool Symbolizer::SymbolizeFrame(uptr addr, FrameInfo *info) { return false; }
59
5760// This is used in some places for suppression checking, which we
5861// don't really support for Fuchsia. It's also used in UBSan to
5962// identify a PC location to a function name, so we always fill in
......@@ -83,11 +86,14 @@ void RenderData(InternalScopedString *buffer, const char *format,
8386 buffer->append(kFormatData, DI->start);
8487}
8588
89bool RenderNeedsSymbolization(const char *format) { return false; }
90
8691// We don't support the stack_trace_format flag at all.
8792void RenderFrame(InternalScopedString *buffer, const char *format, int frame_no,
88 const AddressInfo &info, bool vs_style,
93 uptr address, const AddressInfo *info, bool vs_style,
8994 const char *strip_path_prefix, const char *strip_func_prefix) {
90 buffer->append(kFormatFrame, frame_no, info.address);
95 CHECK(!RenderNeedsSymbolization(format));
96 buffer->append(kFormatFrame, frame_no, address);
9197}
9298
9399Symbolizer *Symbolizer::PlatformInit() {
lib/tsan/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp+14-5
......@@ -201,7 +201,7 @@ bool SymbolizerProcess::StartSymbolizerSubprocess() {
201201 return true;
202202}
203203
204class Addr2LineProcess : public SymbolizerProcess {
204class Addr2LineProcess final : public SymbolizerProcess {
205205 public:
206206 Addr2LineProcess(const char *path, const char *module_name)
207207 : SymbolizerProcess(path), module_name_(internal_strdup(module_name)) {}
......@@ -261,7 +261,7 @@ bool Addr2LineProcess::ReachedEndOfOutput(const char *buffer,
261261 output_terminator_, kTerminatorLen);
262262}
263263
264class Addr2LinePool : public SymbolizerTool {
264class Addr2LinePool final : public SymbolizerTool {
265265 public:
266266 explicit Addr2LinePool(const char *addr2line_path,
267267 LowLevelAllocator *allocator)
......@@ -328,7 +328,7 @@ int __sanitizer_symbolize_demangle(const char *Name, char *Buffer,
328328 int MaxLength);
329329} // extern "C"
330330
331class InternalSymbolizer : public SymbolizerTool {
331class InternalSymbolizer final : public SymbolizerTool {
332332 public:
333333 static InternalSymbolizer *get(LowLevelAllocator *alloc) {
334334 if (__sanitizer_symbolize_code != 0 &&
......@@ -387,7 +387,7 @@ class InternalSymbolizer : public SymbolizerTool {
387387};
388388#else // SANITIZER_SUPPORTS_WEAK_HOOKS
389389
390class InternalSymbolizer : public SymbolizerTool {
390class InternalSymbolizer final : public SymbolizerTool {
391391 public:
392392 static InternalSymbolizer *get(LowLevelAllocator *alloc) { return 0; }
393393};
......@@ -400,11 +400,20 @@ const char *Symbolizer::PlatformDemangle(const char *name) {
400400
401401static SymbolizerTool *ChooseExternalSymbolizer(LowLevelAllocator *allocator) {
402402 const char *path = common_flags()->external_symbolizer_path;
403
404 if (path && internal_strchr(path, '%')) {
405 char *new_path = (char *)InternalAlloc(kMaxPathLength);
406 SubstituteForFlagValue(path, new_path, kMaxPathLength);
407 path = new_path;
408 }
409
403410 const char *binary_name = path ? StripModuleName(path) : "";
411 static const char kLLVMSymbolizerPrefix[] = "llvm-symbolizer";
404412 if (path && path[0] == '\0') {
405413 VReport(2, "External symbolizer is explicitly disabled.\n");
406414 return nullptr;
407 } else if (!internal_strcmp(binary_name, "llvm-symbolizer")) {
415 } else if (!internal_strncmp(binary_name, kLLVMSymbolizerPrefix,
416 internal_strlen(kLLVMSymbolizerPrefix))) {
408417 VReport(2, "Using llvm-symbolizer at user-specified path: %s\n", path);
409418 return new(*allocator) LLVMSymbolizer(path, allocator);
410419 } else if (!internal_strcmp(binary_name, "atos")) {
lib/tsan/sanitizer_common/sanitizer_symbolizer_report.cpp+17-18
......@@ -31,9 +31,10 @@ namespace __sanitizer {
3131void ReportErrorSummary(const char *error_type, const AddressInfo &info,
3232 const char *alt_tool_name) {
3333 if (!common_flags()->print_summary) return;
34 InternalScopedString buff(kMaxSummaryLength);
34 InternalScopedString buff;
3535 buff.append("%s ", error_type);
36 RenderFrame(&buff, "%L %F", 0, info, common_flags()->symbolize_vs_style,
36 RenderFrame(&buff, "%L %F", 0, info.address, &info,
37 common_flags()->symbolize_vs_style,
3738 common_flags()->strip_path_prefix);
3839 ReportErrorSummary(buff.data(), alt_tool_name);
3940}
......@@ -47,14 +48,14 @@ bool ReportFile::SupportsColors() {
4748 return SupportsColoredOutput(fd);
4849}
4950
50static INLINE bool ReportSupportsColors() {
51static inline bool ReportSupportsColors() {
5152 return report_file.SupportsColors();
5253}
5354
5455#else // SANITIZER_FUCHSIA
5556
5657// Fuchsia's logs always go through post-processing that handles colorization.
57static INLINE bool ReportSupportsColors() { return true; }
58static inline bool ReportSupportsColors() { return true; }
5859
5960#endif // !SANITIZER_FUCHSIA
6061
......@@ -119,7 +120,7 @@ void ReportMmapWriteExec(int prot) {
119120#endif
120121}
121122
122#if !SANITIZER_FUCHSIA && !SANITIZER_RTEMS && !SANITIZER_GO
123#if !SANITIZER_FUCHSIA && !SANITIZER_GO
123124void StartReportDeadlySignal() {
124125 // Write the first message using fd=2, just in case.
125126 // It may actually fail to write in case stderr is closed.
......@@ -149,7 +150,7 @@ static void PrintMemoryByte(InternalScopedString *str, const char *before,
149150static void MaybeDumpInstructionBytes(uptr pc) {
150151 if (!common_flags()->dump_instruction_bytes || (pc < GetPageSizeCached()))
151152 return;
152 InternalScopedString str(1024);
153 InternalScopedString str;
153154 str.append("First 16 instruction bytes at pc: ");
154155 if (IsAccessibleMemoryRange(pc, 16)) {
155156 for (int i = 0; i < 16; ++i) {
......@@ -210,7 +211,7 @@ static void ReportDeadlySignalImpl(const SignalContext &sig, u32 tid,
210211 Report("The signal is caused by a %s memory access.\n", access_type);
211212 if (!sig.is_true_faulting_addr)
212213 Report("Hint: this fault was caused by a dereference of a high value "
213 "address (see register values below). Dissassemble the provided "
214 "address (see register values below). Disassemble the provided "
214215 "pc to learn which register was used.\n");
215216 else if (sig.addr < GetPageSizeCached())
216217 Report("Hint: address points to the zero page.\n");
......@@ -249,17 +250,17 @@ void HandleDeadlySignal(void *siginfo, void *context, u32 tid,
249250
250251#endif // !SANITIZER_FUCHSIA && !SANITIZER_GO
251252
252static atomic_uintptr_t reporting_thread = {0};
253static StaticSpinMutex CommonSanitizerReportMutex;
253atomic_uintptr_t ScopedErrorReportLock::reporting_thread_ = {0};
254StaticSpinMutex ScopedErrorReportLock::mutex_;
254255
255ScopedErrorReportLock::ScopedErrorReportLock() {
256void ScopedErrorReportLock::Lock() {
256257 uptr current = GetThreadSelf();
257258 for (;;) {
258259 uptr expected = 0;
259 if (atomic_compare_exchange_strong(&reporting_thread, &expected, current,
260 if (atomic_compare_exchange_strong(&reporting_thread_, &expected, current,
260261 memory_order_relaxed)) {
261262 // We've claimed reporting_thread so proceed.
262 CommonSanitizerReportMutex.Lock();
263 mutex_.Lock();
263264 return;
264265 }
265266
......@@ -281,13 +282,11 @@ ScopedErrorReportLock::ScopedErrorReportLock() {
281282 }
282283}
283284
284ScopedErrorReportLock::~ScopedErrorReportLock() {
285 CommonSanitizerReportMutex.Unlock();
286 atomic_store_relaxed(&reporting_thread, 0);
285void ScopedErrorReportLock::Unlock() {
286 mutex_.Unlock();
287 atomic_store_relaxed(&reporting_thread_, 0);
287288}
288289
289void ScopedErrorReportLock::CheckLocked() {
290 CommonSanitizerReportMutex.CheckLocked();
291}
290void ScopedErrorReportLock::CheckLocked() { mutex_.CheckLocked(); }
292291
293292} // namespace __sanitizer
lib/tsan/sanitizer_common/sanitizer_symbolizer_rtems.h deleted-40
......@@ -1,40 +0,0 @@
1//===-- sanitizer_symbolizer_rtems.h -----------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file is shared between various sanitizers' runtime libraries.
10//
11// Define RTEMS's string formats and limits for the markup symbolizer.
12//===----------------------------------------------------------------------===//
13#ifndef SANITIZER_SYMBOLIZER_RTEMS_H
14#define SANITIZER_SYMBOLIZER_RTEMS_H
15
16#include "sanitizer_internal_defs.h"
17
18namespace __sanitizer {
19
20// The Myriad RTEMS symbolizer currently only parses backtrace lines,
21// so use a format that the symbolizer understands. For other
22// markups, keep them the same as the Fuchsia's.
23
24// This is used by UBSan for type names, and by ASan for global variable names.
25constexpr const char *kFormatDemangle = "{{{symbol:%s}}}";
26constexpr uptr kFormatDemangleMax = 1024; // Arbitrary.
27
28// Function name or equivalent from PC location.
29constexpr const char *kFormatFunction = "{{{pc:%p}}}";
30constexpr uptr kFormatFunctionMax = 64; // More than big enough for 64-bit hex.
31
32// Global variable name or equivalent from data memory address.
33constexpr const char *kFormatData = "{{{data:%p}}}";
34
35// One frame in a backtrace (printed on a line by itself).
36constexpr const char *kFormatFrame = " [%u] IP: %p";
37
38} // namespace __sanitizer
39
40#endif // SANITIZER_SYMBOLIZER_RTEMS_H
lib/tsan/sanitizer_common/sanitizer_symbolizer_win.cpp+14-6
......@@ -33,7 +33,7 @@ decltype(::UnDecorateSymbolName) *UnDecorateSymbolName;
3333
3434namespace {
3535
36class WinSymbolizerTool : public SymbolizerTool {
36class WinSymbolizerTool final : public SymbolizerTool {
3737 public:
3838 // The constructor is provided to avoid synthesized memsets.
3939 WinSymbolizerTool() {}
......@@ -136,9 +136,10 @@ void InitializeDbgHelpIfNeeded() {
136136bool WinSymbolizerTool::SymbolizePC(uptr addr, SymbolizedStack *frame) {
137137 InitializeDbgHelpIfNeeded();
138138
139 // See http://msdn.microsoft.com/en-us/library/ms680578(VS.85).aspx
140 char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(CHAR)];
141 PSYMBOL_INFO symbol = (PSYMBOL_INFO)buffer;
139 // See https://docs.microsoft.com/en-us/windows/win32/debug/retrieving-symbol-information-by-address
140 InternalMmapVector<char> buffer(sizeof(SYMBOL_INFO) +
141 MAX_SYM_NAME * sizeof(CHAR));
142 PSYMBOL_INFO symbol = (PSYMBOL_INFO)&buffer[0];
142143 symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
143144 symbol->MaxNameLen = MAX_SYM_NAME;
144145 DWORD64 offset = 0;
......@@ -223,7 +224,7 @@ bool SymbolizerProcess::StartSymbolizerSubprocess() {
223224 // Compute the command line. Wrap double quotes around everything.
224225 const char *argv[kArgVMax];
225226 GetArgV(path_, argv);
226 InternalScopedString command_line(kMaxPathLength * 3);
227 InternalScopedString command_line;
227228 for (int i = 0; argv[i]; i++) {
228229 const char *arg = argv[i];
229230 int arglen = internal_strlen(arg);
......@@ -281,8 +282,15 @@ static void ChooseSymbolizerTools(IntrusiveList<SymbolizerTool> *list,
281282 return;
282283 }
283284
284 // Add llvm-symbolizer in case the binary has dwarf.
285 // Add llvm-symbolizer.
285286 const char *user_path = common_flags()->external_symbolizer_path;
287
288 if (user_path && internal_strchr(user_path, '%')) {
289 char *new_path = (char *)InternalAlloc(kMaxPathLength);
290 SubstituteForFlagValue(user_path, new_path, kMaxPathLength);
291 user_path = new_path;
292 }
293
286294 const char *path =
287295 user_path ? user_path : FindPathToBinary("llvm-symbolizer.exe");
288296 if (path) {
lib/tsan/sanitizer_common/sanitizer_syscall_generic.inc+1-1
......@@ -13,7 +13,7 @@
1313// NetBSD uses libc calls directly
1414#if !SANITIZER_NETBSD
1515
16#if SANITIZER_FREEBSD || SANITIZER_MAC || SANITIZER_OPENBSD || SANITIZER_SOLARIS
16#if SANITIZER_FREEBSD || SANITIZER_MAC || SANITIZER_SOLARIS
1717# define SYSCALL(name) SYS_ ## name
1818#else
1919# define SYSCALL(name) __NR_ ## name
lib/tsan/sanitizer_common/sanitizer_syscalls_netbsd.inc+113-6
......@@ -42,8 +42,8 @@
4242// DO NOT EDIT! THIS FILE HAS BEEN GENERATED!
4343//
4444// Generated with: generate_netbsd_syscalls.awk
45// Generated date: 2019-12-24
46// Generated from: syscalls.master,v 1.296 2019/09/22 22:59:39 christos Exp
45// Generated date: 2020-09-10
46// Generated from: syscalls.master,v 1.306 2020/08/14 00:53:16 riastradh Exp
4747//
4848//===----------------------------------------------------------------------===//
4949
......@@ -872,7 +872,13 @@ PRE_SYSCALL(dup2)(long long from_, long long to_) { /* Nothing to do */ }
872872POST_SYSCALL(dup2)(long long res, long long from_, long long to_) {
873873 /* Nothing to do */
874874}
875/* syscall 91 has been skipped */
875PRE_SYSCALL(getrandom)(void *buf_, long long buflen_, long long flags_) {
876 /* TODO */
877}
878POST_SYSCALL(getrandom)
879(long long res, void *buf_, long long buflen_, long long flags_) {
880 /* TODO */
881}
876882PRE_SYSCALL(fcntl)(long long fd_, long long cmd_, void *arg_) {
877883 /* Nothing to do */
878884}
......@@ -1332,9 +1338,29 @@ PRE_SYSCALL(compat_09_ouname)(void *name_) { /* TODO */ }
13321338POST_SYSCALL(compat_09_ouname)(long long res, void *name_) { /* TODO */ }
13331339PRE_SYSCALL(sysarch)(long long op_, void *parms_) { /* TODO */ }
13341340POST_SYSCALL(sysarch)(long long res, long long op_, void *parms_) { /* TODO */ }
1335/* syscall 166 has been skipped */
1336/* syscall 167 has been skipped */
1337/* syscall 168 has been skipped */
1341PRE_SYSCALL(__futex)
1342(void *uaddr_, long long op_, long long val_, void *timeout_, void *uaddr2_,
1343 long long val2_, long long val3_) {
1344 /* TODO */
1345}
1346POST_SYSCALL(__futex)
1347(long long res, void *uaddr_, long long op_, long long val_, void *timeout_,
1348 void *uaddr2_, long long val2_, long long val3_) {
1349 /* TODO */
1350}
1351PRE_SYSCALL(__futex_set_robust_list)(void *head_, long long len_) { /* TODO */ }
1352POST_SYSCALL(__futex_set_robust_list)
1353(long long res, void *head_, long long len_) {
1354 /* TODO */
1355}
1356PRE_SYSCALL(__futex_get_robust_list)
1357(long long lwpid_, void **headp_, void *lenp_) {
1358 /* TODO */
1359}
1360POST_SYSCALL(__futex_get_robust_list)
1361(long long res, long long lwpid_, void **headp_, void *lenp_) {
1362 /* TODO */
1363}
13381364#if !defined(_LP64)
13391365PRE_SYSCALL(compat_10_osemsys)
13401366(long long which_, long long a2_, long long a3_, long long a4_, long long a5_) {
......@@ -3824,6 +3850,87 @@ PRE_SYSCALL(__fhstatvfs190)
38243850}
38253851POST_SYSCALL(__fhstatvfs190)
38263852(long long res, void *fhp_, long long fh_size_, void *buf_, long long flags_) {}
3853PRE_SYSCALL(__acl_get_link)(void *path_, long long type_, void *aclp_) {
3854 /* TODO */
3855}
3856POST_SYSCALL(__acl_get_link)
3857(long long res, void *path_, long long type_, void *aclp_) {
3858 /* TODO */
3859}
3860PRE_SYSCALL(__acl_set_link)(void *path_, long long type_, void *aclp_) {
3861 /* TODO */
3862}
3863POST_SYSCALL(__acl_set_link)
3864(long long res, void *path_, long long type_, void *aclp_) {
3865 /* TODO */
3866}
3867PRE_SYSCALL(__acl_delete_link)(void *path_, long long type_) { /* TODO */ }
3868POST_SYSCALL(__acl_delete_link)(long long res, void *path_, long long type_) {
3869 /* TODO */
3870}
3871PRE_SYSCALL(__acl_aclcheck_link)(void *path_, long long type_, void *aclp_) {
3872 /* TODO */
3873}
3874POST_SYSCALL(__acl_aclcheck_link)
3875(long long res, void *path_, long long type_, void *aclp_) {
3876 /* TODO */
3877}
3878PRE_SYSCALL(__acl_get_file)(void *path_, long long type_, void *aclp_) {
3879 /* TODO */
3880}
3881POST_SYSCALL(__acl_get_file)
3882(long long res, void *path_, long long type_, void *aclp_) {
3883 /* TODO */
3884}
3885PRE_SYSCALL(__acl_set_file)(void *path_, long long type_, void *aclp_) {
3886 /* TODO */
3887}
3888POST_SYSCALL(__acl_set_file)
3889(long long res, void *path_, long long type_, void *aclp_) {
3890 /* TODO */
3891}
3892PRE_SYSCALL(__acl_get_fd)(long long filedes_, long long type_, void *aclp_) {
3893 /* TODO */
3894}
3895POST_SYSCALL(__acl_get_fd)
3896(long long res, long long filedes_, long long type_, void *aclp_) {
3897 /* TODO */
3898}
3899PRE_SYSCALL(__acl_set_fd)(long long filedes_, long long type_, void *aclp_) {
3900 /* TODO */
3901}
3902POST_SYSCALL(__acl_set_fd)
3903(long long res, long long filedes_, long long type_, void *aclp_) {
3904 /* TODO */
3905}
3906PRE_SYSCALL(__acl_delete_file)(void *path_, long long type_) { /* TODO */ }
3907POST_SYSCALL(__acl_delete_file)(long long res, void *path_, long long type_) {
3908 /* TODO */
3909}
3910PRE_SYSCALL(__acl_delete_fd)(long long filedes_, long long type_) { /* TODO */ }
3911POST_SYSCALL(__acl_delete_fd)
3912(long long res, long long filedes_, long long type_) {
3913 /* TODO */
3914}
3915PRE_SYSCALL(__acl_aclcheck_file)(void *path_, long long type_, void *aclp_) {
3916 /* TODO */
3917}
3918POST_SYSCALL(__acl_aclcheck_file)
3919(long long res, void *path_, long long type_, void *aclp_) {
3920 /* TODO */
3921}
3922PRE_SYSCALL(__acl_aclcheck_fd)
3923(long long filedes_, long long type_, void *aclp_) {
3924 /* TODO */
3925}
3926POST_SYSCALL(__acl_aclcheck_fd)
3927(long long res, long long filedes_, long long type_, void *aclp_) {
3928 /* TODO */
3929}
3930PRE_SYSCALL(lpathconf)(void *path_, long long name_) { /* TODO */ }
3931POST_SYSCALL(lpathconf)(long long res, void *path_, long long name_) {
3932 /* TODO */
3933}
38273934#undef SYS_MAXSYSARGS
38283935} // extern "C"
38293936
lib/tsan/sanitizer_common/sanitizer_termination.cpp+19-14
......@@ -59,26 +59,31 @@ void NORETURN Die() {
5959 internal__exit(common_flags()->exitcode);
6060}
6161
62static CheckFailedCallbackType CheckFailedCallback;
63void SetCheckFailedCallback(CheckFailedCallbackType callback) {
64 CheckFailedCallback = callback;
62static void (*CheckUnwindCallback)();
63void SetCheckUnwindCallback(void (*callback)()) {
64 CheckUnwindCallback = callback;
6565}
6666
67const int kSecondsToSleepWhenRecursiveCheckFailed = 2;
68
6967void NORETURN CheckFailed(const char *file, int line, const char *cond,
7068 u64 v1, u64 v2) {
71 static atomic_uint32_t num_calls;
72 if (atomic_fetch_add(&num_calls, 1, memory_order_relaxed) > 10) {
73 SleepForSeconds(kSecondsToSleepWhenRecursiveCheckFailed);
69 u32 tid = GetTid();
70 Printf("%s: CHECK failed: %s:%d \"%s\" (0x%zx, 0x%zx) (tid=%u)\n",
71 SanitizerToolName, StripModuleName(file), line, cond, (uptr)v1,
72 (uptr)v2, tid);
73 static atomic_uint32_t first_tid;
74 u32 cmp = 0;
75 if (!atomic_compare_exchange_strong(&first_tid, &cmp, tid,
76 memory_order_relaxed)) {
77 if (cmp == tid) {
78 // Recursing into CheckFailed.
79 } else {
80 // Another thread fails already, let it print the stack and terminate.
81 SleepForSeconds(2);
82 }
7483 Trap();
7584 }
76
77 if (CheckFailedCallback) {
78 CheckFailedCallback(file, line, cond, v1, v2);
79 }
80 Report("Sanitizer CHECK failed: %s:%d %s (%lld, %lld)\n", file, line, cond,
81 v1, v2);
85 if (CheckUnwindCallback)
86 CheckUnwindCallback();
8287 Die();
8388}
8489
lib/tsan/sanitizer_common/sanitizer_thread_registry.cpp+18-23
......@@ -85,7 +85,7 @@ void ThreadContextBase::SetCreated(uptr _user_id, u64 _unique_id,
8585 unique_id = _unique_id;
8686 detached = _detached;
8787 // Parent tid makes no sense for the main thread.
88 if (tid != 0)
88 if (tid != kMainTid)
8989 parent_tid = _parent_tid;
9090 OnCreated(arg);
9191}
......@@ -99,7 +99,8 @@ void ThreadContextBase::Reset() {
9999
100100// ThreadRegistry implementation.
101101
102const u32 ThreadRegistry::kUnknownTid = ~0U;
102ThreadRegistry::ThreadRegistry(ThreadContextFactory factory)
103 : ThreadRegistry(factory, UINT32_MAX, UINT32_MAX, 0) {}
103104
104105ThreadRegistry::ThreadRegistry(ThreadContextFactory factory, u32 max_threads,
105106 u32 thread_quarantine_size, u32 max_reuse)
......@@ -108,13 +109,10 @@ ThreadRegistry::ThreadRegistry(ThreadContextFactory factory, u32 max_threads,
108109 thread_quarantine_size_(thread_quarantine_size),
109110 max_reuse_(max_reuse),
110111 mtx_(),
111 n_contexts_(0),
112112 total_threads_(0),
113113 alive_threads_(0),
114114 max_alive_threads_(0),
115115 running_threads_(0) {
116 threads_ = (ThreadContextBase **)MmapOrDie(max_threads_ * sizeof(threads_[0]),
117 "ThreadRegistry");
118116 dead_threads_.clear();
119117 invalid_threads_.clear();
120118}
......@@ -122,7 +120,8 @@ ThreadRegistry::ThreadRegistry(ThreadContextFactory factory, u32 max_threads,
122120void ThreadRegistry::GetNumberOfThreads(uptr *total, uptr *running,
123121 uptr *alive) {
124122 BlockingMutexLock l(&mtx_);
125 if (total) *total = n_contexts_;
123 if (total)
124 *total = threads_.size();
126125 if (running) *running = running_threads_;
127126 if (alive) *alive = alive_threads_;
128127}
......@@ -135,15 +134,15 @@ uptr ThreadRegistry::GetMaxAliveThreads() {
135134u32 ThreadRegistry::CreateThread(uptr user_id, bool detached, u32 parent_tid,
136135 void *arg) {
137136 BlockingMutexLock l(&mtx_);
138 u32 tid = kUnknownTid;
137 u32 tid = kInvalidTid;
139138 ThreadContextBase *tctx = QuarantinePop();
140139 if (tctx) {
141140 tid = tctx->tid;
142 } else if (n_contexts_ < max_threads_) {
141 } else if (threads_.size() < max_threads_) {
143142 // Allocate new thread context and tid.
144 tid = n_contexts_++;
143 tid = threads_.size();
145144 tctx = context_factory_(tid);
146 threads_[tid] = tctx;
145 threads_.push_back(tctx);
147146 } else {
148147#if !SANITIZER_GO
149148 Report("%s: Thread limit (%u threads) exceeded. Dying.\n",
......@@ -155,7 +154,7 @@ u32 ThreadRegistry::CreateThread(uptr user_id, bool detached, u32 parent_tid,
155154 Die();
156155 }
157156 CHECK_NE(tctx, 0);
158 CHECK_NE(tid, kUnknownTid);
157 CHECK_NE(tid, kInvalidTid);
159158 CHECK_LT(tid, max_threads_);
160159 CHECK_EQ(tctx->status, ThreadStatusInvalid);
161160 alive_threads_++;
......@@ -171,7 +170,7 @@ u32 ThreadRegistry::CreateThread(uptr user_id, bool detached, u32 parent_tid,
171170void ThreadRegistry::RunCallbackForEachThreadLocked(ThreadCallback cb,
172171 void *arg) {
173172 CheckLocked();
174 for (u32 tid = 0; tid < n_contexts_; tid++) {
173 for (u32 tid = 0; tid < threads_.size(); tid++) {
175174 ThreadContextBase *tctx = threads_[tid];
176175 if (tctx == 0)
177176 continue;
......@@ -181,18 +180,18 @@ void ThreadRegistry::RunCallbackForEachThreadLocked(ThreadCallback cb,
181180
182181u32 ThreadRegistry::FindThread(FindThreadCallback cb, void *arg) {
183182 BlockingMutexLock l(&mtx_);
184 for (u32 tid = 0; tid < n_contexts_; tid++) {
183 for (u32 tid = 0; tid < threads_.size(); tid++) {
185184 ThreadContextBase *tctx = threads_[tid];
186185 if (tctx != 0 && cb(tctx, arg))
187186 return tctx->tid;
188187 }
189 return kUnknownTid;
188 return kInvalidTid;
190189}
191190
192191ThreadContextBase *
193192ThreadRegistry::FindThreadContextLocked(FindThreadCallback cb, void *arg) {
194193 CheckLocked();
195 for (u32 tid = 0; tid < n_contexts_; tid++) {
194 for (u32 tid = 0; tid < threads_.size(); tid++) {
196195 ThreadContextBase *tctx = threads_[tid];
197196 if (tctx != 0 && cb(tctx, arg))
198197 return tctx;
......@@ -213,7 +212,6 @@ ThreadContextBase *ThreadRegistry::FindThreadContextByOsIDLocked(tid_t os_id) {
213212
214213void ThreadRegistry::SetThreadName(u32 tid, const char *name) {
215214 BlockingMutexLock l(&mtx_);
216 CHECK_LT(tid, n_contexts_);
217215 ThreadContextBase *tctx = threads_[tid];
218216 CHECK_NE(tctx, 0);
219217 CHECK_EQ(SANITIZER_FUCHSIA ? ThreadStatusCreated : ThreadStatusRunning,
......@@ -223,7 +221,7 @@ void ThreadRegistry::SetThreadName(u32 tid, const char *name) {
223221
224222void ThreadRegistry::SetThreadNameByUserId(uptr user_id, const char *name) {
225223 BlockingMutexLock l(&mtx_);
226 for (u32 tid = 0; tid < n_contexts_; tid++) {
224 for (u32 tid = 0; tid < threads_.size(); tid++) {
227225 ThreadContextBase *tctx = threads_[tid];
228226 if (tctx != 0 && tctx->user_id == user_id &&
229227 tctx->status != ThreadStatusInvalid) {
......@@ -235,7 +233,6 @@ void ThreadRegistry::SetThreadNameByUserId(uptr user_id, const char *name) {
235233
236234void ThreadRegistry::DetachThread(u32 tid, void *arg) {
237235 BlockingMutexLock l(&mtx_);
238 CHECK_LT(tid, n_contexts_);
239236 ThreadContextBase *tctx = threads_[tid];
240237 CHECK_NE(tctx, 0);
241238 if (tctx->status == ThreadStatusInvalid) {
......@@ -256,7 +253,6 @@ void ThreadRegistry::JoinThread(u32 tid, void *arg) {
256253 do {
257254 {
258255 BlockingMutexLock l(&mtx_);
259 CHECK_LT(tid, n_contexts_);
260256 ThreadContextBase *tctx = threads_[tid];
261257 CHECK_NE(tctx, 0);
262258 if (tctx->status == ThreadStatusInvalid) {
......@@ -278,14 +274,14 @@ void ThreadRegistry::JoinThread(u32 tid, void *arg) {
278274// really started. We just did CreateThread for a prospective new
279275// thread before trying to create it, and then failed to actually
280276// create it, and so never called StartThread.
281void ThreadRegistry::FinishThread(u32 tid) {
277ThreadStatus ThreadRegistry::FinishThread(u32 tid) {
282278 BlockingMutexLock l(&mtx_);
283279 CHECK_GT(alive_threads_, 0);
284280 alive_threads_--;
285 CHECK_LT(tid, n_contexts_);
286281 ThreadContextBase *tctx = threads_[tid];
287282 CHECK_NE(tctx, 0);
288283 bool dead = tctx->detached;
284 ThreadStatus prev_status = tctx->status;
289285 if (tctx->status == ThreadStatusRunning) {
290286 CHECK_GT(running_threads_, 0);
291287 running_threads_--;
......@@ -300,13 +296,13 @@ void ThreadRegistry::FinishThread(u32 tid) {
300296 QuarantinePush(tctx);
301297 }
302298 tctx->SetDestroyed();
299 return prev_status;
303300}
304301
305302void ThreadRegistry::StartThread(u32 tid, tid_t os_id, ThreadType thread_type,
306303 void *arg) {
307304 BlockingMutexLock l(&mtx_);
308305 running_threads_++;
309 CHECK_LT(tid, n_contexts_);
310306 ThreadContextBase *tctx = threads_[tid];
311307 CHECK_NE(tctx, 0);
312308 CHECK_EQ(ThreadStatusCreated, tctx->status);
......@@ -339,7 +335,6 @@ ThreadContextBase *ThreadRegistry::QuarantinePop() {
339335
340336void ThreadRegistry::SetThreadUserId(u32 tid, uptr user_id) {
341337 BlockingMutexLock l(&mtx_);
342 CHECK_LT(tid, n_contexts_);
343338 ThreadContextBase *tctx = threads_[tid];
344339 CHECK_NE(tctx, 0);
345340 CHECK_NE(tctx->status, ThreadStatusInvalid);
lib/tsan/sanitizer_common/sanitizer_thread_registry.h+14-16
......@@ -39,8 +39,6 @@ enum class ThreadType {
3939class ThreadContextBase {
4040 public:
4141 explicit ThreadContextBase(u32 tid);
42 ~ThreadContextBase(); // Should never be called.
43
4442 const u32 tid; // Thread ID. Main thread should have tid = 0.
4543 u64 unique_id; // Unique thread ID.
4644 u32 reuse_count; // Number of times this tid was reused.
......@@ -80,28 +78,29 @@ class ThreadContextBase {
8078 virtual void OnCreated(void *arg) {}
8179 virtual void OnReset() {}
8280 virtual void OnDetached(void *arg) {}
81
82 protected:
83 ~ThreadContextBase();
8384};
8485
8586typedef ThreadContextBase* (*ThreadContextFactory)(u32 tid);
8687
87class ThreadRegistry {
88class MUTEX ThreadRegistry {
8889 public:
89 static const u32 kUnknownTid;
90
90 ThreadRegistry(ThreadContextFactory factory);
9191 ThreadRegistry(ThreadContextFactory factory, u32 max_threads,
92 u32 thread_quarantine_size, u32 max_reuse = 0);
92 u32 thread_quarantine_size, u32 max_reuse);
9393 void GetNumberOfThreads(uptr *total = nullptr, uptr *running = nullptr,
9494 uptr *alive = nullptr);
9595 uptr GetMaxAliveThreads();
9696
97 void Lock() { mtx_.Lock(); }
98 void CheckLocked() { mtx_.CheckLocked(); }
99 void Unlock() { mtx_.Unlock(); }
97 void Lock() ACQUIRE() { mtx_.Lock(); }
98 void CheckLocked() const CHECK_LOCKED() { mtx_.CheckLocked(); }
99 void Unlock() RELEASE() { mtx_.Unlock(); }
100100
101101 // Should be guarded by ThreadRegistryLock.
102102 ThreadContextBase *GetThreadLocked(u32 tid) {
103 DCHECK_LT(tid, n_contexts_);
104 return threads_[tid];
103 return threads_.empty() ? nullptr : threads_[tid];
105104 }
106105
107106 u32 CreateThread(uptr user_id, bool detached, u32 parent_tid, void *arg);
......@@ -112,7 +111,7 @@ class ThreadRegistry {
112111 void RunCallbackForEachThreadLocked(ThreadCallback cb, void *arg);
113112
114113 typedef bool (*FindThreadCallback)(ThreadContextBase *tctx, void *arg);
115 // Finds a thread using the provided callback. Returns kUnknownTid if no
114 // Finds a thread using the provided callback. Returns kInvalidTid if no
116115 // thread is found.
117116 u32 FindThread(FindThreadCallback cb, void *arg);
118117 // Should be guarded by ThreadRegistryLock. Return 0 if no thread
......@@ -125,7 +124,8 @@ class ThreadRegistry {
125124 void SetThreadNameByUserId(uptr user_id, const char *name);
126125 void DetachThread(u32 tid, void *arg);
127126 void JoinThread(u32 tid, void *arg);
128 void FinishThread(u32 tid);
127 // Finishes thread and returns previous status.
128 ThreadStatus FinishThread(u32 tid);
129129 void StartThread(u32 tid, tid_t os_id, ThreadType thread_type, void *arg);
130130 void SetThreadUserId(u32 tid, uptr user_id);
131131
......@@ -137,15 +137,13 @@ class ThreadRegistry {
137137
138138 BlockingMutex mtx_;
139139
140 u32 n_contexts_; // Number of created thread contexts,
141 // at most max_threads_.
142140 u64 total_threads_; // Total number of created threads. May be greater than
143141 // max_threads_ if contexts were reused.
144142 uptr alive_threads_; // Created or running.
145143 uptr max_alive_threads_;
146144 uptr running_threads_;
147145
148 ThreadContextBase **threads_; // Array of thread contexts is leaked.
146 InternalMmapVector<ThreadContextBase *> threads_;
149147 IntrusiveList<ThreadContextBase> dead_threads_;
150148 IntrusiveList<ThreadContextBase> invalid_threads_;
151149
lib/tsan/sanitizer_common/sanitizer_thread_safety.h created+42
......@@ -0,0 +1,42 @@
1//===-- sanitizer_thread_safety.h -------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file is shared between sanitizer tools.
10//
11// Wrappers around thread safety annotations.
12// https://clang.llvm.org/docs/ThreadSafetyAnalysis.html
13//===----------------------------------------------------------------------===//
14
15#ifndef SANITIZER_THREAD_SAFETY_H
16#define SANITIZER_THREAD_SAFETY_H
17
18#if defined(__clang__)
19# define THREAD_ANNOTATION(x) __attribute__((x))
20#else
21# define THREAD_ANNOTATION(x)
22#endif
23
24#define MUTEX THREAD_ANNOTATION(capability("mutex"))
25#define SCOPED_LOCK THREAD_ANNOTATION(scoped_lockable)
26#define GUARDED_BY(x) THREAD_ANNOTATION(guarded_by(x))
27#define PT_GUARDED_BY(x) THREAD_ANNOTATION(pt_guarded_by(x))
28#define REQUIRES(...) THREAD_ANNOTATION(requires_capability(__VA_ARGS__))
29#define REQUIRES_SHARED(...) \
30 THREAD_ANNOTATION(requires_shared_capability(__VA_ARGS__))
31#define ACQUIRE(...) THREAD_ANNOTATION(acquire_capability(__VA_ARGS__))
32#define ACQUIRE_SHARED(...) \
33 THREAD_ANNOTATION(acquire_shared_capability(__VA_ARGS__))
34#define TRY_ACQUIRE(...) THREAD_ANNOTATION(try_acquire_capability(__VA_ARGS__))
35#define RELEASE(...) THREAD_ANNOTATION(release_capability(__VA_ARGS__))
36#define RELEASE_SHARED(...) \
37 THREAD_ANNOTATION(release_shared_capability(__VA_ARGS__))
38#define EXCLUDES(...) THREAD_ANNOTATION(locks_excluded(__VA_ARGS__))
39#define CHECK_LOCKED(...) THREAD_ANNOTATION(assert_capability(__VA_ARGS__))
40#define NO_THREAD_SAFETY_ANALYSIS THREAD_ANNOTATION(no_thread_safety_analysis)
41
42#endif
lib/tsan/sanitizer_common/sanitizer_tls_get_addr.cpp+54-32
......@@ -12,6 +12,7 @@
1212
1313#include "sanitizer_tls_get_addr.h"
1414
15#include "sanitizer_atomic.h"
1516#include "sanitizer_flags.h"
1617#include "sanitizer_platform_interceptors.h"
1718
......@@ -42,46 +43,66 @@ static atomic_uintptr_t number_of_live_dtls;
4243
4344static const uptr kDestroyedThread = -1;
4445
45static inline void DTLS_Deallocate(DTLS::DTV *dtv, uptr size) {
46 if (!size) return;
47 VReport(2, "__tls_get_addr: DTLS_Deallocate %p %zd\n", dtv, size);
48 UnmapOrDie(dtv, size * sizeof(DTLS::DTV));
46static void DTLS_Deallocate(DTLS::DTVBlock *block) {
47 VReport(2, "__tls_get_addr: DTLS_Deallocate %p %zd\n", block);
48 UnmapOrDie(block, sizeof(DTLS::DTVBlock));
4949 atomic_fetch_sub(&number_of_live_dtls, 1, memory_order_relaxed);
5050}
5151
52static inline void DTLS_Resize(uptr new_size) {
53 if (dtls.dtv_size >= new_size) return;
54 new_size = RoundUpToPowerOfTwo(new_size);
55 new_size = Max(new_size, 4096UL / sizeof(DTLS::DTV));
56 DTLS::DTV *new_dtv =
57 (DTLS::DTV *)MmapOrDie(new_size * sizeof(DTLS::DTV), "DTLS_Resize");
52static DTLS::DTVBlock *DTLS_NextBlock(atomic_uintptr_t *cur) {
53 uptr v = atomic_load(cur, memory_order_acquire);
54 if (v == kDestroyedThread)
55 return nullptr;
56 DTLS::DTVBlock *next = (DTLS::DTVBlock *)v;
57 if (next)
58 return next;
59 DTLS::DTVBlock *new_dtv =
60 (DTLS::DTVBlock *)MmapOrDie(sizeof(DTLS::DTVBlock), "DTLS_NextBlock");
61 uptr prev = 0;
62 if (!atomic_compare_exchange_strong(cur, &prev, (uptr)new_dtv,
63 memory_order_seq_cst)) {
64 UnmapOrDie(new_dtv, sizeof(DTLS::DTVBlock));
65 return (DTLS::DTVBlock *)prev;
66 }
5867 uptr num_live_dtls =
5968 atomic_fetch_add(&number_of_live_dtls, 1, memory_order_relaxed);
60 VReport(2, "__tls_get_addr: DTLS_Resize %p %zd\n", &dtls, num_live_dtls);
61 CHECK_LT(num_live_dtls, 1 << 20);
62 uptr old_dtv_size = dtls.dtv_size;
63 DTLS::DTV *old_dtv = dtls.dtv;
64 if (old_dtv_size)
65 internal_memcpy(new_dtv, dtls.dtv, dtls.dtv_size * sizeof(DTLS::DTV));
66 dtls.dtv = new_dtv;
67 dtls.dtv_size = new_size;
68 if (old_dtv_size)
69 DTLS_Deallocate(old_dtv, old_dtv_size);
69 VReport(2, "__tls_get_addr: DTLS_NextBlock %p %zd\n", &dtls, num_live_dtls);
70 return new_dtv;
71}
72
73static DTLS::DTV *DTLS_Find(uptr id) {
74 VReport(2, "__tls_get_addr: DTLS_Find %p %zd\n", &dtls, id);
75 static constexpr uptr kPerBlock = ARRAY_SIZE(DTLS::DTVBlock::dtvs);
76 DTLS::DTVBlock *cur = DTLS_NextBlock(&dtls.dtv_block);
77 if (!cur)
78 return nullptr;
79 for (; id >= kPerBlock; id -= kPerBlock) cur = DTLS_NextBlock(&cur->next);
80 return cur->dtvs + id;
7081}
7182
7283void DTLS_Destroy() {
7384 if (!common_flags()->intercept_tls_get_addr) return;
74 VReport(2, "__tls_get_addr: DTLS_Destroy %p %zd\n", &dtls, dtls.dtv_size);
75 uptr s = dtls.dtv_size;
76 dtls.dtv_size = kDestroyedThread; // Do this before unmap for AS-safety.
77 DTLS_Deallocate(dtls.dtv, s);
85 VReport(2, "__tls_get_addr: DTLS_Destroy %p\n", &dtls);
86 DTLS::DTVBlock *block = (DTLS::DTVBlock *)atomic_exchange(
87 &dtls.dtv_block, kDestroyedThread, memory_order_release);
88 while (block) {
89 DTLS::DTVBlock *next =
90 (DTLS::DTVBlock *)atomic_load(&block->next, memory_order_acquire);
91 DTLS_Deallocate(block);
92 block = next;
93 }
7894}
7995
8096#if defined(__powerpc64__) || defined(__mips__)
8197// This is glibc's TLS_DTV_OFFSET:
8298// "Dynamic thread vector pointers point 0x8000 past the start of each
83// TLS block."
99// TLS block." (sysdeps/<arch>/dl-tls.h)
84100static const uptr kDtvOffset = 0x8000;
101#elif defined(__riscv)
102// This is glibc's TLS_DTV_OFFSET:
103// "Dynamic thread vector pointers point 0x800 past the start of each
104// TLS block." (sysdeps/riscv/dl-tls.h)
105static const uptr kDtvOffset = 0x800;
85106#else
86107static const uptr kDtvOffset = 0;
87108#endif
......@@ -91,9 +112,9 @@ DTLS::DTV *DTLS_on_tls_get_addr(void *arg_void, void *res,
91112 if (!common_flags()->intercept_tls_get_addr) return 0;
92113 TlsGetAddrParam *arg = reinterpret_cast<TlsGetAddrParam *>(arg_void);
93114 uptr dso_id = arg->dso_id;
94 if (dtls.dtv_size == kDestroyedThread) return 0;
95 DTLS_Resize(dso_id + 1);
96 if (dtls.dtv[dso_id].beg) return 0;
115 DTLS::DTV *dtv = DTLS_Find(dso_id);
116 if (!dtv || dtv->beg)
117 return 0;
97118 uptr tls_size = 0;
98119 uptr tls_beg = reinterpret_cast<uptr>(res) - arg->offset - kDtvOffset;
99120 VReport(2, "__tls_get_addr: %p {%p,%p} => %p; tls_beg: %p; sp: %p "
......@@ -121,9 +142,9 @@ DTLS::DTV *DTLS_on_tls_get_addr(void *arg_void, void *res,
121142 // This may happen inside the DTOR of main thread, so just ignore it.
122143 tls_size = 0;
123144 }
124 dtls.dtv[dso_id].beg = tls_beg;
125 dtls.dtv[dso_id].size = tls_size;
126 return dtls.dtv + dso_id;
145 dtv->beg = tls_beg;
146 dtv->size = tls_size;
147 return dtv;
127148}
128149
129150void DTLS_on_libc_memalign(void *ptr, uptr size) {
......@@ -136,7 +157,8 @@ void DTLS_on_libc_memalign(void *ptr, uptr size) {
136157DTLS *DTLS_Get() { return &dtls; }
137158
138159bool DTLSInDestruction(DTLS *dtls) {
139 return dtls->dtv_size == kDestroyedThread;
160 return atomic_load(&dtls->dtv_block, memory_order_relaxed) ==
161 kDestroyedThread;
140162}
141163
142164#else
lib/tsan/sanitizer_common/sanitizer_tls_get_addr.h+19-2
......@@ -28,6 +28,7 @@
2828#ifndef SANITIZER_TLS_GET_ADDR_H
2929#define SANITIZER_TLS_GET_ADDR_H
3030
31#include "sanitizer_atomic.h"
3132#include "sanitizer_common.h"
3233
3334namespace __sanitizer {
......@@ -38,15 +39,31 @@ struct DTLS {
3839 struct DTV {
3940 uptr beg, size;
4041 };
42 struct DTVBlock {
43 atomic_uintptr_t next;
44 DTV dtvs[(4096UL - sizeof(next)) / sizeof(DTLS::DTV)];
45 };
46
47 static_assert(sizeof(DTVBlock) <= 4096UL, "Unexpected block size");
4148
42 uptr dtv_size;
43 DTV *dtv; // dtv_size elements, allocated by MmapOrDie.
49 atomic_uintptr_t dtv_block;
4450
4551 // Auxiliary fields, don't access them outside sanitizer_tls_get_addr.cpp
4652 uptr last_memalign_size;
4753 uptr last_memalign_ptr;
4854};
4955
56template <typename Fn>
57void ForEachDVT(DTLS *dtls, const Fn &fn) {
58 DTLS::DTVBlock *block =
59 (DTLS::DTVBlock *)atomic_load(&dtls->dtv_block, memory_order_acquire);
60 while (block) {
61 int id = 0;
62 for (auto &d : block->dtvs) fn(d, id++);
63 block = (DTLS::DTVBlock *)atomic_load(&block->next, memory_order_acquire);
64 }
65}
66
5067// Returns pointer and size of a linker-allocated TLS block.
5168// Each block is returned exactly once.
5269DTLS::DTV *DTLS_on_tls_get_addr(void *arg, void *res, uptr static_tls_begin,
lib/tsan/sanitizer_common/sanitizer_unwind_win.cpp+11
......@@ -37,8 +37,16 @@ void BufferedStackTrace::UnwindSlow(uptr pc, u32 max_depth) {
3737 // Skip the RTL frames by searching for the PC in the stacktrace.
3838 uptr pc_location = LocatePcInTrace(pc);
3939 PopStackFrames(pc_location);
40
41 // Replace the first frame with the PC because the frame in the
42 // stacktrace might be incorrect.
43 trace_buffer[0] = pc;
4044}
4145
46#ifdef __clang__
47#pragma clang diagnostic push
48#pragma clang diagnostic ignored "-Wframe-larger-than="
49#endif
4250void BufferedStackTrace::UnwindSlow(uptr pc, void *context, u32 max_depth) {
4351 CHECK(context);
4452 CHECK_GE(max_depth, 2);
......@@ -70,6 +78,9 @@ void BufferedStackTrace::UnwindSlow(uptr pc, void *context, u32 max_depth) {
7078 trace_buffer[size++] = (uptr)stack_frame.AddrPC.Offset;
7179 }
7280}
81#ifdef __clang__
82#pragma clang diagnostic pop
83#endif
7384#endif // #if !SANITIZER_GO
7485
7586#endif // SANITIZER_WINDOWS
lib/tsan/sanitizer_common/sanitizer_win.cpp+91-39
......@@ -44,6 +44,9 @@ TRACELOGGING_DEFINE_PROVIDER(g_asan_provider, "AddressSanitizerLoggingProvider",
4444#define TraceLoggingUnregister(x)
4545#endif
4646
47// For WaitOnAddress
48# pragma comment(lib, "synchronization.lib")
49
4750// A macro to tell the compiler that this part of the code cannot be reached,
4851// if the compiler supports this feature. Since we're using this in
4952// code that is called when terminating the process, the expansion of the
......@@ -334,8 +337,12 @@ bool MprotectNoAccess(uptr addr, uptr size) {
334337}
335338
336339void ReleaseMemoryPagesToOS(uptr beg, uptr end) {
337 // This is almost useless on 32-bits.
338 // FIXME: add madvise-analog when we move to 64-bits.
340 uptr beg_aligned = RoundDownTo(beg, GetPageSizeCached()),
341 end_aligned = RoundDownTo(end, GetPageSizeCached());
342 CHECK(beg < end); // make sure the region is sane
343 if (beg_aligned == end_aligned) // make sure we're freeing at least 1 page;
344 return;
345 UnmapOrDie((void *)beg, end_aligned - beg_aligned);
339346}
340347
341348void SetShadowRegionHugePageMode(uptr addr, uptr size) {
......@@ -348,6 +355,22 @@ bool DontDumpShadowMemory(uptr addr, uptr length) {
348355 return true;
349356}
350357
358uptr MapDynamicShadow(uptr shadow_size_bytes, uptr shadow_scale,
359 uptr min_shadow_base_alignment,
360 UNUSED uptr &high_mem_end) {
361 const uptr granularity = GetMmapGranularity();
362 const uptr alignment =
363 Max<uptr>(granularity << shadow_scale, 1ULL << min_shadow_base_alignment);
364 const uptr left_padding =
365 Max<uptr>(granularity, 1ULL << min_shadow_base_alignment);
366 uptr space_size = shadow_size_bytes + left_padding;
367 uptr shadow_start = FindAvailableMemoryRange(space_size, alignment,
368 granularity, nullptr, nullptr);
369 CHECK_NE((uptr)0, shadow_start);
370 CHECK(IsAligned(shadow_start, alignment));
371 return shadow_start;
372}
373
351374uptr FindAvailableMemoryRange(uptr size, uptr alignment, uptr left_padding,
352375 uptr *largest_gap_found,
353376 uptr *max_occupied_addr) {
......@@ -370,6 +393,12 @@ uptr FindAvailableMemoryRange(uptr size, uptr alignment, uptr left_padding,
370393 return 0;
371394}
372395
396uptr MapDynamicShadowAndAliases(uptr shadow_size, uptr alias_size,
397 uptr num_aliases, uptr ring_buffer_size) {
398 CHECK(false && "HWASan aliasing is unimplemented on Windows");
399 return 0;
400}
401
373402bool MemoryRangeIsAvailable(uptr range_start, uptr range_end) {
374403 MEMORY_BASIC_INFORMATION mbi;
375404 CHECK(VirtualQuery((void *)range_start, &mbi, sizeof(mbi)));
......@@ -475,8 +504,6 @@ void DumpProcessMap() {
475504}
476505#endif
477506
478void PrintModuleMap() { }
479
480507void DisableCoreDumperIfNecessary() {
481508 // Do nothing.
482509}
......@@ -517,13 +544,7 @@ bool IsAbsolutePath(const char *path) {
517544 IsPathSeparator(path[2]);
518545}
519546
520void SleepForSeconds(int seconds) {
521 Sleep(seconds * 1000);
522}
523
524void SleepForMillis(int millis) {
525 Sleep(millis);
526}
547void internal_usleep(u64 useconds) { Sleep(useconds / 1000); }
527548
528549u64 NanoTime() {
529550 static LARGE_INTEGER frequency = {};
......@@ -550,7 +571,7 @@ void Abort() {
550571// load the image at this address. Therefore, we call it the preferred base. Any
551572// addresses in the DWARF typically assume that the object has been loaded at
552573// this address.
553static uptr GetPreferredBase(const char *modname) {
574static uptr GetPreferredBase(const char *modname, char *buf, size_t buf_size) {
554575 fd_t fd = OpenFile(modname, RdOnly, nullptr);
555576 if (fd == kInvalidFd)
556577 return 0;
......@@ -572,12 +593,10 @@ static uptr GetPreferredBase(const char *modname) {
572593 // IMAGE_FILE_HEADER
573594 // IMAGE_OPTIONAL_HEADER
574595 // Seek to e_lfanew and read all that data.
575 char buf[4 + sizeof(IMAGE_FILE_HEADER) + sizeof(IMAGE_OPTIONAL_HEADER)];
576596 if (::SetFilePointer(fd, dos_header.e_lfanew, nullptr, FILE_BEGIN) ==
577597 INVALID_SET_FILE_POINTER)
578598 return 0;
579 if (!ReadFromFile(fd, &buf[0], sizeof(buf), &bytes_read) ||
580 bytes_read != sizeof(buf))
599 if (!ReadFromFile(fd, buf, buf_size, &bytes_read) || bytes_read != buf_size)
581600 return 0;
582601
583602 // Check for "PE\0\0" before the PE header.
......@@ -619,6 +638,10 @@ void ListOfModules::init() {
619638 }
620639 }
621640
641 InternalMmapVector<char> buf(4 + sizeof(IMAGE_FILE_HEADER) +
642 sizeof(IMAGE_OPTIONAL_HEADER));
643 InternalMmapVector<wchar_t> modname_utf16(kMaxPathLength);
644 InternalMmapVector<char> module_name(kMaxPathLength);
622645 // |num_modules| is the number of modules actually present,
623646 size_t num_modules = bytes_required / sizeof(HMODULE);
624647 for (size_t i = 0; i < num_modules; ++i) {
......@@ -628,15 +651,13 @@ void ListOfModules::init() {
628651 continue;
629652
630653 // Get the UTF-16 path and convert to UTF-8.
631 wchar_t modname_utf16[kMaxPathLength];
632654 int modname_utf16_len =
633 GetModuleFileNameW(handle, modname_utf16, kMaxPathLength);
655 GetModuleFileNameW(handle, &modname_utf16[0], kMaxPathLength);
634656 if (modname_utf16_len == 0)
635657 modname_utf16[0] = '\0';
636 char module_name[kMaxPathLength];
637 int module_name_len =
638 ::WideCharToMultiByte(CP_UTF8, 0, modname_utf16, modname_utf16_len + 1,
639 &module_name[0], kMaxPathLength, NULL, NULL);
658 int module_name_len = ::WideCharToMultiByte(
659 CP_UTF8, 0, &modname_utf16[0], modname_utf16_len + 1, &module_name[0],
660 kMaxPathLength, NULL, NULL);
640661 module_name[module_name_len] = '\0';
641662
642663 uptr base_address = (uptr)mi.lpBaseOfDll;
......@@ -646,15 +667,16 @@ void ListOfModules::init() {
646667 // RVA when computing the module offset. This helps llvm-symbolizer find the
647668 // right DWARF CU. In the common case that the image is loaded at it's
648669 // preferred address, we will now print normal virtual addresses.
649 uptr preferred_base = GetPreferredBase(&module_name[0]);
670 uptr preferred_base =
671 GetPreferredBase(&module_name[0], &buf[0], buf.size());
650672 uptr adjusted_base = base_address - preferred_base;
651673
652 LoadedModule cur_module;
653 cur_module.set(module_name, adjusted_base);
674 modules_.push_back(LoadedModule());
675 LoadedModule &cur_module = modules_.back();
676 cur_module.set(&module_name[0], adjusted_base);
654677 // We add the whole module as one single address range.
655678 cur_module.addAddressRange(base_address, end_address, /*executable*/ true,
656679 /*writable*/ true);
657 modules_.push_back(cur_module);
658680 }
659681 UnmapOrDie(hmodules, modules_buffer_size);
660682}
......@@ -794,6 +816,17 @@ uptr GetRSS() {
794816void *internal_start_thread(void *(*func)(void *arg), void *arg) { return 0; }
795817void internal_join_thread(void *th) { }
796818
819void FutexWait(atomic_uint32_t *p, u32 cmp) {
820 WaitOnAddress(p, &cmp, sizeof(cmp), INFINITE);
821}
822
823void FutexWake(atomic_uint32_t *p, u32 count) {
824 if (count == 1)
825 WakeByAddressSingle(p);
826 else
827 WakeByAddressAll(p);
828}
829
797830// ---------------------- BlockingMutex ---------------- {{{1
798831
799832BlockingMutex::BlockingMutex() {
......@@ -813,9 +846,7 @@ void BlockingMutex::Unlock() {
813846 ReleaseSRWLockExclusive((PSRWLOCK)opaque_storage_);
814847}
815848
816void BlockingMutex::CheckLocked() {
817 CHECK_EQ(owner_, GetThreadSelf());
818}
849void BlockingMutex::CheckLocked() const { CHECK_EQ(owner_, GetThreadSelf()); }
819850
820851uptr GetTlsSize() {
821852 return 0;
......@@ -942,22 +973,27 @@ void SignalContext::InitPcSpBp() {
942973
943974uptr SignalContext::GetAddress() const {
944975 EXCEPTION_RECORD *exception_record = (EXCEPTION_RECORD *)siginfo;
945 return exception_record->ExceptionInformation[1];
976 if (exception_record->ExceptionCode == EXCEPTION_ACCESS_VIOLATION)
977 return exception_record->ExceptionInformation[1];
978 return (uptr)exception_record->ExceptionAddress;
946979}
947980
948981bool SignalContext::IsMemoryAccess() const {
949 return GetWriteFlag() != SignalContext::UNKNOWN;
982 return ((EXCEPTION_RECORD *)siginfo)->ExceptionCode ==
983 EXCEPTION_ACCESS_VIOLATION;
950984}
951985
952bool SignalContext::IsTrueFaultingAddress() const {
953 // FIXME: Provide real implementation for this. See Linux and Mac variants.
954 return IsMemoryAccess();
955}
986bool SignalContext::IsTrueFaultingAddress() const { return true; }
956987
957988SignalContext::WriteFlag SignalContext::GetWriteFlag() const {
958989 EXCEPTION_RECORD *exception_record = (EXCEPTION_RECORD *)siginfo;
990
991 // The write flag is only available for access violation exceptions.
992 if (exception_record->ExceptionCode != EXCEPTION_ACCESS_VIOLATION)
993 return SignalContext::UNKNOWN;
994
959995 // The contents of this array are documented at
960 // https://msdn.microsoft.com/en-us/library/windows/desktop/aa363082(v=vs.85).aspx
996 // https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-exception_record
961997 // The first element indicates read as 0, write as 1, or execute as 8. The
962998 // second element is the faulting address.
963999 switch (exception_record->ExceptionInformation[0]) {
......@@ -1023,10 +1059,24 @@ const char *SignalContext::Describe() const {
10231059}
10241060
10251061uptr ReadBinaryName(/*out*/char *buf, uptr buf_len) {
1026 // FIXME: Actually implement this function.
1027 CHECK_GT(buf_len, 0);
1028 buf[0] = 0;
1029 return 0;
1062 if (buf_len == 0)
1063 return 0;
1064
1065 // Get the UTF-16 path and convert to UTF-8.
1066 InternalMmapVector<wchar_t> binname_utf16(kMaxPathLength);
1067 int binname_utf16_len =
1068 GetModuleFileNameW(NULL, &binname_utf16[0], kMaxPathLength);
1069 if (binname_utf16_len == 0) {
1070 buf[0] = '\0';
1071 return 0;
1072 }
1073 int binary_name_len =
1074 ::WideCharToMultiByte(CP_UTF8, 0, &binname_utf16[0], binname_utf16_len,
1075 buf, buf_len, NULL, NULL);
1076 if ((unsigned)binary_name_len == buf_len)
1077 --binary_name_len;
1078 buf[binary_name_len] = '\0';
1079 return binary_name_len;
10301080}
10311081
10321082uptr ReadLongProcessName(/*out*/char *buf, uptr buf_len) {
......@@ -1124,6 +1174,8 @@ void LogFullErrorReport(const char *buffer) {
11241174}
11251175#endif // SANITIZER_WIN_TRACE
11261176
1177void InitializePlatformCommonFlags(CommonFlags *cf) {}
1178
11271179} // namespace __sanitizer
11281180
11291181#endif // _WIN32
lib/tsan/tsan_clock.cpp+18-48
......@@ -80,14 +80,6 @@
8080// release-store operation by the thread with release_store_tid_ index.
8181// release_store_reused_ - reuse count of release_store_tid_.
8282
83// We don't have ThreadState in these methods, so this is an ugly hack that
84// works only in C++.
85#if !SANITIZER_GO
86# define CPP_STAT_INC(typ) StatInc(cur_thread(), typ)
87#else
88# define CPP_STAT_INC(typ) (void)0
89#endif
90
9183namespace __tsan {
9284
9385static atomic_uint32_t *ref_ptr(ClockBlock *cb) {
......@@ -138,19 +130,16 @@ void ThreadClock::ResetCached(ClockCache *c) {
138130void ThreadClock::acquire(ClockCache *c, SyncClock *src) {
139131 DCHECK_LE(nclk_, kMaxTid);
140132 DCHECK_LE(src->size_, kMaxTid);
141 CPP_STAT_INC(StatClockAcquire);
142133
143134 // Check if it's empty -> no need to do anything.
144135 const uptr nclk = src->size_;
145 if (nclk == 0) {
146 CPP_STAT_INC(StatClockAcquireEmpty);
136 if (nclk == 0)
147137 return;
148 }
149138
150139 bool acquired = false;
151140 for (unsigned i = 0; i < kDirtyTids; i++) {
152141 SyncClock::Dirty dirty = src->dirty_[i];
153 unsigned tid = dirty.tid;
142 unsigned tid = dirty.tid();
154143 if (tid != kInvalidTid) {
155144 if (clk_[tid] < dirty.epoch) {
156145 clk_[tid] = dirty.epoch;
......@@ -162,7 +151,6 @@ void ThreadClock::acquire(ClockCache *c, SyncClock *src) {
162151 // Check if we've already acquired src after the last release operation on src
163152 if (tid_ >= nclk || src->elem(tid_).reused != reused_) {
164153 // O(N) acquire.
165 CPP_STAT_INC(StatClockAcquireFull);
166154 nclk_ = max(nclk_, nclk);
167155 u64 *dst_pos = &clk_[0];
168156 for (ClockElem &src_elem : *src) {
......@@ -180,7 +168,6 @@ void ThreadClock::acquire(ClockCache *c, SyncClock *src) {
180168 }
181169
182170 if (acquired) {
183 CPP_STAT_INC(StatClockAcquiredSomething);
184171 last_acquire_ = clk_[tid_];
185172 ResetCached(c);
186173 }
......@@ -223,7 +210,6 @@ void ThreadClock::releaseStoreAcquire(ClockCache *c, SyncClock *sc) {
223210 sc->release_store_reused_ = 0;
224211
225212 if (acquired) {
226 CPP_STAT_INC(StatClockAcquiredSomething);
227213 last_acquire_ = clk_[tid_];
228214 ResetCached(c);
229215 }
......@@ -240,7 +226,6 @@ void ThreadClock::release(ClockCache *c, SyncClock *dst) {
240226 return;
241227 }
242228
243 CPP_STAT_INC(StatClockRelease);
244229 // Check if we need to resize dst.
245230 if (dst->size_ < nclk_)
246231 dst->Resize(c, nclk_);
......@@ -257,12 +242,9 @@ void ThreadClock::release(ClockCache *c, SyncClock *dst) {
257242 }
258243
259244 // O(N) release.
260 CPP_STAT_INC(StatClockReleaseFull);
261245 dst->Unshare(c);
262246 // First, remember whether we've acquired dst.
263247 bool acquired = IsAlreadyAcquired(dst);
264 if (acquired)
265 CPP_STAT_INC(StatClockReleaseAcquired);
266248 // Update dst->clk_.
267249 dst->FlushDirty();
268250 uptr i = 0;
......@@ -272,8 +254,6 @@ void ThreadClock::release(ClockCache *c, SyncClock *dst) {
272254 i++;
273255 }
274256 // Clear 'acquired' flag in the remaining elements.
275 if (nclk_ < dst->size_)
276 CPP_STAT_INC(StatClockReleaseClearTail);
277257 dst->release_store_tid_ = kInvalidTid;
278258 dst->release_store_reused_ = 0;
279259 // If we've acquired dst, remember this fact,
......@@ -285,7 +265,6 @@ void ThreadClock::release(ClockCache *c, SyncClock *dst) {
285265void ThreadClock::ReleaseStore(ClockCache *c, SyncClock *dst) {
286266 DCHECK_LE(nclk_, kMaxTid);
287267 DCHECK_LE(dst->size_, kMaxTid);
288 CPP_STAT_INC(StatClockStore);
289268
290269 if (dst->size_ == 0 && cached_idx_ != 0) {
291270 // Reuse the cached clock.
......@@ -299,10 +278,10 @@ void ThreadClock::ReleaseStore(ClockCache *c, SyncClock *dst) {
299278 dst->tab_idx_ = cached_idx_;
300279 dst->size_ = cached_size_;
301280 dst->blocks_ = cached_blocks_;
302 CHECK_EQ(dst->dirty_[0].tid, kInvalidTid);
281 CHECK_EQ(dst->dirty_[0].tid(), kInvalidTid);
303282 // The cached clock is shared (immutable),
304283 // so this is where we store the current clock.
305 dst->dirty_[0].tid = tid_;
284 dst->dirty_[0].set_tid(tid_);
306285 dst->dirty_[0].epoch = clk_[tid_];
307286 dst->release_store_tid_ = tid_;
308287 dst->release_store_reused_ = reused_;
......@@ -320,13 +299,11 @@ void ThreadClock::ReleaseStore(ClockCache *c, SyncClock *dst) {
320299 if (dst->release_store_tid_ == tid_ &&
321300 dst->release_store_reused_ == reused_ &&
322301 !HasAcquiredAfterRelease(dst)) {
323 CPP_STAT_INC(StatClockStoreFast);
324302 UpdateCurrentThread(c, dst);
325303 return;
326304 }
327305
328306 // O(N) release-store.
329 CPP_STAT_INC(StatClockStoreFull);
330307 dst->Unshare(c);
331308 // Note: dst can be larger than this ThreadClock.
332309 // This is fine since clk_ beyond size is all zeros.
......@@ -336,8 +313,7 @@ void ThreadClock::ReleaseStore(ClockCache *c, SyncClock *dst) {
336313 ce.reused = 0;
337314 i++;
338315 }
339 for (uptr i = 0; i < kDirtyTids; i++)
340 dst->dirty_[i].tid = kInvalidTid;
316 for (uptr i = 0; i < kDirtyTids; i++) dst->dirty_[i].set_tid(kInvalidTid);
341317 dst->release_store_tid_ = tid_;
342318 dst->release_store_reused_ = reused_;
343319 // Rememeber that we don't need to acquire it in future.
......@@ -359,7 +335,6 @@ void ThreadClock::ReleaseStore(ClockCache *c, SyncClock *dst) {
359335}
360336
361337void ThreadClock::acq_rel(ClockCache *c, SyncClock *dst) {
362 CPP_STAT_INC(StatClockAcquireRelease);
363338 acquire(c, dst);
364339 ReleaseStore(c, dst);
365340}
......@@ -369,10 +344,9 @@ void ThreadClock::UpdateCurrentThread(ClockCache *c, SyncClock *dst) const {
369344 // Update the threads time, but preserve 'acquired' flag.
370345 for (unsigned i = 0; i < kDirtyTids; i++) {
371346 SyncClock::Dirty *dirty = &dst->dirty_[i];
372 const unsigned tid = dirty->tid;
347 const unsigned tid = dirty->tid();
373348 if (tid == tid_ || tid == kInvalidTid) {
374 CPP_STAT_INC(StatClockReleaseFast);
375 dirty->tid = tid_;
349 dirty->set_tid(tid_);
376350 dirty->epoch = clk_[tid_];
377351 return;
378352 }
......@@ -380,7 +354,6 @@ void ThreadClock::UpdateCurrentThread(ClockCache *c, SyncClock *dst) const {
380354 // Reset all 'acquired' flags, O(N).
381355 // We are going to touch dst elements, so we need to unshare it.
382356 dst->Unshare(c);
383 CPP_STAT_INC(StatClockReleaseSlow);
384357 dst->elem(tid_).epoch = clk_[tid_];
385358 for (uptr i = 0; i < dst->size_; i++)
386359 dst->elem(i).reused = 0;
......@@ -393,8 +366,8 @@ bool ThreadClock::IsAlreadyAcquired(const SyncClock *src) const {
393366 return false;
394367 for (unsigned i = 0; i < kDirtyTids; i++) {
395368 SyncClock::Dirty dirty = src->dirty_[i];
396 if (dirty.tid != kInvalidTid) {
397 if (clk_[dirty.tid] < dirty.epoch)
369 if (dirty.tid() != kInvalidTid) {
370 if (clk_[dirty.tid()] < dirty.epoch)
398371 return false;
399372 }
400373 }
......@@ -453,12 +426,10 @@ void SyncClock::ResetImpl() {
453426 blocks_ = 0;
454427 release_store_tid_ = kInvalidTid;
455428 release_store_reused_ = 0;
456 for (uptr i = 0; i < kDirtyTids; i++)
457 dirty_[i].tid = kInvalidTid;
429 for (uptr i = 0; i < kDirtyTids; i++) dirty_[i].set_tid(kInvalidTid);
458430}
459431
460432void SyncClock::Resize(ClockCache *c, uptr nclk) {
461 CPP_STAT_INC(StatClockReleaseResize);
462433 Unshare(c);
463434 if (nclk <= capacity()) {
464435 // Memory is already allocated, just increase the size.
......@@ -503,10 +474,10 @@ void SyncClock::Resize(ClockCache *c, uptr nclk) {
503474void SyncClock::FlushDirty() {
504475 for (unsigned i = 0; i < kDirtyTids; i++) {
505476 Dirty *dirty = &dirty_[i];
506 if (dirty->tid != kInvalidTid) {
507 CHECK_LT(dirty->tid, size_);
508 elem(dirty->tid).epoch = dirty->epoch;
509 dirty->tid = kInvalidTid;
477 if (dirty->tid() != kInvalidTid) {
478 CHECK_LT(dirty->tid(), size_);
479 elem(dirty->tid()).epoch = dirty->epoch;
480 dirty->set_tid(kInvalidTid);
510481 }
511482 }
512483}
......@@ -559,7 +530,7 @@ ALWAYS_INLINE bool SyncClock::Cachable() const {
559530 if (size_ == 0)
560531 return false;
561532 for (unsigned i = 0; i < kDirtyTids; i++) {
562 if (dirty_[i].tid != kInvalidTid)
533 if (dirty_[i].tid() != kInvalidTid)
563534 return false;
564535 }
565536 return atomic_load_relaxed(ref_ptr(tab_)) == 1;
......@@ -606,7 +577,7 @@ ALWAYS_INLINE void SyncClock::append_block(u32 idx) {
606577u64 SyncClock::get(unsigned tid) const {
607578 for (unsigned i = 0; i < kDirtyTids; i++) {
608579 Dirty dirty = dirty_[i];
609 if (dirty.tid == tid)
580 if (dirty.tid() == tid)
610581 return dirty.epoch;
611582 }
612583 return elem(tid).epoch;
......@@ -625,9 +596,8 @@ void SyncClock::DebugDump(int(*printf)(const char *s, ...)) {
625596 for (uptr i = 0; i < size_; i++)
626597 printf("%s%llu", i == 0 ? "" : ",", elem(i).reused);
627598 printf("] release_store_tid=%d/%d dirty_tids=%d[%llu]/%d[%llu]",
628 release_store_tid_, release_store_reused_,
629 dirty_[0].tid, dirty_[0].epoch,
630 dirty_[1].tid, dirty_[1].epoch);
599 release_store_tid_, release_store_reused_, dirty_[0].tid(),
600 dirty_[0].epoch, dirty_[1].tid(), dirty_[1].epoch);
631601}
632602
633603void SyncClock::Iter::Next() {
lib/tsan/tsan_clock.h+13-3
......@@ -17,7 +17,7 @@
1717
1818namespace __tsan {
1919
20typedef DenseSlabAlloc<ClockBlock, 1<<16, 1<<10> ClockAlloc;
20typedef DenseSlabAlloc<ClockBlock, 1 << 22, 1 << 10> ClockAlloc;
2121typedef DenseSlabAllocCache ClockCache;
2222
2323// The clock that lives in sync variables (mutexes, atomics, etc).
......@@ -65,10 +65,20 @@ class SyncClock {
6565 static const uptr kDirtyTids = 2;
6666
6767 struct Dirty {
68 u64 epoch : kClkBits;
69 u64 tid : 64 - kClkBits; // kInvalidId if not active
68 u32 tid() const { return tid_ == kShortInvalidTid ? kInvalidTid : tid_; }
69 void set_tid(u32 tid) {
70 tid_ = tid == kInvalidTid ? kShortInvalidTid : tid;
71 }
72 u64 epoch : kClkBits;
73
74 private:
75 // Full kInvalidTid won't fit into Dirty::tid.
76 static const u64 kShortInvalidTid = (1ull << (64 - kClkBits)) - 1;
77 u64 tid_ : 64 - kClkBits; // kInvalidId if not active
7078 };
7179
80 static_assert(sizeof(Dirty) == 8, "Dirty is not 64bit");
81
7282 unsigned release_store_tid_;
7383 unsigned release_store_reused_;
7484 Dirty dirty_[kDirtyTids];
lib/tsan/tsan_defs.h+12-18
......@@ -15,7 +15,7 @@
1515
1616#include "sanitizer_common/sanitizer_internal_defs.h"
1717#include "sanitizer_common/sanitizer_libc.h"
18#include "tsan_stat.h"
18#include "sanitizer_common/sanitizer_mutex.h"
1919#include "ubsan/ubsan_platform.h"
2020
2121// Setup defaults for compile definitions.
......@@ -23,10 +23,6 @@
2323# define TSAN_NO_HISTORY 0
2424#endif
2525
26#ifndef TSAN_COLLECT_STATS
27# define TSAN_COLLECT_STATS 0
28#endif
29
3026#ifndef TSAN_CONTAINS_UBSAN
3127# if CAN_SANITIZE_UB && !SANITIZER_GO
3228# define TSAN_CONTAINS_UBSAN 1
......@@ -98,8 +94,6 @@ const bool kCollectHistory = false;
9894const bool kCollectHistory = true;
9995#endif
10096
101const u16 kInvalidTid = kMaxTid + 1;
102
10397// The following "build consistency" machinery ensures that all source files
10498// are built in the same configuration. Inconsistent builds lead to
10599// hard to debug crashes.
......@@ -109,23 +103,12 @@ void build_consistency_debug();
109103void build_consistency_release();
110104#endif
111105
112#if TSAN_COLLECT_STATS
113void build_consistency_stats();
114#else
115void build_consistency_nostats();
116#endif
117
118106static inline void USED build_consistency() {
119107#if SANITIZER_DEBUG
120108 build_consistency_debug();
121109#else
122110 build_consistency_release();
123111#endif
124#if TSAN_COLLECT_STATS
125 build_consistency_stats();
126#else
127 build_consistency_nostats();
128#endif
129112}
130113
131114template<typename T>
......@@ -190,6 +173,17 @@ enum ExternalTag : uptr {
190173 // as 16-bit values, see tsan_defs.h.
191174};
192175
176enum MutexType {
177 MutexTypeTrace = MutexLastCommon,
178 MutexTypeReport,
179 MutexTypeSyncVar,
180 MutexTypeAnnotations,
181 MutexTypeAtExit,
182 MutexTypeFired,
183 MutexTypeRacy,
184 MutexTypeGlobalProc,
185};
186
193187} // namespace __tsan
194188
195189#endif // TSAN_DEFS_H
lib/tsan/tsan_dense_alloc.h+22-11
......@@ -20,7 +20,6 @@
2020
2121#include "sanitizer_common/sanitizer_common.h"
2222#include "tsan_defs.h"
23#include "tsan_mutex.h"
2423
2524namespace __tsan {
2625
......@@ -29,28 +28,40 @@ class DenseSlabAllocCache {
2928 typedef u32 IndexT;
3029 uptr pos;
3130 IndexT cache[kSize];
32 template<typename T, uptr kL1Size, uptr kL2Size> friend class DenseSlabAlloc;
31 template <typename, uptr, uptr, u64>
32 friend class DenseSlabAlloc;
3333};
3434
35template<typename T, uptr kL1Size, uptr kL2Size>
35template <typename T, uptr kL1Size, uptr kL2Size, u64 kReserved = 0>
3636class DenseSlabAlloc {
3737 public:
3838 typedef DenseSlabAllocCache Cache;
3939 typedef typename Cache::IndexT IndexT;
4040
41 explicit DenseSlabAlloc(const char *name) {
42 // Check that kL1Size and kL2Size are sane.
43 CHECK_EQ(kL1Size & (kL1Size - 1), 0);
44 CHECK_EQ(kL2Size & (kL2Size - 1), 0);
45 CHECK_GE(1ull << (sizeof(IndexT) * 8), kL1Size * kL2Size);
46 // Check that it makes sense to use the dense alloc.
47 CHECK_GE(sizeof(T), sizeof(IndexT));
48 internal_memset(map_, 0, sizeof(map_));
41 static_assert((kL1Size & (kL1Size - 1)) == 0,
42 "kL1Size must be a power-of-two");
43 static_assert((kL2Size & (kL2Size - 1)) == 0,
44 "kL2Size must be a power-of-two");
45 static_assert((kL1Size * kL2Size) <= (1ull << (sizeof(IndexT) * 8)),
46 "kL1Size/kL2Size are too large");
47 static_assert(((kL1Size * kL2Size - 1) & kReserved) == 0,
48 "reserved bits don't fit");
49 static_assert(sizeof(T) > sizeof(IndexT),
50 "it doesn't make sense to use dense alloc");
51
52 explicit DenseSlabAlloc(LinkerInitialized, const char *name) {
4953 freelist_ = 0;
5054 fillpos_ = 0;
5155 name_ = name;
5256 }
5357
58 explicit DenseSlabAlloc(const char *name)
59 : DenseSlabAlloc(LINKER_INITIALIZED, name) {
60 // It can be very large.
61 // Don't page it in for linker initialized objects.
62 internal_memset(map_, 0, sizeof(map_));
63 }
64
5465 ~DenseSlabAlloc() {
5566 for (uptr i = 0; i < kL1Size; i++) {
5667 if (map_[i] != 0)
lib/tsan/tsan_external.cpp+6-5
......@@ -11,6 +11,7 @@
1111//===----------------------------------------------------------------------===//
1212#include "tsan_rtl.h"
1313#include "tsan_interceptors.h"
14#include "sanitizer_common/sanitizer_ptrauth.h"
1415
1516namespace __tsan {
1617
......@@ -57,13 +58,13 @@ uptr TagFromShadowStackFrame(uptr pc) {
5758#if !SANITIZER_GO
5859
5960typedef void(*AccessFunc)(ThreadState *, uptr, uptr, int);
60void ExternalAccess(void *addr, void *caller_pc, void *tag, AccessFunc access) {
61void ExternalAccess(void *addr, uptr caller_pc, void *tag, AccessFunc access) {
6162 CHECK_LT(tag, atomic_load(&used_tags, memory_order_relaxed));
6263 ThreadState *thr = cur_thread();
63 if (caller_pc) FuncEntry(thr, (uptr)caller_pc);
64 if (caller_pc) FuncEntry(thr, caller_pc);
6465 InsertShadowStackFrameForTag(thr, (uptr)tag);
6566 bool in_ignored_lib;
66 if (!caller_pc || !libignore()->IsIgnored((uptr)caller_pc, &in_ignored_lib)) {
67 if (!caller_pc || !libignore()->IsIgnored(caller_pc, &in_ignored_lib)) {
6768 access(thr, CALLERPC, (uptr)addr, kSizeLog1);
6869 }
6970 FuncExit(thr);
......@@ -110,12 +111,12 @@ void __tsan_external_assign_tag(void *addr, void *tag) {
110111
111112SANITIZER_INTERFACE_ATTRIBUTE
112113void __tsan_external_read(void *addr, void *caller_pc, void *tag) {
113 ExternalAccess(addr, caller_pc, tag, MemoryRead);
114 ExternalAccess(addr, STRIP_PAC_PC(caller_pc), tag, MemoryRead);
114115}
115116
116117SANITIZER_INTERFACE_ATTRIBUTE
117118void __tsan_external_write(void *addr, void *caller_pc, void *tag) {
118 ExternalAccess(addr, caller_pc, tag, MemoryWrite);
119 ExternalAccess(addr, STRIP_PAC_PC(caller_pc), tag, MemoryWrite);
119120}
120121} // extern "C"
121122
lib/tsan/tsan_flags.cpp+1-1
......@@ -87,7 +87,7 @@ void InitializeFlags(Flags *f, const char *env, const char *env_option_name) {
8787 // Let a frontend override.
8888 parser.ParseString(__tsan_default_options());
8989#if TSAN_CONTAINS_UBSAN
90 const char *ubsan_default_options = __ubsan::MaybeCallUbsanDefaultOptions();
90 const char *ubsan_default_options = __ubsan_default_options();
9191 ubsan_parser.ParseString(ubsan_default_options);
9292#endif
9393 // Override from command line.
lib/tsan/tsan_interceptors.h+9-9
......@@ -22,7 +22,7 @@ class ScopedInterceptor {
2222LibIgnore *libignore();
2323
2424#if !SANITIZER_GO
25INLINE bool in_symbolizer() {
25inline bool in_symbolizer() {
2626 cur_thread_init();
2727 return UNLIKELY(cur_thread()->in_symbolizer);
2828}
......@@ -30,14 +30,14 @@ INLINE bool in_symbolizer() {
3030
3131} // namespace __tsan
3232
33#define SCOPED_INTERCEPTOR_RAW(func, ...) \
34 cur_thread_init(); \
35 ThreadState *thr = cur_thread(); \
36 const uptr caller_pc = GET_CALLER_PC(); \
37 ScopedInterceptor si(thr, #func, caller_pc); \
38 const uptr pc = StackTrace::GetCurrentPc(); \
39 (void)pc; \
40/**/
33#define SCOPED_INTERCEPTOR_RAW(func, ...) \
34 cur_thread_init(); \
35 ThreadState *thr = cur_thread(); \
36 const uptr caller_pc = GET_CALLER_PC(); \
37 ScopedInterceptor si(thr, #func, caller_pc); \
38 const uptr pc = GET_CURRENT_PC(); \
39 (void)pc; \
40 /**/
4141
4242#define SCOPED_TSAN_INTERCEPTOR(func, ...) \
4343 SCOPED_INTERCEPTOR_RAW(func, __VA_ARGS__); \
lib/tsan/tsan_interceptors_mac.cpp+6-4
......@@ -44,8 +44,9 @@ namespace __tsan {
4444// actually aliases of each other, and we cannot have different interceptors for
4545// them, because they're actually the same function. Thus, we have to stay
4646// conservative and treat the non-barrier versions as mo_acq_rel.
47static const morder kMacOrderBarrier = mo_acq_rel;
48static const morder kMacOrderNonBarrier = mo_acq_rel;
47static constexpr morder kMacOrderBarrier = mo_acq_rel;
48static constexpr morder kMacOrderNonBarrier = mo_acq_rel;
49static constexpr morder kMacFailureOrder = mo_relaxed;
4950
5051#define OSATOMIC_INTERCEPTOR(return_t, t, tsan_t, f, tsan_atomic_f, mo) \
5152 TSAN_INTERCEPTOR(return_t, f, t x, volatile t *ptr) { \
......@@ -110,7 +111,7 @@ OSATOMIC_INTERCEPTORS_BITWISE(OSAtomicXor, fetch_xor,
110111 SCOPED_TSAN_INTERCEPTOR(f, old_value, new_value, ptr); \
111112 return tsan_atomic_f##_compare_exchange_strong( \
112113 (volatile tsan_t *)ptr, (tsan_t *)&old_value, (tsan_t)new_value, \
113 kMacOrderNonBarrier, kMacOrderNonBarrier); \
114 kMacOrderNonBarrier, kMacFailureOrder); \
114115 } \
115116 \
116117 TSAN_INTERCEPTOR(bool, f##Barrier, t old_value, t new_value, \
......@@ -118,7 +119,7 @@ OSATOMIC_INTERCEPTORS_BITWISE(OSAtomicXor, fetch_xor,
118119 SCOPED_TSAN_INTERCEPTOR(f##Barrier, old_value, new_value, ptr); \
119120 return tsan_atomic_f##_compare_exchange_strong( \
120121 (volatile tsan_t *)ptr, (tsan_t *)&old_value, (tsan_t)new_value, \
121 kMacOrderBarrier, kMacOrderNonBarrier); \
122 kMacOrderBarrier, kMacFailureOrder); \
122123 }
123124
124125OSATOMIC_INTERCEPTORS_CAS(OSAtomicCompareAndSwapInt, __tsan_atomic32, a32, int)
......@@ -438,6 +439,7 @@ struct fake_shared_weak_count {
438439 virtual void on_zero_shared() = 0;
439440 virtual void _unused_0x18() = 0;
440441 virtual void on_zero_shared_weak() = 0;
442 virtual ~fake_shared_weak_count() = 0; // suppress -Wnon-virtual-dtor
441443};
442444} // namespace
443445
lib/tsan/tsan_interceptors_mach_vm.cpp+10-9
......@@ -19,12 +19,11 @@
1919
2020namespace __tsan {
2121
22static bool intersects_with_shadow(mach_vm_address_t *address,
22static bool intersects_with_shadow(mach_vm_address_t address,
2323 mach_vm_size_t size, int flags) {
2424 // VM_FLAGS_FIXED is 0x0, so we have to test for VM_FLAGS_ANYWHERE.
2525 if (flags & VM_FLAGS_ANYWHERE) return false;
26 uptr ptr = *address;
27 return !IsAppMem(ptr) || !IsAppMem(ptr + size - 1);
26 return !IsAppMem(address) || !IsAppMem(address + size - 1);
2827}
2928
3029TSAN_INTERCEPTOR(kern_return_t, mach_vm_allocate, vm_map_t target,
......@@ -32,12 +31,12 @@ TSAN_INTERCEPTOR(kern_return_t, mach_vm_allocate, vm_map_t target,
3231 SCOPED_TSAN_INTERCEPTOR(mach_vm_allocate, target, address, size, flags);
3332 if (target != mach_task_self())
3433 return REAL(mach_vm_allocate)(target, address, size, flags);
35 if (intersects_with_shadow(address, size, flags))
34 if (address && intersects_with_shadow(*address, size, flags))
3635 return KERN_NO_SPACE;
37 kern_return_t res = REAL(mach_vm_allocate)(target, address, size, flags);
38 if (res == KERN_SUCCESS)
36 kern_return_t kr = REAL(mach_vm_allocate)(target, address, size, flags);
37 if (kr == KERN_SUCCESS)
3938 MemoryRangeImitateWriteOrResetRange(thr, pc, *address, size);
40 return res;
39 return kr;
4140}
4241
4342TSAN_INTERCEPTOR(kern_return_t, mach_vm_deallocate, vm_map_t target,
......@@ -45,8 +44,10 @@ TSAN_INTERCEPTOR(kern_return_t, mach_vm_deallocate, vm_map_t target,
4544 SCOPED_TSAN_INTERCEPTOR(mach_vm_deallocate, target, address, size);
4645 if (target != mach_task_self())
4746 return REAL(mach_vm_deallocate)(target, address, size);
48 UnmapShadow(thr, address, size);
49 return REAL(mach_vm_deallocate)(target, address, size);
47 kern_return_t kr = REAL(mach_vm_deallocate)(target, address, size);
48 if (kr == KERN_SUCCESS && address)
49 UnmapShadow(thr, address, size);
50 return kr;
5051}
5152
5253} // namespace __tsan
lib/tsan/tsan_interceptors_posix.cpp+164-74
......@@ -31,6 +31,8 @@
3131#include "tsan_mman.h"
3232#include "tsan_fd.h"
3333
34#include <stdarg.h>
35
3436using namespace __tsan;
3537
3638#if SANITIZER_FREEBSD || SANITIZER_MAC
......@@ -52,10 +54,6 @@ using namespace __tsan;
5254#define vfork __vfork14
5355#endif
5456
55#if SANITIZER_ANDROID
56#define mallopt(a, b)
57#endif
58
5957#ifdef __mips__
6058const int kSigCount = 129;
6159#else
......@@ -73,7 +71,8 @@ struct ucontext_t {
7371};
7472#endif
7573
76#if defined(__x86_64__) || defined(__mips__) || SANITIZER_PPC64V1
74#if defined(__x86_64__) || defined(__mips__) || SANITIZER_PPC64V1 || \
75 defined(__s390x__)
7776#define PTHREAD_ABI_BASE "GLIBC_2.3.2"
7877#elif defined(__aarch64__) || SANITIZER_PPC64V2
7978#define PTHREAD_ABI_BASE "GLIBC_2.17"
......@@ -83,6 +82,8 @@ extern "C" int pthread_attr_init(void *attr);
8382extern "C" int pthread_attr_destroy(void *attr);
8483DECLARE_REAL(int, pthread_attr_getdetachstate, void *, void *)
8584extern "C" int pthread_attr_setstacksize(void *attr, uptr stacksize);
85extern "C" int pthread_atfork(void (*prepare)(void), void (*parent)(void),
86 void (*child)(void));
8687extern "C" int pthread_key_create(unsigned *key, void (*destructor)(void* v));
8788extern "C" int pthread_setspecific(unsigned key, const void *v);
8889DECLARE_REAL(int, pthread_mutexattr_gettype, void *, void *)
......@@ -95,7 +96,7 @@ extern "C" void _exit(int status);
9596extern "C" int fileno_unlocked(void *stream);
9697extern "C" int dirfd(void *dirp);
9798#endif
98#if !SANITIZER_FREEBSD && !SANITIZER_ANDROID && !SANITIZER_NETBSD
99#if SANITIZER_GLIBC
99100extern "C" int mallopt(int param, int value);
100101#endif
101102#if SANITIZER_NETBSD
......@@ -135,6 +136,7 @@ const int PTHREAD_BARRIER_SERIAL_THREAD = -1;
135136#endif
136137const int MAP_FIXED = 0x10;
137138typedef long long_t;
139typedef __sanitizer::u16 mode_t;
138140
139141// From /usr/include/unistd.h
140142# define F_ULOCK 0 /* Unlock a previously locked region. */
......@@ -194,12 +196,10 @@ struct InterceptorContext {
194196 unsigned finalize_key;
195197#endif
196198
197 BlockingMutex atexit_mu;
199 Mutex atexit_mu;
198200 Vector<struct AtExitCtx *> AtExitStack;
199201
200 InterceptorContext()
201 : libignore(LINKER_INITIALIZED), AtExitStack() {
202 }
202 InterceptorContext() : libignore(LINKER_INITIALIZED), atexit_mu(MutexTypeAtExit), AtExitStack() {}
203203};
204204
205205static ALIGNED(64) char interceptor_placeholder[sizeof(InterceptorContext)];
......@@ -265,7 +265,7 @@ ScopedInterceptor::~ScopedInterceptor() {
265265 if (!thr_->ignore_interceptors) {
266266 ProcessPendingSignals(thr_);
267267 FuncExit(thr_);
268 CheckNoLocks(thr_);
268 CheckedMutex::CheckNoLocks();
269269 }
270270}
271271
......@@ -375,7 +375,7 @@ static void at_exit_wrapper() {
375375 AtExitCtx *ctx;
376376 {
377377 // Ensure thread-safety.
378 BlockingMutexLock l(&interceptor_ctx()->atexit_mu);
378 Lock l(&interceptor_ctx()->atexit_mu);
379379
380380 // Pop AtExitCtx from the top of the stack of callback functions
381381 uptr element = interceptor_ctx()->AtExitStack.Size() - 1;
......@@ -431,7 +431,10 @@ static int setup_at_exit_wrapper(ThreadState *thr, uptr pc, void(*f)(),
431431 // Store ctx in a local stack-like structure
432432
433433 // Ensure thread-safety.
434 BlockingMutexLock l(&interceptor_ctx()->atexit_mu);
434 Lock l(&interceptor_ctx()->atexit_mu);
435 // __cxa_atexit calls calloc. If we don't ignore interceptors, we will fail
436 // due to atexit_mu held on exit from the calloc interceptor.
437 ScopedIgnoreInterceptors ignore;
435438
436439 res = REAL(__cxa_atexit)((void (*)(void *a))at_exit_wrapper, 0, 0);
437440 // Push AtExitCtx on the top of the stack of callback functions
......@@ -656,8 +659,11 @@ TSAN_INTERCEPTOR(void*, malloc, uptr size) {
656659 return p;
657660}
658661
662// In glibc<2.25, dynamic TLS blocks are allocated by __libc_memalign. Intercept
663// __libc_memalign so that (1) we can detect races (2) free will not be called
664// on libc internally allocated blocks.
659665TSAN_INTERCEPTOR(void*, __libc_memalign, uptr align, uptr sz) {
660 SCOPED_TSAN_INTERCEPTOR(__libc_memalign, align, sz);
666 SCOPED_INTERCEPTOR_RAW(__libc_memalign, align, sz);
661667 return user_memalign(thr, pc, align, sz);
662668}
663669
......@@ -770,6 +776,11 @@ static void *mmap_interceptor(ThreadState *thr, uptr pc, Mmap real_mmap,
770776 if (!fix_mmap_addr(&addr, sz, flags)) return MAP_FAILED;
771777 void *res = real_mmap(addr, sz, prot, flags, fd, off);
772778 if (res != MAP_FAILED) {
779 if (!IsAppMem((uptr)res) || !IsAppMem((uptr)res + sz - 1)) {
780 Report("ThreadSanitizer: mmap at bad address: addr=%p size=%p res=%p\n",
781 addr, (void*)sz, res);
782 Die();
783 }
773784 if (fd > 0) FdAccess(thr, pc, fd);
774785 MemoryRangeImitateWriteOrResetRange(thr, pc, (uptr)res, sz);
775786 }
......@@ -1119,27 +1130,37 @@ static void *init_cond(void *c, bool force = false) {
11191130 return (void*)cond;
11201131}
11211132
1133namespace {
1134
1135template <class Fn>
11221136struct CondMutexUnlockCtx {
11231137 ScopedInterceptor *si;
11241138 ThreadState *thr;
11251139 uptr pc;
11261140 void *m;
1141 void *c;
1142 const Fn &fn;
1143
1144 int Cancel() const { return fn(); }
1145 void Unlock() const;
11271146};
11281147
1129static void cond_mutex_unlock(CondMutexUnlockCtx *arg) {
1148template <class Fn>
1149void CondMutexUnlockCtx<Fn>::Unlock() const {
11301150 // pthread_cond_wait interceptor has enabled async signal delivery
11311151 // (see BlockingCall below). Disable async signals since we are running
11321152 // tsan code. Also ScopedInterceptor and BlockingCall destructors won't run
11331153 // since the thread is cancelled, so we have to manually execute them
11341154 // (the thread still can run some user code due to pthread_cleanup_push).
1135 ThreadSignalContext *ctx = SigCtx(arg->thr);
1155 ThreadSignalContext *ctx = SigCtx(thr);
11361156 CHECK_EQ(atomic_load(&ctx->in_blocking_func, memory_order_relaxed), 1);
11371157 atomic_store(&ctx->in_blocking_func, 0, memory_order_relaxed);
1138 MutexPostLock(arg->thr, arg->pc, (uptr)arg->m, MutexFlagDoPreLockOnPostLock);
1158 MutexPostLock(thr, pc, (uptr)m, MutexFlagDoPreLockOnPostLock);
11391159 // Undo BlockingCall ctor effects.
1140 arg->thr->ignore_interceptors--;
1141 arg->si->~ScopedInterceptor();
1160 thr->ignore_interceptors--;
1161 si->~ScopedInterceptor();
11421162}
1163} // namespace
11431164
11441165INTERCEPTOR(int, pthread_cond_init, void *c, void *a) {
11451166 void *cond = init_cond(c, true);
......@@ -1148,20 +1169,24 @@ INTERCEPTOR(int, pthread_cond_init, void *c, void *a) {
11481169 return REAL(pthread_cond_init)(cond, a);
11491170}
11501171
1151static int cond_wait(ThreadState *thr, uptr pc, ScopedInterceptor *si,
1152 int (*fn)(void *c, void *m, void *abstime), void *c,
1153 void *m, void *t) {
1172template <class Fn>
1173int cond_wait(ThreadState *thr, uptr pc, ScopedInterceptor *si, const Fn &fn,
1174 void *c, void *m) {
11541175 MemoryAccessRange(thr, pc, (uptr)c, sizeof(uptr), false);
11551176 MutexUnlock(thr, pc, (uptr)m);
1156 CondMutexUnlockCtx arg = {si, thr, pc, m};
11571177 int res = 0;
11581178 // This ensures that we handle mutex lock even in case of pthread_cancel.
11591179 // See test/tsan/cond_cancel.cpp.
11601180 {
11611181 // Enable signal delivery while the thread is blocked.
11621182 BlockingCall bc(thr);
1183 CondMutexUnlockCtx<Fn> arg = {si, thr, pc, m, c, fn};
11631184 res = call_pthread_cancel_with_cleanup(
1164 fn, c, m, t, (void (*)(void *arg))cond_mutex_unlock, &arg);
1185 [](void *arg) -> int {
1186 return ((const CondMutexUnlockCtx<Fn> *)arg)->Cancel();
1187 },
1188 [](void *arg) { ((const CondMutexUnlockCtx<Fn> *)arg)->Unlock(); },
1189 &arg);
11651190 }
11661191 if (res == errno_EOWNERDEAD) MutexRepair(thr, pc, (uptr)m);
11671192 MutexPostLock(thr, pc, (uptr)m, MutexFlagDoPreLockOnPostLock);
......@@ -1171,25 +1196,46 @@ static int cond_wait(ThreadState *thr, uptr pc, ScopedInterceptor *si,
11711196INTERCEPTOR(int, pthread_cond_wait, void *c, void *m) {
11721197 void *cond = init_cond(c);
11731198 SCOPED_TSAN_INTERCEPTOR(pthread_cond_wait, cond, m);
1174 return cond_wait(thr, pc, &si, (int (*)(void *c, void *m, void *abstime))REAL(
1175 pthread_cond_wait),
1176 cond, m, 0);
1199 return cond_wait(
1200 thr, pc, &si, [=]() { return REAL(pthread_cond_wait)(cond, m); }, cond,
1201 m);
11771202}
11781203
11791204INTERCEPTOR(int, pthread_cond_timedwait, void *c, void *m, void *abstime) {
11801205 void *cond = init_cond(c);
11811206 SCOPED_TSAN_INTERCEPTOR(pthread_cond_timedwait, cond, m, abstime);
1182 return cond_wait(thr, pc, &si, REAL(pthread_cond_timedwait), cond, m,
1183 abstime);
1207 return cond_wait(
1208 thr, pc, &si,
1209 [=]() { return REAL(pthread_cond_timedwait)(cond, m, abstime); }, cond,
1210 m);
11841211}
11851212
1213#if SANITIZER_LINUX
1214INTERCEPTOR(int, pthread_cond_clockwait, void *c, void *m,
1215 __sanitizer_clockid_t clock, void *abstime) {
1216 void *cond = init_cond(c);
1217 SCOPED_TSAN_INTERCEPTOR(pthread_cond_clockwait, cond, m, clock, abstime);
1218 return cond_wait(
1219 thr, pc, &si,
1220 [=]() { return REAL(pthread_cond_clockwait)(cond, m, clock, abstime); },
1221 cond, m);
1222}
1223#define TSAN_MAYBE_PTHREAD_COND_CLOCKWAIT TSAN_INTERCEPT(pthread_cond_clockwait)
1224#else
1225#define TSAN_MAYBE_PTHREAD_COND_CLOCKWAIT
1226#endif
1227
11861228#if SANITIZER_MAC
11871229INTERCEPTOR(int, pthread_cond_timedwait_relative_np, void *c, void *m,
11881230 void *reltime) {
11891231 void *cond = init_cond(c);
11901232 SCOPED_TSAN_INTERCEPTOR(pthread_cond_timedwait_relative_np, cond, m, reltime);
1191 return cond_wait(thr, pc, &si, REAL(pthread_cond_timedwait_relative_np), cond,
1192 m, reltime);
1233 return cond_wait(
1234 thr, pc, &si,
1235 [=]() {
1236 return REAL(pthread_cond_timedwait_relative_np)(cond, m, reltime);
1237 },
1238 cond, m);
11931239}
11941240#endif
11951241
......@@ -1508,20 +1554,28 @@ TSAN_INTERCEPTOR(int, fstat64, int fd, void *buf) {
15081554#define TSAN_MAYBE_INTERCEPT_FSTAT64
15091555#endif
15101556
1511TSAN_INTERCEPTOR(int, open, const char *name, int flags, int mode) {
1512 SCOPED_TSAN_INTERCEPTOR(open, name, flags, mode);
1557TSAN_INTERCEPTOR(int, open, const char *name, int oflag, ...) {
1558 va_list ap;
1559 va_start(ap, oflag);
1560 mode_t mode = va_arg(ap, int);
1561 va_end(ap);
1562 SCOPED_TSAN_INTERCEPTOR(open, name, oflag, mode);
15131563 READ_STRING(thr, pc, name, 0);
1514 int fd = REAL(open)(name, flags, mode);
1564 int fd = REAL(open)(name, oflag, mode);
15151565 if (fd >= 0)
15161566 FdFileCreate(thr, pc, fd);
15171567 return fd;
15181568}
15191569
15201570#if SANITIZER_LINUX
1521TSAN_INTERCEPTOR(int, open64, const char *name, int flags, int mode) {
1522 SCOPED_TSAN_INTERCEPTOR(open64, name, flags, mode);
1571TSAN_INTERCEPTOR(int, open64, const char *name, int oflag, ...) {
1572 va_list ap;
1573 va_start(ap, oflag);
1574 mode_t mode = va_arg(ap, int);
1575 va_end(ap);
1576 SCOPED_TSAN_INTERCEPTOR(open64, name, oflag, mode);
15231577 READ_STRING(thr, pc, name, 0);
1524 int fd = REAL(open64)(name, flags, mode);
1578 int fd = REAL(open64)(name, oflag, mode);
15251579 if (fd >= 0)
15261580 FdFileCreate(thr, pc, fd);
15271581 return fd;
......@@ -1926,7 +1980,8 @@ static void CallUserSignalHandler(ThreadState *thr, bool sync, bool acquire,
19261980 // because in async signal processing case (when handler is called directly
19271981 // from rtl_generic_sighandler) we have not yet received the reraised
19281982 // signal; and it looks too fragile to intercept all ways to reraise a signal.
1929 if (flags()->report_bugs && !sync && sig != SIGTERM && errno != 99) {
1983 if (ShouldReport(thr, ReportTypeErrnoInSignal) && !sync && sig != SIGTERM &&
1984 errno != 99) {
19301985 VarSizeStackTrace stack;
19311986 // StackTrace::GetNestInstructionPc(pc) is used because return address is
19321987 // expected, OutputReport() will undo this.
......@@ -2096,26 +2151,32 @@ TSAN_INTERCEPTOR(int, fork, int fake) {
20962151 if (in_symbolizer())
20972152 return REAL(fork)(fake);
20982153 SCOPED_INTERCEPTOR_RAW(fork, fake);
2154 return REAL(fork)(fake);
2155}
2156
2157void atfork_prepare() {
2158 if (in_symbolizer())
2159 return;
2160 ThreadState *thr = cur_thread();
2161 const uptr pc = StackTrace::GetCurrentPc();
20992162 ForkBefore(thr, pc);
2100 int pid;
2101 {
2102 // On OS X, REAL(fork) can call intercepted functions (OSSpinLockLock), and
2103 // we'll assert in CheckNoLocks() unless we ignore interceptors.
2104 ScopedIgnoreInterceptors ignore;
2105 pid = REAL(fork)(fake);
2106 }
2107 if (pid == 0) {
2108 // child
2109 ForkChildAfter(thr, pc);
2110 FdOnFork(thr, pc);
2111 } else if (pid > 0) {
2112 // parent
2113 ForkParentAfter(thr, pc);
2114 } else {
2115 // error
2116 ForkParentAfter(thr, pc);
2117 }
2118 return pid;
2163}
2164
2165void atfork_parent() {
2166 if (in_symbolizer())
2167 return;
2168 ThreadState *thr = cur_thread();
2169 const uptr pc = StackTrace::GetCurrentPc();
2170 ForkParentAfter(thr, pc);
2171}
2172
2173void atfork_child() {
2174 if (in_symbolizer())
2175 return;
2176 ThreadState *thr = cur_thread();
2177 const uptr pc = StackTrace::GetCurrentPc();
2178 ForkChildAfter(thr, pc);
2179 FdOnFork(thr, pc);
21192180}
21202181
21212182TSAN_INTERCEPTOR(int, vfork, int fake) {
......@@ -2211,11 +2272,14 @@ static void HandleRecvmsg(ThreadState *thr, uptr pc,
22112272#define NEED_TLS_GET_ADDR
22122273#endif
22132274#undef SANITIZER_INTERCEPT_TLS_GET_ADDR
2275#define SANITIZER_INTERCEPT_TLS_GET_OFFSET 1
22142276#undef SANITIZER_INTERCEPT_PTHREAD_SIGMASK
22152277
22162278#define COMMON_INTERCEPT_FUNCTION(name) INTERCEPT_FUNCTION(name)
22172279#define COMMON_INTERCEPT_FUNCTION_VER(name, ver) \
22182280 INTERCEPT_FUNCTION_VER(name, ver)
2281#define COMMON_INTERCEPT_FUNCTION_VER_UNVERSIONED_FALLBACK(name, ver) \
2282 (INTERCEPT_FUNCTION_VER(name, ver) || INTERCEPT_FUNCTION(name))
22192283
22202284#define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size) \
22212285 MemoryAccessRange(((TsanInterceptorContext *)ctx)->thr, \
......@@ -2359,6 +2423,10 @@ int sigaction_impl(int sig, const __sanitizer_sigaction *act,
23592423 // the signal handler through rtl_sigaction, very bad things will happen.
23602424 // The handler will run synchronously and corrupt tsan per-thread state.
23612425 SCOPED_INTERCEPTOR_RAW(sigaction, sig, act, old);
2426 if (sig <= 0 || sig >= kSigCount) {
2427 errno = errno_EINVAL;
2428 return -1;
2429 }
23622430 __sanitizer_sigaction *sigactions = interceptor_ctx()->sigactions;
23632431 __sanitizer_sigaction old_stored;
23642432 if (old) internal_memcpy(&old_stored, &sigactions[sig], sizeof(old_stored));
......@@ -2437,13 +2505,13 @@ static void syscall_access_range(uptr pc, uptr p, uptr s, bool write) {
24372505 MemoryAccessRange(thr, pc, p, s, write);
24382506}
24392507
2440static void syscall_acquire(uptr pc, uptr addr) {
2508static USED void syscall_acquire(uptr pc, uptr addr) {
24412509 TSAN_SYSCALL();
24422510 Acquire(thr, pc, addr);
24432511 DPrintf("syscall_acquire(%p)\n", addr);
24442512}
24452513
2446static void syscall_release(uptr pc, uptr addr) {
2514static USED void syscall_release(uptr pc, uptr addr) {
24472515 TSAN_SYSCALL();
24482516 DPrintf("syscall_release(%p)\n", addr);
24492517 Release(thr, pc, addr);
......@@ -2466,13 +2534,10 @@ static USED void syscall_fd_release(uptr pc, int fd) {
24662534 FdRelease(thr, pc, fd);
24672535}
24682536
2469static void syscall_pre_fork(uptr pc) {
2470 TSAN_SYSCALL();
2471 ForkBefore(thr, pc);
2472}
2537static void syscall_pre_fork(uptr pc) { ForkBefore(cur_thread(), pc); }
24732538
24742539static void syscall_post_fork(uptr pc, int pid) {
2475 TSAN_SYSCALL();
2540 ThreadState *thr = cur_thread();
24762541 if (pid == 0) {
24772542 // child
24782543 ForkChildAfter(thr, pc);
......@@ -2527,6 +2592,20 @@ static void syscall_post_fork(uptr pc, int pid) {
25272592#include "sanitizer_common/sanitizer_syscalls_netbsd.inc"
25282593
25292594#ifdef NEED_TLS_GET_ADDR
2595
2596static void handle_tls_addr(void *arg, void *res) {
2597 ThreadState *thr = cur_thread();
2598 if (!thr)
2599 return;
2600 DTLS::DTV *dtv = DTLS_on_tls_get_addr(arg, res, thr->tls_addr,
2601 thr->tls_addr + thr->tls_size);
2602 if (!dtv)
2603 return;
2604 // New DTLS block has been allocated.
2605 MemoryResetRange(thr, 0, dtv->beg, dtv->size);
2606}
2607
2608#if !SANITIZER_S390
25302609// Define own interceptor instead of sanitizer_common's for three reasons:
25312610// 1. It must not process pending signals.
25322611// Signal handlers may contain MOVDQA instruction (see below).
......@@ -2539,17 +2618,17 @@ static void syscall_post_fork(uptr pc, int pid) {
25392618// execute MOVDQA with stack addresses.
25402619TSAN_INTERCEPTOR(void *, __tls_get_addr, void *arg) {
25412620 void *res = REAL(__tls_get_addr)(arg);
2542 ThreadState *thr = cur_thread();
2543 if (!thr)
2544 return res;
2545 DTLS::DTV *dtv = DTLS_on_tls_get_addr(arg, res, thr->tls_addr,
2546 thr->tls_addr + thr->tls_size);
2547 if (!dtv)
2548 return res;
2549 // New DTLS block has been allocated.
2550 MemoryResetRange(thr, 0, dtv->beg, dtv->size);
2621 handle_tls_addr(arg, res);
25512622 return res;
25522623}
2624#else // SANITIZER_S390
2625TSAN_INTERCEPTOR(uptr, __tls_get_addr_internal, void *arg) {
2626 uptr res = __tls_get_offset_wrapper(arg, REAL(__tls_get_offset));
2627 char *tp = static_cast<char *>(__builtin_thread_pointer());
2628 handle_tls_addr(arg, res + tp);
2629 return res;
2630}
2631#endif
25532632#endif
25542633
25552634#if SANITIZER_NETBSD
......@@ -2622,7 +2701,7 @@ void InitializeInterceptors() {
26222701#endif
26232702
26242703 // Instruct libc malloc to consume less memory.
2625#if SANITIZER_LINUX
2704#if SANITIZER_GLIBC
26262705 mallopt(1, 0); // M_MXFAST
26272706 mallopt(-3, 32*1024); // M_MMAP_THRESHOLD
26282707#endif
......@@ -2685,6 +2764,8 @@ void InitializeInterceptors() {
26852764 TSAN_INTERCEPT_VER(pthread_cond_timedwait, PTHREAD_ABI_BASE);
26862765 TSAN_INTERCEPT_VER(pthread_cond_destroy, PTHREAD_ABI_BASE);
26872766
2767 TSAN_MAYBE_PTHREAD_COND_CLOCKWAIT;
2768
26882769 TSAN_INTERCEPT(pthread_mutex_init);
26892770 TSAN_INTERCEPT(pthread_mutex_destroy);
26902771 TSAN_INTERCEPT(pthread_mutex_trylock);
......@@ -2770,7 +2851,12 @@ void InitializeInterceptors() {
27702851 TSAN_INTERCEPT(_exit);
27712852
27722853#ifdef NEED_TLS_GET_ADDR
2854#if !SANITIZER_S390
27732855 TSAN_INTERCEPT(__tls_get_addr);
2856#else
2857 TSAN_INTERCEPT(__tls_get_addr_internal);
2858 TSAN_INTERCEPT(__tls_get_offset);
2859#endif
27742860#endif
27752861
27762862 TSAN_MAYBE_INTERCEPT__LWP_EXIT;
......@@ -2786,6 +2872,10 @@ void InitializeInterceptors() {
27862872 Printf("ThreadSanitizer: failed to setup atexit callback\n");
27872873 Die();
27882874 }
2875 if (pthread_atfork(atfork_prepare, atfork_parent, atfork_child)) {
2876 Printf("ThreadSanitizer: failed to setup atfork callbacks\n");
2877 Die();
2878 }
27892879
27902880#if !SANITIZER_MAC && !SANITIZER_NETBSD && !SANITIZER_FREEBSD
27912881 if (pthread_key_create(&interceptor_ctx()->finalize_key, &thread_finalize)) {
lib/tsan/tsan_interface.cpp+5-8
......@@ -14,15 +14,12 @@
1414#include "tsan_interface_ann.h"
1515#include "tsan_rtl.h"
1616#include "sanitizer_common/sanitizer_internal_defs.h"
17#include "sanitizer_common/sanitizer_ptrauth.h"
1718
1819#define CALLERPC ((uptr)__builtin_return_address(0))
1920
2021using namespace __tsan;
2122
22typedef u16 uint16_t;
23typedef u32 uint32_t;
24typedef u64 uint64_t;
25
2623void __tsan_init() {
2724 cur_thread_init();
2825 Initialize(cur_thread());
......@@ -43,13 +40,13 @@ void __tsan_write16(void *addr) {
4340}
4441
4542void __tsan_read16_pc(void *addr, void *pc) {
46 MemoryRead(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog8);
47 MemoryRead(cur_thread(), (uptr)pc, (uptr)addr + 8, kSizeLog8);
43 MemoryRead(cur_thread(), STRIP_PAC_PC(pc), (uptr)addr, kSizeLog8);
44 MemoryRead(cur_thread(), STRIP_PAC_PC(pc), (uptr)addr + 8, kSizeLog8);
4845}
4946
5047void __tsan_write16_pc(void *addr, void *pc) {
51 MemoryWrite(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog8);
52 MemoryWrite(cur_thread(), (uptr)pc, (uptr)addr + 8, kSizeLog8);
48 MemoryWrite(cur_thread(), STRIP_PAC_PC(pc), (uptr)addr, kSizeLog8);
49 MemoryWrite(cur_thread(), STRIP_PAC_PC(pc), (uptr)addr + 8, kSizeLog8);
5350}
5451
5552// __tsan_unaligned_read/write calls are emitted by compiler.
lib/tsan/tsan_interface.h+10-2
......@@ -196,7 +196,8 @@ typedef unsigned short a16;
196196typedef unsigned int a32;
197197typedef unsigned long long a64;
198198#if !SANITIZER_GO && (defined(__SIZEOF_INT128__) \
199 || (__clang_major__ * 100 + __clang_minor__ >= 302)) && !defined(__mips64)
199 || (__clang_major__ * 100 + __clang_minor__ >= 302)) && \
200 !defined(__mips64) && !defined(__s390x__)
200201__extension__ typedef __int128 a128;
201202# define __TSAN_HAS_INT128 1
202203#else
......@@ -204,7 +205,7 @@ __extension__ typedef __int128 a128;
204205#endif
205206
206207// Part of ABI, do not change.
207// https://github.com/llvm/llvm-project/blob/master/libcxx/include/atomic
208// https://github.com/llvm/llvm-project/blob/main/libcxx/include/atomic
208209typedef enum {
209210 mo_relaxed,
210211 mo_consume,
......@@ -415,6 +416,13 @@ void __tsan_go_atomic32_compare_exchange(ThreadState *thr, uptr cpc, uptr pc,
415416SANITIZER_INTERFACE_ATTRIBUTE
416417void __tsan_go_atomic64_compare_exchange(ThreadState *thr, uptr cpc, uptr pc,
417418 u8 *a);
419
420SANITIZER_INTERFACE_ATTRIBUTE
421void __tsan_on_initialize();
422
423SANITIZER_INTERFACE_ATTRIBUTE
424int __tsan_on_finalize(int failed);
425
418426} // extern "C"
419427
420428} // namespace __tsan
lib/tsan/tsan_interface_ann.cpp+2-7
......@@ -15,7 +15,6 @@
1515#include "sanitizer_common/sanitizer_stacktrace.h"
1616#include "sanitizer_common/sanitizer_vector.h"
1717#include "tsan_interface_ann.h"
18#include "tsan_mutex.h"
1918#include "tsan_report.h"
2019#include "tsan_rtl.h"
2120#include "tsan_mman.h"
......@@ -38,7 +37,7 @@ class ScopedAnnotation {
3837
3938 ~ScopedAnnotation() {
4039 FuncExit(thr_);
41 CheckNoLocks(thr_);
40 CheckedMutex::CheckNoLocks();
4241 }
4342 private:
4443 ThreadState *const thr_;
......@@ -49,8 +48,6 @@ class ScopedAnnotation {
4948 return ret; \
5049 ThreadState *thr = cur_thread(); \
5150 const uptr caller_pc = (uptr)__builtin_return_address(0); \
52 StatInc(thr, StatAnnotation); \
53 StatInc(thr, Stat##typ); \
5451 ScopedAnnotation sa(thr, __func__, caller_pc); \
5552 const uptr pc = StackTrace::GetCurrentPc(); \
5653 (void)pc; \
......@@ -77,9 +74,7 @@ struct DynamicAnnContext {
7774 ExpectRace expect;
7875 ExpectRace benign;
7976
80 DynamicAnnContext()
81 : mtx(MutexTypeAnnotations, StatMtxAnnotations) {
82 }
77 DynamicAnnContext() : mtx(MutexTypeAnnotations) {}
8378};
8479
8580static DynamicAnnContext *dyn_ann_ctx;
lib/tsan/tsan_interface_atomic.cpp+35-39
......@@ -218,8 +218,9 @@ static a128 NoTsanAtomicLoad(const volatile a128 *a, morder mo) {
218218}
219219#endif
220220
221template<typename T>
222static T AtomicLoad(ThreadState *thr, uptr pc, const volatile T *a, morder mo) {
221template <typename T>
222static T AtomicLoad(ThreadState *thr, uptr pc, const volatile T *a,
223 morder mo) NO_THREAD_SAFETY_ANALYSIS {
223224 CHECK(IsLoadOrder(mo));
224225 // This fast-path is critical for performance.
225226 // Assume the access is atomic.
......@@ -254,9 +255,9 @@ static void NoTsanAtomicStore(volatile a128 *a, a128 v, morder mo) {
254255}
255256#endif
256257
257template<typename T>
258template <typename T>
258259static void AtomicStore(ThreadState *thr, uptr pc, volatile T *a, T v,
259 morder mo) {
260 morder mo) NO_THREAD_SAFETY_ANALYSIS {
260261 CHECK(IsStoreOrder(mo));
261262 MemoryWriteAtomic(thr, pc, (uptr)a, SizeLog<T>());
262263 // This fast-path is critical for performance.
......@@ -277,8 +278,9 @@ static void AtomicStore(ThreadState *thr, uptr pc, volatile T *a, T v,
277278 s->mtx.Unlock();
278279}
279280
280template<typename T, T (*F)(volatile T *v, T op)>
281static T AtomicRMW(ThreadState *thr, uptr pc, volatile T *a, T v, morder mo) {
281template <typename T, T (*F)(volatile T *v, T op)>
282static T AtomicRMW(ThreadState *thr, uptr pc, volatile T *a, T v,
283 morder mo) NO_THREAD_SAFETY_ANALYSIS {
282284 MemoryWriteAtomic(thr, pc, (uptr)a, SizeLog<T>());
283285 SyncVar *s = 0;
284286 if (mo != mo_relaxed) {
......@@ -399,37 +401,48 @@ static T NoTsanAtomicCAS(volatile T *a, T c, T v, morder mo, morder fmo) {
399401 return c;
400402}
401403
402template<typename T>
403static bool AtomicCAS(ThreadState *thr, uptr pc,
404 volatile T *a, T *c, T v, morder mo, morder fmo) {
405 (void)fmo; // Unused because llvm does not pass it yet.
404template <typename T>
405static bool AtomicCAS(ThreadState *thr, uptr pc, volatile T *a, T *c, T v, morder mo,
406 morder fmo) NO_THREAD_SAFETY_ANALYSIS {
407 // 31.7.2.18: "The failure argument shall not be memory_order_release
408 // nor memory_order_acq_rel". LLVM (2021-05) fallbacks to Monotonic
409 // (mo_relaxed) when those are used.
410 CHECK(IsLoadOrder(fmo));
411
406412 MemoryWriteAtomic(thr, pc, (uptr)a, SizeLog<T>());
407413 SyncVar *s = 0;
408 bool write_lock = mo != mo_acquire && mo != mo_consume;
409 if (mo != mo_relaxed) {
414 bool write_lock = IsReleaseOrder(mo);
415
416 if (mo != mo_relaxed || fmo != mo_relaxed)
410417 s = ctx->metamap.GetOrCreateAndLock(thr, pc, (uptr)a, write_lock);
418
419 T cc = *c;
420 T pr = func_cas(a, cc, v);
421 bool success = pr == cc;
422 if (!success) {
423 *c = pr;
424 mo = fmo;
425 }
426
427 if (s) {
411428 thr->fast_state.IncrementEpoch();
412429 // Can't increment epoch w/o writing to the trace as well.
413430 TraceAddEvent(thr, thr->fast_state, EventTypeMop, 0);
414 if (IsAcqRelOrder(mo))
431
432 if (success && IsAcqRelOrder(mo))
415433 AcquireReleaseImpl(thr, pc, &s->clock);
416 else if (IsReleaseOrder(mo))
434 else if (success && IsReleaseOrder(mo))
417435 ReleaseImpl(thr, pc, &s->clock);
418436 else if (IsAcquireOrder(mo))
419437 AcquireImpl(thr, pc, &s->clock);
420 }
421 T cc = *c;
422 T pr = func_cas(a, cc, v);
423 if (s) {
438
424439 if (write_lock)
425440 s->mtx.Unlock();
426441 else
427442 s->mtx.ReadUnlock();
428443 }
429 if (pr == cc)
430 return true;
431 *c = pr;
432 return false;
444
445 return success;
433446}
434447
435448template<typename T>
......@@ -481,7 +494,6 @@ static morder convert_morder(morder mo) {
481494 const uptr callpc = (uptr)__builtin_return_address(0); \
482495 uptr pc = StackTrace::GetCurrentPc(); \
483496 mo = convert_morder(mo); \
484 AtomicStatInc(thr, sizeof(*a), mo, StatAtomic##func); \
485497 ScopedAtomic sa(thr, callpc, a, mo, __func__); \
486498 return Atomic##func(thr, pc, __VA_ARGS__); \
487499/**/
......@@ -502,22 +514,6 @@ class ScopedAtomic {
502514 ThreadState *thr_;
503515};
504516
505static void AtomicStatInc(ThreadState *thr, uptr size, morder mo, StatType t) {
506 StatInc(thr, StatAtomic);
507 StatInc(thr, t);
508 StatInc(thr, size == 1 ? StatAtomic1
509 : size == 2 ? StatAtomic2
510 : size == 4 ? StatAtomic4
511 : size == 8 ? StatAtomic8
512 : StatAtomic16);
513 StatInc(thr, mo == mo_relaxed ? StatAtomicRelaxed
514 : mo == mo_consume ? StatAtomicConsume
515 : mo == mo_acquire ? StatAtomicAcquire
516 : mo == mo_release ? StatAtomicRelease
517 : mo == mo_acq_rel ? StatAtomicAcq_Rel
518 : StatAtomicSeq_Cst);
519}
520
521517extern "C" {
522518SANITIZER_INTERFACE_ATTRIBUTE
523519a8 __tsan_atomic8_load(const volatile a8 *a, morder mo) {
lib/tsan/tsan_interface_inl.h+12-11
......@@ -12,6 +12,7 @@
1212
1313#include "tsan_interface.h"
1414#include "tsan_rtl.h"
15#include "sanitizer_common/sanitizer_ptrauth.h"
1516
1617#define CALLERPC ((uptr)__builtin_return_address(0))
1718
......@@ -50,35 +51,35 @@ void __tsan_write8(void *addr) {
5051}
5152
5253void __tsan_read1_pc(void *addr, void *pc) {
53 MemoryRead(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog1);
54 MemoryRead(cur_thread(), STRIP_PAC_PC(pc), (uptr)addr, kSizeLog1);
5455}
5556
5657void __tsan_read2_pc(void *addr, void *pc) {
57 MemoryRead(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog2);
58 MemoryRead(cur_thread(), STRIP_PAC_PC(pc), (uptr)addr, kSizeLog2);
5859}
5960
6061void __tsan_read4_pc(void *addr, void *pc) {
61 MemoryRead(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog4);
62 MemoryRead(cur_thread(), STRIP_PAC_PC(pc), (uptr)addr, kSizeLog4);
6263}
6364
6465void __tsan_read8_pc(void *addr, void *pc) {
65 MemoryRead(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog8);
66 MemoryRead(cur_thread(), STRIP_PAC_PC(pc), (uptr)addr, kSizeLog8);
6667}
6768
6869void __tsan_write1_pc(void *addr, void *pc) {
69 MemoryWrite(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog1);
70 MemoryWrite(cur_thread(), STRIP_PAC_PC(pc), (uptr)addr, kSizeLog1);
7071}
7172
7273void __tsan_write2_pc(void *addr, void *pc) {
73 MemoryWrite(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog2);
74 MemoryWrite(cur_thread(), STRIP_PAC_PC(pc), (uptr)addr, kSizeLog2);
7475}
7576
7677void __tsan_write4_pc(void *addr, void *pc) {
77 MemoryWrite(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog4);
78 MemoryWrite(cur_thread(), STRIP_PAC_PC(pc), (uptr)addr, kSizeLog4);
7879}
7980
8081void __tsan_write8_pc(void *addr, void *pc) {
81 MemoryWrite(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog8);
82 MemoryWrite(cur_thread(), STRIP_PAC_PC(pc), (uptr)addr, kSizeLog8);
8283}
8384
8485void __tsan_vptr_update(void **vptr_p, void *new_val) {
......@@ -100,7 +101,7 @@ void __tsan_vptr_read(void **vptr_p) {
100101}
101102
102103void __tsan_func_entry(void *pc) {
103 FuncEntry(cur_thread(), (uptr)pc);
104 FuncEntry(cur_thread(), STRIP_PAC_PC(pc));
104105}
105106
106107void __tsan_func_exit() {
......@@ -124,9 +125,9 @@ void __tsan_write_range(void *addr, uptr size) {
124125}
125126
126127void __tsan_read_range_pc(void *addr, uptr size, void *pc) {
127 MemoryAccessRange(cur_thread(), (uptr)pc, (uptr)addr, size, false);
128 MemoryAccessRange(cur_thread(), STRIP_PAC_PC(pc), (uptr)addr, size, false);
128129}
129130
130131void __tsan_write_range_pc(void *addr, uptr size, void *pc) {
131 MemoryAccessRange(cur_thread(), (uptr)pc, (uptr)addr, size, true);
132 MemoryAccessRange(cur_thread(), STRIP_PAC_PC(pc), (uptr)addr, size, true);
132133}
lib/tsan/tsan_interface_java.cpp-1
......@@ -12,7 +12,6 @@
1212
1313#include "tsan_interface_java.h"
1414#include "tsan_rtl.h"
15#include "tsan_mutex.h"
1615#include "sanitizer_common/sanitizer_internal_defs.h"
1716#include "sanitizer_common/sanitizer_common.h"
1817#include "sanitizer_common/sanitizer_placement_new.h"
lib/tsan/tsan_mman.cpp+2-5
......@@ -70,10 +70,7 @@ struct GlobalProc {
7070 Mutex mtx;
7171 Processor *proc;
7272
73 GlobalProc()
74 : mtx(MutexTypeGlobalProc, StatMtxGlobalProc)
75 , proc(ProcCreate()) {
76 }
73 GlobalProc() : mtx(MutexTypeGlobalProc), proc(ProcCreate()) {}
7774};
7875
7976static char global_proc_placeholder[sizeof(GlobalProc)] ALIGNED(64);
......@@ -145,7 +142,7 @@ void AllocatorPrintStats() {
145142
146143static void SignalUnsafeCall(ThreadState *thr, uptr pc) {
147144 if (atomic_load_relaxed(&thr->in_signal_handler) == 0 ||
148 !flags()->report_signal_unsafe)
145 !ShouldReport(thr, ReportTypeSignalUnsafe))
149146 return;
150147 VarSizeStackTrace stack;
151148 ObtainCurrentStack(thr, pc, &stack);
lib/tsan/tsan_mutex.cpp deleted-289
......@@ -1,289 +0,0 @@
1//===-- tsan_mutex.cpp ----------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file is a part of ThreadSanitizer (TSan), a race detector.
10//
11//===----------------------------------------------------------------------===//
12#include "sanitizer_common/sanitizer_libc.h"
13#include "tsan_mutex.h"
14#include "tsan_platform.h"
15#include "tsan_rtl.h"
16
17namespace __tsan {
18
19// Simple reader-writer spin-mutex. Optimized for not-so-contended case.
20// Readers have preference, can possibly starvate writers.
21
22// The table fixes what mutexes can be locked under what mutexes.
23// E.g. if the row for MutexTypeThreads contains MutexTypeReport,
24// then Report mutex can be locked while under Threads mutex.
25// The leaf mutexes can be locked under any other mutexes.
26// Recursive locking is not supported.
27#if SANITIZER_DEBUG && !SANITIZER_GO
28const MutexType MutexTypeLeaf = (MutexType)-1;
29static MutexType CanLockTab[MutexTypeCount][MutexTypeCount] = {
30 /*0 MutexTypeInvalid*/ {},
31 /*1 MutexTypeTrace*/ {MutexTypeLeaf},
32 /*2 MutexTypeThreads*/ {MutexTypeReport},
33 /*3 MutexTypeReport*/ {MutexTypeSyncVar,
34 MutexTypeMBlock, MutexTypeJavaMBlock},
35 /*4 MutexTypeSyncVar*/ {MutexTypeDDetector},
36 /*5 MutexTypeSyncTab*/ {}, // unused
37 /*6 MutexTypeSlab*/ {MutexTypeLeaf},
38 /*7 MutexTypeAnnotations*/ {},
39 /*8 MutexTypeAtExit*/ {MutexTypeSyncVar},
40 /*9 MutexTypeMBlock*/ {MutexTypeSyncVar},
41 /*10 MutexTypeJavaMBlock*/ {MutexTypeSyncVar},
42 /*11 MutexTypeDDetector*/ {},
43 /*12 MutexTypeFired*/ {MutexTypeLeaf},
44 /*13 MutexTypeRacy*/ {MutexTypeLeaf},
45 /*14 MutexTypeGlobalProc*/ {},
46};
47
48static bool CanLockAdj[MutexTypeCount][MutexTypeCount];
49#endif
50
51void InitializeMutex() {
52#if SANITIZER_DEBUG && !SANITIZER_GO
53 // Build the "can lock" adjacency matrix.
54 // If [i][j]==true, then one can lock mutex j while under mutex i.
55 const int N = MutexTypeCount;
56 int cnt[N] = {};
57 bool leaf[N] = {};
58 for (int i = 1; i < N; i++) {
59 for (int j = 0; j < N; j++) {
60 MutexType z = CanLockTab[i][j];
61 if (z == MutexTypeInvalid)
62 continue;
63 if (z == MutexTypeLeaf) {
64 CHECK(!leaf[i]);
65 leaf[i] = true;
66 continue;
67 }
68 CHECK(!CanLockAdj[i][(int)z]);
69 CanLockAdj[i][(int)z] = true;
70 cnt[i]++;
71 }
72 }
73 for (int i = 0; i < N; i++) {
74 CHECK(!leaf[i] || cnt[i] == 0);
75 }
76 // Add leaf mutexes.
77 for (int i = 0; i < N; i++) {
78 if (!leaf[i])
79 continue;
80 for (int j = 0; j < N; j++) {
81 if (i == j || leaf[j] || j == MutexTypeInvalid)
82 continue;
83 CHECK(!CanLockAdj[j][i]);
84 CanLockAdj[j][i] = true;
85 }
86 }
87 // Build the transitive closure.
88 bool CanLockAdj2[MutexTypeCount][MutexTypeCount];
89 for (int i = 0; i < N; i++) {
90 for (int j = 0; j < N; j++) {
91 CanLockAdj2[i][j] = CanLockAdj[i][j];
92 }
93 }
94 for (int k = 0; k < N; k++) {
95 for (int i = 0; i < N; i++) {
96 for (int j = 0; j < N; j++) {
97 if (CanLockAdj2[i][k] && CanLockAdj2[k][j]) {
98 CanLockAdj2[i][j] = true;
99 }
100 }
101 }
102 }
103#if 0
104 Printf("Can lock graph:\n");
105 for (int i = 0; i < N; i++) {
106 for (int j = 0; j < N; j++) {
107 Printf("%d ", CanLockAdj[i][j]);
108 }
109 Printf("\n");
110 }
111 Printf("Can lock graph closure:\n");
112 for (int i = 0; i < N; i++) {
113 for (int j = 0; j < N; j++) {
114 Printf("%d ", CanLockAdj2[i][j]);
115 }
116 Printf("\n");
117 }
118#endif
119 // Verify that the graph is acyclic.
120 for (int i = 0; i < N; i++) {
121 if (CanLockAdj2[i][i]) {
122 Printf("Mutex %d participates in a cycle\n", i);
123 Die();
124 }
125 }
126#endif
127}
128
129InternalDeadlockDetector::InternalDeadlockDetector() {
130 // Rely on zero initialization because some mutexes can be locked before ctor.
131}
132
133#if SANITIZER_DEBUG && !SANITIZER_GO
134void InternalDeadlockDetector::Lock(MutexType t) {
135 // Printf("LOCK %d @%zu\n", t, seq_ + 1);
136 CHECK_GT(t, MutexTypeInvalid);
137 CHECK_LT(t, MutexTypeCount);
138 u64 max_seq = 0;
139 u64 max_idx = MutexTypeInvalid;
140 for (int i = 0; i != MutexTypeCount; i++) {
141 if (locked_[i] == 0)
142 continue;
143 CHECK_NE(locked_[i], max_seq);
144 if (max_seq < locked_[i]) {
145 max_seq = locked_[i];
146 max_idx = i;
147 }
148 }
149 locked_[t] = ++seq_;
150 if (max_idx == MutexTypeInvalid)
151 return;
152 // Printf(" last %d @%zu\n", max_idx, max_seq);
153 if (!CanLockAdj[max_idx][t]) {
154 Printf("ThreadSanitizer: internal deadlock detected\n");
155 Printf("ThreadSanitizer: can't lock %d while under %zu\n",
156 t, (uptr)max_idx);
157 CHECK(0);
158 }
159}
160
161void InternalDeadlockDetector::Unlock(MutexType t) {
162 // Printf("UNLO %d @%zu #%zu\n", t, seq_, locked_[t]);
163 CHECK(locked_[t]);
164 locked_[t] = 0;
165}
166
167void InternalDeadlockDetector::CheckNoLocks() {
168 for (int i = 0; i != MutexTypeCount; i++) {
169 CHECK_EQ(locked_[i], 0);
170 }
171}
172#endif
173
174void CheckNoLocks(ThreadState *thr) {
175#if SANITIZER_DEBUG && !SANITIZER_GO
176 thr->internal_deadlock_detector.CheckNoLocks();
177#endif
178}
179
180const uptr kUnlocked = 0;
181const uptr kWriteLock = 1;
182const uptr kReadLock = 2;
183
184class Backoff {
185 public:
186 Backoff()
187 : iter_() {
188 }
189
190 bool Do() {
191 if (iter_++ < kActiveSpinIters)
192 proc_yield(kActiveSpinCnt);
193 else
194 internal_sched_yield();
195 return true;
196 }
197
198 u64 Contention() const {
199 u64 active = iter_ % kActiveSpinIters;
200 u64 passive = iter_ - active;
201 return active + 10 * passive;
202 }
203
204 private:
205 int iter_;
206 static const int kActiveSpinIters = 10;
207 static const int kActiveSpinCnt = 20;
208};
209
210Mutex::Mutex(MutexType type, StatType stat_type) {
211 CHECK_GT(type, MutexTypeInvalid);
212 CHECK_LT(type, MutexTypeCount);
213#if SANITIZER_DEBUG
214 type_ = type;
215#endif
216#if TSAN_COLLECT_STATS
217 stat_type_ = stat_type;
218#endif
219 atomic_store(&state_, kUnlocked, memory_order_relaxed);
220}
221
222Mutex::~Mutex() {
223 CHECK_EQ(atomic_load(&state_, memory_order_relaxed), kUnlocked);
224}
225
226void Mutex::Lock() {
227#if SANITIZER_DEBUG && !SANITIZER_GO
228 cur_thread()->internal_deadlock_detector.Lock(type_);
229#endif
230 uptr cmp = kUnlocked;
231 if (atomic_compare_exchange_strong(&state_, &cmp, kWriteLock,
232 memory_order_acquire))
233 return;
234 for (Backoff backoff; backoff.Do();) {
235 if (atomic_load(&state_, memory_order_relaxed) == kUnlocked) {
236 cmp = kUnlocked;
237 if (atomic_compare_exchange_weak(&state_, &cmp, kWriteLock,
238 memory_order_acquire)) {
239#if TSAN_COLLECT_STATS && !SANITIZER_GO
240 StatInc(cur_thread(), stat_type_, backoff.Contention());
241#endif
242 return;
243 }
244 }
245 }
246}
247
248void Mutex::Unlock() {
249 uptr prev = atomic_fetch_sub(&state_, kWriteLock, memory_order_release);
250 (void)prev;
251 DCHECK_NE(prev & kWriteLock, 0);
252#if SANITIZER_DEBUG && !SANITIZER_GO
253 cur_thread()->internal_deadlock_detector.Unlock(type_);
254#endif
255}
256
257void Mutex::ReadLock() {
258#if SANITIZER_DEBUG && !SANITIZER_GO
259 cur_thread()->internal_deadlock_detector.Lock(type_);
260#endif
261 uptr prev = atomic_fetch_add(&state_, kReadLock, memory_order_acquire);
262 if ((prev & kWriteLock) == 0)
263 return;
264 for (Backoff backoff; backoff.Do();) {
265 prev = atomic_load(&state_, memory_order_acquire);
266 if ((prev & kWriteLock) == 0) {
267#if TSAN_COLLECT_STATS && !SANITIZER_GO
268 StatInc(cur_thread(), stat_type_, backoff.Contention());
269#endif
270 return;
271 }
272 }
273}
274
275void Mutex::ReadUnlock() {
276 uptr prev = atomic_fetch_sub(&state_, kReadLock, memory_order_release);
277 (void)prev;
278 DCHECK_EQ(prev & kWriteLock, 0);
279 DCHECK_GT(prev & ~kWriteLock, 0);
280#if SANITIZER_DEBUG && !SANITIZER_GO
281 cur_thread()->internal_deadlock_detector.Unlock(type_);
282#endif
283}
284
285void Mutex::CheckLocked() {
286 CHECK_NE(atomic_load(&state_, memory_order_relaxed), 0);
287}
288
289} // namespace __tsan
lib/tsan/tsan_mutex.h deleted-90
......@@ -1,90 +0,0 @@
1//===-- tsan_mutex.h --------------------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file is a part of ThreadSanitizer (TSan), a race detector.
10//
11//===----------------------------------------------------------------------===//
12#ifndef TSAN_MUTEX_H
13#define TSAN_MUTEX_H
14
15#include "sanitizer_common/sanitizer_atomic.h"
16#include "sanitizer_common/sanitizer_mutex.h"
17#include "tsan_defs.h"
18
19namespace __tsan {
20
21enum MutexType {
22 MutexTypeInvalid,
23 MutexTypeTrace,
24 MutexTypeThreads,
25 MutexTypeReport,
26 MutexTypeSyncVar,
27 MutexTypeSyncTab,
28 MutexTypeSlab,
29 MutexTypeAnnotations,
30 MutexTypeAtExit,
31 MutexTypeMBlock,
32 MutexTypeJavaMBlock,
33 MutexTypeDDetector,
34 MutexTypeFired,
35 MutexTypeRacy,
36 MutexTypeGlobalProc,
37
38 // This must be the last.
39 MutexTypeCount
40};
41
42class Mutex {
43 public:
44 explicit Mutex(MutexType type, StatType stat_type);
45 ~Mutex();
46
47 void Lock();
48 void Unlock();
49
50 void ReadLock();
51 void ReadUnlock();
52
53 void CheckLocked();
54
55 private:
56 atomic_uintptr_t state_;
57#if SANITIZER_DEBUG
58 MutexType type_;
59#endif
60#if TSAN_COLLECT_STATS
61 StatType stat_type_;
62#endif
63
64 Mutex(const Mutex&);
65 void operator = (const Mutex&);
66};
67
68typedef GenericScopedLock<Mutex> Lock;
69typedef GenericScopedReadLock<Mutex> ReadLock;
70
71class InternalDeadlockDetector {
72 public:
73 InternalDeadlockDetector();
74 void Lock(MutexType t);
75 void Unlock(MutexType t);
76 void CheckNoLocks();
77 private:
78 u64 seq_;
79 u64 locked_[MutexTypeCount];
80};
81
82void InitializeMutex();
83
84// Checks that the current thread does not hold any runtime locks
85// (e.g. when returning from an interceptor).
86void CheckNoLocks(ThreadState *thr);
87
88} // namespace __tsan
89
90#endif // TSAN_MUTEX_H
lib/tsan/tsan_platform.h+191-8
......@@ -23,9 +23,21 @@
2323
2424namespace __tsan {
2525
26#if defined(__x86_64__)
27#define HAS_48_BIT_ADDRESS_SPACE 1
28#elif SANITIZER_IOSSIM // arm64 iOS simulators (order of #if matters)
29#define HAS_48_BIT_ADDRESS_SPACE 1
30#elif SANITIZER_IOS // arm64 iOS devices (order of #if matters)
31#define HAS_48_BIT_ADDRESS_SPACE 0
32#elif SANITIZER_MAC // arm64 macOS (order of #if matters)
33#define HAS_48_BIT_ADDRESS_SPACE 1
34#else
35#define HAS_48_BIT_ADDRESS_SPACE 0
36#endif
37
2638#if !SANITIZER_GO
2739
28#if defined(__x86_64__)
40#if HAS_48_BIT_ADDRESS_SPACE
2941/*
3042C/C++ on linux/x86_64 and freebsd/x86_64
31430000 0000 1000 - 0080 0000 0000: main binary and/or MAP_32BIT mappings (512GB)
......@@ -93,7 +105,7 @@ fe00 0000 00 - ff00 0000 00: heap (4 GB)
93105ff00 0000 00 - ff80 0000 00: - (2 GB)
94106ff80 0000 00 - ffff ffff ff: modules and main thread stack (<2 GB)
95107*/
96struct Mapping {
108struct Mapping40 {
97109 static const uptr kMetaShadowBeg = 0x4000000000ull;
98110 static const uptr kMetaShadowEnd = 0x5000000000ull;
99111 static const uptr kTraceMemBeg = 0xb000000000ull;
......@@ -114,6 +126,7 @@ struct Mapping {
114126};
115127
116128#define TSAN_MID_APP_RANGE 1
129#define TSAN_RUNTIME_VMA 1
117130#elif defined(__aarch64__) && defined(__APPLE__)
118131/*
119132C/C++ on Darwin/iOS/ARM64 (36-bit VMA, 64 GB VM)
......@@ -146,7 +159,7 @@ struct Mapping {
146159 static const uptr kVdsoBeg = 0x7000000000000000ull;
147160};
148161
149#elif defined(__aarch64__)
162#elif defined(__aarch64__) && !defined(__APPLE__)
150163// AArch64 supports multiple VMA which leads to multiple address transformation
151164// functions. To support these multiple VMAS transformations and mappings TSAN
152165// runtime for AArch64 uses an external memory read (vmaSize) to select which
......@@ -352,9 +365,41 @@ struct Mapping47 {
352365
353366// Indicates the runtime will define the memory regions at runtime.
354367#define TSAN_RUNTIME_VMA 1
368#elif defined(__s390x__)
369/*
370C/C++ on linux/s390x
371While the kernel provides a 64-bit address space, we have to restrict ourselves
372to 48 bits due to how e.g. SyncVar::GetId() works.
3730000 0000 1000 - 0e00 0000 0000: binary, modules, stacks - 14 TiB
3740e00 0000 0000 - 4000 0000 0000: -
3754000 0000 0000 - 8000 0000 0000: shadow - 64TiB (4 * app)
3768000 0000 0000 - 9000 0000 0000: -
3779000 0000 0000 - 9800 0000 0000: metainfo - 8TiB (0.5 * app)
3789800 0000 0000 - a000 0000 0000: -
379a000 0000 0000 - b000 0000 0000: traces - 16TiB (max history * 128k threads)
380b000 0000 0000 - be00 0000 0000: -
381be00 0000 0000 - c000 0000 0000: heap - 2TiB (max supported by the allocator)
382*/
383struct Mapping {
384 static const uptr kMetaShadowBeg = 0x900000000000ull;
385 static const uptr kMetaShadowEnd = 0x980000000000ull;
386 static const uptr kTraceMemBeg = 0xa00000000000ull;
387 static const uptr kTraceMemEnd = 0xb00000000000ull;
388 static const uptr kShadowBeg = 0x400000000000ull;
389 static const uptr kShadowEnd = 0x800000000000ull;
390 static const uptr kHeapMemBeg = 0xbe0000000000ull;
391 static const uptr kHeapMemEnd = 0xc00000000000ull;
392 static const uptr kLoAppMemBeg = 0x000000001000ull;
393 static const uptr kLoAppMemEnd = 0x0e0000000000ull;
394 static const uptr kHiAppMemBeg = 0xc00000004000ull;
395 static const uptr kHiAppMemEnd = 0xc00000004000ull;
396 static const uptr kAppMemMsk = 0xb00000000000ull;
397 static const uptr kAppMemXor = 0x100000000000ull;
398 static const uptr kVdsoBeg = 0xfffffffff000ull;
399};
355400#endif
356401
357#elif SANITIZER_GO && !SANITIZER_WINDOWS && defined(__x86_64__)
402#elif SANITIZER_GO && !SANITIZER_WINDOWS && HAS_48_BIT_ADDRESS_SPACE
358403
359404/* Go on linux, darwin and freebsd on x86_64
3604050000 0000 1000 - 0000 1000 0000: executable
......@@ -461,7 +506,7 @@ struct Mapping47 {
461506
462507#elif SANITIZER_GO && defined(__aarch64__)
463508
464/* Go on linux/aarch64 (48-bit VMA)
509/* Go on linux/aarch64 (48-bit VMA) and darwin/aarch64 (47-bit VMA)
4655100000 0000 1000 - 0000 1000 0000: executable
4665110000 1000 0000 - 00c0 0000 0000: -
46751200c0 0000 0000 - 00e0 0000 0000: heap
......@@ -488,6 +533,55 @@ struct Mapping {
488533// Indicates the runtime will define the memory regions at runtime.
489534#define TSAN_RUNTIME_VMA 1
490535
536#elif SANITIZER_GO && defined(__mips64)
537/*
538Go on linux/mips64 (47-bit VMA)
5390000 0000 1000 - 0000 1000 0000: executable
5400000 1000 0000 - 00c0 0000 0000: -
54100c0 0000 0000 - 00e0 0000 0000: heap
54200e0 0000 0000 - 2000 0000 0000: -
5432000 0000 0000 - 3000 0000 0000: shadow
5443000 0000 0000 - 3000 0000 0000: -
5453000 0000 0000 - 4000 0000 0000: metainfo (memory blocks and sync objects)
5464000 0000 0000 - 6000 0000 0000: -
5476000 0000 0000 - 6200 0000 0000: traces
5486200 0000 0000 - 8000 0000 0000: -
549*/
550struct Mapping47 {
551 static const uptr kMetaShadowBeg = 0x300000000000ull;
552 static const uptr kMetaShadowEnd = 0x400000000000ull;
553 static const uptr kTraceMemBeg = 0x600000000000ull;
554 static const uptr kTraceMemEnd = 0x620000000000ull;
555 static const uptr kShadowBeg = 0x200000000000ull;
556 static const uptr kShadowEnd = 0x300000000000ull;
557 static const uptr kAppMemBeg = 0x000000001000ull;
558 static const uptr kAppMemEnd = 0x00e000000000ull;
559};
560
561#define TSAN_RUNTIME_VMA 1
562
563#elif SANITIZER_GO && defined(__s390x__)
564/*
565Go on linux/s390x
5660000 0000 1000 - 1000 0000 0000: executable and heap - 16 TiB
5671000 0000 0000 - 4000 0000 0000: -
5684000 0000 0000 - 8000 0000 0000: shadow - 64TiB (4 * app)
5698000 0000 0000 - 9000 0000 0000: -
5709000 0000 0000 - 9800 0000 0000: metainfo - 8TiB (0.5 * app)
5719800 0000 0000 - a000 0000 0000: -
572a000 0000 0000 - b000 0000 0000: traces - 16TiB (max history * 128k threads)
573*/
574struct Mapping {
575 static const uptr kMetaShadowBeg = 0x900000000000ull;
576 static const uptr kMetaShadowEnd = 0x980000000000ull;
577 static const uptr kTraceMemBeg = 0xa00000000000ull;
578 static const uptr kTraceMemEnd = 0xb00000000000ull;
579 static const uptr kShadowBeg = 0x400000000000ull;
580 static const uptr kShadowEnd = 0x800000000000ull;
581 static const uptr kAppMemBeg = 0x000000001000ull;
582 static const uptr kAppMemEnd = 0x100000000000ull;
583};
584
491585#else
492586# error "Unknown platform"
493587#endif
......@@ -568,6 +662,16 @@ uptr MappingArchImpl(void) {
568662 }
569663 DCHECK(0);
570664 return 0;
665#elif defined(__mips64)
666 switch (vmaSize) {
667#if !SANITIZER_GO
668 case 40: return MappingImpl<Mapping40, Type>();
669#else
670 case 47: return MappingImpl<Mapping47, Type>();
671#endif
672 }
673 DCHECK(0);
674 return 0;
571675#else
572676 return MappingImpl<Mapping, Type>();
573677#endif
......@@ -725,6 +829,16 @@ bool IsAppMem(uptr mem) {
725829 }
726830 DCHECK(0);
727831 return false;
832#elif defined(__mips64)
833 switch (vmaSize) {
834#if !SANITIZER_GO
835 case 40: return IsAppMemImpl<Mapping40>(mem);
836#else
837 case 47: return IsAppMemImpl<Mapping47>(mem);
838#endif
839 }
840 DCHECK(0);
841 return false;
728842#else
729843 return IsAppMemImpl<Mapping>(mem);
730844#endif
......@@ -756,6 +870,16 @@ bool IsShadowMem(uptr mem) {
756870 }
757871 DCHECK(0);
758872 return false;
873#elif defined(__mips64)
874 switch (vmaSize) {
875#if !SANITIZER_GO
876 case 40: return IsShadowMemImpl<Mapping40>(mem);
877#else
878 case 47: return IsShadowMemImpl<Mapping47>(mem);
879#endif
880 }
881 DCHECK(0);
882 return false;
759883#else
760884 return IsShadowMemImpl<Mapping>(mem);
761885#endif
......@@ -787,6 +911,16 @@ bool IsMetaMem(uptr mem) {
787911 }
788912 DCHECK(0);
789913 return false;
914#elif defined(__mips64)
915 switch (vmaSize) {
916#if !SANITIZER_GO
917 case 40: return IsMetaMemImpl<Mapping40>(mem);
918#else
919 case 47: return IsMetaMemImpl<Mapping47>(mem);
920#endif
921 }
922 DCHECK(0);
923 return false;
790924#else
791925 return IsMetaMemImpl<Mapping>(mem);
792926#endif
......@@ -828,6 +962,16 @@ uptr MemToShadow(uptr x) {
828962 }
829963 DCHECK(0);
830964 return 0;
965#elif defined(__mips64)
966 switch (vmaSize) {
967#if !SANITIZER_GO
968 case 40: return MemToShadowImpl<Mapping40>(x);
969#else
970 case 47: return MemToShadowImpl<Mapping47>(x);
971#endif
972 }
973 DCHECK(0);
974 return 0;
831975#else
832976 return MemToShadowImpl<Mapping>(x);
833977#endif
......@@ -871,6 +1015,16 @@ u32 *MemToMeta(uptr x) {
8711015 }
8721016 DCHECK(0);
8731017 return 0;
1018#elif defined(__mips64)
1019 switch (vmaSize) {
1020#if !SANITIZER_GO
1021 case 40: return MemToMetaImpl<Mapping40>(x);
1022#else
1023 case 47: return MemToMetaImpl<Mapping47>(x);
1024#endif
1025 }
1026 DCHECK(0);
1027 return 0;
8741028#else
8751029 return MemToMetaImpl<Mapping>(x);
8761030#endif
......@@ -927,6 +1081,16 @@ uptr ShadowToMem(uptr s) {
9271081 }
9281082 DCHECK(0);
9291083 return 0;
1084#elif defined(__mips64)
1085 switch (vmaSize) {
1086#if !SANITIZER_GO
1087 case 40: return ShadowToMemImpl<Mapping40>(s);
1088#else
1089 case 47: return ShadowToMemImpl<Mapping47>(s);
1090#endif
1091 }
1092 DCHECK(0);
1093 return 0;
9301094#else
9311095 return ShadowToMemImpl<Mapping>(s);
9321096#endif
......@@ -966,6 +1130,16 @@ uptr GetThreadTrace(int tid) {
9661130 }
9671131 DCHECK(0);
9681132 return 0;
1133#elif defined(__mips64)
1134 switch (vmaSize) {
1135#if !SANITIZER_GO
1136 case 40: return GetThreadTraceImpl<Mapping40>(tid);
1137#else
1138 case 47: return GetThreadTraceImpl<Mapping47>(tid);
1139#endif
1140 }
1141 DCHECK(0);
1142 return 0;
9691143#else
9701144 return GetThreadTraceImpl<Mapping>(tid);
9711145#endif
......@@ -1000,6 +1174,16 @@ uptr GetThreadTraceHeader(int tid) {
10001174 }
10011175 DCHECK(0);
10021176 return 0;
1177#elif defined(__mips64)
1178 switch (vmaSize) {
1179#if !SANITIZER_GO
1180 case 40: return GetThreadTraceHeaderImpl<Mapping40>(tid);
1181#else
1182 case 47: return GetThreadTraceHeaderImpl<Mapping47>(tid);
1183#endif
1184 }
1185 DCHECK(0);
1186 return 0;
10031187#else
10041188 return GetThreadTraceHeaderImpl<Mapping>(tid);
10051189#endif
......@@ -1016,9 +1200,8 @@ int ExtractRecvmsgFDs(void *msg, int *fds, int nfd);
10161200uptr ExtractLongJmpSp(uptr *env);
10171201void ImitateTlsWrite(ThreadState *thr, uptr tls_addr, uptr tls_size);
10181202
1019int call_pthread_cancel_with_cleanup(int(*fn)(void *c, void *m,
1020 void *abstime), void *c, void *m, void *abstime,
1021 void(*cleanup)(void *arg), void *arg);
1203int call_pthread_cancel_with_cleanup(int (*fn)(void *arg),
1204 void (*cleanup)(void *arg), void *arg);
10221205
10231206void DestroyThreadState();
10241207void PlatformCleanUpThreadState(ThreadState *thr);
lib/tsan/tsan_platform_linux.cpp+33-13
......@@ -12,14 +12,12 @@
1212//===----------------------------------------------------------------------===//
1313
1414#include "sanitizer_common/sanitizer_platform.h"
15#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || \
16 SANITIZER_OPENBSD
15#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD
1716
1817#include "sanitizer_common/sanitizer_common.h"
1918#include "sanitizer_common/sanitizer_libc.h"
2019#include "sanitizer_common/sanitizer_linux.h"
2120#include "sanitizer_common/sanitizer_platform_limits_netbsd.h"
22#include "sanitizer_common/sanitizer_platform_limits_openbsd.h"
2321#include "sanitizer_common/sanitizer_platform_limits_posix.h"
2422#include "sanitizer_common/sanitizer_posix.h"
2523#include "sanitizer_common/sanitizer_procmaps.h"
......@@ -252,6 +250,20 @@ void InitializePlatformEarly() {
252250 Die();
253251 }
254252# endif
253#elif defined(__mips64)
254# if !SANITIZER_GO
255 if (vmaSize != 40) {
256 Printf("FATAL: ThreadSanitizer: unsupported VMA range\n");
257 Printf("FATAL: Found %zd - Supported 40\n", vmaSize);
258 Die();
259 }
260# else
261 if (vmaSize != 47) {
262 Printf("FATAL: ThreadSanitizer: unsupported VMA range\n");
263 Printf("FATAL: Found %zd - Supported 47\n", vmaSize);
264 Die();
265 }
266# endif
255267#endif
256268#endif
257269}
......@@ -379,22 +391,32 @@ static uptr UnmangleLongJmpSp(uptr mangled_sp) {
379391 return mangled_sp ^ xor_key;
380392#elif defined(__mips__)
381393 return mangled_sp;
394#elif defined(__s390x__)
395 // tcbhead_t.stack_guard
396 uptr xor_key = ((uptr *)__builtin_thread_pointer())[5];
397 return mangled_sp ^ xor_key;
382398#else
383399 #error "Unknown platform"
384400#endif
385401}
386402
387#ifdef __powerpc__
403#if SANITIZER_NETBSD
404# ifdef __x86_64__
405# define LONG_JMP_SP_ENV_SLOT 6
406# else
407# error unsupported
408# endif
409#elif defined(__powerpc__)
388410# define LONG_JMP_SP_ENV_SLOT 0
389411#elif SANITIZER_FREEBSD
390412# define LONG_JMP_SP_ENV_SLOT 2
391#elif SANITIZER_NETBSD
392# define LONG_JMP_SP_ENV_SLOT 6
393413#elif SANITIZER_LINUX
394414# ifdef __aarch64__
395415# define LONG_JMP_SP_ENV_SLOT 13
396416# elif defined(__mips64)
397417# define LONG_JMP_SP_ENV_SLOT 1
418# elif defined(__s390x__)
419# define LONG_JMP_SP_ENV_SLOT 9
398420# else
399421# define LONG_JMP_SP_ENV_SLOT 6
400422# endif
......@@ -441,14 +463,13 @@ void ImitateTlsWrite(ThreadState *thr, uptr tls_addr, uptr tls_size) {
441463
442464// Note: this function runs with async signals enabled,
443465// so it must not touch any tsan state.
444int call_pthread_cancel_with_cleanup(int(*fn)(void *c, void *m,
445 void *abstime), void *c, void *m, void *abstime,
446 void(*cleanup)(void *arg), void *arg) {
466int call_pthread_cancel_with_cleanup(int (*fn)(void *arg),
467 void (*cleanup)(void *arg), void *arg) {
447468 // pthread_cleanup_push/pop are hardcore macros mess.
448469 // We can't intercept nor call them w/o including pthread.h.
449470 int res;
450471 pthread_cleanup_push(cleanup, arg);
451 res = fn(c, m, abstime);
472 res = fn(arg);
452473 pthread_cleanup_pop(0);
453474 return res;
454475}
......@@ -482,7 +503,7 @@ ThreadState *cur_thread() {
482503 dead_thread_state->fast_state.SetIgnoreBit();
483504 dead_thread_state->ignore_interceptors = 1;
484505 dead_thread_state->is_dead = true;
485 *const_cast<int*>(&dead_thread_state->tid) = -1;
506 *const_cast<u32*>(&dead_thread_state->tid) = -1;
486507 CHECK_EQ(0, internal_mprotect(dead_thread_state, sizeof(ThreadState),
487508 PROT_READ));
488509 }
......@@ -513,5 +534,4 @@ void cur_thread_finalize() {
513534
514535} // namespace __tsan
515536
516#endif // SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD ||
517 // SANITIZER_OPENBSD
537#endif // SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD
lib/tsan/tsan_platform_mac.cpp+4-5
......@@ -234,7 +234,7 @@ static void my_pthread_introspection_hook(unsigned int event, pthread_t thread,
234234#endif
235235
236236void InitializePlatformEarly() {
237#if defined(__aarch64__)
237#if !SANITIZER_GO && !HAS_48_BIT_ADDRESS_SPACE
238238 uptr max_vm = GetMaxUserVirtualAddress() + 1;
239239 if (max_vm != Mapping::kHiAppMemEnd) {
240240 Printf("ThreadSanitizer: unsupported vm address limit %p, expected %p.\n",
......@@ -306,14 +306,13 @@ void ImitateTlsWrite(ThreadState *thr, uptr tls_addr, uptr tls_size) {
306306#if !SANITIZER_GO
307307// Note: this function runs with async signals enabled,
308308// so it must not touch any tsan state.
309int call_pthread_cancel_with_cleanup(int(*fn)(void *c, void *m,
310 void *abstime), void *c, void *m, void *abstime,
311 void(*cleanup)(void *arg), void *arg) {
309int call_pthread_cancel_with_cleanup(int (*fn)(void *arg),
310 void (*cleanup)(void *arg), void *arg) {
312311 // pthread_cleanup_push/pop are hardcore macros mess.
313312 // We can't intercept nor call them w/o including pthread.h.
314313 int res;
315314 pthread_cleanup_push(cleanup, arg);
316 res = fn(c, m, abstime);
315 res = fn(arg);
317316 pthread_cleanup_pop(0);
318317 return res;
319318}
lib/tsan/tsan_platform_posix.cpp+21-48
......@@ -29,10 +29,6 @@ static const char kShadowMemoryMappingHint[] =
2929 "HINT: if %s is not supported in your environment, you may set "
3030 "TSAN_OPTIONS=%s=0\n";
3131
32static void NoHugePagesInShadow(uptr addr, uptr size) {
33 SetShadowRegionHugePageMode(addr, size);
34}
35
3632static void DontDumpShadow(uptr addr, uptr size) {
3733 if (common_flags()->use_madv_dontdump)
3834 if (!DontDumpShadowMemory(addr, size)) {
......@@ -46,7 +42,8 @@ static void DontDumpShadow(uptr addr, uptr size) {
4642#if !SANITIZER_GO
4743void InitializeShadowMemory() {
4844 // Map memory shadow.
49 if (!MmapFixedNoReserve(ShadowBeg(), ShadowEnd() - ShadowBeg(), "shadow")) {
45 if (!MmapFixedSuperNoReserve(ShadowBeg(), ShadowEnd() - ShadowBeg(),
46 "shadow")) {
5047 Printf("FATAL: ThreadSanitizer can not mmap the shadow memory\n");
5148 Printf("FATAL: Make sure to compile with -fPIE and to link with -pie.\n");
5249 Die();
......@@ -55,43 +52,6 @@ void InitializeShadowMemory() {
5552 // Frequently a thread uses only a small part of stack and similarly
5653 // a program uses a small part of large mmap. On some programs
5754 // we see 20% memory usage reduction without huge pages for this range.
58 // FIXME: don't use constants here.
59#if defined(__x86_64__)
60 const uptr kMadviseRangeBeg = 0x7f0000000000ull;
61 const uptr kMadviseRangeSize = 0x010000000000ull;
62#elif defined(__mips64)
63 const uptr kMadviseRangeBeg = 0xff00000000ull;
64 const uptr kMadviseRangeSize = 0x0100000000ull;
65#elif defined(__aarch64__) && defined(__APPLE__)
66 uptr kMadviseRangeBeg = LoAppMemBeg();
67 uptr kMadviseRangeSize = LoAppMemEnd() - LoAppMemBeg();
68#elif defined(__aarch64__)
69 uptr kMadviseRangeBeg = 0;
70 uptr kMadviseRangeSize = 0;
71 if (vmaSize == 39) {
72 kMadviseRangeBeg = 0x7d00000000ull;
73 kMadviseRangeSize = 0x0300000000ull;
74 } else if (vmaSize == 42) {
75 kMadviseRangeBeg = 0x3f000000000ull;
76 kMadviseRangeSize = 0x01000000000ull;
77 } else {
78 DCHECK(0);
79 }
80#elif defined(__powerpc64__)
81 uptr kMadviseRangeBeg = 0;
82 uptr kMadviseRangeSize = 0;
83 if (vmaSize == 44) {
84 kMadviseRangeBeg = 0x0f60000000ull;
85 kMadviseRangeSize = 0x0010000000ull;
86 } else if (vmaSize == 46) {
87 kMadviseRangeBeg = 0x3f0000000000ull;
88 kMadviseRangeSize = 0x010000000000ull;
89 } else {
90 DCHECK(0);
91 }
92#endif
93 NoHugePagesInShadow(MemToShadow(kMadviseRangeBeg),
94 kMadviseRangeSize * kShadowMultiplier);
9555 DontDumpShadow(ShadowBeg(), ShadowEnd() - ShadowBeg());
9656 DPrintf("memory shadow: %zx-%zx (%zuGB)\n",
9757 ShadowBeg(), ShadowEnd(),
......@@ -100,12 +60,11 @@ void InitializeShadowMemory() {
10060 // Map meta shadow.
10161 const uptr meta = MetaShadowBeg();
10262 const uptr meta_size = MetaShadowEnd() - meta;
103 if (!MmapFixedNoReserve(meta, meta_size, "meta shadow")) {
63 if (!MmapFixedSuperNoReserve(meta, meta_size, "meta shadow")) {
10464 Printf("FATAL: ThreadSanitizer can not mmap the shadow memory\n");
10565 Printf("FATAL: Make sure to compile with -fPIE and to link with -pie.\n");
10666 Die();
10767 }
108 NoHugePagesInShadow(meta, meta_size);
10968 DontDumpShadow(meta, meta_size);
11069 DPrintf("meta shadow: %zx-%zx (%zuGB)\n",
11170 meta, meta + meta_size, meta_size >> 30);
......@@ -113,11 +72,15 @@ void InitializeShadowMemory() {
11372 InitializeShadowMemoryPlatform();
11473}
11574
116static void ProtectRange(uptr beg, uptr end) {
75static bool TryProtectRange(uptr beg, uptr end) {
11776 CHECK_LE(beg, end);
11877 if (beg == end)
119 return;
120 if (beg != (uptr)MmapFixedNoAccess(beg, end - beg)) {
78 return true;
79 return beg == (uptr)MmapFixedNoAccess(beg, end - beg);
80}
81
82static void ProtectRange(uptr beg, uptr end) {
83 if (!TryProtectRange(beg, end)) {
12184 Printf("FATAL: ThreadSanitizer can not protect [%zx,%zx]\n", beg, end);
12285 Printf("FATAL: Make sure you are not using unlimited stack\n");
12386 Die();
......@@ -140,7 +103,7 @@ void CheckAndProtect() {
140103 Die();
141104 }
142105
143#if defined(__aarch64__) && defined(__APPLE__)
106#if defined(__aarch64__) && defined(__APPLE__) && !HAS_48_BIT_ADDRESS_SPACE
144107 ProtectRange(HeapMemEnd(), ShadowBeg());
145108 ProtectRange(ShadowEnd(), MetaShadowBeg());
146109 ProtectRange(MetaShadowEnd(), TraceMemBeg());
......@@ -159,6 +122,16 @@ void CheckAndProtect() {
159122 ProtectRange(TraceMemEnd(), HeapMemBeg());
160123 ProtectRange(HeapEnd(), HiAppMemBeg());
161124#endif
125
126#if defined(__s390x__)
127 // Protect the rest of the address space.
128 const uptr user_addr_max_l4 = 0x0020000000000000ull;
129 const uptr user_addr_max_l5 = 0xfffffffffffff000ull;
130 // All the maintained s390x kernels support at least 4-level page tables.
131 ProtectRange(HiAppMemEnd(), user_addr_max_l4);
132 // Older s390x kernels may not support 5-level page tables.
133 TryProtectRange(user_addr_max_l4, user_addr_max_l5);
134#endif
162135}
163136#endif
164137
lib/tsan/tsan_report.cpp+11-9
......@@ -69,7 +69,7 @@ ReportDesc::~ReportDesc() {
6969
7070const int kThreadBufSize = 32;
7171const char *thread_name(char *buf, int tid) {
72 if (tid == 0)
72 if (tid == kMainTid)
7373 return "main thread";
7474 internal_snprintf(buf, kThreadBufSize, "thread T%d", tid);
7575 return buf;
......@@ -127,8 +127,9 @@ void PrintStack(const ReportStack *ent) {
127127 }
128128 SymbolizedStack *frame = ent->frames;
129129 for (int i = 0; frame && frame->info.address; frame = frame->next, i++) {
130 InternalScopedString res(2 * GetPageSizeCached());
131 RenderFrame(&res, common_flags()->stack_trace_format, i, frame->info,
130 InternalScopedString res;
131 RenderFrame(&res, common_flags()->stack_trace_format, i,
132 frame->info.address, &frame->info,
132133 common_flags()->symbolize_vs_style,
133134 common_flags()->strip_path_prefix, kInterposedFunctionPrefix);
134135 Printf("%s\n", res.data());
......@@ -249,7 +250,7 @@ static void PrintMutex(const ReportMutex *rm) {
249250
250251static void PrintThread(const ReportThread *rt) {
251252 Decorator d;
252 if (rt->id == 0) // Little sense in describing the main thread.
253 if (rt->id == kMainTid) // Little sense in describing the main thread.
253254 return;
254255 Printf("%s", d.ThreadDescription());
255256 Printf(" Thread T%d", rt->id);
......@@ -385,14 +386,15 @@ void PrintReport(const ReportDesc *rep) {
385386 ReportErrorSummary(rep_typ_str, frame->info);
386387 }
387388
388 if (common_flags()->print_module_map == 2) PrintModuleMap();
389 if (common_flags()->print_module_map == 2)
390 DumpProcessMap();
389391
390392 Printf("==================\n");
391393}
392394
393395#else // #if !SANITIZER_GO
394396
395const int kMainThreadId = 1;
397const u32 kMainGoroutineId = 1;
396398
397399void PrintStack(const ReportStack *ent) {
398400 if (ent == 0 || ent->frames == 0) {
......@@ -413,7 +415,7 @@ static void PrintMop(const ReportMop *mop, bool first) {
413415 Printf("%s at %p by ",
414416 (first ? (mop->write ? "Write" : "Read")
415417 : (mop->write ? "Previous write" : "Previous read")), mop->addr);
416 if (mop->tid == kMainThreadId)
418 if (mop->tid == kMainGoroutineId)
417419 Printf("main goroutine:\n");
418420 else
419421 Printf("goroutine %d:\n", mop->tid);
......@@ -426,7 +428,7 @@ static void PrintLocation(const ReportLocation *loc) {
426428 Printf("\n");
427429 Printf("Heap block of size %zu at %p allocated by ",
428430 loc->heap_chunk_size, loc->heap_chunk_start);
429 if (loc->tid == kMainThreadId)
431 if (loc->tid == kMainGoroutineId)
430432 Printf("main goroutine:\n");
431433 else
432434 Printf("goroutine %d:\n", loc->tid);
......@@ -446,7 +448,7 @@ static void PrintLocation(const ReportLocation *loc) {
446448}
447449
448450static void PrintThread(const ReportThread *rt) {
449 if (rt->id == kMainThreadId)
451 if (rt->id == kMainGoroutineId)
450452 return;
451453 Printf("\n");
452454 Printf("Goroutine %d (%s) created at:\n",
lib/tsan/tsan_rtl.cpp+123-91
......@@ -11,17 +11,19 @@
1111// Main file (entry points) for the TSan run-time.
1212//===----------------------------------------------------------------------===//
1313
14#include "tsan_rtl.h"
15
1416#include "sanitizer_common/sanitizer_atomic.h"
1517#include "sanitizer_common/sanitizer_common.h"
1618#include "sanitizer_common/sanitizer_file.h"
1719#include "sanitizer_common/sanitizer_libc.h"
18#include "sanitizer_common/sanitizer_stackdepot.h"
1920#include "sanitizer_common/sanitizer_placement_new.h"
21#include "sanitizer_common/sanitizer_stackdepot.h"
2022#include "sanitizer_common/sanitizer_symbolizer.h"
2123#include "tsan_defs.h"
22#include "tsan_platform.h"
23#include "tsan_rtl.h"
24#include "tsan_interface.h"
2425#include "tsan_mman.h"
26#include "tsan_platform.h"
2527#include "tsan_suppressions.h"
2628#include "tsan_symbolize.h"
2729#include "ubsan/ubsan_init.h"
......@@ -56,15 +58,26 @@ Context *ctx;
5658bool OnFinalize(bool failed);
5759void OnInitialize();
5860#else
61#include <dlfcn.h>
5962SANITIZER_WEAK_CXX_DEFAULT_IMPL
6063bool OnFinalize(bool failed) {
64#if !SANITIZER_GO
65 if (auto *ptr = dlsym(RTLD_DEFAULT, "__tsan_on_finalize"))
66 return reinterpret_cast<decltype(&__tsan_on_finalize)>(ptr)(failed);
67#endif
6168 return failed;
6269}
6370SANITIZER_WEAK_CXX_DEFAULT_IMPL
64void OnInitialize() {}
71void OnInitialize() {
72#if !SANITIZER_GO
73 if (auto *ptr = dlsym(RTLD_DEFAULT, "__tsan_on_initialize")) {
74 return reinterpret_cast<decltype(&__tsan_on_initialize)>(ptr)();
75 }
76#endif
77}
6578#endif
6679
67static char thread_registry_placeholder[sizeof(ThreadRegistry)];
80static ALIGNED(64) char thread_registry_placeholder[sizeof(ThreadRegistry)];
6881
6982static ThreadContextBase *CreateThreadContext(u32 tid) {
7083 // Map thread trace when context is created.
......@@ -77,12 +90,19 @@ static ThreadContextBase *CreateThreadContext(u32 tid) {
7790 new((void*)hdr) Trace();
7891 // We are going to use only a small part of the trace with the default
7992 // value of history_size. However, the constructor writes to the whole trace.
80 // Unmap the unused part.
93 // Release the unused part.
8194 uptr hdr_end = hdr + sizeof(Trace);
8295 hdr_end -= sizeof(TraceHeader) * (kTraceParts - TraceParts());
8396 hdr_end = RoundUp(hdr_end, GetPageSizeCached());
84 if (hdr_end < hdr + sizeof(Trace))
85 UnmapOrDie((void*)hdr_end, hdr + sizeof(Trace) - hdr_end);
97 if (hdr_end < hdr + sizeof(Trace)) {
98 ReleaseMemoryPagesToOS(hdr_end, hdr + sizeof(Trace));
99 uptr unused = hdr + sizeof(Trace) - hdr_end;
100 if (hdr_end != (uptr)MmapFixedNoAccess(hdr_end, unused)) {
101 Report("ThreadSanitizer: failed to mprotect(%p, %p)\n",
102 hdr_end, unused);
103 CHECK("unable to mprotect" && 0);
104 }
105 }
86106 void *mem = internal_alloc(MBlockThreadContex, sizeof(ThreadContext));
87107 return new(mem) ThreadContext(tid);
88108}
......@@ -94,42 +114,45 @@ static const u32 kThreadQuarantineSize = 64;
94114#endif
95115
96116Context::Context()
97 : initialized()
98 , report_mtx(MutexTypeReport, StatMtxReport)
99 , nreported()
100 , nmissed_expected()
101 , thread_registry(new(thread_registry_placeholder) ThreadRegistry(
102 CreateThreadContext, kMaxTid, kThreadQuarantineSize, kMaxTidReuse))
103 , racy_mtx(MutexTypeRacy, StatMtxRacy)
104 , racy_stacks()
105 , racy_addresses()
106 , fired_suppressions_mtx(MutexTypeFired, StatMtxFired)
107 , clock_alloc("clock allocator") {
117 : initialized(),
118 report_mtx(MutexTypeReport),
119 nreported(),
120 nmissed_expected(),
121 thread_registry(new (thread_registry_placeholder) ThreadRegistry(
122 CreateThreadContext, kMaxTid, kThreadQuarantineSize, kMaxTidReuse)),
123 racy_mtx(MutexTypeRacy),
124 racy_stacks(),
125 racy_addresses(),
126 fired_suppressions_mtx(MutexTypeFired),
127 clock_alloc(LINKER_INITIALIZED, "clock allocator") {
108128 fired_suppressions.reserve(8);
109129}
110130
111131// The objects are allocated in TLS, so one may rely on zero-initialization.
112ThreadState::ThreadState(Context *ctx, int tid, int unique_id, u64 epoch,
113 unsigned reuse_count,
114 uptr stk_addr, uptr stk_size,
132ThreadState::ThreadState(Context *ctx, u32 tid, int unique_id, u64 epoch,
133 unsigned reuse_count, uptr stk_addr, uptr stk_size,
115134 uptr tls_addr, uptr tls_size)
116 : fast_state(tid, epoch)
117 // Do not touch these, rely on zero initialization,
118 // they may be accessed before the ctor.
119 // , ignore_reads_and_writes()
120 // , ignore_interceptors()
121 , clock(tid, reuse_count)
135 : fast_state(tid, epoch)
136 // Do not touch these, rely on zero initialization,
137 // they may be accessed before the ctor.
138 // , ignore_reads_and_writes()
139 // , ignore_interceptors()
140 ,
141 clock(tid, reuse_count)
122142#if !SANITIZER_GO
123 , jmp_bufs()
143 ,
144 jmp_bufs()
124145#endif
125 , tid(tid)
126 , unique_id(unique_id)
127 , stk_addr(stk_addr)
128 , stk_size(stk_size)
129 , tls_addr(tls_addr)
130 , tls_size(tls_size)
146 ,
147 tid(tid),
148 unique_id(unique_id),
149 stk_addr(stk_addr),
150 stk_size(stk_size),
151 tls_addr(tls_addr),
152 tls_size(tls_size)
131153#if !SANITIZER_GO
132 , last_sleep_clock(tid)
154 ,
155 last_sleep_clock(tid)
133156#endif
134157{
135158}
......@@ -160,12 +183,12 @@ static void *BackgroundThread(void *arg) {
160183 } else if (internal_strcmp(flags()->profile_memory, "stderr") == 0) {
161184 mprof_fd = 2;
162185 } else {
163 InternalScopedString filename(kMaxPathLength);
186 InternalScopedString filename;
164187 filename.append("%s.%d", flags()->profile_memory, (int)internal_getpid());
165188 fd_t fd = OpenFile(filename.data(), WrOnly);
166189 if (fd == kInvalidFd) {
167190 Printf("ThreadSanitizer: failed to open memory profile file '%s'\n",
168 &filename[0]);
191 filename.data());
169192 } else {
170193 mprof_fd = fd;
171194 }
......@@ -256,7 +279,8 @@ void MapShadow(uptr addr, uptr size) {
256279 const uptr kPageSize = GetPageSizeCached();
257280 uptr shadow_begin = RoundDownTo((uptr)MemToShadow(addr), kPageSize);
258281 uptr shadow_end = RoundUpTo((uptr)MemToShadow(addr + size), kPageSize);
259 if (!MmapFixedNoReserve(shadow_begin, shadow_end - shadow_begin, "shadow"))
282 if (!MmapFixedSuperNoReserve(shadow_begin, shadow_end - shadow_begin,
283 "shadow"))
260284 Die();
261285
262286 // Meta shadow is 2:1, so tread carefully.
......@@ -269,7 +293,8 @@ void MapShadow(uptr addr, uptr size) {
269293 if (!data_mapped) {
270294 // First call maps data+bss.
271295 data_mapped = true;
272 if (!MmapFixedNoReserve(meta_begin, meta_end - meta_begin, "meta shadow"))
296 if (!MmapFixedSuperNoReserve(meta_begin, meta_end - meta_begin,
297 "meta shadow"))
273298 Die();
274299 } else {
275300 // Mapping continous heap.
......@@ -280,7 +305,8 @@ void MapShadow(uptr addr, uptr size) {
280305 return;
281306 if (meta_begin < mapped_meta_end)
282307 meta_begin = mapped_meta_end;
283 if (!MmapFixedNoReserve(meta_begin, meta_end - meta_begin, "meta shadow"))
308 if (!MmapFixedSuperNoReserve(meta_begin, meta_end - meta_begin,
309 "meta shadow"))
284310 Die();
285311 mapped_meta_end = meta_end;
286312 }
......@@ -293,7 +319,7 @@ void MapThreadTrace(uptr addr, uptr size, const char *name) {
293319 CHECK_GE(addr, TraceMemBeg());
294320 CHECK_LE(addr + size, TraceMemEnd());
295321 CHECK_EQ(addr, addr & ~((64 << 10) - 1)); // windows wants 64K alignment
296 if (!MmapFixedNoReserve(addr, size, name)) {
322 if (!MmapFixedSuperNoReserve(addr, size, name)) {
297323 Printf("FATAL: ThreadSanitizer can not mmap thread trace (%p/%p)\n",
298324 addr, size);
299325 Die();
......@@ -348,6 +374,18 @@ static void TsanOnDeadlySignal(int signo, void *siginfo, void *context) {
348374}
349375#endif
350376
377void CheckUnwind() {
378 // There is high probability that interceptors will check-fail as well,
379 // on the other hand there is no sense in processing interceptors
380 // since we are going to die soon.
381 ScopedIgnoreInterceptors ignore;
382#if !SANITIZER_GO
383 cur_thread()->ignore_sync++;
384 cur_thread()->ignore_reads_and_writes++;
385#endif
386 PrintCurrentStackSlow(StackTrace::GetCurrentPc());
387}
388
351389void Initialize(ThreadState *thr) {
352390 // Thread safe because done before all threads exist.
353391 static bool is_initialized = false;
......@@ -358,7 +396,7 @@ void Initialize(ThreadState *thr) {
358396 ScopedIgnoreInterceptors ignore;
359397 SanitizerToolName = "ThreadSanitizer";
360398 // Install tool-specific callbacks in sanitizer_common.
361 SetCheckFailedCallback(TsanCheckFailed);
399 SetCheckUnwindCallback(CheckUnwind);
362400
363401 ctx = new(ctx_placeholder) Context;
364402 const char *env_name = SANITIZER_GO ? "GORACE" : "TSAN_OPTIONS";
......@@ -384,7 +422,6 @@ void Initialize(ThreadState *thr) {
384422 InitializeInterceptors();
385423 CheckShadowMapping();
386424 InitializePlatform();
387 InitializeMutex();
388425 InitializeDynamicAnnotations();
389426#if !SANITIZER_GO
390427 InitializeShadowMemory();
......@@ -443,7 +480,8 @@ void MaybeSpawnBackgroundThread() {
443480int Finalize(ThreadState *thr) {
444481 bool failed = false;
445482
446 if (common_flags()->print_module_map == 1) PrintModuleMap();
483 if (common_flags()->print_module_map == 1)
484 DumpProcessMap();
447485
448486 if (flags()->atexit_sleep_ms > 0 && ThreadCount(thr) > 1)
449487 SleepForMillis(flags()->atexit_sleep_ms);
......@@ -483,35 +521,37 @@ int Finalize(ThreadState *thr) {
483521
484522 failed = OnFinalize(failed);
485523
486#if TSAN_COLLECT_STATS
487 StatAggregate(ctx->stat, thr->stat);
488 StatOutput(ctx->stat);
489#endif
490
491524 return failed ? common_flags()->exitcode : 0;
492525}
493526
494527#if !SANITIZER_GO
495void ForkBefore(ThreadState *thr, uptr pc) {
528void ForkBefore(ThreadState *thr, uptr pc) NO_THREAD_SAFETY_ANALYSIS {
496529 ctx->thread_registry->Lock();
497530 ctx->report_mtx.Lock();
498 // Ignore memory accesses in the pthread_atfork callbacks.
499 // If any of them triggers a data race we will deadlock
500 // on the report_mtx.
501 // We could ignore interceptors and sync operations as well,
531 ScopedErrorReportLock::Lock();
532 // Suppress all reports in the pthread_atfork callbacks.
533 // Reports will deadlock on the report_mtx.
534 // We could ignore sync operations as well,
502535 // but so far it's unclear if it will do more good or harm.
503536 // Unnecessarily ignoring things can lead to false positives later.
504 ThreadIgnoreBegin(thr, pc);
537 thr->suppress_reports++;
538 // On OS X, REAL(fork) can call intercepted functions (OSSpinLockLock), and
539 // we'll assert in CheckNoLocks() unless we ignore interceptors.
540 thr->ignore_interceptors++;
505541}
506542
507void ForkParentAfter(ThreadState *thr, uptr pc) {
508 ThreadIgnoreEnd(thr, pc); // Begin is in ForkBefore.
543void ForkParentAfter(ThreadState *thr, uptr pc) NO_THREAD_SAFETY_ANALYSIS {
544 thr->suppress_reports--; // Enabled in ForkBefore.
545 thr->ignore_interceptors--;
546 ScopedErrorReportLock::Unlock();
509547 ctx->report_mtx.Unlock();
510548 ctx->thread_registry->Unlock();
511549}
512550
513void ForkChildAfter(ThreadState *thr, uptr pc) {
514 ThreadIgnoreEnd(thr, pc); // Begin is in ForkBefore.
551void ForkChildAfter(ThreadState *thr, uptr pc) NO_THREAD_SAFETY_ANALYSIS {
552 thr->suppress_reports--; // Enabled in ForkBefore.
553 thr->ignore_interceptors--;
554 ScopedErrorReportLock::Unlock();
515555 ctx->report_mtx.Unlock();
516556 ctx->thread_registry->Unlock();
517557
......@@ -650,9 +690,6 @@ ALWAYS_INLINE
650690void MemoryAccessImpl1(ThreadState *thr, uptr addr,
651691 int kAccessSizeLog, bool kAccessIsWrite, bool kIsAtomic,
652692 u64 *shadow_mem, Shadow cur) {
653 StatInc(thr, StatMop);
654 StatInc(thr, kAccessIsWrite ? StatMopWrite : StatMopRead);
655 StatInc(thr, (StatType)(StatMop1 + kAccessSizeLog));
656693
657694 // This potentially can live in an MMX/SSE scratch register.
658695 // The required intrinsics are:
......@@ -709,7 +746,6 @@ void MemoryAccessImpl1(ThreadState *thr, uptr addr,
709746 return;
710747 // choose a random candidate slot and replace it
711748 StoreShadow(shadow_mem + (cur.epoch() % kShadowCnt), store_word);
712 StatInc(thr, StatShadowReplace);
713749 return;
714750 RACE:
715751 HandleRace(thr, shadow_mem, cur, old);
......@@ -848,19 +884,11 @@ void MemoryAccess(ThreadState *thr, uptr pc, uptr addr,
848884 if (!SANITIZER_GO && !kAccessIsWrite && *shadow_mem == kShadowRodata) {
849885 // Access to .rodata section, no races here.
850886 // Measurements show that it can be 10-20% of all memory accesses.
851 StatInc(thr, StatMop);
852 StatInc(thr, kAccessIsWrite ? StatMopWrite : StatMopRead);
853 StatInc(thr, (StatType)(StatMop1 + kAccessSizeLog));
854 StatInc(thr, StatMopRodata);
855887 return;
856888 }
857889
858890 FastState fast_state = thr->fast_state;
859891 if (UNLIKELY(fast_state.GetIgnoreBit())) {
860 StatInc(thr, StatMop);
861 StatInc(thr, kAccessIsWrite ? StatMopWrite : StatMopRead);
862 StatInc(thr, (StatType)(StatMop1 + kAccessSizeLog));
863 StatInc(thr, StatMopIgnored);
864892 return;
865893 }
866894
......@@ -871,10 +899,6 @@ void MemoryAccess(ThreadState *thr, uptr pc, uptr addr,
871899
872900 if (LIKELY(ContainsSameAccess(shadow_mem, cur.raw(),
873901 thr->fast_synch_epoch, kAccessIsWrite))) {
874 StatInc(thr, StatMop);
875 StatInc(thr, kAccessIsWrite ? StatMopWrite : StatMopRead);
876 StatInc(thr, (StatType)(StatMop1 + kAccessSizeLog));
877 StatInc(thr, StatMopSame);
878902 return;
879903 }
880904
......@@ -896,10 +920,6 @@ void MemoryAccessImpl(ThreadState *thr, uptr addr,
896920 u64 *shadow_mem, Shadow cur) {
897921 if (LIKELY(ContainsSameAccess(shadow_mem, cur.raw(),
898922 thr->fast_synch_epoch, kAccessIsWrite))) {
899 StatInc(thr, StatMop);
900 StatInc(thr, kAccessIsWrite ? StatMopWrite : StatMopRead);
901 StatInc(thr, (StatType)(StatMop1 + kAccessSizeLog));
902 StatInc(thr, StatMopSame);
903923 return;
904924 }
905925
......@@ -956,8 +976,7 @@ static void MemoryRangeSet(ThreadState *thr, uptr pc, uptr addr, uptr size,
956976 // Reset middle part.
957977 u64 *p1 = p;
958978 p = RoundDown(end, kPageSize);
959 UnmapOrDie((void*)p1, (uptr)p - (uptr)p1);
960 if (!MmapFixedNoReserve((uptr)p1, (uptr)p - (uptr)p1))
979 if (!MmapFixedSuperNoReserve((uptr)p1, (uptr)p - (uptr)p1))
961980 Die();
962981 // Set the ending.
963982 while (p < end) {
......@@ -1016,7 +1035,6 @@ void MemoryRangeImitateWriteOrResetRange(ThreadState *thr, uptr pc, uptr addr,
10161035
10171036ALWAYS_INLINE USED
10181037void FuncEntry(ThreadState *thr, uptr pc) {
1019 StatInc(thr, StatFuncEnter);
10201038 DPrintf2("#%d: FuncEntry %p\n", (int)thr->fast_state.tid(), (void*)pc);
10211039 if (kCollectHistory) {
10221040 thr->fast_state.IncrementEpoch();
......@@ -1038,7 +1056,6 @@ void FuncEntry(ThreadState *thr, uptr pc) {
10381056
10391057ALWAYS_INLINE USED
10401058void FuncExit(ThreadState *thr) {
1041 StatInc(thr, StatFuncExit);
10421059 DPrintf2("#%d: FuncExit\n", (int)thr->fast_state.tid());
10431060 if (kCollectHistory) {
10441061 thr->fast_state.IncrementEpoch();
......@@ -1113,15 +1130,30 @@ void build_consistency_debug() {}
11131130void build_consistency_release() {}
11141131#endif
11151132
1116#if TSAN_COLLECT_STATS
1117void build_consistency_stats() {}
1118#else
1119void build_consistency_nostats() {}
1120#endif
1121
11221133} // namespace __tsan
11231134
1135#if SANITIZER_CHECK_DEADLOCKS
1136namespace __sanitizer {
1137using namespace __tsan;
1138MutexMeta mutex_meta[] = {
1139 {MutexInvalid, "Invalid", {}},
1140 {MutexThreadRegistry, "ThreadRegistry", {}},
1141 {MutexTypeTrace, "Trace", {MutexLeaf}},
1142 {MutexTypeReport, "Report", {MutexTypeSyncVar}},
1143 {MutexTypeSyncVar, "SyncVar", {}},
1144 {MutexTypeAnnotations, "Annotations", {}},
1145 {MutexTypeAtExit, "AtExit", {MutexTypeSyncVar}},
1146 {MutexTypeFired, "Fired", {MutexLeaf}},
1147 {MutexTypeRacy, "Racy", {MutexLeaf}},
1148 {MutexTypeGlobalProc, "GlobalProc", {}},
1149 {},
1150};
1151
1152void PrintMutexPC(uptr pc) { StackTrace(&pc, 1).Print(); }
1153} // namespace __sanitizer
1154#endif
1155
11241156#if !SANITIZER_GO
11251157// Must be included in this file to make sure everything is inlined.
1126#include "tsan_interface_inl.h"
1158# include "tsan_interface_inl.h"
11271159#endif
lib/tsan/tsan_rtl.h+10-37
......@@ -84,9 +84,6 @@ typedef Allocator::AllocatorCache AllocatorCache;
8484Allocator *allocator();
8585#endif
8686
87void TsanCheckFailed(const char *file, int line, const char *cond,
88 u64 v1, u64 v2);
89
9087const u64 kShadowRodata = (u64)-1; // .rodata shadow marker
9188
9289// FastState (from most significant bit):
......@@ -403,10 +400,7 @@ struct ThreadState {
403400 Vector<JmpBuf> jmp_bufs;
404401 int ignore_interceptors;
405402#endif
406#if TSAN_COLLECT_STATS
407 u64 stat[StatCnt];
408#endif
409 const int tid;
403 const u32 tid;
410404 const int unique_id;
411405 bool in_symbolizer;
412406 bool in_ignored_lib;
......@@ -420,9 +414,6 @@ struct ThreadState {
420414 const uptr tls_size;
421415 ThreadContext *tctx;
422416
423#if SANITIZER_DEBUG && !SANITIZER_GO
424 InternalDeadlockDetector internal_deadlock_detector;
425#endif
426417 DDLogicalThread *dd_lt;
427418
428419 // Current wired Processor, or nullptr. Required to handle any events.
......@@ -447,9 +438,8 @@ struct ThreadState {
447438
448439 const ReportDesc *current_report;
449440
450 explicit ThreadState(Context *ctx, int tid, int unique_id, u64 epoch,
451 unsigned reuse_count,
452 uptr stk_addr, uptr stk_size,
441 explicit ThreadState(Context *ctx, u32 tid, int unique_id, u64 epoch,
442 unsigned reuse_count, uptr stk_addr, uptr stk_size,
453443 uptr tls_addr, uptr tls_size);
454444};
455445
......@@ -458,26 +448,26 @@ struct ThreadState {
458448ThreadState *cur_thread();
459449void set_cur_thread(ThreadState *thr);
460450void cur_thread_finalize();
461INLINE void cur_thread_init() { }
451inline void cur_thread_init() { }
462452#else
463453__attribute__((tls_model("initial-exec")))
464454extern THREADLOCAL char cur_thread_placeholder[];
465INLINE ThreadState *cur_thread() {
455inline ThreadState *cur_thread() {
466456 return reinterpret_cast<ThreadState *>(cur_thread_placeholder)->current;
467457}
468INLINE void cur_thread_init() {
458inline void cur_thread_init() {
469459 ThreadState *thr = reinterpret_cast<ThreadState *>(cur_thread_placeholder);
470460 if (UNLIKELY(!thr->current))
471461 thr->current = thr;
472462}
473INLINE void set_cur_thread(ThreadState *thr) {
463inline void set_cur_thread(ThreadState *thr) {
474464 reinterpret_cast<ThreadState *>(cur_thread_placeholder)->current = thr;
475465}
476INLINE void cur_thread_finalize() { }
466inline void cur_thread_finalize() { }
477467#endif // SANITIZER_MAC || SANITIZER_ANDROID
478468#endif // SANITIZER_GO
479469
480class ThreadContext : public ThreadContextBase {
470class ThreadContext final : public ThreadContextBase {
481471 public:
482472 explicit ThreadContext(int tid);
483473 ~ThreadContext();
......@@ -554,7 +544,6 @@ struct Context {
554544
555545 Flags flags;
556546
557 u64 stat[StatCnt];
558547 u64 int_alloc_cnt[MBlockTypeCount];
559548 u64 int_alloc_siz[MBlockTypeCount];
560549};
......@@ -624,6 +613,7 @@ class ScopedReport : public ScopedReportBase {
624613 ScopedErrorReportLock lock_;
625614};
626615
616bool ShouldReport(ThreadState *thr, ReportType typ);
627617ThreadContext *IsThreadStackOrTls(uptr addr, bool *is_stack);
628618void RestoreStack(int tid, const u64 epoch, VarSizeStackTrace *stk,
629619 MutexSet *mset, uptr *tag = nullptr);
......@@ -661,22 +651,6 @@ void ObtainCurrentStack(ThreadState *thr, uptr toppc, StackTraceTy *stack,
661651 ObtainCurrentStack(thr, pc, &stack); \
662652 stack.ReverseOrder();
663653
664#if TSAN_COLLECT_STATS
665void StatAggregate(u64 *dst, u64 *src);
666void StatOutput(u64 *stat);
667#endif
668
669void ALWAYS_INLINE StatInc(ThreadState *thr, StatType typ, u64 n = 1) {
670#if TSAN_COLLECT_STATS
671 thr->stat[typ] += n;
672#endif
673}
674void ALWAYS_INLINE StatSet(ThreadState *thr, StatType typ, u64 n) {
675#if TSAN_COLLECT_STATS
676 thr->stat[typ] = n;
677#endif
678}
679
680654void MapShadow(uptr addr, uptr size);
681655void MapThreadTrace(uptr addr, uptr size, const char *name);
682656void DontNeedShadowFor(uptr addr, uptr size);
......@@ -857,7 +831,6 @@ void ALWAYS_INLINE TraceAddEvent(ThreadState *thr, FastState fs,
857831 DCHECK_GE((int)typ, 0);
858832 DCHECK_LE((int)typ, 7);
859833 DCHECK_EQ(GetLsb(addr, kEventPCBits), addr);
860 StatInc(thr, StatEvents);
861834 u64 pos = fs.GetTracePos();
862835 if (UNLIKELY((pos % kTracePartSize) == 0)) {
863836#if !SANITIZER_GO
lib/tsan/tsan_rtl_mutex.cpp+30-45
......@@ -24,7 +24,7 @@ namespace __tsan {
2424
2525void ReportDeadlock(ThreadState *thr, uptr pc, DDReport *r);
2626
27struct Callback : DDCallback {
27struct Callback final : public DDCallback {
2828 ThreadState *thr;
2929 uptr pc;
3030
......@@ -51,6 +51,8 @@ static void ReportMutexMisuse(ThreadState *thr, uptr pc, ReportType typ,
5151 // or false positives (e.g. unlock in a different thread).
5252 if (SANITIZER_GO)
5353 return;
54 if (!ShouldReport(thr, typ))
55 return;
5456 ThreadRegistryLock l(ctx->thread_registry);
5557 ScopedReport rep(typ);
5658 rep.AddMutex(mid);
......@@ -61,9 +63,8 @@ static void ReportMutexMisuse(ThreadState *thr, uptr pc, ReportType typ,
6163 OutputReport(thr, rep);
6264}
6365
64void MutexCreate(ThreadState *thr, uptr pc, uptr addr, u32 flagz) {
66void MutexCreate(ThreadState *thr, uptr pc, uptr addr, u32 flagz) NO_THREAD_SAFETY_ANALYSIS {
6567 DPrintf("#%d: MutexCreate %zx flagz=0x%x\n", thr->tid, addr, flagz);
66 StatInc(thr, StatMutexCreate);
6768 if (!(flagz & MutexFlagLinkerInit) && IsAppMem(addr)) {
6869 CHECK(!thr->is_freeing);
6970 thr->is_freeing = true;
......@@ -77,9 +78,8 @@ void MutexCreate(ThreadState *thr, uptr pc, uptr addr, u32 flagz) {
7778 s->mtx.Unlock();
7879}
7980
80void MutexDestroy(ThreadState *thr, uptr pc, uptr addr, u32 flagz) {
81void MutexDestroy(ThreadState *thr, uptr pc, uptr addr, u32 flagz) NO_THREAD_SAFETY_ANALYSIS {
8182 DPrintf("#%d: MutexDestroy %zx\n", thr->tid, addr);
82 StatInc(thr, StatMutexDestroy);
8383 SyncVar *s = ctx->metamap.GetIfExistsAndLock(addr, true);
8484 if (s == 0)
8585 return;
......@@ -96,9 +96,8 @@ void MutexDestroy(ThreadState *thr, uptr pc, uptr addr, u32 flagz) {
9696 ctx->dd->MutexInit(&cb, &s->dd);
9797 }
9898 bool unlock_locked = false;
99 if (flags()->report_destroy_locked
100 && s->owner_tid != SyncVar::kInvalidTid
101 && !s->IsFlagSet(MutexFlagBroken)) {
99 if (flags()->report_destroy_locked && s->owner_tid != kInvalidTid &&
100 !s->IsFlagSet(MutexFlagBroken)) {
102101 s->SetFlags(MutexFlagBroken);
103102 unlock_locked = true;
104103 }
......@@ -107,7 +106,7 @@ void MutexDestroy(ThreadState *thr, uptr pc, uptr addr, u32 flagz) {
107106 if (!unlock_locked)
108107 s->Reset(thr->proc()); // must not reset it before the report is printed
109108 s->mtx.Unlock();
110 if (unlock_locked) {
109 if (unlock_locked && ShouldReport(thr, ReportTypeMutexDestroyLocked)) {
111110 ThreadRegistryLock l(ctx->thread_registry);
112111 ScopedReport rep(ReportTypeMutexDestroyLocked);
113112 rep.AddMutex(mid);
......@@ -139,7 +138,7 @@ void MutexDestroy(ThreadState *thr, uptr pc, uptr addr, u32 flagz) {
139138 // s will be destroyed and freed in MetaMap::FreeBlock.
140139}
141140
142void MutexPreLock(ThreadState *thr, uptr pc, uptr addr, u32 flagz) {
141void MutexPreLock(ThreadState *thr, uptr pc, uptr addr, u32 flagz) NO_THREAD_SAFETY_ANALYSIS {
143142 DPrintf("#%d: MutexPreLock %zx flagz=0x%x\n", thr->tid, addr, flagz);
144143 if (!(flagz & MutexFlagTryLock) && common_flags()->detect_deadlocks) {
145144 SyncVar *s = ctx->metamap.GetOrCreateAndLock(thr, pc, addr, false);
......@@ -155,7 +154,8 @@ void MutexPreLock(ThreadState *thr, uptr pc, uptr addr, u32 flagz) {
155154 }
156155}
157156
158void MutexPostLock(ThreadState *thr, uptr pc, uptr addr, u32 flagz, int rec) {
157void MutexPostLock(ThreadState *thr, uptr pc, uptr addr, u32 flagz,
158 int rec) NO_THREAD_SAFETY_ANALYSIS {
159159 DPrintf("#%d: MutexPostLock %zx flag=0x%x rec=%d\n",
160160 thr->tid, addr, flagz, rec);
161161 if (flagz & MutexFlagRecursiveLock)
......@@ -169,7 +169,7 @@ void MutexPostLock(ThreadState *thr, uptr pc, uptr addr, u32 flagz, int rec) {
169169 thr->fast_state.IncrementEpoch();
170170 TraceAddEvent(thr, thr->fast_state, EventTypeLock, s->GetId());
171171 bool report_double_lock = false;
172 if (s->owner_tid == SyncVar::kInvalidTid) {
172 if (s->owner_tid == kInvalidTid) {
173173 CHECK_EQ(s->recursion, 0);
174174 s->owner_tid = thr->tid;
175175 s->last_lock = thr->fast_state.raw();
......@@ -182,11 +182,9 @@ void MutexPostLock(ThreadState *thr, uptr pc, uptr addr, u32 flagz, int rec) {
182182 const bool first = s->recursion == 0;
183183 s->recursion += rec;
184184 if (first) {
185 StatInc(thr, StatMutexLock);
186185 AcquireImpl(thr, pc, &s->clock);
187186 AcquireImpl(thr, pc, &s->read_clock);
188187 } else if (!s->IsFlagSet(MutexFlagWriteReentrant)) {
189 StatInc(thr, StatMutexRecLock);
190188 }
191189 thr->mset.Add(s->GetId(), true, thr->fast_state.epoch());
192190 bool pre_lock = false;
......@@ -210,7 +208,7 @@ void MutexPostLock(ThreadState *thr, uptr pc, uptr addr, u32 flagz, int rec) {
210208 }
211209}
212210
213int MutexUnlock(ThreadState *thr, uptr pc, uptr addr, u32 flagz) {
211int MutexUnlock(ThreadState *thr, uptr pc, uptr addr, u32 flagz) NO_THREAD_SAFETY_ANALYSIS {
214212 DPrintf("#%d: MutexUnlock %zx flagz=0x%x\n", thr->tid, addr, flagz);
215213 if (IsAppMem(addr))
216214 MemoryReadAtomic(thr, pc, addr, kSizeLog1);
......@@ -228,11 +226,9 @@ int MutexUnlock(ThreadState *thr, uptr pc, uptr addr, u32 flagz) {
228226 rec = (flagz & MutexFlagRecursiveUnlock) ? s->recursion : 1;
229227 s->recursion -= rec;
230228 if (s->recursion == 0) {
231 StatInc(thr, StatMutexUnlock);
232 s->owner_tid = SyncVar::kInvalidTid;
229 s->owner_tid = kInvalidTid;
233230 ReleaseStoreImpl(thr, pc, &s->clock);
234231 } else {
235 StatInc(thr, StatMutexRecUnlock);
236232 }
237233 }
238234 thr->mset.Del(s->GetId(), true);
......@@ -253,7 +249,7 @@ int MutexUnlock(ThreadState *thr, uptr pc, uptr addr, u32 flagz) {
253249 return rec;
254250}
255251
256void MutexPreReadLock(ThreadState *thr, uptr pc, uptr addr, u32 flagz) {
252void MutexPreReadLock(ThreadState *thr, uptr pc, uptr addr, u32 flagz) NO_THREAD_SAFETY_ANALYSIS {
257253 DPrintf("#%d: MutexPreReadLock %zx flagz=0x%x\n", thr->tid, addr, flagz);
258254 if (!(flagz & MutexFlagTryLock) && common_flags()->detect_deadlocks) {
259255 SyncVar *s = ctx->metamap.GetOrCreateAndLock(thr, pc, addr, false);
......@@ -265,9 +261,8 @@ void MutexPreReadLock(ThreadState *thr, uptr pc, uptr addr, u32 flagz) {
265261 }
266262}
267263
268void MutexPostReadLock(ThreadState *thr, uptr pc, uptr addr, u32 flagz) {
264void MutexPostReadLock(ThreadState *thr, uptr pc, uptr addr, u32 flagz) NO_THREAD_SAFETY_ANALYSIS {
269265 DPrintf("#%d: MutexPostReadLock %zx flagz=0x%x\n", thr->tid, addr, flagz);
270 StatInc(thr, StatMutexReadLock);
271266 if (IsAppMem(addr))
272267 MemoryReadAtomic(thr, pc, addr, kSizeLog1);
273268 SyncVar *s = ctx->metamap.GetOrCreateAndLock(thr, pc, addr, false);
......@@ -275,7 +270,7 @@ void MutexPostReadLock(ThreadState *thr, uptr pc, uptr addr, u32 flagz) {
275270 thr->fast_state.IncrementEpoch();
276271 TraceAddEvent(thr, thr->fast_state, EventTypeRLock, s->GetId());
277272 bool report_bad_lock = false;
278 if (s->owner_tid != SyncVar::kInvalidTid) {
273 if (s->owner_tid != kInvalidTid) {
279274 if (flags()->report_mutex_bugs && !s->IsFlagSet(MutexFlagBroken)) {
280275 s->SetFlags(MutexFlagBroken);
281276 report_bad_lock = true;
......@@ -305,16 +300,15 @@ void MutexPostReadLock(ThreadState *thr, uptr pc, uptr addr, u32 flagz) {
305300 }
306301}
307302
308void MutexReadUnlock(ThreadState *thr, uptr pc, uptr addr) {
303void MutexReadUnlock(ThreadState *thr, uptr pc, uptr addr) NO_THREAD_SAFETY_ANALYSIS {
309304 DPrintf("#%d: MutexReadUnlock %zx\n", thr->tid, addr);
310 StatInc(thr, StatMutexReadUnlock);
311305 if (IsAppMem(addr))
312306 MemoryReadAtomic(thr, pc, addr, kSizeLog1);
313307 SyncVar *s = ctx->metamap.GetOrCreateAndLock(thr, pc, addr, true);
314308 thr->fast_state.IncrementEpoch();
315309 TraceAddEvent(thr, thr->fast_state, EventTypeRUnlock, s->GetId());
316310 bool report_bad_unlock = false;
317 if (s->owner_tid != SyncVar::kInvalidTid) {
311 if (s->owner_tid != kInvalidTid) {
318312 if (flags()->report_mutex_bugs && !s->IsFlagSet(MutexFlagBroken)) {
319313 s->SetFlags(MutexFlagBroken);
320314 report_bad_unlock = true;
......@@ -337,17 +331,16 @@ void MutexReadUnlock(ThreadState *thr, uptr pc, uptr addr) {
337331 }
338332}
339333
340void MutexReadOrWriteUnlock(ThreadState *thr, uptr pc, uptr addr) {
334void MutexReadOrWriteUnlock(ThreadState *thr, uptr pc, uptr addr) NO_THREAD_SAFETY_ANALYSIS {
341335 DPrintf("#%d: MutexReadOrWriteUnlock %zx\n", thr->tid, addr);
342336 if (IsAppMem(addr))
343337 MemoryReadAtomic(thr, pc, addr, kSizeLog1);
344338 SyncVar *s = ctx->metamap.GetOrCreateAndLock(thr, pc, addr, true);
345339 bool write = true;
346340 bool report_bad_unlock = false;
347 if (s->owner_tid == SyncVar::kInvalidTid) {
341 if (s->owner_tid == kInvalidTid) {
348342 // Seems to be read unlock.
349343 write = false;
350 StatInc(thr, StatMutexReadUnlock);
351344 thr->fast_state.IncrementEpoch();
352345 TraceAddEvent(thr, thr->fast_state, EventTypeRUnlock, s->GetId());
353346 ReleaseImpl(thr, pc, &s->read_clock);
......@@ -358,11 +351,9 @@ void MutexReadOrWriteUnlock(ThreadState *thr, uptr pc, uptr addr) {
358351 CHECK_GT(s->recursion, 0);
359352 s->recursion--;
360353 if (s->recursion == 0) {
361 StatInc(thr, StatMutexUnlock);
362 s->owner_tid = SyncVar::kInvalidTid;
354 s->owner_tid = kInvalidTid;
363355 ReleaseStoreImpl(thr, pc, &s->clock);
364356 } else {
365 StatInc(thr, StatMutexRecUnlock);
366357 }
367358 } else if (!s->IsFlagSet(MutexFlagBroken)) {
368359 s->SetFlags(MutexFlagBroken);
......@@ -384,15 +375,15 @@ void MutexReadOrWriteUnlock(ThreadState *thr, uptr pc, uptr addr) {
384375 }
385376}
386377
387void MutexRepair(ThreadState *thr, uptr pc, uptr addr) {
378void MutexRepair(ThreadState *thr, uptr pc, uptr addr) NO_THREAD_SAFETY_ANALYSIS {
388379 DPrintf("#%d: MutexRepair %zx\n", thr->tid, addr);
389380 SyncVar *s = ctx->metamap.GetOrCreateAndLock(thr, pc, addr, true);
390 s->owner_tid = SyncVar::kInvalidTid;
381 s->owner_tid = kInvalidTid;
391382 s->recursion = 0;
392383 s->mtx.Unlock();
393384}
394385
395void MutexInvalidAccess(ThreadState *thr, uptr pc, uptr addr) {
386void MutexInvalidAccess(ThreadState *thr, uptr pc, uptr addr) NO_THREAD_SAFETY_ANALYSIS {
396387 DPrintf("#%d: MutexInvalidAccess %zx\n", thr->tid, addr);
397388 SyncVar *s = ctx->metamap.GetOrCreateAndLock(thr, pc, addr, true);
398389 u64 mid = s->GetId();
......@@ -400,7 +391,7 @@ void MutexInvalidAccess(ThreadState *thr, uptr pc, uptr addr) {
400391 ReportMutexMisuse(thr, pc, ReportTypeMutexInvalidAccess, addr, mid);
401392}
402393
403void Acquire(ThreadState *thr, uptr pc, uptr addr) {
394void Acquire(ThreadState *thr, uptr pc, uptr addr) NO_THREAD_SAFETY_ANALYSIS {
404395 DPrintf("#%d: Acquire %zx\n", thr->tid, addr);
405396 if (thr->ignore_sync)
406397 return;
......@@ -431,7 +422,7 @@ void AcquireGlobal(ThreadState *thr, uptr pc) {
431422 UpdateClockCallback, thr);
432423}
433424
434void ReleaseStoreAcquire(ThreadState *thr, uptr pc, uptr addr) {
425void ReleaseStoreAcquire(ThreadState *thr, uptr pc, uptr addr) NO_THREAD_SAFETY_ANALYSIS {
435426 DPrintf("#%d: ReleaseStoreAcquire %zx\n", thr->tid, addr);
436427 if (thr->ignore_sync)
437428 return;
......@@ -443,7 +434,7 @@ void ReleaseStoreAcquire(ThreadState *thr, uptr pc, uptr addr) {
443434 s->mtx.Unlock();
444435}
445436
446void Release(ThreadState *thr, uptr pc, uptr addr) {
437void Release(ThreadState *thr, uptr pc, uptr addr) NO_THREAD_SAFETY_ANALYSIS {
447438 DPrintf("#%d: Release %zx\n", thr->tid, addr);
448439 if (thr->ignore_sync)
449440 return;
......@@ -455,7 +446,7 @@ void Release(ThreadState *thr, uptr pc, uptr addr) {
455446 s->mtx.Unlock();
456447}
457448
458void ReleaseStore(ThreadState *thr, uptr pc, uptr addr) {
449void ReleaseStore(ThreadState *thr, uptr pc, uptr addr) NO_THREAD_SAFETY_ANALYSIS {
459450 DPrintf("#%d: ReleaseStore %zx\n", thr->tid, addr);
460451 if (thr->ignore_sync)
461452 return;
......@@ -493,7 +484,6 @@ void AcquireImpl(ThreadState *thr, uptr pc, SyncClock *c) {
493484 return;
494485 thr->clock.set(thr->fast_state.epoch());
495486 thr->clock.acquire(&thr->proc()->clock_cache, c);
496 StatInc(thr, StatSyncAcquire);
497487}
498488
499489void ReleaseStoreAcquireImpl(ThreadState *thr, uptr pc, SyncClock *c) {
......@@ -502,7 +492,6 @@ void ReleaseStoreAcquireImpl(ThreadState *thr, uptr pc, SyncClock *c) {
502492 thr->clock.set(thr->fast_state.epoch());
503493 thr->fast_synch_epoch = thr->fast_state.epoch();
504494 thr->clock.releaseStoreAcquire(&thr->proc()->clock_cache, c);
505 StatInc(thr, StatSyncReleaseStoreAcquire);
506495}
507496
508497void ReleaseImpl(ThreadState *thr, uptr pc, SyncClock *c) {
......@@ -511,7 +500,6 @@ void ReleaseImpl(ThreadState *thr, uptr pc, SyncClock *c) {
511500 thr->clock.set(thr->fast_state.epoch());
512501 thr->fast_synch_epoch = thr->fast_state.epoch();
513502 thr->clock.release(&thr->proc()->clock_cache, c);
514 StatInc(thr, StatSyncRelease);
515503}
516504
517505void ReleaseStoreImpl(ThreadState *thr, uptr pc, SyncClock *c) {
......@@ -520,7 +508,6 @@ void ReleaseStoreImpl(ThreadState *thr, uptr pc, SyncClock *c) {
520508 thr->clock.set(thr->fast_state.epoch());
521509 thr->fast_synch_epoch = thr->fast_state.epoch();
522510 thr->clock.ReleaseStore(&thr->proc()->clock_cache, c);
523 StatInc(thr, StatSyncRelease);
524511}
525512
526513void AcquireReleaseImpl(ThreadState *thr, uptr pc, SyncClock *c) {
......@@ -529,12 +516,10 @@ void AcquireReleaseImpl(ThreadState *thr, uptr pc, SyncClock *c) {
529516 thr->clock.set(thr->fast_state.epoch());
530517 thr->fast_synch_epoch = thr->fast_state.epoch();
531518 thr->clock.acq_rel(&thr->proc()->clock_cache, c);
532 StatInc(thr, StatSyncAcquire);
533 StatInc(thr, StatSyncRelease);
534519}
535520
536521void ReportDeadlock(ThreadState *thr, uptr pc, DDReport *r) {
537 if (r == 0)
522 if (r == 0 || !ShouldReport(thr, ReportTypeDeadlock))
538523 return;
539524 ThreadRegistryLock l(ctx->thread_registry);
540525 ScopedReport rep(ReportTypeDeadlock);
lib/tsan/tsan_rtl_report.cpp+37-27
......@@ -31,23 +31,6 @@ using namespace __sanitizer;
3131
3232static ReportStack *SymbolizeStack(StackTrace trace);
3333
34void TsanCheckFailed(const char *file, int line, const char *cond,
35 u64 v1, u64 v2) {
36 // There is high probability that interceptors will check-fail as well,
37 // on the other hand there is no sense in processing interceptors
38 // since we are going to die soon.
39 ScopedIgnoreInterceptors ignore;
40#if !SANITIZER_GO
41 cur_thread()->ignore_sync++;
42 cur_thread()->ignore_reads_and_writes++;
43#endif
44 Printf("FATAL: ThreadSanitizer CHECK failed: "
45 "%s:%d \"%s\" (0x%zx, 0x%zx)\n",
46 file, line, cond, (uptr)v1, (uptr)v2);
47 PrintCurrentStackSlow(StackTrace::GetCurrentPc());
48 Die();
49}
50
5134// Can be overriden by an application/test to intercept reports.
5235#ifdef TSAN_EXTERNAL_HOOKS
5336bool OnReport(const ReportDesc *rep, bool suppressed);
......@@ -142,6 +125,34 @@ static ReportStack *SymbolizeStack(StackTrace trace) {
142125 return stack;
143126}
144127
128bool ShouldReport(ThreadState *thr, ReportType typ) {
129 // We set thr->suppress_reports in the fork context.
130 // Taking any locking in the fork context can lead to deadlocks.
131 // If any locks are already taken, it's too late to do this check.
132 CheckedMutex::CheckNoLocks();
133 // For the same reason check we didn't lock thread_registry yet.
134 if (SANITIZER_DEBUG)
135 ThreadRegistryLock l(ctx->thread_registry);
136 if (!flags()->report_bugs || thr->suppress_reports)
137 return false;
138 switch (typ) {
139 case ReportTypeSignalUnsafe:
140 return flags()->report_signal_unsafe;
141 case ReportTypeThreadLeak:
142#if !SANITIZER_GO
143 // It's impossible to join phantom threads
144 // in the child after fork.
145 if (ctx->after_multithreaded_fork)
146 return false;
147#endif
148 return flags()->report_thread_leaks;
149 case ReportTypeMutexDestroyLocked:
150 return flags()->report_destroy_locked;
151 default:
152 return true;
153 }
154}
155
145156ScopedReportBase::ScopedReportBase(ReportType typ, uptr tag) {
146157 ctx->thread_registry->CheckLocked();
147158 void *mem = internal_alloc(MBlockReport, sizeof(ReportDesc));
......@@ -274,7 +285,7 @@ void ScopedReportBase::AddMutex(const SyncVar *s) {
274285 rm->stack = SymbolizeStackId(s->creation_stack_id);
275286}
276287
277u64 ScopedReportBase::AddMutex(u64 id) {
288u64 ScopedReportBase::AddMutex(u64 id) NO_THREAD_SAFETY_ANALYSIS {
278289 u64 uid = 0;
279290 u64 mid = id;
280291 uptr addr = SyncVar::SplitId(id, &uid);
......@@ -497,8 +508,10 @@ static bool HandleRacyAddress(ThreadState *thr, uptr addr_min, uptr addr_max) {
497508}
498509
499510bool OutputReport(ThreadState *thr, const ScopedReport &srep) {
500 if (!flags()->report_bugs || thr->suppress_reports)
501 return false;
511 // These should have been checked in ShouldReport.
512 // It's too late to check them here, we have already taken locks.
513 CHECK(flags()->report_bugs);
514 CHECK(!thr->suppress_reports);
502515 atomic_store_relaxed(&ctx->last_symbolize_time_ns, NanoTime());
503516 const ReportDesc *rep = srep.GetReport();
504517 CHECK_EQ(thr->current_report, nullptr);
......@@ -583,13 +596,13 @@ static bool RaceBetweenAtomicAndFree(ThreadState *thr) {
583596}
584597
585598void ReportRace(ThreadState *thr) {
586 CheckNoLocks(thr);
599 CheckedMutex::CheckNoLocks();
587600
588601 // Symbolizer makes lots of intercepted calls. If we try to process them,
589602 // at best it will cause deadlocks on internal mutexes.
590603 ScopedIgnoreInterceptors ignore;
591604
592 if (!flags()->report_bugs)
605 if (!ShouldReport(thr, ReportTypeRace))
593606 return;
594607 if (!flags()->report_atomic_races && !RaceBetweenAtomicAndFree(thr))
595608 return;
......@@ -706,9 +719,7 @@ void ReportRace(ThreadState *thr) {
706719 }
707720#endif
708721
709 if (!OutputReport(thr, rep))
710 return;
711
722 OutputReport(thr, rep);
712723}
713724
714725void PrintCurrentStack(ThreadState *thr, uptr pc) {
......@@ -724,8 +735,7 @@ void PrintCurrentStack(ThreadState *thr, uptr pc) {
724735// However, this solution is not reliable enough, please see dvyukov's comment
725736// http://reviews.llvm.org/D19148#406208
726737// Also see PR27280 comment 2 and 3 for breaking examples and analysis.
727ALWAYS_INLINE
728void PrintCurrentStackSlow(uptr pc) {
738ALWAYS_INLINE USED void PrintCurrentStackSlow(uptr pc) {
729739#if !SANITIZER_GO
730740 uptr bp = GET_CURRENT_FRAME();
731741 BufferedStackTrace *ptrace =
lib/tsan/tsan_rtl_thread.cpp+7-18
......@@ -51,7 +51,7 @@ struct OnCreatedArgs {
5151
5252void ThreadContext::OnCreated(void *arg) {
5353 thr = 0;
54 if (tid == 0)
54 if (tid == kMainTid)
5555 return;
5656 OnCreatedArgs *args = static_cast<OnCreatedArgs *>(arg);
5757 if (!args->thr) // GCD workers don't have a parent thread.
......@@ -61,8 +61,6 @@ void ThreadContext::OnCreated(void *arg) {
6161 TraceAddEvent(args->thr, args->thr->fast_state, EventTypeMop, 0);
6262 ReleaseImpl(args->thr, 0, &sync);
6363 creation_stack_id = CurrentStackId(args->thr, args->pc);
64 if (reuse_count == 0)
65 StatInc(args->thr, StatThreadMaxTid);
6664}
6765
6866void ThreadContext::OnReset() {
......@@ -115,7 +113,6 @@ void ThreadContext::OnStarted(void *arg) {
115113
116114 thr->fast_synch_epoch = epoch0;
117115 AcquireImpl(thr, 0, &sync);
118 StatInc(thr, StatSyncAcquire);
119116 sync.Reset(&thr->proc()->clock_cache);
120117 thr->is_inited = true;
121118 DPrintf("#%d: ThreadStart epoch=%zu stk_addr=%zx stk_size=%zx "
......@@ -149,9 +146,6 @@ void ThreadContext::OnFinished() {
149146 PlatformCleanUpThreadState(thr);
150147#endif
151148 thr->~ThreadState();
152#if TSAN_COLLECT_STATS
153 StatAggregate(ctx->stat, thr->stat);
154#endif
155149 thr = 0;
156150}
157151
......@@ -179,7 +173,7 @@ static void MaybeReportThreadLeak(ThreadContextBase *tctx_base, void *arg) {
179173
180174#if !SANITIZER_GO
181175static void ReportIgnoresEnabled(ThreadContext *tctx, IgnoreSet *set) {
182 if (tctx->tid == 0) {
176 if (tctx->tid == kMainTid) {
183177 Printf("ThreadSanitizer: main thread finished with ignores enabled\n");
184178 } else {
185179 Printf("ThreadSanitizer: thread T%d %s finished with ignores enabled,"
......@@ -210,7 +204,7 @@ static void ThreadCheckIgnore(ThreadState *thr) {}
210204void ThreadFinalize(ThreadState *thr) {
211205 ThreadCheckIgnore(thr);
212206#if !SANITIZER_GO
213 if (!flags()->report_thread_leaks)
207 if (!ShouldReport(thr, ReportTypeThreadLeak))
214208 return;
215209 ThreadRegistryLock l(ctx->thread_registry);
216210 Vector<ThreadLeak> leaks;
......@@ -232,13 +226,11 @@ int ThreadCount(ThreadState *thr) {
232226}
233227
234228int ThreadCreate(ThreadState *thr, uptr pc, uptr uid, bool detached) {
235 StatInc(thr, StatThreadCreate);
236229 OnCreatedArgs args = { thr, pc };
237230 u32 parent_tid = thr ? thr->tid : kInvalidTid; // No parent for GCD workers.
238231 int tid =
239232 ctx->thread_registry->CreateThread(uid, detached, parent_tid, &args);
240233 DPrintf("#%d: ThreadCreate tid=%d uid=%zu\n", parent_tid, tid, uid);
241 StatSet(thr, StatThreadMaxAlive, ctx->thread_registry->GetMaxAliveThreads());
242234 return tid;
243235}
244236
......@@ -250,9 +242,10 @@ void ThreadStart(ThreadState *thr, int tid, tid_t os_id,
250242 uptr tls_size = 0;
251243#if !SANITIZER_GO
252244 if (thread_type != ThreadType::Fiber)
253 GetThreadStackAndTls(tid == 0, &stk_addr, &stk_size, &tls_addr, &tls_size);
245 GetThreadStackAndTls(tid == kMainTid, &stk_addr, &stk_size, &tls_addr,
246 &tls_size);
254247
255 if (tid) {
248 if (tid != kMainTid) {
256249 if (stk_addr && stk_size)
257250 MemoryRangeImitateWrite(thr, /*pc=*/ 1, stk_addr, stk_size);
258251
......@@ -279,7 +272,6 @@ void ThreadStart(ThreadState *thr, int tid, tid_t os_id,
279272
280273void ThreadFinish(ThreadState *thr) {
281274 ThreadCheckIgnore(thr);
282 StatInc(thr, StatThreadFinish);
283275 if (thr->stk_addr && thr->stk_size)
284276 DontNeedShadowFor(thr->stk_addr, thr->stk_size);
285277 if (thr->tls_addr && thr->tls_size)
......@@ -313,7 +305,7 @@ static bool ConsumeThreadByUid(ThreadContextBase *tctx, void *arg) {
313305int ThreadConsumeTid(ThreadState *thr, uptr pc, uptr uid) {
314306 ConsumeThreadContext findCtx = {uid, nullptr};
315307 ctx->thread_registry->FindThread(ConsumeThreadByUid, &findCtx);
316 int tid = findCtx.tctx ? findCtx.tctx->tid : ThreadRegistry::kUnknownTid;
308 int tid = findCtx.tctx ? findCtx.tctx->tid : kInvalidTid;
317309 DPrintf("#%d: ThreadTid uid=%zu tid=%d\n", thr->tid, uid, tid);
318310 return tid;
319311}
......@@ -371,13 +363,10 @@ void MemoryAccessRange(ThreadState *thr, uptr pc, uptr addr,
371363 }
372364#endif
373365
374 StatInc(thr, StatMopRange);
375
376366 if (*shadow_mem == kShadowRodata) {
377367 DCHECK(!is_write);
378368 // Access to .rodata section, no races here.
379369 // Measurements show that it can be 10-20% of all memory accesses.
380 StatInc(thr, StatMopRangeRodata);
381370 return;
382371 }
383372
lib/tsan/tsan_stack_trace.cpp+3-5
......@@ -54,10 +54,8 @@ void __sanitizer::BufferedStackTrace::UnwindImpl(
5454 uptr pc, uptr bp, void *context, bool request_fast, u32 max_depth) {
5555 uptr top = 0;
5656 uptr bottom = 0;
57 if (StackTrace::WillUseFastUnwind(request_fast)) {
58 GetThreadStackTopAndBottom(false, &top, &bottom);
59 Unwind(max_depth, pc, bp, nullptr, top, bottom, true);
60 } else
61 Unwind(max_depth, pc, 0, context, 0, 0, false);
57 GetThreadStackTopAndBottom(false, &top, &bottom);
58 bool fast = StackTrace::WillUseFastUnwind(request_fast);
59 Unwind(max_depth, pc, bp, context, top, bottom, fast);
6260}
6361#endif // SANITIZER_GO
lib/tsan/tsan_stat.cpp deleted-186
......@@ -1,186 +0,0 @@
1//===-- tsan_stat.cpp -----------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file is a part of ThreadSanitizer (TSan), a race detector.
10//
11//===----------------------------------------------------------------------===//
12#include "tsan_stat.h"
13#include "tsan_rtl.h"
14
15namespace __tsan {
16
17#if TSAN_COLLECT_STATS
18
19void StatAggregate(u64 *dst, u64 *src) {
20 for (int i = 0; i < StatCnt; i++)
21 dst[i] += src[i];
22}
23
24void StatOutput(u64 *stat) {
25 stat[StatShadowNonZero] = stat[StatShadowProcessed] - stat[StatShadowZero];
26
27 static const char *name[StatCnt] = {};
28 name[StatMop] = "Memory accesses ";
29 name[StatMopRead] = " Including reads ";
30 name[StatMopWrite] = " writes ";
31 name[StatMop1] = " Including size 1 ";
32 name[StatMop2] = " size 2 ";
33 name[StatMop4] = " size 4 ";
34 name[StatMop8] = " size 8 ";
35 name[StatMopSame] = " Including same ";
36 name[StatMopIgnored] = " Including ignored ";
37 name[StatMopRange] = " Including range ";
38 name[StatMopRodata] = " Including .rodata ";
39 name[StatMopRangeRodata] = " Including .rodata range ";
40 name[StatShadowProcessed] = "Shadow processed ";
41 name[StatShadowZero] = " Including empty ";
42 name[StatShadowNonZero] = " Including non empty ";
43 name[StatShadowSameSize] = " Including same size ";
44 name[StatShadowIntersect] = " intersect ";
45 name[StatShadowNotIntersect] = " not intersect ";
46 name[StatShadowSameThread] = " Including same thread ";
47 name[StatShadowAnotherThread] = " another thread ";
48 name[StatShadowReplace] = " Including evicted ";
49
50 name[StatFuncEnter] = "Function entries ";
51 name[StatFuncExit] = "Function exits ";
52 name[StatEvents] = "Events collected ";
53
54 name[StatThreadCreate] = "Total threads created ";
55 name[StatThreadFinish] = " threads finished ";
56 name[StatThreadReuse] = " threads reused ";
57 name[StatThreadMaxTid] = " max tid ";
58 name[StatThreadMaxAlive] = " max alive threads ";
59
60 name[StatMutexCreate] = "Mutexes created ";
61 name[StatMutexDestroy] = " destroyed ";
62 name[StatMutexLock] = " lock ";
63 name[StatMutexUnlock] = " unlock ";
64 name[StatMutexRecLock] = " recursive lock ";
65 name[StatMutexRecUnlock] = " recursive unlock ";
66 name[StatMutexReadLock] = " read lock ";
67 name[StatMutexReadUnlock] = " read unlock ";
68
69 name[StatSyncCreated] = "Sync objects created ";
70 name[StatSyncDestroyed] = " destroyed ";
71 name[StatSyncAcquire] = " acquired ";
72 name[StatSyncRelease] = " released ";
73
74 name[StatClockAcquire] = "Clock acquire ";
75 name[StatClockAcquireEmpty] = " empty clock ";
76 name[StatClockAcquireFastRelease] = " fast from release-store ";
77 name[StatClockAcquireFull] = " full (slow) ";
78 name[StatClockAcquiredSomething] = " acquired something ";
79 name[StatClockRelease] = "Clock release ";
80 name[StatClockReleaseResize] = " resize ";
81 name[StatClockReleaseFast] = " fast ";
82 name[StatClockReleaseSlow] = " dirty overflow (slow) ";
83 name[StatClockReleaseFull] = " full (slow) ";
84 name[StatClockReleaseAcquired] = " was acquired ";
85 name[StatClockReleaseClearTail] = " clear tail ";
86 name[StatClockStore] = "Clock release store ";
87 name[StatClockStoreResize] = " resize ";
88 name[StatClockStoreFast] = " fast ";
89 name[StatClockStoreFull] = " slow ";
90 name[StatClockStoreTail] = " clear tail ";
91 name[StatClockAcquireRelease] = "Clock acquire-release ";
92
93 name[StatAtomic] = "Atomic operations ";
94 name[StatAtomicLoad] = " Including load ";
95 name[StatAtomicStore] = " store ";
96 name[StatAtomicExchange] = " exchange ";
97 name[StatAtomicFetchAdd] = " fetch_add ";
98 name[StatAtomicFetchSub] = " fetch_sub ";
99 name[StatAtomicFetchAnd] = " fetch_and ";
100 name[StatAtomicFetchOr] = " fetch_or ";
101 name[StatAtomicFetchXor] = " fetch_xor ";
102 name[StatAtomicFetchNand] = " fetch_nand ";
103 name[StatAtomicCAS] = " compare_exchange ";
104 name[StatAtomicFence] = " fence ";
105 name[StatAtomicRelaxed] = " Including relaxed ";
106 name[StatAtomicConsume] = " consume ";
107 name[StatAtomicAcquire] = " acquire ";
108 name[StatAtomicRelease] = " release ";
109 name[StatAtomicAcq_Rel] = " acq_rel ";
110 name[StatAtomicSeq_Cst] = " seq_cst ";
111 name[StatAtomic1] = " Including size 1 ";
112 name[StatAtomic2] = " size 2 ";
113 name[StatAtomic4] = " size 4 ";
114 name[StatAtomic8] = " size 8 ";
115 name[StatAtomic16] = " size 16 ";
116
117 name[StatAnnotation] = "Dynamic annotations ";
118 name[StatAnnotateHappensBefore] = " HappensBefore ";
119 name[StatAnnotateHappensAfter] = " HappensAfter ";
120 name[StatAnnotateCondVarSignal] = " CondVarSignal ";
121 name[StatAnnotateCondVarSignalAll] = " CondVarSignalAll ";
122 name[StatAnnotateMutexIsNotPHB] = " MutexIsNotPHB ";
123 name[StatAnnotateCondVarWait] = " CondVarWait ";
124 name[StatAnnotateRWLockCreate] = " RWLockCreate ";
125 name[StatAnnotateRWLockCreateStatic] = " StatAnnotateRWLockCreateStatic ";
126 name[StatAnnotateRWLockDestroy] = " RWLockDestroy ";
127 name[StatAnnotateRWLockAcquired] = " RWLockAcquired ";
128 name[StatAnnotateRWLockReleased] = " RWLockReleased ";
129 name[StatAnnotateTraceMemory] = " TraceMemory ";
130 name[StatAnnotateFlushState] = " FlushState ";
131 name[StatAnnotateNewMemory] = " NewMemory ";
132 name[StatAnnotateNoOp] = " NoOp ";
133 name[StatAnnotateFlushExpectedRaces] = " FlushExpectedRaces ";
134 name[StatAnnotateEnableRaceDetection] = " EnableRaceDetection ";
135 name[StatAnnotateMutexIsUsedAsCondVar] = " MutexIsUsedAsCondVar ";
136 name[StatAnnotatePCQGet] = " PCQGet ";
137 name[StatAnnotatePCQPut] = " PCQPut ";
138 name[StatAnnotatePCQDestroy] = " PCQDestroy ";
139 name[StatAnnotatePCQCreate] = " PCQCreate ";
140 name[StatAnnotateExpectRace] = " ExpectRace ";
141 name[StatAnnotateBenignRaceSized] = " BenignRaceSized ";
142 name[StatAnnotateBenignRace] = " BenignRace ";
143 name[StatAnnotateIgnoreReadsBegin] = " IgnoreReadsBegin ";
144 name[StatAnnotateIgnoreReadsEnd] = " IgnoreReadsEnd ";
145 name[StatAnnotateIgnoreWritesBegin] = " IgnoreWritesBegin ";
146 name[StatAnnotateIgnoreWritesEnd] = " IgnoreWritesEnd ";
147 name[StatAnnotateIgnoreSyncBegin] = " IgnoreSyncBegin ";
148 name[StatAnnotateIgnoreSyncEnd] = " IgnoreSyncEnd ";
149 name[StatAnnotatePublishMemoryRange] = " PublishMemoryRange ";
150 name[StatAnnotateUnpublishMemoryRange] = " UnpublishMemoryRange ";
151 name[StatAnnotateThreadName] = " ThreadName ";
152 name[Stat__tsan_mutex_create] = " __tsan_mutex_create ";
153 name[Stat__tsan_mutex_destroy] = " __tsan_mutex_destroy ";
154 name[Stat__tsan_mutex_pre_lock] = " __tsan_mutex_pre_lock ";
155 name[Stat__tsan_mutex_post_lock] = " __tsan_mutex_post_lock ";
156 name[Stat__tsan_mutex_pre_unlock] = " __tsan_mutex_pre_unlock ";
157 name[Stat__tsan_mutex_post_unlock] = " __tsan_mutex_post_unlock ";
158 name[Stat__tsan_mutex_pre_signal] = " __tsan_mutex_pre_signal ";
159 name[Stat__tsan_mutex_post_signal] = " __tsan_mutex_post_signal ";
160 name[Stat__tsan_mutex_pre_divert] = " __tsan_mutex_pre_divert ";
161 name[Stat__tsan_mutex_post_divert] = " __tsan_mutex_post_divert ";
162
163 name[StatMtxTotal] = "Contentionz ";
164 name[StatMtxTrace] = " Trace ";
165 name[StatMtxThreads] = " Threads ";
166 name[StatMtxReport] = " Report ";
167 name[StatMtxSyncVar] = " SyncVar ";
168 name[StatMtxSyncTab] = " SyncTab ";
169 name[StatMtxSlab] = " Slab ";
170 name[StatMtxAtExit] = " Atexit ";
171 name[StatMtxAnnotations] = " Annotations ";
172 name[StatMtxMBlock] = " MBlock ";
173 name[StatMtxDeadlockDetector] = " DeadlockDetector ";
174 name[StatMtxFired] = " FiredSuppressions ";
175 name[StatMtxRacy] = " RacyStacks ";
176 name[StatMtxFD] = " FD ";
177 name[StatMtxGlobalProc] = " GlobalProc ";
178
179 Printf("Statistics:\n");
180 for (int i = 0; i < StatCnt; i++)
181 Printf("%s: %16zu\n", name[i], (uptr)stat[i]);
182}
183
184#endif
185
186} // namespace __tsan
lib/tsan/tsan_stat.h deleted-191
......@@ -1,191 +0,0 @@
1//===-- tsan_stat.h ---------------------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file is a part of ThreadSanitizer (TSan), a race detector.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef TSAN_STAT_H
14#define TSAN_STAT_H
15
16namespace __tsan {
17
18enum StatType {
19 // Memory access processing related stuff.
20 StatMop,
21 StatMopRead,
22 StatMopWrite,
23 StatMop1, // These must be consequtive.
24 StatMop2,
25 StatMop4,
26 StatMop8,
27 StatMopSame,
28 StatMopIgnored,
29 StatMopRange,
30 StatMopRodata,
31 StatMopRangeRodata,
32 StatShadowProcessed,
33 StatShadowZero,
34 StatShadowNonZero, // Derived.
35 StatShadowSameSize,
36 StatShadowIntersect,
37 StatShadowNotIntersect,
38 StatShadowSameThread,
39 StatShadowAnotherThread,
40 StatShadowReplace,
41
42 // Func processing.
43 StatFuncEnter,
44 StatFuncExit,
45
46 // Trace processing.
47 StatEvents,
48
49 // Threads.
50 StatThreadCreate,
51 StatThreadFinish,
52 StatThreadReuse,
53 StatThreadMaxTid,
54 StatThreadMaxAlive,
55
56 // Mutexes.
57 StatMutexCreate,
58 StatMutexDestroy,
59 StatMutexLock,
60 StatMutexUnlock,
61 StatMutexRecLock,
62 StatMutexRecUnlock,
63 StatMutexReadLock,
64 StatMutexReadUnlock,
65
66 // Synchronization.
67 StatSyncCreated,
68 StatSyncDestroyed,
69 StatSyncAcquire,
70 StatSyncRelease,
71 StatSyncReleaseStoreAcquire,
72
73 // Clocks - acquire.
74 StatClockAcquire,
75 StatClockAcquireEmpty,
76 StatClockAcquireFastRelease,
77 StatClockAcquireFull,
78 StatClockAcquiredSomething,
79 // Clocks - release.
80 StatClockRelease,
81 StatClockReleaseResize,
82 StatClockReleaseFast,
83 StatClockReleaseSlow,
84 StatClockReleaseFull,
85 StatClockReleaseAcquired,
86 StatClockReleaseClearTail,
87 // Clocks - release store.
88 StatClockStore,
89 StatClockStoreResize,
90 StatClockStoreFast,
91 StatClockStoreFull,
92 StatClockStoreTail,
93 // Clocks - acquire-release.
94 StatClockAcquireRelease,
95
96 // Atomics.
97 StatAtomic,
98 StatAtomicLoad,
99 StatAtomicStore,
100 StatAtomicExchange,
101 StatAtomicFetchAdd,
102 StatAtomicFetchSub,
103 StatAtomicFetchAnd,
104 StatAtomicFetchOr,
105 StatAtomicFetchXor,
106 StatAtomicFetchNand,
107 StatAtomicCAS,
108 StatAtomicFence,
109 StatAtomicRelaxed,
110 StatAtomicConsume,
111 StatAtomicAcquire,
112 StatAtomicRelease,
113 StatAtomicAcq_Rel,
114 StatAtomicSeq_Cst,
115 StatAtomic1,
116 StatAtomic2,
117 StatAtomic4,
118 StatAtomic8,
119 StatAtomic16,
120
121 // Dynamic annotations.
122 StatAnnotation,
123 StatAnnotateHappensBefore,
124 StatAnnotateHappensAfter,
125 StatAnnotateCondVarSignal,
126 StatAnnotateCondVarSignalAll,
127 StatAnnotateMutexIsNotPHB,
128 StatAnnotateCondVarWait,
129 StatAnnotateRWLockCreate,
130 StatAnnotateRWLockCreateStatic,
131 StatAnnotateRWLockDestroy,
132 StatAnnotateRWLockAcquired,
133 StatAnnotateRWLockReleased,
134 StatAnnotateTraceMemory,
135 StatAnnotateFlushState,
136 StatAnnotateNewMemory,
137 StatAnnotateNoOp,
138 StatAnnotateFlushExpectedRaces,
139 StatAnnotateEnableRaceDetection,
140 StatAnnotateMutexIsUsedAsCondVar,
141 StatAnnotatePCQGet,
142 StatAnnotatePCQPut,
143 StatAnnotatePCQDestroy,
144 StatAnnotatePCQCreate,
145 StatAnnotateExpectRace,
146 StatAnnotateBenignRaceSized,
147 StatAnnotateBenignRace,
148 StatAnnotateIgnoreReadsBegin,
149 StatAnnotateIgnoreReadsEnd,
150 StatAnnotateIgnoreWritesBegin,
151 StatAnnotateIgnoreWritesEnd,
152 StatAnnotateIgnoreSyncBegin,
153 StatAnnotateIgnoreSyncEnd,
154 StatAnnotatePublishMemoryRange,
155 StatAnnotateUnpublishMemoryRange,
156 StatAnnotateThreadName,
157 Stat__tsan_mutex_create,
158 Stat__tsan_mutex_destroy,
159 Stat__tsan_mutex_pre_lock,
160 Stat__tsan_mutex_post_lock,
161 Stat__tsan_mutex_pre_unlock,
162 Stat__tsan_mutex_post_unlock,
163 Stat__tsan_mutex_pre_signal,
164 Stat__tsan_mutex_post_signal,
165 Stat__tsan_mutex_pre_divert,
166 Stat__tsan_mutex_post_divert,
167
168 // Internal mutex contentionz.
169 StatMtxTotal,
170 StatMtxTrace,
171 StatMtxThreads,
172 StatMtxReport,
173 StatMtxSyncVar,
174 StatMtxSyncTab,
175 StatMtxSlab,
176 StatMtxAnnotations,
177 StatMtxAtExit,
178 StatMtxMBlock,
179 StatMtxDeadlockDetector,
180 StatMtxFired,
181 StatMtxRacy,
182 StatMtxFD,
183 StatMtxGlobalProc,
184
185 // This must be the last.
186 StatCnt
187};
188
189} // namespace __tsan
190
191#endif // TSAN_STAT_H
lib/tsan/tsan_sync.cpp+6-9
......@@ -18,10 +18,7 @@ namespace __tsan {
1818
1919void DDMutexInit(ThreadState *thr, uptr pc, SyncVar *s);
2020
21SyncVar::SyncVar()
22 : mtx(MutexTypeSyncVar, StatMtxSyncVar) {
23 Reset(0);
24}
21SyncVar::SyncVar() : mtx(MutexTypeSyncVar) { Reset(0); }
2522
2623void SyncVar::Init(ThreadState *thr, uptr pc, uptr addr, u64 uid) {
2724 this->addr = addr;
......@@ -53,8 +50,8 @@ void SyncVar::Reset(Processor *proc) {
5350}
5451
5552MetaMap::MetaMap()
56 : block_alloc_("heap block allocator")
57 , sync_alloc_("sync allocator") {
53 : block_alloc_(LINKER_INITIALIZED, "heap block allocator"),
54 sync_alloc_(LINKER_INITIALIZED, "sync allocator") {
5855 atomic_store(&uid_gen_, 0, memory_order_relaxed);
5956}
6057
......@@ -175,7 +172,7 @@ void MetaMap::ResetRange(Processor *proc, uptr p, uptr sz) {
175172 uptr metap = (uptr)MemToMeta(p0);
176173 uptr metasz = sz0 / kMetaRatio;
177174 UnmapOrDie((void*)metap, metasz);
178 if (!MmapFixedNoReserve(metap, metasz))
175 if (!MmapFixedSuperNoReserve(metap, metasz))
179176 Die();
180177}
181178
......@@ -202,8 +199,8 @@ SyncVar* MetaMap::GetIfExistsAndLock(uptr addr, bool write_lock) {
202199 return GetAndLock(0, 0, addr, write_lock, false);
203200}
204201
205SyncVar* MetaMap::GetAndLock(ThreadState *thr, uptr pc,
206 uptr addr, bool write_lock, bool create) {
202SyncVar *MetaMap::GetAndLock(ThreadState *thr, uptr pc, uptr addr, bool write_lock,
203 bool create) NO_THREAD_SAFETY_ANALYSIS {
207204 u32 *meta = MemToMeta(addr);
208205 u32 idx0 = *meta;
209206 u32 myidx = 0;
lib/tsan/tsan_sync.h+3-6
......@@ -17,7 +17,6 @@
1717#include "sanitizer_common/sanitizer_deadlock_detector_interface.h"
1818#include "tsan_defs.h"
1919#include "tsan_clock.h"
20#include "tsan_mutex.h"
2120#include "tsan_dense_alloc.h"
2221
2322namespace __tsan {
......@@ -50,13 +49,11 @@ enum MutexFlags {
5049struct SyncVar {
5150 SyncVar();
5251
53 static const int kInvalidTid = -1;
54
5552 uptr addr; // overwritten by DenseSlabAlloc freelist
5653 Mutex mtx;
5754 u64 uid; // Globally unique id.
5855 u32 creation_stack_id;
59 int owner_tid; // Set only by exclusive owners.
56 u32 owner_tid; // Set only by exclusive owners.
6057 u64 last_lock;
6158 int recursion;
6259 atomic_uint32_t flags;
......@@ -130,8 +127,8 @@ class MetaMap {
130127 static const u32 kFlagMask = 3u << 30;
131128 static const u32 kFlagBlock = 1u << 30;
132129 static const u32 kFlagSync = 2u << 30;
133 typedef DenseSlabAlloc<MBlock, 1<<16, 1<<12> BlockAlloc;
134 typedef DenseSlabAlloc<SyncVar, 1<<16, 1<<10> SyncAlloc;
130 typedef DenseSlabAlloc<MBlock, 1 << 18, 1 << 12, kFlagMask> BlockAlloc;
131 typedef DenseSlabAlloc<SyncVar, 1 << 20, 1 << 10, kFlagMask> SyncAlloc;
135132 BlockAlloc block_alloc_;
136133 SyncAlloc sync_alloc_;
137134 atomic_uint64_t uid_gen_;
lib/tsan/tsan_trace.h+1-4
......@@ -13,7 +13,6 @@
1313#define TSAN_TRACE_H
1414
1515#include "tsan_defs.h"
16#include "tsan_mutex.h"
1716#include "tsan_stack_trace.h"
1817#include "tsan_mutexset.h"
1918
......@@ -65,9 +64,7 @@ struct Trace {
6564 // CreateThreadContext.
6665 TraceHeader headers[kTraceParts];
6766
68 Trace()
69 : mtx(MutexTypeTrace, StatMtxTrace) {
70 }
67 Trace() : mtx(MutexTypeTrace) {}
7168};
7269
7370} // namespace __tsan
lib/tsan/tsan_update_shadow_word_inl.h+1-11
......@@ -13,12 +13,10 @@
1313// produce sligtly less efficient code.
1414//===----------------------------------------------------------------------===//
1515do {
16 StatInc(thr, StatShadowProcessed);
1716 const unsigned kAccessSize = 1 << kAccessSizeLog;
1817 u64 *sp = &shadow_mem[idx];
1918 old = LoadShadow(sp);
2019 if (LIKELY(old.IsZero())) {
21 StatInc(thr, StatShadowZero);
2220 if (!stored) {
2321 StoreIfNotYetStored(sp, &store_word);
2422 stored = true;
......@@ -27,17 +25,14 @@ do {
2725 }
2826 // is the memory access equal to the previous?
2927 if (LIKELY(Shadow::Addr0AndSizeAreEqual(cur, old))) {
30 StatInc(thr, StatShadowSameSize);
3128 // same thread?
3229 if (LIKELY(Shadow::TidsAreEqual(old, cur))) {
33 StatInc(thr, StatShadowSameThread);
3430 if (LIKELY(old.IsRWWeakerOrEqual(kAccessIsWrite, kIsAtomic))) {
3531 StoreIfNotYetStored(sp, &store_word);
3632 stored = true;
3733 }
3834 break;
3935 }
40 StatInc(thr, StatShadowAnotherThread);
4136 if (HappensBefore(old, thr)) {
4237 if (old.IsRWWeakerOrEqual(kAccessIsWrite, kIsAtomic)) {
4338 StoreIfNotYetStored(sp, &store_word);
......@@ -51,12 +46,8 @@ do {
5146 }
5247 // Do the memory access intersect?
5348 if (Shadow::TwoRangesIntersect(old, cur, kAccessSize)) {
54 StatInc(thr, StatShadowIntersect);
55 if (Shadow::TidsAreEqual(old, cur)) {
56 StatInc(thr, StatShadowSameThread);
49 if (Shadow::TidsAreEqual(old, cur))
5750 break;
58 }
59 StatInc(thr, StatShadowAnotherThread);
6051 if (old.IsBothReadsOrAtomic(kAccessIsWrite, kIsAtomic))
6152 break;
6253 if (LIKELY(HappensBefore(old, thr)))
......@@ -64,6 +55,5 @@ do {
6455 goto RACE;
6556 }
6657 // The accesses do not intersect.
67 StatInc(thr, StatShadowNotIntersect);
6858 break;
6959} while (0);
lib/tsan/ubsan/ubsan_flags.h-2
......@@ -34,8 +34,6 @@ inline Flags *flags() { return &ubsan_flags; }
3434void InitializeFlags();
3535void RegisterUbsanFlags(FlagParser *parser, Flags *f);
3636
37const char *MaybeCallUbsanDefaultOptions();
38
3937} // namespace __ubsan
4038
4139extern "C" {
lib/tsan/ubsan/ubsan_platform.h+4-4
......@@ -14,10 +14,10 @@
1414
1515// Other platforms should be easy to add, and probably work as-is.
1616#if defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__) || \
17 defined(__NetBSD__) || defined(__OpenBSD__) || \
18 (defined(__sun__) && defined(__svr4__)) || \
19 defined(_WIN32) || defined(__Fuchsia__) || defined(__rtems__)
20# define CAN_SANITIZE_UB 1
17 defined(__NetBSD__) || defined(__DragonFly__) || \
18 (defined(__sun__) && defined(__svr4__)) || defined(_WIN32) || \
19 defined(__Fuchsia__)
20#define CAN_SANITIZE_UB 1
2121#else
2222# define CAN_SANITIZE_UB 0
2323#endif
src/Cache.zig+1-1
......@@ -210,7 +210,7 @@ pub const Manifest = struct {
210210 pub fn addFile(self: *Manifest, file_path: []const u8, max_file_size: ?usize) !usize {
211211 assert(self.manifest_file == null);
212212
213 try self.files.ensureCapacity(self.cache.gpa, self.files.items.len + 1);
213 try self.files.ensureUnusedCapacity(self.cache.gpa, 1);
214214 const resolved_path = try fs.path.resolve(self.cache.gpa, &[_][]const u8{file_path});
215215
216216 const idx = self.files.items.len;
src/Compilation.zig+4-2
......@@ -2666,7 +2666,7 @@ fn reportRetryableCObjectError(
26662666
26672667 const c_obj_err_msg = try comp.gpa.create(CObject.ErrorMsg);
26682668 errdefer comp.gpa.destroy(c_obj_err_msg);
2669 const msg = try std.fmt.allocPrint(comp.gpa, "unable to build C object: {s}", .{@errorName(err)});
2669 const msg = try std.fmt.allocPrint(comp.gpa, "{s}", .{@errorName(err)});
26702670 errdefer comp.gpa.free(msg);
26712671 c_obj_err_msg.* = .{
26722672 .msg = msg,
......@@ -2742,6 +2742,8 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: *std.P
27422742 const tracy = trace(@src());
27432743 defer tracy.end();
27442744
2745 log.debug("updating C object: {s}", .{c_object.src.src_path});
2746
27452747 if (c_object.clearStatus(comp.gpa)) {
27462748 // There was previous failure.
27472749 const lock = comp.mutex.acquire();
......@@ -3271,7 +3273,7 @@ fn failCObjWithOwnedErrorMsg(
32713273 defer lock.release();
32723274 {
32733275 errdefer err_msg.destroy(comp.gpa);
3274 try comp.failed_c_objects.ensureCapacity(comp.gpa, comp.failed_c_objects.count() + 1);
3276 try comp.failed_c_objects.ensureUnusedCapacity(comp.gpa, 1);
32753277 }
32763278 comp.failed_c_objects.putAssumeCapacityNoClobber(c_object, err_msg);
32773279 }
src/libcxx.zig+2
......@@ -45,6 +45,7 @@ const libcxx_files = [_][]const u8{
4545 "src/filesystem/directory_iterator.cpp",
4646 "src/filesystem/int128_builtins.cpp",
4747 "src/filesystem/operations.cpp",
48 "src/format.cpp",
4849 "src/functional.cpp",
4950 "src/future.cpp",
5051 "src/hash.cpp",
......@@ -64,6 +65,7 @@ const libcxx_files = [_][]const u8{
6465 "src/stdexcept.cpp",
6566 "src/string.cpp",
6667 "src/strstream.cpp",
68 "src/support/ibm/xlocale_zos.cpp",
6769 "src/support/solaris/xlocale.cpp",
6870 "src/support/win32/locale_win32.cpp",
6971 "src/support/win32/support.cpp",
src/libtsan.zig+4-6
......@@ -260,7 +260,6 @@ const tsan_sources = [_][]const u8{
260260 "tsan_malloc_mac.cpp",
261261 "tsan_md5.cpp",
262262 "tsan_mman.cpp",
263 "tsan_mutex.cpp",
264263 "tsan_mutexset.cpp",
265264 "tsan_preinit.cpp",
266265 "tsan_report.cpp",
......@@ -270,7 +269,6 @@ const tsan_sources = [_][]const u8{
270269 "tsan_rtl_report.cpp",
271270 "tsan_rtl_thread.cpp",
272271 "tsan_stack_trace.cpp",
273 "tsan_stat.cpp",
274272 "tsan_suppressions.cpp",
275273 "tsan_symbolize.cpp",
276274 "tsan_sync.cpp",
......@@ -295,14 +293,15 @@ const sanitizer_common_sources = [_][]const u8{
295293 "sanitizer_deadlock_detector2.cpp",
296294 "sanitizer_errno.cpp",
297295 "sanitizer_file.cpp",
298 "sanitizer_flags.cpp",
299296 "sanitizer_flag_parser.cpp",
297 "sanitizer_flags.cpp",
300298 "sanitizer_fuchsia.cpp",
301299 "sanitizer_libc.cpp",
302300 "sanitizer_libignore.cpp",
303301 "sanitizer_linux.cpp",
304302 "sanitizer_linux_s390.cpp",
305303 "sanitizer_mac.cpp",
304 "sanitizer_mutex.cpp",
306305 "sanitizer_netbsd.cpp",
307306 "sanitizer_openbsd.cpp",
308307 "sanitizer_persistent_allocator.cpp",
......@@ -314,20 +313,19 @@ const sanitizer_common_sources = [_][]const u8{
314313 "sanitizer_platform_limits_solaris.cpp",
315314 "sanitizer_posix.cpp",
316315 "sanitizer_printf.cpp",
317 "sanitizer_procmaps_common.cpp",
318316 "sanitizer_procmaps_bsd.cpp",
317 "sanitizer_procmaps_common.cpp",
319318 "sanitizer_procmaps_fuchsia.cpp",
320319 "sanitizer_procmaps_linux.cpp",
321320 "sanitizer_procmaps_mac.cpp",
322321 "sanitizer_procmaps_solaris.cpp",
323 "sanitizer_rtems.cpp",
324322 "sanitizer_solaris.cpp",
325323 "sanitizer_stoptheworld_fuchsia.cpp",
326324 "sanitizer_stoptheworld_mac.cpp",
327325 "sanitizer_suppressions.cpp",
328326 "sanitizer_termination.cpp",
329 "sanitizer_tls_get_addr.cpp",
330327 "sanitizer_thread_registry.cpp",
328 "sanitizer_tls_get_addr.cpp",
331329 "sanitizer_type_traits.cpp",
332330 "sanitizer_win.cpp",
333331};