feat: multi-user system, bug fixes, security & performance fixes, and more

This commit is contained in:
2026-03-14 13:28:46 +01:00
parent 576ad34f95
commit 261b536041
389 changed files with 231853 additions and 591 deletions
@@ -0,0 +1,970 @@
// <algorithm> Forward declarations -*- C++ -*-
// Copyright (C) 2007-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/algorithmfwd.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{algorithm}
*/
#ifndef _GLIBCXX_ALGORITHMFWD_H
#define _GLIBCXX_ALGORITHMFWD_H 1
#pragma GCC system_header
#include <bits/c++config.h>
#include <bits/stl_pair.h>
#include <bits/stl_iterator_base_types.h>
#if __cplusplus >= 201103L
#include <initializer_list>
#endif
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/*
adjacent_find
all_of (C++11)
any_of (C++11)
binary_search
clamp (C++17)
copy
copy_backward
copy_if (C++11)
copy_n (C++11)
count
count_if
equal
equal_range
fill
fill_n
find
find_end
find_first_of
find_if
find_if_not (C++11)
for_each
generate
generate_n
includes
inplace_merge
is_heap (C++11)
is_heap_until (C++11)
is_partitioned (C++11)
is_sorted (C++11)
is_sorted_until (C++11)
iter_swap
lexicographical_compare
lower_bound
make_heap
max
max_element
merge
min
min_element
minmax (C++11)
minmax_element (C++11)
mismatch
next_permutation
none_of (C++11)
nth_element
partial_sort
partial_sort_copy
partition
partition_copy (C++11)
partition_point (C++11)
pop_heap
prev_permutation
push_heap
random_shuffle
remove
remove_copy
remove_copy_if
remove_if
replace
replace_copy
replace_copy_if
replace_if
reverse
reverse_copy
rotate
rotate_copy
search
search_n
set_difference
set_intersection
set_symmetric_difference
set_union
shuffle (C++11)
sort
sort_heap
stable_partition
stable_sort
swap
swap_ranges
transform
unique
unique_copy
upper_bound
*/
/**
* @defgroup algorithms Algorithms
*
* Components for performing algorithmic operations. Includes
* non-modifying sequence, modifying (mutating) sequence, sorting,
* searching, merge, partition, heap, set, minima, maxima, and
* permutation operations.
*/
/**
* @defgroup mutating_algorithms Mutating
* @ingroup algorithms
*/
/**
* @defgroup non_mutating_algorithms Non-Mutating
* @ingroup algorithms
*/
/**
* @defgroup sorting_algorithms Sorting
* @ingroup algorithms
*/
/**
* @defgroup set_algorithms Set Operations
* @ingroup sorting_algorithms
*
* These algorithms are common set operations performed on sequences
* that are already sorted. The number of comparisons will be
* linear.
*/
/**
* @defgroup binary_search_algorithms Binary Search
* @ingroup sorting_algorithms
*
* These algorithms are variations of a classic binary search, and
* all assume that the sequence being searched is already sorted.
*
* The number of comparisons will be logarithmic (and as few as
* possible). The number of steps through the sequence will be
* logarithmic for random-access iterators (e.g., pointers), and
* linear otherwise.
*
* The LWG has passed Defect Report 270, which notes: <em>The
* proposed resolution reinterprets binary search. Instead of
* thinking about searching for a value in a sorted range, we view
* that as an important special case of a more general algorithm:
* searching for the partition point in a partitioned range. We
* also add a guarantee that the old wording did not: we ensure that
* the upper bound is no earlier than the lower bound, that the pair
* returned by equal_range is a valid range, and that the first part
* of that pair is the lower bound.</em>
*
* The actual effect of the first sentence is that a comparison
* functor passed by the user doesn't necessarily need to induce a
* strict weak ordering relation. Rather, it partitions the range.
*/
// adjacent_find
#if __cplusplus >= 201103L
template<typename _IIter, typename _Predicate>
_GLIBCXX20_CONSTEXPR
bool
all_of(_IIter, _IIter, _Predicate);
template<typename _IIter, typename _Predicate>
_GLIBCXX20_CONSTEXPR
bool
any_of(_IIter, _IIter, _Predicate);
#endif
template<typename _FIter, typename _Tp>
_GLIBCXX20_CONSTEXPR
bool
binary_search(_FIter, _FIter, const _Tp&);
template<typename _FIter, typename _Tp, typename _Compare>
_GLIBCXX20_CONSTEXPR
bool
binary_search(_FIter, _FIter, const _Tp&, _Compare);
#if __cplusplus > 201402L
template<typename _Tp>
_GLIBCXX14_CONSTEXPR
const _Tp&
clamp(const _Tp&, const _Tp&, const _Tp&);
template<typename _Tp, typename _Compare>
_GLIBCXX14_CONSTEXPR
const _Tp&
clamp(const _Tp&, const _Tp&, const _Tp&, _Compare);
#endif
template<typename _IIter, typename _OIter>
_GLIBCXX20_CONSTEXPR
_OIter
copy(_IIter, _IIter, _OIter);
template<typename _BIter1, typename _BIter2>
_GLIBCXX20_CONSTEXPR
_BIter2
copy_backward(_BIter1, _BIter1, _BIter2);
#if __cplusplus >= 201103L
template<typename _IIter, typename _OIter, typename _Predicate>
_GLIBCXX20_CONSTEXPR
_OIter
copy_if(_IIter, _IIter, _OIter, _Predicate);
template<typename _IIter, typename _Size, typename _OIter>
_GLIBCXX20_CONSTEXPR
_OIter
copy_n(_IIter, _Size, _OIter);
#endif
// count
// count_if
template<typename _FIter, typename _Tp>
_GLIBCXX20_CONSTEXPR
pair<_FIter, _FIter>
equal_range(_FIter, _FIter, const _Tp&);
template<typename _FIter, typename _Tp, typename _Compare>
_GLIBCXX20_CONSTEXPR
pair<_FIter, _FIter>
equal_range(_FIter, _FIter, const _Tp&, _Compare);
template<typename _FIter, typename _Tp>
_GLIBCXX20_CONSTEXPR
void
fill(_FIter, _FIter, const _Tp&);
template<typename _OIter, typename _Size, typename _Tp>
_GLIBCXX20_CONSTEXPR
_OIter
fill_n(_OIter, _Size, const _Tp&);
// find
template<typename _FIter1, typename _FIter2>
_GLIBCXX20_CONSTEXPR
_FIter1
find_end(_FIter1, _FIter1, _FIter2, _FIter2);
template<typename _FIter1, typename _FIter2, typename _BinaryPredicate>
_GLIBCXX20_CONSTEXPR
_FIter1
find_end(_FIter1, _FIter1, _FIter2, _FIter2, _BinaryPredicate);
// find_first_of
// find_if
#if __cplusplus >= 201103L
template<typename _IIter, typename _Predicate>
_GLIBCXX20_CONSTEXPR
_IIter
find_if_not(_IIter, _IIter, _Predicate);
#endif
// for_each
// generate
// generate_n
template<typename _IIter1, typename _IIter2>
_GLIBCXX20_CONSTEXPR
bool
includes(_IIter1, _IIter1, _IIter2, _IIter2);
template<typename _IIter1, typename _IIter2, typename _Compare>
_GLIBCXX20_CONSTEXPR
bool
includes(_IIter1, _IIter1, _IIter2, _IIter2, _Compare);
template<typename _BIter>
void
inplace_merge(_BIter, _BIter, _BIter);
template<typename _BIter, typename _Compare>
void
inplace_merge(_BIter, _BIter, _BIter, _Compare);
#if __cplusplus >= 201103L
template<typename _RAIter>
_GLIBCXX20_CONSTEXPR
bool
is_heap(_RAIter, _RAIter);
template<typename _RAIter, typename _Compare>
_GLIBCXX20_CONSTEXPR
bool
is_heap(_RAIter, _RAIter, _Compare);
template<typename _RAIter>
_GLIBCXX20_CONSTEXPR
_RAIter
is_heap_until(_RAIter, _RAIter);
template<typename _RAIter, typename _Compare>
_GLIBCXX20_CONSTEXPR
_RAIter
is_heap_until(_RAIter, _RAIter, _Compare);
template<typename _IIter, typename _Predicate>
_GLIBCXX20_CONSTEXPR
bool
is_partitioned(_IIter, _IIter, _Predicate);
template<typename _FIter1, typename _FIter2>
_GLIBCXX20_CONSTEXPR
bool
is_permutation(_FIter1, _FIter1, _FIter2);
template<typename _FIter1, typename _FIter2,
typename _BinaryPredicate>
_GLIBCXX20_CONSTEXPR
bool
is_permutation(_FIter1, _FIter1, _FIter2, _BinaryPredicate);
template<typename _FIter>
_GLIBCXX20_CONSTEXPR
bool
is_sorted(_FIter, _FIter);
template<typename _FIter, typename _Compare>
_GLIBCXX20_CONSTEXPR
bool
is_sorted(_FIter, _FIter, _Compare);
template<typename _FIter>
_GLIBCXX20_CONSTEXPR
_FIter
is_sorted_until(_FIter, _FIter);
template<typename _FIter, typename _Compare>
_GLIBCXX20_CONSTEXPR
_FIter
is_sorted_until(_FIter, _FIter, _Compare);
#endif
template<typename _FIter1, typename _FIter2>
_GLIBCXX20_CONSTEXPR
void
iter_swap(_FIter1, _FIter2);
template<typename _FIter, typename _Tp>
_GLIBCXX20_CONSTEXPR
_FIter
lower_bound(_FIter, _FIter, const _Tp&);
template<typename _FIter, typename _Tp, typename _Compare>
_GLIBCXX20_CONSTEXPR
_FIter
lower_bound(_FIter, _FIter, const _Tp&, _Compare);
template<typename _RAIter>
_GLIBCXX20_CONSTEXPR
void
make_heap(_RAIter, _RAIter);
template<typename _RAIter, typename _Compare>
_GLIBCXX20_CONSTEXPR
void
make_heap(_RAIter, _RAIter, _Compare);
template<typename _Tp>
_GLIBCXX14_CONSTEXPR
const _Tp&
max(const _Tp&, const _Tp&);
template<typename _Tp, typename _Compare>
_GLIBCXX14_CONSTEXPR
const _Tp&
max(const _Tp&, const _Tp&, _Compare);
// max_element
// merge
template<typename _Tp>
_GLIBCXX14_CONSTEXPR
const _Tp&
min(const _Tp&, const _Tp&);
template<typename _Tp, typename _Compare>
_GLIBCXX14_CONSTEXPR
const _Tp&
min(const _Tp&, const _Tp&, _Compare);
// min_element
#if __cplusplus >= 201103L
template<typename _Tp>
_GLIBCXX14_CONSTEXPR
pair<const _Tp&, const _Tp&>
minmax(const _Tp&, const _Tp&);
template<typename _Tp, typename _Compare>
_GLIBCXX14_CONSTEXPR
pair<const _Tp&, const _Tp&>
minmax(const _Tp&, const _Tp&, _Compare);
template<typename _FIter>
_GLIBCXX14_CONSTEXPR
pair<_FIter, _FIter>
minmax_element(_FIter, _FIter);
template<typename _FIter, typename _Compare>
_GLIBCXX14_CONSTEXPR
pair<_FIter, _FIter>
minmax_element(_FIter, _FIter, _Compare);
template<typename _Tp>
_GLIBCXX14_CONSTEXPR
_Tp
min(initializer_list<_Tp>);
template<typename _Tp, typename _Compare>
_GLIBCXX14_CONSTEXPR
_Tp
min(initializer_list<_Tp>, _Compare);
template<typename _Tp>
_GLIBCXX14_CONSTEXPR
_Tp
max(initializer_list<_Tp>);
template<typename _Tp, typename _Compare>
_GLIBCXX14_CONSTEXPR
_Tp
max(initializer_list<_Tp>, _Compare);
template<typename _Tp>
_GLIBCXX14_CONSTEXPR
pair<_Tp, _Tp>
minmax(initializer_list<_Tp>);
template<typename _Tp, typename _Compare>
_GLIBCXX14_CONSTEXPR
pair<_Tp, _Tp>
minmax(initializer_list<_Tp>, _Compare);
#endif
// mismatch
template<typename _BIter>
_GLIBCXX20_CONSTEXPR
bool
next_permutation(_BIter, _BIter);
template<typename _BIter, typename _Compare>
_GLIBCXX20_CONSTEXPR
bool
next_permutation(_BIter, _BIter, _Compare);
#if __cplusplus >= 201103L
template<typename _IIter, typename _Predicate>
_GLIBCXX20_CONSTEXPR
bool
none_of(_IIter, _IIter, _Predicate);
#endif
// nth_element
// partial_sort
template<typename _IIter, typename _RAIter>
_GLIBCXX20_CONSTEXPR
_RAIter
partial_sort_copy(_IIter, _IIter, _RAIter, _RAIter);
template<typename _IIter, typename _RAIter, typename _Compare>
_GLIBCXX20_CONSTEXPR
_RAIter
partial_sort_copy(_IIter, _IIter, _RAIter, _RAIter, _Compare);
// partition
#if __cplusplus >= 201103L
template<typename _IIter, typename _OIter1,
typename _OIter2, typename _Predicate>
_GLIBCXX20_CONSTEXPR
pair<_OIter1, _OIter2>
partition_copy(_IIter, _IIter, _OIter1, _OIter2, _Predicate);
template<typename _FIter, typename _Predicate>
_GLIBCXX20_CONSTEXPR
_FIter
partition_point(_FIter, _FIter, _Predicate);
#endif
template<typename _RAIter>
_GLIBCXX20_CONSTEXPR
void
pop_heap(_RAIter, _RAIter);
template<typename _RAIter, typename _Compare>
_GLIBCXX20_CONSTEXPR
void
pop_heap(_RAIter, _RAIter, _Compare);
template<typename _BIter>
_GLIBCXX20_CONSTEXPR
bool
prev_permutation(_BIter, _BIter);
template<typename _BIter, typename _Compare>
_GLIBCXX20_CONSTEXPR
bool
prev_permutation(_BIter, _BIter, _Compare);
template<typename _RAIter>
_GLIBCXX20_CONSTEXPR
void
push_heap(_RAIter, _RAIter);
template<typename _RAIter, typename _Compare>
_GLIBCXX20_CONSTEXPR
void
push_heap(_RAIter, _RAIter, _Compare);
// random_shuffle
template<typename _FIter, typename _Tp>
_GLIBCXX20_CONSTEXPR
_FIter
remove(_FIter, _FIter, const _Tp&);
template<typename _FIter, typename _Predicate>
_GLIBCXX20_CONSTEXPR
_FIter
remove_if(_FIter, _FIter, _Predicate);
template<typename _IIter, typename _OIter, typename _Tp>
_GLIBCXX20_CONSTEXPR
_OIter
remove_copy(_IIter, _IIter, _OIter, const _Tp&);
template<typename _IIter, typename _OIter, typename _Predicate>
_GLIBCXX20_CONSTEXPR
_OIter
remove_copy_if(_IIter, _IIter, _OIter, _Predicate);
// replace
template<typename _IIter, typename _OIter, typename _Tp>
_GLIBCXX20_CONSTEXPR
_OIter
replace_copy(_IIter, _IIter, _OIter, const _Tp&, const _Tp&);
template<typename _Iter, typename _OIter, typename _Predicate, typename _Tp>
_GLIBCXX20_CONSTEXPR
_OIter
replace_copy_if(_Iter, _Iter, _OIter, _Predicate, const _Tp&);
// replace_if
template<typename _BIter>
_GLIBCXX20_CONSTEXPR
void
reverse(_BIter, _BIter);
template<typename _BIter, typename _OIter>
_GLIBCXX20_CONSTEXPR
_OIter
reverse_copy(_BIter, _BIter, _OIter);
_GLIBCXX_BEGIN_INLINE_ABI_NAMESPACE(_V2)
template<typename _FIter>
_GLIBCXX20_CONSTEXPR
_FIter
rotate(_FIter, _FIter, _FIter);
_GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
template<typename _FIter, typename _OIter>
_GLIBCXX20_CONSTEXPR
_OIter
rotate_copy(_FIter, _FIter, _FIter, _OIter);
// search
// search_n
// set_difference
// set_intersection
// set_symmetric_difference
// set_union
#if __cplusplus >= 201103L
template<typename _RAIter, typename _UGenerator>
void
shuffle(_RAIter, _RAIter, _UGenerator&&);
#endif
template<typename _RAIter>
_GLIBCXX20_CONSTEXPR
void
sort_heap(_RAIter, _RAIter);
template<typename _RAIter, typename _Compare>
_GLIBCXX20_CONSTEXPR
void
sort_heap(_RAIter, _RAIter, _Compare);
#if _GLIBCXX_HOSTED
template<typename _BIter, typename _Predicate>
_BIter
stable_partition(_BIter, _BIter, _Predicate);
#endif
#if __cplusplus < 201103L
// For C++11 swap() is declared in <type_traits>.
template<typename _Tp, size_t _Nm>
_GLIBCXX20_CONSTEXPR
inline void
swap(_Tp& __a, _Tp& __b);
template<typename _Tp, size_t _Nm>
_GLIBCXX20_CONSTEXPR
inline void
swap(_Tp (&__a)[_Nm], _Tp (&__b)[_Nm]);
#endif
template<typename _FIter1, typename _FIter2>
_GLIBCXX20_CONSTEXPR
_FIter2
swap_ranges(_FIter1, _FIter1, _FIter2);
// transform
template<typename _FIter>
_GLIBCXX20_CONSTEXPR
_FIter
unique(_FIter, _FIter);
template<typename _FIter, typename _BinaryPredicate>
_GLIBCXX20_CONSTEXPR
_FIter
unique(_FIter, _FIter, _BinaryPredicate);
// unique_copy
template<typename _FIter, typename _Tp>
_GLIBCXX20_CONSTEXPR
_FIter
upper_bound(_FIter, _FIter, const _Tp&);
template<typename _FIter, typename _Tp, typename _Compare>
_GLIBCXX20_CONSTEXPR
_FIter
upper_bound(_FIter, _FIter, const _Tp&, _Compare);
_GLIBCXX_BEGIN_NAMESPACE_ALGO
template<typename _FIter>
_GLIBCXX20_CONSTEXPR
_FIter
adjacent_find(_FIter, _FIter);
template<typename _FIter, typename _BinaryPredicate>
_GLIBCXX20_CONSTEXPR
_FIter
adjacent_find(_FIter, _FIter, _BinaryPredicate);
template<typename _IIter, typename _Tp>
_GLIBCXX20_CONSTEXPR
typename iterator_traits<_IIter>::difference_type
count(_IIter, _IIter, const _Tp&);
template<typename _IIter, typename _Predicate>
_GLIBCXX20_CONSTEXPR
typename iterator_traits<_IIter>::difference_type
count_if(_IIter, _IIter, _Predicate);
template<typename _IIter1, typename _IIter2>
_GLIBCXX20_CONSTEXPR
bool
equal(_IIter1, _IIter1, _IIter2);
template<typename _IIter1, typename _IIter2, typename _BinaryPredicate>
_GLIBCXX20_CONSTEXPR
bool
equal(_IIter1, _IIter1, _IIter2, _BinaryPredicate);
template<typename _IIter, typename _Tp>
_GLIBCXX20_CONSTEXPR
_IIter
find(_IIter, _IIter, const _Tp&);
template<typename _FIter1, typename _FIter2>
_GLIBCXX20_CONSTEXPR
_FIter1
find_first_of(_FIter1, _FIter1, _FIter2, _FIter2);
template<typename _FIter1, typename _FIter2, typename _BinaryPredicate>
_GLIBCXX20_CONSTEXPR
_FIter1
find_first_of(_FIter1, _FIter1, _FIter2, _FIter2, _BinaryPredicate);
template<typename _IIter, typename _Predicate>
_GLIBCXX20_CONSTEXPR
_IIter
find_if(_IIter, _IIter, _Predicate);
template<typename _IIter, typename _Funct>
_GLIBCXX20_CONSTEXPR
_Funct
for_each(_IIter, _IIter, _Funct);
template<typename _FIter, typename _Generator>
_GLIBCXX20_CONSTEXPR
void
generate(_FIter, _FIter, _Generator);
template<typename _OIter, typename _Size, typename _Generator>
_GLIBCXX20_CONSTEXPR
_OIter
generate_n(_OIter, _Size, _Generator);
template<typename _IIter1, typename _IIter2>
_GLIBCXX20_CONSTEXPR
bool
lexicographical_compare(_IIter1, _IIter1, _IIter2, _IIter2);
template<typename _IIter1, typename _IIter2, typename _Compare>
_GLIBCXX20_CONSTEXPR
bool
lexicographical_compare(_IIter1, _IIter1, _IIter2, _IIter2, _Compare);
template<typename _FIter>
_GLIBCXX14_CONSTEXPR
_FIter
max_element(_FIter, _FIter);
template<typename _FIter, typename _Compare>
_GLIBCXX14_CONSTEXPR
_FIter
max_element(_FIter, _FIter, _Compare);
template<typename _IIter1, typename _IIter2, typename _OIter>
_GLIBCXX20_CONSTEXPR
_OIter
merge(_IIter1, _IIter1, _IIter2, _IIter2, _OIter);
template<typename _IIter1, typename _IIter2, typename _OIter,
typename _Compare>
_GLIBCXX20_CONSTEXPR
_OIter
merge(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Compare);
template<typename _FIter>
_GLIBCXX14_CONSTEXPR
_FIter
min_element(_FIter, _FIter);
template<typename _FIter, typename _Compare>
_GLIBCXX14_CONSTEXPR
_FIter
min_element(_FIter, _FIter, _Compare);
template<typename _IIter1, typename _IIter2>
_GLIBCXX20_CONSTEXPR
pair<_IIter1, _IIter2>
mismatch(_IIter1, _IIter1, _IIter2);
template<typename _IIter1, typename _IIter2, typename _BinaryPredicate>
_GLIBCXX20_CONSTEXPR
pair<_IIter1, _IIter2>
mismatch(_IIter1, _IIter1, _IIter2, _BinaryPredicate);
template<typename _RAIter>
_GLIBCXX20_CONSTEXPR
void
nth_element(_RAIter, _RAIter, _RAIter);
template<typename _RAIter, typename _Compare>
_GLIBCXX20_CONSTEXPR
void
nth_element(_RAIter, _RAIter, _RAIter, _Compare);
template<typename _RAIter>
_GLIBCXX20_CONSTEXPR
void
partial_sort(_RAIter, _RAIter, _RAIter);
template<typename _RAIter, typename _Compare>
_GLIBCXX20_CONSTEXPR
void
partial_sort(_RAIter, _RAIter, _RAIter, _Compare);
template<typename _BIter, typename _Predicate>
_GLIBCXX20_CONSTEXPR
_BIter
partition(_BIter, _BIter, _Predicate);
#if _GLIBCXX_HOSTED
template<typename _RAIter>
_GLIBCXX14_DEPRECATED_SUGGEST("std::shuffle")
void
random_shuffle(_RAIter, _RAIter);
template<typename _RAIter, typename _Generator>
_GLIBCXX14_DEPRECATED_SUGGEST("std::shuffle")
void
random_shuffle(_RAIter, _RAIter,
#if __cplusplus >= 201103L
_Generator&&);
#else
_Generator&);
#endif
#endif // HOSTED
template<typename _FIter, typename _Tp>
_GLIBCXX20_CONSTEXPR
void
replace(_FIter, _FIter, const _Tp&, const _Tp&);
template<typename _FIter, typename _Predicate, typename _Tp>
_GLIBCXX20_CONSTEXPR
void
replace_if(_FIter, _FIter, _Predicate, const _Tp&);
template<typename _FIter1, typename _FIter2>
_GLIBCXX20_CONSTEXPR
_FIter1
search(_FIter1, _FIter1, _FIter2, _FIter2);
template<typename _FIter1, typename _FIter2, typename _BinaryPredicate>
_GLIBCXX20_CONSTEXPR
_FIter1
search(_FIter1, _FIter1, _FIter2, _FIter2, _BinaryPredicate);
template<typename _FIter, typename _Size, typename _Tp>
_GLIBCXX20_CONSTEXPR
_FIter
search_n(_FIter, _FIter, _Size, const _Tp&);
template<typename _FIter, typename _Size, typename _Tp,
typename _BinaryPredicate>
_GLIBCXX20_CONSTEXPR
_FIter
search_n(_FIter, _FIter, _Size, const _Tp&, _BinaryPredicate);
template<typename _IIter1, typename _IIter2, typename _OIter>
_GLIBCXX20_CONSTEXPR
_OIter
set_difference(_IIter1, _IIter1, _IIter2, _IIter2, _OIter);
template<typename _IIter1, typename _IIter2, typename _OIter,
typename _Compare>
_GLIBCXX20_CONSTEXPR
_OIter
set_difference(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Compare);
template<typename _IIter1, typename _IIter2, typename _OIter>
_GLIBCXX20_CONSTEXPR
_OIter
set_intersection(_IIter1, _IIter1, _IIter2, _IIter2, _OIter);
template<typename _IIter1, typename _IIter2, typename _OIter,
typename _Compare>
_GLIBCXX20_CONSTEXPR
_OIter
set_intersection(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Compare);
template<typename _IIter1, typename _IIter2, typename _OIter>
_GLIBCXX20_CONSTEXPR
_OIter
set_symmetric_difference(_IIter1, _IIter1, _IIter2, _IIter2, _OIter);
template<typename _IIter1, typename _IIter2, typename _OIter,
typename _Compare>
_GLIBCXX20_CONSTEXPR
_OIter
set_symmetric_difference(_IIter1, _IIter1, _IIter2, _IIter2,
_OIter, _Compare);
template<typename _IIter1, typename _IIter2, typename _OIter>
_GLIBCXX20_CONSTEXPR
_OIter
set_union(_IIter1, _IIter1, _IIter2, _IIter2, _OIter);
template<typename _IIter1, typename _IIter2, typename _OIter,
typename _Compare>
_GLIBCXX20_CONSTEXPR
_OIter
set_union(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Compare);
template<typename _RAIter>
_GLIBCXX20_CONSTEXPR
void
sort(_RAIter, _RAIter);
template<typename _RAIter, typename _Compare>
_GLIBCXX20_CONSTEXPR
void
sort(_RAIter, _RAIter, _Compare);
template<typename _RAIter>
void
stable_sort(_RAIter, _RAIter);
template<typename _RAIter, typename _Compare>
void
stable_sort(_RAIter, _RAIter, _Compare);
template<typename _IIter, typename _OIter, typename _UnaryOperation>
_GLIBCXX20_CONSTEXPR
_OIter
transform(_IIter, _IIter, _OIter, _UnaryOperation);
template<typename _IIter1, typename _IIter2, typename _OIter,
typename _BinaryOperation>
_GLIBCXX20_CONSTEXPR
_OIter
transform(_IIter1, _IIter1, _IIter2, _OIter, _BinaryOperation);
template<typename _IIter, typename _OIter>
_GLIBCXX20_CONSTEXPR
_OIter
unique_copy(_IIter, _IIter, _OIter);
template<typename _IIter, typename _OIter, typename _BinaryPredicate>
_GLIBCXX20_CONSTEXPR
_OIter
unique_copy(_IIter, _IIter, _OIter, _BinaryPredicate);
_GLIBCXX_END_NAMESPACE_ALGO
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#ifdef _GLIBCXX_PARALLEL
# include <parallel/algorithmfwd.h>
#endif
#endif
+109
View File
@@ -0,0 +1,109 @@
// align implementation -*- C++ -*-
// Copyright (C) 2014-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/align.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{memory}
*/
#ifndef _GLIBCXX_ALIGN_H
#define _GLIBCXX_ALIGN_H 1
#include <bit> // std::has_single_bit
#include <stdint.h> // uintptr_t
#include <debug/assertions.h> // _GLIBCXX_DEBUG_ASSERT
#include <bits/version.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
* @brief Fit aligned storage in buffer.
*
* This function tries to fit @a __size bytes of storage with alignment
* @a __align into the buffer @a __ptr of size @a __space bytes. If such
* a buffer fits then @a __ptr is changed to point to the first byte of the
* aligned storage and @a __space is reduced by the bytes used for alignment.
*
* C++11 20.6.5 [ptr.align]
*
* @param __align A fundamental or extended alignment value.
* @param __size Size of the aligned storage required.
* @param __ptr Pointer to a buffer of @a __space bytes.
* @param __space Size of the buffer pointed to by @a __ptr.
* @return the updated pointer if the aligned storage fits, otherwise nullptr.
*
* @ingroup memory
*/
inline void*
align(size_t __align, size_t __size, void*& __ptr, size_t& __space) noexcept
{
if (__space < __size)
return nullptr;
const auto __intptr = reinterpret_cast<uintptr_t>(__ptr);
const auto __aligned = (__intptr - 1u + __align) & -__align;
const auto __diff = __aligned - __intptr;
if (__diff > (__space - __size))
return nullptr;
else
{
__space -= __diff;
return __ptr = reinterpret_cast<void*>(__aligned);
}
}
#ifdef __glibcxx_assume_aligned // C++ >= 20
/** @brief Inform the compiler that a pointer is aligned.
*
* @tparam _Align An alignment value (i.e. a power of two)
* @tparam _Tp An object type
* @param __ptr A pointer that is aligned to _Align
*
* C++20 20.10.6 [ptr.align]
*
* @ingroup memory
*/
template<size_t _Align, class _Tp>
[[nodiscard,__gnu__::__always_inline__]]
constexpr _Tp*
assume_aligned(_Tp* __ptr) noexcept
{
static_assert(std::has_single_bit(_Align));
if (std::is_constant_evaluated())
return __ptr;
else
{
// This function is expected to be used in hot code, where
// __glibcxx_assert would add unwanted overhead.
_GLIBCXX_DEBUG_ASSERT((uintptr_t)__ptr % _Align == 0);
return static_cast<_Tp*>(__builtin_assume_aligned(__ptr, _Align));
}
}
#endif // __glibcxx_assume_aligned
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif /* _GLIBCXX_ALIGN_H */
@@ -0,0 +1,951 @@
// Allocator traits -*- C++ -*-
// Copyright (C) 2011-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/alloc_traits.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{memory}
*/
#ifndef _ALLOC_TRAITS_H
#define _ALLOC_TRAITS_H 1
#include <bits/stl_construct.h>
#include <bits/memoryfwd.h>
#if __cplusplus >= 201103L
# include <bits/ptr_traits.h>
# include <ext/numeric_traits.h>
# if _GLIBCXX_HOSTED
# include <bits/allocator.h>
# endif
# if __cpp_exceptions
# include <bits/stl_iterator.h> // __make_move_if_noexcept_iterator
# endif
#endif
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
#if __cplusplus >= 201103L
/// @cond undocumented
struct __allocator_traits_base
{
template<typename _Tp, typename _Up, typename = void>
struct __rebind : __replace_first_arg<_Tp, _Up>
{
static_assert(is_same<
typename __replace_first_arg<_Tp, typename _Tp::value_type>::type,
_Tp>::value,
"allocator_traits<A>::rebind_alloc<A::value_type> must be A");
};
template<typename _Tp, typename _Up>
struct __rebind<_Tp, _Up,
__void_t<typename _Tp::template rebind<_Up>::other>>
{
using type = typename _Tp::template rebind<_Up>::other;
static_assert(is_same<
typename _Tp::template rebind<typename _Tp::value_type>::other,
_Tp>::value,
"allocator_traits<A>::rebind_alloc<A::value_type> must be A");
};
protected:
template<typename _Tp>
using __pointer = typename _Tp::pointer;
template<typename _Tp>
using __c_pointer = typename _Tp::const_pointer;
template<typename _Tp>
using __v_pointer = typename _Tp::void_pointer;
template<typename _Tp>
using __cv_pointer = typename _Tp::const_void_pointer;
template<typename _Tp>
using __pocca = typename _Tp::propagate_on_container_copy_assignment;
template<typename _Tp>
using __pocma = typename _Tp::propagate_on_container_move_assignment;
template<typename _Tp>
using __pocs = typename _Tp::propagate_on_container_swap;
template<typename _Tp>
using __equal = __type_identity<typename _Tp::is_always_equal>;
};
template<typename _Alloc, typename _Up>
using __alloc_rebind
= typename __allocator_traits_base::template __rebind<_Alloc, _Up>::type;
/// @endcond
/**
* @brief Uniform interface to all allocator types.
* @headerfile memory
* @ingroup allocators
* @since C++11
*/
template<typename _Alloc>
struct allocator_traits : __allocator_traits_base
{
/// The allocator type
typedef _Alloc allocator_type;
/// The allocated type
typedef typename _Alloc::value_type value_type;
/**
* @brief The allocator's pointer type.
*
* @c Alloc::pointer if that type exists, otherwise @c value_type*
*/
using pointer = __detected_or_t<value_type*, __pointer, _Alloc>;
private:
// Select _Func<_Alloc> or pointer_traits<pointer>::rebind<_Tp>
template<template<typename> class _Func, typename _Tp, typename = void>
struct _Ptr
{
using type = typename pointer_traits<pointer>::template rebind<_Tp>;
};
template<template<typename> class _Func, typename _Tp>
struct _Ptr<_Func, _Tp, __void_t<_Func<_Alloc>>>
{
using type = _Func<_Alloc>;
};
// Select _A2::difference_type or pointer_traits<_Ptr>::difference_type
template<typename _A2, typename _PtrT, typename = void>
struct _Diff
{ using type = typename pointer_traits<_PtrT>::difference_type; };
template<typename _A2, typename _PtrT>
struct _Diff<_A2, _PtrT, __void_t<typename _A2::difference_type>>
{ using type = typename _A2::difference_type; };
// Select _A2::size_type or make_unsigned<_DiffT>::type
template<typename _A2, typename _DiffT, typename = void>
struct _Size : make_unsigned<_DiffT> { };
template<typename _A2, typename _DiffT>
struct _Size<_A2, _DiffT, __void_t<typename _A2::size_type>>
{ using type = typename _A2::size_type; };
public:
/**
* @brief The allocator's const pointer type.
*
* @c Alloc::const_pointer if that type exists, otherwise
* <tt> pointer_traits<pointer>::rebind<const value_type> </tt>
*/
using const_pointer = typename _Ptr<__c_pointer, const value_type>::type;
/**
* @brief The allocator's void pointer type.
*
* @c Alloc::void_pointer if that type exists, otherwise
* <tt> pointer_traits<pointer>::rebind<void> </tt>
*/
using void_pointer = typename _Ptr<__v_pointer, void>::type;
/**
* @brief The allocator's const void pointer type.
*
* @c Alloc::const_void_pointer if that type exists, otherwise
* <tt> pointer_traits<pointer>::rebind<const void> </tt>
*/
using const_void_pointer = typename _Ptr<__cv_pointer, const void>::type;
/**
* @brief The allocator's difference type
*
* @c Alloc::difference_type if that type exists, otherwise
* <tt> pointer_traits<pointer>::difference_type </tt>
*/
using difference_type = typename _Diff<_Alloc, pointer>::type;
/**
* @brief The allocator's size type
*
* @c Alloc::size_type if that type exists, otherwise
* <tt> make_unsigned<difference_type>::type </tt>
*/
using size_type = typename _Size<_Alloc, difference_type>::type;
/**
* @brief How the allocator is propagated on copy assignment
*
* @c Alloc::propagate_on_container_copy_assignment if that type exists,
* otherwise @c false_type
*/
using propagate_on_container_copy_assignment
= __detected_or_t<false_type, __pocca, _Alloc>;
/**
* @brief How the allocator is propagated on move assignment
*
* @c Alloc::propagate_on_container_move_assignment if that type exists,
* otherwise @c false_type
*/
using propagate_on_container_move_assignment
= __detected_or_t<false_type, __pocma, _Alloc>;
/**
* @brief How the allocator is propagated on swap
*
* @c Alloc::propagate_on_container_swap if that type exists,
* otherwise @c false_type
*/
using propagate_on_container_swap
= __detected_or_t<false_type, __pocs, _Alloc>;
/**
* @brief Whether all instances of the allocator type compare equal.
*
* @c Alloc::is_always_equal if that type exists,
* otherwise @c is_empty<Alloc>::type
*/
using is_always_equal
= typename __detected_or_t<is_empty<_Alloc>, __equal, _Alloc>::type;
template<typename _Tp>
using rebind_alloc = __alloc_rebind<_Alloc, _Tp>;
template<typename _Tp>
using rebind_traits = allocator_traits<rebind_alloc<_Tp>>;
private:
template<typename _Alloc2>
static constexpr auto
_S_allocate(_Alloc2& __a, size_type __n, const_void_pointer __hint, int)
-> decltype(__a.allocate(__n, __hint))
{ return __a.allocate(__n, __hint); }
template<typename _Alloc2>
static constexpr pointer
_S_allocate(_Alloc2& __a, size_type __n, const_void_pointer, ...)
{ return __a.allocate(__n); }
template<typename _Tp, typename... _Args>
struct __construct_helper
{
template<typename _Alloc2,
typename = decltype(std::declval<_Alloc2*>()->construct(
std::declval<_Tp*>(), std::declval<_Args>()...))>
static true_type __test(int);
template<typename>
static false_type __test(...);
using type = decltype(__test<_Alloc>(0));
};
template<typename _Tp, typename... _Args>
using __has_construct
= typename __construct_helper<_Tp, _Args...>::type;
template<typename _Tp, typename... _Args>
static _GLIBCXX14_CONSTEXPR _Require<__has_construct<_Tp, _Args...>>
_S_construct(_Alloc& __a, _Tp* __p, _Args&&... __args)
noexcept(noexcept(__a.construct(__p, std::forward<_Args>(__args)...)))
{ __a.construct(__p, std::forward<_Args>(__args)...); }
template<typename _Tp, typename... _Args>
static _GLIBCXX14_CONSTEXPR
_Require<__and_<__not_<__has_construct<_Tp, _Args...>>,
is_constructible<_Tp, _Args...>>>
_S_construct(_Alloc&, _Tp* __p, _Args&&... __args)
noexcept(std::is_nothrow_constructible<_Tp, _Args...>::value)
{
#if __cplusplus <= 201703L
::new((void*)__p) _Tp(std::forward<_Args>(__args)...);
#else
std::construct_at(__p, std::forward<_Args>(__args)...);
#endif
}
template<typename _Alloc2, typename _Tp>
static _GLIBCXX14_CONSTEXPR auto
_S_destroy(_Alloc2& __a, _Tp* __p, int)
noexcept(noexcept(__a.destroy(__p)))
-> decltype(__a.destroy(__p))
{ __a.destroy(__p); }
template<typename _Alloc2, typename _Tp>
static _GLIBCXX14_CONSTEXPR void
_S_destroy(_Alloc2&, _Tp* __p, ...)
noexcept(std::is_nothrow_destructible<_Tp>::value)
{ std::_Destroy(__p); }
template<typename _Alloc2>
static constexpr auto
_S_max_size(_Alloc2& __a, int)
-> decltype(__a.max_size())
{ return __a.max_size(); }
template<typename _Alloc2>
static constexpr size_type
_S_max_size(_Alloc2&, ...)
{
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 2466. allocator_traits::max_size() default behavior is incorrect
return __gnu_cxx::__numeric_traits<size_type>::__max
/ sizeof(value_type);
}
template<typename _Alloc2>
static constexpr auto
_S_select(_Alloc2& __a, int)
-> decltype(__a.select_on_container_copy_construction())
{ return __a.select_on_container_copy_construction(); }
template<typename _Alloc2>
static constexpr _Alloc2
_S_select(_Alloc2& __a, ...)
{ return __a; }
public:
/**
* @brief Allocate memory.
* @param __a An allocator.
* @param __n The number of objects to allocate space for.
*
* Calls @c a.allocate(n)
*/
_GLIBCXX_NODISCARD static _GLIBCXX20_CONSTEXPR pointer
allocate(_Alloc& __a, size_type __n)
{ return __a.allocate(__n); }
/**
* @brief Allocate memory.
* @param __a An allocator.
* @param __n The number of objects to allocate space for.
* @param __hint Aid to locality.
* @return Memory of suitable size and alignment for @a n objects
* of type @c value_type
*
* Returns <tt> a.allocate(n, hint) </tt> if that expression is
* well-formed, otherwise returns @c a.allocate(n)
*/
_GLIBCXX_NODISCARD static _GLIBCXX20_CONSTEXPR pointer
allocate(_Alloc& __a, size_type __n, const_void_pointer __hint)
{ return _S_allocate(__a, __n, __hint, 0); }
/**
* @brief Deallocate memory.
* @param __a An allocator.
* @param __p Pointer to the memory to deallocate.
* @param __n The number of objects space was allocated for.
*
* Calls <tt> a.deallocate(p, n) </tt>
*/
static _GLIBCXX20_CONSTEXPR void
deallocate(_Alloc& __a, pointer __p, size_type __n)
{ __a.deallocate(__p, __n); }
/**
* @brief Construct an object of type `_Tp`
* @param __a An allocator.
* @param __p Pointer to memory of suitable size and alignment for Tp
* @param __args Constructor arguments.
*
* Calls <tt> __a.construct(__p, std::forward<Args>(__args)...) </tt>
* if that expression is well-formed, otherwise uses placement-new
* to construct an object of type @a _Tp at location @a __p from the
* arguments @a __args...
*/
template<typename _Tp, typename... _Args>
static _GLIBCXX20_CONSTEXPR auto
construct(_Alloc& __a, _Tp* __p, _Args&&... __args)
noexcept(noexcept(_S_construct(__a, __p,
std::forward<_Args>(__args)...)))
-> decltype(_S_construct(__a, __p, std::forward<_Args>(__args)...))
{ _S_construct(__a, __p, std::forward<_Args>(__args)...); }
/**
* @brief Destroy an object of type @a _Tp
* @param __a An allocator.
* @param __p Pointer to the object to destroy
*
* Calls @c __a.destroy(__p) if that expression is well-formed,
* otherwise calls @c __p->~_Tp()
*/
template<typename _Tp>
static _GLIBCXX20_CONSTEXPR void
destroy(_Alloc& __a, _Tp* __p)
noexcept(noexcept(_S_destroy(__a, __p, 0)))
{ _S_destroy(__a, __p, 0); }
/**
* @brief The maximum supported allocation size
* @param __a An allocator.
* @return @c __a.max_size() or @c numeric_limits<size_type>::max()
*
* Returns @c __a.max_size() if that expression is well-formed,
* otherwise returns @c numeric_limits<size_type>::max()
*/
static _GLIBCXX20_CONSTEXPR size_type
max_size(const _Alloc& __a) noexcept
{ return _S_max_size(__a, 0); }
/**
* @brief Obtain an allocator to use when copying a container.
* @param __rhs An allocator.
* @return @c __rhs.select_on_container_copy_construction() or @a __rhs
*
* Returns @c __rhs.select_on_container_copy_construction() if that
* expression is well-formed, otherwise returns @a __rhs
*/
static _GLIBCXX20_CONSTEXPR _Alloc
select_on_container_copy_construction(const _Alloc& __rhs)
{ return _S_select(__rhs, 0); }
};
#if _GLIBCXX_HOSTED
/// Partial specialization for std::allocator.
template<typename _Tp>
struct allocator_traits<allocator<_Tp>>
{
/// The allocator type
using allocator_type = allocator<_Tp>;
/// The allocated type
using value_type = _Tp;
/// The allocator's pointer type.
using pointer = _Tp*;
/// The allocator's const pointer type.
using const_pointer = const _Tp*;
/// The allocator's void pointer type.
using void_pointer = void*;
/// The allocator's const void pointer type.
using const_void_pointer = const void*;
/// The allocator's difference type
using difference_type = std::ptrdiff_t;
/// The allocator's size type
using size_type = std::size_t;
/// How the allocator is propagated on copy assignment
using propagate_on_container_copy_assignment = false_type;
/// How the allocator is propagated on move assignment
using propagate_on_container_move_assignment = true_type;
/// How the allocator is propagated on swap
using propagate_on_container_swap = false_type;
/// Whether all instances of the allocator type compare equal.
using is_always_equal = true_type;
template<typename _Up>
using rebind_alloc = allocator<_Up>;
template<typename _Up>
using rebind_traits = allocator_traits<allocator<_Up>>;
/**
* @brief Allocate memory.
* @param __a An allocator.
* @param __n The number of objects to allocate space for.
*
* Calls @c a.allocate(n)
*/
[[__nodiscard__,__gnu__::__always_inline__]]
static _GLIBCXX20_CONSTEXPR pointer
allocate(allocator_type& __a, size_type __n)
{ return __a.allocate(__n); }
/**
* @brief Allocate memory.
* @param __a An allocator.
* @param __n The number of objects to allocate space for.
* @param __hint Aid to locality.
* @return Memory of suitable size and alignment for @a n objects
* of type @c value_type
*
* Returns <tt> a.allocate(n, hint) </tt>
*/
[[__nodiscard__,__gnu__::__always_inline__]]
static _GLIBCXX20_CONSTEXPR pointer
allocate(allocator_type& __a, size_type __n,
[[maybe_unused]] const_void_pointer __hint)
{
#if __cplusplus <= 201703L
return __a.allocate(__n, __hint);
#else
return __a.allocate(__n);
#endif
}
/**
* @brief Deallocate memory.
* @param __a An allocator.
* @param __p Pointer to the memory to deallocate.
* @param __n The number of objects space was allocated for.
*
* Calls <tt> a.deallocate(p, n) </tt>
*/
[[__gnu__::__always_inline__]]
static _GLIBCXX20_CONSTEXPR void
deallocate(allocator_type& __a, pointer __p, size_type __n)
{ __a.deallocate(__p, __n); }
/**
* @brief Construct an object of type `_Up`
* @param __a An allocator.
* @param __p Pointer to memory of suitable size and alignment for
* an object of type `_Up`.
* @param __args Constructor arguments.
*
* Calls `__a.construct(__p, std::forward<_Args>(__args)...)`
* in C++11, C++14 and C++17. Changed in C++20 to call
* `std::construct_at(__p, std::forward<_Args>(__args)...)` instead.
*/
template<typename _Up, typename... _Args>
[[__gnu__::__always_inline__]]
static _GLIBCXX20_CONSTEXPR void
construct(allocator_type& __a __attribute__((__unused__)), _Up* __p,
_Args&&... __args)
noexcept(std::is_nothrow_constructible<_Up, _Args...>::value)
{
#if __cplusplus <= 201703L
__a.construct(__p, std::forward<_Args>(__args)...);
#else
std::construct_at(__p, std::forward<_Args>(__args)...);
#endif
}
/**
* @brief Destroy an object of type @a _Up
* @param __a An allocator.
* @param __p Pointer to the object to destroy
*
* Calls @c __a.destroy(__p).
*/
template<typename _Up>
[[__gnu__::__always_inline__]]
static _GLIBCXX20_CONSTEXPR void
destroy(allocator_type& __a __attribute__((__unused__)), _Up* __p)
noexcept(is_nothrow_destructible<_Up>::value)
{
#if __cplusplus <= 201703L
__a.destroy(__p);
#else
std::destroy_at(__p);
#endif
}
/**
* @brief The maximum supported allocation size
* @param __a An allocator.
* @return @c __a.max_size()
*/
[[__gnu__::__always_inline__]]
static _GLIBCXX20_CONSTEXPR size_type
max_size(const allocator_type& __a __attribute__((__unused__))) noexcept
{
#if __cplusplus <= 201703L
return __a.max_size();
#else
return size_t(-1) / sizeof(value_type);
#endif
}
/**
* @brief Obtain an allocator to use when copying a container.
* @param __rhs An allocator.
* @return @c __rhs
*/
[[__gnu__::__always_inline__]]
static _GLIBCXX20_CONSTEXPR allocator_type
select_on_container_copy_construction(const allocator_type& __rhs)
{ return __rhs; }
};
/// Explicit specialization for std::allocator<void>.
template<>
struct allocator_traits<allocator<void>>
{
/// The allocator type
using allocator_type = allocator<void>;
/// The allocated type
using value_type = void;
/// The allocator's pointer type.
using pointer = void*;
/// The allocator's const pointer type.
using const_pointer = const void*;
/// The allocator's void pointer type.
using void_pointer = void*;
/// The allocator's const void pointer type.
using const_void_pointer = const void*;
/// The allocator's difference type
using difference_type = std::ptrdiff_t;
/// The allocator's size type
using size_type = std::size_t;
/// How the allocator is propagated on copy assignment
using propagate_on_container_copy_assignment = false_type;
/// How the allocator is propagated on move assignment
using propagate_on_container_move_assignment = true_type;
/// How the allocator is propagated on swap
using propagate_on_container_swap = false_type;
/// Whether all instances of the allocator type compare equal.
using is_always_equal = true_type;
template<typename _Up>
using rebind_alloc = allocator<_Up>;
template<typename _Up>
using rebind_traits = allocator_traits<allocator<_Up>>;
/// allocate is ill-formed for allocator<void>
static void*
allocate(allocator_type&, size_type, const void* = nullptr) = delete;
/// deallocate is ill-formed for allocator<void>
static void
deallocate(allocator_type&, void*, size_type) = delete;
/**
* @brief Construct an object of type `_Up`
* @param __a An allocator.
* @param __p Pointer to memory of suitable size and alignment for
* an object of type `_Up`.
* @param __args Constructor arguments.
*
* Calls `__a.construct(__p, std::forward<_Args>(__args)...)`
* in C++11, C++14 and C++17. Changed in C++20 to call
* `std::construct_at(__p, std::forward<_Args>(__args)...)` instead.
*/
template<typename _Up, typename... _Args>
[[__gnu__::__always_inline__]]
static _GLIBCXX20_CONSTEXPR void
construct(allocator_type&, _Up* __p, _Args&&... __args)
noexcept(std::is_nothrow_constructible<_Up, _Args...>::value)
{ std::_Construct(__p, std::forward<_Args>(__args)...); }
/**
* @brief Destroy an object of type `_Up`
* @param __a An allocator.
* @param __p Pointer to the object to destroy
*
* Invokes the destructor for `*__p`.
*/
template<typename _Up>
[[__gnu__::__always_inline__]]
static _GLIBCXX20_CONSTEXPR void
destroy(allocator_type&, _Up* __p)
noexcept(is_nothrow_destructible<_Up>::value)
{ std::_Destroy(__p); }
/// max_size is ill-formed for allocator<void>
static size_type
max_size(const allocator_type&) = delete;
/**
* @brief Obtain an allocator to use when copying a container.
* @param __rhs An allocator.
* @return `__rhs`
*/
[[__gnu__::__always_inline__]]
static _GLIBCXX20_CONSTEXPR allocator_type
select_on_container_copy_construction(const allocator_type& __rhs)
{ return __rhs; }
};
#endif
/// @cond undocumented
#if __cplusplus < 201703L
template<typename _Alloc>
[[__gnu__::__always_inline__]]
inline void
__do_alloc_on_copy(_Alloc& __one, const _Alloc& __two, true_type)
{ __one = __two; }
template<typename _Alloc>
[[__gnu__::__always_inline__]]
inline void
__do_alloc_on_copy(_Alloc&, const _Alloc&, false_type)
{ }
#endif
template<typename _Alloc>
[[__gnu__::__always_inline__]]
_GLIBCXX14_CONSTEXPR inline void
__alloc_on_copy(_Alloc& __one, const _Alloc& __two)
{
using __traits = allocator_traits<_Alloc>;
using __pocca =
typename __traits::propagate_on_container_copy_assignment::type;
#if __cplusplus >= 201703L
if constexpr (__pocca::value)
__one = __two;
#else
__do_alloc_on_copy(__one, __two, __pocca());
#endif
}
template<typename _Alloc>
[[__gnu__::__always_inline__]]
constexpr _Alloc
__alloc_on_copy(const _Alloc& __a)
{
typedef allocator_traits<_Alloc> __traits;
return __traits::select_on_container_copy_construction(__a);
}
#if __cplusplus < 201703L
template<typename _Alloc>
[[__gnu__::__always_inline__]]
inline void __do_alloc_on_move(_Alloc& __one, _Alloc& __two, true_type)
{ __one = std::move(__two); }
template<typename _Alloc>
[[__gnu__::__always_inline__]]
inline void __do_alloc_on_move(_Alloc&, _Alloc&, false_type)
{ }
#endif
template<typename _Alloc>
[[__gnu__::__always_inline__]]
_GLIBCXX14_CONSTEXPR inline void
__alloc_on_move(_Alloc& __one, _Alloc& __two)
{
using __traits = allocator_traits<_Alloc>;
using __pocma
= typename __traits::propagate_on_container_move_assignment::type;
#if __cplusplus >= 201703L
if constexpr (__pocma::value)
__one = std::move(__two);
#else
__do_alloc_on_move(__one, __two, __pocma());
#endif
}
#if __cplusplus < 201703L
template<typename _Alloc>
[[__gnu__::__always_inline__]]
inline void __do_alloc_on_swap(_Alloc& __one, _Alloc& __two, true_type)
{
using std::swap;
swap(__one, __two);
}
template<typename _Alloc>
[[__gnu__::__always_inline__]]
inline void __do_alloc_on_swap(_Alloc&, _Alloc&, false_type)
{ }
#endif
template<typename _Alloc>
[[__gnu__::__always_inline__]]
_GLIBCXX14_CONSTEXPR inline void
__alloc_on_swap(_Alloc& __one, _Alloc& __two)
{
using __traits = allocator_traits<_Alloc>;
using __pocs = typename __traits::propagate_on_container_swap::type;
#if __cplusplus >= 201703L
if constexpr (__pocs::value)
{
using std::swap;
swap(__one, __two);
}
#else
__do_alloc_on_swap(__one, __two, __pocs());
#endif
}
template<typename _Alloc, typename _Tp,
typename _ValueT = __remove_cvref_t<typename _Alloc::value_type>,
typename = void>
struct __is_alloc_insertable_impl
: false_type
{ };
template<typename _Alloc, typename _Tp, typename _ValueT>
struct __is_alloc_insertable_impl<_Alloc, _Tp, _ValueT,
__void_t<decltype(allocator_traits<_Alloc>::construct(
std::declval<_Alloc&>(), std::declval<_ValueT*>(),
std::declval<_Tp>()))>>
: true_type
{ };
// true if _Alloc::value_type is CopyInsertable into containers using _Alloc
// (might be wrong if _Alloc::construct exists but is not constrained,
// i.e. actually trying to use it would still be invalid. Use with caution.)
template<typename _Alloc>
struct __is_copy_insertable
: __is_alloc_insertable_impl<_Alloc,
typename _Alloc::value_type const&>::type
{ };
#if _GLIBCXX_HOSTED
// std::allocator<_Tp> just requires CopyConstructible
template<typename _Tp>
struct __is_copy_insertable<allocator<_Tp>>
: is_copy_constructible<_Tp>
{ };
#endif
// true if _Alloc::value_type is MoveInsertable into containers using _Alloc
// (might be wrong if _Alloc::construct exists but is not constrained,
// i.e. actually trying to use it would still be invalid. Use with caution.)
template<typename _Alloc>
struct __is_move_insertable
: __is_alloc_insertable_impl<_Alloc, typename _Alloc::value_type>::type
{ };
#if _GLIBCXX_HOSTED
// std::allocator<_Tp> just requires MoveConstructible
template<typename _Tp>
struct __is_move_insertable<allocator<_Tp>>
: is_move_constructible<_Tp>
{ };
#endif
// Trait to detect Allocator-like types.
template<typename _Alloc, typename = void>
struct __is_allocator : false_type { };
template<typename _Alloc>
struct __is_allocator<_Alloc,
__void_t<typename _Alloc::value_type,
decltype(std::declval<_Alloc&>().allocate(size_t{}))>>
: true_type { };
template<typename _Alloc>
using _RequireAllocator
= typename enable_if<__is_allocator<_Alloc>::value, _Alloc>::type;
template<typename _Alloc>
using _RequireNotAllocator
= typename enable_if<!__is_allocator<_Alloc>::value, _Alloc>::type;
#if __cpp_concepts >= 201907L
template<typename _Alloc>
concept __allocator_like = requires (_Alloc& __a) {
typename _Alloc::value_type;
__a.deallocate(__a.allocate(1u), 1u);
};
#endif
/// @endcond
#endif // C++11
/// @cond undocumented
// To implement Option 3 of DR 431.
template<typename _Alloc, bool = __is_empty(_Alloc)>
struct __alloc_swap
{ static void _S_do_it(_Alloc&, _Alloc&) _GLIBCXX_NOEXCEPT { } };
template<typename _Alloc>
struct __alloc_swap<_Alloc, false>
{
static void
_S_do_it(_Alloc& __one, _Alloc& __two) _GLIBCXX_NOEXCEPT
{
// Precondition: swappable allocators.
if (__one != __two)
swap(__one, __two);
}
};
#if __cplusplus >= 201103L
template<typename _Tp, bool
= __or_<is_copy_constructible<typename _Tp::value_type>,
is_nothrow_move_constructible<typename _Tp::value_type>>::value>
struct __shrink_to_fit_aux
{ static bool _S_do_it(_Tp&) noexcept { return false; } };
template<typename _Tp>
struct __shrink_to_fit_aux<_Tp, true>
{
_GLIBCXX20_CONSTEXPR
static bool
_S_do_it(_Tp& __c) noexcept
{
#if __cpp_exceptions
try
{
_Tp(__make_move_if_noexcept_iterator(__c.begin()),
__make_move_if_noexcept_iterator(__c.end()),
__c.get_allocator()).swap(__c);
return true;
}
catch(...)
{ return false; }
#else
return false;
#endif
}
};
#endif
/**
* Destroy a range of objects using the supplied allocator. For
* non-default allocators we do not optimize away invocation of
* destroy() even if _Tp has a trivial destructor.
*/
template<typename _ForwardIterator, typename _Allocator>
_GLIBCXX20_CONSTEXPR
void
_Destroy(_ForwardIterator __first, _ForwardIterator __last,
_Allocator& __alloc)
{
for (; __first != __last; ++__first)
#if __cplusplus < 201103L
__alloc.destroy(std::__addressof(*__first));
#else
allocator_traits<_Allocator>::destroy(__alloc,
std::__addressof(*__first));
#endif
}
#if _GLIBCXX_HOSTED
template<typename _ForwardIterator, typename _Tp>
__attribute__((__always_inline__)) _GLIBCXX20_CONSTEXPR
inline void
_Destroy(_ForwardIterator __first, _ForwardIterator __last,
allocator<_Tp>&)
{
std::_Destroy(__first, __last);
}
#endif
/// @endcond
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif // _ALLOC_TRAITS_H
+295
View File
@@ -0,0 +1,295 @@
// Allocators -*- C++ -*-
// Copyright (C) 2001-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/*
* Copyright (c) 1996-1997
* Silicon Graphics Computer Systems, Inc.
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Silicon Graphics makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*/
/** @file bits/allocator.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{memory}
*/
#ifndef _ALLOCATOR_H
#define _ALLOCATOR_H 1
#include <bits/c++allocator.h> // Define the base class to std::allocator.
#include <bits/memoryfwd.h>
#if __cplusplus >= 201103L
#include <type_traits>
#endif
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
* @addtogroup allocators
* @{
*/
// Since C++20 the primary template should be used for allocator<void>,
// but then it would have a non-trivial default ctor and dtor for C++20,
// but trivial for C++98-17, which would be an ABI incompatibility between
// different standard dialects. So C++20 still uses the allocator<void>
// explicit specialization, with the historical ABI properties, but with
// the same members that are present in the primary template.
/** std::allocator<void> specialization.
*
* @headerfile memory
*/
template<>
class allocator<void>
{
public:
typedef void value_type;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
#if __cplusplus <= 201703L
// These were removed for C++20, allocator_traits does the right thing.
typedef void* pointer;
typedef const void* const_pointer;
template<typename _Tp1>
struct rebind
{ typedef allocator<_Tp1> other; };
#endif
#if __cplusplus >= 201103L
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 2103. std::allocator propagate_on_container_move_assignment
using propagate_on_container_move_assignment = true_type;
using is_always_equal
_GLIBCXX20_DEPRECATED_SUGGEST("std::allocator_traits::is_always_equal")
= true_type;
#if __cplusplus >= 202002L
// As noted above, these members are present for C++20 to provide the
// same API as the primary template, but still trivial as in pre-C++20.
allocator() = default;
~allocator() = default;
template<typename _Up>
__attribute__((__always_inline__))
constexpr
allocator(const allocator<_Up>&) noexcept { }
// No allocate member because it's ill-formed by LWG 3307.
// No deallocate member because it would be undefined to call it
// with any pointer which wasn't obtained from allocate.
#endif // C++20
#endif // C++11
};
/**
* @brief The @a standard allocator, as per C++03 [20.4.1].
*
* See https://gcc.gnu.org/onlinedocs/libstdc++/manual/memory.html#std.util.memory.allocator
* for further details.
*
* @tparam _Tp Type of allocated object.
*
* @headerfile memory
*/
template<typename _Tp>
class allocator : public __allocator_base<_Tp>
{
public:
typedef _Tp value_type;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
#if __cplusplus <= 201703L
// These were removed for C++20.
typedef _Tp* pointer;
typedef const _Tp* const_pointer;
typedef _Tp& reference;
typedef const _Tp& const_reference;
template<typename _Tp1>
struct rebind
{ typedef allocator<_Tp1> other; };
#endif
#if __cplusplus >= 201103L
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 2103. std::allocator propagate_on_container_move_assignment
using propagate_on_container_move_assignment = true_type;
using is_always_equal
_GLIBCXX20_DEPRECATED_SUGGEST("std::allocator_traits::is_always_equal")
= true_type;
#endif
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 3035. std::allocator's constructors should be constexpr
__attribute__((__always_inline__))
_GLIBCXX20_CONSTEXPR
allocator() _GLIBCXX_NOTHROW { }
__attribute__((__always_inline__))
_GLIBCXX20_CONSTEXPR
allocator(const allocator& __a) _GLIBCXX_NOTHROW
: __allocator_base<_Tp>(__a) { }
#if __cplusplus >= 201103L
// Avoid implicit deprecation.
allocator& operator=(const allocator&) = default;
#endif
template<typename _Tp1>
__attribute__((__always_inline__))
_GLIBCXX20_CONSTEXPR
allocator(const allocator<_Tp1>&) _GLIBCXX_NOTHROW { }
__attribute__((__always_inline__))
#if __cpp_constexpr_dynamic_alloc
constexpr
#endif
~allocator() _GLIBCXX_NOTHROW { }
#if __cplusplus > 201703L
[[nodiscard,__gnu__::__always_inline__]]
constexpr _Tp*
allocate(size_t __n)
{
if (std::__is_constant_evaluated())
{
if (__builtin_mul_overflow(__n, sizeof(_Tp), &__n))
std::__throw_bad_array_new_length();
return static_cast<_Tp*>(::operator new(__n));
}
return __allocator_base<_Tp>::allocate(__n, 0);
}
[[__gnu__::__always_inline__]]
constexpr void
deallocate(_Tp* __p, size_t __n)
{
if (std::__is_constant_evaluated())
{
::operator delete(__p);
return;
}
__allocator_base<_Tp>::deallocate(__p, __n);
}
#endif // C++20
friend __attribute__((__always_inline__)) _GLIBCXX20_CONSTEXPR
bool
operator==(const allocator&, const allocator&) _GLIBCXX_NOTHROW
{ return true; }
#if __cpp_impl_three_way_comparison < 201907L
friend __attribute__((__always_inline__)) _GLIBCXX20_CONSTEXPR
bool
operator!=(const allocator&, const allocator&) _GLIBCXX_NOTHROW
{ return false; }
#endif
// Inherit everything else.
};
/** Equality comparison for std::allocator objects
*
* @return true, for all std::allocator objects.
* @relates std::allocator
*/
template<typename _T1, typename _T2>
__attribute__((__always_inline__))
inline _GLIBCXX20_CONSTEXPR bool
operator==(const allocator<_T1>&, const allocator<_T2>&)
_GLIBCXX_NOTHROW
{ return true; }
#if __cpp_impl_three_way_comparison < 201907L
template<typename _T1, typename _T2>
__attribute__((__always_inline__))
inline _GLIBCXX20_CONSTEXPR bool
operator!=(const allocator<_T1>&, const allocator<_T2>&)
_GLIBCXX_NOTHROW
{ return false; }
#endif
/// @cond undocumented
// Invalid allocator<cv T> partial specializations.
// allocator_traits::rebind_alloc can be used to form a valid allocator type.
template<typename _Tp>
class allocator<const _Tp>
{
public:
typedef _Tp value_type;
allocator() { }
template<typename _Up> allocator(const allocator<_Up>&) { }
};
template<typename _Tp>
class allocator<volatile _Tp>
{
public:
typedef _Tp value_type;
allocator() { }
template<typename _Up> allocator(const allocator<_Up>&) { }
};
template<typename _Tp>
class allocator<const volatile _Tp>
{
public:
typedef _Tp value_type;
allocator() { }
template<typename _Up> allocator(const allocator<_Up>&) { }
};
/// @endcond
/// @} group allocator
// Inhibit implicit instantiations for required instantiations,
// which are defined via explicit instantiations elsewhere.
#if _GLIBCXX_EXTERN_TEMPLATE
extern template class allocator<char>;
extern template class allocator<wchar_t>;
#endif
// Undefine.
#undef __allocator_base
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,66 @@
// -*- C++ -*- header.
// Copyright (C) 2008-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/atomic_lockfree_defines.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{atomic}
*/
#ifndef _GLIBCXX_ATOMIC_LOCK_FREE_H
#define _GLIBCXX_ATOMIC_LOCK_FREE_H 1
#pragma GCC system_header
/**
* @addtogroup atomics
* @{
*/
/**
* Lock-free property.
*
* 0 indicates that the types are never lock-free.
* 1 indicates that the types are sometimes lock-free.
* 2 indicates that the types are always lock-free.
*/
#if __cplusplus >= 201103L
#define ATOMIC_BOOL_LOCK_FREE __GCC_ATOMIC_BOOL_LOCK_FREE
#define ATOMIC_CHAR_LOCK_FREE __GCC_ATOMIC_CHAR_LOCK_FREE
#define ATOMIC_WCHAR_T_LOCK_FREE __GCC_ATOMIC_WCHAR_T_LOCK_FREE
#ifdef _GLIBCXX_USE_CHAR8_T
#define ATOMIC_CHAR8_T_LOCK_FREE __GCC_ATOMIC_CHAR8_T_LOCK_FREE
#endif
#define ATOMIC_CHAR16_T_LOCK_FREE __GCC_ATOMIC_CHAR16_T_LOCK_FREE
#define ATOMIC_CHAR32_T_LOCK_FREE __GCC_ATOMIC_CHAR32_T_LOCK_FREE
#define ATOMIC_SHORT_LOCK_FREE __GCC_ATOMIC_SHORT_LOCK_FREE
#define ATOMIC_INT_LOCK_FREE __GCC_ATOMIC_INT_LOCK_FREE
#define ATOMIC_LONG_LOCK_FREE __GCC_ATOMIC_LONG_LOCK_FREE
#define ATOMIC_LLONG_LOCK_FREE __GCC_ATOMIC_LLONG_LOCK_FREE
#define ATOMIC_POINTER_LOCK_FREE __GCC_ATOMIC_POINTER_LOCK_FREE
#endif
/// @} group atomics
#endif
@@ -0,0 +1,40 @@
// Low-level type for atomic operations -*- C++ -*-
// Copyright (C) 2004-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file atomic_word.h
* This file is a GNU extension to the Standard C++ Library.
*/
#ifndef _GLIBCXX_ATOMIC_WORD_H
#define _GLIBCXX_ATOMIC_WORD_H 1
typedef int _Atomic_word;
// This is a memory order acquire fence.
#define _GLIBCXX_READ_MEM_BARRIER __atomic_thread_fence (__ATOMIC_ACQUIRE)
// This is a memory order release fence.
#define _GLIBCXX_WRITE_MEM_BARRIER __atomic_thread_fence (__ATOMIC_RELEASE)
#endif
+148
View File
@@ -0,0 +1,148 @@
// Wrapper of C-language FILE struct -*- C++ -*-
// Copyright (C) 2000-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
//
// ISO C++ 14882: 27.8 File-based streams
//
/** @file bits/basic_file.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{ios}
*/
#ifndef _GLIBCXX_BASIC_FILE_STDIO_H
#define _GLIBCXX_BASIC_FILE_STDIO_H 1
#pragma GCC system_header
#include <bits/c++config.h>
#include <bits/c++io.h> // for __c_lock and __c_file
#include <bits/move.h> // for swap
#include <ios>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
// Generic declaration.
template<typename _CharT>
class __basic_file;
// Specialization.
template<>
class __basic_file<char>
{
// Underlying data source/sink.
__c_file* _M_cfile;
// True iff we opened _M_cfile, and thus must close it ourselves.
bool _M_cfile_created;
public:
__basic_file(__c_lock* __lock = 0) throw ();
#if __cplusplus >= 201103L
__basic_file(__basic_file&& __rv, __c_lock* = 0) noexcept
: _M_cfile(__rv._M_cfile), _M_cfile_created(__rv._M_cfile_created)
{
__rv._M_cfile = nullptr;
__rv._M_cfile_created = false;
}
__basic_file& operator=(const __basic_file&) = delete;
__basic_file& operator=(__basic_file&&) = delete;
void
swap(__basic_file& __f) noexcept
{
std::swap(_M_cfile, __f._M_cfile);
std::swap(_M_cfile_created, __f._M_cfile_created);
}
#endif
__basic_file*
open(const char* __name, ios_base::openmode __mode, int __prot = 0664);
#if _GLIBCXX_HAVE__WFOPEN && _GLIBCXX_USE_WCHAR_T
__basic_file*
open(const wchar_t* __name, ios_base::openmode __mode);
#endif
__basic_file*
sys_open(__c_file* __file, ios_base::openmode);
__basic_file*
sys_open(int __fd, ios_base::openmode __mode) throw ();
__basic_file*
close();
_GLIBCXX_PURE bool
is_open() const throw ();
_GLIBCXX_PURE int
fd() throw ();
_GLIBCXX_PURE __c_file*
file() throw ();
~__basic_file();
streamsize
xsputn(const char* __s, streamsize __n);
streamsize
xsputn_2(const char* __s1, streamsize __n1,
const char* __s2, streamsize __n2);
streamsize
xsgetn(char* __s, streamsize __n);
streamoff
seekoff(streamoff __off, ios_base::seekdir __way) throw ();
int
sync();
streamsize
showmanyc();
#if __cplusplus >= 201103L
#ifdef _GLIBCXX_USE_STDIO_PURE
using native_handle_type = __c_file*; // FILE*
#elif _GLIBCXX_USE__GET_OSFHANDLE
using native_handle_type = void*; // HANDLE
#else
using native_handle_type = int; // POSIX file descriptor
#endif
native_handle_type
native_handle() const noexcept;
#endif
};
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif
@@ -0,0 +1,883 @@
// -*- C++ -*-
// Copyright (C) 2004-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
// (C) Copyright Jeremy Siek 2000. Permission to copy, use, modify,
// sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
//
/** @file bits/boost_concept_check.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{iterator}
*/
// GCC Note: based on version 1.12.0 of the Boost library.
#ifndef _BOOST_CONCEPT_CHECK_H
#define _BOOST_CONCEPT_CHECK_H 1
#pragma GCC system_header
#include <bits/c++config.h>
#include <bits/stl_iterator_base_types.h> // for traits and tags
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
_GLIBCXX_BEGIN_NAMESPACE_CONTAINER
struct _Bit_iterator;
struct _Bit_const_iterator;
_GLIBCXX_END_NAMESPACE_CONTAINER
_GLIBCXX_END_NAMESPACE_VERSION
}
namespace __gnu_debug
{
template<typename _Iterator, typename _Sequence, typename _Category>
class _Safe_iterator;
}
namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
#define _IsUnused __attribute__ ((__unused__))
// When the C-C code is in use, we would like this function to do as little
// as possible at runtime, use as few resources as possible, and hopefully
// be elided out of existence... hmmm.
template <class _Concept>
_GLIBCXX14_CONSTEXPR inline void __function_requires()
{
void (_Concept::*__x)() _IsUnused = &_Concept::__constraints;
}
// No definition: if this is referenced, there's a problem with
// the instantiating type not being one of the required integer types.
// Unfortunately, this results in a link-time error, not a compile-time error.
void __error_type_must_be_an_integer_type();
void __error_type_must_be_an_unsigned_integer_type();
void __error_type_must_be_a_signed_integer_type();
// ??? Should the "concept_checking*" structs begin with more than _ ?
#define _GLIBCXX_CLASS_REQUIRES(_type_var, _ns, _concept) \
typedef void (_ns::_concept <_type_var>::* _func##_type_var##_concept)(); \
template <_func##_type_var##_concept _Tp1> \
struct _concept_checking##_type_var##_concept { }; \
typedef _concept_checking##_type_var##_concept< \
&_ns::_concept <_type_var>::__constraints> \
_concept_checking_typedef##_type_var##_concept
#define _GLIBCXX_CLASS_REQUIRES2(_type_var1, _type_var2, _ns, _concept) \
typedef void (_ns::_concept <_type_var1,_type_var2>::* _func##_type_var1##_type_var2##_concept)(); \
template <_func##_type_var1##_type_var2##_concept _Tp1> \
struct _concept_checking##_type_var1##_type_var2##_concept { }; \
typedef _concept_checking##_type_var1##_type_var2##_concept< \
&_ns::_concept <_type_var1,_type_var2>::__constraints> \
_concept_checking_typedef##_type_var1##_type_var2##_concept
#define _GLIBCXX_CLASS_REQUIRES3(_type_var1, _type_var2, _type_var3, _ns, _concept) \
typedef void (_ns::_concept <_type_var1,_type_var2,_type_var3>::* _func##_type_var1##_type_var2##_type_var3##_concept)(); \
template <_func##_type_var1##_type_var2##_type_var3##_concept _Tp1> \
struct _concept_checking##_type_var1##_type_var2##_type_var3##_concept { }; \
typedef _concept_checking##_type_var1##_type_var2##_type_var3##_concept< \
&_ns::_concept <_type_var1,_type_var2,_type_var3>::__constraints> \
_concept_checking_typedef##_type_var1##_type_var2##_type_var3##_concept
#define _GLIBCXX_CLASS_REQUIRES4(_type_var1, _type_var2, _type_var3, _type_var4, _ns, _concept) \
typedef void (_ns::_concept <_type_var1,_type_var2,_type_var3,_type_var4>::* _func##_type_var1##_type_var2##_type_var3##_type_var4##_concept)(); \
template <_func##_type_var1##_type_var2##_type_var3##_type_var4##_concept _Tp1> \
struct _concept_checking##_type_var1##_type_var2##_type_var3##_type_var4##_concept { }; \
typedef _concept_checking##_type_var1##_type_var2##_type_var3##_type_var4##_concept< \
&_ns::_concept <_type_var1,_type_var2,_type_var3,_type_var4>::__constraints> \
_concept_checking_typedef##_type_var1##_type_var2##_type_var3##_type_var4##_concept
template <class _Tp1, class _Tp2>
struct _Aux_require_same { };
template <class _Tp>
struct _Aux_require_same<_Tp,_Tp> { typedef _Tp _Type; };
template <class _Tp1, class _Tp2>
struct _SameTypeConcept
{
void __constraints() {
typedef typename _Aux_require_same<_Tp1, _Tp2>::_Type _Required;
}
};
template <class _Tp>
struct _IntegerConcept {
void __constraints() {
__error_type_must_be_an_integer_type();
}
};
template <> struct _IntegerConcept<short> { void __constraints() {} };
template <> struct _IntegerConcept<unsigned short> { void __constraints(){} };
template <> struct _IntegerConcept<int> { void __constraints() {} };
template <> struct _IntegerConcept<unsigned int> { void __constraints() {} };
template <> struct _IntegerConcept<long> { void __constraints() {} };
template <> struct _IntegerConcept<unsigned long> { void __constraints() {} };
template <> struct _IntegerConcept<long long> { void __constraints() {} };
template <> struct _IntegerConcept<unsigned long long>
{ void __constraints() {} };
template <class _Tp>
struct _SignedIntegerConcept {
void __constraints() {
__error_type_must_be_a_signed_integer_type();
}
};
template <> struct _SignedIntegerConcept<short> { void __constraints() {} };
template <> struct _SignedIntegerConcept<int> { void __constraints() {} };
template <> struct _SignedIntegerConcept<long> { void __constraints() {} };
template <> struct _SignedIntegerConcept<long long> { void __constraints(){}};
template <class _Tp>
struct _UnsignedIntegerConcept {
void __constraints() {
__error_type_must_be_an_unsigned_integer_type();
}
};
template <> struct _UnsignedIntegerConcept<unsigned short>
{ void __constraints() {} };
template <> struct _UnsignedIntegerConcept<unsigned int>
{ void __constraints() {} };
template <> struct _UnsignedIntegerConcept<unsigned long>
{ void __constraints() {} };
template <> struct _UnsignedIntegerConcept<unsigned long long>
{ void __constraints() {} };
//===========================================================================
// Basic Concepts
template <class _Tp>
struct _DefaultConstructibleConcept
{
void __constraints() {
_Tp __a _IsUnused; // require default constructor
}
};
template <class _Tp>
struct _AssignableConcept
{
void __constraints() {
__a = __a; // require assignment operator
__const_constraints(__a);
}
void __const_constraints(const _Tp& __b) {
__a = __b; // const required for argument to assignment
}
_Tp __a;
// possibly should be "Tp* a;" and then dereference "a" in constraint
// functions? present way would require a default ctor, i think...
};
template <class _Tp>
struct _CopyConstructibleConcept
{
void __constraints() {
_Tp __a(__b); // require copy constructor
_Tp* __ptr _IsUnused = &__a; // require address of operator
__const_constraints(__a);
}
void __const_constraints(const _Tp& __a) {
_Tp __c _IsUnused(__a); // require const copy constructor
const _Tp* __ptr _IsUnused = &__a; // require const address of operator
}
_Tp __b;
};
// The SGI STL version of Assignable requires copy constructor and operator=
template <class _Tp>
struct _SGIAssignableConcept
{
void __constraints() {
_Tp __b _IsUnused(__a);
__a = __a; // require assignment operator
__const_constraints(__a);
}
void __const_constraints(const _Tp& __b) {
_Tp __c _IsUnused(__b);
__a = __b; // const required for argument to assignment
}
_Tp __a;
};
template <class _From, class _To>
struct _ConvertibleConcept
{
void __constraints() {
_To __y _IsUnused = __x;
}
_From __x;
};
// The C++ standard requirements for many concepts talk about return
// types that must be "convertible to bool". The problem with this
// requirement is that it leaves the door open for evil proxies that
// define things like operator|| with strange return types. Two
// possible solutions are:
// 1) require the return type to be exactly bool
// 2) stay with convertible to bool, and also
// specify stuff about all the logical operators.
// For now we just test for convertible to bool.
template <class _Tp>
void __aux_require_boolean_expr(const _Tp& __t) {
bool __x _IsUnused = __t;
}
// FIXME
template <class _Tp>
struct _EqualityComparableConcept
{
void __constraints() {
__aux_require_boolean_expr(__a == __b);
}
_Tp __a, __b;
};
template <class _Tp>
struct _LessThanComparableConcept
{
void __constraints() {
__aux_require_boolean_expr(__a < __b);
}
_Tp __a, __b;
};
// This is equivalent to SGI STL's LessThanComparable.
template <class _Tp>
struct _ComparableConcept
{
void __constraints() {
__aux_require_boolean_expr(__a < __b);
__aux_require_boolean_expr(__a > __b);
__aux_require_boolean_expr(__a <= __b);
__aux_require_boolean_expr(__a >= __b);
}
_Tp __a, __b;
};
#define _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(_OP,_NAME) \
template <class _First, class _Second> \
struct _NAME { \
void __constraints() { (void)__constraints_(); } \
bool __constraints_() { \
return __a _OP __b; \
} \
_First __a; \
_Second __b; \
}
#define _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(_OP,_NAME) \
template <class _Ret, class _First, class _Second> \
struct _NAME { \
void __constraints() { (void)__constraints_(); } \
_Ret __constraints_() { \
return __a _OP __b; \
} \
_First __a; \
_Second __b; \
}
_GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(==, _EqualOpConcept);
_GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(!=, _NotEqualOpConcept);
_GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<, _LessThanOpConcept);
_GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<=, _LessEqualOpConcept);
_GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>, _GreaterThanOpConcept);
_GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>=, _GreaterEqualOpConcept);
_GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(+, _PlusOpConcept);
_GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(*, _TimesOpConcept);
_GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(/, _DivideOpConcept);
_GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(-, _SubtractOpConcept);
_GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(%, _ModOpConcept);
#undef _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT
#undef _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT
//===========================================================================
// Function Object Concepts
template <class _Func, class _Return>
struct _GeneratorConcept
{
void __constraints() {
const _Return& __r _IsUnused = __f();// require operator() member function
}
_Func __f;
};
template <class _Func>
struct _GeneratorConcept<_Func,void>
{
void __constraints() {
__f(); // require operator() member function
}
_Func __f;
};
template <class _Func, class _Return, class _Arg>
struct _UnaryFunctionConcept
{
void __constraints() {
__r = __f(__arg); // require operator()
}
_Func __f;
_Arg __arg;
_Return __r;
};
template <class _Func, class _Arg>
struct _UnaryFunctionConcept<_Func, void, _Arg> {
void __constraints() {
__f(__arg); // require operator()
}
_Func __f;
_Arg __arg;
};
template <class _Func, class _Return, class _First, class _Second>
struct _BinaryFunctionConcept
{
void __constraints() {
__r = __f(__first, __second); // require operator()
}
_Func __f;
_First __first;
_Second __second;
_Return __r;
};
template <class _Func, class _First, class _Second>
struct _BinaryFunctionConcept<_Func, void, _First, _Second>
{
void __constraints() {
__f(__first, __second); // require operator()
}
_Func __f;
_First __first;
_Second __second;
};
template <class _Func, class _Arg>
struct _UnaryPredicateConcept
{
void __constraints() {
__aux_require_boolean_expr(__f(__arg)); // require op() returning bool
}
_Func __f;
_Arg __arg;
};
template <class _Func, class _First, class _Second>
struct _BinaryPredicateConcept
{
void __constraints() {
__aux_require_boolean_expr(__f(__a, __b)); // require op() returning bool
}
_Func __f;
_First __a;
_Second __b;
};
// use this when functor is used inside a container class like std::set
template <class _Func, class _First, class _Second>
struct _Const_BinaryPredicateConcept {
void __constraints() {
__const_constraints(__f);
}
void __const_constraints(const _Func& __fun) {
__function_requires<_BinaryPredicateConcept<_Func, _First, _Second> >();
// operator() must be a const member function
__aux_require_boolean_expr(__fun(__a, __b));
}
_Func __f;
_First __a;
_Second __b;
};
//===========================================================================
// Iterator Concepts
template <class _Tp>
struct _TrivialIteratorConcept
{
void __constraints() {
// __function_requires< _DefaultConstructibleConcept<_Tp> >();
__function_requires< _AssignableConcept<_Tp> >();
__function_requires< _EqualityComparableConcept<_Tp> >();
// typedef typename std::iterator_traits<_Tp>::value_type _V;
(void)*__i; // require dereference operator
}
_Tp __i;
};
template <class _Tp>
struct _Mutable_TrivialIteratorConcept
{
void __constraints() {
__function_requires< _TrivialIteratorConcept<_Tp> >();
*__i = *__j; // require dereference and assignment
}
_Tp __i, __j;
};
template <class _Tp>
struct _InputIteratorConcept
{
void __constraints() {
__function_requires< _TrivialIteratorConcept<_Tp> >();
// require iterator_traits typedef's
typedef typename std::iterator_traits<_Tp>::difference_type _Diff;
// __function_requires< _SignedIntegerConcept<_Diff> >();
typedef typename std::iterator_traits<_Tp>::reference _Ref;
typedef typename std::iterator_traits<_Tp>::pointer _Pt;
typedef typename std::iterator_traits<_Tp>::iterator_category _Cat;
__function_requires< _ConvertibleConcept<
typename std::iterator_traits<_Tp>::iterator_category,
std::input_iterator_tag> >();
++__i; // require preincrement operator
__i++; // require postincrement operator
}
_Tp __i;
};
template <class _Tp, class _ValueT>
struct _OutputIteratorConcept
{
void __constraints() {
__function_requires< _AssignableConcept<_Tp> >();
++__i; // require preincrement operator
__i++; // require postincrement operator
*__i++ = __val(); // require postincrement and assignment
}
_Tp __i;
// Use a function pointer here so no definition of the function needed.
// Just need something that returns a _ValueT (which might be a reference).
_ValueT (*__val)();
};
template<typename _Tp>
struct _Is_vector_bool_iterator
{ static const bool __value = false; };
#ifdef _GLIBCXX_DEBUG
namespace __cont = ::std::_GLIBCXX_STD_C;
#else
namespace __cont = ::std;
#endif
// Trait to identify vector<bool>::iterator
template <>
struct _Is_vector_bool_iterator<__cont::_Bit_iterator>
{ static const bool __value = true; };
// And for vector<bool>::const_iterator.
template <>
struct _Is_vector_bool_iterator<__cont::_Bit_const_iterator>
{ static const bool __value = true; };
// And for __gnu_debug::vector<bool> iterators too.
template <typename _It, typename _Seq, typename _Tag>
struct _Is_vector_bool_iterator<__gnu_debug::_Safe_iterator<_It, _Seq, _Tag> >
: _Is_vector_bool_iterator<_It> { };
template <class _Tp, bool = _Is_vector_bool_iterator<_Tp>::__value>
struct _ForwardIteratorReferenceConcept
{
void __constraints() {
#if __cplusplus >= 201103L
typedef typename std::iterator_traits<_Tp>::reference _Ref;
static_assert(std::is_reference<_Ref>::value,
"reference type of a forward iterator must be a real reference");
#endif
}
};
template <class _Tp, bool = _Is_vector_bool_iterator<_Tp>::__value>
struct _Mutable_ForwardIteratorReferenceConcept
{
void __constraints() {
typedef typename std::iterator_traits<_Tp>::reference _Ref;
typedef typename std::iterator_traits<_Tp>::value_type _Val;
__function_requires< _SameTypeConcept<_Ref, _Val&> >();
}
};
// vector<bool> iterators are not real forward iterators, but we ignore that.
template <class _Tp>
struct _ForwardIteratorReferenceConcept<_Tp, true>
{
void __constraints() { }
};
// vector<bool> iterators are not real forward iterators, but we ignore that.
template <class _Tp>
struct _Mutable_ForwardIteratorReferenceConcept<_Tp, true>
{
void __constraints() { }
};
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-variable"
template <class _Tp>
struct _ForwardIteratorConcept
{
void __constraints() {
__function_requires< _InputIteratorConcept<_Tp> >();
__function_requires< _DefaultConstructibleConcept<_Tp> >();
__function_requires< _ConvertibleConcept<
typename std::iterator_traits<_Tp>::iterator_category,
std::forward_iterator_tag> >();
__function_requires< _ForwardIteratorReferenceConcept<_Tp> >();
_Tp& __j = ++__i;
const _Tp& __k = __i++;
typedef typename std::iterator_traits<_Tp>::reference _Ref;
_Ref __r = *__k;
_Ref __r2 = *__i++;
}
_Tp __i;
};
template <class _Tp>
struct _Mutable_ForwardIteratorConcept
{
void __constraints() {
__function_requires< _ForwardIteratorConcept<_Tp> >();
typedef typename std::iterator_traits<_Tp>::reference _Ref;
typedef typename std::iterator_traits<_Tp>::value_type _Val;
__function_requires< _Mutable_ForwardIteratorReferenceConcept<_Tp> >();
}
_Tp __i;
};
template <class _Tp>
struct _BidirectionalIteratorConcept
{
void __constraints() {
__function_requires< _ForwardIteratorConcept<_Tp> >();
__function_requires< _ConvertibleConcept<
typename std::iterator_traits<_Tp>::iterator_category,
std::bidirectional_iterator_tag> >();
_Tp& __j = --__i; // require predecrement operator
const _Tp& __k = __i--; // require postdecrement operator
typedef typename std::iterator_traits<_Tp>::reference _Ref;
_Ref __r = *__j--;
}
_Tp __i;
};
template <class _Tp>
struct _Mutable_BidirectionalIteratorConcept
{
void __constraints() {
__function_requires< _BidirectionalIteratorConcept<_Tp> >();
__function_requires< _Mutable_ForwardIteratorConcept<_Tp> >();
}
_Tp __i;
};
template <class _Tp>
struct _RandomAccessIteratorConcept
{
void __constraints() {
__function_requires< _BidirectionalIteratorConcept<_Tp> >();
__function_requires< _ComparableConcept<_Tp> >();
__function_requires< _ConvertibleConcept<
typename std::iterator_traits<_Tp>::iterator_category,
std::random_access_iterator_tag> >();
typedef typename std::iterator_traits<_Tp>::reference _Ref;
_Tp& __j = __i += __n; // require assignment addition operator
__i = __i + __n; __i = __n + __i; // require addition with difference type
_Tp& __k = __i -= __n; // require assignment subtraction op
__i = __i - __n; // require subtraction with
// difference type
__n = __i - __j; // require difference operator
_Ref __r = __i[__n]; // require element access operator
}
_Tp __a, __b;
_Tp __i, __j;
typename std::iterator_traits<_Tp>::difference_type __n;
};
template <class _Tp>
struct _Mutable_RandomAccessIteratorConcept
{
void __constraints() {
__function_requires< _RandomAccessIteratorConcept<_Tp> >();
__function_requires< _Mutable_BidirectionalIteratorConcept<_Tp> >();
}
_Tp __i;
typename std::iterator_traits<_Tp>::difference_type __n;
};
#pragma GCC diagnostic pop
//===========================================================================
// Container Concepts
template <class _Container>
struct _ContainerConcept
{
typedef typename _Container::value_type _Value_type;
typedef typename _Container::difference_type _Difference_type;
typedef typename _Container::size_type _Size_type;
typedef typename _Container::const_reference _Const_reference;
typedef typename _Container::const_pointer _Const_pointer;
typedef typename _Container::const_iterator _Const_iterator;
void __constraints() {
__function_requires< _InputIteratorConcept<_Const_iterator> >();
__function_requires< _AssignableConcept<_Container> >();
const _Container __c;
__i = __c.begin();
__i = __c.end();
__n = __c.size();
__n = __c.max_size();
__b = __c.empty();
}
bool __b;
_Const_iterator __i;
_Size_type __n;
};
template <class _Container>
struct _Mutable_ContainerConcept
{
typedef typename _Container::value_type _Value_type;
typedef typename _Container::reference _Reference;
typedef typename _Container::iterator _Iterator;
typedef typename _Container::pointer _Pointer;
void __constraints() {
__function_requires< _ContainerConcept<_Container> >();
__function_requires< _AssignableConcept<_Value_type> >();
__function_requires< _InputIteratorConcept<_Iterator> >();
__i = __c.begin();
__i = __c.end();
__c.swap(__c2);
}
_Iterator __i;
_Container __c, __c2;
};
template <class _ForwardContainer>
struct _ForwardContainerConcept
{
void __constraints() {
__function_requires< _ContainerConcept<_ForwardContainer> >();
typedef typename _ForwardContainer::const_iterator _Const_iterator;
__function_requires< _ForwardIteratorConcept<_Const_iterator> >();
}
};
template <class _ForwardContainer>
struct _Mutable_ForwardContainerConcept
{
void __constraints() {
__function_requires< _ForwardContainerConcept<_ForwardContainer> >();
__function_requires< _Mutable_ContainerConcept<_ForwardContainer> >();
typedef typename _ForwardContainer::iterator _Iterator;
__function_requires< _Mutable_ForwardIteratorConcept<_Iterator> >();
}
};
template <class _ReversibleContainer>
struct _ReversibleContainerConcept
{
typedef typename _ReversibleContainer::const_iterator _Const_iterator;
typedef typename _ReversibleContainer::const_reverse_iterator
_Const_reverse_iterator;
void __constraints() {
__function_requires< _ForwardContainerConcept<_ReversibleContainer> >();
__function_requires< _BidirectionalIteratorConcept<_Const_iterator> >();
__function_requires<
_BidirectionalIteratorConcept<_Const_reverse_iterator> >();
const _ReversibleContainer __c;
_Const_reverse_iterator __i = __c.rbegin();
__i = __c.rend();
}
};
template <class _ReversibleContainer>
struct _Mutable_ReversibleContainerConcept
{
typedef typename _ReversibleContainer::iterator _Iterator;
typedef typename _ReversibleContainer::reverse_iterator _Reverse_iterator;
void __constraints() {
__function_requires<_ReversibleContainerConcept<_ReversibleContainer> >();
__function_requires<
_Mutable_ForwardContainerConcept<_ReversibleContainer> >();
__function_requires<_Mutable_BidirectionalIteratorConcept<_Iterator> >();
__function_requires<
_Mutable_BidirectionalIteratorConcept<_Reverse_iterator> >();
_Reverse_iterator __i = __c.rbegin();
__i = __c.rend();
}
_ReversibleContainer __c;
};
template <class _RandomAccessContainer>
struct _RandomAccessContainerConcept
{
typedef typename _RandomAccessContainer::size_type _Size_type;
typedef typename _RandomAccessContainer::const_reference _Const_reference;
typedef typename _RandomAccessContainer::const_iterator _Const_iterator;
typedef typename _RandomAccessContainer::const_reverse_iterator
_Const_reverse_iterator;
void __constraints() {
__function_requires<
_ReversibleContainerConcept<_RandomAccessContainer> >();
__function_requires< _RandomAccessIteratorConcept<_Const_iterator> >();
__function_requires<
_RandomAccessIteratorConcept<_Const_reverse_iterator> >();
const _RandomAccessContainer __c;
_Const_reference __r _IsUnused = __c[__n];
}
_Size_type __n;
};
template <class _RandomAccessContainer>
struct _Mutable_RandomAccessContainerConcept
{
typedef typename _RandomAccessContainer::size_type _Size_type;
typedef typename _RandomAccessContainer::reference _Reference;
typedef typename _RandomAccessContainer::iterator _Iterator;
typedef typename _RandomAccessContainer::reverse_iterator _Reverse_iterator;
void __constraints() {
__function_requires<
_RandomAccessContainerConcept<_RandomAccessContainer> >();
__function_requires<
_Mutable_ReversibleContainerConcept<_RandomAccessContainer> >();
__function_requires< _Mutable_RandomAccessIteratorConcept<_Iterator> >();
__function_requires<
_Mutable_RandomAccessIteratorConcept<_Reverse_iterator> >();
_Reference __r _IsUnused = __c[__i];
}
_Size_type __i;
_RandomAccessContainer __c;
};
// A Sequence is inherently mutable
template <class _Sequence>
struct _SequenceConcept
{
typedef typename _Sequence::reference _Reference;
typedef typename _Sequence::const_reference _Const_reference;
void __constraints() {
// Matt Austern's book puts DefaultConstructible here, the C++
// standard places it in Container
// function_requires< DefaultConstructible<Sequence> >();
__function_requires< _Mutable_ForwardContainerConcept<_Sequence> >();
__function_requires< _DefaultConstructibleConcept<_Sequence> >();
_Sequence
__c _IsUnused(__n, __t),
__c2 _IsUnused(__first, __last);
__c.insert(__p, __t);
__c.insert(__p, __n, __t);
__c.insert(__p, __first, __last);
__c.erase(__p);
__c.erase(__p, __q);
_Reference __r _IsUnused = __c.front();
__const_constraints(__c);
}
void __const_constraints(const _Sequence& __c) {
_Const_reference __r _IsUnused = __c.front();
}
typename _Sequence::value_type __t;
typename _Sequence::size_type __n;
typename _Sequence::value_type *__first, *__last;
typename _Sequence::iterator __p, __q;
};
template <class _FrontInsertionSequence>
struct _FrontInsertionSequenceConcept
{
void __constraints() {
__function_requires< _SequenceConcept<_FrontInsertionSequence> >();
__c.push_front(__t);
__c.pop_front();
}
_FrontInsertionSequence __c;
typename _FrontInsertionSequence::value_type __t;
};
template <class _BackInsertionSequence>
struct _BackInsertionSequenceConcept
{
typedef typename _BackInsertionSequence::reference _Reference;
typedef typename _BackInsertionSequence::const_reference _Const_reference;
void __constraints() {
__function_requires< _SequenceConcept<_BackInsertionSequence> >();
__c.push_back(__t);
__c.pop_back();
_Reference __r _IsUnused = __c.back();
}
void __const_constraints(const _BackInsertionSequence& __c) {
_Const_reference __r _IsUnused = __c.back();
};
_BackInsertionSequence __c;
typename _BackInsertionSequence::value_type __t;
};
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#pragma GCC diagnostic pop
#undef _IsUnused
#endif // _GLIBCXX_BOOST_CONCEPT_CHECK
@@ -0,0 +1,37 @@
// Copyright (C) 2007-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/c++0x_warning.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{iosfwd}
*/
#ifndef _CXX0X_WARNING_H
#define _CXX0X_WARNING_H 1
#if __cplusplus < 201103L
#error This file requires compiler and library support \
for the ISO C++ 2011 standard. This support must be enabled \
with the -std=c++11 or -std=gnu++11 compiler options.
#endif
#endif
@@ -0,0 +1,64 @@
// Base to std::allocator -*- C++ -*-
// Copyright (C) 2004-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/c++allocator.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{memory}
*/
#ifndef _GLIBCXX_CXX_ALLOCATOR_H
#define _GLIBCXX_CXX_ALLOCATOR_H 1
#include <bits/new_allocator.h>
#if __cplusplus >= 201103L
namespace std
{
/**
* @brief An alias to the base class for std::allocator.
*
* Used to set the std::allocator base class to std::__new_allocator.
*
* @ingroup allocators
* @tparam _Tp Type of allocated object.
*/
template<typename _Tp>
using __allocator_base = __new_allocator<_Tp>;
}
#else
// Define __new_allocator as the base class to std::allocator.
# define __allocator_base __new_allocator
#endif
#ifndef _GLIBCXX_SANITIZE_STD_ALLOCATOR
# if defined(__SANITIZE_ADDRESS__)
# define _GLIBCXX_SANITIZE_STD_ALLOCATOR 1
# elif defined __has_feature
# if __has_feature(address_sanitizer)
# define _GLIBCXX_SANITIZE_STD_ALLOCATOR 1
# endif
# endif
#endif
#endif
File diff suppressed because it is too large Load Diff
+57
View File
@@ -0,0 +1,57 @@
// Underlying io library details -*- C++ -*-
// Copyright (C) 2000-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/c++io.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{ios}
*/
// c_io_stdio.h - Defines for using "C" stdio.h
#ifndef _GLIBCXX_CXX_IO_H
#define _GLIBCXX_CXX_IO_H 1
#include <cstdio>
#include <bits/gthr.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
#ifdef __GTHREAD_LEGACY_MUTEX_T
// The layout of __gthread_mutex_t changed in GCC 13, but libstdc++ doesn't
// actually use the basic_filebuf::_M_lock member, so define it consistently
// with the old __gthread_mutex_t to avoid an unnecessary layout change:
typedef __GTHREAD_LEGACY_MUTEX_T __c_lock;
#else
typedef __gthread_mutex_t __c_lock;
#endif
// for basic_file.h
typedef FILE __c_file;
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif
+92
View File
@@ -0,0 +1,92 @@
// Wrapper for underlying C-language localization -*- C++ -*-
// Copyright (C) 2001-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/c++locale.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{locale}
*/
//
// ISO C++ 14882: 22.8 Standard locale categories.
//
// Written by Benjamin Kosnik <bkoz@redhat.com>
#ifndef _GLIBCXX_CXX_LOCALE_H
#define _GLIBCXX_CXX_LOCALE_H 1
#pragma GCC system_header
#include <clocale>
#define _GLIBCXX_NUM_CATEGORIES 0
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
typedef int* __c_locale;
// Convert numeric value of type double and long double to string and
// return length of string. If vsnprintf is available use it, otherwise
// fall back to the unsafe vsprintf which, in general, can be dangerous
// and should be avoided.
inline int
__convert_from_v(const __c_locale&, char* __out,
const int __size __attribute__((__unused__)),
const char* __fmt, ...)
{
char* __old = std::setlocale(LC_NUMERIC, 0);
char* __sav = 0;
if (__builtin_strcmp(__old, "C"))
{
const size_t __len = __builtin_strlen(__old) + 1;
__sav = new char[__len];
__builtin_memcpy(__sav, __old, __len);
std::setlocale(LC_NUMERIC, "C");
}
__builtin_va_list __args;
__builtin_va_start(__args, __fmt);
#if _GLIBCXX_USE_C99_STDIO && !_GLIBCXX_HAVE_BROKEN_VSNPRINTF
const int __ret = __builtin_vsnprintf(__out, __size, __fmt, __args);
#else
const int __ret = __builtin_vsprintf(__out, __fmt, __args);
#endif
__builtin_va_end(__args);
if (__sav)
{
std::setlocale(LC_NUMERIC, __sav);
delete [] __sav;
}
return __ret;
}
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,81 @@
// Concept-checking control -*- C++ -*-
// Copyright (C) 2001-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/concept_check.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{iterator}
*/
#ifndef _CONCEPT_CHECK_H
#define _CONCEPT_CHECK_H 1
#pragma GCC system_header
#include <bits/c++config.h>
// All places in libstdc++-v3 where these are used, or /might/ be used, or
// don't need to be used, or perhaps /should/ be used, are commented with
// "concept requirements" (and maybe some more text). So grep like crazy
// if you're looking for additional places to use these.
// Concept-checking code is off by default unless users turn it on via
// configure options or editing c++config.h.
// It is not supported for freestanding implementations.
#if !defined(_GLIBCXX_CONCEPT_CHECKS)
#define __glibcxx_function_requires(...)
#define __glibcxx_class_requires(_a,_b)
#define __glibcxx_class_requires2(_a,_b,_c)
#define __glibcxx_class_requires3(_a,_b,_c,_d)
#define __glibcxx_class_requires4(_a,_b,_c,_d,_e)
#else // the checks are on
#include <bits/boost_concept_check.h>
// Note that the obvious and elegant approach of
//
//#define glibcxx_function_requires(C) debug::function_requires< debug::C >()
//
// won't work due to concept templates with more than one parameter, e.g.,
// BinaryPredicateConcept. The preprocessor tries to split things up on
// the commas in the template argument list. We can't use an inner pair of
// parenthesis to hide the commas, because "debug::(Temp<Foo,Bar>)" isn't
// a valid instantiation pattern. Thus, we steal a feature from C99.
#define __glibcxx_function_requires(...) \
__gnu_cxx::__function_requires< __gnu_cxx::__VA_ARGS__ >();
#define __glibcxx_class_requires(_a,_C) \
_GLIBCXX_CLASS_REQUIRES(_a, __gnu_cxx, _C);
#define __glibcxx_class_requires2(_a,_b,_C) \
_GLIBCXX_CLASS_REQUIRES2(_a, _b, __gnu_cxx, _C);
#define __glibcxx_class_requires3(_a,_b,_c,_C) \
_GLIBCXX_CLASS_REQUIRES3(_a, _b, _c, __gnu_cxx, _C);
#define __glibcxx_class_requires4(_a,_b,_c,_d,_C) \
_GLIBCXX_CLASS_REQUIRES4(_a, _b, _c, _d, __gnu_cxx, _C);
#endif // enable/disable
#endif // _GLIBCXX_CONCEPT_CHECK
@@ -0,0 +1,614 @@
// The -*- C++ -*- type traits classes for internal use in libstdc++
// Copyright (C) 2000-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/cpp_type_traits.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{ext/type_traits}
*/
// Written by Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr>
#ifndef _CPP_TYPE_TRAITS_H
#define _CPP_TYPE_TRAITS_H 1
#pragma GCC system_header
#include <bits/c++config.h>
//
// This file provides some compile-time information about various types.
// These representations were designed, on purpose, to be constant-expressions
// and not types as found in <bits/type_traits.h>. In particular, they
// can be used in control structures and the optimizer hopefully will do
// the obvious thing.
//
// Why integral expressions, and not functions nor types?
// Firstly, these compile-time entities are used as template-arguments
// so function return values won't work: We need compile-time entities.
// We're left with types and constant integral expressions.
// Secondly, from the point of view of ease of use, type-based compile-time
// information is -not- *that* convenient. One has to write lots of
// overloaded functions and to hope that the compiler will select the right
// one. As a net effect, the overall structure isn't very clear at first
// glance.
// Thirdly, partial ordering and overload resolution (of function templates)
// is highly costly in terms of compiler-resource. It is a Good Thing to
// keep these resource consumption as least as possible.
//
// See valarray_array.h for a case use.
//
// -- Gaby (dosreis@cmla.ens-cachan.fr) 2000-03-06.
//
// Update 2005: types are also provided and <bits/type_traits.h> has been
// removed.
//
extern "C++" {
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
struct __true_type { };
struct __false_type { };
template<bool>
struct __truth_type
{ typedef __false_type __type; };
template<>
struct __truth_type<true>
{ typedef __true_type __type; };
// N.B. The conversions to bool are needed due to the issue
// explained in c++/19404.
template<class _Sp, class _Tp>
struct __traitor
{
enum { __value = bool(_Sp::__value) || bool(_Tp::__value) };
typedef typename __truth_type<__value>::__type __type;
};
// Compare for equality of types.
template<typename, typename>
struct __are_same
{
enum { __value = 0 };
typedef __false_type __type;
};
template<typename _Tp>
struct __are_same<_Tp, _Tp>
{
enum { __value = 1 };
typedef __true_type __type;
};
// Holds if the template-argument is a void type.
template<typename _Tp>
struct __is_void
{
enum { __value = 0 };
typedef __false_type __type;
};
template<>
struct __is_void<void>
{
enum { __value = 1 };
typedef __true_type __type;
};
//
// Integer types
//
template<typename _Tp>
struct __is_integer
{
enum { __value = 0 };
typedef __false_type __type;
};
// Thirteen specializations (yes there are eleven standard integer
// types; <em>long long</em> and <em>unsigned long long</em> are
// supported as extensions). Up to four target-specific __int<N>
// types are supported as well.
template<>
struct __is_integer<bool>
{
enum { __value = 1 };
typedef __true_type __type;
};
template<>
struct __is_integer<char>
{
enum { __value = 1 };
typedef __true_type __type;
};
template<>
struct __is_integer<signed char>
{
enum { __value = 1 };
typedef __true_type __type;
};
template<>
struct __is_integer<unsigned char>
{
enum { __value = 1 };
typedef __true_type __type;
};
# ifdef __WCHAR_TYPE__
template<>
struct __is_integer<wchar_t>
{
enum { __value = 1 };
typedef __true_type __type;
};
# endif
#ifdef _GLIBCXX_USE_CHAR8_T
template<>
struct __is_integer<char8_t>
{
enum { __value = 1 };
typedef __true_type __type;
};
#endif
#if __cplusplus >= 201103L
template<>
struct __is_integer<char16_t>
{
enum { __value = 1 };
typedef __true_type __type;
};
template<>
struct __is_integer<char32_t>
{
enum { __value = 1 };
typedef __true_type __type;
};
#endif
template<>
struct __is_integer<short>
{
enum { __value = 1 };
typedef __true_type __type;
};
template<>
struct __is_integer<unsigned short>
{
enum { __value = 1 };
typedef __true_type __type;
};
template<>
struct __is_integer<int>
{
enum { __value = 1 };
typedef __true_type __type;
};
template<>
struct __is_integer<unsigned int>
{
enum { __value = 1 };
typedef __true_type __type;
};
template<>
struct __is_integer<long>
{
enum { __value = 1 };
typedef __true_type __type;
};
template<>
struct __is_integer<unsigned long>
{
enum { __value = 1 };
typedef __true_type __type;
};
template<>
struct __is_integer<long long>
{
enum { __value = 1 };
typedef __true_type __type;
};
template<>
struct __is_integer<unsigned long long>
{
enum { __value = 1 };
typedef __true_type __type;
};
#define __INT_N(TYPE) \
__extension__ \
template<> \
struct __is_integer<TYPE> \
{ \
enum { __value = 1 }; \
typedef __true_type __type; \
}; \
__extension__ \
template<> \
struct __is_integer<unsigned TYPE> \
{ \
enum { __value = 1 }; \
typedef __true_type __type; \
};
#ifdef __GLIBCXX_TYPE_INT_N_0
__INT_N(__GLIBCXX_TYPE_INT_N_0)
#endif
#ifdef __GLIBCXX_TYPE_INT_N_1
__INT_N(__GLIBCXX_TYPE_INT_N_1)
#endif
#ifdef __GLIBCXX_TYPE_INT_N_2
__INT_N(__GLIBCXX_TYPE_INT_N_2)
#endif
#ifdef __GLIBCXX_TYPE_INT_N_3
__INT_N(__GLIBCXX_TYPE_INT_N_3)
#endif
#undef __INT_N
//
// Floating point types
//
template<typename _Tp>
struct __is_floating
{
enum { __value = 0 };
typedef __false_type __type;
};
// three specializations (float, double and 'long double')
template<>
struct __is_floating<float>
{
enum { __value = 1 };
typedef __true_type __type;
};
template<>
struct __is_floating<double>
{
enum { __value = 1 };
typedef __true_type __type;
};
template<>
struct __is_floating<long double>
{
enum { __value = 1 };
typedef __true_type __type;
};
#ifdef __STDCPP_FLOAT16_T__
template<>
struct __is_floating<_Float16>
{
enum { __value = 1 };
typedef __true_type __type;
};
#endif
#ifdef __STDCPP_FLOAT32_T__
template<>
struct __is_floating<_Float32>
{
enum { __value = 1 };
typedef __true_type __type;
};
#endif
#ifdef __STDCPP_FLOAT64_T__
template<>
struct __is_floating<_Float64>
{
enum { __value = 1 };
typedef __true_type __type;
};
#endif
#ifdef __STDCPP_FLOAT128_T__
template<>
struct __is_floating<_Float128>
{
enum { __value = 1 };
typedef __true_type __type;
};
#endif
#ifdef __STDCPP_BFLOAT16_T__
template<>
struct __is_floating<__gnu_cxx::__bfloat16_t>
{
enum { __value = 1 };
typedef __true_type __type;
};
#endif
//
// Pointer types
//
template<typename _Tp>
struct __is_pointer
{
enum { __value = 0 };
typedef __false_type __type;
};
template<typename _Tp>
struct __is_pointer<_Tp*>
{
enum { __value = 1 };
typedef __true_type __type;
};
//
// An arithmetic type is an integer type or a floating point type
//
template<typename _Tp>
struct __is_arithmetic
: public __traitor<__is_integer<_Tp>, __is_floating<_Tp> >
{ };
//
// A scalar type is an arithmetic type or a pointer type
//
template<typename _Tp>
struct __is_scalar
: public __traitor<__is_arithmetic<_Tp>, __is_pointer<_Tp> >
{ };
//
// For use in std::copy and std::find overloads for streambuf iterators.
//
template<typename _Tp>
struct __is_char
{
enum { __value = 0 };
typedef __false_type __type;
};
template<>
struct __is_char<char>
{
enum { __value = 1 };
typedef __true_type __type;
};
#ifdef __WCHAR_TYPE__
template<>
struct __is_char<wchar_t>
{
enum { __value = 1 };
typedef __true_type __type;
};
#endif
template<typename _Tp>
struct __is_byte
{
enum { __value = 0 };
typedef __false_type __type;
};
template<>
struct __is_byte<char>
{
enum { __value = 1 };
typedef __true_type __type;
};
template<>
struct __is_byte<signed char>
{
enum { __value = 1 };
typedef __true_type __type;
};
template<>
struct __is_byte<unsigned char>
{
enum { __value = 1 };
typedef __true_type __type;
};
#if __cplusplus >= 201703L
enum class byte : unsigned char;
template<>
struct __is_byte<byte>
{
enum { __value = 1 };
typedef __true_type __type;
};
#endif // C++17
#ifdef _GLIBCXX_USE_CHAR8_T
template<>
struct __is_byte<char8_t>
{
enum { __value = 1 };
typedef __true_type __type;
};
#endif
template<typename> struct iterator_traits;
// A type that is safe for use with memcpy, memmove, memcmp etc.
template<typename _Tp>
struct __is_nonvolatile_trivially_copyable
{
enum { __value = __is_trivially_copyable(_Tp) };
};
// Cannot use memcpy/memmove/memcmp on volatile types even if they are
// trivially copyable, so ensure __memcpyable<volatile int*, volatile int*>
// and similar will be false.
template<typename _Tp>
struct __is_nonvolatile_trivially_copyable<volatile _Tp>
{
enum { __value = 0 };
};
// Whether two iterator types can be used with memcpy/memmove.
template<typename _OutputIter, typename _InputIter>
struct __memcpyable
{
enum { __value = 0 };
};
template<typename _Tp>
struct __memcpyable<_Tp*, _Tp*>
: __is_nonvolatile_trivially_copyable<_Tp>
{ };
template<typename _Tp>
struct __memcpyable<_Tp*, const _Tp*>
: __is_nonvolatile_trivially_copyable<_Tp>
{ };
// Whether two iterator types can be used with memcmp.
// This trait only says it's well-formed to use memcmp, not that it
// gives the right answer for a given algorithm. So for example, std::equal
// needs to add additional checks that the types are integers or pointers,
// because other trivially copyable types can overload operator==.
template<typename _Iter1, typename _Iter2>
struct __memcmpable
{
enum { __value = 0 };
};
// OK to use memcmp with pointers to trivially copyable types.
template<typename _Tp>
struct __memcmpable<_Tp*, _Tp*>
: __is_nonvolatile_trivially_copyable<_Tp>
{ };
template<typename _Tp>
struct __memcmpable<const _Tp*, _Tp*>
: __is_nonvolatile_trivially_copyable<_Tp>
{ };
template<typename _Tp>
struct __memcmpable<_Tp*, const _Tp*>
: __is_nonvolatile_trivially_copyable<_Tp>
{ };
// Whether memcmp can be used to determine ordering for a type
// e.g. in std::lexicographical_compare or three-way comparisons.
// True for unsigned integer-like types where comparing each byte in turn
// as an unsigned char yields the right result. This is true for all
// unsigned integers on big endian targets, but only unsigned narrow
// character types (and std::byte) on little endian targets.
template<typename _Tp, bool _TreatAsBytes =
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
__is_integer<_Tp>::__value
#else
__is_byte<_Tp>::__value
#endif
>
struct __is_memcmp_ordered
{
static const bool __value = _Tp(-1) > _Tp(1); // is unsigned
};
template<typename _Tp>
struct __is_memcmp_ordered<_Tp, false>
{
static const bool __value = false;
};
// Whether two types can be compared using memcmp.
template<typename _Tp, typename _Up, bool = sizeof(_Tp) == sizeof(_Up)>
struct __is_memcmp_ordered_with
{
static const bool __value = __is_memcmp_ordered<_Tp>::__value
&& __is_memcmp_ordered<_Up>::__value;
};
template<typename _Tp, typename _Up>
struct __is_memcmp_ordered_with<_Tp, _Up, false>
{
static const bool __value = false;
};
#if __cplusplus >= 201703L
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
// std::byte is not an integer, but it can be compared using memcmp.
template<>
struct __is_memcmp_ordered<std::byte, false>
{ static constexpr bool __value = true; };
#endif
// std::byte can only be compared to itself, not to other types.
template<>
struct __is_memcmp_ordered_with<std::byte, std::byte, true>
{ static constexpr bool __value = true; };
template<typename _Tp, bool _SameSize>
struct __is_memcmp_ordered_with<_Tp, std::byte, _SameSize>
{ static constexpr bool __value = false; };
template<typename _Up, bool _SameSize>
struct __is_memcmp_ordered_with<std::byte, _Up, _SameSize>
{ static constexpr bool __value = false; };
#endif
//
// Move iterator type
//
template<typename _Tp>
struct __is_move_iterator
{
enum { __value = 0 };
typedef __false_type __type;
};
// Fallback implementation of the function in bits/stl_iterator.h used to
// remove the move_iterator wrapper.
template<typename _Iterator>
_GLIBCXX20_CONSTEXPR
inline _Iterator
__miter_base(_Iterator __it)
{ return __it; }
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
} // extern "C++"
#endif //_CPP_TYPE_TRAITS_H
@@ -0,0 +1,33 @@
// Specific definitions for generic platforms -*- C++ -*-
// Copyright (C) 2005-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/cpu_defines.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{iosfwd}
*/
#ifndef _GLIBCXX_CPU_DEFINES
#define _GLIBCXX_CPU_DEFINES 1
#endif
@@ -0,0 +1,59 @@
// Locale support -*- C++ -*-
// Copyright (C) 1997-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
//
// ISO C++ 14882: 22.1 Locales
//
// Default information, may not be appropriate for specific host.
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/// @brief Base class for ctype.
struct ctype_base
{
// Non-standard typedefs.
typedef const int* __to_type;
// NB: Offsets into ctype<char>::_M_table force a particular size
// on the mask type. Because of this, we don't use an enum.
typedef unsigned int mask;
static const mask upper = 1 << 0;
static const mask lower = 1 << 1;
static const mask alpha = 1 << 2;
static const mask digit = 1 << 3;
static const mask xdigit = 1 << 4;
static const mask space = 1 << 5;
static const mask print = 1 << 6;
static const mask graph = (1 << 2) | (1 << 3) | (1 << 9); // alnum|punct
static const mask cntrl = 1 << 8;
static const mask punct = 1 << 9;
static const mask alnum = (1 << 2) | (1 << 3); // alpha|digit
static const mask blank = 1 << 10;
};
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
@@ -0,0 +1,173 @@
// Locale support -*- C++ -*-
// Copyright (C) 2000-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/ctype_inline.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{locale}
*/
//
// ISO C++ 14882: 22.1 Locales
//
// ctype bits to be inlined go here. Non-inlinable (ie virtual do_*)
// functions go in ctype.cc
// The following definitions are portable, but insanely slow. If one
// cares at all about performance, then specialized ctype
// functionality should be added for the native os in question: see
// the config/os/bits/ctype_*.h files.
// Constructing a synthetic "C" table should be seriously considered...
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
bool
ctype<char>::
is(mask __m, char __c) const
{
if (_M_table)
return _M_table[static_cast<unsigned char>(__c)] & __m;
else
{
bool __ret = false;
const size_t __bitmasksize = 15;
size_t __bitcur = 0; // Lowest bitmask in ctype_base == 0
for (; __bitcur <= __bitmasksize; ++__bitcur)
{
const mask __bit = static_cast<mask>(1 << __bitcur);
if (__m & __bit)
{
bool __testis;
switch (__bit)
{
case space:
__testis = isspace(__c);
break;
case print:
__testis = isprint(__c);
break;
case cntrl:
__testis = iscntrl(__c);
break;
case upper:
__testis = isupper(__c);
break;
case lower:
__testis = islower(__c);
break;
case alpha:
__testis = isalpha(__c);
break;
case digit:
__testis = isdigit(__c);
break;
case punct:
__testis = ispunct(__c);
break;
case xdigit:
__testis = isxdigit(__c);
break;
case alnum:
__testis = isalnum(__c);
break;
case graph:
__testis = isgraph(__c);
break;
#ifdef _GLIBCXX_USE_C99_CTYPE_TR1
case blank:
__testis = isblank(__c);
break;
#endif
default:
__testis = false;
break;
}
__ret |= __testis;
}
}
return __ret;
}
}
const char*
ctype<char>::
is(const char* __low, const char* __high, mask* __vec) const
{
if (_M_table)
while (__low < __high)
*__vec++ = _M_table[static_cast<unsigned char>(*__low++)];
else
{
// Highest bitmask in ctype_base == 11.
const size_t __bitmasksize = 15;
for (;__low < __high; ++__vec, ++__low)
{
mask __m = 0;
// Lowest bitmask in ctype_base == 0
size_t __i = 0;
for (;__i <= __bitmasksize; ++__i)
{
const mask __bit = static_cast<mask>(1 << __i);
if (this->is(__bit, *__low))
__m |= __bit;
}
*__vec = __m;
}
}
return __high;
}
const char*
ctype<char>::
scan_is(mask __m, const char* __low, const char* __high) const
{
if (_M_table)
while (__low < __high
&& !(_M_table[static_cast<unsigned char>(*__low)] & __m))
++__low;
else
while (__low < __high && !this->is(__m, *__low))
++__low;
return __low;
}
const char*
ctype<char>::
scan_not(mask __m, const char* __low, const char* __high) const
{
if (_M_table)
while (__low < __high
&& (_M_table[static_cast<unsigned char>(*__low)] & __m) != 0)
++__low;
else
while (__low < __high && this->is(__m, *__low) != 0)
++__low;
return __low;
}
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
@@ -0,0 +1,60 @@
// cxxabi.h subset for cancellation -*- C++ -*-
// Copyright (C) 2007-2024 Free Software Foundation, Inc.
//
// This file is part of GCC.
//
// GCC is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3, or (at your option)
// any later version.
//
// GCC is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/cxxabi_forced.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{cxxabi.h}
*/
#ifndef _CXXABI_FORCED_H
#define _CXXABI_FORCED_H 1
#pragma GCC system_header
#pragma GCC visibility push(default)
#ifdef __cplusplus
namespace __cxxabiv1
{
/**
* @brief Thrown as part of forced unwinding.
* @ingroup exceptions
*
* A magic placeholder class that can be caught by reference to
* recognize forced unwinding.
*/
class __forced_unwind
{
virtual ~__forced_unwind() throw();
// Prevent catch by value.
virtual void __pure_dummy() = 0;
};
}
#endif // __cplusplus
#pragma GCC visibility pop
#endif // __CXXABI_FORCED_H
@@ -0,0 +1,81 @@
// ABI Support -*- C++ -*-
// Copyright (C) 2016-2024 Free Software Foundation, Inc.
//
// This file is part of GCC.
//
// GCC is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3, or (at your option)
// any later version.
//
// GCC is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/cxxabi_init_exception.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly.
*/
#ifndef _CXXABI_INIT_EXCEPTION_H
#define _CXXABI_INIT_EXCEPTION_H 1
#pragma GCC system_header
#pragma GCC visibility push(default)
#include <stddef.h>
#include <bits/c++config.h>
#ifndef _GLIBCXX_CDTOR_CALLABI
#define _GLIBCXX_CDTOR_CALLABI
#define _GLIBCXX_HAVE_CDTOR_CALLABI 0
#else
#define _GLIBCXX_HAVE_CDTOR_CALLABI 1
#endif
#ifdef __cplusplus
namespace std
{
class type_info;
}
namespace __cxxabiv1
{
struct __cxa_refcounted_exception;
extern "C"
{
// Allocate memory for the primary exception plus the thrown object.
void*
__cxa_allocate_exception(size_t) _GLIBCXX_NOTHROW;
void
__cxa_free_exception(void*) _GLIBCXX_NOTHROW;
// Initialize exception (this is a GNU extension)
__cxa_refcounted_exception*
__cxa_init_primary_exception(void *__object, std::type_info *__tinfo,
void (_GLIBCXX_CDTOR_CALLABI *__dest) (void *))
_GLIBCXX_NOTHROW;
}
} // namespace __cxxabiv1
#endif
#pragma GCC visibility pop
#endif // _CXXABI_INIT_EXCEPTION_H
@@ -0,0 +1,59 @@
// Control various target specific ABI tweaks. Generic version.
// Copyright (C) 2004-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/cxxabi_tweaks.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{cxxabi.h}
*/
#ifndef _CXXABI_TWEAKS_H
#define _CXXABI_TWEAKS_H 1
#ifdef __cplusplus
namespace __cxxabiv1
{
extern "C"
{
#endif
// The generic ABI uses the first byte of a 64-bit guard variable.
#define _GLIBCXX_GUARD_TEST(x) (*(char *) (x) != 0)
#define _GLIBCXX_GUARD_SET(x) *(char *) (x) = 1
#define _GLIBCXX_GUARD_BIT __guard_test_bit (0, 1)
#define _GLIBCXX_GUARD_PENDING_BIT __guard_test_bit (1, 1)
#define _GLIBCXX_GUARD_WAITING_BIT __guard_test_bit (2, 1)
__extension__ typedef int __guard __attribute__((mode (__DI__)));
// __cxa_vec_ctor has void return type.
typedef void __cxa_vec_ctor_return_type;
#define _GLIBCXX_CXA_VEC_CTOR_RETURN(x) return
// Constructors and destructors do not return a value.
typedef void __cxa_cdtor_return_type;
#ifdef __cplusplus
}
} // namespace __cxxabiv1
#endif
#endif
@@ -0,0 +1,72 @@
// Tag type for yielding ranges rather than values in <generator> -*- C++ -*-
// Copyright (C) 2023-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
#ifndef _GLIBCXX_BITS_ELEMENTS_OF
#define _GLIBCXX_BITS_ELEMENTS_OF
#pragma GCC system_header
#include <bits/c++config.h>
#include <bits/version.h>
// C++ >= 23 && __glibcxx_coroutine
#if defined(__glibcxx_ranges) && defined(__glibcxx_generator)
#include <bits/ranges_base.h>
#include <bits/memoryfwd.h>
#if _GLIBCXX_HOSTED
# include <bits/allocator.h> // likely desirable if hosted.
#endif // HOSTED
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
namespace ranges
{
/**
* @ingroup ranges
* @since C++23
* @{
*/
template<range _Range, typename _Alloc = allocator<byte>>
struct elements_of
{
[[no_unique_address]] _Range range;
[[no_unique_address]] _Alloc allocator = _Alloc();
};
template<typename _Range, typename _Alloc = allocator<byte>>
elements_of(_Range&&, _Alloc = _Alloc())
-> elements_of<_Range&&, _Alloc>;
/// @}
}
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif // __glibcxx_generator && __glibcxx_ranges
#endif // _GLIBCXX_BITS_ELEMENTS_OF
@@ -0,0 +1,316 @@
// <bits/enable_special_members.h> -*- C++ -*-
// Copyright (C) 2013-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/enable_special_members.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly.
*/
#ifndef _ENABLE_SPECIAL_MEMBERS_H
#define _ENABLE_SPECIAL_MEMBERS_H 1
#pragma GCC system_header
#include <bits/c++config.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/// @cond undocumented
struct _Enable_default_constructor_tag
{
explicit constexpr _Enable_default_constructor_tag() = default;
};
/**
* @brief A mixin helper to conditionally enable or disable the default
* constructor.
* @sa _Enable_special_members
*/
template<bool _Switch, typename _Tag = void>
struct _Enable_default_constructor
{
constexpr _Enable_default_constructor() noexcept = default;
constexpr _Enable_default_constructor(_Enable_default_constructor const&)
noexcept = default;
constexpr _Enable_default_constructor(_Enable_default_constructor&&)
noexcept = default;
_Enable_default_constructor&
operator=(_Enable_default_constructor const&) noexcept = default;
_Enable_default_constructor&
operator=(_Enable_default_constructor&&) noexcept = default;
// Can be used in other ctors.
constexpr explicit
_Enable_default_constructor(_Enable_default_constructor_tag) { }
};
/**
* @brief A mixin helper to conditionally enable or disable the default
* destructor.
* @sa _Enable_special_members
*/
template<bool _Switch, typename _Tag = void>
struct _Enable_destructor { };
/**
* @brief A mixin helper to conditionally enable or disable the copy/move
* special members.
* @sa _Enable_special_members
*/
template<bool _Copy, bool _CopyAssignment,
bool _Move, bool _MoveAssignment,
typename _Tag = void>
struct _Enable_copy_move { };
/**
* @brief A mixin helper to conditionally enable or disable the special
* members.
*
* The @c _Tag type parameter is to make mixin bases unique and thus avoid
* ambiguities.
*/
template<bool _Default, bool _Destructor,
bool _Copy, bool _CopyAssignment,
bool _Move, bool _MoveAssignment,
typename _Tag = void>
struct _Enable_special_members
: private _Enable_default_constructor<_Default, _Tag>,
private _Enable_destructor<_Destructor, _Tag>,
private _Enable_copy_move<_Copy, _CopyAssignment,
_Move, _MoveAssignment,
_Tag>
{ };
// Boilerplate follows.
template<typename _Tag>
struct _Enable_default_constructor<false, _Tag>
{
constexpr _Enable_default_constructor() noexcept = delete;
constexpr _Enable_default_constructor(_Enable_default_constructor const&)
noexcept = default;
constexpr _Enable_default_constructor(_Enable_default_constructor&&)
noexcept = default;
_Enable_default_constructor&
operator=(_Enable_default_constructor const&) noexcept = default;
_Enable_default_constructor&
operator=(_Enable_default_constructor&&) noexcept = default;
// Can be used in other ctors.
constexpr explicit
_Enable_default_constructor(_Enable_default_constructor_tag) { }
};
template<typename _Tag>
struct _Enable_destructor<false, _Tag>
{ ~_Enable_destructor() noexcept = delete; };
template<typename _Tag>
struct _Enable_copy_move<false, true, true, true, _Tag>
{
constexpr _Enable_copy_move() noexcept = default;
constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = delete;
constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = default;
_Enable_copy_move&
operator=(_Enable_copy_move const&) noexcept = default;
_Enable_copy_move&
operator=(_Enable_copy_move&&) noexcept = default;
};
template<typename _Tag>
struct _Enable_copy_move<true, false, true, true, _Tag>
{
constexpr _Enable_copy_move() noexcept = default;
constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = default;
constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = default;
_Enable_copy_move&
operator=(_Enable_copy_move const&) noexcept = delete;
_Enable_copy_move&
operator=(_Enable_copy_move&&) noexcept = default;
};
template<typename _Tag>
struct _Enable_copy_move<false, false, true, true, _Tag>
{
constexpr _Enable_copy_move() noexcept = default;
constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = delete;
constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = default;
_Enable_copy_move&
operator=(_Enable_copy_move const&) noexcept = delete;
_Enable_copy_move&
operator=(_Enable_copy_move&&) noexcept = default;
};
template<typename _Tag>
struct _Enable_copy_move<true, true, false, true, _Tag>
{
constexpr _Enable_copy_move() noexcept = default;
constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = default;
constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = delete;
_Enable_copy_move&
operator=(_Enable_copy_move const&) noexcept = default;
_Enable_copy_move&
operator=(_Enable_copy_move&&) noexcept = default;
};
template<typename _Tag>
struct _Enable_copy_move<false, true, false, true, _Tag>
{
constexpr _Enable_copy_move() noexcept = default;
constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = delete;
constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = delete;
_Enable_copy_move&
operator=(_Enable_copy_move const&) noexcept = default;
_Enable_copy_move&
operator=(_Enable_copy_move&&) noexcept = default;
};
template<typename _Tag>
struct _Enable_copy_move<true, false, false, true, _Tag>
{
constexpr _Enable_copy_move() noexcept = default;
constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = default;
constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = delete;
_Enable_copy_move&
operator=(_Enable_copy_move const&) noexcept = delete;
_Enable_copy_move&
operator=(_Enable_copy_move&&) noexcept = default;
};
template<typename _Tag>
struct _Enable_copy_move<false, false, false, true, _Tag>
{
constexpr _Enable_copy_move() noexcept = default;
constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = delete;
constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = delete;
_Enable_copy_move&
operator=(_Enable_copy_move const&) noexcept = delete;
_Enable_copy_move&
operator=(_Enable_copy_move&&) noexcept = default;
};
template<typename _Tag>
struct _Enable_copy_move<true, true, true, false, _Tag>
{
constexpr _Enable_copy_move() noexcept = default;
constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = default;
constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = default;
_Enable_copy_move&
operator=(_Enable_copy_move const&) noexcept = default;
_Enable_copy_move&
operator=(_Enable_copy_move&&) noexcept = delete;
};
template<typename _Tag>
struct _Enable_copy_move<false, true, true, false, _Tag>
{
constexpr _Enable_copy_move() noexcept = default;
constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = delete;
constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = default;
_Enable_copy_move&
operator=(_Enable_copy_move const&) noexcept = default;
_Enable_copy_move&
operator=(_Enable_copy_move&&) noexcept = delete;
};
template<typename _Tag>
struct _Enable_copy_move<true, false, true, false, _Tag>
{
constexpr _Enable_copy_move() noexcept = default;
constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = default;
constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = default;
_Enable_copy_move&
operator=(_Enable_copy_move const&) noexcept = delete;
_Enable_copy_move&
operator=(_Enable_copy_move&&) noexcept = delete;
};
template<typename _Tag>
struct _Enable_copy_move<false, false, true, false, _Tag>
{
constexpr _Enable_copy_move() noexcept = default;
constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = delete;
constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = default;
_Enable_copy_move&
operator=(_Enable_copy_move const&) noexcept = delete;
_Enable_copy_move&
operator=(_Enable_copy_move&&) noexcept = delete;
};
template<typename _Tag>
struct _Enable_copy_move<true, true, false, false, _Tag>
{
constexpr _Enable_copy_move() noexcept = default;
constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = default;
constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = delete;
_Enable_copy_move&
operator=(_Enable_copy_move const&) noexcept = default;
_Enable_copy_move&
operator=(_Enable_copy_move&&) noexcept = delete;
};
template<typename _Tag>
struct _Enable_copy_move<false, true, false, false, _Tag>
{
constexpr _Enable_copy_move() noexcept = default;
constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = delete;
constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = delete;
_Enable_copy_move&
operator=(_Enable_copy_move const&) noexcept = default;
_Enable_copy_move&
operator=(_Enable_copy_move&&) noexcept = delete;
};
template<typename _Tag>
struct _Enable_copy_move<true, false, false, false, _Tag>
{
constexpr _Enable_copy_move() noexcept = default;
constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = default;
constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = delete;
_Enable_copy_move&
operator=(_Enable_copy_move const&) noexcept = delete;
_Enable_copy_move&
operator=(_Enable_copy_move&&) noexcept = delete;
};
template<typename _Tag>
struct _Enable_copy_move<false, false, false, false, _Tag>
{
constexpr _Enable_copy_move() noexcept = default;
constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = delete;
constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = delete;
_Enable_copy_move&
operator=(_Enable_copy_move const&) noexcept = delete;
_Enable_copy_move&
operator=(_Enable_copy_move&&) noexcept = delete;
};
/// @endcond
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif // _ENABLE_SPECIAL_MEMBERS_H
@@ -0,0 +1,180 @@
// Specific definitions for generic platforms -*- C++ -*-
// Copyright (C) 2007-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/error_constants.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{system_error}
*/
#ifndef _GLIBCXX_ERROR_CONSTANTS
#define _GLIBCXX_ERROR_CONSTANTS 1
#include <bits/c++config.h>
#include <cerrno>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
enum class errc
{
address_family_not_supported = EAFNOSUPPORT,
address_in_use = EADDRINUSE,
address_not_available = EADDRNOTAVAIL,
already_connected = EISCONN,
argument_list_too_long = E2BIG,
argument_out_of_domain = EDOM,
bad_address = EFAULT,
bad_file_descriptor = EBADF,
#ifdef EBADMSG
bad_message = EBADMSG,
#endif
broken_pipe = EPIPE,
connection_aborted = ECONNABORTED,
connection_already_in_progress = EALREADY,
connection_refused = ECONNREFUSED,
connection_reset = ECONNRESET,
cross_device_link = EXDEV,
destination_address_required = EDESTADDRREQ,
device_or_resource_busy = EBUSY,
directory_not_empty = ENOTEMPTY,
executable_format_error = ENOEXEC,
file_exists = EEXIST,
file_too_large = EFBIG,
filename_too_long = ENAMETOOLONG,
function_not_supported = ENOSYS,
host_unreachable = EHOSTUNREACH,
#ifdef EIDRM
identifier_removed = EIDRM,
#endif
illegal_byte_sequence = EILSEQ,
inappropriate_io_control_operation = ENOTTY,
interrupted = EINTR,
invalid_argument = EINVAL,
invalid_seek = ESPIPE,
io_error = EIO,
is_a_directory = EISDIR,
message_size = EMSGSIZE,
network_down = ENETDOWN,
network_reset = ENETRESET,
network_unreachable = ENETUNREACH,
no_buffer_space = ENOBUFS,
no_child_process = ECHILD,
#ifdef ENOLINK
no_link = ENOLINK,
#endif
no_lock_available = ENOLCK,
#ifdef ENODATA
no_message_available = ENODATA,
#endif
no_message = ENOMSG,
no_protocol_option = ENOPROTOOPT,
no_space_on_device = ENOSPC,
#ifdef ENOSR
no_stream_resources = ENOSR,
#endif
no_such_device_or_address = ENXIO,
no_such_device = ENODEV,
no_such_file_or_directory = ENOENT,
no_such_process = ESRCH,
not_a_directory = ENOTDIR,
not_a_socket = ENOTSOCK,
#ifdef ENOSTR
not_a_stream = ENOSTR,
#endif
not_connected = ENOTCONN,
not_enough_memory = ENOMEM,
#ifdef ENOTSUP
not_supported = ENOTSUP,
#endif
#ifdef ECANCELED
operation_canceled = ECANCELED,
#endif
operation_in_progress = EINPROGRESS,
operation_not_permitted = EPERM,
operation_not_supported = EOPNOTSUPP,
operation_would_block = EWOULDBLOCK,
#ifdef EOWNERDEAD
owner_dead = EOWNERDEAD,
#endif
permission_denied = EACCES,
#ifdef EPROTO
protocol_error = EPROTO,
#endif
protocol_not_supported = EPROTONOSUPPORT,
read_only_file_system = EROFS,
resource_deadlock_would_occur = EDEADLK,
resource_unavailable_try_again = EAGAIN,
result_out_of_range = ERANGE,
#ifdef ENOTRECOVERABLE
state_not_recoverable = ENOTRECOVERABLE,
#endif
#ifdef ETIME
stream_timeout = ETIME,
#endif
#ifdef ETXTBSY
text_file_busy = ETXTBSY,
#endif
timed_out = ETIMEDOUT,
too_many_files_open_in_system = ENFILE,
too_many_files_open = EMFILE,
too_many_links = EMLINK,
too_many_symbolic_link_levels = ELOOP,
#ifdef EOVERFLOW
value_too_large = EOVERFLOW,
#elif defined __AVR__
value_too_large = 999,
#endif
wrong_protocol_type = EPROTOTYPE
};
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif
+83
View File
@@ -0,0 +1,83 @@
// Exception Handling support header for -*- C++ -*-
// Copyright (C) 2016-2024 Free Software Foundation, Inc.
//
// This file is part of GCC.
//
// GCC is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3, or (at your option)
// any later version.
//
// GCC is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/exception.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly.
*/
#ifndef __EXCEPTION_H
#define __EXCEPTION_H 1
#pragma GCC system_header
#include <bits/c++config.h>
extern "C++" {
namespace std _GLIBCXX_VISIBILITY(default)
{
/**
* @defgroup exceptions Exceptions
* @ingroup diagnostics
* @since C++98
*
* Classes and functions for reporting errors via exceptions.
* @{
*/
/**
* @brief Base class for all library exceptions.
*
* This is the base class for all exceptions thrown by the standard
* library, and by certain language expressions. You are free to derive
* your own %exception classes, or use a different hierarchy, or to
* throw non-class data (e.g., fundamental types).
*/
class exception
{
public:
exception() _GLIBCXX_NOTHROW { }
virtual ~exception() _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_NOTHROW;
#if __cplusplus >= 201103L
exception(const exception&) = default;
exception& operator=(const exception&) = default;
exception(exception&&) = default;
exception& operator=(exception&&) = default;
#endif
/** Returns a C-style character string describing the general cause
* of the current error. */
virtual const char*
what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_NOTHROW;
};
/// @}
} // namespace std
}
#endif
@@ -0,0 +1,45 @@
// -fno-exceptions Support -*- C++ -*-
// Copyright (C) 2001-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/exception_defines.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{exception}
*/
#ifndef _EXCEPTION_DEFINES_H
#define _EXCEPTION_DEFINES_H 1
#if ! __cpp_exceptions
// Iff -fno-exceptions, transform error handling code to work without it.
# define __try if (true)
# define __catch(X) if (false)
# define __throw_exception_again
#else
// Else proceed normally.
# define __try try
# define __catch(X) catch(X)
# define __throw_exception_again throw
#endif
#endif
@@ -0,0 +1,295 @@
// Exception Handling support header (exception_ptr class) for -*- C++ -*-
// Copyright (C) 2008-2024 Free Software Foundation, Inc.
//
// This file is part of GCC.
//
// GCC is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3, or (at your option)
// any later version.
//
// GCC is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/exception_ptr.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{exception}
*/
#ifndef _EXCEPTION_PTR_H
#define _EXCEPTION_PTR_H
#include <bits/c++config.h>
#include <bits/exception_defines.h>
#include <bits/cxxabi_init_exception.h>
#include <typeinfo>
#include <new>
#if __cplusplus >= 201103L
# include <bits/move.h>
#endif
#ifdef _GLIBCXX_EH_PTR_RELOPS_COMPAT
# define _GLIBCXX_EH_PTR_USED __attribute__((__used__))
#else
# define _GLIBCXX_EH_PTR_USED
#endif
extern "C++" {
namespace std _GLIBCXX_VISIBILITY(default)
{
class type_info;
/**
* @addtogroup exceptions
* @{
*/
namespace __exception_ptr
{
class exception_ptr;
}
using __exception_ptr::exception_ptr;
/** Obtain an exception_ptr to the currently handled exception.
*
* If there is none, or the currently handled exception is foreign,
* return the null value.
*
* @since C++11
*/
exception_ptr current_exception() _GLIBCXX_USE_NOEXCEPT;
template<typename _Ex>
exception_ptr make_exception_ptr(_Ex) _GLIBCXX_USE_NOEXCEPT;
/// Throw the object pointed to by the exception_ptr.
void rethrow_exception(exception_ptr) __attribute__ ((__noreturn__));
namespace __exception_ptr
{
using std::rethrow_exception; // So that ADL finds it.
/**
* @brief An opaque pointer to an arbitrary exception.
*
* The actual name of this type is unspecified, so the alias
* `std::exception_ptr` should be used to refer to it.
*
* @headerfile exception
* @since C++11 (but usable in C++98 as a GCC extension)
* @ingroup exceptions
*/
class exception_ptr
{
void* _M_exception_object;
explicit exception_ptr(void* __e) _GLIBCXX_USE_NOEXCEPT;
void _M_addref() _GLIBCXX_USE_NOEXCEPT;
void _M_release() _GLIBCXX_USE_NOEXCEPT;
void *_M_get() const _GLIBCXX_NOEXCEPT __attribute__ ((__pure__));
friend exception_ptr std::current_exception() _GLIBCXX_USE_NOEXCEPT;
friend void std::rethrow_exception(exception_ptr);
template<typename _Ex>
friend exception_ptr std::make_exception_ptr(_Ex) _GLIBCXX_USE_NOEXCEPT;
public:
exception_ptr() _GLIBCXX_USE_NOEXCEPT;
exception_ptr(const exception_ptr&) _GLIBCXX_USE_NOEXCEPT;
#if __cplusplus >= 201103L
exception_ptr(nullptr_t) noexcept
: _M_exception_object(nullptr)
{ }
exception_ptr(exception_ptr&& __o) noexcept
: _M_exception_object(__o._M_exception_object)
{ __o._M_exception_object = nullptr; }
#endif
#if (__cplusplus < 201103L) || defined (_GLIBCXX_EH_PTR_COMPAT)
typedef void (exception_ptr::*__safe_bool)();
// For construction from nullptr or 0.
exception_ptr(__safe_bool) _GLIBCXX_USE_NOEXCEPT;
#endif
exception_ptr&
operator=(const exception_ptr&) _GLIBCXX_USE_NOEXCEPT;
#if __cplusplus >= 201103L
exception_ptr&
operator=(exception_ptr&& __o) noexcept
{
exception_ptr(static_cast<exception_ptr&&>(__o)).swap(*this);
return *this;
}
#endif
~exception_ptr() _GLIBCXX_USE_NOEXCEPT;
void
swap(exception_ptr&) _GLIBCXX_USE_NOEXCEPT;
#ifdef _GLIBCXX_EH_PTR_COMPAT
// Retained for compatibility with CXXABI_1.3.
void _M_safe_bool_dummy() _GLIBCXX_USE_NOEXCEPT
__attribute__ ((__const__));
bool operator!() const _GLIBCXX_USE_NOEXCEPT
__attribute__ ((__pure__));
operator __safe_bool() const _GLIBCXX_USE_NOEXCEPT;
#endif
#if __cplusplus >= 201103L
explicit operator bool() const noexcept
{ return _M_exception_object; }
#endif
#if __cpp_impl_three_way_comparison >= 201907L \
&& ! defined _GLIBCXX_EH_PTR_RELOPS_COMPAT
friend bool
operator==(const exception_ptr&, const exception_ptr&) noexcept = default;
#else
friend _GLIBCXX_EH_PTR_USED bool
operator==(const exception_ptr& __x, const exception_ptr& __y)
_GLIBCXX_USE_NOEXCEPT
{ return __x._M_exception_object == __y._M_exception_object; }
friend _GLIBCXX_EH_PTR_USED bool
operator!=(const exception_ptr& __x, const exception_ptr& __y)
_GLIBCXX_USE_NOEXCEPT
{ return __x._M_exception_object != __y._M_exception_object; }
#endif
const class std::type_info*
__cxa_exception_type() const _GLIBCXX_USE_NOEXCEPT
__attribute__ ((__pure__));
};
_GLIBCXX_EH_PTR_USED
inline
exception_ptr::exception_ptr() _GLIBCXX_USE_NOEXCEPT
: _M_exception_object(0)
{ }
_GLIBCXX_EH_PTR_USED
inline
exception_ptr::exception_ptr(const exception_ptr& __other)
_GLIBCXX_USE_NOEXCEPT
: _M_exception_object(__other._M_exception_object)
{
if (_M_exception_object)
_M_addref();
}
_GLIBCXX_EH_PTR_USED
inline
exception_ptr::~exception_ptr() _GLIBCXX_USE_NOEXCEPT
{
if (_M_exception_object)
_M_release();
}
_GLIBCXX_EH_PTR_USED
inline exception_ptr&
exception_ptr::operator=(const exception_ptr& __other) _GLIBCXX_USE_NOEXCEPT
{
exception_ptr(__other).swap(*this);
return *this;
}
_GLIBCXX_EH_PTR_USED
inline void
exception_ptr::swap(exception_ptr &__other) _GLIBCXX_USE_NOEXCEPT
{
void *__tmp = _M_exception_object;
_M_exception_object = __other._M_exception_object;
__other._M_exception_object = __tmp;
}
/// @relates exception_ptr
inline void
swap(exception_ptr& __lhs, exception_ptr& __rhs)
{ __lhs.swap(__rhs); }
/// @cond undocumented
template<typename _Ex>
_GLIBCXX_CDTOR_CALLABI
inline void
__dest_thunk(void* __x)
{ static_cast<_Ex*>(__x)->~_Ex(); }
/// @endcond
} // namespace __exception_ptr
using __exception_ptr::swap; // So that std::swap(exp1, exp2) finds it.
/// Obtain an exception_ptr pointing to a copy of the supplied object.
#if (__cplusplus >= 201103L && __cpp_rtti) || __cpp_exceptions
template<typename _Ex>
exception_ptr
make_exception_ptr(_Ex __ex) _GLIBCXX_USE_NOEXCEPT
{
#if __cplusplus >= 201103L && __cpp_rtti
using _Ex2 = typename decay<_Ex>::type;
void* __e = __cxxabiv1::__cxa_allocate_exception(sizeof(_Ex));
(void) __cxxabiv1::__cxa_init_primary_exception(
__e, const_cast<std::type_info*>(&typeid(_Ex)),
__exception_ptr::__dest_thunk<_Ex2>);
__try
{
::new (__e) _Ex2(__ex);
return exception_ptr(__e);
}
__catch(...)
{
__cxxabiv1::__cxa_free_exception(__e);
return current_exception();
}
#else
try
{
throw __ex;
}
catch(...)
{
return current_exception();
}
#endif
}
#else // no RTTI and no exceptions
// This is always_inline so the linker will never use this useless definition
// instead of a working one compiled with RTTI and/or exceptions enabled.
template<typename _Ex>
__attribute__ ((__always_inline__))
inline exception_ptr
make_exception_ptr(_Ex) _GLIBCXX_USE_NOEXCEPT
{ return exception_ptr(); }
#endif
#undef _GLIBCXX_EH_PTR_USED
/// @} group exceptions
} // namespace std
} // extern "C++"
#endif
+86
View File
@@ -0,0 +1,86 @@
// C++ includes used for precompiling extensions -*- C++ -*-
// Copyright (C) 2006-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file extc++.h
* This is an implementation file for a precompiled header.
*/
#if __cplusplus < 201103L
#include <bits/stdtr1c++.h>
#else
#include <bits/stdc++.h>
#endif
#if __cplusplus >= 201103L
# include <ext/aligned_buffer.h>
#endif
#include <ext/alloc_traits.h>
#include <ext/atomicity.h>
#include <ext/cast.h>
#include <ext/iterator>
#include <ext/numeric_traits.h>
#include <ext/pointer.h>
#include <ext/typelist.h>
#include <ext/type_traits.h>
#if _GLIBCXX_HOSTED
#include <ext/algorithm>
#include <ext/bitmap_allocator.h>
#if __cplusplus >= 201103L
# include <ext/cmath>
#endif
#include <ext/concurrence.h>
#include <ext/debug_allocator.h>
#include <ext/extptr_allocator.h>
#include <ext/functional>
#include <ext/malloc_allocator.h>
#include <ext/memory>
#include <ext/mt_allocator.h>
#include <ext/new_allocator.h>
#include <ext/numeric>
#include <ext/pod_char_traits.h>
#include <ext/pool_allocator.h>
#if __cplusplus >= 201103L
# include <ext/random>
#endif
#include <ext/rb_tree>
#include <ext/rope>
#include <ext/slist>
#include <ext/stdio_filebuf.h>
#include <ext/stdio_sync_filebuf.h>
#include <ext/throw_allocator.h>
#include <ext/vstring.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/priority_queue.hpp>
#include <ext/pb_ds/exception.hpp>
#include <ext/pb_ds/hash_policy.hpp>
#include <ext/pb_ds/list_update_policy.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/trie_policy.hpp>
#ifdef _GLIBCXX_HAVE_ICONV
#include <ext/codecvt_specializations.h>
#include <ext/enc_filebuf.h>
#endif
#endif // HOSTED
+143
View File
@@ -0,0 +1,143 @@
// Function-Based Exception Support -*- C++ -*-
// Copyright (C) 2001-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/functexcept.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{exception}
*
* This header provides support for -fno-exceptions.
*/
//
// ISO C++ 14882: 19.1 Exception classes
//
#ifndef _FUNCTEXCEPT_H
#define _FUNCTEXCEPT_H 1
#include <bits/c++config.h>
#include <bits/exception_defines.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
#if _GLIBCXX_HOSTED
// Helper for exception objects in <except>
void
__throw_bad_exception(void) __attribute__((__noreturn__));
// Helper for exception objects in <new>
void
__throw_bad_alloc(void) __attribute__((__noreturn__));
void
__throw_bad_array_new_length(void) __attribute__((__noreturn__));
// Helper for exception objects in <typeinfo>
void
__throw_bad_cast(void) __attribute__((__noreturn__,__cold__));
void
__throw_bad_typeid(void) __attribute__((__noreturn__,__cold__));
// Helpers for exception objects in <stdexcept>
void
__throw_logic_error(const char*) __attribute__((__noreturn__,__cold__));
void
__throw_domain_error(const char*) __attribute__((__noreturn__,__cold__));
void
__throw_invalid_argument(const char*) __attribute__((__noreturn__,__cold__));
void
__throw_length_error(const char*) __attribute__((__noreturn__,__cold__));
void
__throw_out_of_range(const char*) __attribute__((__noreturn__,__cold__));
void
__throw_out_of_range_fmt(const char*, ...) __attribute__((__noreturn__,__cold__))
__attribute__((__format__(__gnu_printf__, 1, 2)));
void
__throw_runtime_error(const char*) __attribute__((__noreturn__,__cold__));
void
__throw_range_error(const char*) __attribute__((__noreturn__,__cold__));
void
__throw_overflow_error(const char*) __attribute__((__noreturn__,__cold__));
void
__throw_underflow_error(const char*) __attribute__((__noreturn__,__cold__));
// Helpers for exception objects in <ios>
void
__throw_ios_failure(const char*) __attribute__((__noreturn__,__cold__));
void
__throw_ios_failure(const char*, int) __attribute__((__noreturn__,__cold__));
// Helpers for exception objects in <system_error>
void
__throw_system_error(int) __attribute__((__noreturn__,__cold__));
// Helpers for exception objects in <future>
void
__throw_future_error(int) __attribute__((__noreturn__,__cold__));
// Helpers for exception objects in <functional>
void
__throw_bad_function_call() __attribute__((__noreturn__,__cold__));
#else // ! HOSTED
__attribute__((__noreturn__)) inline void
__throw_invalid_argument(const char*)
{ std::__terminate(); }
__attribute__((__noreturn__)) inline void
__throw_out_of_range(const char*)
{ std::__terminate(); }
__attribute__((__noreturn__)) inline void
__throw_out_of_range_fmt(const char*, ...)
{ std::__terminate(); }
__attribute__((__noreturn__)) inline void
__throw_runtime_error(const char*)
{ std::__terminate(); }
__attribute__((__noreturn__)) inline void
__throw_overflow_error(const char*)
{ std::__terminate(); }
#endif // HOSTED
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif
@@ -0,0 +1,305 @@
// functional_hash.h header -*- C++ -*-
// Copyright (C) 2007-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/functional_hash.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{functional}
*/
#ifndef _FUNCTIONAL_HASH_H
#define _FUNCTIONAL_HASH_H 1
#pragma GCC system_header
#include <type_traits>
#include <bits/hash_bytes.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/** @defgroup hashes Hashes
* @ingroup functors
*
* Hashing functors taking a variable type and returning a @c std::size_t.
*
* @{
*/
template<typename _Result, typename _Arg>
struct __hash_base
{
typedef _Result result_type _GLIBCXX17_DEPRECATED;
typedef _Arg argument_type _GLIBCXX17_DEPRECATED;
};
/// Primary class template hash.
template<typename _Tp>
struct hash;
template<typename _Tp, typename = void>
struct __poison_hash
{
static constexpr bool __enable_hash_call = false;
private:
// Private rather than deleted to be non-trivially-copyable.
__poison_hash(__poison_hash&&);
~__poison_hash();
};
template<typename _Tp>
struct __poison_hash<_Tp, __void_t<decltype(hash<_Tp>()(declval<_Tp>()))>>
{
static constexpr bool __enable_hash_call = true;
};
// Helper struct for SFINAE-poisoning non-enum types.
template<typename _Tp, bool = is_enum<_Tp>::value>
struct __hash_enum
{
private:
// Private rather than deleted to be non-trivially-copyable.
__hash_enum(__hash_enum&&);
~__hash_enum();
};
// Helper struct for hash with enum types.
template<typename _Tp>
struct __hash_enum<_Tp, true> : public __hash_base<size_t, _Tp>
{
size_t
operator()(_Tp __val) const noexcept
{
using __type = typename underlying_type<_Tp>::type;
return hash<__type>{}(static_cast<__type>(__val));
}
};
/// Primary class template hash, usable for enum types only.
// Use with non-enum types still SFINAES.
template<typename _Tp>
struct hash : __hash_enum<_Tp>
{ };
/// Partial specializations for pointer types.
template<typename _Tp>
struct hash<_Tp*> : public __hash_base<size_t, _Tp*>
{
size_t
operator()(_Tp* __p) const noexcept
{ return reinterpret_cast<size_t>(__p); }
};
// Explicit specializations for integer types.
#define _Cxx_hashtable_define_trivial_hash(_Tp) \
template<> \
struct hash<_Tp> : public __hash_base<size_t, _Tp> \
{ \
size_t \
operator()(_Tp __val) const noexcept \
{ return static_cast<size_t>(__val); } \
};
/// Explicit specialization for bool.
_Cxx_hashtable_define_trivial_hash(bool)
/// Explicit specialization for char.
_Cxx_hashtable_define_trivial_hash(char)
/// Explicit specialization for signed char.
_Cxx_hashtable_define_trivial_hash(signed char)
/// Explicit specialization for unsigned char.
_Cxx_hashtable_define_trivial_hash(unsigned char)
/// Explicit specialization for wchar_t.
_Cxx_hashtable_define_trivial_hash(wchar_t)
#ifdef _GLIBCXX_USE_CHAR8_T
/// Explicit specialization for char8_t.
_Cxx_hashtable_define_trivial_hash(char8_t)
#endif
/// Explicit specialization for char16_t.
_Cxx_hashtable_define_trivial_hash(char16_t)
/// Explicit specialization for char32_t.
_Cxx_hashtable_define_trivial_hash(char32_t)
/// Explicit specialization for short.
_Cxx_hashtable_define_trivial_hash(short)
/// Explicit specialization for int.
_Cxx_hashtable_define_trivial_hash(int)
/// Explicit specialization for long.
_Cxx_hashtable_define_trivial_hash(long)
/// Explicit specialization for long long.
_Cxx_hashtable_define_trivial_hash(long long)
/// Explicit specialization for unsigned short.
_Cxx_hashtable_define_trivial_hash(unsigned short)
/// Explicit specialization for unsigned int.
_Cxx_hashtable_define_trivial_hash(unsigned int)
/// Explicit specialization for unsigned long.
_Cxx_hashtable_define_trivial_hash(unsigned long)
/// Explicit specialization for unsigned long long.
_Cxx_hashtable_define_trivial_hash(unsigned long long)
#ifdef __GLIBCXX_TYPE_INT_N_0
__extension__
_Cxx_hashtable_define_trivial_hash(__GLIBCXX_TYPE_INT_N_0)
__extension__
_Cxx_hashtable_define_trivial_hash(__GLIBCXX_TYPE_INT_N_0 unsigned)
#endif
#ifdef __GLIBCXX_TYPE_INT_N_1
__extension__
_Cxx_hashtable_define_trivial_hash(__GLIBCXX_TYPE_INT_N_1)
__extension__
_Cxx_hashtable_define_trivial_hash(__GLIBCXX_TYPE_INT_N_1 unsigned)
#endif
#ifdef __GLIBCXX_TYPE_INT_N_2
__extension__
_Cxx_hashtable_define_trivial_hash(__GLIBCXX_TYPE_INT_N_2)
__extension__
_Cxx_hashtable_define_trivial_hash(__GLIBCXX_TYPE_INT_N_2 unsigned)
#endif
#ifdef __GLIBCXX_TYPE_INT_N_3
__extension__
_Cxx_hashtable_define_trivial_hash(__GLIBCXX_TYPE_INT_N_3)
__extension__
_Cxx_hashtable_define_trivial_hash(__GLIBCXX_TYPE_INT_N_3 unsigned)
#endif
#undef _Cxx_hashtable_define_trivial_hash
struct _Hash_impl
{
static size_t
hash(const void* __ptr, size_t __clength,
size_t __seed = static_cast<size_t>(0xc70f6907UL))
{ return _Hash_bytes(__ptr, __clength, __seed); }
template<typename _Tp>
static size_t
hash(const _Tp& __val)
{ return hash(&__val, sizeof(__val)); }
template<typename _Tp>
static size_t
__hash_combine(const _Tp& __val, size_t __hash)
{ return hash(&__val, sizeof(__val), __hash); }
};
// A hash function similar to FNV-1a (see PR59406 for how it differs).
struct _Fnv_hash_impl
{
static size_t
hash(const void* __ptr, size_t __clength,
size_t __seed = static_cast<size_t>(2166136261UL))
{ return _Fnv_hash_bytes(__ptr, __clength, __seed); }
template<typename _Tp>
static size_t
hash(const _Tp& __val)
{ return hash(&__val, sizeof(__val)); }
template<typename _Tp>
static size_t
__hash_combine(const _Tp& __val, size_t __hash)
{ return hash(&__val, sizeof(__val), __hash); }
};
/// Specialization for float.
template<>
struct hash<float> : public __hash_base<size_t, float>
{
size_t
operator()(float __val) const noexcept
{
// 0 and -0 both hash to zero.
return __val != 0.0f ? std::_Hash_impl::hash(__val) : 0;
}
};
/// Specialization for double.
template<>
struct hash<double> : public __hash_base<size_t, double>
{
size_t
operator()(double __val) const noexcept
{
// 0 and -0 both hash to zero.
return __val != 0.0 ? std::_Hash_impl::hash(__val) : 0;
}
};
/// Specialization for long double.
template<>
struct hash<long double>
: public __hash_base<size_t, long double>
{
_GLIBCXX_PURE size_t
operator()(long double __val) const noexcept;
};
#if __cplusplus >= 201703L
template<>
struct hash<nullptr_t> : public __hash_base<size_t, nullptr_t>
{
size_t
operator()(nullptr_t) const noexcept
{ return 0; }
};
#endif
/// @} group hashes
/** Hint about performance of hash functions.
*
* If a given hash function object is not fast, the hash-based containers
* will cache the hash code.
* The default behavior is to consider that hashers are fast unless specified
* otherwise.
*
* Users can specialize this for their own hash functions in order to force
* caching of hash codes in unordered containers. Specializing this trait
* affects the ABI of the unordered containers, so use it carefully.
*/
template<typename _Hash>
struct __is_fast_hash : public std::true_type
{ };
template<>
struct __is_fast_hash<hash<long double>> : public std::false_type
{ };
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif // _FUNCTIONAL_HASH_H
@@ -0,0 +1,298 @@
/* Threads compatibility routines for libgcc2 and libobjc. */
/* Compile this one with gcc. */
/* Copyright (C) 1997-2024 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
#ifndef _GLIBCXX_GCC_GTHR_SINGLE_H
#define _GLIBCXX_GCC_GTHR_SINGLE_H
/* Just provide compatibility for mutex handling. */
typedef int __gthread_key_t;
typedef int __gthread_once_t;
typedef int __gthread_mutex_t;
typedef int __gthread_recursive_mutex_t;
#define __GTHREAD_ONCE_INIT 0
#define __GTHREAD_MUTEX_INIT 0
#define __GTHREAD_MUTEX_INIT_FUNCTION(mx) do {} while (0)
#define __GTHREAD_RECURSIVE_MUTEX_INIT 0
#define _GLIBCXX_UNUSED __attribute__((__unused__))
#ifdef _LIBOBJC
/* Thread local storage for a single thread */
static void *thread_local_storage = NULL;
/* Backend initialization functions */
/* Initialize the threads subsystem. */
static inline int
__gthread_objc_init_thread_system (void)
{
/* No thread support available */
return -1;
}
/* Close the threads subsystem. */
static inline int
__gthread_objc_close_thread_system (void)
{
/* No thread support available */
return -1;
}
/* Backend thread functions */
/* Create a new thread of execution. */
static inline objc_thread_t
__gthread_objc_thread_detach (void (* func)(void *), void * arg _GLIBCXX_UNUSED)
{
/* No thread support available */
return NULL;
}
/* Set the current thread's priority. */
static inline int
__gthread_objc_thread_set_priority (int priority _GLIBCXX_UNUSED)
{
/* No thread support available */
return -1;
}
/* Return the current thread's priority. */
static inline int
__gthread_objc_thread_get_priority (void)
{
return OBJC_THREAD_INTERACTIVE_PRIORITY;
}
/* Yield our process time to another thread. */
static inline void
__gthread_objc_thread_yield (void)
{
return;
}
/* Terminate the current thread. */
static inline int
__gthread_objc_thread_exit (void)
{
/* No thread support available */
/* Should we really exit the program */
/* exit (&__objc_thread_exit_status); */
return -1;
}
/* Returns an integer value which uniquely describes a thread. */
static inline objc_thread_t
__gthread_objc_thread_id (void)
{
/* No thread support, use 1. */
return (objc_thread_t) 1;
}
/* Sets the thread's local storage pointer. */
static inline int
__gthread_objc_thread_set_data (void *value)
{
thread_local_storage = value;
return 0;
}
/* Returns the thread's local storage pointer. */
static inline void *
__gthread_objc_thread_get_data (void)
{
return thread_local_storage;
}
/* Backend mutex functions */
/* Allocate a mutex. */
static inline int
__gthread_objc_mutex_allocate (objc_mutex_t mutex _GLIBCXX_UNUSED)
{
return 0;
}
/* Deallocate a mutex. */
static inline int
__gthread_objc_mutex_deallocate (objc_mutex_t mutex _GLIBCXX_UNUSED)
{
return 0;
}
/* Grab a lock on a mutex. */
static inline int
__gthread_objc_mutex_lock (objc_mutex_t mutex _GLIBCXX_UNUSED)
{
/* There can only be one thread, so we always get the lock */
return 0;
}
/* Try to grab a lock on a mutex. */
static inline int
__gthread_objc_mutex_trylock (objc_mutex_t mutex _GLIBCXX_UNUSED)
{
/* There can only be one thread, so we always get the lock */
return 0;
}
/* Unlock the mutex */
static inline int
__gthread_objc_mutex_unlock (objc_mutex_t mutex _GLIBCXX_UNUSED)
{
return 0;
}
/* Backend condition mutex functions */
/* Allocate a condition. */
static inline int
__gthread_objc_condition_allocate (objc_condition_t condition _GLIBCXX_UNUSED)
{
return 0;
}
/* Deallocate a condition. */
static inline int
__gthread_objc_condition_deallocate (objc_condition_t condition _GLIBCXX_UNUSED)
{
return 0;
}
/* Wait on the condition */
static inline int
__gthread_objc_condition_wait (objc_condition_t condition _GLIBCXX_UNUSED,
objc_mutex_t mutex _GLIBCXX_UNUSED)
{
return 0;
}
/* Wake up all threads waiting on this condition. */
static inline int
__gthread_objc_condition_broadcast (objc_condition_t condition _GLIBCXX_UNUSED)
{
return 0;
}
/* Wake up one thread waiting on this condition. */
static inline int
__gthread_objc_condition_signal (objc_condition_t condition _GLIBCXX_UNUSED)
{
return 0;
}
#else /* _LIBOBJC */
static inline int
__gthread_active_p (void)
{
return 0;
}
static inline int
__gthread_once (__gthread_once_t *__once _GLIBCXX_UNUSED, void (*__func) (void) _GLIBCXX_UNUSED)
{
return 0;
}
static inline int _GLIBCXX_UNUSED
__gthread_key_create (__gthread_key_t *__key _GLIBCXX_UNUSED, void (*__func) (void *) _GLIBCXX_UNUSED)
{
return 0;
}
static int _GLIBCXX_UNUSED
__gthread_key_delete (__gthread_key_t __key _GLIBCXX_UNUSED)
{
return 0;
}
static inline void *
__gthread_getspecific (__gthread_key_t __key _GLIBCXX_UNUSED)
{
return 0;
}
static inline int
__gthread_setspecific (__gthread_key_t __key _GLIBCXX_UNUSED, const void *__v _GLIBCXX_UNUSED)
{
return 0;
}
static inline int
__gthread_mutex_destroy (__gthread_mutex_t *__mutex _GLIBCXX_UNUSED)
{
return 0;
}
static inline int
__gthread_mutex_lock (__gthread_mutex_t *__mutex _GLIBCXX_UNUSED)
{
return 0;
}
static inline int
__gthread_mutex_trylock (__gthread_mutex_t *__mutex _GLIBCXX_UNUSED)
{
return 0;
}
static inline int
__gthread_mutex_unlock (__gthread_mutex_t *__mutex _GLIBCXX_UNUSED)
{
return 0;
}
static inline int
__gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *__mutex)
{
return __gthread_mutex_lock (__mutex);
}
static inline int
__gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *__mutex)
{
return __gthread_mutex_trylock (__mutex);
}
static inline int
__gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *__mutex)
{
return __gthread_mutex_unlock (__mutex);
}
static inline int
__gthread_recursive_mutex_destroy (__gthread_recursive_mutex_t *__mutex)
{
return __gthread_mutex_destroy (__mutex);
}
#endif /* _LIBOBJC */
#undef _GLIBCXX_UNUSED
#endif /* ! _GLIBCXX_GCC_GTHR_SINGLE_H */
+950
View File
@@ -0,0 +1,950 @@
/* Threads compatibility routines for libgcc2 and libobjc. */
/* Compile this one with gcc. */
/* Copyright (C) 1997-2024 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
#ifndef _GLIBCXX_GCC_GTHR_POSIX_H
#define _GLIBCXX_GCC_GTHR_POSIX_H
/* POSIX threads specific definitions.
Easy, since the interface is just one-to-one mapping. */
#define __GTHREADS 1
#define __GTHREADS_CXX0X 1
#include <pthread.h>
#if ((defined(_LIBOBJC) || defined(_LIBOBJC_WEAK)) \
|| !defined(_GTHREAD_USE_MUTEX_TIMEDLOCK))
# include <unistd.h>
# if defined(_POSIX_TIMEOUTS) && _POSIX_TIMEOUTS >= 0
# define _GTHREAD_USE_MUTEX_TIMEDLOCK 1
# else
# define _GTHREAD_USE_MUTEX_TIMEDLOCK 0
# endif
#endif
typedef pthread_t __gthread_t;
typedef pthread_key_t __gthread_key_t;
typedef pthread_once_t __gthread_once_t;
typedef pthread_mutex_t __gthread_mutex_t;
#ifndef __cplusplus
typedef pthread_rwlock_t __gthread_rwlock_t;
#endif
typedef pthread_mutex_t __gthread_recursive_mutex_t;
typedef pthread_cond_t __gthread_cond_t;
typedef struct timespec __gthread_time_t;
/* POSIX like conditional variables are supported. Please look at comments
in gthr.h for details. */
#define __GTHREAD_HAS_COND 1
#define __GTHREAD_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER
#define __GTHREAD_MUTEX_INIT_FUNCTION __gthread_mutex_init_function
#ifndef __cplusplus
#define __GTHREAD_RWLOCK_INIT PTHREAD_RWLOCK_INITIALIZER
#endif
#define __GTHREAD_ONCE_INIT PTHREAD_ONCE_INIT
#if defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER)
#define __GTHREAD_RECURSIVE_MUTEX_INIT PTHREAD_RECURSIVE_MUTEX_INITIALIZER
#elif defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP)
#define __GTHREAD_RECURSIVE_MUTEX_INIT PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
#else
#define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION __gthread_recursive_mutex_init_function
#endif
#define __GTHREAD_COND_INIT PTHREAD_COND_INITIALIZER
#define __GTHREAD_TIME_INIT {0,0}
#ifdef _GTHREAD_USE_MUTEX_INIT_FUNC
# undef __GTHREAD_MUTEX_INIT
#endif
#ifdef _GTHREAD_USE_RECURSIVE_MUTEX_INIT_FUNC
# undef __GTHREAD_RECURSIVE_MUTEX_INIT
# undef __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION
# define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION __gthread_recursive_mutex_init_function
#endif
#ifdef _GTHREAD_USE_COND_INIT_FUNC
# undef __GTHREAD_COND_INIT
# define __GTHREAD_COND_INIT_FUNCTION __gthread_cond_init_function
#endif
#if __GXX_WEAK__ && _GLIBCXX_GTHREAD_USE_WEAK
# ifndef __gthrw_pragma
# define __gthrw_pragma(pragma)
# endif
# define __gthrw2(name,name2,type) \
static __typeof(type) name \
__attribute__ ((__weakref__(#name2), __copy__ (type))); \
__gthrw_pragma(weak type)
# define __gthrw_(name) __gthrw_ ## name
#else
# define __gthrw2(name,name2,type)
# define __gthrw_(name) name
#endif
/* Typically, __gthrw_foo is a weak reference to symbol foo. */
#define __gthrw(name) __gthrw2(__gthrw_ ## name,name,name)
__gthrw(pthread_once)
__gthrw(pthread_getspecific)
__gthrw(pthread_setspecific)
__gthrw(pthread_create)
__gthrw(pthread_join)
__gthrw(pthread_equal)
__gthrw(pthread_self)
__gthrw(pthread_detach)
#ifndef __BIONIC__
__gthrw(pthread_cancel)
#endif
__gthrw(sched_yield)
__gthrw(pthread_mutex_lock)
__gthrw(pthread_mutex_trylock)
#if _GTHREAD_USE_MUTEX_TIMEDLOCK
__gthrw(pthread_mutex_timedlock)
#endif
__gthrw(pthread_mutex_unlock)
__gthrw(pthread_mutex_init)
__gthrw(pthread_mutex_destroy)
__gthrw(pthread_cond_init)
__gthrw(pthread_cond_broadcast)
__gthrw(pthread_cond_signal)
__gthrw(pthread_cond_wait)
__gthrw(pthread_cond_timedwait)
__gthrw(pthread_cond_destroy)
__gthrw(pthread_key_create)
__gthrw(pthread_key_delete)
__gthrw(pthread_mutexattr_init)
__gthrw(pthread_mutexattr_settype)
__gthrw(pthread_mutexattr_destroy)
#ifndef __cplusplus
__gthrw(pthread_rwlock_rdlock)
__gthrw(pthread_rwlock_tryrdlock)
__gthrw(pthread_rwlock_wrlock)
__gthrw(pthread_rwlock_trywrlock)
__gthrw(pthread_rwlock_unlock)
#endif
#if defined(_LIBOBJC) || defined(_LIBOBJC_WEAK)
/* Objective-C. */
__gthrw(pthread_exit)
#ifdef _POSIX_PRIORITY_SCHEDULING
#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
__gthrw(sched_get_priority_max)
__gthrw(sched_get_priority_min)
#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
#endif /* _POSIX_PRIORITY_SCHEDULING */
__gthrw(pthread_attr_destroy)
__gthrw(pthread_attr_init)
__gthrw(pthread_attr_setdetachstate)
#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
__gthrw(pthread_getschedparam)
__gthrw(pthread_setschedparam)
#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
#endif /* _LIBOBJC || _LIBOBJC_WEAK */
#if __GXX_WEAK__ && _GLIBCXX_GTHREAD_USE_WEAK
/* On Solaris 2.6 up to 9, the libc exposes a POSIX threads interface even if
-pthreads is not specified. The functions are dummies and most return an
error value. However pthread_once returns 0 without invoking the routine
it is passed so we cannot pretend that the interface is active if -pthreads
is not specified. On Solaris 2.5.1, the interface is not exposed at all so
we need to play the usual game with weak symbols. On Solaris 10 and up, a
working interface is always exposed. On FreeBSD 6 and later, libc also
exposes a dummy POSIX threads interface, similar to what Solaris 2.6 up
to 9 does. FreeBSD >= 700014 even provides a pthread_cancel stub in libc,
which means the alternate __gthread_active_p below cannot be used there. */
#if defined(__FreeBSD__) || (defined(__sun) && defined(__svr4__))
static volatile int __gthread_active = -1;
static void
__gthread_trigger (void)
{
__gthread_active = 1;
}
static inline int
__gthread_active_p (void)
{
static pthread_mutex_t __gthread_active_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_once_t __gthread_active_once = PTHREAD_ONCE_INIT;
/* Avoid reading __gthread_active twice on the main code path. */
int __gthread_active_latest_value = __gthread_active;
/* This test is not protected to avoid taking a lock on the main code
path so every update of __gthread_active in a threaded program must
be atomic with regard to the result of the test. */
if (__builtin_expect (__gthread_active_latest_value < 0, 0))
{
if (__gthrw_(pthread_once))
{
/* If this really is a threaded program, then we must ensure that
__gthread_active has been set to 1 before exiting this block. */
__gthrw_(pthread_mutex_lock) (&__gthread_active_mutex);
__gthrw_(pthread_once) (&__gthread_active_once, __gthread_trigger);
__gthrw_(pthread_mutex_unlock) (&__gthread_active_mutex);
}
/* Make sure we'll never enter this block again. */
if (__gthread_active < 0)
__gthread_active = 0;
__gthread_active_latest_value = __gthread_active;
}
return __gthread_active_latest_value != 0;
}
#else /* neither FreeBSD nor Solaris */
/* For a program to be multi-threaded the only thing that it certainly must
be using is pthread_create. However, there may be other libraries that
intercept pthread_create with their own definitions to wrap pthreads
functionality for some purpose. In those cases, pthread_create being
defined might not necessarily mean that libpthread is actually linked
in.
For the GNU C library, we can use a known internal name. This is always
available in the ABI, but no other library would define it. That is
ideal, since any public pthread function might be intercepted just as
pthread_create might be. __pthread_key_create is an "internal"
implementation symbol, but it is part of the public exported ABI. Also,
it's among the symbols that the static libpthread.a always links in
whenever pthread_create is used, so there is no danger of a false
negative result in any statically-linked, multi-threaded program.
For others, we choose pthread_cancel as a function that seems unlikely
to be redefined by an interceptor library. The bionic (Android) C
library does not provide pthread_cancel, so we do use pthread_create
there (and interceptor libraries lose). */
#ifdef __GLIBC__
__gthrw2(__gthrw_(__pthread_key_create),
__pthread_key_create,
pthread_key_create)
# define GTHR_ACTIVE_PROXY __gthrw_(__pthread_key_create)
#elif defined (__BIONIC__)
# define GTHR_ACTIVE_PROXY __gthrw_(pthread_create)
#else
# define GTHR_ACTIVE_PROXY __gthrw_(pthread_cancel)
#endif
static inline int
__gthread_active_p (void)
{
static void *const __gthread_active_ptr
= __extension__ (void *) &GTHR_ACTIVE_PROXY;
return __gthread_active_ptr != 0;
}
#endif /* FreeBSD or Solaris */
#else /* not __GXX_WEAK__ */
/* Similar to Solaris, HP-UX 11 for PA-RISC provides stubs for pthread
calls in shared flavors of the HP-UX C library. Most of the stubs
have no functionality. The details are described in the "libc cumulative
patch" for each subversion of HP-UX 11. There are two special interfaces
provided for checking whether an application is linked to a shared pthread
library or not. However, these interfaces aren't available in early
libpthread libraries. We also need a test that works for archive
libraries. We can't use pthread_once as some libc versions call the
init function. We also can't use pthread_create or pthread_attr_init
as these create a thread and thereby prevent changing the default stack
size. The function pthread_default_stacksize_np is available in both
the archive and shared versions of libpthread. It can be used to
determine the default pthread stack size. There is a stub in some
shared libc versions which returns a zero size if pthreads are not
active. We provide an equivalent stub to handle cases where libc
doesn't provide one. */
#if defined(__hppa__) && defined(__hpux__)
static volatile int __gthread_active = -1;
static inline int
__gthread_active_p (void)
{
/* Avoid reading __gthread_active twice on the main code path. */
int __gthread_active_latest_value = __gthread_active;
size_t __s;
if (__builtin_expect (__gthread_active_latest_value < 0, 0))
{
pthread_default_stacksize_np (0, &__s);
__gthread_active = __s ? 1 : 0;
__gthread_active_latest_value = __gthread_active;
}
return __gthread_active_latest_value != 0;
}
#else /* not hppa-hpux */
static inline int
__gthread_active_p (void)
{
return 1;
}
#endif /* hppa-hpux */
#endif /* __GXX_WEAK__ */
#ifdef _LIBOBJC
/* This is the config.h file in libobjc/ */
#include <config.h>
#ifdef HAVE_SCHED_H
# include <sched.h>
#endif
/* Key structure for maintaining thread specific storage */
static pthread_key_t _objc_thread_storage;
static pthread_attr_t _objc_thread_attribs;
/* Thread local storage for a single thread */
static void *thread_local_storage = NULL;
/* Backend initialization functions */
/* Initialize the threads subsystem. */
static inline int
__gthread_objc_init_thread_system (void)
{
if (__gthread_active_p ())
{
/* Initialize the thread storage key. */
if (__gthrw_(pthread_key_create) (&_objc_thread_storage, NULL) == 0)
{
/* The normal default detach state for threads is
* PTHREAD_CREATE_JOINABLE which causes threads to not die
* when you think they should. */
if (__gthrw_(pthread_attr_init) (&_objc_thread_attribs) == 0
&& __gthrw_(pthread_attr_setdetachstate) (&_objc_thread_attribs,
PTHREAD_CREATE_DETACHED) == 0)
return 0;
}
}
return -1;
}
/* Close the threads subsystem. */
static inline int
__gthread_objc_close_thread_system (void)
{
if (__gthread_active_p ()
&& __gthrw_(pthread_key_delete) (_objc_thread_storage) == 0
&& __gthrw_(pthread_attr_destroy) (&_objc_thread_attribs) == 0)
return 0;
return -1;
}
/* Backend thread functions */
/* Create a new thread of execution. */
static inline objc_thread_t
__gthread_objc_thread_detach (void (*func)(void *), void *arg)
{
objc_thread_t thread_id;
pthread_t new_thread_handle;
if (!__gthread_active_p ())
return NULL;
if (!(__gthrw_(pthread_create) (&new_thread_handle, &_objc_thread_attribs,
(void *) func, arg)))
thread_id = (objc_thread_t) new_thread_handle;
else
thread_id = NULL;
return thread_id;
}
/* Set the current thread's priority. */
static inline int
__gthread_objc_thread_set_priority (int priority)
{
if (!__gthread_active_p ())
return -1;
else
{
#ifdef _POSIX_PRIORITY_SCHEDULING
#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
pthread_t thread_id = __gthrw_(pthread_self) ();
int policy;
struct sched_param params;
int priority_min, priority_max;
if (__gthrw_(pthread_getschedparam) (thread_id, &policy, &params) == 0)
{
if ((priority_max = __gthrw_(sched_get_priority_max) (policy)) == -1)
return -1;
if ((priority_min = __gthrw_(sched_get_priority_min) (policy)) == -1)
return -1;
if (priority > priority_max)
priority = priority_max;
else if (priority < priority_min)
priority = priority_min;
params.sched_priority = priority;
/*
* The solaris 7 and several other man pages incorrectly state that
* this should be a pointer to policy but pthread.h is universally
* at odds with this.
*/
if (__gthrw_(pthread_setschedparam) (thread_id, policy, &params) == 0)
return 0;
}
#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
#endif /* _POSIX_PRIORITY_SCHEDULING */
return -1;
}
}
/* Return the current thread's priority. */
static inline int
__gthread_objc_thread_get_priority (void)
{
#ifdef _POSIX_PRIORITY_SCHEDULING
#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
if (__gthread_active_p ())
{
int policy;
struct sched_param params;
if (__gthrw_(pthread_getschedparam) (__gthrw_(pthread_self) (), &policy, &params) == 0)
return params.sched_priority;
else
return -1;
}
else
#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
#endif /* _POSIX_PRIORITY_SCHEDULING */
return OBJC_THREAD_INTERACTIVE_PRIORITY;
}
/* Yield our process time to another thread. */
static inline void
__gthread_objc_thread_yield (void)
{
if (__gthread_active_p ())
__gthrw_(sched_yield) ();
}
/* Terminate the current thread. */
static inline int
__gthread_objc_thread_exit (void)
{
if (__gthread_active_p ())
/* exit the thread */
__gthrw_(pthread_exit) (&__objc_thread_exit_status);
/* Failed if we reached here */
return -1;
}
/* Returns an integer value which uniquely describes a thread. */
static inline objc_thread_t
__gthread_objc_thread_id (void)
{
if (__gthread_active_p ())
return (objc_thread_t) __gthrw_(pthread_self) ();
else
return (objc_thread_t) 1;
}
/* Sets the thread's local storage pointer. */
static inline int
__gthread_objc_thread_set_data (void *value)
{
if (__gthread_active_p ())
return __gthrw_(pthread_setspecific) (_objc_thread_storage, value);
else
{
thread_local_storage = value;
return 0;
}
}
/* Returns the thread's local storage pointer. */
static inline void *
__gthread_objc_thread_get_data (void)
{
if (__gthread_active_p ())
return __gthrw_(pthread_getspecific) (_objc_thread_storage);
else
return thread_local_storage;
}
/* Backend mutex functions */
/* Allocate a mutex. */
static inline int
__gthread_objc_mutex_allocate (objc_mutex_t mutex)
{
if (__gthread_active_p ())
{
mutex->backend = objc_malloc (sizeof (pthread_mutex_t));
if (__gthrw_(pthread_mutex_init) ((pthread_mutex_t *) mutex->backend, NULL))
{
objc_free (mutex->backend);
mutex->backend = NULL;
return -1;
}
}
return 0;
}
/* Deallocate a mutex. */
static inline int
__gthread_objc_mutex_deallocate (objc_mutex_t mutex)
{
if (__gthread_active_p ())
{
int count;
/*
* Posix Threads specifically require that the thread be unlocked
* for __gthrw_(pthread_mutex_destroy) to work.
*/
do
{
count = __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend);
if (count < 0)
return -1;
}
while (count);
if (__gthrw_(pthread_mutex_destroy) ((pthread_mutex_t *) mutex->backend))
return -1;
objc_free (mutex->backend);
mutex->backend = NULL;
}
return 0;
}
/* Grab a lock on a mutex. */
static inline int
__gthread_objc_mutex_lock (objc_mutex_t mutex)
{
if (__gthread_active_p ()
&& __gthrw_(pthread_mutex_lock) ((pthread_mutex_t *) mutex->backend) != 0)
{
return -1;
}
return 0;
}
/* Try to grab a lock on a mutex. */
static inline int
__gthread_objc_mutex_trylock (objc_mutex_t mutex)
{
if (__gthread_active_p ()
&& __gthrw_(pthread_mutex_trylock) ((pthread_mutex_t *) mutex->backend) != 0)
{
return -1;
}
return 0;
}
/* Unlock the mutex */
static inline int
__gthread_objc_mutex_unlock (objc_mutex_t mutex)
{
if (__gthread_active_p ()
&& __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend) != 0)
{
return -1;
}
return 0;
}
/* Backend condition mutex functions */
/* Allocate a condition. */
static inline int
__gthread_objc_condition_allocate (objc_condition_t condition)
{
if (__gthread_active_p ())
{
condition->backend = objc_malloc (sizeof (pthread_cond_t));
if (__gthrw_(pthread_cond_init) ((pthread_cond_t *) condition->backend, NULL))
{
objc_free (condition->backend);
condition->backend = NULL;
return -1;
}
}
return 0;
}
/* Deallocate a condition. */
static inline int
__gthread_objc_condition_deallocate (objc_condition_t condition)
{
if (__gthread_active_p ())
{
if (__gthrw_(pthread_cond_destroy) ((pthread_cond_t *) condition->backend))
return -1;
objc_free (condition->backend);
condition->backend = NULL;
}
return 0;
}
/* Wait on the condition */
static inline int
__gthread_objc_condition_wait (objc_condition_t condition, objc_mutex_t mutex)
{
if (__gthread_active_p ())
return __gthrw_(pthread_cond_wait) ((pthread_cond_t *) condition->backend,
(pthread_mutex_t *) mutex->backend);
else
return 0;
}
/* Wake up all threads waiting on this condition. */
static inline int
__gthread_objc_condition_broadcast (objc_condition_t condition)
{
if (__gthread_active_p ())
return __gthrw_(pthread_cond_broadcast) ((pthread_cond_t *) condition->backend);
else
return 0;
}
/* Wake up one thread waiting on this condition. */
static inline int
__gthread_objc_condition_signal (objc_condition_t condition)
{
if (__gthread_active_p ())
return __gthrw_(pthread_cond_signal) ((pthread_cond_t *) condition->backend);
else
return 0;
}
#else /* _LIBOBJC */
static inline int
__gthread_create (__gthread_t *__threadid, void *(*__func) (void*),
void *__args)
{
return __gthrw_(pthread_create) (__threadid, NULL, __func, __args);
}
static inline int
__gthread_join (__gthread_t __threadid, void **__value_ptr)
{
return __gthrw_(pthread_join) (__threadid, __value_ptr);
}
static inline int
__gthread_detach (__gthread_t __threadid)
{
return __gthrw_(pthread_detach) (__threadid);
}
static inline int
__gthread_equal (__gthread_t __t1, __gthread_t __t2)
{
return __gthrw_(pthread_equal) (__t1, __t2);
}
static inline __gthread_t
__gthread_self (void)
{
return __gthrw_(pthread_self) ();
}
static inline int
__gthread_yield (void)
{
return __gthrw_(sched_yield) ();
}
static inline int
__gthread_once (__gthread_once_t *__once, void (*__func) (void))
{
if (__gthread_active_p ())
return __gthrw_(pthread_once) (__once, __func);
else
return -1;
}
static inline int
__gthread_key_create (__gthread_key_t *__key, void (*__dtor) (void *))
{
return __gthrw_(pthread_key_create) (__key, __dtor);
}
static inline int
__gthread_key_delete (__gthread_key_t __key)
{
return __gthrw_(pthread_key_delete) (__key);
}
static inline void *
__gthread_getspecific (__gthread_key_t __key)
{
return __gthrw_(pthread_getspecific) (__key);
}
static inline int
__gthread_setspecific (__gthread_key_t __key, const void *__ptr)
{
return __gthrw_(pthread_setspecific) (__key, __ptr);
}
static inline void
__gthread_mutex_init_function (__gthread_mutex_t *__mutex)
{
if (__gthread_active_p ())
__gthrw_(pthread_mutex_init) (__mutex, NULL);
}
static inline int
__gthread_mutex_destroy (__gthread_mutex_t *__mutex)
{
if (__gthread_active_p ())
return __gthrw_(pthread_mutex_destroy) (__mutex);
else
return 0;
}
static inline int
__gthread_mutex_lock (__gthread_mutex_t *__mutex)
{
if (__gthread_active_p ())
return __gthrw_(pthread_mutex_lock) (__mutex);
else
return 0;
}
static inline int
__gthread_mutex_trylock (__gthread_mutex_t *__mutex)
{
if (__gthread_active_p ())
return __gthrw_(pthread_mutex_trylock) (__mutex);
else
return 0;
}
#if _GTHREAD_USE_MUTEX_TIMEDLOCK
static inline int
__gthread_mutex_timedlock (__gthread_mutex_t *__mutex,
const __gthread_time_t *__abs_timeout)
{
if (__gthread_active_p ())
return __gthrw_(pthread_mutex_timedlock) (__mutex, __abs_timeout);
else
return 0;
}
#endif
static inline int
__gthread_mutex_unlock (__gthread_mutex_t *__mutex)
{
if (__gthread_active_p ())
return __gthrw_(pthread_mutex_unlock) (__mutex);
else
return 0;
}
#if !defined( PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP) \
|| defined(_GTHREAD_USE_RECURSIVE_MUTEX_INIT_FUNC)
static inline int
__gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *__mutex)
{
if (__gthread_active_p ())
{
pthread_mutexattr_t __attr;
int __r;
__r = __gthrw_(pthread_mutexattr_init) (&__attr);
if (!__r)
__r = __gthrw_(pthread_mutexattr_settype) (&__attr,
PTHREAD_MUTEX_RECURSIVE);
if (!__r)
__r = __gthrw_(pthread_mutex_init) (__mutex, &__attr);
if (!__r)
__r = __gthrw_(pthread_mutexattr_destroy) (&__attr);
return __r;
}
return 0;
}
#endif
static inline int
__gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *__mutex)
{
return __gthread_mutex_lock (__mutex);
}
static inline int
__gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *__mutex)
{
return __gthread_mutex_trylock (__mutex);
}
#if _GTHREAD_USE_MUTEX_TIMEDLOCK
static inline int
__gthread_recursive_mutex_timedlock (__gthread_recursive_mutex_t *__mutex,
const __gthread_time_t *__abs_timeout)
{
return __gthread_mutex_timedlock (__mutex, __abs_timeout);
}
#endif
static inline int
__gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *__mutex)
{
return __gthread_mutex_unlock (__mutex);
}
static inline int
__gthread_recursive_mutex_destroy (__gthread_recursive_mutex_t *__mutex)
{
return __gthread_mutex_destroy (__mutex);
}
#ifdef _GTHREAD_USE_COND_INIT_FUNC
static inline void
__gthread_cond_init_function (__gthread_cond_t *__cond)
{
if (__gthread_active_p ())
__gthrw_(pthread_cond_init) (__cond, NULL);
}
#endif
static inline int
__gthread_cond_broadcast (__gthread_cond_t *__cond)
{
return __gthrw_(pthread_cond_broadcast) (__cond);
}
static inline int
__gthread_cond_signal (__gthread_cond_t *__cond)
{
return __gthrw_(pthread_cond_signal) (__cond);
}
static inline int
__gthread_cond_wait (__gthread_cond_t *__cond, __gthread_mutex_t *__mutex)
{
return __gthrw_(pthread_cond_wait) (__cond, __mutex);
}
static inline int
__gthread_cond_timedwait (__gthread_cond_t *__cond, __gthread_mutex_t *__mutex,
const __gthread_time_t *__abs_timeout)
{
return __gthrw_(pthread_cond_timedwait) (__cond, __mutex, __abs_timeout);
}
static inline int
__gthread_cond_wait_recursive (__gthread_cond_t *__cond,
__gthread_recursive_mutex_t *__mutex)
{
return __gthread_cond_wait (__cond, __mutex);
}
static inline int
__gthread_cond_destroy (__gthread_cond_t* __cond)
{
return __gthrw_(pthread_cond_destroy) (__cond);
}
#ifndef __cplusplus
static inline int
__gthread_rwlock_rdlock (__gthread_rwlock_t *__rwlock)
{
if (__gthread_active_p ())
return __gthrw_(pthread_rwlock_rdlock) (__rwlock);
else
return 0;
}
static inline int
__gthread_rwlock_tryrdlock (__gthread_rwlock_t *__rwlock)
{
if (__gthread_active_p ())
return __gthrw_(pthread_rwlock_tryrdlock) (__rwlock);
else
return 0;
}
static inline int
__gthread_rwlock_wrlock (__gthread_rwlock_t *__rwlock)
{
if (__gthread_active_p ())
return __gthrw_(pthread_rwlock_wrlock) (__rwlock);
else
return 0;
}
static inline int
__gthread_rwlock_trywrlock (__gthread_rwlock_t *__rwlock)
{
if (__gthread_active_p ())
return __gthrw_(pthread_rwlock_trywrlock) (__rwlock);
else
return 0;
}
static inline int
__gthread_rwlock_unlock (__gthread_rwlock_t *__rwlock)
{
if (__gthread_active_p ())
return __gthrw_(pthread_rwlock_unlock) (__rwlock);
else
return 0;
}
#endif
#endif /* _LIBOBJC */
#endif /* ! _GLIBCXX_GCC_GTHR_POSIX_H */
+298
View File
@@ -0,0 +1,298 @@
/* Threads compatibility routines for libgcc2 and libobjc. */
/* Compile this one with gcc. */
/* Copyright (C) 1997-2024 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
#ifndef _GLIBCXX_GCC_GTHR_SINGLE_H
#define _GLIBCXX_GCC_GTHR_SINGLE_H
/* Just provide compatibility for mutex handling. */
typedef int __gthread_key_t;
typedef int __gthread_once_t;
typedef int __gthread_mutex_t;
typedef int __gthread_recursive_mutex_t;
#define __GTHREAD_ONCE_INIT 0
#define __GTHREAD_MUTEX_INIT 0
#define __GTHREAD_MUTEX_INIT_FUNCTION(mx) do {} while (0)
#define __GTHREAD_RECURSIVE_MUTEX_INIT 0
#define _GLIBCXX_UNUSED __attribute__((__unused__))
#ifdef _LIBOBJC
/* Thread local storage for a single thread */
static void *thread_local_storage = NULL;
/* Backend initialization functions */
/* Initialize the threads subsystem. */
static inline int
__gthread_objc_init_thread_system (void)
{
/* No thread support available */
return -1;
}
/* Close the threads subsystem. */
static inline int
__gthread_objc_close_thread_system (void)
{
/* No thread support available */
return -1;
}
/* Backend thread functions */
/* Create a new thread of execution. */
static inline objc_thread_t
__gthread_objc_thread_detach (void (* func)(void *), void * arg _GLIBCXX_UNUSED)
{
/* No thread support available */
return NULL;
}
/* Set the current thread's priority. */
static inline int
__gthread_objc_thread_set_priority (int priority _GLIBCXX_UNUSED)
{
/* No thread support available */
return -1;
}
/* Return the current thread's priority. */
static inline int
__gthread_objc_thread_get_priority (void)
{
return OBJC_THREAD_INTERACTIVE_PRIORITY;
}
/* Yield our process time to another thread. */
static inline void
__gthread_objc_thread_yield (void)
{
return;
}
/* Terminate the current thread. */
static inline int
__gthread_objc_thread_exit (void)
{
/* No thread support available */
/* Should we really exit the program */
/* exit (&__objc_thread_exit_status); */
return -1;
}
/* Returns an integer value which uniquely describes a thread. */
static inline objc_thread_t
__gthread_objc_thread_id (void)
{
/* No thread support, use 1. */
return (objc_thread_t) 1;
}
/* Sets the thread's local storage pointer. */
static inline int
__gthread_objc_thread_set_data (void *value)
{
thread_local_storage = value;
return 0;
}
/* Returns the thread's local storage pointer. */
static inline void *
__gthread_objc_thread_get_data (void)
{
return thread_local_storage;
}
/* Backend mutex functions */
/* Allocate a mutex. */
static inline int
__gthread_objc_mutex_allocate (objc_mutex_t mutex _GLIBCXX_UNUSED)
{
return 0;
}
/* Deallocate a mutex. */
static inline int
__gthread_objc_mutex_deallocate (objc_mutex_t mutex _GLIBCXX_UNUSED)
{
return 0;
}
/* Grab a lock on a mutex. */
static inline int
__gthread_objc_mutex_lock (objc_mutex_t mutex _GLIBCXX_UNUSED)
{
/* There can only be one thread, so we always get the lock */
return 0;
}
/* Try to grab a lock on a mutex. */
static inline int
__gthread_objc_mutex_trylock (objc_mutex_t mutex _GLIBCXX_UNUSED)
{
/* There can only be one thread, so we always get the lock */
return 0;
}
/* Unlock the mutex */
static inline int
__gthread_objc_mutex_unlock (objc_mutex_t mutex _GLIBCXX_UNUSED)
{
return 0;
}
/* Backend condition mutex functions */
/* Allocate a condition. */
static inline int
__gthread_objc_condition_allocate (objc_condition_t condition _GLIBCXX_UNUSED)
{
return 0;
}
/* Deallocate a condition. */
static inline int
__gthread_objc_condition_deallocate (objc_condition_t condition _GLIBCXX_UNUSED)
{
return 0;
}
/* Wait on the condition */
static inline int
__gthread_objc_condition_wait (objc_condition_t condition _GLIBCXX_UNUSED,
objc_mutex_t mutex _GLIBCXX_UNUSED)
{
return 0;
}
/* Wake up all threads waiting on this condition. */
static inline int
__gthread_objc_condition_broadcast (objc_condition_t condition _GLIBCXX_UNUSED)
{
return 0;
}
/* Wake up one thread waiting on this condition. */
static inline int
__gthread_objc_condition_signal (objc_condition_t condition _GLIBCXX_UNUSED)
{
return 0;
}
#else /* _LIBOBJC */
static inline int
__gthread_active_p (void)
{
return 0;
}
static inline int
__gthread_once (__gthread_once_t *__once _GLIBCXX_UNUSED, void (*__func) (void) _GLIBCXX_UNUSED)
{
return 0;
}
static inline int _GLIBCXX_UNUSED
__gthread_key_create (__gthread_key_t *__key _GLIBCXX_UNUSED, void (*__func) (void *) _GLIBCXX_UNUSED)
{
return 0;
}
static int _GLIBCXX_UNUSED
__gthread_key_delete (__gthread_key_t __key _GLIBCXX_UNUSED)
{
return 0;
}
static inline void *
__gthread_getspecific (__gthread_key_t __key _GLIBCXX_UNUSED)
{
return 0;
}
static inline int
__gthread_setspecific (__gthread_key_t __key _GLIBCXX_UNUSED, const void *__v _GLIBCXX_UNUSED)
{
return 0;
}
static inline int
__gthread_mutex_destroy (__gthread_mutex_t *__mutex _GLIBCXX_UNUSED)
{
return 0;
}
static inline int
__gthread_mutex_lock (__gthread_mutex_t *__mutex _GLIBCXX_UNUSED)
{
return 0;
}
static inline int
__gthread_mutex_trylock (__gthread_mutex_t *__mutex _GLIBCXX_UNUSED)
{
return 0;
}
static inline int
__gthread_mutex_unlock (__gthread_mutex_t *__mutex _GLIBCXX_UNUSED)
{
return 0;
}
static inline int
__gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *__mutex)
{
return __gthread_mutex_lock (__mutex);
}
static inline int
__gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *__mutex)
{
return __gthread_mutex_trylock (__mutex);
}
static inline int
__gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *__mutex)
{
return __gthread_mutex_unlock (__mutex);
}
static inline int
__gthread_recursive_mutex_destroy (__gthread_recursive_mutex_t *__mutex)
{
return __gthread_mutex_destroy (__mutex);
}
#endif /* _LIBOBJC */
#undef _GLIBCXX_UNUSED
#endif /* ! _GLIBCXX_GCC_GTHR_SINGLE_H */
+163
View File
@@ -0,0 +1,163 @@
/* Threads compatibility routines for libgcc2. */
/* Compile this one with gcc. */
/* Copyright (C) 1997-2024 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
#ifndef _GLIBCXX_GCC_GTHR_H
#define _GLIBCXX_GCC_GTHR_H
#ifndef _GLIBCXX_HIDE_EXPORTS
#pragma GCC visibility push(default)
#endif
/* If this file is compiled with threads support, it must
#define __GTHREADS 1
to indicate that threads support is present. Also it has define
function
int __gthread_active_p ()
that returns 1 if thread system is active, 0 if not.
The threads interface must define the following types:
__gthread_key_t
__gthread_once_t
__gthread_mutex_t
__gthread_recursive_mutex_t
The threads interface must define the following macros:
__GTHREAD_ONCE_INIT
to initialize __gthread_once_t
__GTHREAD_MUTEX_INIT
to initialize __gthread_mutex_t to get a fast
non-recursive mutex.
__GTHREAD_MUTEX_INIT_FUNCTION
to initialize __gthread_mutex_t to get a fast
non-recursive mutex.
Define this to a function which looks like this:
void __GTHREAD_MUTEX_INIT_FUNCTION (__gthread_mutex_t *)
Some systems can't initialize a mutex without a
function call. Don't define __GTHREAD_MUTEX_INIT in this case.
__GTHREAD_RECURSIVE_MUTEX_INIT
__GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION
as above, but for a recursive mutex.
The threads interface must define the following static functions:
int __gthread_once (__gthread_once_t *once, void (*func) ())
int __gthread_key_create (__gthread_key_t *keyp, void (*dtor) (void *))
int __gthread_key_delete (__gthread_key_t key)
void *__gthread_getspecific (__gthread_key_t key)
int __gthread_setspecific (__gthread_key_t key, const void *ptr)
int __gthread_mutex_destroy (__gthread_mutex_t *mutex);
int __gthread_recursive_mutex_destroy (__gthread_recursive_mutex_t *mutex);
int __gthread_mutex_lock (__gthread_mutex_t *mutex);
int __gthread_mutex_trylock (__gthread_mutex_t *mutex);
int __gthread_mutex_unlock (__gthread_mutex_t *mutex);
int __gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *mutex);
int __gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *mutex);
int __gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *mutex);
The following are supported in POSIX threads only. They are required to
fix a deadlock in static initialization inside libsupc++. The header file
gthr-posix.h defines a symbol __GTHREAD_HAS_COND to signify that these extra
features are supported.
Types:
__gthread_cond_t
Macros:
__GTHREAD_COND_INIT
__GTHREAD_COND_INIT_FUNCTION
Interface:
int __gthread_cond_broadcast (__gthread_cond_t *cond);
int __gthread_cond_wait (__gthread_cond_t *cond, __gthread_mutex_t *mutex);
int __gthread_cond_wait_recursive (__gthread_cond_t *cond,
__gthread_recursive_mutex_t *mutex);
All functions returning int should return zero on success or the error
number. If the operation is not supported, -1 is returned.
If the following are also defined, you should
#define __GTHREADS_CXX0X 1
to enable the c++0x thread library.
Types:
__gthread_t
__gthread_time_t
Interface:
int __gthread_create (__gthread_t *thread, void *(*func) (void*),
void *args);
int __gthread_join (__gthread_t thread, void **value_ptr);
int __gthread_detach (__gthread_t thread);
int __gthread_equal (__gthread_t t1, __gthread_t t2);
__gthread_t __gthread_self (void);
int __gthread_yield (void);
int __gthread_mutex_timedlock (__gthread_mutex_t *m,
const __gthread_time_t *abs_timeout);
int __gthread_recursive_mutex_timedlock (__gthread_recursive_mutex_t *m,
const __gthread_time_t *abs_time);
int __gthread_cond_signal (__gthread_cond_t *cond);
int __gthread_cond_timedwait (__gthread_cond_t *cond,
__gthread_mutex_t *mutex,
const __gthread_time_t *abs_timeout);
*/
#if __GXX_WEAK__
/* The pe-coff weak support isn't fully compatible to ELF's weak.
For static libraries it might would work, but as we need to deal
with shared versions too, we disable it for mingw-targets. */
#ifdef __MINGW32__
#undef _GLIBCXX_GTHREAD_USE_WEAK
#define _GLIBCXX_GTHREAD_USE_WEAK 0
#endif
#ifdef _GLIBCXX___GLIBC_PREREQ
#if _GLIBCXX___GLIBC_PREREQ(2, 34) && !defined(_GLIBCXX___gnu_GLIBCXX__hurd_GLIBCXX___)
/* glibc 2.34 and later has all pthread_* APIs inside of libc,
no need to link separately with -lpthread. */
#undef _GLIBCXX_GTHREAD_USE_WEAK
#define _GLIBCXX_GTHREAD_USE_WEAK 0
#endif
#endif
#ifndef _GLIBCXX_GTHREAD_USE_WEAK
#define _GLIBCXX_GTHREAD_USE_WEAK 1
#endif
#endif
#include <bits/gthr-default.h>
#ifndef _GLIBCXX_HIDE_EXPORTS
#pragma GCC visibility pop
#endif
#endif /* ! _GLIBCXX_GCC_GTHR_H */
@@ -0,0 +1,59 @@
// Declarations for hash functions. -*- C++ -*-
// Copyright (C) 2010-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/hash_bytes.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{functional}
*/
#ifndef _HASH_BYTES_H
#define _HASH_BYTES_H 1
#pragma GCC system_header
#include <bits/c++config.h>
namespace std
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
// Hash function implementation for the nontrivial specialization.
// All of them are based on a primitive that hashes a pointer to a
// byte array. The actual hash algorithm is not guaranteed to stay
// the same from release to release -- it may be updated or tuned to
// improve hash quality or speed.
size_t
_Hash_bytes(const void* __ptr, size_t __len, size_t __seed);
// A similar hash primitive, using the FNV hash algorithm. This
// algorithm is guaranteed to stay the same from release to release.
// (although it might not produce the same values on different
// machines.)
size_t
_Fnv_hash_bytes(const void* __ptr, size_t __len, size_t __seed);
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif
+160
View File
@@ -0,0 +1,160 @@
// Implementation of INVOKE -*- C++ -*-
// Copyright (C) 2016-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file include/bits/invoke.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{functional}
*/
#ifndef _GLIBCXX_INVOKE_H
#define _GLIBCXX_INVOKE_H 1
#pragma GCC system_header
#if __cplusplus < 201103L
# include <bits/c++0x_warning.h>
#else
#include <type_traits>
#include <bits/move.h> // forward
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
* @addtogroup utilities
* @{
*/
// Used by __invoke_impl instead of std::forward<_Tp> so that a
// reference_wrapper is converted to an lvalue-reference.
template<typename _Tp, typename _Up = typename __inv_unwrap<_Tp>::type>
constexpr _Up&&
__invfwd(typename remove_reference<_Tp>::type& __t) noexcept
{ return static_cast<_Up&&>(__t); }
template<typename _Res, typename _Fn, typename... _Args>
constexpr _Res
__invoke_impl(__invoke_other, _Fn&& __f, _Args&&... __args)
{ return std::forward<_Fn>(__f)(std::forward<_Args>(__args)...); }
template<typename _Res, typename _MemFun, typename _Tp, typename... _Args>
constexpr _Res
__invoke_impl(__invoke_memfun_ref, _MemFun&& __f, _Tp&& __t,
_Args&&... __args)
{ return (__invfwd<_Tp>(__t).*__f)(std::forward<_Args>(__args)...); }
template<typename _Res, typename _MemFun, typename _Tp, typename... _Args>
constexpr _Res
__invoke_impl(__invoke_memfun_deref, _MemFun&& __f, _Tp&& __t,
_Args&&... __args)
{
return ((*std::forward<_Tp>(__t)).*__f)(std::forward<_Args>(__args)...);
}
template<typename _Res, typename _MemPtr, typename _Tp>
constexpr _Res
__invoke_impl(__invoke_memobj_ref, _MemPtr&& __f, _Tp&& __t)
{ return __invfwd<_Tp>(__t).*__f; }
template<typename _Res, typename _MemPtr, typename _Tp>
constexpr _Res
__invoke_impl(__invoke_memobj_deref, _MemPtr&& __f, _Tp&& __t)
{ return (*std::forward<_Tp>(__t)).*__f; }
/// Invoke a callable object.
template<typename _Callable, typename... _Args>
constexpr typename __invoke_result<_Callable, _Args...>::type
__invoke(_Callable&& __fn, _Args&&... __args)
noexcept(__is_nothrow_invocable<_Callable, _Args...>::value)
{
using __result = __invoke_result<_Callable, _Args...>;
using __type = typename __result::type;
using __tag = typename __result::__invoke_type;
return std::__invoke_impl<__type>(__tag{}, std::forward<_Callable>(__fn),
std::forward<_Args>(__args)...);
}
#if __cplusplus >= 201703L
// INVOKE<R>: Invoke a callable object and convert the result to R.
template<typename _Res, typename _Callable, typename... _Args>
constexpr enable_if_t<is_invocable_r_v<_Res, _Callable, _Args...>, _Res>
__invoke_r(_Callable&& __fn, _Args&&... __args)
noexcept(is_nothrow_invocable_r_v<_Res, _Callable, _Args...>)
{
using __result = __invoke_result<_Callable, _Args...>;
using __type = typename __result::type;
using __tag = typename __result::__invoke_type;
if constexpr (is_void_v<_Res>)
std::__invoke_impl<__type>(__tag{}, std::forward<_Callable>(__fn),
std::forward<_Args>(__args)...);
else
return std::__invoke_impl<__type>(__tag{},
std::forward<_Callable>(__fn),
std::forward<_Args>(__args)...);
}
#else // C++11 or C++14
// This is a non-SFINAE-friendly std::invoke_r<R>(fn, args...) for C++11/14.
// It's used in std::function, std::bind, and std::packaged_task. Only
// std::function is constrained on is_invocable_r, but that is checked on
// construction so doesn't need to be checked again when calling __invoke_r.
// Consequently, these __invoke_r overloads do not check for invocable
// arguments, nor check that the invoke result is convertible to R.
// INVOKE<R>: Invoke a callable object and convert the result to R.
template<typename _Res, typename _Callable, typename... _Args>
constexpr __enable_if_t<!is_void<_Res>::value, _Res>
__invoke_r(_Callable&& __fn, _Args&&... __args)
{
using __result = __invoke_result<_Callable, _Args...>;
using __type = typename __result::type;
#if __has_builtin(__reference_converts_from_temporary)
static_assert(!__reference_converts_from_temporary(_Res, __type),
"INVOKE<R> must not create a dangling reference");
#endif
using __tag = typename __result::__invoke_type;
return std::__invoke_impl<__type>(__tag{}, std::forward<_Callable>(__fn),
std::forward<_Args>(__args)...);
}
// INVOKE<R> when R is cv void
template<typename _Res, typename _Callable, typename... _Args>
_GLIBCXX14_CONSTEXPR __enable_if_t<is_void<_Res>::value, _Res>
__invoke_r(_Callable&& __fn, _Args&&... __args)
{
using __result = __invoke_result<_Callable, _Args...>;
using __type = typename __result::type;
using __tag = typename __result::__invoke_type;
std::__invoke_impl<__type>(__tag{}, std::forward<_Callable>(__fn),
std::forward<_Args>(__args)...);
}
#endif // C++11 or C++14
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif // C++11
#endif // _GLIBCXX_INVOKE_H
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,823 @@
// <max_size_type.h> -*- C++ -*-
// Copyright (C) 2019-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/max_size_type.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{iterator}
*/
#ifndef _GLIBCXX_MAX_SIZE_TYPE_H
#define _GLIBCXX_MAX_SIZE_TYPE_H 1
#pragma GCC system_header
#if __cplusplus > 201703L && __cpp_lib_concepts
#include <ext/numeric_traits.h>
#include <numbers>
// This header implements unsigned and signed integer-class types (as per
// [iterator.concept.winc]) that are one bit wider than the widest supported
// integer type.
//
// The set of integer types we consider includes __int128 and unsigned __int128
// (when they exist), even though they are really integer types only in GNU
// mode. This is to obtain a consistent ABI for these integer-class types
// across strict mode and GNU mode.
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Tp>
struct numeric_limits;
namespace ranges
{
namespace __detail
{
class __max_size_type
{
public:
__max_size_type() = default;
template<typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
constexpr
__max_size_type(_Tp __i) noexcept
: _M_val(__i), _M_msb(__i < 0)
{ }
constexpr explicit
__max_size_type(const __max_diff_type& __d) noexcept;
template<typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
constexpr explicit
operator _Tp() const noexcept
{ return _M_val; }
constexpr explicit
operator bool() const noexcept
{ return _M_val != 0 || _M_msb != 0; }
constexpr __max_size_type
operator+() const noexcept
{ return *this; }
constexpr __max_size_type
operator~() const noexcept
{ return __max_size_type{~_M_val, !_M_msb}; }
constexpr __max_size_type
operator-() const noexcept
{ return operator~() + 1; }
constexpr __max_size_type&
operator++() noexcept
{ return *this += 1; }
constexpr __max_size_type
operator++(int) noexcept
{
auto __tmp = *this;
++*this;
return __tmp;
}
constexpr __max_size_type&
operator--() noexcept
{ return *this -= 1; }
constexpr __max_size_type
operator--(int) noexcept
{
auto __tmp = *this;
--*this;
return __tmp;
}
constexpr __max_size_type&
operator+=(const __max_size_type& __r) noexcept
{
const auto __sum = _M_val + __r._M_val;
const bool __overflow = (__sum < _M_val);
_M_msb = _M_msb ^ __r._M_msb ^ __overflow;
_M_val = __sum;
return *this;
}
constexpr __max_size_type&
operator-=(const __max_size_type& __r) noexcept
{ return *this += -__r; }
constexpr __max_size_type&
operator*=(__max_size_type __r) noexcept
{
constexpr __max_size_type __threshold
= __rep(1) << (_S_rep_bits / 2 - 1);
if (_M_val < __threshold && __r < __threshold)
// When both operands are below this threshold then the
// multiplication can be safely computed in the base precision.
_M_val = _M_val * __r._M_val;
else
{
// Otherwise, perform the multiplication in four steps, by
// decomposing the LHS and the RHS into 2*x+a and 2*y+b,
// respectively, and computing 4*x*y + 2*x*b + 2*y*a + a*b.
const bool __lsb = _M_val & 1;
const bool __rlsb = __r._M_val & 1;
*this >>= 1;
__r >>= 1;
_M_val = (2 * _M_val * __r._M_val
+ _M_val * __rlsb + __r._M_val * __lsb);
*this <<= 1;
*this += __rlsb * __lsb;
}
return *this;
}
constexpr __max_size_type&
operator/=(const __max_size_type& __r) noexcept
{
__glibcxx_assert(__r != 0);
if (!_M_msb && !__r._M_msb) [[likely]]
_M_val /= __r._M_val;
else if (_M_msb && __r._M_msb)
{
_M_val = (_M_val >= __r._M_val);
_M_msb = 0;
}
else if (!_M_msb && __r._M_msb)
_M_val = 0;
else if (_M_msb && !__r._M_msb)
{
// The non-trivial case: the dividend has its MSB set and the
// divisor doesn't. In this case we compute ((LHS/2)/RHS)*2
// in the base precision. This quantity is either the true
// quotient or one less than the true quotient.
const auto __orig = *this;
*this >>= 1;
_M_val /= __r._M_val;
*this <<= 1;
if (__orig - *this * __r >= __r)
++_M_val;
}
return *this;
}
constexpr __max_size_type&
operator%=(const __max_size_type& __r) noexcept
{
if (!_M_msb && !__r._M_msb) [[likely]]
_M_val %= __r._M_val;
else
*this -= (*this / __r) * __r;
return *this;
}
constexpr __max_size_type&
operator<<=(const __max_size_type& __r) noexcept
{
__glibcxx_assert(__r <= _S_rep_bits);
if (__r != 0)
{
_M_msb = (_M_val >> (_S_rep_bits - __r._M_val)) & 1;
if (__r._M_val == _S_rep_bits) [[unlikely]]
_M_val = 0;
else
_M_val <<= __r._M_val;
}
return *this;
}
constexpr __max_size_type&
operator>>=(const __max_size_type& __r) noexcept
{
__glibcxx_assert(__r <= _S_rep_bits);
if (__r != 0)
{
if (__r._M_val == _S_rep_bits) [[unlikely]]
_M_val = 0;
else
_M_val >>= __r._M_val;
if (_M_msb) [[unlikely]]
{
_M_val |= __rep(1) << (_S_rep_bits - __r._M_val);
_M_msb = 0;
}
}
return *this;
}
constexpr __max_size_type&
operator&=(const __max_size_type& __r) noexcept
{
_M_val &= __r._M_val;
_M_msb &= __r._M_msb;
return *this;
}
constexpr __max_size_type&
operator|=(const __max_size_type& __r) noexcept
{
_M_val |= __r._M_val;
_M_msb |= __r._M_msb;
return *this;
}
constexpr __max_size_type&
operator^=(const __max_size_type& __r) noexcept
{
_M_val ^= __r._M_val;
_M_msb ^= __r._M_msb;
return *this;
}
template<typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
friend constexpr _Tp&
operator+=(_Tp& __a, const __max_size_type& __b) noexcept
{ return (__a = static_cast<_Tp>(__a + __b)); }
template<typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
friend constexpr _Tp&
operator-=(_Tp& __a, const __max_size_type& __b) noexcept
{ return (__a = static_cast<_Tp>(__a - __b)); }
template<typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
friend constexpr _Tp&
operator*=(_Tp& __a, const __max_size_type& __b) noexcept
{ return (__a = static_cast<_Tp>(__a * __b)); }
template<typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
friend constexpr _Tp&
operator/=(_Tp& __a, const __max_size_type& __b) noexcept
{ return (__a = static_cast<_Tp>(__a / __b)); }
template<typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
friend constexpr _Tp&
operator%=(_Tp& __a, const __max_size_type& __b) noexcept
{ return (__a = static_cast<_Tp>(__a % __b)); }
template<typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
friend constexpr _Tp&
operator&=(_Tp& __a, const __max_size_type& __b) noexcept
{ return (__a = static_cast<_Tp>(__a & __b)); }
template<typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
friend constexpr _Tp&
operator|=(_Tp& __a, const __max_size_type& __b) noexcept
{ return (__a = static_cast<_Tp>(__a | __b)); }
template<typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
friend constexpr _Tp&
operator^=(_Tp& __a, const __max_size_type& __b) noexcept
{ return (__a = static_cast<_Tp>(__a ^ __b)); }
template<typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
friend constexpr _Tp&
operator<<=(_Tp& __a, const __max_size_type& __b) noexcept
{ return (__a = static_cast<_Tp>(__a << __b)); }
template<typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
friend constexpr _Tp&
operator>>=(_Tp& __a, const __max_size_type& __b) noexcept
{ return (__a = static_cast<_Tp>(__a >> __b)); }
friend constexpr __max_size_type
operator+(__max_size_type __l, const __max_size_type& __r) noexcept
{
__l += __r;
return __l;
}
friend constexpr __max_size_type
operator-(__max_size_type __l, const __max_size_type& __r) noexcept
{
__l -= __r;
return __l;
}
friend constexpr __max_size_type
operator*(__max_size_type __l, const __max_size_type& __r) noexcept
{
__l *= __r;
return __l;
}
friend constexpr __max_size_type
operator/(__max_size_type __l, const __max_size_type& __r) noexcept
{
__l /= __r;
return __l;
}
friend constexpr __max_size_type
operator%(__max_size_type __l, const __max_size_type& __r) noexcept
{
__l %= __r;
return __l;
}
friend constexpr __max_size_type
operator<<(__max_size_type __l, const __max_size_type& __r) noexcept
{
__l <<= __r;
return __l;
}
friend constexpr __max_size_type
operator>>(__max_size_type __l, const __max_size_type& __r) noexcept
{
__l >>= __r;
return __l;
}
friend constexpr __max_size_type
operator&(__max_size_type __l, const __max_size_type& __r) noexcept
{
__l &= __r;
return __l;
}
friend constexpr __max_size_type
operator|(__max_size_type __l, const __max_size_type& __r) noexcept
{
__l |= __r;
return __l;
}
friend constexpr __max_size_type
operator^(__max_size_type __l, const __max_size_type& __r) noexcept
{
__l ^= __r;
return __l;
}
friend constexpr bool
operator==(const __max_size_type& __l, const __max_size_type& __r) noexcept
{ return __l._M_val == __r._M_val && __l._M_msb == __r._M_msb; }
#if __cpp_lib_three_way_comparison
friend constexpr strong_ordering
operator<=>(const __max_size_type& __l, const __max_size_type& __r) noexcept
{
if (__l._M_msb ^ __r._M_msb)
return __l._M_msb ? strong_ordering::greater : strong_ordering::less;
else
return __l._M_val <=> __r._M_val;
}
#else
friend constexpr bool
operator!=(const __max_size_type& __l, const __max_size_type& __r) noexcept
{ return !(__l == __r); }
friend constexpr bool
operator<(const __max_size_type& __l, const __max_size_type& __r) noexcept
{
if (__l._M_msb == __r._M_msb)
return __l._M_val < __r._M_val;
else
return __r._M_msb;
}
friend constexpr bool
operator>(const __max_size_type& __l, const __max_size_type& __r) noexcept
{ return __r < __l; }
friend constexpr bool
operator<=(const __max_size_type& __l, const __max_size_type& __r) noexcept
{ return !(__l > __r); }
friend constexpr bool
operator>=(const __max_size_type& __l, const __max_size_type& __r) noexcept
{ return __r <= __l; }
#endif
#if __SIZEOF_INT128__
__extension__
using __rep = unsigned __int128;
#else
using __rep = unsigned long long;
#endif
static constexpr size_t _S_rep_bits = sizeof(__rep) * __CHAR_BIT__;
private:
__rep _M_val = 0;
unsigned _M_msb:1 = 0;
constexpr explicit
__max_size_type(__rep __val, int __msb) noexcept
: _M_val(__val), _M_msb(__msb)
{ }
friend __max_diff_type;
friend std::numeric_limits<__max_size_type>;
friend std::numeric_limits<__max_diff_type>;
};
class __max_diff_type
{
public:
__max_diff_type() = default;
template<typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
constexpr
__max_diff_type(_Tp __i) noexcept
: _M_rep(__i)
{ }
constexpr explicit
__max_diff_type(const __max_size_type& __d) noexcept
: _M_rep(__d)
{ }
template<typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
constexpr explicit
operator _Tp() const noexcept
{ return static_cast<_Tp>(_M_rep); }
constexpr explicit
operator bool() const noexcept
{ return _M_rep != 0; }
constexpr __max_diff_type
operator+() const noexcept
{ return *this; }
constexpr __max_diff_type
operator-() const noexcept
{ return __max_diff_type(-_M_rep); }
constexpr __max_diff_type
operator~() const noexcept
{ return __max_diff_type(~_M_rep); }
constexpr __max_diff_type&
operator++() noexcept
{ return *this += 1; }
constexpr __max_diff_type
operator++(int) noexcept
{
auto __tmp = *this;
++*this;
return __tmp;
}
constexpr __max_diff_type&
operator--() noexcept
{ return *this -= 1; }
constexpr __max_diff_type
operator--(int) noexcept
{
auto __tmp = *this;
--*this;
return __tmp;
}
constexpr __max_diff_type&
operator+=(const __max_diff_type& __r) noexcept
{
_M_rep += __r._M_rep;
return *this;
}
constexpr __max_diff_type&
operator-=(const __max_diff_type& __r) noexcept
{
_M_rep -= __r._M_rep;
return *this;
}
constexpr __max_diff_type&
operator*=(const __max_diff_type& __r) noexcept
{
_M_rep *= __r._M_rep;
return *this;
}
constexpr __max_diff_type&
operator/=(const __max_diff_type& __r) noexcept
{
__glibcxx_assert (__r != 0);
const bool __neg = *this < 0;
const bool __rneg = __r < 0;
if (!__neg && !__rneg)
_M_rep = _M_rep / __r._M_rep;
else if (__neg && __rneg)
_M_rep = -_M_rep / -__r._M_rep;
else if (__neg && !__rneg)
_M_rep = -(-_M_rep / __r._M_rep);
else
_M_rep = -(_M_rep / -__r._M_rep);
return *this ;
}
constexpr __max_diff_type&
operator%=(const __max_diff_type& __r) noexcept
{
__glibcxx_assert (__r != 0);
if (*this >= 0 && __r > 0)
_M_rep %= __r._M_rep;
else
*this -= (*this / __r) * __r;
return *this;
}
constexpr __max_diff_type&
operator<<=(const __max_diff_type& __r) noexcept
{
_M_rep.operator<<=(__r._M_rep);
return *this;
}
constexpr __max_diff_type&
operator>>=(const __max_diff_type& __r) noexcept
{
// Arithmetic right shift.
const auto __msb = _M_rep._M_msb;
_M_rep >>= __r._M_rep;
if (__msb)
_M_rep |= ~(__max_size_type(-1) >> __r._M_rep);
return *this;
}
constexpr __max_diff_type&
operator&=(const __max_diff_type& __r) noexcept
{
_M_rep &= __r._M_rep;
return *this;
}
constexpr __max_diff_type&
operator|=(const __max_diff_type& __r) noexcept
{
_M_rep |= __r._M_rep;
return *this;
}
constexpr __max_diff_type&
operator^=(const __max_diff_type& __r) noexcept
{
_M_rep ^= __r._M_rep;
return *this;
}
template<typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
friend constexpr _Tp&
operator+=(_Tp& __a, const __max_diff_type& __b) noexcept
{ return (__a = static_cast<_Tp>(__a + __b)); }
template<typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
friend constexpr _Tp&
operator-=(_Tp& __a, const __max_diff_type& __b) noexcept
{ return (__a = static_cast<_Tp>(__a - __b)); }
template<typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
friend constexpr _Tp&
operator*=(_Tp& __a, const __max_diff_type& __b) noexcept
{ return (__a = static_cast<_Tp>(__a * __b)); }
template<typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
friend constexpr _Tp&
operator/=(_Tp& __a, const __max_diff_type& __b) noexcept
{ return (__a = static_cast<_Tp>(__a / __b)); }
template<typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
friend constexpr _Tp&
operator%=(_Tp& __a, const __max_diff_type& __b) noexcept
{ return (__a = static_cast<_Tp>(__a % __b)); }
template<typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
friend constexpr _Tp&
operator&=(_Tp& __a, const __max_diff_type& __b) noexcept
{ return (__a = static_cast<_Tp>(__a & __b)); }
template<typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
friend constexpr _Tp&
operator|=(_Tp& __a, const __max_diff_type& __b) noexcept
{ return (__a = static_cast<_Tp>(__a | __b)); }
template<typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
friend constexpr _Tp&
operator^=(_Tp& __a, const __max_diff_type& __b) noexcept
{ return (__a = static_cast<_Tp>(__a ^ __b)); }
template<typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
friend constexpr _Tp&
operator<<=(_Tp& __a, const __max_diff_type& __b) noexcept
{ return (__a = static_cast<_Tp>(__a << __b)); }
template<typename _Tp> requires integral<_Tp> || __is_int128<_Tp>
friend constexpr _Tp&
operator>>=(_Tp& __a, const __max_diff_type& __b) noexcept
{ return (__a = static_cast<_Tp>(__a >> __b)); }
friend constexpr __max_diff_type
operator+(__max_diff_type __l, const __max_diff_type& __r) noexcept
{
__l += __r;
return __l;
}
friend constexpr __max_diff_type
operator-(__max_diff_type __l, const __max_diff_type& __r) noexcept
{
__l -= __r;
return __l;
}
friend constexpr __max_diff_type
operator*(__max_diff_type __l, const __max_diff_type& __r) noexcept
{
__l *= __r;
return __l;
}
friend constexpr __max_diff_type
operator/(__max_diff_type __l, const __max_diff_type& __r) noexcept
{
__l /= __r;
return __l;
}
friend constexpr __max_diff_type
operator%(__max_diff_type __l, const __max_diff_type& __r) noexcept
{
__l %= __r;
return __l;
}
friend constexpr __max_diff_type
operator<<(__max_diff_type __l, const __max_diff_type& __r) noexcept
{
__l <<= __r;
return __l;
}
friend constexpr __max_diff_type
operator>>(__max_diff_type __l, const __max_diff_type& __r) noexcept
{
__l >>= __r;
return __l;
}
friend constexpr __max_diff_type
operator&(__max_diff_type __l, const __max_diff_type& __r) noexcept
{
__l &= __r;
return __l;
}
friend constexpr __max_diff_type
operator|(__max_diff_type __l, const __max_diff_type& __r) noexcept
{
__l |= __r;
return __l;
}
friend constexpr __max_diff_type
operator^(__max_diff_type __l, const __max_diff_type& __r) noexcept
{
__l ^= __r;
return __l;
}
friend constexpr bool
operator==(const __max_diff_type& __l, const __max_diff_type& __r) noexcept
{ return __l._M_rep == __r._M_rep; }
#if __cpp_lib_three_way_comparison
constexpr strong_ordering
operator<=>(const __max_diff_type& __r) const noexcept
{
const auto __lsign = _M_rep._M_msb;
const auto __rsign = __r._M_rep._M_msb;
if (__lsign ^ __rsign)
return __lsign ? strong_ordering::less : strong_ordering::greater;
else
return _M_rep <=> __r._M_rep;
}
#else
friend constexpr bool
operator!=(const __max_diff_type& __l, const __max_diff_type& __r) noexcept
{ return !(__l == __r); }
constexpr bool
operator<(const __max_diff_type& __r) const noexcept
{
const auto __lsign = _M_rep._M_msb;
const auto __rsign = __r._M_rep._M_msb;
if (__lsign ^ __rsign)
return __lsign;
else
return _M_rep < __r._M_rep;
}
friend constexpr bool
operator>(const __max_diff_type& __l, const __max_diff_type& __r) noexcept
{ return __r < __l; }
friend constexpr bool
operator<=(const __max_diff_type& __l, const __max_diff_type& __r) noexcept
{ return !(__r < __l); }
friend constexpr bool
operator>=(const __max_diff_type& __l, const __max_diff_type& __r) noexcept
{ return !(__l < __r); }
#endif
private:
__max_size_type _M_rep = 0;
friend class __max_size_type;
};
constexpr
__max_size_type::__max_size_type(const __max_diff_type& __d) noexcept
: __max_size_type(__d._M_rep)
{ }
} // namespace __detail
} // namespace ranges
template<>
struct numeric_limits<ranges::__detail::__max_size_type>
{
using _Sp = ranges::__detail::__max_size_type;
static constexpr bool is_specialized = true;
static constexpr bool is_signed = false;
static constexpr bool is_integer = true;
static constexpr bool is_exact = true;
static constexpr int digits
= __gnu_cxx::__int_traits<_Sp::__rep>::__digits + 1;
static constexpr int digits10
= static_cast<int>(digits * numbers::ln2 / numbers::ln10);
static constexpr _Sp
min() noexcept
{ return 0; }
static constexpr _Sp
max() noexcept
{ return _Sp(static_cast<_Sp::__rep>(-1), 1); }
static constexpr _Sp
lowest() noexcept
{ return min(); }
};
template<>
struct numeric_limits<ranges::__detail::__max_diff_type>
{
using _Dp = ranges::__detail::__max_diff_type;
using _Sp = ranges::__detail::__max_size_type;
static constexpr bool is_specialized = true;
static constexpr bool is_signed = true;
static constexpr bool is_integer = true;
static constexpr bool is_exact = true;
static constexpr int digits = numeric_limits<_Sp>::digits - 1;
static constexpr int digits10
= static_cast<int>(digits * numbers::ln2 / numbers::ln10);
static constexpr _Dp
min() noexcept
{ return _Dp(_Sp(0, 1)); }
static constexpr _Dp
max() noexcept
{ return _Dp(_Sp(static_cast<_Sp::__rep>(-1), 0)); }
static constexpr _Dp
lowest() noexcept
{ return min(); }
};
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif // C++20 && library concepts
#endif // _GLIBCXX_MAX_SIZE_TYPE_H
+84
View File
@@ -0,0 +1,84 @@
// <memory> Forward declarations -*- C++ -*-
// Copyright (C) 2001-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/*
* Copyright (c) 1996-1997
* Silicon Graphics Computer Systems, Inc.
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Silicon Graphics makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*/
/** @file bits/memoryfwd.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{memory}
*/
#ifndef _MEMORYFWD_H
#define _MEMORYFWD_H 1
#pragma GCC system_header
#include <bits/c++config.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
* @defgroup allocators Allocators
* @ingroup memory
*
* Classes encapsulating memory operations.
*
* @{
*/
// Included in freestanding as a libstdc++ extension.
template<typename>
class allocator;
template<>
class allocator<void>;
#if __cplusplus >= 201103L
/// Declare uses_allocator so it can be specialized in `<queue>` etc.
template<typename, typename>
struct uses_allocator;
template<typename>
struct allocator_traits;
#endif
/// @} group memory
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif
@@ -0,0 +1,92 @@
// std::messages implementation details, generic version -*- C++ -*-
// Copyright (C) 2001-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/messages_members.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{locale}
*/
//
// ISO C++ 14882: 22.2.7.1.2 messages virtual functions
//
// Written by Benjamin Kosnik <bkoz@redhat.com>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
// Non-virtual member functions.
template<typename _CharT>
messages<_CharT>::messages(size_t __refs)
: facet(__refs)
{ _M_c_locale_messages = _S_get_c_locale(); }
template<typename _CharT>
messages<_CharT>::messages(__c_locale, const char*, size_t __refs)
: facet(__refs)
{ _M_c_locale_messages = _S_get_c_locale(); }
template<typename _CharT>
typename messages<_CharT>::catalog
messages<_CharT>::open(const basic_string<char>& __s, const locale& __loc,
const char*) const
{ return this->do_open(__s, __loc); }
// Virtual member functions.
template<typename _CharT>
messages<_CharT>::~messages()
{ _S_destroy_c_locale(_M_c_locale_messages); }
template<typename _CharT>
typename messages<_CharT>::catalog
messages<_CharT>::do_open(const basic_string<char>&, const locale&) const
{ return 0; }
template<typename _CharT>
typename messages<_CharT>::string_type
messages<_CharT>::do_get(catalog, int, int,
const string_type& __dfault) const
{ return __dfault; }
template<typename _CharT>
void
messages<_CharT>::do_close(catalog) const
{ }
// messages_byname
template<typename _CharT>
messages_byname<_CharT>::messages_byname(const char* __s, size_t __refs)
: messages<_CharT>(__refs)
{
if (__builtin_strcmp(__s, "C") != 0
&& __builtin_strcmp(__s, "POSIX") != 0)
{
this->_S_destroy_c_locale(this->_M_c_locale_messages);
this->_S_create_c_locale(this->_M_c_locale_messages, __s);
}
}
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
+248
View File
@@ -0,0 +1,248 @@
// Move, forward and identity for C++11 + swap -*- C++ -*-
// Copyright (C) 2007-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/move.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{utility}
*/
#ifndef _MOVE_H
#define _MOVE_H 1
#include <bits/c++config.h>
#if __cplusplus < 201103L
# include <bits/concept_check.h>
#else
# include <type_traits> // Brings in std::declval too.
#endif
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
// Used, in C++03 mode too, by allocators, etc.
/**
* @brief Same as C++11 std::addressof
* @ingroup utilities
*/
template<typename _Tp>
inline _GLIBCXX_CONSTEXPR _Tp*
__addressof(_Tp& __r) _GLIBCXX_NOEXCEPT
{ return __builtin_addressof(__r); }
#if __cplusplus >= 201103L
/**
* @addtogroup utilities
* @{
*/
/**
* @brief Forward an lvalue.
* @return The parameter cast to the specified type.
*
* This function is used to implement "perfect forwarding".
*/
template<typename _Tp>
_GLIBCXX_NODISCARD
constexpr _Tp&&
forward(typename std::remove_reference<_Tp>::type& __t) noexcept
{ return static_cast<_Tp&&>(__t); }
/**
* @brief Forward an rvalue.
* @return The parameter cast to the specified type.
*
* This function is used to implement "perfect forwarding".
*/
template<typename _Tp>
_GLIBCXX_NODISCARD
constexpr _Tp&&
forward(typename std::remove_reference<_Tp>::type&& __t) noexcept
{
static_assert(!std::is_lvalue_reference<_Tp>::value,
"std::forward must not be used to convert an rvalue to an lvalue");
return static_cast<_Tp&&>(__t);
}
#if __glibcxx_forward_like // C++ >= 23
template<typename _Tp, typename _Up>
[[nodiscard]]
constexpr decltype(auto)
forward_like(_Up&& __x) noexcept
{
constexpr bool __as_rval = is_rvalue_reference_v<_Tp&&>;
if constexpr (is_const_v<remove_reference_t<_Tp>>)
{
using _Up2 = remove_reference_t<_Up>;
if constexpr (__as_rval)
return static_cast<const _Up2&&>(__x);
else
return static_cast<const _Up2&>(__x);
}
else
{
if constexpr (__as_rval)
return static_cast<remove_reference_t<_Up>&&>(__x);
else
return static_cast<_Up&>(__x);
}
}
template<typename _Tp, typename _Up>
using __like_t = decltype(std::forward_like<_Tp>(std::declval<_Up>()));
#endif
/**
* @brief Convert a value to an rvalue.
* @param __t A thing of arbitrary type.
* @return The parameter cast to an rvalue-reference to allow moving it.
*/
template<typename _Tp>
_GLIBCXX_NODISCARD
constexpr typename std::remove_reference<_Tp>::type&&
move(_Tp&& __t) noexcept
{ return static_cast<typename std::remove_reference<_Tp>::type&&>(__t); }
template<typename _Tp>
struct __move_if_noexcept_cond
: public __and_<__not_<is_nothrow_move_constructible<_Tp>>,
is_copy_constructible<_Tp>>::type { };
/**
* @brief Conditionally convert a value to an rvalue.
* @param __x A thing of arbitrary type.
* @return The parameter, possibly cast to an rvalue-reference.
*
* Same as std::move unless the type's move constructor could throw and the
* type is copyable, in which case an lvalue-reference is returned instead.
*/
template<typename _Tp>
_GLIBCXX_NODISCARD
constexpr
__conditional_t<__move_if_noexcept_cond<_Tp>::value, const _Tp&, _Tp&&>
move_if_noexcept(_Tp& __x) noexcept
{ return std::move(__x); }
// declval, from type_traits.
/**
* @brief Returns the actual address of the object or function
* referenced by r, even in the presence of an overloaded
* operator&.
* @param __r Reference to an object or function.
* @return The actual address.
*/
template<typename _Tp>
_GLIBCXX_NODISCARD
inline _GLIBCXX17_CONSTEXPR _Tp*
addressof(_Tp& __r) noexcept
{ return std::__addressof(__r); }
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 2598. addressof works on temporaries
template<typename _Tp>
const _Tp* addressof(const _Tp&&) = delete;
// C++11 version of std::exchange for internal use.
template <typename _Tp, typename _Up = _Tp>
_GLIBCXX20_CONSTEXPR
inline _Tp
__exchange(_Tp& __obj, _Up&& __new_val)
{
_Tp __old_val = std::move(__obj);
__obj = std::forward<_Up>(__new_val);
return __old_val;
}
/// @} group utilities
#define _GLIBCXX_FWDREF(_Tp) _Tp&&
#define _GLIBCXX_MOVE(__val) std::move(__val)
#define _GLIBCXX_FORWARD(_Tp, __val) std::forward<_Tp>(__val)
#else
#define _GLIBCXX_FWDREF(_Tp) const _Tp&
#define _GLIBCXX_MOVE(__val) (__val)
#define _GLIBCXX_FORWARD(_Tp, __val) (__val)
#endif
/**
* @addtogroup utilities
* @{
*/
/**
* @brief Swaps two values.
* @param __a A thing of arbitrary type.
* @param __b Another thing of arbitrary type.
* @return Nothing.
*/
template<typename _Tp>
_GLIBCXX20_CONSTEXPR
inline
#if __cplusplus >= 201103L
typename enable_if<__and_<__not_<__is_tuple_like<_Tp>>,
is_move_constructible<_Tp>,
is_move_assignable<_Tp>>::value>::type
#else
void
#endif
swap(_Tp& __a, _Tp& __b)
_GLIBCXX_NOEXCEPT_IF(__and_<is_nothrow_move_constructible<_Tp>,
is_nothrow_move_assignable<_Tp>>::value)
{
#if __cplusplus < 201103L
// concept requirements
__glibcxx_function_requires(_SGIAssignableConcept<_Tp>)
#endif
_Tp __tmp = _GLIBCXX_MOVE(__a);
__a = _GLIBCXX_MOVE(__b);
__b = _GLIBCXX_MOVE(__tmp);
}
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 809. std::swap should be overloaded for array types.
/// Swap the contents of two arrays.
template<typename _Tp, size_t _Nm>
_GLIBCXX20_CONSTEXPR
inline
#if __cplusplus >= 201103L
typename enable_if<__is_swappable<_Tp>::value>::type
#else
void
#endif
swap(_Tp (&__a)[_Nm], _Tp (&__b)[_Nm])
_GLIBCXX_NOEXCEPT_IF(__is_nothrow_swappable<_Tp>::value)
{
for (size_t __n = 0; __n < _Nm; ++__n)
swap(__a[__n], __b[__n]);
}
/// @} group utilities
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif /* _MOVE_H */
@@ -0,0 +1,243 @@
// Nested Exception support header (nested_exception class) for -*- C++ -*-
// Copyright (C) 2009-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/nested_exception.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{exception}
*/
#ifndef _GLIBCXX_NESTED_EXCEPTION_H
#define _GLIBCXX_NESTED_EXCEPTION_H 1
#if __cplusplus < 201103L
# include <bits/c++0x_warning.h>
#else
#include <bits/move.h>
#include <bits/exception_ptr.h>
extern "C++" {
namespace std _GLIBCXX_VISIBILITY(default)
{
/**
* @addtogroup exceptions
* @{
*/
/** Mixin class that stores the current exception.
*
* This type can be used via `std::throw_with_nested` to store
* the current exception nested within another exception.
*
* @headerfile exception
* @since C++11
* @see std::throw_with_nested
* @ingroup exceptions
*/
class nested_exception
{
exception_ptr _M_ptr;
public:
/// The default constructor stores the current exception (if any).
nested_exception() noexcept : _M_ptr(current_exception()) { }
nested_exception(const nested_exception&) noexcept = default;
nested_exception& operator=(const nested_exception&) noexcept = default;
virtual ~nested_exception() noexcept;
/// Rethrow the stored exception, or terminate if none was stored.
[[noreturn]]
void
rethrow_nested() const
{
if (_M_ptr)
rethrow_exception(_M_ptr);
std::terminate();
}
/// Access the stored exception.
exception_ptr
nested_ptr() const noexcept
{ return _M_ptr; }
};
/// @cond undocumented
template<typename _Except>
struct _Nested_exception : public _Except, public nested_exception
{
explicit _Nested_exception(const _Except& __ex)
: _Except(__ex)
{ }
explicit _Nested_exception(_Except&& __ex)
: _Except(static_cast<_Except&&>(__ex))
{ }
};
#if __cplusplus < 201703L || ! defined __cpp_if_constexpr
// [except.nested]/8
// Throw an exception of unspecified type that is publicly derived from
// both remove_reference_t<_Tp> and nested_exception.
template<typename _Tp>
[[noreturn]]
inline void
__throw_with_nested_impl(_Tp&& __t, true_type)
{
throw _Nested_exception<__remove_cvref_t<_Tp>>{std::forward<_Tp>(__t)};
}
template<typename _Tp>
[[noreturn]]
inline void
__throw_with_nested_impl(_Tp&& __t, false_type)
{ throw std::forward<_Tp>(__t); }
#endif
/// @endcond
/** Throw an exception that also stores the currently active exception.
*
* If `_Tp` is derived from `std::nested_exception` or is not usable
* as a base-class, throws a copy of `__t`.
* Otherwise, throws an object of an implementation-defined type derived
* from both `_Tp` and `std::nested_exception`, containing a copy of `__t`
* and the result of `std::current_exception()`.
*
* In other words, throws the argument as a new exception that contains
* the currently active exception nested within it. This is intended for
* use in a catch handler to replace the caught exception with a different
* type, while still preserving the original exception. When the new
* exception is caught, the nested exception can be rethrown by using
* `std::rethrow_if_nested`.
*
* This can be used at API boundaries, for example to catch a library's
* internal exception type and rethrow it nested with a `std::runtime_error`,
* or vice versa.
*
* @since C++11
*/
template<typename _Tp>
[[noreturn]]
inline void
throw_with_nested(_Tp&& __t)
{
using _Up = typename decay<_Tp>::type;
using _CopyConstructible
= __and_<is_copy_constructible<_Up>, is_move_constructible<_Up>>;
static_assert(_CopyConstructible::value,
"throw_with_nested argument must be CopyConstructible");
#if __cplusplus >= 201703L && __cpp_if_constexpr
if constexpr (is_class_v<_Up>)
if constexpr (!is_final_v<_Up>)
if constexpr (!is_base_of_v<nested_exception, _Up>)
throw _Nested_exception<_Up>{std::forward<_Tp>(__t)};
throw std::forward<_Tp>(__t);
#else
using __nest = __and_<is_class<_Up>, __bool_constant<!__is_final(_Up)>,
__not_<is_base_of<nested_exception, _Up>>>;
std::__throw_with_nested_impl(std::forward<_Tp>(__t), __nest{});
#endif
}
#if __cplusplus < 201703L || ! defined __cpp_if_constexpr
/// @cond undocumented
// Attempt dynamic_cast to nested_exception and call rethrow_nested().
template<typename _Ex>
inline void
__rethrow_if_nested_impl(const _Ex* __ptr, true_type)
{
if (auto __ne_ptr = dynamic_cast<const nested_exception*>(__ptr))
__ne_ptr->rethrow_nested();
}
// Otherwise, no effects.
inline void
__rethrow_if_nested_impl(const void*, false_type)
{ }
/// @endcond
#endif
/** Rethrow a nested exception
*
* If `__ex` contains a `std::nested_exception` object, call its
* `rethrow_nested()` member to rethrow the stored exception.
*
* After catching an exception thrown by a call to `std::throw_with_nested`
* this function can be used to rethrow the exception that was active when
* `std::throw_with_nested` was called.
*
* @since C++11
*/
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 2484. rethrow_if_nested() is doubly unimplementable
// 2784. Resolution to LWG 2484 is missing "otherwise, no effects" and [...]
template<typename _Ex>
# if ! __cpp_rtti
[[__gnu__::__always_inline__]]
#endif
inline void
rethrow_if_nested(const _Ex& __ex)
{
const _Ex* __ptr = __builtin_addressof(__ex);
#if __cplusplus < 201703L || ! defined __cpp_if_constexpr
# if __cpp_rtti
using __cast = __and_<is_polymorphic<_Ex>,
__or_<__not_<is_base_of<nested_exception, _Ex>>,
is_convertible<_Ex*, nested_exception*>>>;
# else
using __cast = __and_<is_polymorphic<_Ex>,
is_base_of<nested_exception, _Ex>,
is_convertible<_Ex*, nested_exception*>>;
# endif
std::__rethrow_if_nested_impl(__ptr, __cast{});
#else
if constexpr (!is_polymorphic_v<_Ex>)
return;
else if constexpr (is_base_of_v<nested_exception, _Ex>
&& !is_convertible_v<_Ex*, nested_exception*>)
return; // nested_exception base class is inaccessible or ambiguous.
# if ! __cpp_rtti
else if constexpr (!is_base_of_v<nested_exception, _Ex>)
return; // Cannot do polymorphic casts without RTTI.
# endif
else if (auto __ne_ptr = dynamic_cast<const nested_exception*>(__ptr))
__ne_ptr->rethrow_nested();
#endif
}
/// @} group exceptions
} // namespace std
} // extern "C++"
#endif // C++11
#endif // _GLIBCXX_NESTED_EXCEPTION_H
+221
View File
@@ -0,0 +1,221 @@
// Optimizations for random number functions, x86 version -*- C++ -*-
// Copyright (C) 2012-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/opt_random.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{random}
*/
#ifndef _BITS_OPT_RANDOM_H
#define _BITS_OPT_RANDOM_H 1
#ifdef __SSE3__
#include <pmmintrin.h>
#endif
#pragma GCC system_header
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
#ifdef __SSE3__
template<>
template<typename _UniformRandomNumberGenerator>
void
normal_distribution<double>::
__generate(typename normal_distribution<double>::result_type* __f,
typename normal_distribution<double>::result_type* __t,
_UniformRandomNumberGenerator& __urng,
const param_type& __param)
{
typedef uint64_t __uctype;
if (__f == __t)
return;
if (_M_saved_available)
{
_M_saved_available = false;
*__f++ = _M_saved * __param.stddev() + __param.mean();
if (__f == __t)
return;
}
constexpr uint64_t __maskval = 0xfffffffffffffull;
static const __m128i __mask = _mm_set1_epi64x(__maskval);
static const __m128i __two = _mm_set1_epi64x(0x4000000000000000ull);
static const __m128d __three = _mm_set1_pd(3.0);
const __m128d __av = _mm_set1_pd(__param.mean());
const __uctype __urngmin = __urng.min();
const __uctype __urngmax = __urng.max();
const __uctype __urngrange = __urngmax - __urngmin;
const __uctype __uerngrange = __urngrange + 1;
while (__f + 1 < __t)
{
double __le;
__m128d __x;
do
{
union
{
__m128i __i;
__m128d __d;
} __v;
if (__urngrange > __maskval)
{
if (__detail::_Power_of_2(__uerngrange))
__v.__i = _mm_and_si128(_mm_set_epi64x(__urng(),
__urng()),
__mask);
else
{
const __uctype __uerange = __maskval + 1;
const __uctype __scaling = __urngrange / __uerange;
const __uctype __past = __uerange * __scaling;
uint64_t __v1;
do
__v1 = __uctype(__urng()) - __urngmin;
while (__v1 >= __past);
__v1 /= __scaling;
uint64_t __v2;
do
__v2 = __uctype(__urng()) - __urngmin;
while (__v2 >= __past);
__v2 /= __scaling;
__v.__i = _mm_set_epi64x(__v1, __v2);
}
}
else if (__urngrange == __maskval)
__v.__i = _mm_set_epi64x(__urng(), __urng());
else if ((__urngrange + 2) * __urngrange >= __maskval
&& __detail::_Power_of_2(__uerngrange))
{
uint64_t __v1 = __urng() * __uerngrange + __urng();
uint64_t __v2 = __urng() * __uerngrange + __urng();
__v.__i = _mm_and_si128(_mm_set_epi64x(__v1, __v2),
__mask);
}
else
{
size_t __nrng = 2;
__uctype __high = __maskval / __uerngrange / __uerngrange;
while (__high > __uerngrange)
{
++__nrng;
__high /= __uerngrange;
}
const __uctype __highrange = __high + 1;
const __uctype __scaling = __urngrange / __highrange;
const __uctype __past = __highrange * __scaling;
__uctype __tmp;
uint64_t __v1;
do
{
do
__tmp = __uctype(__urng()) - __urngmin;
while (__tmp >= __past);
__v1 = __tmp / __scaling;
for (size_t __cnt = 0; __cnt < __nrng; ++__cnt)
{
__tmp = __v1;
__v1 *= __uerngrange;
__v1 += __uctype(__urng()) - __urngmin;
}
}
while (__v1 > __maskval || __v1 < __tmp);
uint64_t __v2;
do
{
do
__tmp = __uctype(__urng()) - __urngmin;
while (__tmp >= __past);
__v2 = __tmp / __scaling;
for (size_t __cnt = 0; __cnt < __nrng; ++__cnt)
{
__tmp = __v2;
__v2 *= __uerngrange;
__v2 += __uctype(__urng()) - __urngmin;
}
}
while (__v2 > __maskval || __v2 < __tmp);
__v.__i = _mm_set_epi64x(__v1, __v2);
}
__v.__i = _mm_or_si128(__v.__i, __two);
__x = _mm_sub_pd(__v.__d, __three);
__m128d __m = _mm_mul_pd(__x, __x);
__le = _mm_cvtsd_f64(_mm_hadd_pd (__m, __m));
}
while (__le == 0.0 || __le >= 1.0);
double __mult = (std::sqrt(-2.0 * std::log(__le) / __le)
* __param.stddev());
__x = _mm_add_pd(_mm_mul_pd(__x, _mm_set1_pd(__mult)), __av);
_mm_storeu_pd(__f, __x);
__f += 2;
}
if (__f != __t)
{
result_type __x, __y, __r2;
__detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
__aurng(__urng);
do
{
__x = result_type(2.0) * __aurng() - 1.0;
__y = result_type(2.0) * __aurng() - 1.0;
__r2 = __x * __x + __y * __y;
}
while (__r2 > 1.0 || __r2 == 0.0);
const result_type __mult = std::sqrt(-2 * std::log(__r2) / __r2);
_M_saved = __x * __mult;
_M_saved_available = true;
*__f = __y * __mult * __param.stddev() + __param.mean();
}
}
#endif
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif // _BITS_OPT_RANDOM_H
@@ -0,0 +1,41 @@
// Specific definitions for generic platforms -*- C++ -*-
// Copyright (C) 2000-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/os_defines.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{iosfwd}
*/
#ifndef _GLIBCXX_OS_DEFINES
#define _GLIBCXX_OS_DEFINES 1
// System-specific #define, typedefs, corrections, etc, go here. This
// file will come before all others.
// Disable the weak reference logic in gthr.h for os/generic because it
// is broken on every platform unless there is implementation specific
// workaround in gthr-posix.h and at link-time for static linking.
#define _GLIBCXX_GTHREAD_USE_WEAK 0
#endif
+473
View File
@@ -0,0 +1,473 @@
// Smart pointer adaptors -*- C++ -*-
// Copyright The GNU Toolchain Authors.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file include/bits/out_ptr.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{memory}
*/
#ifndef _GLIBCXX_OUT_PTR_H
#define _GLIBCXX_OUT_PTR_H 1
#pragma GCC system_header
#include <bits/version.h>
#ifdef __glibcxx_out_ptr // C++ >= 23
#include <tuple>
#include <bits/ptr_traits.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/// Smart pointer adaptor for functions taking an output pointer parameter.
/**
* @tparam _Smart The type of pointer to adapt.
* @tparam _Pointer The type of pointer to convert to.
* @tparam _Args... Argument types used when resetting the smart pointer.
* @since C++23
* @headerfile <memory>
*/
template<typename _Smart, typename _Pointer, typename... _Args>
class out_ptr_t
{
#if _GLIBCXX_HOSTED
static_assert(!__is_shared_ptr<_Smart> || sizeof...(_Args) != 0,
"a deleter must be used when adapting std::shared_ptr "
"with std::out_ptr");
#endif
public:
explicit
out_ptr_t(_Smart& __smart, _Args... __args)
: _M_impl{__smart, std::forward<_Args>(__args)...}
{
if constexpr (requires { _M_impl._M_out_init(); })
_M_impl._M_out_init();
}
out_ptr_t(const out_ptr_t&) = delete;
~out_ptr_t() = default;
operator _Pointer*() const noexcept
{ return _M_impl._M_get(); }
operator void**() const noexcept requires (!same_as<_Pointer, void*>)
{
static_assert(is_pointer_v<_Pointer>);
_Pointer* __p = *this;
return static_cast<void**>(static_cast<void*>(__p));
}
private:
// TODO: Move this to namespace scope? e.g. __detail::_Ptr_adapt_impl
template<typename, typename, typename...>
struct _Impl
{
// This constructor must not modify __s because out_ptr_t and
// inout_ptr_t want to do different things. After construction
// they call _M_out_init() or _M_inout_init() respectively.
_Impl(_Smart& __s, _Args&&... __args)
: _M_smart(__s), _M_args(std::forward<_Args>(__args)...)
{ }
// Called by out_ptr_t to clear the smart pointer before using it.
void
_M_out_init()
{
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 3734. Inconsistency in inout_ptr and out_ptr for empty case
if constexpr (requires { _M_smart.reset(); })
_M_smart.reset();
else
_M_smart = _Smart();
}
// Called by inout_ptr_t to copy the smart pointer's value
// to the pointer that is returned from _M_get().
void
_M_inout_init()
{ _M_ptr = _M_smart.release(); }
// The pointer value returned by operator Pointer*().
_Pointer*
_M_get() const
{ return __builtin_addressof(const_cast<_Pointer&>(_M_ptr)); }
// Finalize the effects on the smart pointer.
~_Impl() noexcept(false);
_Smart& _M_smart;
[[no_unique_address]] _Pointer _M_ptr{};
[[no_unique_address]] tuple<_Args...> _M_args;
};
// Partial specialization for raw pointers.
template<typename _Tp>
struct _Impl<_Tp*, _Tp*>
{
void
_M_out_init()
{ _M_p = nullptr; }
void
_M_inout_init()
{ }
_Tp**
_M_get() const
{ return __builtin_addressof(const_cast<_Tp*&>(_M_p)); }
_Tp*& _M_p;
};
// Partial specialization for raw pointers, with conversion.
template<typename _Tp, typename _Ptr> requires (!is_same_v<_Ptr, _Tp*>)
struct _Impl<_Tp*, _Ptr>
{
explicit
_Impl(_Tp*& __p)
: _M_p(__p)
{ }
void
_M_out_init()
{ _M_p = nullptr; }
void
_M_inout_init()
{ _M_ptr = _M_p; }
_Pointer*
_M_get() const
{ return __builtin_addressof(const_cast<_Pointer&>(_M_ptr)); }
~_Impl() { _M_p = static_cast<_Tp*>(_M_ptr); }
_Tp*& _M_p;
_Pointer _M_ptr{};
};
// Partial specialization for std::unique_ptr.
// This specialization gives direct access to the private member
// of the unique_ptr, avoiding the overhead of storing a separate
// pointer and then resetting the unique_ptr in the destructor.
// FIXME: constrain to only match the primary template,
// not program-defined specializations of unique_ptr.
template<typename _Tp, typename _Del>
struct _Impl<unique_ptr<_Tp, _Del>,
typename unique_ptr<_Tp, _Del>::pointer>
{
void
_M_out_init()
{ _M_smart.reset(); }
_Pointer*
_M_get() const noexcept
{ return __builtin_addressof(_M_smart._M_t._M_ptr()); }
_Smart& _M_smart;
};
// Partial specialization for std::unique_ptr with replacement deleter.
// FIXME: constrain to only match the primary template,
// not program-defined specializations of unique_ptr.
template<typename _Tp, typename _Del, typename _Del2>
struct _Impl<unique_ptr<_Tp, _Del>,
typename unique_ptr<_Tp, _Del>::pointer, _Del2>
{
void
_M_out_init()
{ _M_smart.reset(); }
_Pointer*
_M_get() const noexcept
{ return __builtin_addressof(_M_smart._M_t._M_ptr()); }
~_Impl()
{
if (_M_smart.get())
_M_smart._M_t._M_deleter() = std::forward<_Del2>(_M_del);
}
_Smart& _M_smart;
[[no_unique_address]] _Del2 _M_del;
};
#if _GLIBCXX_HOSTED
// Partial specialization for std::shared_ptr.
// This specialization gives direct access to the private member
// of the shared_ptr, avoiding the overhead of storing a separate
// pointer and then resetting the shared_ptr in the destructor.
// A new control block is allocated in the constructor, so that if
// allocation fails it doesn't throw an exception from the destructor.
template<typename _Tp, typename _Del, typename _Alloc>
requires (is_base_of_v<__shared_ptr<_Tp>, shared_ptr<_Tp>>)
struct _Impl<shared_ptr<_Tp>,
typename shared_ptr<_Tp>::element_type*, _Del, _Alloc>
{
_Impl(_Smart& __s, _Del __d, _Alloc __a = _Alloc())
: _M_smart(__s)
{
// We know shared_ptr cannot be used with inout_ptr_t
// so we can do all set up here, instead of in _M_out_init().
_M_smart.reset();
// Similar to the shared_ptr(Y*, D, A) constructor, except that if
// the allocation throws we do not need (or want) to call deleter.
typename _Scd::__allocator_type __a2(__a);
auto __mem = __a2.allocate(1);
::new (__mem) _Scd(nullptr, std::forward<_Del>(__d),
std::forward<_Alloc>(__a));
_M_smart._M_refcount._M_pi = __mem;
}
_Pointer*
_M_get() const noexcept
{ return __builtin_addressof(_M_smart._M_ptr); }
~_Impl()
{
auto& __pi = _M_smart._M_refcount._M_pi;
if (_Sp __ptr = _M_smart.get())
static_cast<_Scd*>(__pi)->_M_impl._M_ptr = __ptr;
else // Destroy the control block manually without invoking deleter.
std::__exchange(__pi, nullptr)->_M_destroy();
}
_Smart& _M_smart;
using _Sp = typename _Smart::element_type*;
using _Scd = _Sp_counted_deleter<_Sp, decay_t<_Del>,
remove_cvref_t<_Alloc>,
__default_lock_policy>;
};
// Partial specialization for std::shared_ptr, without custom allocator.
template<typename _Tp, typename _Del>
requires (is_base_of_v<__shared_ptr<_Tp>, shared_ptr<_Tp>>)
struct _Impl<shared_ptr<_Tp>,
typename shared_ptr<_Tp>::element_type*, _Del>
: _Impl<_Smart, _Pointer, _Del, allocator<void>>
{
using _Impl<_Smart, _Pointer, _Del, allocator<void>>::_Impl;
};
#endif
using _Impl_t = _Impl<_Smart, _Pointer, _Args...>;
_Impl_t _M_impl;
template<typename, typename, typename...> friend class inout_ptr_t;
};
/// Smart pointer adaptor for functions taking an inout pointer parameter.
/**
* @tparam _Smart The type of pointer to adapt.
* @tparam _Pointer The type of pointer to convert to.
* @tparam _Args... Argument types used when resetting the smart pointer.
* @since C++23
* @headerfile <memory>
*/
template<typename _Smart, typename _Pointer, typename... _Args>
class inout_ptr_t
{
#if _GLIBCXX_HOSTED
static_assert(!__is_shared_ptr<_Smart>,
"std::inout_ptr can not be used to wrap std::shared_ptr");
#endif
public:
explicit
inout_ptr_t(_Smart& __smart, _Args... __args)
: _M_impl{__smart, std::forward<_Args>(__args)...}
{
if constexpr (requires { _M_impl._M_inout_init(); })
_M_impl._M_inout_init();
}
inout_ptr_t(const inout_ptr_t&) = delete;
~inout_ptr_t() = default;
operator _Pointer*() const noexcept
{ return _M_impl._M_get(); }
operator void**() const noexcept requires (!same_as<_Pointer, void*>)
{
static_assert(is_pointer_v<_Pointer>);
_Pointer* __p = *this;
return static_cast<void**>(static_cast<void*>(__p));
}
private:
#if _GLIBCXX_HOSTED
// Avoid an invalid instantiation of out_ptr_t<shared_ptr<T>, ...>
using _Out_ptr_t
= __conditional_t<__is_shared_ptr<_Smart>,
out_ptr_t<void*, void*>,
out_ptr_t<_Smart, _Pointer, _Args...>>;
#else
using _Out_ptr_t = out_ptr_t<_Smart, _Pointer, _Args...>;
#endif
using _Impl_t = typename _Out_ptr_t::_Impl_t;
_Impl_t _M_impl;
};
/// @cond undocumented
namespace __detail
{
// POINTER_OF metafunction
template<typename _Tp>
consteval auto
__pointer_of()
{
if constexpr (requires { typename _Tp::pointer; })
return type_identity<typename _Tp::pointer>{};
else if constexpr (requires { typename _Tp::element_type; })
return type_identity<typename _Tp::element_type*>{};
else
{
using _Traits = pointer_traits<_Tp>;
if constexpr (requires { typename _Traits::element_type; })
return type_identity<typename _Traits::element_type*>{};
}
// else POINTER_OF(S) is not a valid type, return void.
}
// POINTER_OF_OR metafunction
template<typename _Smart, typename _Ptr>
consteval auto
__pointer_of_or()
{
using _TypeId = decltype(__detail::__pointer_of<_Smart>());
if constexpr (is_void_v<_TypeId>)
return type_identity<_Ptr>{};
else
return _TypeId{};
}
// Returns Pointer if !is_void_v<Pointer>, otherwise POINTER_OF(Smart).
template<typename _Ptr, typename _Smart>
consteval auto
__choose_ptr()
{
if constexpr (!is_void_v<_Ptr>)
return type_identity<_Ptr>{};
else
return __detail::__pointer_of<_Smart>();
}
template<typename _Smart, typename _Sp, typename... _Args>
concept __resettable = requires (_Smart& __s) {
__s.reset(std::declval<_Sp>(), std::declval<_Args>()...);
};
}
/// @endcond
/// Adapt a smart pointer for functions taking an output pointer parameter.
/**
* @tparam _Pointer The type of pointer to convert to.
* @param __s The pointer that should take ownership of the result.
* @param __args... Arguments to use when resetting the smart pointer.
* @return A std::inout_ptr_t referring to `__s`.
* @since C++23
* @headerfile <memory>
*/
template<typename _Pointer = void, typename _Smart, typename... _Args>
inline auto
out_ptr(_Smart& __s, _Args&&... __args)
{
using _TypeId = decltype(__detail::__choose_ptr<_Pointer, _Smart>());
static_assert(!is_void_v<_TypeId>, "first argument to std::out_ptr "
"must be a pointer-like type");
using _Ret = out_ptr_t<_Smart, typename _TypeId::type, _Args&&...>;
return _Ret(__s, std::forward<_Args>(__args)...);
}
/// Adapt a smart pointer for functions taking an inout pointer parameter.
/**
* @tparam _Pointer The type of pointer to convert to.
* @param __s The pointer that should take ownership of the result.
* @param __args... Arguments to use when resetting the smart pointer.
* @return A std::inout_ptr_t referring to `__s`.
* @since C++23
* @headerfile <memory>
*/
template<typename _Pointer = void, typename _Smart, typename... _Args>
inline auto
inout_ptr(_Smart& __s, _Args&&... __args)
{
using _TypeId = decltype(__detail::__choose_ptr<_Pointer, _Smart>());
static_assert(!is_void_v<_TypeId>, "first argument to std::inout_ptr "
"must be a pointer-like type");
using _Ret = inout_ptr_t<_Smart, typename _TypeId::type, _Args&&...>;
return _Ret(__s, std::forward<_Args>(__args)...);
}
/// @cond undocumented
template<typename _Smart, typename _Pointer, typename... _Args>
template<typename _Smart2, typename _Pointer2, typename... _Args2>
inline
out_ptr_t<_Smart, _Pointer, _Args...>::
_Impl<_Smart2, _Pointer2, _Args2...>::~_Impl()
{
using _TypeId = decltype(__detail::__pointer_of_or<_Smart, _Pointer>());
using _Sp = typename _TypeId::type;
if (!_M_ptr)
return;
_Smart& __s = _M_smart;
_Pointer& __p = _M_ptr;
auto __reset = [&](auto&&... __args) {
if constexpr (__detail::__resettable<_Smart, _Sp, _Args...>)
__s.reset(static_cast<_Sp>(__p), std::forward<_Args>(__args)...);
else if constexpr (is_constructible_v<_Smart, _Sp, _Args...>)
__s = _Smart(static_cast<_Sp>(__p), std::forward<_Args>(__args)...);
else
static_assert(is_constructible_v<_Smart, _Sp, _Args...>);
};
if constexpr (sizeof...(_Args) >= 2)
std::apply(__reset, std::move(_M_args));
else if constexpr (sizeof...(_Args) == 1)
__reset(std::get<0>(std::move(_M_args)));
else
__reset();
}
/// @endcond
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif // __glibcxx_out_ptr
#endif /* _GLIBCXX_OUT_PTR_H */
@@ -0,0 +1,295 @@
// Components for compile-time parsing of numbers -*- C++ -*-
// Copyright (C) 2013-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/parse_numbers.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{chrono}
*/
#ifndef _GLIBCXX_PARSE_NUMBERS_H
#define _GLIBCXX_PARSE_NUMBERS_H 1
#pragma GCC system_header
// From n3642.pdf except I added binary literals and digit separator '\''.
#if __cplusplus >= 201402L
#include <type_traits>
#include <ext/numeric_traits.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
namespace __parse_int
{
template<unsigned _Base, char _Dig>
struct _Digit;
template<unsigned _Base>
struct _Digit<_Base, '0'> : integral_constant<unsigned, 0>
{
using __valid = true_type;
};
template<unsigned _Base>
struct _Digit<_Base, '1'> : integral_constant<unsigned, 1>
{
using __valid = true_type;
};
template<unsigned _Base, unsigned _Val>
struct _Digit_impl : integral_constant<unsigned, _Val>
{
static_assert(_Base > _Val, "invalid digit");
using __valid = true_type;
};
template<unsigned _Base>
struct _Digit<_Base, '2'> : _Digit_impl<_Base, 2>
{ };
template<unsigned _Base>
struct _Digit<_Base, '3'> : _Digit_impl<_Base, 3>
{ };
template<unsigned _Base>
struct _Digit<_Base, '4'> : _Digit_impl<_Base, 4>
{ };
template<unsigned _Base>
struct _Digit<_Base, '5'> : _Digit_impl<_Base, 5>
{ };
template<unsigned _Base>
struct _Digit<_Base, '6'> : _Digit_impl<_Base, 6>
{ };
template<unsigned _Base>
struct _Digit<_Base, '7'> : _Digit_impl<_Base, 7>
{ };
template<unsigned _Base>
struct _Digit<_Base, '8'> : _Digit_impl<_Base, 8>
{ };
template<unsigned _Base>
struct _Digit<_Base, '9'> : _Digit_impl<_Base, 9>
{ };
template<unsigned _Base>
struct _Digit<_Base, 'a'> : _Digit_impl<_Base, 0xa>
{ };
template<unsigned _Base>
struct _Digit<_Base, 'A'> : _Digit_impl<_Base, 0xa>
{ };
template<unsigned _Base>
struct _Digit<_Base, 'b'> : _Digit_impl<_Base, 0xb>
{ };
template<unsigned _Base>
struct _Digit<_Base, 'B'> : _Digit_impl<_Base, 0xb>
{ };
template<unsigned _Base>
struct _Digit<_Base, 'c'> : _Digit_impl<_Base, 0xc>
{ };
template<unsigned _Base>
struct _Digit<_Base, 'C'> : _Digit_impl<_Base, 0xc>
{ };
template<unsigned _Base>
struct _Digit<_Base, 'd'> : _Digit_impl<_Base, 0xd>
{ };
template<unsigned _Base>
struct _Digit<_Base, 'D'> : _Digit_impl<_Base, 0xd>
{ };
template<unsigned _Base>
struct _Digit<_Base, 'e'> : _Digit_impl<_Base, 0xe>
{ };
template<unsigned _Base>
struct _Digit<_Base, 'E'> : _Digit_impl<_Base, 0xe>
{ };
template<unsigned _Base>
struct _Digit<_Base, 'f'> : _Digit_impl<_Base, 0xf>
{ };
template<unsigned _Base>
struct _Digit<_Base, 'F'> : _Digit_impl<_Base, 0xf>
{ };
// Digit separator
template<unsigned _Base>
struct _Digit<_Base, '\''> : integral_constant<unsigned, 0>
{
using __valid = false_type;
};
//------------------------------------------------------------------------------
template<unsigned long long _Val>
using __ull_constant = integral_constant<unsigned long long, _Val>;
template<unsigned _Base, char _Dig, char... _Digs>
struct _Power_help
{
using __next = typename _Power_help<_Base, _Digs...>::type;
using __valid_digit = typename _Digit<_Base, _Dig>::__valid;
using type
= __ull_constant<__next::value * (__valid_digit{} ? _Base : 1ULL)>;
};
template<unsigned _Base, char _Dig>
struct _Power_help<_Base, _Dig>
{
using __valid_digit = typename _Digit<_Base, _Dig>::__valid;
using type = __ull_constant<__valid_digit::value>;
};
template<unsigned _Base, char... _Digs>
struct _Power : _Power_help<_Base, _Digs...>::type
{ };
template<unsigned _Base>
struct _Power<_Base> : __ull_constant<0>
{ };
//------------------------------------------------------------------------------
template<unsigned _Base, unsigned long long _Pow, char _Dig, char... _Digs>
struct _Number_help
{
using __digit = _Digit<_Base, _Dig>;
using __valid_digit = typename __digit::__valid;
using __next = _Number_help<_Base,
__valid_digit::value ? _Pow / _Base : _Pow,
_Digs...>;
using type = __ull_constant<_Pow * __digit::value + __next::type::value>;
static_assert((type::value / _Pow) == __digit::value,
"integer literal does not fit in unsigned long long");
};
// Skip past digit separators:
template<unsigned _Base, unsigned long long _Pow, char _Dig, char..._Digs>
struct _Number_help<_Base, _Pow, '\'', _Dig, _Digs...>
: _Number_help<_Base, _Pow, _Dig, _Digs...>
{ };
// Terminating case for recursion:
template<unsigned _Base, char _Dig>
struct _Number_help<_Base, 1ULL, _Dig>
{
using type = __ull_constant<_Digit<_Base, _Dig>::value>;
};
template<unsigned _Base, char... _Digs>
struct _Number
: _Number_help<_Base, _Power<_Base, _Digs...>::value, _Digs...>::type
{ };
template<unsigned _Base>
struct _Number<_Base>
: __ull_constant<0>
{ };
//------------------------------------------------------------------------------
template<char... _Digs>
struct _Parse_int;
template<char... _Digs>
struct _Parse_int<'0', 'b', _Digs...>
: _Number<2U, _Digs...>::type
{ };
template<char... _Digs>
struct _Parse_int<'0', 'B', _Digs...>
: _Number<2U, _Digs...>::type
{ };
template<char... _Digs>
struct _Parse_int<'0', 'x', _Digs...>
: _Number<16U, _Digs...>::type
{ };
template<char... _Digs>
struct _Parse_int<'0', 'X', _Digs...>
: _Number<16U, _Digs...>::type
{ };
template<char... _Digs>
struct _Parse_int<'0', _Digs...>
: _Number<8U, _Digs...>::type
{ };
template<char... _Digs>
struct _Parse_int
: _Number<10U, _Digs...>::type
{ };
} // namespace __parse_int
namespace __select_int
{
template<unsigned long long _Val, typename... _Ints>
struct _Select_int_base;
template<unsigned long long _Val, typename _IntType, typename... _Ints>
struct _Select_int_base<_Val, _IntType, _Ints...>
: __conditional_t<(_Val <= __gnu_cxx::__int_traits<_IntType>::__max),
integral_constant<_IntType, (_IntType)_Val>,
_Select_int_base<_Val, _Ints...>>
{ };
template<unsigned long long _Val>
struct _Select_int_base<_Val>
{ };
template<char... _Digs>
using _Select_int = typename _Select_int_base<
__parse_int::_Parse_int<_Digs...>::value,
unsigned char,
unsigned short,
unsigned int,
unsigned long,
unsigned long long
>::type;
} // namespace __select_int
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif // C++14
#endif // _GLIBCXX_PARSE_NUMBERS_H
@@ -0,0 +1,407 @@
// Default predicates for internal use -*- C++ -*-
// Copyright (C) 2013-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file predefined_ops.h
* This is an internal header file, included by other library headers.
* You should not attempt to use it directly. @headername{algorithm}
*/
#ifndef _GLIBCXX_PREDEFINED_OPS_H
#define _GLIBCXX_PREDEFINED_OPS_H 1
#include <bits/move.h>
namespace __gnu_cxx
{
namespace __ops
{
struct _Iter_less_iter
{
template<typename _Iterator1, typename _Iterator2>
_GLIBCXX14_CONSTEXPR
bool
operator()(_Iterator1 __it1, _Iterator2 __it2) const
{ return *__it1 < *__it2; }
};
_GLIBCXX14_CONSTEXPR
inline _Iter_less_iter
__iter_less_iter()
{ return _Iter_less_iter(); }
struct _Iter_less_val
{
#if __cplusplus >= 201103L
constexpr _Iter_less_val() = default;
#else
_Iter_less_val() { }
#endif
_GLIBCXX20_CONSTEXPR
explicit
_Iter_less_val(_Iter_less_iter) { }
template<typename _Iterator, typename _Value>
_GLIBCXX20_CONSTEXPR
bool
operator()(_Iterator __it, _Value& __val) const
{ return *__it < __val; }
};
_GLIBCXX20_CONSTEXPR
inline _Iter_less_val
__iter_less_val()
{ return _Iter_less_val(); }
_GLIBCXX20_CONSTEXPR
inline _Iter_less_val
__iter_comp_val(_Iter_less_iter)
{ return _Iter_less_val(); }
struct _Val_less_iter
{
#if __cplusplus >= 201103L
constexpr _Val_less_iter() = default;
#else
_Val_less_iter() { }
#endif
_GLIBCXX20_CONSTEXPR
explicit
_Val_less_iter(_Iter_less_iter) { }
template<typename _Value, typename _Iterator>
_GLIBCXX20_CONSTEXPR
bool
operator()(_Value& __val, _Iterator __it) const
{ return __val < *__it; }
};
_GLIBCXX20_CONSTEXPR
inline _Val_less_iter
__val_less_iter()
{ return _Val_less_iter(); }
_GLIBCXX20_CONSTEXPR
inline _Val_less_iter
__val_comp_iter(_Iter_less_iter)
{ return _Val_less_iter(); }
struct _Iter_equal_to_iter
{
template<typename _Iterator1, typename _Iterator2>
_GLIBCXX20_CONSTEXPR
bool
operator()(_Iterator1 __it1, _Iterator2 __it2) const
{ return *__it1 == *__it2; }
};
_GLIBCXX20_CONSTEXPR
inline _Iter_equal_to_iter
__iter_equal_to_iter()
{ return _Iter_equal_to_iter(); }
struct _Iter_equal_to_val
{
template<typename _Iterator, typename _Value>
_GLIBCXX20_CONSTEXPR
bool
operator()(_Iterator __it, _Value& __val) const
{ return *__it == __val; }
};
_GLIBCXX20_CONSTEXPR
inline _Iter_equal_to_val
__iter_equal_to_val()
{ return _Iter_equal_to_val(); }
_GLIBCXX20_CONSTEXPR
inline _Iter_equal_to_val
__iter_comp_val(_Iter_equal_to_iter)
{ return _Iter_equal_to_val(); }
template<typename _Compare>
struct _Iter_comp_iter
{
_Compare _M_comp;
explicit _GLIBCXX14_CONSTEXPR
_Iter_comp_iter(_Compare __comp)
: _M_comp(_GLIBCXX_MOVE(__comp))
{ }
template<typename _Iterator1, typename _Iterator2>
_GLIBCXX14_CONSTEXPR
bool
operator()(_Iterator1 __it1, _Iterator2 __it2)
{ return bool(_M_comp(*__it1, *__it2)); }
};
template<typename _Compare>
_GLIBCXX14_CONSTEXPR
inline _Iter_comp_iter<_Compare>
__iter_comp_iter(_Compare __comp)
{ return _Iter_comp_iter<_Compare>(_GLIBCXX_MOVE(__comp)); }
template<typename _Compare>
struct _Iter_comp_val
{
_Compare _M_comp;
_GLIBCXX20_CONSTEXPR
explicit
_Iter_comp_val(_Compare __comp)
: _M_comp(_GLIBCXX_MOVE(__comp))
{ }
_GLIBCXX20_CONSTEXPR
explicit
_Iter_comp_val(const _Iter_comp_iter<_Compare>& __comp)
: _M_comp(__comp._M_comp)
{ }
#if __cplusplus >= 201103L
_GLIBCXX20_CONSTEXPR
explicit
_Iter_comp_val(_Iter_comp_iter<_Compare>&& __comp)
: _M_comp(std::move(__comp._M_comp))
{ }
#endif
template<typename _Iterator, typename _Value>
_GLIBCXX20_CONSTEXPR
bool
operator()(_Iterator __it, _Value& __val)
{ return bool(_M_comp(*__it, __val)); }
};
template<typename _Compare>
_GLIBCXX20_CONSTEXPR
inline _Iter_comp_val<_Compare>
__iter_comp_val(_Compare __comp)
{ return _Iter_comp_val<_Compare>(_GLIBCXX_MOVE(__comp)); }
template<typename _Compare>
_GLIBCXX20_CONSTEXPR
inline _Iter_comp_val<_Compare>
__iter_comp_val(_Iter_comp_iter<_Compare> __comp)
{ return _Iter_comp_val<_Compare>(_GLIBCXX_MOVE(__comp)); }
template<typename _Compare>
struct _Val_comp_iter
{
_Compare _M_comp;
_GLIBCXX20_CONSTEXPR
explicit
_Val_comp_iter(_Compare __comp)
: _M_comp(_GLIBCXX_MOVE(__comp))
{ }
_GLIBCXX20_CONSTEXPR
explicit
_Val_comp_iter(const _Iter_comp_iter<_Compare>& __comp)
: _M_comp(__comp._M_comp)
{ }
#if __cplusplus >= 201103L
_GLIBCXX20_CONSTEXPR
explicit
_Val_comp_iter(_Iter_comp_iter<_Compare>&& __comp)
: _M_comp(std::move(__comp._M_comp))
{ }
#endif
template<typename _Value, typename _Iterator>
_GLIBCXX20_CONSTEXPR
bool
operator()(_Value& __val, _Iterator __it)
{ return bool(_M_comp(__val, *__it)); }
};
template<typename _Compare>
_GLIBCXX20_CONSTEXPR
inline _Val_comp_iter<_Compare>
__val_comp_iter(_Compare __comp)
{ return _Val_comp_iter<_Compare>(_GLIBCXX_MOVE(__comp)); }
template<typename _Compare>
_GLIBCXX20_CONSTEXPR
inline _Val_comp_iter<_Compare>
__val_comp_iter(_Iter_comp_iter<_Compare> __comp)
{ return _Val_comp_iter<_Compare>(_GLIBCXX_MOVE(__comp)); }
template<typename _Value>
struct _Iter_equals_val
{
_Value& _M_value;
_GLIBCXX20_CONSTEXPR
explicit
_Iter_equals_val(_Value& __value)
: _M_value(__value)
{ }
template<typename _Iterator>
_GLIBCXX20_CONSTEXPR
bool
operator()(_Iterator __it)
{ return *__it == _M_value; }
};
template<typename _Value>
_GLIBCXX20_CONSTEXPR
inline _Iter_equals_val<_Value>
__iter_equals_val(_Value& __val)
{ return _Iter_equals_val<_Value>(__val); }
template<typename _Iterator1>
struct _Iter_equals_iter
{
_Iterator1 _M_it1;
_GLIBCXX20_CONSTEXPR
explicit
_Iter_equals_iter(_Iterator1 __it1)
: _M_it1(__it1)
{ }
template<typename _Iterator2>
_GLIBCXX20_CONSTEXPR
bool
operator()(_Iterator2 __it2)
{ return *__it2 == *_M_it1; }
};
template<typename _Iterator>
_GLIBCXX20_CONSTEXPR
inline _Iter_equals_iter<_Iterator>
__iter_comp_iter(_Iter_equal_to_iter, _Iterator __it)
{ return _Iter_equals_iter<_Iterator>(__it); }
template<typename _Predicate>
struct _Iter_pred
{
_Predicate _M_pred;
_GLIBCXX20_CONSTEXPR
explicit
_Iter_pred(_Predicate __pred)
: _M_pred(_GLIBCXX_MOVE(__pred))
{ }
template<typename _Iterator>
_GLIBCXX20_CONSTEXPR
bool
operator()(_Iterator __it)
{ return bool(_M_pred(*__it)); }
};
template<typename _Predicate>
_GLIBCXX20_CONSTEXPR
inline _Iter_pred<_Predicate>
__pred_iter(_Predicate __pred)
{ return _Iter_pred<_Predicate>(_GLIBCXX_MOVE(__pred)); }
template<typename _Compare, typename _Value>
struct _Iter_comp_to_val
{
_Compare _M_comp;
_Value& _M_value;
_GLIBCXX20_CONSTEXPR
_Iter_comp_to_val(_Compare __comp, _Value& __value)
: _M_comp(_GLIBCXX_MOVE(__comp)), _M_value(__value)
{ }
template<typename _Iterator>
_GLIBCXX20_CONSTEXPR
bool
operator()(_Iterator __it)
{ return bool(_M_comp(*__it, _M_value)); }
};
template<typename _Compare, typename _Value>
_Iter_comp_to_val<_Compare, _Value>
_GLIBCXX20_CONSTEXPR
__iter_comp_val(_Compare __comp, _Value &__val)
{
return _Iter_comp_to_val<_Compare, _Value>(_GLIBCXX_MOVE(__comp), __val);
}
template<typename _Compare, typename _Iterator1>
struct _Iter_comp_to_iter
{
_Compare _M_comp;
_Iterator1 _M_it1;
_GLIBCXX20_CONSTEXPR
_Iter_comp_to_iter(_Compare __comp, _Iterator1 __it1)
: _M_comp(_GLIBCXX_MOVE(__comp)), _M_it1(__it1)
{ }
template<typename _Iterator2>
_GLIBCXX20_CONSTEXPR
bool
operator()(_Iterator2 __it2)
{ return bool(_M_comp(*__it2, *_M_it1)); }
};
template<typename _Compare, typename _Iterator>
_GLIBCXX20_CONSTEXPR
inline _Iter_comp_to_iter<_Compare, _Iterator>
__iter_comp_iter(_Iter_comp_iter<_Compare> __comp, _Iterator __it)
{
return _Iter_comp_to_iter<_Compare, _Iterator>(
_GLIBCXX_MOVE(__comp._M_comp), __it);
}
template<typename _Predicate>
struct _Iter_negate
{
_Predicate _M_pred;
_GLIBCXX20_CONSTEXPR
explicit
_Iter_negate(_Predicate __pred)
: _M_pred(_GLIBCXX_MOVE(__pred))
{ }
template<typename _Iterator>
_GLIBCXX20_CONSTEXPR
bool
operator()(_Iterator __it)
{ return !bool(_M_pred(*__it)); }
};
template<typename _Predicate>
_GLIBCXX20_CONSTEXPR
inline _Iter_negate<_Predicate>
__negate(_Iter_pred<_Predicate> __pred)
{ return _Iter_negate<_Predicate>(_GLIBCXX_MOVE(__pred._M_pred)); }
} // namespace __ops
} // namespace __gnu_cxx
#endif
+262
View File
@@ -0,0 +1,262 @@
// Pointer Traits -*- C++ -*-
// Copyright (C) 2011-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/ptr_traits.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{memory}
*/
#ifndef _PTR_TRAITS_H
#define _PTR_TRAITS_H 1
#if __cplusplus >= 201103L
#include <bits/move.h>
#if __cplusplus > 201703L
#include <concepts>
namespace __gnu_debug { struct _Safe_iterator_base; }
#endif
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/// @cond undocumented
class __undefined;
// For a specialization `SomeTemplate<T, Types...>` the member `type` is T,
// otherwise `type` is `__undefined`.
template<typename _Tp>
struct __get_first_arg
{ using type = __undefined; };
template<template<typename, typename...> class _SomeTemplate, typename _Tp,
typename... _Types>
struct __get_first_arg<_SomeTemplate<_Tp, _Types...>>
{ using type = _Tp; };
// For a specialization `SomeTemplate<T, Args...>` and a type `U` the member
// `type` is `SomeTemplate<U, Args...>`, otherwise there is no member `type`.
template<typename _Tp, typename _Up>
struct __replace_first_arg
{ };
template<template<typename, typename...> class _SomeTemplate, typename _Up,
typename _Tp, typename... _Types>
struct __replace_first_arg<_SomeTemplate<_Tp, _Types...>, _Up>
{ using type = _SomeTemplate<_Up, _Types...>; };
// Detect the element type of a pointer-like type.
template<typename _Ptr, typename = void>
struct __ptr_traits_elem : __get_first_arg<_Ptr>
{ };
// Use _Ptr::element_type if is a valid type.
#if __cpp_concepts
template<typename _Ptr> requires requires { typename _Ptr::element_type; }
struct __ptr_traits_elem<_Ptr, void>
{ using type = typename _Ptr::element_type; };
#else
template<typename _Ptr>
struct __ptr_traits_elem<_Ptr, __void_t<typename _Ptr::element_type>>
{ using type = typename _Ptr::element_type; };
#endif
template<typename _Ptr>
using __ptr_traits_elem_t = typename __ptr_traits_elem<_Ptr>::type;
/// @endcond
// Define pointer_traits<P>::pointer_to.
template<typename _Ptr, typename _Elt, bool = is_void<_Elt>::value>
struct __ptr_traits_ptr_to
{
using pointer = _Ptr;
using element_type = _Elt;
/**
* @brief Obtain a pointer to an object
* @param __r A reference to an object of type `element_type`
* @return `pointer::pointer_to(__r)`
* @pre `pointer::pointer_to(__r)` is a valid expression.
*/
static pointer
pointer_to(element_type& __r)
#if __cpp_lib_concepts
requires requires {
{ pointer::pointer_to(__r) } -> convertible_to<pointer>;
}
#endif
{ return pointer::pointer_to(__r); }
};
// Do not define pointer_traits<P>::pointer_to if element type is void.
template<typename _Ptr, typename _Elt>
struct __ptr_traits_ptr_to<_Ptr, _Elt, true>
{ };
// Partial specialization defining pointer_traits<T*>::pointer_to(T&).
template<typename _Tp>
struct __ptr_traits_ptr_to<_Tp*, _Tp, false>
{
using pointer = _Tp*;
using element_type = _Tp;
/**
* @brief Obtain a pointer to an object
* @param __r A reference to an object of type `element_type`
* @return `addressof(__r)`
*/
static _GLIBCXX20_CONSTEXPR pointer
pointer_to(element_type& __r) noexcept
{ return std::addressof(__r); }
};
template<typename _Ptr, typename _Elt>
struct __ptr_traits_impl : __ptr_traits_ptr_to<_Ptr, _Elt>
{
private:
template<typename _Tp>
using __diff_t = typename _Tp::difference_type;
template<typename _Tp, typename _Up>
using __rebind = __type_identity<typename _Tp::template rebind<_Up>>;
public:
/// The pointer type.
using pointer = _Ptr;
/// The type pointed to.
using element_type = _Elt;
/// The type used to represent the difference between two pointers.
using difference_type = __detected_or_t<ptrdiff_t, __diff_t, _Ptr>;
/// A pointer to a different type.
template<typename _Up>
using rebind = typename __detected_or_t<__replace_first_arg<_Ptr, _Up>,
__rebind, _Ptr, _Up>::type;
};
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 3545. std::pointer_traits should be SFINAE-friendly
template<typename _Ptr>
struct __ptr_traits_impl<_Ptr, __undefined>
{ };
/**
* @brief Uniform interface to all pointer-like types
* @headerfile memory
* @ingroup pointer_abstractions
* @since C++11
*/
template<typename _Ptr>
struct pointer_traits : __ptr_traits_impl<_Ptr, __ptr_traits_elem_t<_Ptr>>
{ };
/**
* @brief Partial specialization for built-in pointers.
* @headerfile memory
* @ingroup pointer_abstractions
* @since C++11
*/
template<typename _Tp>
struct pointer_traits<_Tp*> : __ptr_traits_ptr_to<_Tp*, _Tp>
{
/// The pointer type
typedef _Tp* pointer;
/// The type pointed to
typedef _Tp element_type;
/// Type used to represent the difference between two pointers
typedef ptrdiff_t difference_type;
/// A pointer to a different type.
template<typename _Up> using rebind = _Up*;
};
/// Convenience alias for rebinding pointers.
template<typename _Ptr, typename _Tp>
using __ptr_rebind = typename pointer_traits<_Ptr>::template rebind<_Tp>;
template<typename _Tp>
constexpr _Tp*
__to_address(_Tp* __ptr) noexcept
{
static_assert(!std::is_function<_Tp>::value, "not a function pointer");
return __ptr;
}
#ifndef __glibcxx_to_address // C++ < 20
template<typename _Ptr>
constexpr typename std::pointer_traits<_Ptr>::element_type*
__to_address(const _Ptr& __ptr)
{ return std::__to_address(__ptr.operator->()); }
#else
template<typename _Ptr>
constexpr auto
__to_address(const _Ptr& __ptr) noexcept
-> decltype(std::pointer_traits<_Ptr>::to_address(__ptr))
{ return std::pointer_traits<_Ptr>::to_address(__ptr); }
template<typename _Ptr, typename... _None>
constexpr auto
__to_address(const _Ptr& __ptr, _None...) noexcept
{
if constexpr (is_base_of_v<__gnu_debug::_Safe_iterator_base, _Ptr>)
return std::__to_address(__ptr.base().operator->());
else
return std::__to_address(__ptr.operator->());
}
/**
* @brief Obtain address referenced by a pointer to an object
* @param __ptr A pointer to an object
* @return @c __ptr
* @ingroup pointer_abstractions
*/
template<typename _Tp>
constexpr _Tp*
to_address(_Tp* __ptr) noexcept
{ return std::__to_address(__ptr); }
/**
* @brief Obtain address referenced by a pointer to an object
* @param __ptr A pointer to an object
* @return @c pointer_traits<_Ptr>::to_address(__ptr) if that expression is
well-formed, otherwise @c to_address(__ptr.operator->())
* @ingroup pointer_abstractions
*/
template<typename _Ptr>
constexpr auto
to_address(const _Ptr& __ptr) noexcept
{ return std::__to_address(__ptr); }
#endif // __glibcxx_to_address
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif
#endif
@@ -0,0 +1,370 @@
// Range access functions for containers -*- C++ -*-
// Copyright (C) 2010-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/range_access.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{iterator}
*/
#ifndef _GLIBCXX_RANGE_ACCESS_H
#define _GLIBCXX_RANGE_ACCESS_H 1
#pragma GCC system_header
#if __cplusplus >= 201103L
#include <initializer_list>
#include <type_traits> // common_type_t, make_signed_t
#include <bits/stl_iterator.h> // reverse_iterator
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
* @brief Return an iterator pointing to the first element of
* the container.
* @param __cont Container.
*/
template<typename _Container>
[[__nodiscard__, __gnu__::__always_inline__]]
inline _GLIBCXX17_CONSTEXPR auto
begin(_Container& __cont) -> decltype(__cont.begin())
{ return __cont.begin(); }
/**
* @brief Return an iterator pointing to the first element of
* the const container.
* @param __cont Container.
*/
template<typename _Container>
[[__nodiscard__, __gnu__::__always_inline__]]
inline _GLIBCXX17_CONSTEXPR auto
begin(const _Container& __cont) -> decltype(__cont.begin())
{ return __cont.begin(); }
/**
* @brief Return an iterator pointing to one past the last element of
* the container.
* @param __cont Container.
*/
template<typename _Container>
[[__nodiscard__, __gnu__::__always_inline__]]
inline _GLIBCXX17_CONSTEXPR auto
end(_Container& __cont) -> decltype(__cont.end())
{ return __cont.end(); }
/**
* @brief Return an iterator pointing to one past the last element of
* the const container.
* @param __cont Container.
*/
template<typename _Container>
[[__nodiscard__, __gnu__::__always_inline__]]
inline _GLIBCXX17_CONSTEXPR auto
end(const _Container& __cont) -> decltype(__cont.end())
{ return __cont.end(); }
/**
* @brief Return an iterator pointing to the first element of the array.
* @param __arr Array.
*/
template<typename _Tp, size_t _Nm>
[[__nodiscard__, __gnu__::__always_inline__]]
inline _GLIBCXX14_CONSTEXPR _Tp*
begin(_Tp (&__arr)[_Nm]) noexcept
{ return __arr; }
/**
* @brief Return an iterator pointing to one past the last element
* of the array.
* @param __arr Array.
*/
template<typename _Tp, size_t _Nm>
[[__nodiscard__, __gnu__::__always_inline__]]
inline _GLIBCXX14_CONSTEXPR _Tp*
end(_Tp (&__arr)[_Nm]) noexcept
{ return __arr + _Nm; }
#if __cplusplus >= 201402L
template<typename _Tp> class valarray;
// These overloads must be declared for cbegin and cend to use them.
template<typename _Tp> _Tp* begin(valarray<_Tp>&) noexcept;
template<typename _Tp> const _Tp* begin(const valarray<_Tp>&) noexcept;
template<typename _Tp> _Tp* end(valarray<_Tp>&) noexcept;
template<typename _Tp> const _Tp* end(const valarray<_Tp>&) noexcept;
/**
* @brief Return an iterator pointing to the first element of
* the const container.
* @param __cont Container.
*/
template<typename _Container>
[[__nodiscard__, __gnu__::__always_inline__]]
constexpr auto
cbegin(const _Container& __cont) noexcept(noexcept(std::begin(__cont)))
-> decltype(std::begin(__cont))
{ return std::begin(__cont); }
/**
* @brief Return an iterator pointing to one past the last element of
* the const container.
* @param __cont Container.
*/
template<typename _Container>
[[__nodiscard__, __gnu__::__always_inline__]]
constexpr auto
cend(const _Container& __cont) noexcept(noexcept(std::end(__cont)))
-> decltype(std::end(__cont))
{ return std::end(__cont); }
/**
* @brief Return a reverse iterator pointing to the last element of
* the container.
* @param __cont Container.
*/
template<typename _Container>
[[__nodiscard__, __gnu__::__always_inline__]]
inline _GLIBCXX17_CONSTEXPR auto
rbegin(_Container& __cont) -> decltype(__cont.rbegin())
{ return __cont.rbegin(); }
/**
* @brief Return a reverse iterator pointing to the last element of
* the const container.
* @param __cont Container.
*/
template<typename _Container>
[[__nodiscard__, __gnu__::__always_inline__]]
inline _GLIBCXX17_CONSTEXPR auto
rbegin(const _Container& __cont) -> decltype(__cont.rbegin())
{ return __cont.rbegin(); }
/**
* @brief Return a reverse iterator pointing one past the first element of
* the container.
* @param __cont Container.
*/
template<typename _Container>
[[__nodiscard__, __gnu__::__always_inline__]]
inline _GLIBCXX17_CONSTEXPR auto
rend(_Container& __cont) -> decltype(__cont.rend())
{ return __cont.rend(); }
/**
* @brief Return a reverse iterator pointing one past the first element of
* the const container.
* @param __cont Container.
*/
template<typename _Container>
[[__nodiscard__, __gnu__::__always_inline__]]
inline _GLIBCXX17_CONSTEXPR auto
rend(const _Container& __cont) -> decltype(__cont.rend())
{ return __cont.rend(); }
/**
* @brief Return a reverse iterator pointing to the last element of
* the array.
* @param __arr Array.
*/
template<typename _Tp, size_t _Nm>
[[__nodiscard__]]
inline _GLIBCXX17_CONSTEXPR reverse_iterator<_Tp*>
rbegin(_Tp (&__arr)[_Nm]) noexcept
{ return reverse_iterator<_Tp*>(__arr + _Nm); }
/**
* @brief Return a reverse iterator pointing one past the first element of
* the array.
* @param __arr Array.
*/
template<typename _Tp, size_t _Nm>
[[__nodiscard__]]
inline _GLIBCXX17_CONSTEXPR reverse_iterator<_Tp*>
rend(_Tp (&__arr)[_Nm]) noexcept
{ return reverse_iterator<_Tp*>(__arr); }
/**
* @brief Return a reverse iterator pointing to the last element of
* the initializer_list.
* @param __il initializer_list.
*/
template<typename _Tp>
[[__nodiscard__]]
inline _GLIBCXX17_CONSTEXPR reverse_iterator<const _Tp*>
rbegin(initializer_list<_Tp> __il) noexcept
{ return reverse_iterator<const _Tp*>(__il.end()); }
/**
* @brief Return a reverse iterator pointing one past the first element of
* the initializer_list.
* @param __il initializer_list.
*/
template<typename _Tp>
[[__nodiscard__]]
inline _GLIBCXX17_CONSTEXPR reverse_iterator<const _Tp*>
rend(initializer_list<_Tp> __il) noexcept
{ return reverse_iterator<const _Tp*>(__il.begin()); }
/**
* @brief Return a reverse iterator pointing to the last element of
* the const container.
* @param __cont Container.
*/
template<typename _Container>
[[__nodiscard__, __gnu__::__always_inline__]]
inline _GLIBCXX17_CONSTEXPR auto
crbegin(const _Container& __cont) -> decltype(std::rbegin(__cont))
{ return std::rbegin(__cont); }
/**
* @brief Return a reverse iterator pointing one past the first element of
* the const container.
* @param __cont Container.
*/
template<typename _Container>
[[__nodiscard__, __gnu__::__always_inline__]]
inline _GLIBCXX17_CONSTEXPR auto
crend(const _Container& __cont) -> decltype(std::rend(__cont))
{ return std::rend(__cont); }
#endif // C++14
#ifdef __glibcxx_nonmember_container_access // C++ >= 17
/**
* @brief Return the size of a container.
* @param __cont Container.
*/
template <typename _Container>
[[nodiscard, __gnu__::__always_inline__]]
constexpr auto
size(const _Container& __cont) noexcept(noexcept(__cont.size()))
-> decltype(__cont.size())
{ return __cont.size(); }
/**
* @brief Return the size of an array.
*/
template <typename _Tp, size_t _Nm>
[[nodiscard, __gnu__::__always_inline__]]
constexpr size_t
size(const _Tp (&)[_Nm]) noexcept
{ return _Nm; }
/**
* @brief Return whether a container is empty.
* @param __cont Container.
*/
template <typename _Container>
[[nodiscard, __gnu__::__always_inline__]]
constexpr auto
empty(const _Container& __cont) noexcept(noexcept(__cont.empty()))
-> decltype(__cont.empty())
{ return __cont.empty(); }
/**
* @brief Return whether an array is empty (always false).
*/
template <typename _Tp, size_t _Nm>
[[nodiscard, __gnu__::__always_inline__]]
constexpr bool
empty(const _Tp (&)[_Nm]) noexcept
{ return false; }
/**
* @brief Return whether an initializer_list is empty.
* @param __il Initializer list.
*/
template <typename _Tp>
[[nodiscard, __gnu__::__always_inline__]]
constexpr bool
empty(initializer_list<_Tp> __il) noexcept
{ return __il.size() == 0;}
/**
* @brief Return the data pointer of a container.
* @param __cont Container.
*/
template <typename _Container>
[[nodiscard, __gnu__::__always_inline__]]
constexpr auto
data(_Container& __cont) noexcept(noexcept(__cont.data()))
-> decltype(__cont.data())
{ return __cont.data(); }
/**
* @brief Return the data pointer of a const container.
* @param __cont Container.
*/
template <typename _Container>
[[nodiscard, __gnu__::__always_inline__]]
constexpr auto
data(const _Container& __cont) noexcept(noexcept(__cont.data()))
-> decltype(__cont.data())
{ return __cont.data(); }
/**
* @brief Return the data pointer of an array.
* @param __array Array.
*/
template <typename _Tp, size_t _Nm>
[[nodiscard, __gnu__::__always_inline__]]
constexpr _Tp*
data(_Tp (&__array)[_Nm]) noexcept
{ return __array; }
/**
* @brief Return the data pointer of an initializer list.
* @param __il Initializer list.
*/
template <typename _Tp>
[[nodiscard, __gnu__::__always_inline__]]
constexpr const _Tp*
data(initializer_list<_Tp> __il) noexcept
{ return __il.begin(); }
#endif // __glibcxx_nonmember_container_access
#ifdef __glibcxx_ssize // C++ >= 20
template<typename _Container>
[[nodiscard, __gnu__::__always_inline__]]
constexpr auto
ssize(const _Container& __cont)
noexcept(noexcept(__cont.size()))
-> common_type_t<ptrdiff_t, make_signed_t<decltype(__cont.size())>>
{
using type = make_signed_t<decltype(__cont.size())>;
return static_cast<common_type_t<ptrdiff_t, type>>(__cont.size());
}
template<typename _Tp, ptrdiff_t _Num>
[[nodiscard, __gnu__::__always_inline__]]
constexpr ptrdiff_t
ssize(const _Tp (&)[_Num]) noexcept
{ return _Num; }
#endif // __glibcxx_ssize
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif // C++11
#endif // _GLIBCXX_RANGE_ACCESS_H
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,601 @@
// Core algorithmic facilities -*- C++ -*-
// Copyright (C) 2020-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/ranges_algobase.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{algorithm}
*/
#ifndef _RANGES_ALGOBASE_H
#define _RANGES_ALGOBASE_H 1
#if __cplusplus > 201703L
#include <compare>
#include <bits/stl_iterator_base_funcs.h>
#include <bits/stl_iterator.h>
#include <bits/ranges_base.h> // ranges::begin, ranges::range etc.
#include <bits/invoke.h> // __invoke
#include <bits/cpp_type_traits.h> // __is_byte
#if __cpp_lib_concepts
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
namespace ranges
{
namespace __detail
{
template<typename _Tp>
constexpr inline bool __is_normal_iterator = false;
template<typename _Iterator, typename _Container>
constexpr inline bool
__is_normal_iterator<__gnu_cxx::__normal_iterator<_Iterator,
_Container>> = true;
template<typename _Tp>
constexpr inline bool __is_reverse_iterator = false;
template<typename _Iterator>
constexpr inline bool
__is_reverse_iterator<reverse_iterator<_Iterator>> = true;
template<typename _Tp>
constexpr inline bool __is_move_iterator = false;
template<typename _Iterator>
constexpr inline bool
__is_move_iterator<move_iterator<_Iterator>> = true;
} // namespace __detail
struct __equal_fn
{
template<input_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
input_iterator _Iter2, sentinel_for<_Iter2> _Sent2,
typename _Pred = ranges::equal_to,
typename _Proj1 = identity, typename _Proj2 = identity>
requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2>
constexpr bool
operator()(_Iter1 __first1, _Sent1 __last1,
_Iter2 __first2, _Sent2 __last2, _Pred __pred = {},
_Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
{
// TODO: implement more specializations to at least have parity with
// std::equal.
if constexpr (__detail::__is_normal_iterator<_Iter1>
&& same_as<_Iter1, _Sent1>)
return (*this)(__first1.base(), __last1.base(),
std::move(__first2), std::move(__last2),
std::move(__pred),
std::move(__proj1), std::move(__proj2));
else if constexpr (__detail::__is_normal_iterator<_Iter2>
&& same_as<_Iter2, _Sent2>)
return (*this)(std::move(__first1), std::move(__last1),
__first2.base(), __last2.base(),
std::move(__pred),
std::move(__proj1), std::move(__proj2));
else if constexpr (sized_sentinel_for<_Sent1, _Iter1>
&& sized_sentinel_for<_Sent2, _Iter2>)
{
auto __d1 = ranges::distance(__first1, __last1);
auto __d2 = ranges::distance(__first2, __last2);
if (__d1 != __d2)
return false;
using _ValueType1 = iter_value_t<_Iter1>;
constexpr bool __use_memcmp
= ((is_integral_v<_ValueType1> || is_pointer_v<_ValueType1>)
&& __memcmpable<_Iter1, _Iter2>::__value
&& is_same_v<_Pred, ranges::equal_to>
&& is_same_v<_Proj1, identity>
&& is_same_v<_Proj2, identity>);
if constexpr (__use_memcmp)
{
if (const size_t __len = (__last1 - __first1))
return !std::__memcmp(__first1, __first2, __len);
return true;
}
else
{
for (; __first1 != __last1; ++__first1, (void)++__first2)
if (!(bool)std::__invoke(__pred,
std::__invoke(__proj1, *__first1),
std::__invoke(__proj2, *__first2)))
return false;
return true;
}
}
else
{
for (; __first1 != __last1 && __first2 != __last2;
++__first1, (void)++__first2)
if (!(bool)std::__invoke(__pred,
std::__invoke(__proj1, *__first1),
std::__invoke(__proj2, *__first2)))
return false;
return __first1 == __last1 && __first2 == __last2;
}
}
template<input_range _Range1, input_range _Range2,
typename _Pred = ranges::equal_to,
typename _Proj1 = identity, typename _Proj2 = identity>
requires indirectly_comparable<iterator_t<_Range1>, iterator_t<_Range2>,
_Pred, _Proj1, _Proj2>
constexpr bool
operator()(_Range1&& __r1, _Range2&& __r2, _Pred __pred = {},
_Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
{
return (*this)(ranges::begin(__r1), ranges::end(__r1),
ranges::begin(__r2), ranges::end(__r2),
std::move(__pred),
std::move(__proj1), std::move(__proj2));
}
};
inline constexpr __equal_fn equal{};
template<typename _Iter, typename _Out>
struct in_out_result
{
[[no_unique_address]] _Iter in;
[[no_unique_address]] _Out out;
template<typename _Iter2, typename _Out2>
requires convertible_to<const _Iter&, _Iter2>
&& convertible_to<const _Out&, _Out2>
constexpr
operator in_out_result<_Iter2, _Out2>() const &
{ return {in, out}; }
template<typename _Iter2, typename _Out2>
requires convertible_to<_Iter, _Iter2>
&& convertible_to<_Out, _Out2>
constexpr
operator in_out_result<_Iter2, _Out2>() &&
{ return {std::move(in), std::move(out)}; }
};
template<typename _Iter, typename _Out>
using copy_result = in_out_result<_Iter, _Out>;
template<typename _Iter, typename _Out>
using move_result = in_out_result<_Iter, _Out>;
template<typename _Iter1, typename _Iter2>
using move_backward_result = in_out_result<_Iter1, _Iter2>;
template<typename _Iter1, typename _Iter2>
using copy_backward_result = in_out_result<_Iter1, _Iter2>;
template<bool _IsMove,
bidirectional_iterator _Iter, sentinel_for<_Iter> _Sent,
bidirectional_iterator _Out>
requires (_IsMove
? indirectly_movable<_Iter, _Out>
: indirectly_copyable<_Iter, _Out>)
constexpr __conditional_t<_IsMove,
move_backward_result<_Iter, _Out>,
copy_backward_result<_Iter, _Out>>
__copy_or_move_backward(_Iter __first, _Sent __last, _Out __result);
template<bool _IsMove,
input_iterator _Iter, sentinel_for<_Iter> _Sent,
weakly_incrementable _Out>
requires (_IsMove
? indirectly_movable<_Iter, _Out>
: indirectly_copyable<_Iter, _Out>)
constexpr __conditional_t<_IsMove,
move_result<_Iter, _Out>,
copy_result<_Iter, _Out>>
__copy_or_move(_Iter __first, _Sent __last, _Out __result)
{
// TODO: implement more specializations to be at least on par with
// std::copy/std::move.
using __detail::__is_move_iterator;
using __detail::__is_reverse_iterator;
using __detail::__is_normal_iterator;
if constexpr (__is_move_iterator<_Iter> && same_as<_Iter, _Sent>)
{
auto [__in, __out]
= ranges::__copy_or_move<true>(std::move(__first).base(),
std::move(__last).base(),
std::move(__result));
return {move_iterator{std::move(__in)}, std::move(__out)};
}
else if constexpr (__is_reverse_iterator<_Iter> && same_as<_Iter, _Sent>
&& __is_reverse_iterator<_Out>)
{
auto [__in,__out]
= ranges::__copy_or_move_backward<_IsMove>(std::move(__last).base(),
std::move(__first).base(),
std::move(__result).base());
return {reverse_iterator{std::move(__in)},
reverse_iterator{std::move(__out)}};
}
else if constexpr (__is_normal_iterator<_Iter> && same_as<_Iter, _Sent>)
{
auto [__in,__out]
= ranges::__copy_or_move<_IsMove>(__first.base(), __last.base(),
std::move(__result));
return {decltype(__first){__in}, std::move(__out)};
}
else if constexpr (__is_normal_iterator<_Out>)
{
auto [__in,__out]
= ranges::__copy_or_move<_IsMove>(std::move(__first), __last, __result.base());
return {std::move(__in), decltype(__result){__out}};
}
else if constexpr (sized_sentinel_for<_Sent, _Iter>)
{
if (!std::__is_constant_evaluated())
{
if constexpr (__memcpyable<_Iter, _Out>::__value)
{
using _ValueTypeI = iter_value_t<_Iter>;
static_assert(_IsMove
? is_move_assignable_v<_ValueTypeI>
: is_copy_assignable_v<_ValueTypeI>);
auto __num = __last - __first;
if (__num)
__builtin_memmove(__result, __first,
sizeof(_ValueTypeI) * __num);
return {__first + __num, __result + __num};
}
}
for (auto __n = __last - __first; __n > 0; --__n)
{
if constexpr (_IsMove)
*__result = std::move(*__first);
else
*__result = *__first;
++__first;
++__result;
}
return {std::move(__first), std::move(__result)};
}
else
{
while (__first != __last)
{
if constexpr (_IsMove)
*__result = std::move(*__first);
else
*__result = *__first;
++__first;
++__result;
}
return {std::move(__first), std::move(__result)};
}
}
struct __copy_fn
{
template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
weakly_incrementable _Out>
requires indirectly_copyable<_Iter, _Out>
constexpr copy_result<_Iter, _Out>
operator()(_Iter __first, _Sent __last, _Out __result) const
{
return ranges::__copy_or_move<false>(std::move(__first),
std::move(__last),
std::move(__result));
}
template<input_range _Range, weakly_incrementable _Out>
requires indirectly_copyable<iterator_t<_Range>, _Out>
constexpr copy_result<borrowed_iterator_t<_Range>, _Out>
operator()(_Range&& __r, _Out __result) const
{
return (*this)(ranges::begin(__r), ranges::end(__r),
std::move(__result));
}
};
inline constexpr __copy_fn copy{};
struct __move_fn
{
template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
weakly_incrementable _Out>
requires indirectly_movable<_Iter, _Out>
constexpr move_result<_Iter, _Out>
operator()(_Iter __first, _Sent __last, _Out __result) const
{
return ranges::__copy_or_move<true>(std::move(__first),
std::move(__last),
std::move(__result));
}
template<input_range _Range, weakly_incrementable _Out>
requires indirectly_movable<iterator_t<_Range>, _Out>
constexpr move_result<borrowed_iterator_t<_Range>, _Out>
operator()(_Range&& __r, _Out __result) const
{
return (*this)(ranges::begin(__r), ranges::end(__r),
std::move(__result));
}
};
inline constexpr __move_fn move{};
template<bool _IsMove,
bidirectional_iterator _Iter, sentinel_for<_Iter> _Sent,
bidirectional_iterator _Out>
requires (_IsMove
? indirectly_movable<_Iter, _Out>
: indirectly_copyable<_Iter, _Out>)
constexpr __conditional_t<_IsMove,
move_backward_result<_Iter, _Out>,
copy_backward_result<_Iter, _Out>>
__copy_or_move_backward(_Iter __first, _Sent __last, _Out __result)
{
// TODO: implement more specializations to be at least on par with
// std::copy_backward/std::move_backward.
using __detail::__is_reverse_iterator;
using __detail::__is_normal_iterator;
if constexpr (__is_reverse_iterator<_Iter> && same_as<_Iter, _Sent>
&& __is_reverse_iterator<_Out>)
{
auto [__in,__out]
= ranges::__copy_or_move<_IsMove>(std::move(__last).base(),
std::move(__first).base(),
std::move(__result).base());
return {reverse_iterator{std::move(__in)},
reverse_iterator{std::move(__out)}};
}
else if constexpr (__is_normal_iterator<_Iter> && same_as<_Iter, _Sent>)
{
auto [__in,__out]
= ranges::__copy_or_move_backward<_IsMove>(__first.base(),
__last.base(),
std::move(__result));
return {decltype(__first){__in}, std::move(__out)};
}
else if constexpr (__is_normal_iterator<_Out>)
{
auto [__in,__out]
= ranges::__copy_or_move_backward<_IsMove>(std::move(__first),
std::move(__last),
__result.base());
return {std::move(__in), decltype(__result){__out}};
}
else if constexpr (sized_sentinel_for<_Sent, _Iter>)
{
if (!std::__is_constant_evaluated())
{
if constexpr (__memcpyable<_Out, _Iter>::__value)
{
using _ValueTypeI = iter_value_t<_Iter>;
static_assert(_IsMove
? is_move_assignable_v<_ValueTypeI>
: is_copy_assignable_v<_ValueTypeI>);
auto __num = __last - __first;
if (__num)
__builtin_memmove(__result - __num, __first,
sizeof(_ValueTypeI) * __num);
return {__first + __num, __result - __num};
}
}
auto __lasti = ranges::next(__first, __last);
auto __tail = __lasti;
for (auto __n = __last - __first; __n > 0; --__n)
{
--__tail;
--__result;
if constexpr (_IsMove)
*__result = std::move(*__tail);
else
*__result = *__tail;
}
return {std::move(__lasti), std::move(__result)};
}
else
{
auto __lasti = ranges::next(__first, __last);
auto __tail = __lasti;
while (__first != __tail)
{
--__tail;
--__result;
if constexpr (_IsMove)
*__result = std::move(*__tail);
else
*__result = *__tail;
}
return {std::move(__lasti), std::move(__result)};
}
}
struct __copy_backward_fn
{
template<bidirectional_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
bidirectional_iterator _Iter2>
requires indirectly_copyable<_Iter1, _Iter2>
constexpr copy_backward_result<_Iter1, _Iter2>
operator()(_Iter1 __first, _Sent1 __last, _Iter2 __result) const
{
return ranges::__copy_or_move_backward<false>(std::move(__first),
std::move(__last),
std::move(__result));
}
template<bidirectional_range _Range, bidirectional_iterator _Iter>
requires indirectly_copyable<iterator_t<_Range>, _Iter>
constexpr copy_backward_result<borrowed_iterator_t<_Range>, _Iter>
operator()(_Range&& __r, _Iter __result) const
{
return (*this)(ranges::begin(__r), ranges::end(__r),
std::move(__result));
}
};
inline constexpr __copy_backward_fn copy_backward{};
struct __move_backward_fn
{
template<bidirectional_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
bidirectional_iterator _Iter2>
requires indirectly_movable<_Iter1, _Iter2>
constexpr move_backward_result<_Iter1, _Iter2>
operator()(_Iter1 __first, _Sent1 __last, _Iter2 __result) const
{
return ranges::__copy_or_move_backward<true>(std::move(__first),
std::move(__last),
std::move(__result));
}
template<bidirectional_range _Range, bidirectional_iterator _Iter>
requires indirectly_movable<iterator_t<_Range>, _Iter>
constexpr move_backward_result<borrowed_iterator_t<_Range>, _Iter>
operator()(_Range&& __r, _Iter __result) const
{
return (*this)(ranges::begin(__r), ranges::end(__r),
std::move(__result));
}
};
inline constexpr __move_backward_fn move_backward{};
template<typename _Iter, typename _Out>
using copy_n_result = in_out_result<_Iter, _Out>;
struct __copy_n_fn
{
template<input_iterator _Iter, weakly_incrementable _Out>
requires indirectly_copyable<_Iter, _Out>
constexpr copy_n_result<_Iter, _Out>
operator()(_Iter __first, iter_difference_t<_Iter> __n,
_Out __result) const
{
if constexpr (random_access_iterator<_Iter>)
{
if (__n > 0)
return ranges::copy(__first, __first + __n, std::move(__result));
}
else
{
for (; __n > 0; --__n, (void)++__result, (void)++__first)
*__result = *__first;
}
return {std::move(__first), std::move(__result)};
}
};
inline constexpr __copy_n_fn copy_n{};
struct __fill_n_fn
{
template<typename _Tp, output_iterator<const _Tp&> _Out>
constexpr _Out
operator()(_Out __first, iter_difference_t<_Out> __n,
const _Tp& __value) const
{
// TODO: implement more specializations to be at least on par with
// std::fill_n
if (__n <= 0)
return __first;
if constexpr (is_scalar_v<_Tp>)
{
// TODO: Generalize this optimization to contiguous iterators.
if constexpr (is_pointer_v<_Out>
// Note that __is_byte already implies !is_volatile.
&& __is_byte<remove_pointer_t<_Out>>::__value
&& integral<_Tp>)
{
if (!std::__is_constant_evaluated())
{
__builtin_memset(__first,
static_cast<unsigned char>(__value),
__n);
return __first + __n;
}
}
const auto __tmp = __value;
for (; __n > 0; --__n, (void)++__first)
*__first = __tmp;
return __first;
}
else
{
for (; __n > 0; --__n, (void)++__first)
*__first = __value;
return __first;
}
}
};
inline constexpr __fill_n_fn fill_n{};
struct __fill_fn
{
template<typename _Tp,
output_iterator<const _Tp&> _Out, sentinel_for<_Out> _Sent>
constexpr _Out
operator()(_Out __first, _Sent __last, const _Tp& __value) const
{
// TODO: implement more specializations to be at least on par with
// std::fill
if constexpr (sized_sentinel_for<_Sent, _Out>)
{
const auto __len = __last - __first;
return ranges::fill_n(__first, __len, __value);
}
else if constexpr (is_scalar_v<_Tp>)
{
const auto __tmp = __value;
for (; __first != __last; ++__first)
*__first = __tmp;
return __first;
}
else
{
for (; __first != __last; ++__first)
*__first = __value;
return __first;
}
}
template<typename _Tp, output_range<const _Tp&> _Range>
constexpr borrowed_iterator_t<_Range>
operator()(_Range&& __r, const _Tp& __value) const
{
return (*this)(ranges::begin(__r), ranges::end(__r), __value);
}
};
inline constexpr __fill_fn fill{};
}
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif // concepts
#endif // C++20
#endif // _RANGES_ALGOBASE_H
File diff suppressed because it is too large Load Diff
+179
View File
@@ -0,0 +1,179 @@
// Concept-constrained comparison implementations -*- C++ -*-
// Copyright (C) 2019-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/ranges_cmp.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{functional}
*/
#ifndef _RANGES_CMP_H
#define _RANGES_CMP_H 1
#if __cplusplus > 201703L
# include <bits/move.h>
# include <concepts>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
struct __is_transparent; // not defined
// Define std::identity here so that <iterator> and <ranges>
// don't need to include <bits/stl_function.h> to get it.
/// [func.identity] The identity function.
struct identity
{
template<typename _Tp>
[[nodiscard]]
constexpr _Tp&&
operator()(_Tp&& __t) const noexcept
{ return std::forward<_Tp>(__t); }
using is_transparent = __is_transparent;
};
#ifdef __glibcxx_ranges // C++ >= 20
namespace ranges
{
namespace __detail
{
// BUILTIN-PTR-CMP(T, <, U)
// This determines whether t < u results in a call to a built-in operator<
// comparing pointers. It doesn't work for function pointers (PR 93628).
template<typename _Tp, typename _Up>
concept __less_builtin_ptr_cmp
= requires (_Tp&& __t, _Up&& __u) { { __t < __u } -> same_as<bool>; }
&& convertible_to<_Tp, const volatile void*>
&& convertible_to<_Up, const volatile void*>
&& (! requires(_Tp&& __t, _Up&& __u)
{ operator<(std::forward<_Tp>(__t), std::forward<_Up>(__u)); }
&& ! requires(_Tp&& __t, _Up&& __u)
{ std::forward<_Tp>(__t).operator<(std::forward<_Up>(__u)); });
} // namespace __detail
// [range.cmp] Concept-constrained comparisons
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 3530 BUILTIN-PTR-MEOW should not opt the type out of syntactic checks
/// ranges::equal_to function object type.
struct equal_to
{
template<typename _Tp, typename _Up>
requires equality_comparable_with<_Tp, _Up>
constexpr bool
operator()(_Tp&& __t, _Up&& __u) const
noexcept(noexcept(std::declval<_Tp>() == std::declval<_Up>()))
{ return std::forward<_Tp>(__t) == std::forward<_Up>(__u); }
using is_transparent = __is_transparent;
};
/// ranges::not_equal_to function object type.
struct not_equal_to
{
template<typename _Tp, typename _Up>
requires equality_comparable_with<_Tp, _Up>
constexpr bool
operator()(_Tp&& __t, _Up&& __u) const
noexcept(noexcept(std::declval<_Up>() == std::declval<_Tp>()))
{ return !equal_to{}(std::forward<_Tp>(__t), std::forward<_Up>(__u)); }
using is_transparent = __is_transparent;
};
/// ranges::less function object type.
struct less
{
template<typename _Tp, typename _Up>
requires totally_ordered_with<_Tp, _Up>
constexpr bool
operator()(_Tp&& __t, _Up&& __u) const
noexcept(noexcept(std::declval<_Tp>() < std::declval<_Up>()))
{
if constexpr (__detail::__less_builtin_ptr_cmp<_Tp, _Up>)
{
if (std::__is_constant_evaluated())
return __t < __u;
auto __x = reinterpret_cast<__UINTPTR_TYPE__>(
static_cast<const volatile void*>(std::forward<_Tp>(__t)));
auto __y = reinterpret_cast<__UINTPTR_TYPE__>(
static_cast<const volatile void*>(std::forward<_Up>(__u)));
return __x < __y;
}
else
return std::forward<_Tp>(__t) < std::forward<_Up>(__u);
}
using is_transparent = __is_transparent;
};
/// ranges::greater function object type.
struct greater
{
template<typename _Tp, typename _Up>
requires totally_ordered_with<_Tp, _Up>
constexpr bool
operator()(_Tp&& __t, _Up&& __u) const
noexcept(noexcept(std::declval<_Up>() < std::declval<_Tp>()))
{ return less{}(std::forward<_Up>(__u), std::forward<_Tp>(__t)); }
using is_transparent = __is_transparent;
};
/// ranges::greater_equal function object type.
struct greater_equal
{
template<typename _Tp, typename _Up>
requires totally_ordered_with<_Tp, _Up>
constexpr bool
operator()(_Tp&& __t, _Up&& __u) const
noexcept(noexcept(std::declval<_Tp>() < std::declval<_Up>()))
{ return !less{}(std::forward<_Tp>(__t), std::forward<_Up>(__u)); }
using is_transparent = __is_transparent;
};
/// ranges::less_equal function object type.
struct less_equal
{
template<typename _Tp, typename _Up>
requires totally_ordered_with<_Tp, _Up>
constexpr bool
operator()(_Tp&& __t, _Up&& __u) const
noexcept(noexcept(std::declval<_Up>() < std::declval<_Tp>()))
{ return !less{}(std::forward<_Up>(__u), std::forward<_Tp>(__t)); }
using is_transparent = __is_transparent;
};
} // namespace ranges
#endif // __glibcxx_ranges
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif // C++20
#endif // _RANGES_CMP_H
@@ -0,0 +1,574 @@
// Raw memory manipulators -*- C++ -*-
// Copyright (C) 2020-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/ranges_uninitialized.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{memory}
*/
#ifndef _RANGES_UNINITIALIZED_H
#define _RANGES_UNINITIALIZED_H 1
#if __cplusplus > 201703L
#if __cpp_lib_concepts
#include <bits/ranges_algobase.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
namespace ranges
{
namespace __detail
{
template<typename _Tp>
constexpr void*
__voidify(_Tp& __obj) noexcept
{
return const_cast<void*>
(static_cast<const volatile void*>(std::__addressof(__obj)));
}
template<typename _Iter>
concept __nothrow_input_iterator
= (input_iterator<_Iter>
&& is_lvalue_reference_v<iter_reference_t<_Iter>>
&& same_as<remove_cvref_t<iter_reference_t<_Iter>>,
iter_value_t<_Iter>>);
template<typename _Sent, typename _Iter>
concept __nothrow_sentinel = sentinel_for<_Sent, _Iter>;
template<typename _Range>
concept __nothrow_input_range
= (range<_Range>
&& __nothrow_input_iterator<iterator_t<_Range>>
&& __nothrow_sentinel<sentinel_t<_Range>, iterator_t<_Range>>);
template<typename _Iter>
concept __nothrow_forward_iterator
= (__nothrow_input_iterator<_Iter>
&& forward_iterator<_Iter>
&& __nothrow_sentinel<_Iter, _Iter>);
template<typename _Range>
concept __nothrow_forward_range
= (__nothrow_input_range<_Range>
&& __nothrow_forward_iterator<iterator_t<_Range>>);
} // namespace __detail
struct __destroy_fn
{
template<__detail::__nothrow_input_iterator _Iter,
__detail::__nothrow_sentinel<_Iter> _Sent>
requires destructible<iter_value_t<_Iter>>
constexpr _Iter
operator()(_Iter __first, _Sent __last) const noexcept;
template<__detail::__nothrow_input_range _Range>
requires destructible<range_value_t<_Range>>
constexpr borrowed_iterator_t<_Range>
operator()(_Range&& __r) const noexcept;
};
inline constexpr __destroy_fn destroy{};
namespace __detail
{
template<typename _Iter>
requires destructible<iter_value_t<_Iter>>
struct _DestroyGuard
{
private:
_Iter _M_first;
const _Iter* _M_cur;
public:
explicit
_DestroyGuard(const _Iter& __iter)
: _M_first(__iter), _M_cur(std::__addressof(__iter))
{ }
void
release() noexcept
{ _M_cur = nullptr; }
~_DestroyGuard()
{
if (_M_cur != nullptr)
ranges::destroy(std::move(_M_first), *_M_cur);
}
};
template<typename _Iter>
requires destructible<iter_value_t<_Iter>>
&& is_trivially_destructible_v<iter_value_t<_Iter>>
struct _DestroyGuard<_Iter>
{
explicit
_DestroyGuard(const _Iter&)
{ }
void
release() noexcept
{ }
};
} // namespace __detail
struct __uninitialized_default_construct_fn
{
template<__detail::__nothrow_forward_iterator _Iter,
__detail::__nothrow_sentinel<_Iter> _Sent>
requires default_initializable<iter_value_t<_Iter>>
_Iter
operator()(_Iter __first, _Sent __last) const
{
using _ValueType = remove_reference_t<iter_reference_t<_Iter>>;
if constexpr (is_trivially_default_constructible_v<_ValueType>)
return ranges::next(__first, __last);
else
{
auto __guard = __detail::_DestroyGuard(__first);
for (; __first != __last; ++__first)
::new (__detail::__voidify(*__first)) _ValueType;
__guard.release();
return __first;
}
}
template<__detail::__nothrow_forward_range _Range>
requires default_initializable<range_value_t<_Range>>
borrowed_iterator_t<_Range>
operator()(_Range&& __r) const
{
return (*this)(ranges::begin(__r), ranges::end(__r));
}
};
inline constexpr __uninitialized_default_construct_fn
uninitialized_default_construct{};
struct __uninitialized_default_construct_n_fn
{
template<__detail::__nothrow_forward_iterator _Iter>
requires default_initializable<iter_value_t<_Iter>>
_Iter
operator()(_Iter __first, iter_difference_t<_Iter> __n) const
{
using _ValueType = remove_reference_t<iter_reference_t<_Iter>>;
if constexpr (is_trivially_default_constructible_v<_ValueType>)
return ranges::next(__first, __n);
else
{
auto __guard = __detail::_DestroyGuard(__first);
for (; __n > 0; ++__first, (void) --__n)
::new (__detail::__voidify(*__first)) _ValueType;
__guard.release();
return __first;
}
}
};
inline constexpr __uninitialized_default_construct_n_fn
uninitialized_default_construct_n;
struct __uninitialized_value_construct_fn
{
template<__detail::__nothrow_forward_iterator _Iter,
__detail::__nothrow_sentinel<_Iter> _Sent>
requires default_initializable<iter_value_t<_Iter>>
_Iter
operator()(_Iter __first, _Sent __last) const
{
using _ValueType = remove_reference_t<iter_reference_t<_Iter>>;
if constexpr (is_trivial_v<_ValueType>
&& is_copy_assignable_v<_ValueType>)
return ranges::fill(__first, __last, _ValueType());
else
{
auto __guard = __detail::_DestroyGuard(__first);
for (; __first != __last; ++__first)
::new (__detail::__voidify(*__first)) _ValueType();
__guard.release();
return __first;
}
}
template<__detail::__nothrow_forward_range _Range>
requires default_initializable<range_value_t<_Range>>
borrowed_iterator_t<_Range>
operator()(_Range&& __r) const
{
return (*this)(ranges::begin(__r), ranges::end(__r));
}
};
inline constexpr __uninitialized_value_construct_fn
uninitialized_value_construct{};
struct __uninitialized_value_construct_n_fn
{
template<__detail::__nothrow_forward_iterator _Iter>
requires default_initializable<iter_value_t<_Iter>>
_Iter
operator()(_Iter __first, iter_difference_t<_Iter> __n) const
{
using _ValueType = remove_reference_t<iter_reference_t<_Iter>>;
if constexpr (is_trivial_v<_ValueType>
&& is_copy_assignable_v<_ValueType>)
return ranges::fill_n(__first, __n, _ValueType());
else
{
auto __guard = __detail::_DestroyGuard(__first);
for (; __n > 0; ++__first, (void) --__n)
::new (__detail::__voidify(*__first)) _ValueType();
__guard.release();
return __first;
}
}
};
inline constexpr __uninitialized_value_construct_n_fn
uninitialized_value_construct_n;
template<typename _Iter, typename _Out>
using uninitialized_copy_result = in_out_result<_Iter, _Out>;
struct __uninitialized_copy_fn
{
template<input_iterator _Iter, sentinel_for<_Iter> _ISent,
__detail::__nothrow_forward_iterator _Out,
__detail::__nothrow_sentinel<_Out> _OSent>
requires constructible_from<iter_value_t<_Out>, iter_reference_t<_Iter>>
uninitialized_copy_result<_Iter, _Out>
operator()(_Iter __ifirst, _ISent __ilast,
_Out __ofirst, _OSent __olast) const
{
using _OutType = remove_reference_t<iter_reference_t<_Out>>;
if constexpr (sized_sentinel_for<_ISent, _Iter>
&& sized_sentinel_for<_OSent, _Out>
&& is_trivial_v<_OutType>
&& is_nothrow_assignable_v<_OutType&,
iter_reference_t<_Iter>>)
{
auto __d1 = __ilast - __ifirst;
auto __d2 = __olast - __ofirst;
return ranges::copy_n(std::move(__ifirst), std::min(__d1, __d2),
__ofirst);
}
else
{
auto __guard = __detail::_DestroyGuard(__ofirst);
for (; __ifirst != __ilast && __ofirst != __olast;
++__ofirst, (void)++__ifirst)
::new (__detail::__voidify(*__ofirst)) _OutType(*__ifirst);
__guard.release();
return {std::move(__ifirst), __ofirst};
}
}
template<input_range _IRange, __detail::__nothrow_forward_range _ORange>
requires constructible_from<range_value_t<_ORange>,
range_reference_t<_IRange>>
uninitialized_copy_result<borrowed_iterator_t<_IRange>,
borrowed_iterator_t<_ORange>>
operator()(_IRange&& __inr, _ORange&& __outr) const
{
return (*this)(ranges::begin(__inr), ranges::end(__inr),
ranges::begin(__outr), ranges::end(__outr));
}
};
inline constexpr __uninitialized_copy_fn uninitialized_copy{};
template<typename _Iter, typename _Out>
using uninitialized_copy_n_result = in_out_result<_Iter, _Out>;
struct __uninitialized_copy_n_fn
{
template<input_iterator _Iter, __detail::__nothrow_forward_iterator _Out,
__detail::__nothrow_sentinel<_Out> _Sent>
requires constructible_from<iter_value_t<_Out>, iter_reference_t<_Iter>>
uninitialized_copy_n_result<_Iter, _Out>
operator()(_Iter __ifirst, iter_difference_t<_Iter> __n,
_Out __ofirst, _Sent __olast) const
{
using _OutType = remove_reference_t<iter_reference_t<_Out>>;
if constexpr (sized_sentinel_for<_Sent, _Out>
&& is_trivial_v<_OutType>
&& is_nothrow_assignable_v<_OutType&,
iter_reference_t<_Iter>>)
{
auto __d = __olast - __ofirst;
return ranges::copy_n(std::move(__ifirst), std::min(__n, __d),
__ofirst);
}
else
{
auto __guard = __detail::_DestroyGuard(__ofirst);
for (; __n > 0 && __ofirst != __olast;
++__ofirst, (void)++__ifirst, (void)--__n)
::new (__detail::__voidify(*__ofirst)) _OutType(*__ifirst);
__guard.release();
return {std::move(__ifirst), __ofirst};
}
}
};
inline constexpr __uninitialized_copy_n_fn uninitialized_copy_n{};
template<typename _Iter, typename _Out>
using uninitialized_move_result = in_out_result<_Iter, _Out>;
struct __uninitialized_move_fn
{
template<input_iterator _Iter, sentinel_for<_Iter> _ISent,
__detail::__nothrow_forward_iterator _Out,
__detail::__nothrow_sentinel<_Out> _OSent>
requires constructible_from<iter_value_t<_Out>,
iter_rvalue_reference_t<_Iter>>
uninitialized_move_result<_Iter, _Out>
operator()(_Iter __ifirst, _ISent __ilast,
_Out __ofirst, _OSent __olast) const
{
using _OutType = remove_reference_t<iter_reference_t<_Out>>;
if constexpr (sized_sentinel_for<_ISent, _Iter>
&& sized_sentinel_for<_OSent, _Out>
&& is_trivial_v<_OutType>
&& is_nothrow_assignable_v<_OutType&,
iter_rvalue_reference_t<_Iter>>)
{
auto __d1 = __ilast - __ifirst;
auto __d2 = __olast - __ofirst;
auto [__in, __out]
= ranges::copy_n(std::make_move_iterator(std::move(__ifirst)),
std::min(__d1, __d2), __ofirst);
return {std::move(__in).base(), __out};
}
else
{
auto __guard = __detail::_DestroyGuard(__ofirst);
for (; __ifirst != __ilast && __ofirst != __olast;
++__ofirst, (void)++__ifirst)
::new (__detail::__voidify(*__ofirst))
_OutType(ranges::iter_move(__ifirst));
__guard.release();
return {std::move(__ifirst), __ofirst};
}
}
template<input_range _IRange, __detail::__nothrow_forward_range _ORange>
requires constructible_from<range_value_t<_ORange>,
range_rvalue_reference_t<_IRange>>
uninitialized_move_result<borrowed_iterator_t<_IRange>,
borrowed_iterator_t<_ORange>>
operator()(_IRange&& __inr, _ORange&& __outr) const
{
return (*this)(ranges::begin(__inr), ranges::end(__inr),
ranges::begin(__outr), ranges::end(__outr));
}
};
inline constexpr __uninitialized_move_fn uninitialized_move{};
template<typename _Iter, typename _Out>
using uninitialized_move_n_result = in_out_result<_Iter, _Out>;
struct __uninitialized_move_n_fn
{
template<input_iterator _Iter, __detail::__nothrow_forward_iterator _Out,
__detail::__nothrow_sentinel<_Out> _Sent>
requires constructible_from<iter_value_t<_Out>,
iter_rvalue_reference_t<_Iter>>
uninitialized_move_n_result<_Iter, _Out>
operator()(_Iter __ifirst, iter_difference_t<_Iter> __n,
_Out __ofirst, _Sent __olast) const
{
using _OutType = remove_reference_t<iter_reference_t<_Out>>;
if constexpr (sized_sentinel_for<_Sent, _Out>
&& is_trivial_v<_OutType>
&& is_nothrow_assignable_v<_OutType&,
iter_rvalue_reference_t<_Iter>>)
{
auto __d = __olast - __ofirst;
auto [__in, __out]
= ranges::copy_n(std::make_move_iterator(std::move(__ifirst)),
std::min(__n, __d), __ofirst);
return {std::move(__in).base(), __out};
}
else
{
auto __guard = __detail::_DestroyGuard(__ofirst);
for (; __n > 0 && __ofirst != __olast;
++__ofirst, (void)++__ifirst, (void)--__n)
::new (__detail::__voidify(*__ofirst))
_OutType(ranges::iter_move(__ifirst));
__guard.release();
return {std::move(__ifirst), __ofirst};
}
}
};
inline constexpr __uninitialized_move_n_fn uninitialized_move_n{};
struct __uninitialized_fill_fn
{
template<__detail::__nothrow_forward_iterator _Iter,
__detail::__nothrow_sentinel<_Iter> _Sent, typename _Tp>
requires constructible_from<iter_value_t<_Iter>, const _Tp&>
_Iter
operator()(_Iter __first, _Sent __last, const _Tp& __x) const
{
using _ValueType = remove_reference_t<iter_reference_t<_Iter>>;
if constexpr (is_trivial_v<_ValueType>
&& is_nothrow_assignable_v<_ValueType&, const _Tp&>)
return ranges::fill(__first, __last, __x);
else
{
auto __guard = __detail::_DestroyGuard(__first);
for (; __first != __last; ++__first)
::new (__detail::__voidify(*__first)) _ValueType(__x);
__guard.release();
return __first;
}
}
template<__detail::__nothrow_forward_range _Range, typename _Tp>
requires constructible_from<range_value_t<_Range>, const _Tp&>
borrowed_iterator_t<_Range>
operator()(_Range&& __r, const _Tp& __x) const
{
return (*this)(ranges::begin(__r), ranges::end(__r), __x);
}
};
inline constexpr __uninitialized_fill_fn uninitialized_fill{};
struct __uninitialized_fill_n_fn
{
template<__detail::__nothrow_forward_iterator _Iter, typename _Tp>
requires constructible_from<iter_value_t<_Iter>, const _Tp&>
_Iter
operator()(_Iter __first, iter_difference_t<_Iter> __n,
const _Tp& __x) const
{
using _ValueType = remove_reference_t<iter_reference_t<_Iter>>;
if constexpr (is_trivial_v<_ValueType>
&& is_nothrow_assignable_v<_ValueType&, const _Tp&>)
return ranges::fill_n(__first, __n, __x);
else
{
auto __guard = __detail::_DestroyGuard(__first);
for (; __n > 0; ++__first, (void)--__n)
::new (__detail::__voidify(*__first)) _ValueType(__x);
__guard.release();
return __first;
}
}
};
inline constexpr __uninitialized_fill_n_fn uninitialized_fill_n{};
struct __construct_at_fn
{
template<typename _Tp, typename... _Args>
requires requires {
::new (std::declval<void*>()) _Tp(std::declval<_Args>()...);
}
constexpr _Tp*
operator()(_Tp* __location, _Args&&... __args) const
noexcept(noexcept(std::construct_at(__location,
std::forward<_Args>(__args)...)))
{
return std::construct_at(__location,
std::forward<_Args>(__args)...);
}
};
inline constexpr __construct_at_fn construct_at{};
struct __destroy_at_fn
{
template<destructible _Tp>
constexpr void
operator()(_Tp* __location) const noexcept
{
if constexpr (is_array_v<_Tp>)
ranges::destroy(ranges::begin(*__location), ranges::end(*__location));
else
__location->~_Tp();
}
};
inline constexpr __destroy_at_fn destroy_at{};
template<__detail::__nothrow_input_iterator _Iter,
__detail::__nothrow_sentinel<_Iter> _Sent>
requires destructible<iter_value_t<_Iter>>
constexpr _Iter
__destroy_fn::operator()(_Iter __first, _Sent __last) const noexcept
{
if constexpr (is_trivially_destructible_v<iter_value_t<_Iter>>)
return ranges::next(std::move(__first), __last);
else
{
for (; __first != __last; ++__first)
ranges::destroy_at(std::__addressof(*__first));
return __first;
}
}
template<__detail::__nothrow_input_range _Range>
requires destructible<range_value_t<_Range>>
constexpr borrowed_iterator_t<_Range>
__destroy_fn::operator()(_Range&& __r) const noexcept
{
return (*this)(ranges::begin(__r), ranges::end(__r));
}
struct __destroy_n_fn
{
template<__detail::__nothrow_input_iterator _Iter>
requires destructible<iter_value_t<_Iter>>
constexpr _Iter
operator()(_Iter __first, iter_difference_t<_Iter> __n) const noexcept
{
if constexpr (is_trivially_destructible_v<iter_value_t<_Iter>>)
return ranges::next(std::move(__first), __n);
else
{
for (; __n > 0; ++__first, (void)--__n)
ranges::destroy_at(std::__addressof(*__first));
return __first;
}
}
};
inline constexpr __destroy_n_fn destroy_n{};
}
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif // concepts
#endif // C++20
#endif // _RANGES_UNINITIALIZED_H
+823
View File
@@ -0,0 +1,823 @@
// Utilities for representing and manipulating ranges -*- C++ -*-
// Copyright (C) 2019-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/ranges_util.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{ranges}
*/
#ifndef _RANGES_UTIL_H
#define _RANGES_UTIL_H 1
#if __cplusplus > 201703L
# include <bits/ranges_base.h>
# include <bits/utility.h>
# include <bits/invoke.h>
#ifdef __glibcxx_ranges
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
namespace ranges
{
// C++20 24.5 [range.utility] Range utilities
namespace __detail
{
template<typename _Range>
concept __simple_view = view<_Range> && range<const _Range>
&& same_as<iterator_t<_Range>, iterator_t<const _Range>>
&& same_as<sentinel_t<_Range>, sentinel_t<const _Range>>;
template<typename _It>
concept __has_arrow = input_iterator<_It>
&& (is_pointer_v<_It> || requires(_It __it) { __it.operator->(); });
using std::__detail::__different_from;
} // namespace __detail
/// The ranges::view_interface class template
template<typename _Derived>
requires is_class_v<_Derived> && same_as<_Derived, remove_cv_t<_Derived>>
class view_interface
{
private:
constexpr _Derived& _M_derived() noexcept
{
static_assert(derived_from<_Derived, view_interface<_Derived>>);
static_assert(view<_Derived>);
return static_cast<_Derived&>(*this);
}
constexpr const _Derived& _M_derived() const noexcept
{
static_assert(derived_from<_Derived, view_interface<_Derived>>);
static_assert(view<_Derived>);
return static_cast<const _Derived&>(*this);
}
static constexpr bool
_S_bool(bool) noexcept; // not defined
template<typename _Tp>
static constexpr bool
_S_empty(_Tp& __t)
noexcept(noexcept(_S_bool(ranges::begin(__t) == ranges::end(__t))))
{ return ranges::begin(__t) == ranges::end(__t); }
template<typename _Tp>
static constexpr auto
_S_size(_Tp& __t)
noexcept(noexcept(ranges::end(__t) - ranges::begin(__t)))
{ return ranges::end(__t) - ranges::begin(__t); }
public:
constexpr bool
empty()
noexcept(noexcept(_S_empty(_M_derived())))
requires forward_range<_Derived> && (!sized_range<_Derived>)
{ return _S_empty(_M_derived()); }
constexpr bool
empty()
noexcept(noexcept(ranges::size(_M_derived()) == 0))
requires sized_range<_Derived>
{ return ranges::size(_M_derived()) == 0; }
constexpr bool
empty() const
noexcept(noexcept(_S_empty(_M_derived())))
requires forward_range<const _Derived> && (!sized_range<const _Derived>)
{ return _S_empty(_M_derived()); }
constexpr bool
empty() const
noexcept(noexcept(ranges::size(_M_derived()) == 0))
requires sized_range<const _Derived>
{ return ranges::size(_M_derived()) == 0; }
constexpr explicit
operator bool() noexcept(noexcept(ranges::empty(_M_derived())))
requires requires { ranges::empty(_M_derived()); }
{ return !ranges::empty(_M_derived()); }
constexpr explicit
operator bool() const noexcept(noexcept(ranges::empty(_M_derived())))
requires requires { ranges::empty(_M_derived()); }
{ return !ranges::empty(_M_derived()); }
constexpr auto
data() noexcept(noexcept(ranges::begin(_M_derived())))
requires contiguous_iterator<iterator_t<_Derived>>
{ return std::to_address(ranges::begin(_M_derived())); }
constexpr auto
data() const noexcept(noexcept(ranges::begin(_M_derived())))
requires range<const _Derived>
&& contiguous_iterator<iterator_t<const _Derived>>
{ return std::to_address(ranges::begin(_M_derived())); }
constexpr auto
size() noexcept(noexcept(_S_size(_M_derived())))
requires forward_range<_Derived>
&& sized_sentinel_for<sentinel_t<_Derived>, iterator_t<_Derived>>
{ return _S_size(_M_derived()); }
constexpr auto
size() const noexcept(noexcept(_S_size(_M_derived())))
requires forward_range<const _Derived>
&& sized_sentinel_for<sentinel_t<const _Derived>,
iterator_t<const _Derived>>
{ return _S_size(_M_derived()); }
constexpr decltype(auto)
front() requires forward_range<_Derived>
{
__glibcxx_assert(!empty());
return *ranges::begin(_M_derived());
}
constexpr decltype(auto)
front() const requires forward_range<const _Derived>
{
__glibcxx_assert(!empty());
return *ranges::begin(_M_derived());
}
constexpr decltype(auto)
back()
requires bidirectional_range<_Derived> && common_range<_Derived>
{
__glibcxx_assert(!empty());
return *ranges::prev(ranges::end(_M_derived()));
}
constexpr decltype(auto)
back() const
requires bidirectional_range<const _Derived>
&& common_range<const _Derived>
{
__glibcxx_assert(!empty());
return *ranges::prev(ranges::end(_M_derived()));
}
template<random_access_range _Range = _Derived>
constexpr decltype(auto)
operator[](range_difference_t<_Range> __n)
{ return ranges::begin(_M_derived())[__n]; }
template<random_access_range _Range = const _Derived>
constexpr decltype(auto)
operator[](range_difference_t<_Range> __n) const
{ return ranges::begin(_M_derived())[__n]; }
#if __cplusplus > 202002L
constexpr auto
cbegin() requires input_range<_Derived>
{ return ranges::cbegin(_M_derived()); }
constexpr auto
cbegin() const requires input_range<const _Derived>
{ return ranges::cbegin(_M_derived()); }
constexpr auto
cend() requires input_range<_Derived>
{ return ranges::cend(_M_derived()); }
constexpr auto
cend() const requires input_range<const _Derived>
{ return ranges::cend(_M_derived()); }
#endif
};
namespace __detail
{
template<typename _From, typename _To>
concept __uses_nonqualification_pointer_conversion
= is_pointer_v<_From> && is_pointer_v<_To>
&& !convertible_to<remove_pointer_t<_From>(*)[],
remove_pointer_t<_To>(*)[]>;
template<typename _From, typename _To>
concept __convertible_to_non_slicing = convertible_to<_From, _To>
&& !__uses_nonqualification_pointer_conversion<decay_t<_From>,
decay_t<_To>>;
#if __glibcxx_tuple_like // >= C++23
// P2165R4 version of __pair_like is defined in <bits/stl_pair.h>.
#else
// C++20 version of __pair_like from P2321R2.
template<typename _Tp>
concept __pair_like
= !is_reference_v<_Tp> && requires(_Tp __t)
{
typename tuple_size<_Tp>::type;
requires derived_from<tuple_size<_Tp>, integral_constant<size_t, 2>>;
typename tuple_element_t<0, remove_const_t<_Tp>>;
typename tuple_element_t<1, remove_const_t<_Tp>>;
{ get<0>(__t) } -> convertible_to<const tuple_element_t<0, _Tp>&>;
{ get<1>(__t) } -> convertible_to<const tuple_element_t<1, _Tp>&>;
};
#endif
template<typename _Tp, typename _Up, typename _Vp>
concept __pair_like_convertible_from
= !range<_Tp> && !is_reference_v<_Vp> && __pair_like<_Tp>
&& constructible_from<_Tp, _Up, _Vp>
&& __convertible_to_non_slicing<_Up, tuple_element_t<0, _Tp>>
&& convertible_to<_Vp, tuple_element_t<1, _Tp>>;
} // namespace __detail
namespace views { struct _Drop; } // defined in <ranges>
enum class subrange_kind : bool { unsized, sized };
/// The ranges::subrange class template
template<input_or_output_iterator _It, sentinel_for<_It> _Sent = _It,
subrange_kind _Kind = sized_sentinel_for<_Sent, _It>
? subrange_kind::sized : subrange_kind::unsized>
requires (_Kind == subrange_kind::sized || !sized_sentinel_for<_Sent, _It>)
class subrange : public view_interface<subrange<_It, _Sent, _Kind>>
{
private:
static constexpr bool _S_store_size
= _Kind == subrange_kind::sized && !sized_sentinel_for<_Sent, _It>;
friend struct views::_Drop; // Needs to inspect _S_store_size.
_It _M_begin = _It();
[[no_unique_address]] _Sent _M_end = _Sent();
using __size_type
= __detail::__make_unsigned_like_t<iter_difference_t<_It>>;
template<typename _Tp, bool = _S_store_size>
struct _Size
{
[[__gnu__::__always_inline__]]
constexpr _Size(_Tp = {}) { }
};
template<typename _Tp>
struct _Size<_Tp, true>
{
[[__gnu__::__always_inline__]]
constexpr _Size(_Tp __s = {}) : _M_size(__s) { }
_Tp _M_size;
};
[[no_unique_address]] _Size<__size_type> _M_size = {};
public:
subrange() requires default_initializable<_It> = default;
constexpr
subrange(__detail::__convertible_to_non_slicing<_It> auto __i, _Sent __s)
noexcept(is_nothrow_constructible_v<_It, decltype(__i)>
&& is_nothrow_constructible_v<_Sent, _Sent&>)
requires (!_S_store_size)
: _M_begin(std::move(__i)), _M_end(__s)
{ }
constexpr
subrange(__detail::__convertible_to_non_slicing<_It> auto __i, _Sent __s,
__size_type __n)
noexcept(is_nothrow_constructible_v<_It, decltype(__i)>
&& is_nothrow_constructible_v<_Sent, _Sent&>)
requires (_Kind == subrange_kind::sized)
: _M_begin(std::move(__i)), _M_end(__s), _M_size(__n)
{ }
template<__detail::__different_from<subrange> _Rng>
requires borrowed_range<_Rng>
&& __detail::__convertible_to_non_slicing<iterator_t<_Rng>, _It>
&& convertible_to<sentinel_t<_Rng>, _Sent>
constexpr
subrange(_Rng&& __r)
noexcept(noexcept(subrange(__r, ranges::size(__r))))
requires _S_store_size && sized_range<_Rng>
: subrange(__r, ranges::size(__r))
{ }
template<__detail::__different_from<subrange> _Rng>
requires borrowed_range<_Rng>
&& __detail::__convertible_to_non_slicing<iterator_t<_Rng>, _It>
&& convertible_to<sentinel_t<_Rng>, _Sent>
constexpr
subrange(_Rng&& __r)
noexcept(noexcept(subrange(ranges::begin(__r), ranges::end(__r))))
requires (!_S_store_size)
: subrange(ranges::begin(__r), ranges::end(__r))
{ }
template<borrowed_range _Rng>
requires __detail::__convertible_to_non_slicing<iterator_t<_Rng>, _It>
&& convertible_to<sentinel_t<_Rng>, _Sent>
constexpr
subrange(_Rng&& __r, __size_type __n)
noexcept(noexcept(subrange(ranges::begin(__r), ranges::end(__r), __n)))
requires (_Kind == subrange_kind::sized)
: subrange{ranges::begin(__r), ranges::end(__r), __n}
{ }
template<__detail::__different_from<subrange> _PairLike>
requires __detail::__pair_like_convertible_from<_PairLike, const _It&,
const _Sent&>
constexpr
operator _PairLike() const
{ return _PairLike(_M_begin, _M_end); }
constexpr _It
begin() const requires copyable<_It>
{ return _M_begin; }
[[nodiscard]] constexpr _It
begin() requires (!copyable<_It>)
{ return std::move(_M_begin); }
constexpr _Sent end() const { return _M_end; }
constexpr bool empty() const { return _M_begin == _M_end; }
constexpr __size_type
size() const requires (_Kind == subrange_kind::sized)
{
if constexpr (_S_store_size)
return _M_size._M_size;
else
return __detail::__to_unsigned_like(_M_end - _M_begin);
}
[[nodiscard]] constexpr subrange
next(iter_difference_t<_It> __n = 1) const &
requires forward_iterator<_It>
{
auto __tmp = *this;
__tmp.advance(__n);
return __tmp;
}
[[nodiscard]] constexpr subrange
next(iter_difference_t<_It> __n = 1) &&
{
advance(__n);
return std::move(*this);
}
[[nodiscard]] constexpr subrange
prev(iter_difference_t<_It> __n = 1) const
requires bidirectional_iterator<_It>
{
auto __tmp = *this;
__tmp.advance(-__n);
return __tmp;
}
constexpr subrange&
advance(iter_difference_t<_It> __n)
{
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 3433. subrange::advance(n) has UB when n < 0
if constexpr (bidirectional_iterator<_It>)
if (__n < 0)
{
ranges::advance(_M_begin, __n);
if constexpr (_S_store_size)
_M_size._M_size += __detail::__to_unsigned_like(-__n);
return *this;
}
__glibcxx_assert(__n >= 0);
auto __d = __n - ranges::advance(_M_begin, __n, _M_end);
if constexpr (_S_store_size)
_M_size._M_size -= __detail::__to_unsigned_like(__d);
return *this;
}
};
template<input_or_output_iterator _It, sentinel_for<_It> _Sent>
subrange(_It, _Sent) -> subrange<_It, _Sent>;
template<input_or_output_iterator _It, sentinel_for<_It> _Sent>
subrange(_It, _Sent,
__detail::__make_unsigned_like_t<iter_difference_t<_It>>)
-> subrange<_It, _Sent, subrange_kind::sized>;
template<borrowed_range _Rng>
subrange(_Rng&&)
-> subrange<iterator_t<_Rng>, sentinel_t<_Rng>,
(sized_range<_Rng>
|| sized_sentinel_for<sentinel_t<_Rng>, iterator_t<_Rng>>)
? subrange_kind::sized : subrange_kind::unsized>;
template<borrowed_range _Rng>
subrange(_Rng&&,
__detail::__make_unsigned_like_t<range_difference_t<_Rng>>)
-> subrange<iterator_t<_Rng>, sentinel_t<_Rng>, subrange_kind::sized>;
template<size_t _Num, class _It, class _Sent, subrange_kind _Kind>
requires (_Num < 2)
constexpr auto
get(const subrange<_It, _Sent, _Kind>& __r)
{
if constexpr (_Num == 0)
return __r.begin();
else
return __r.end();
}
template<size_t _Num, class _It, class _Sent, subrange_kind _Kind>
requires (_Num < 2)
constexpr auto
get(subrange<_It, _Sent, _Kind>&& __r)
{
if constexpr (_Num == 0)
return __r.begin();
else
return __r.end();
}
template<typename _It, typename _Sent, subrange_kind _Kind>
inline constexpr bool
enable_borrowed_range<subrange<_It, _Sent, _Kind>> = true;
template<range _Range>
using borrowed_subrange_t = __conditional_t<borrowed_range<_Range>,
subrange<iterator_t<_Range>>,
dangling>;
// __is_subrange is defined in <bits/utility.h>.
template<typename _Iter, typename _Sent, subrange_kind _Kind>
inline constexpr bool __detail::__is_subrange<subrange<_Iter, _Sent, _Kind>> = true;
} // namespace ranges
#if __glibcxx_tuple_like // >= C++23
// __is_tuple_like_v is defined in <bits/stl_pair.h>.
template<typename _It, typename _Sent, ranges::subrange_kind _Kind>
inline constexpr bool __is_tuple_like_v<ranges::subrange<_It, _Sent, _Kind>> = true;
#endif
// The following ranges algorithms are used by <ranges>, and are defined here
// so that <ranges> can avoid including all of <bits/ranges_algo.h>.
namespace ranges
{
struct __find_fn
{
template<input_iterator _Iter, sentinel_for<_Iter> _Sent, typename _Tp,
typename _Proj = identity>
requires indirect_binary_predicate<ranges::equal_to,
projected<_Iter, _Proj>, const _Tp*>
constexpr _Iter
operator()(_Iter __first, _Sent __last,
const _Tp& __value, _Proj __proj = {}) const
{
while (__first != __last
&& !(std::__invoke(__proj, *__first) == __value))
++__first;
return __first;
}
template<input_range _Range, typename _Tp, typename _Proj = identity>
requires indirect_binary_predicate<ranges::equal_to,
projected<iterator_t<_Range>, _Proj>,
const _Tp*>
constexpr borrowed_iterator_t<_Range>
operator()(_Range&& __r, const _Tp& __value, _Proj __proj = {}) const
{
return (*this)(ranges::begin(__r), ranges::end(__r),
__value, std::move(__proj));
}
};
inline constexpr __find_fn find{};
struct __find_if_fn
{
template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
typename _Proj = identity,
indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
constexpr _Iter
operator()(_Iter __first, _Sent __last,
_Pred __pred, _Proj __proj = {}) const
{
while (__first != __last
&& !(bool)std::__invoke(__pred, std::__invoke(__proj, *__first)))
++__first;
return __first;
}
template<input_range _Range, typename _Proj = identity,
indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>>
_Pred>
constexpr borrowed_iterator_t<_Range>
operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const
{
return (*this)(ranges::begin(__r), ranges::end(__r),
std::move(__pred), std::move(__proj));
}
};
inline constexpr __find_if_fn find_if{};
struct __find_if_not_fn
{
template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
typename _Proj = identity,
indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
constexpr _Iter
operator()(_Iter __first, _Sent __last,
_Pred __pred, _Proj __proj = {}) const
{
while (__first != __last
&& (bool)std::__invoke(__pred, std::__invoke(__proj, *__first)))
++__first;
return __first;
}
template<input_range _Range, typename _Proj = identity,
indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>>
_Pred>
constexpr borrowed_iterator_t<_Range>
operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const
{
return (*this)(ranges::begin(__r), ranges::end(__r),
std::move(__pred), std::move(__proj));
}
};
inline constexpr __find_if_not_fn find_if_not{};
template<typename _Iter1, typename _Iter2>
struct in_in_result
{
[[no_unique_address]] _Iter1 in1;
[[no_unique_address]] _Iter2 in2;
template<typename _IIter1, typename _IIter2>
requires convertible_to<const _Iter1&, _IIter1>
&& convertible_to<const _Iter2&, _IIter2>
constexpr
operator in_in_result<_IIter1, _IIter2>() const &
{ return {in1, in2}; }
template<typename _IIter1, typename _IIter2>
requires convertible_to<_Iter1, _IIter1>
&& convertible_to<_Iter2, _IIter2>
constexpr
operator in_in_result<_IIter1, _IIter2>() &&
{ return {std::move(in1), std::move(in2)}; }
};
template<typename _Iter1, typename _Iter2>
using mismatch_result = in_in_result<_Iter1, _Iter2>;
struct __mismatch_fn
{
template<input_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
input_iterator _Iter2, sentinel_for<_Iter2> _Sent2,
typename _Pred = ranges::equal_to,
typename _Proj1 = identity, typename _Proj2 = identity>
requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2>
constexpr mismatch_result<_Iter1, _Iter2>
operator()(_Iter1 __first1, _Sent1 __last1,
_Iter2 __first2, _Sent2 __last2, _Pred __pred = {},
_Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
{
while (__first1 != __last1 && __first2 != __last2
&& (bool)std::__invoke(__pred,
std::__invoke(__proj1, *__first1),
std::__invoke(__proj2, *__first2)))
{
++__first1;
++__first2;
}
return { std::move(__first1), std::move(__first2) };
}
template<input_range _Range1, input_range _Range2,
typename _Pred = ranges::equal_to,
typename _Proj1 = identity, typename _Proj2 = identity>
requires indirectly_comparable<iterator_t<_Range1>, iterator_t<_Range2>,
_Pred, _Proj1, _Proj2>
constexpr mismatch_result<iterator_t<_Range1>, iterator_t<_Range2>>
operator()(_Range1&& __r1, _Range2&& __r2, _Pred __pred = {},
_Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
{
return (*this)(ranges::begin(__r1), ranges::end(__r1),
ranges::begin(__r2), ranges::end(__r2),
std::move(__pred),
std::move(__proj1), std::move(__proj2));
}
};
inline constexpr __mismatch_fn mismatch{};
struct __search_fn
{
template<forward_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
forward_iterator _Iter2, sentinel_for<_Iter2> _Sent2,
typename _Pred = ranges::equal_to,
typename _Proj1 = identity, typename _Proj2 = identity>
requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2>
constexpr subrange<_Iter1>
operator()(_Iter1 __first1, _Sent1 __last1,
_Iter2 __first2, _Sent2 __last2, _Pred __pred = {},
_Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
{
if (__first1 == __last1 || __first2 == __last2)
return {__first1, __first1};
for (;;)
{
for (;;)
{
if (__first1 == __last1)
return {__first1, __first1};
if (std::__invoke(__pred,
std::__invoke(__proj1, *__first1),
std::__invoke(__proj2, *__first2)))
break;
++__first1;
}
auto __cur1 = __first1;
auto __cur2 = __first2;
for (;;)
{
if (++__cur2 == __last2)
return {__first1, ++__cur1};
if (++__cur1 == __last1)
return {__cur1, __cur1};
if (!(bool)std::__invoke(__pred,
std::__invoke(__proj1, *__cur1),
std::__invoke(__proj2, *__cur2)))
{
++__first1;
break;
}
}
}
}
template<forward_range _Range1, forward_range _Range2,
typename _Pred = ranges::equal_to,
typename _Proj1 = identity, typename _Proj2 = identity>
requires indirectly_comparable<iterator_t<_Range1>, iterator_t<_Range2>,
_Pred, _Proj1, _Proj2>
constexpr borrowed_subrange_t<_Range1>
operator()(_Range1&& __r1, _Range2&& __r2, _Pred __pred = {},
_Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
{
return (*this)(ranges::begin(__r1), ranges::end(__r1),
ranges::begin(__r2), ranges::end(__r2),
std::move(__pred),
std::move(__proj1), std::move(__proj2));
}
};
inline constexpr __search_fn search{};
struct __min_fn
{
template<typename _Tp, typename _Proj = identity,
indirect_strict_weak_order<projected<const _Tp*, _Proj>>
_Comp = ranges::less>
constexpr const _Tp&
operator()(const _Tp& __a, const _Tp& __b,
_Comp __comp = {}, _Proj __proj = {}) const
{
if (std::__invoke(__comp,
std::__invoke(__proj, __b),
std::__invoke(__proj, __a)))
return __b;
else
return __a;
}
template<input_range _Range, typename _Proj = identity,
indirect_strict_weak_order<projected<iterator_t<_Range>, _Proj>>
_Comp = ranges::less>
requires indirectly_copyable_storable<iterator_t<_Range>,
range_value_t<_Range>*>
constexpr range_value_t<_Range>
operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
{
auto __first = ranges::begin(__r);
auto __last = ranges::end(__r);
__glibcxx_assert(__first != __last);
auto __result = *__first;
while (++__first != __last)
{
auto __tmp = *__first;
if (std::__invoke(__comp,
std::__invoke(__proj, __tmp),
std::__invoke(__proj, __result)))
__result = std::move(__tmp);
}
return __result;
}
template<copyable _Tp, typename _Proj = identity,
indirect_strict_weak_order<projected<const _Tp*, _Proj>>
_Comp = ranges::less>
constexpr _Tp
operator()(initializer_list<_Tp> __r,
_Comp __comp = {}, _Proj __proj = {}) const
{
return (*this)(ranges::subrange(__r),
std::move(__comp), std::move(__proj));
}
};
inline constexpr __min_fn min{};
struct __adjacent_find_fn
{
template<forward_iterator _Iter, sentinel_for<_Iter> _Sent,
typename _Proj = identity,
indirect_binary_predicate<projected<_Iter, _Proj>,
projected<_Iter, _Proj>> _Pred
= ranges::equal_to>
constexpr _Iter
operator()(_Iter __first, _Sent __last,
_Pred __pred = {}, _Proj __proj = {}) const
{
if (__first == __last)
return __first;
auto __next = __first;
for (; ++__next != __last; __first = __next)
{
if (std::__invoke(__pred,
std::__invoke(__proj, *__first),
std::__invoke(__proj, *__next)))
return __first;
}
return __next;
}
template<forward_range _Range, typename _Proj = identity,
indirect_binary_predicate<
projected<iterator_t<_Range>, _Proj>,
projected<iterator_t<_Range>, _Proj>> _Pred = ranges::equal_to>
constexpr borrowed_iterator_t<_Range>
operator()(_Range&& __r, _Pred __pred = {}, _Proj __proj = {}) const
{
return (*this)(ranges::begin(__r), ranges::end(__r),
std::move(__pred), std::move(__proj));
}
};
inline constexpr __adjacent_find_fn adjacent_find{};
} // namespace ranges
using ranges::get;
template<typename _Iter, typename _Sent, ranges::subrange_kind _Kind>
struct tuple_size<ranges::subrange<_Iter, _Sent, _Kind>>
: integral_constant<size_t, 2>
{ };
template<typename _Iter, typename _Sent, ranges::subrange_kind _Kind>
struct tuple_element<0, ranges::subrange<_Iter, _Sent, _Kind>>
{ using type = _Iter; };
template<typename _Iter, typename _Sent, ranges::subrange_kind _Kind>
struct tuple_element<1, ranges::subrange<_Iter, _Sent, _Kind>>
{ using type = _Sent; };
template<typename _Iter, typename _Sent, ranges::subrange_kind _Kind>
struct tuple_element<0, const ranges::subrange<_Iter, _Sent, _Kind>>
{ using type = _Iter; };
template<typename _Iter, typename _Sent, ranges::subrange_kind _Kind>
struct tuple_element<1, const ranges::subrange<_Iter, _Sent, _Kind>>
{ using type = _Sent; };
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif // library concepts
#endif // C++20
#endif // _RANGES_UTIL_H
+462
View File
@@ -0,0 +1,462 @@
// Implementation of std::reference_wrapper -*- C++ -*-
// Copyright (C) 2004-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file include/bits/refwrap.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{functional}
*/
#ifndef _GLIBCXX_REFWRAP_H
#define _GLIBCXX_REFWRAP_H 1
#pragma GCC system_header
#if __cplusplus >= 201103L
#include <bits/move.h>
#include <bits/invoke.h>
#include <bits/stl_function.h> // for unary_function and binary_function
#if __glibcxx_reference_wrapper >= 202403L // >= C++26
# include <compare>
#endif
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/// @cond undocumented
/**
* Derives from @c unary_function or @c binary_function, or perhaps
* nothing, depending on the number of arguments provided. The
* primary template is the basis case, which derives nothing.
*/
template<typename _Res, typename... _ArgTypes>
struct _Maybe_unary_or_binary_function { };
// Ignore warnings about unary_function and binary_function.
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
/// Derives from @c unary_function, as appropriate.
template<typename _Res, typename _T1>
struct _Maybe_unary_or_binary_function<_Res, _T1>
: std::unary_function<_T1, _Res> { };
/// Derives from @c binary_function, as appropriate.
template<typename _Res, typename _T1, typename _T2>
struct _Maybe_unary_or_binary_function<_Res, _T1, _T2>
: std::binary_function<_T1, _T2, _Res> { };
#pragma GCC diagnostic pop
template<typename _Signature>
struct _Mem_fn_traits;
template<typename _Res, typename _Class, typename... _ArgTypes>
struct _Mem_fn_traits_base
{
using __result_type = _Res;
using __maybe_type
= _Maybe_unary_or_binary_function<_Res, _Class*, _ArgTypes...>;
using __arity = integral_constant<size_t, sizeof...(_ArgTypes)>;
};
#define _GLIBCXX_MEM_FN_TRAITS2(_CV, _REF, _LVAL, _RVAL) \
template<typename _Res, typename _Class, typename... _ArgTypes> \
struct _Mem_fn_traits<_Res (_Class::*)(_ArgTypes...) _CV _REF> \
: _Mem_fn_traits_base<_Res, _CV _Class, _ArgTypes...> \
{ \
using __vararg = false_type; \
}; \
template<typename _Res, typename _Class, typename... _ArgTypes> \
struct _Mem_fn_traits<_Res (_Class::*)(_ArgTypes... ...) _CV _REF> \
: _Mem_fn_traits_base<_Res, _CV _Class, _ArgTypes...> \
{ \
using __vararg = true_type; \
};
#define _GLIBCXX_MEM_FN_TRAITS(_REF, _LVAL, _RVAL) \
_GLIBCXX_MEM_FN_TRAITS2( , _REF, _LVAL, _RVAL) \
_GLIBCXX_MEM_FN_TRAITS2(const , _REF, _LVAL, _RVAL) \
_GLIBCXX_MEM_FN_TRAITS2(volatile , _REF, _LVAL, _RVAL) \
_GLIBCXX_MEM_FN_TRAITS2(const volatile, _REF, _LVAL, _RVAL)
_GLIBCXX_MEM_FN_TRAITS( , true_type, true_type)
_GLIBCXX_MEM_FN_TRAITS(&, true_type, false_type)
_GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type)
#if __cplusplus > 201402L
_GLIBCXX_MEM_FN_TRAITS(noexcept, true_type, true_type)
_GLIBCXX_MEM_FN_TRAITS(& noexcept, true_type, false_type)
_GLIBCXX_MEM_FN_TRAITS(&& noexcept, false_type, true_type)
#endif
#undef _GLIBCXX_MEM_FN_TRAITS
#undef _GLIBCXX_MEM_FN_TRAITS2
/// If we have found a result_type, extract it.
template<typename _Functor, typename = __void_t<>>
struct _Maybe_get_result_type
{ };
template<typename _Functor>
struct _Maybe_get_result_type<_Functor,
__void_t<typename _Functor::result_type>>
{ typedef typename _Functor::result_type result_type; };
/**
* Base class for any function object that has a weak result type, as
* defined in 20.8.2 [func.require] of C++11.
*/
template<typename _Functor>
struct _Weak_result_type_impl
: _Maybe_get_result_type<_Functor>
{ };
/// Retrieve the result type for a function type.
template<typename _Res, typename... _ArgTypes _GLIBCXX_NOEXCEPT_PARM>
struct _Weak_result_type_impl<_Res(_ArgTypes...) _GLIBCXX_NOEXCEPT_QUAL>
{ typedef _Res result_type; };
/// Retrieve the result type for a varargs function type.
template<typename _Res, typename... _ArgTypes _GLIBCXX_NOEXCEPT_PARM>
struct _Weak_result_type_impl<_Res(_ArgTypes......) _GLIBCXX_NOEXCEPT_QUAL>
{ typedef _Res result_type; };
/// Retrieve the result type for a function pointer.
template<typename _Res, typename... _ArgTypes _GLIBCXX_NOEXCEPT_PARM>
struct _Weak_result_type_impl<_Res(*)(_ArgTypes...) _GLIBCXX_NOEXCEPT_QUAL>
{ typedef _Res result_type; };
/// Retrieve the result type for a varargs function pointer.
template<typename _Res, typename... _ArgTypes _GLIBCXX_NOEXCEPT_PARM>
struct
_Weak_result_type_impl<_Res(*)(_ArgTypes......) _GLIBCXX_NOEXCEPT_QUAL>
{ typedef _Res result_type; };
// Let _Weak_result_type_impl perform the real work.
template<typename _Functor,
bool = is_member_function_pointer<_Functor>::value>
struct _Weak_result_type_memfun
: _Weak_result_type_impl<_Functor>
{ };
// A pointer to member function has a weak result type.
template<typename _MemFunPtr>
struct _Weak_result_type_memfun<_MemFunPtr, true>
{
using result_type = typename _Mem_fn_traits<_MemFunPtr>::__result_type;
};
// A pointer to data member doesn't have a weak result type.
template<typename _Func, typename _Class>
struct _Weak_result_type_memfun<_Func _Class::*, false>
{ };
/**
* Strip top-level cv-qualifiers from the function object and let
* _Weak_result_type_memfun perform the real work.
*/
template<typename _Functor>
struct _Weak_result_type
: _Weak_result_type_memfun<typename remove_cv<_Functor>::type>
{ };
#if __cplusplus <= 201703L
// Detect nested argument_type.
template<typename _Tp, typename = __void_t<>>
struct _Refwrap_base_arg1
{ };
// Nested argument_type.
template<typename _Tp>
struct _Refwrap_base_arg1<_Tp,
__void_t<typename _Tp::argument_type>>
{
typedef typename _Tp::argument_type argument_type;
};
// Detect nested first_argument_type and second_argument_type.
template<typename _Tp, typename = __void_t<>>
struct _Refwrap_base_arg2
{ };
// Nested first_argument_type and second_argument_type.
template<typename _Tp>
struct _Refwrap_base_arg2<_Tp,
__void_t<typename _Tp::first_argument_type,
typename _Tp::second_argument_type>>
{
typedef typename _Tp::first_argument_type first_argument_type;
typedef typename _Tp::second_argument_type second_argument_type;
};
/**
* Derives from unary_function or binary_function when it
* can. Specializations handle all of the easy cases. The primary
* template determines what to do with a class type, which may
* derive from both unary_function and binary_function.
*/
template<typename _Tp>
struct _Reference_wrapper_base
: _Weak_result_type<_Tp>, _Refwrap_base_arg1<_Tp>, _Refwrap_base_arg2<_Tp>
{ };
// Ignore warnings about unary_function and binary_function.
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
// - a function type (unary)
template<typename _Res, typename _T1 _GLIBCXX_NOEXCEPT_PARM>
struct _Reference_wrapper_base<_Res(_T1) _GLIBCXX_NOEXCEPT_QUAL>
: unary_function<_T1, _Res>
{ };
template<typename _Res, typename _T1>
struct _Reference_wrapper_base<_Res(_T1) const>
: unary_function<_T1, _Res>
{ };
template<typename _Res, typename _T1>
struct _Reference_wrapper_base<_Res(_T1) volatile>
: unary_function<_T1, _Res>
{ };
template<typename _Res, typename _T1>
struct _Reference_wrapper_base<_Res(_T1) const volatile>
: unary_function<_T1, _Res>
{ };
// - a function type (binary)
template<typename _Res, typename _T1, typename _T2 _GLIBCXX_NOEXCEPT_PARM>
struct _Reference_wrapper_base<_Res(_T1, _T2) _GLIBCXX_NOEXCEPT_QUAL>
: binary_function<_T1, _T2, _Res>
{ };
template<typename _Res, typename _T1, typename _T2>
struct _Reference_wrapper_base<_Res(_T1, _T2) const>
: binary_function<_T1, _T2, _Res>
{ };
template<typename _Res, typename _T1, typename _T2>
struct _Reference_wrapper_base<_Res(_T1, _T2) volatile>
: binary_function<_T1, _T2, _Res>
{ };
template<typename _Res, typename _T1, typename _T2>
struct _Reference_wrapper_base<_Res(_T1, _T2) const volatile>
: binary_function<_T1, _T2, _Res>
{ };
// - a function pointer type (unary)
template<typename _Res, typename _T1 _GLIBCXX_NOEXCEPT_PARM>
struct _Reference_wrapper_base<_Res(*)(_T1) _GLIBCXX_NOEXCEPT_QUAL>
: unary_function<_T1, _Res>
{ };
// - a function pointer type (binary)
template<typename _Res, typename _T1, typename _T2 _GLIBCXX_NOEXCEPT_PARM>
struct _Reference_wrapper_base<_Res(*)(_T1, _T2) _GLIBCXX_NOEXCEPT_QUAL>
: binary_function<_T1, _T2, _Res>
{ };
template<typename _Tp, bool = is_member_function_pointer<_Tp>::value>
struct _Reference_wrapper_base_memfun
: _Reference_wrapper_base<_Tp>
{ };
template<typename _MemFunPtr>
struct _Reference_wrapper_base_memfun<_MemFunPtr, true>
: _Mem_fn_traits<_MemFunPtr>::__maybe_type
{
using result_type = typename _Mem_fn_traits<_MemFunPtr>::__result_type;
};
#pragma GCC diagnostic pop
#endif // ! C++20
/// @endcond
/**
* @brief Primary class template for reference_wrapper.
* @ingroup functors
*/
template<typename _Tp>
class reference_wrapper
#if __cplusplus <= 201703L
// In C++20 std::reference_wrapper<T> allows T to be incomplete,
// so checking for nested types could result in ODR violations.
: public _Reference_wrapper_base_memfun<typename remove_cv<_Tp>::type>
#endif
{
_Tp* _M_data;
_GLIBCXX20_CONSTEXPR
static _Tp* _S_fun(_Tp& __r) noexcept { return std::__addressof(__r); }
static void _S_fun(_Tp&&) = delete;
template<typename _Up, typename _Up2 = __remove_cvref_t<_Up>>
using __not_same
= typename enable_if<!is_same<reference_wrapper, _Up2>::value>::type;
public:
typedef _Tp type;
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 2993. reference_wrapper<T> conversion from T&&
// 3041. Unnecessary decay in reference_wrapper
template<typename _Up, typename = __not_same<_Up>, typename
= decltype(reference_wrapper::_S_fun(std::declval<_Up>()))>
_GLIBCXX20_CONSTEXPR
reference_wrapper(_Up&& __uref)
noexcept(noexcept(reference_wrapper::_S_fun(std::declval<_Up>())))
: _M_data(reference_wrapper::_S_fun(std::forward<_Up>(__uref)))
{ }
reference_wrapper(const reference_wrapper&) = default;
reference_wrapper&
operator=(const reference_wrapper&) = default;
_GLIBCXX20_CONSTEXPR
operator _Tp&() const noexcept
{ return this->get(); }
_GLIBCXX20_CONSTEXPR
_Tp&
get() const noexcept
{ return *_M_data; }
template<typename... _Args>
_GLIBCXX20_CONSTEXPR
typename __invoke_result<_Tp&, _Args...>::type
operator()(_Args&&... __args) const
noexcept(__is_nothrow_invocable<_Tp&, _Args...>::value)
{
#if __cplusplus > 201703L
if constexpr (is_object_v<type>)
static_assert(sizeof(type), "type must be complete");
#endif
return std::__invoke(get(), std::forward<_Args>(__args)...);
}
#if __glibcxx_reference_wrapper >= 202403L // >= C++26
// [refwrap.comparisons], comparisons
[[nodiscard]]
friend constexpr bool
operator==(reference_wrapper __x, reference_wrapper __y)
requires requires { { __x.get() == __y.get() } -> convertible_to<bool>; }
{ return __x.get() == __y.get(); }
[[nodiscard]]
friend constexpr bool
operator==(reference_wrapper __x, const _Tp& __y)
requires requires { { __x.get() == __y } -> convertible_to<bool>; }
{ return __x.get() == __y; }
[[nodiscard]]
friend constexpr bool
operator==(reference_wrapper __x, reference_wrapper<const _Tp> __y)
requires (!is_const_v<_Tp>)
&& requires { { __x.get() == __y.get() } -> convertible_to<bool>; }
{ return __x.get() == __y.get(); }
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 4071. reference_wrapper comparisons are not SFINAE-friendly
[[nodiscard]]
friend constexpr auto
operator<=>(reference_wrapper __x, reference_wrapper __y)
requires requires (const _Tp __t) {
{ __t < __t } -> __detail::__boolean_testable;
}
{ return __detail::__synth3way(__x.get(), __y.get()); }
[[nodiscard]]
friend constexpr auto
operator<=>(reference_wrapper __x, const _Tp& __y)
requires requires { { __y < __y } -> __detail::__boolean_testable; }
{ return __detail::__synth3way(__x.get(), __y); }
[[nodiscard]]
friend constexpr auto
operator<=>(reference_wrapper __x, reference_wrapper<const _Tp> __y)
requires (!is_const_v<_Tp>) && requires (const _Tp __t) {
{ __t < __t } -> __detail::__boolean_testable;
}
{ return __detail::__synth3way(__x.get(), __y.get()); }
#endif
};
#if __cpp_deduction_guides
template<typename _Tp>
reference_wrapper(_Tp&) -> reference_wrapper<_Tp>;
#endif
/// @relates reference_wrapper @{
/// Denotes a reference should be taken to a variable.
template<typename _Tp>
_GLIBCXX20_CONSTEXPR
inline reference_wrapper<_Tp>
ref(_Tp& __t) noexcept
{ return reference_wrapper<_Tp>(__t); }
/// Denotes a const reference should be taken to a variable.
template<typename _Tp>
_GLIBCXX20_CONSTEXPR
inline reference_wrapper<const _Tp>
cref(const _Tp& __t) noexcept
{ return reference_wrapper<const _Tp>(__t); }
template<typename _Tp>
void ref(const _Tp&&) = delete;
template<typename _Tp>
void cref(const _Tp&&) = delete;
/// std::ref overload to prevent wrapping a reference_wrapper
template<typename _Tp>
_GLIBCXX20_CONSTEXPR
inline reference_wrapper<_Tp>
ref(reference_wrapper<_Tp> __t) noexcept
{ return __t; }
/// std::cref overload to prevent wrapping a reference_wrapper
template<typename _Tp>
_GLIBCXX20_CONSTEXPR
inline reference_wrapper<const _Tp>
cref(reference_wrapper<_Tp> __t) noexcept
{ return { __t.get() }; }
/// @}
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif // C++11
#endif // _GLIBCXX_REFWRAP_H
+148
View File
@@ -0,0 +1,148 @@
// Saturation arithmetic -*- C++ -*-
// Copyright The GNU Toolchain Authors.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file include/bits/sat_arith.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{numeric}
*/
#ifndef _GLIBCXX_SAT_ARITH_H
#define _GLIBCXX_SAT_ARITH_H 1
#pragma GCC system_header
#include <bits/version.h>
#ifdef __glibcxx_saturation_arithmetic // C++ >= 26
#include <concepts>
#include <ext/numeric_traits.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/// Add two integers, with saturation in case of overflow.
template<typename _Tp> requires __is_standard_integer<_Tp>::value
constexpr _Tp
add_sat(_Tp __x, _Tp __y) noexcept
{
_Tp __z;
if (!__builtin_add_overflow(__x, __y, &__z))
return __z;
if constexpr (is_unsigned_v<_Tp>)
return __gnu_cxx::__int_traits<_Tp>::__max;
else if (__x < 0)
return __gnu_cxx::__int_traits<_Tp>::__min;
else
return __gnu_cxx::__int_traits<_Tp>::__max;
}
/// Subtract one integer from another, with saturation in case of overflow.
template<typename _Tp> requires __is_standard_integer<_Tp>::value
constexpr _Tp
sub_sat(_Tp __x, _Tp __y) noexcept
{
_Tp __z;
if (!__builtin_sub_overflow(__x, __y, &__z))
return __z;
if constexpr (is_unsigned_v<_Tp>)
return __gnu_cxx::__int_traits<_Tp>::__min;
else if (__x < 0)
return __gnu_cxx::__int_traits<_Tp>::__min;
else
return __gnu_cxx::__int_traits<_Tp>::__max;
}
/// Multiply two integers, with saturation in case of overflow.
template<typename _Tp> requires __is_standard_integer<_Tp>::value
constexpr _Tp
mul_sat(_Tp __x, _Tp __y) noexcept
{
_Tp __z;
if (!__builtin_mul_overflow(__x, __y, &__z))
return __z;
if constexpr (is_unsigned_v<_Tp>)
return __gnu_cxx::__int_traits<_Tp>::__max;
else if (__x < 0 != __y < 0)
return __gnu_cxx::__int_traits<_Tp>::__min;
else
return __gnu_cxx::__int_traits<_Tp>::__max;
}
/// Divide one integer by another, with saturation in case of overflow.
template<typename _Tp> requires __is_standard_integer<_Tp>::value
constexpr _Tp
div_sat(_Tp __x, _Tp __y) noexcept
{
__glibcxx_assert(__y != 0);
if constexpr (is_signed_v<_Tp>)
if (__x == __gnu_cxx::__int_traits<_Tp>::__min && __y == _Tp(-1))
return __gnu_cxx::__int_traits<_Tp>::__max;
return __x / __y;
}
/// Divide one integer by another, with saturation in case of overflow.
template<typename _Res, typename _Tp>
requires __is_standard_integer<_Res>::value
&& __is_standard_integer<_Tp>::value
constexpr _Res
saturate_cast(_Tp __x) noexcept
{
constexpr int __digits_R = __gnu_cxx::__int_traits<_Res>::__digits;
constexpr int __digits_T = __gnu_cxx::__int_traits<_Tp>::__digits;
constexpr _Res __max_Res = __gnu_cxx::__int_traits<_Res>::__max;
if constexpr (is_signed_v<_Res> == is_signed_v<_Tp>)
{
if constexpr (__digits_R < __digits_T)
{
constexpr _Res __min_Res = __gnu_cxx::__int_traits<_Res>::__min;
if (__x < static_cast<_Tp>(__min_Res))
return __min_Res;
else if (__x > static_cast<_Tp>(__max_Res))
return __max_Res;
}
}
else if constexpr (is_signed_v<_Tp>) // Res is unsigned
{
if (__x < 0)
return 0;
else if (make_unsigned_t<_Tp>(__x) > __max_Res)
return __gnu_cxx::__int_traits<_Res>::__max;
}
else // Tp is unsigned, Res is signed
{
if (__x > make_unsigned_t<_Res>(__max_Res))
return __max_Res;
}
return static_cast<_Res>(__x);
}
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif // __glibcxx_saturation_arithmetic
#endif /* _GLIBCXX_SAT_ARITH_H */
+239
View File
@@ -0,0 +1,239 @@
// C++ includes used for precompiling -*- C++ -*-
// Copyright (C) 2003-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file stdc++.h
* This is an implementation file for a precompiled header.
*/
// 17.4.1.2 Headers
// C
#ifndef _GLIBCXX_NO_ASSERT
#include <cassert>
#endif
#include <cctype>
#include <cfloat>
#include <ciso646>
#include <climits>
#include <csetjmp>
#include <cstdarg>
#include <cstddef>
#include <cstdlib>
#if __cplusplus >= 201103L
#include <cstdint>
#endif
// C++
// #include <bitset>
// #include <complex>
#include <algorithm>
#include <bitset>
#include <functional>
#include <iterator>
#include <limits>
#include <memory>
#include <new>
#include <numeric>
#include <typeinfo>
#include <utility>
#if __cplusplus >= 201103L
#include <array>
#include <atomic>
#include <initializer_list>
#include <ratio>
#include <scoped_allocator>
#include <tuple>
#include <typeindex>
#include <type_traits>
#endif
#if __cplusplus >= 201402L
#endif
#if __cplusplus >= 201703L
#include <any>
// #include <execution>
#include <optional>
#include <variant>
#include <string_view>
#endif
#if __cplusplus >= 202002L
#include <bit>
#include <compare>
#include <concepts>
#include <numbers>
#include <ranges>
#include <span>
#include <source_location>
#include <version>
#endif
#if __cplusplus > 202002L
#include <expected>
#include <stdatomic.h>
#if __cpp_impl_coroutine
# include <coroutine>
#endif
#endif
#if _GLIBCXX_HOSTED
// C
#ifndef _GLIBCXX_NO_ASSERT
#include <cassert>
#endif
#include <cctype>
#include <cerrno>
#include <cfloat>
#include <ciso646>
#include <climits>
#include <clocale>
#include <cmath>
#include <csetjmp>
#include <csignal>
#include <cstdarg>
#include <cstddef>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <cwchar>
#include <cwctype>
#if __cplusplus >= 201103L
#include <ccomplex>
#include <cfenv>
#include <cinttypes>
#include <cstdalign>
#include <cstdbool>
#include <cstdint>
#include <ctgmath>
#include <cuchar>
#endif
// C++
#include <complex>
#include <deque>
#include <exception>
#include <fstream>
#include <functional>
#include <iomanip>
#include <ios>
#include <iosfwd>
#include <iostream>
#include <istream>
#include <iterator>
#include <limits>
#include <list>
#include <locale>
#include <map>
#include <memory>
#include <new>
#include <numeric>
#include <ostream>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdexcept>
#include <streambuf>
#include <string>
#include <typeinfo>
#include <utility>
#include <valarray>
#include <vector>
#if __cplusplus >= 201103L
#include <array>
#include <atomic>
#include <chrono>
#include <codecvt>
#include <condition_variable>
#include <forward_list>
#include <future>
#include <initializer_list>
#include <mutex>
#include <random>
#include <ratio>
#include <regex>
#include <scoped_allocator>
#include <system_error>
#include <thread>
#include <tuple>
#include <typeindex>
#include <type_traits>
#include <unordered_map>
#include <unordered_set>
#endif
#if __cplusplus >= 201402L
#include <shared_mutex>
#endif
#if __cplusplus >= 201703L
#include <any>
#include <charconv>
// #include <execution>
#include <filesystem>
#include <optional>
#include <memory_resource>
#include <variant>
#endif
#if __cplusplus >= 202002L
#include <barrier>
#include <bit>
#include <compare>
#include <concepts>
#include <format>
#include <latch>
#include <numbers>
#include <ranges>
#include <span>
#include <stop_token>
#include <semaphore>
#include <source_location>
#include <syncstream>
#include <version>
#endif
#if __cplusplus > 202002L
#include <expected>
#include <generator>
#include <print>
#include <spanstream>
#if __has_include(<stacktrace>)
# include <stacktrace>
#endif
#include <stdatomic.h>
#include <stdfloat>
#endif
#if __cplusplus > 202302L
#include <text_encoding>
#endif
#endif // HOSTED
+53
View File
@@ -0,0 +1,53 @@
// C++ includes used for precompiling TR1 -*- C++ -*-
// Copyright (C) 2006-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file stdtr1c++.h
* This is an implementation file for a precompiled header.
*/
#include <bits/stdc++.h>
#include <tr1/array>
#include <tr1/cctype>
#include <tr1/cfenv>
#include <tr1/cfloat>
#include <tr1/cinttypes>
#include <tr1/climits>
#include <tr1/cmath>
#include <tr1/complex>
#include <tr1/cstdarg>
#include <tr1/cstdbool>
#include <tr1/cstdint>
#include <tr1/cstdio>
#include <tr1/cstdlib>
#include <tr1/ctgmath>
#include <tr1/ctime>
#include <tr1/cwchar>
#include <tr1/cwctype>
#include <tr1/functional>
#include <tr1/random>
#include <tr1/tuple>
#include <tr1/unordered_map>
#include <tr1/unordered_set>
#include <tr1/utility>
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,267 @@
// nonstandard construct and destroy functions -*- C++ -*-
// Copyright (C) 2001-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/*
*
* Copyright (c) 1994
* Hewlett-Packard Company
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Hewlett-Packard Company makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*
*
* Copyright (c) 1996,1997
* Silicon Graphics Computer Systems, Inc.
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Silicon Graphics makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*/
/** @file bits/stl_construct.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{memory}
*/
#ifndef _STL_CONSTRUCT_H
#define _STL_CONSTRUCT_H 1
#include <new>
#include <bits/move.h>
#include <bits/stl_iterator_base_types.h> // for iterator_traits
#include <bits/stl_iterator_base_funcs.h> // for advance
/* This file provides the C++17 functions std::destroy_at, std::destroy, and
* std::destroy_n, and the C++20 function std::construct_at.
* It also provides std::_Construct, std::_Destroy,and std::_Destroy_n functions
* which are defined in all standard modes and so can be used in C++98-14 code.
* The _Destroy functions will dispatch to destroy_at during constant
* evaluation, because calls to that function are intercepted by the compiler
* to allow use in constant expressions.
*/
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
#if __glibcxx_raw_memory_algorithms // >= C++17
template <typename _Tp>
_GLIBCXX20_CONSTEXPR inline void
destroy_at(_Tp* __location)
{
if constexpr (__cplusplus > 201703L && is_array_v<_Tp>)
{
for (auto& __x : *__location)
std::destroy_at(std::__addressof(__x));
}
else
__location->~_Tp();
}
#if __cpp_constexpr_dynamic_alloc // >= C++20
template<typename _Tp, typename... _Args>
constexpr auto
construct_at(_Tp* __location, _Args&&... __args)
noexcept(noexcept(::new((void*)0) _Tp(std::declval<_Args>()...)))
-> decltype(::new((void*)0) _Tp(std::declval<_Args>()...))
{ return ::new((void*)__location) _Tp(std::forward<_Args>(__args)...); }
#endif // C++20
#endif// C++17
/**
* Constructs an object in existing memory by invoking an allocated
* object's constructor with an initializer.
*/
#if __cplusplus >= 201103L
template<typename _Tp, typename... _Args>
_GLIBCXX20_CONSTEXPR
inline void
_Construct(_Tp* __p, _Args&&... __args)
{
#if __cpp_constexpr_dynamic_alloc // >= C++20
if (std::__is_constant_evaluated())
{
// Allow std::_Construct to be used in constant expressions.
std::construct_at(__p, std::forward<_Args>(__args)...);
return;
}
#endif
::new((void*)__p) _Tp(std::forward<_Args>(__args)...);
}
#else
template<typename _T1, typename _T2>
inline void
_Construct(_T1* __p, const _T2& __value)
{
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 402. wrong new expression in [some_]allocator::construct
::new(static_cast<void*>(__p)) _T1(__value);
}
#endif
template<typename _T1>
inline void
_Construct_novalue(_T1* __p)
{ ::new((void*)__p) _T1; }
template<typename _ForwardIterator>
_GLIBCXX20_CONSTEXPR void
_Destroy(_ForwardIterator __first, _ForwardIterator __last);
/**
* Destroy the object pointed to by a pointer type.
*/
template<typename _Tp>
_GLIBCXX14_CONSTEXPR inline void
_Destroy(_Tp* __pointer)
{
#if __cpp_constexpr_dynamic_alloc // >= C++20
std::destroy_at(__pointer);
#else
__pointer->~_Tp();
#endif
}
template<bool>
struct _Destroy_aux
{
template<typename _ForwardIterator>
static _GLIBCXX20_CONSTEXPR void
__destroy(_ForwardIterator __first, _ForwardIterator __last)
{
for (; __first != __last; ++__first)
std::_Destroy(std::__addressof(*__first));
}
};
template<>
struct _Destroy_aux<true>
{
template<typename _ForwardIterator>
static void
__destroy(_ForwardIterator, _ForwardIterator) { }
};
/**
* Destroy a range of objects. If the value_type of the object has
* a trivial destructor, the compiler should optimize all of this
* away, otherwise the objects' destructors must be invoked.
*/
template<typename _ForwardIterator>
_GLIBCXX20_CONSTEXPR inline void
_Destroy(_ForwardIterator __first, _ForwardIterator __last)
{
typedef typename iterator_traits<_ForwardIterator>::value_type
_Value_type;
#if __cplusplus >= 201103L
// A deleted destructor is trivial, this ensures we reject such types:
static_assert(is_destructible<_Value_type>::value,
"value type is destructible");
#endif
#if __cpp_constexpr_dynamic_alloc // >= C++20
if (std::__is_constant_evaluated())
return std::_Destroy_aux<false>::__destroy(__first, __last);
#endif
std::_Destroy_aux<__has_trivial_destructor(_Value_type)>::
__destroy(__first, __last);
}
template<bool>
struct _Destroy_n_aux
{
template<typename _ForwardIterator, typename _Size>
static _GLIBCXX20_CONSTEXPR _ForwardIterator
__destroy_n(_ForwardIterator __first, _Size __count)
{
for (; __count > 0; (void)++__first, --__count)
std::_Destroy(std::__addressof(*__first));
return __first;
}
};
template<>
struct _Destroy_n_aux<true>
{
template<typename _ForwardIterator, typename _Size>
static _ForwardIterator
__destroy_n(_ForwardIterator __first, _Size __count)
{
std::advance(__first, __count);
return __first;
}
};
/**
* Destroy a range of objects. If the value_type of the object has
* a trivial destructor, the compiler should optimize all of this
* away, otherwise the objects' destructors must be invoked.
*/
template<typename _ForwardIterator, typename _Size>
_GLIBCXX20_CONSTEXPR inline _ForwardIterator
_Destroy_n(_ForwardIterator __first, _Size __count)
{
typedef typename iterator_traits<_ForwardIterator>::value_type
_Value_type;
#if __cplusplus >= 201103L
// A deleted destructor is trivial, this ensures we reject such types:
static_assert(is_destructible<_Value_type>::value,
"value type is destructible");
#endif
#if __cpp_constexpr_dynamic_alloc // >= C++20
if (std::__is_constant_evaluated())
return std::_Destroy_n_aux<false>::__destroy_n(__first, __count);
#endif
return std::_Destroy_n_aux<__has_trivial_destructor(_Value_type)>::
__destroy_n(__first, __count);
}
#if __glibcxx_raw_memory_algorithms // >= C++17
template <typename _ForwardIterator>
_GLIBCXX20_CONSTEXPR inline void
destroy(_ForwardIterator __first, _ForwardIterator __last)
{
std::_Destroy(__first, __last);
}
template <typename _ForwardIterator, typename _Size>
_GLIBCXX20_CONSTEXPR inline _ForwardIterator
destroy_n(_ForwardIterator __first, _Size __count)
{
return std::_Destroy_n(__first, __count);
}
#endif // C++17
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif /* _STL_CONSTRUCT_H */
File diff suppressed because it is too large Load Diff
+584
View File
@@ -0,0 +1,584 @@
// Heap implementation -*- C++ -*-
// Copyright (C) 2001-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/*
*
* Copyright (c) 1994
* Hewlett-Packard Company
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Hewlett-Packard Company makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*
* Copyright (c) 1997
* Silicon Graphics Computer Systems, Inc.
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Silicon Graphics makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*/
/** @file bits/stl_heap.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{queue}
*/
#ifndef _STL_HEAP_H
#define _STL_HEAP_H 1
#include <debug/debug.h>
#include <bits/move.h>
#include <bits/predefined_ops.h>
#include <bits/stl_iterator_base_funcs.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
* @defgroup heap_algorithms Heap
* @ingroup sorting_algorithms
*/
template<typename _RandomAccessIterator, typename _Distance,
typename _Compare>
_GLIBCXX20_CONSTEXPR
_Distance
__is_heap_until(_RandomAccessIterator __first, _Distance __n,
_Compare& __comp)
{
_Distance __parent = 0;
for (_Distance __child = 1; __child < __n; ++__child)
{
if (__comp(__first + __parent, __first + __child))
return __child;
if ((__child & 1) == 0)
++__parent;
}
return __n;
}
// __is_heap, a predicate testing whether or not a range is a heap.
// This function is an extension, not part of the C++ standard.
template<typename _RandomAccessIterator, typename _Distance>
_GLIBCXX20_CONSTEXPR
inline bool
__is_heap(_RandomAccessIterator __first, _Distance __n)
{
__gnu_cxx::__ops::_Iter_less_iter __comp;
return std::__is_heap_until(__first, __n, __comp) == __n;
}
template<typename _RandomAccessIterator, typename _Compare,
typename _Distance>
_GLIBCXX20_CONSTEXPR
inline bool
__is_heap(_RandomAccessIterator __first, _Compare __comp, _Distance __n)
{
typedef __decltype(__comp) _Cmp;
__gnu_cxx::__ops::_Iter_comp_iter<_Cmp> __cmp(_GLIBCXX_MOVE(__comp));
return std::__is_heap_until(__first, __n, __cmp) == __n;
}
template<typename _RandomAccessIterator>
_GLIBCXX20_CONSTEXPR
inline bool
__is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
{ return std::__is_heap(__first, std::distance(__first, __last)); }
template<typename _RandomAccessIterator, typename _Compare>
_GLIBCXX20_CONSTEXPR
inline bool
__is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
_Compare __comp)
{
return std::__is_heap(__first, _GLIBCXX_MOVE(__comp),
std::distance(__first, __last));
}
// Heap-manipulation functions: push_heap, pop_heap, make_heap, sort_heap,
// + is_heap and is_heap_until in C++0x.
template<typename _RandomAccessIterator, typename _Distance, typename _Tp,
typename _Compare>
_GLIBCXX20_CONSTEXPR
void
__push_heap(_RandomAccessIterator __first,
_Distance __holeIndex, _Distance __topIndex, _Tp __value,
_Compare& __comp)
{
_Distance __parent = (__holeIndex - 1) / 2;
while (__holeIndex > __topIndex && __comp(__first + __parent, __value))
{
*(__first + __holeIndex) = _GLIBCXX_MOVE(*(__first + __parent));
__holeIndex = __parent;
__parent = (__holeIndex - 1) / 2;
}
*(__first + __holeIndex) = _GLIBCXX_MOVE(__value);
}
/**
* @brief Push an element onto a heap.
* @param __first Start of heap.
* @param __last End of heap + element.
* @ingroup heap_algorithms
*
* This operation pushes the element at last-1 onto the valid heap
* over the range [__first,__last-1). After completion,
* [__first,__last) is a valid heap.
*/
template<typename _RandomAccessIterator>
_GLIBCXX20_CONSTEXPR
inline void
push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
{
typedef typename iterator_traits<_RandomAccessIterator>::value_type
_ValueType;
typedef typename iterator_traits<_RandomAccessIterator>::difference_type
_DistanceType;
// concept requirements
__glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
_RandomAccessIterator>)
__glibcxx_function_requires(_LessThanComparableConcept<_ValueType>)
__glibcxx_requires_valid_range(__first, __last);
__glibcxx_requires_irreflexive(__first, __last);
__glibcxx_requires_heap(__first, __last - 1);
__gnu_cxx::__ops::_Iter_less_val __comp;
_ValueType __value = _GLIBCXX_MOVE(*(__last - 1));
std::__push_heap(__first, _DistanceType((__last - __first) - 1),
_DistanceType(0), _GLIBCXX_MOVE(__value), __comp);
}
/**
* @brief Push an element onto a heap using comparison functor.
* @param __first Start of heap.
* @param __last End of heap + element.
* @param __comp Comparison functor.
* @ingroup heap_algorithms
*
* This operation pushes the element at __last-1 onto the valid
* heap over the range [__first,__last-1). After completion,
* [__first,__last) is a valid heap. Compare operations are
* performed using comp.
*/
template<typename _RandomAccessIterator, typename _Compare>
_GLIBCXX20_CONSTEXPR
inline void
push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
_Compare __comp)
{
typedef typename iterator_traits<_RandomAccessIterator>::value_type
_ValueType;
typedef typename iterator_traits<_RandomAccessIterator>::difference_type
_DistanceType;
// concept requirements
__glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
_RandomAccessIterator>)
__glibcxx_requires_valid_range(__first, __last);
__glibcxx_requires_irreflexive_pred(__first, __last, __comp);
__glibcxx_requires_heap_pred(__first, __last - 1, __comp);
__decltype(__gnu_cxx::__ops::__iter_comp_val(_GLIBCXX_MOVE(__comp)))
__cmp(_GLIBCXX_MOVE(__comp));
_ValueType __value = _GLIBCXX_MOVE(*(__last - 1));
std::__push_heap(__first, _DistanceType((__last - __first) - 1),
_DistanceType(0), _GLIBCXX_MOVE(__value), __cmp);
}
template<typename _RandomAccessIterator, typename _Distance,
typename _Tp, typename _Compare>
_GLIBCXX20_CONSTEXPR
void
__adjust_heap(_RandomAccessIterator __first, _Distance __holeIndex,
_Distance __len, _Tp __value, _Compare __comp)
{
const _Distance __topIndex = __holeIndex;
_Distance __secondChild = __holeIndex;
while (__secondChild < (__len - 1) / 2)
{
__secondChild = 2 * (__secondChild + 1);
if (__comp(__first + __secondChild,
__first + (__secondChild - 1)))
__secondChild--;
*(__first + __holeIndex) = _GLIBCXX_MOVE(*(__first + __secondChild));
__holeIndex = __secondChild;
}
if ((__len & 1) == 0 && __secondChild == (__len - 2) / 2)
{
__secondChild = 2 * (__secondChild + 1);
*(__first + __holeIndex) = _GLIBCXX_MOVE(*(__first
+ (__secondChild - 1)));
__holeIndex = __secondChild - 1;
}
__decltype(__gnu_cxx::__ops::__iter_comp_val(_GLIBCXX_MOVE(__comp)))
__cmp(_GLIBCXX_MOVE(__comp));
std::__push_heap(__first, __holeIndex, __topIndex,
_GLIBCXX_MOVE(__value), __cmp);
}
template<typename _RandomAccessIterator, typename _Compare>
_GLIBCXX20_CONSTEXPR
inline void
__pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
_RandomAccessIterator __result, _Compare& __comp)
{
typedef typename iterator_traits<_RandomAccessIterator>::value_type
_ValueType;
typedef typename iterator_traits<_RandomAccessIterator>::difference_type
_DistanceType;
_ValueType __value = _GLIBCXX_MOVE(*__result);
*__result = _GLIBCXX_MOVE(*__first);
std::__adjust_heap(__first, _DistanceType(0),
_DistanceType(__last - __first),
_GLIBCXX_MOVE(__value), __comp);
}
/**
* @brief Pop an element off a heap.
* @param __first Start of heap.
* @param __last End of heap.
* @pre [__first, __last) is a valid, non-empty range.
* @ingroup heap_algorithms
*
* This operation pops the top of the heap. The elements __first
* and __last-1 are swapped and [__first,__last-1) is made into a
* heap.
*/
template<typename _RandomAccessIterator>
_GLIBCXX20_CONSTEXPR
inline void
pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
{
// concept requirements
__glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
_RandomAccessIterator>)
__glibcxx_function_requires(_LessThanComparableConcept<
typename iterator_traits<_RandomAccessIterator>::value_type>)
__glibcxx_requires_non_empty_range(__first, __last);
__glibcxx_requires_valid_range(__first, __last);
__glibcxx_requires_irreflexive(__first, __last);
__glibcxx_requires_heap(__first, __last);
if (__last - __first > 1)
{
--__last;
__gnu_cxx::__ops::_Iter_less_iter __comp;
std::__pop_heap(__first, __last, __last, __comp);
}
}
/**
* @brief Pop an element off a heap using comparison functor.
* @param __first Start of heap.
* @param __last End of heap.
* @param __comp Comparison functor to use.
* @ingroup heap_algorithms
*
* This operation pops the top of the heap. The elements __first
* and __last-1 are swapped and [__first,__last-1) is made into a
* heap. Comparisons are made using comp.
*/
template<typename _RandomAccessIterator, typename _Compare>
_GLIBCXX20_CONSTEXPR
inline void
pop_heap(_RandomAccessIterator __first,
_RandomAccessIterator __last, _Compare __comp)
{
// concept requirements
__glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
_RandomAccessIterator>)
__glibcxx_requires_valid_range(__first, __last);
__glibcxx_requires_irreflexive_pred(__first, __last, __comp);
__glibcxx_requires_non_empty_range(__first, __last);
__glibcxx_requires_heap_pred(__first, __last, __comp);
if (__last - __first > 1)
{
typedef __decltype(__comp) _Cmp;
__gnu_cxx::__ops::_Iter_comp_iter<_Cmp> __cmp(_GLIBCXX_MOVE(__comp));
--__last;
std::__pop_heap(__first, __last, __last, __cmp);
}
}
template<typename _RandomAccessIterator, typename _Compare>
_GLIBCXX20_CONSTEXPR
void
__make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
_Compare& __comp)
{
typedef typename iterator_traits<_RandomAccessIterator>::value_type
_ValueType;
typedef typename iterator_traits<_RandomAccessIterator>::difference_type
_DistanceType;
if (__last - __first < 2)
return;
const _DistanceType __len = __last - __first;
_DistanceType __parent = (__len - 2) / 2;
while (true)
{
_ValueType __value = _GLIBCXX_MOVE(*(__first + __parent));
std::__adjust_heap(__first, __parent, __len, _GLIBCXX_MOVE(__value),
__comp);
if (__parent == 0)
return;
__parent--;
}
}
/**
* @brief Construct a heap over a range.
* @param __first Start of heap.
* @param __last End of heap.
* @ingroup heap_algorithms
*
* This operation makes the elements in [__first,__last) into a heap.
*/
template<typename _RandomAccessIterator>
_GLIBCXX20_CONSTEXPR
inline void
make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
{
// concept requirements
__glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
_RandomAccessIterator>)
__glibcxx_function_requires(_LessThanComparableConcept<
typename iterator_traits<_RandomAccessIterator>::value_type>)
__glibcxx_requires_valid_range(__first, __last);
__glibcxx_requires_irreflexive(__first, __last);
__gnu_cxx::__ops::_Iter_less_iter __comp;
std::__make_heap(__first, __last, __comp);
}
/**
* @brief Construct a heap over a range using comparison functor.
* @param __first Start of heap.
* @param __last End of heap.
* @param __comp Comparison functor to use.
* @ingroup heap_algorithms
*
* This operation makes the elements in [__first,__last) into a heap.
* Comparisons are made using __comp.
*/
template<typename _RandomAccessIterator, typename _Compare>
_GLIBCXX20_CONSTEXPR
inline void
make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
_Compare __comp)
{
// concept requirements
__glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
_RandomAccessIterator>)
__glibcxx_requires_valid_range(__first, __last);
__glibcxx_requires_irreflexive_pred(__first, __last, __comp);
typedef __decltype(__comp) _Cmp;
__gnu_cxx::__ops::_Iter_comp_iter<_Cmp> __cmp(_GLIBCXX_MOVE(__comp));
std::__make_heap(__first, __last, __cmp);
}
template<typename _RandomAccessIterator, typename _Compare>
_GLIBCXX20_CONSTEXPR
void
__sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
_Compare& __comp)
{
while (__last - __first > 1)
{
--__last;
std::__pop_heap(__first, __last, __last, __comp);
}
}
/**
* @brief Sort a heap.
* @param __first Start of heap.
* @param __last End of heap.
* @ingroup heap_algorithms
*
* This operation sorts the valid heap in the range [__first,__last).
*/
template<typename _RandomAccessIterator>
_GLIBCXX20_CONSTEXPR
inline void
sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
{
// concept requirements
__glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
_RandomAccessIterator>)
__glibcxx_function_requires(_LessThanComparableConcept<
typename iterator_traits<_RandomAccessIterator>::value_type>)
__glibcxx_requires_valid_range(__first, __last);
__glibcxx_requires_irreflexive(__first, __last);
__glibcxx_requires_heap(__first, __last);
__gnu_cxx::__ops::_Iter_less_iter __comp;
std::__sort_heap(__first, __last, __comp);
}
/**
* @brief Sort a heap using comparison functor.
* @param __first Start of heap.
* @param __last End of heap.
* @param __comp Comparison functor to use.
* @ingroup heap_algorithms
*
* This operation sorts the valid heap in the range [__first,__last).
* Comparisons are made using __comp.
*/
template<typename _RandomAccessIterator, typename _Compare>
_GLIBCXX20_CONSTEXPR
inline void
sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
_Compare __comp)
{
// concept requirements
__glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
_RandomAccessIterator>)
__glibcxx_requires_valid_range(__first, __last);
__glibcxx_requires_irreflexive_pred(__first, __last, __comp);
__glibcxx_requires_heap_pred(__first, __last, __comp);
typedef __decltype(__comp) _Cmp;
__gnu_cxx::__ops::_Iter_comp_iter<_Cmp> __cmp(_GLIBCXX_MOVE(__comp));
std::__sort_heap(__first, __last, __cmp);
}
#if __cplusplus >= 201103L
/**
* @brief Search the end of a heap.
* @param __first Start of range.
* @param __last End of range.
* @return An iterator pointing to the first element not in the heap.
* @ingroup heap_algorithms
*
* This operation returns the last iterator i in [__first, __last) for which
* the range [__first, i) is a heap.
*/
template<typename _RandomAccessIterator>
_GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
inline _RandomAccessIterator
is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last)
{
// concept requirements
__glibcxx_function_requires(_RandomAccessIteratorConcept<
_RandomAccessIterator>)
__glibcxx_function_requires(_LessThanComparableConcept<
typename iterator_traits<_RandomAccessIterator>::value_type>)
__glibcxx_requires_valid_range(__first, __last);
__glibcxx_requires_irreflexive(__first, __last);
__gnu_cxx::__ops::_Iter_less_iter __comp;
return __first +
std::__is_heap_until(__first, std::distance(__first, __last), __comp);
}
/**
* @brief Search the end of a heap using comparison functor.
* @param __first Start of range.
* @param __last End of range.
* @param __comp Comparison functor to use.
* @return An iterator pointing to the first element not in the heap.
* @ingroup heap_algorithms
*
* This operation returns the last iterator i in [__first, __last) for which
* the range [__first, i) is a heap. Comparisons are made using __comp.
*/
template<typename _RandomAccessIterator, typename _Compare>
_GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
inline _RandomAccessIterator
is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last,
_Compare __comp)
{
// concept requirements
__glibcxx_function_requires(_RandomAccessIteratorConcept<
_RandomAccessIterator>)
__glibcxx_requires_valid_range(__first, __last);
__glibcxx_requires_irreflexive_pred(__first, __last, __comp);
typedef __decltype(__comp) _Cmp;
__gnu_cxx::__ops::_Iter_comp_iter<_Cmp> __cmp(_GLIBCXX_MOVE(__comp));
return __first
+ std::__is_heap_until(__first, std::distance(__first, __last), __cmp);
}
/**
* @brief Determines whether a range is a heap.
* @param __first Start of range.
* @param __last End of range.
* @return True if range is a heap, false otherwise.
* @ingroup heap_algorithms
*/
template<typename _RandomAccessIterator>
_GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
inline bool
is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
{ return std::is_heap_until(__first, __last) == __last; }
/**
* @brief Determines whether a range is a heap using comparison functor.
* @param __first Start of range.
* @param __last End of range.
* @param __comp Comparison functor to use.
* @return True if range is a heap, false otherwise.
* @ingroup heap_algorithms
*/
template<typename _RandomAccessIterator, typename _Compare>
_GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
inline bool
is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
_Compare __comp)
{
// concept requirements
__glibcxx_function_requires(_RandomAccessIteratorConcept<
_RandomAccessIterator>)
__glibcxx_requires_valid_range(__first, __last);
__glibcxx_requires_irreflexive_pred(__first, __last, __comp);
const auto __dist = std::distance(__first, __last);
typedef __decltype(__comp) _Cmp;
__gnu_cxx::__ops::_Iter_comp_iter<_Cmp> __cmp(_GLIBCXX_MOVE(__comp));
return std::__is_heap_until(__first, __dist, __cmp) == __dist;
}
#endif
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif /* _STL_HEAP_H */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,259 @@
// Functions used by iterators -*- C++ -*-
// Copyright (C) 2001-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/*
*
* Copyright (c) 1994
* Hewlett-Packard Company
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Hewlett-Packard Company makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*
*
* Copyright (c) 1996-1998
* Silicon Graphics Computer Systems, Inc.
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Silicon Graphics makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*/
/** @file bits/stl_iterator_base_funcs.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{iterator}
*
* This file contains all of the general iterator-related utility
* functions, such as distance() and advance().
*/
#ifndef _STL_ITERATOR_BASE_FUNCS_H
#define _STL_ITERATOR_BASE_FUNCS_H 1
#pragma GCC system_header
#include <bits/concept_check.h>
#include <debug/assertions.h>
#include <bits/stl_iterator_base_types.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
_GLIBCXX_BEGIN_NAMESPACE_CONTAINER
// Forward declaration for the overloads of __distance.
template <typename> struct _List_iterator;
template <typename> struct _List_const_iterator;
_GLIBCXX_END_NAMESPACE_CONTAINER
template<typename _InputIterator>
inline _GLIBCXX14_CONSTEXPR
typename iterator_traits<_InputIterator>::difference_type
__distance(_InputIterator __first, _InputIterator __last,
input_iterator_tag)
{
// concept requirements
__glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
typename iterator_traits<_InputIterator>::difference_type __n = 0;
while (__first != __last)
{
++__first;
++__n;
}
return __n;
}
template<typename _RandomAccessIterator>
__attribute__((__always_inline__))
inline _GLIBCXX14_CONSTEXPR
typename iterator_traits<_RandomAccessIterator>::difference_type
__distance(_RandomAccessIterator __first, _RandomAccessIterator __last,
random_access_iterator_tag)
{
// concept requirements
__glibcxx_function_requires(_RandomAccessIteratorConcept<
_RandomAccessIterator>)
return __last - __first;
}
#if _GLIBCXX_USE_CXX11_ABI
// Forward declaration because of the qualified call in distance.
template<typename _Tp>
ptrdiff_t
__distance(_GLIBCXX_STD_C::_List_iterator<_Tp>,
_GLIBCXX_STD_C::_List_iterator<_Tp>,
input_iterator_tag);
template<typename _Tp>
ptrdiff_t
__distance(_GLIBCXX_STD_C::_List_const_iterator<_Tp>,
_GLIBCXX_STD_C::_List_const_iterator<_Tp>,
input_iterator_tag);
#endif
#if __cplusplus >= 201103L
// Give better error if std::distance called with a non-Cpp17InputIterator.
template<typename _OutputIterator>
void
__distance(_OutputIterator, _OutputIterator, output_iterator_tag) = delete;
#endif
/**
* @brief A generalization of pointer arithmetic.
* @param __first An input iterator.
* @param __last An input iterator.
* @return The distance between them.
*
* Returns @c n such that __first + n == __last. This requires
* that @p __last must be reachable from @p __first. Note that @c
* n may be negative.
*
* For random access iterators, this uses their @c + and @c - operations
* and are constant time. For other %iterator classes they are linear time.
*/
template<typename _InputIterator>
_GLIBCXX_NODISCARD __attribute__((__always_inline__))
inline _GLIBCXX17_CONSTEXPR
typename iterator_traits<_InputIterator>::difference_type
distance(_InputIterator __first, _InputIterator __last)
{
// concept requirements -- taken care of in __distance
return std::__distance(__first, __last,
std::__iterator_category(__first));
}
template<typename _InputIterator, typename _Distance>
inline _GLIBCXX14_CONSTEXPR void
__advance(_InputIterator& __i, _Distance __n, input_iterator_tag)
{
// concept requirements
__glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
__glibcxx_assert(__n >= 0);
while (__n--)
++__i;
}
template<typename _BidirectionalIterator, typename _Distance>
inline _GLIBCXX14_CONSTEXPR void
__advance(_BidirectionalIterator& __i, _Distance __n,
bidirectional_iterator_tag)
{
// concept requirements
__glibcxx_function_requires(_BidirectionalIteratorConcept<
_BidirectionalIterator>)
if (__n > 0)
while (__n--)
++__i;
else
while (__n++)
--__i;
}
template<typename _RandomAccessIterator, typename _Distance>
inline _GLIBCXX14_CONSTEXPR void
__advance(_RandomAccessIterator& __i, _Distance __n,
random_access_iterator_tag)
{
// concept requirements
__glibcxx_function_requires(_RandomAccessIteratorConcept<
_RandomAccessIterator>)
if (__builtin_constant_p(__n) && __n == 1)
++__i;
else if (__builtin_constant_p(__n) && __n == -1)
--__i;
else
__i += __n;
}
#if __cplusplus >= 201103L
// Give better error if std::advance called with a non-Cpp17InputIterator.
template<typename _OutputIterator, typename _Distance>
void
__advance(_OutputIterator&, _Distance, output_iterator_tag) = delete;
#endif
/**
* @brief A generalization of pointer arithmetic.
* @param __i An input iterator.
* @param __n The @a delta by which to change @p __i.
* @return Nothing.
*
* This increments @p i by @p n. For bidirectional and random access
* iterators, @p __n may be negative, in which case @p __i is decremented.
*
* For random access iterators, this uses their @c + and @c - operations
* and are constant time. For other %iterator classes they are linear time.
*/
template<typename _InputIterator, typename _Distance>
__attribute__((__always_inline__))
inline _GLIBCXX17_CONSTEXPR void
advance(_InputIterator& __i, _Distance __n)
{
// concept requirements -- taken care of in __advance
typename iterator_traits<_InputIterator>::difference_type __d = __n;
std::__advance(__i, __d, std::__iterator_category(__i));
}
#if __cplusplus >= 201103L
template<typename _InputIterator>
_GLIBCXX_NODISCARD [[__gnu__::__always_inline__]]
inline _GLIBCXX17_CONSTEXPR _InputIterator
next(_InputIterator __x, typename
iterator_traits<_InputIterator>::difference_type __n = 1)
{
// concept requirements
__glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
std::advance(__x, __n);
return __x;
}
template<typename _BidirectionalIterator>
_GLIBCXX_NODISCARD [[__gnu__::__always_inline__]]
inline _GLIBCXX17_CONSTEXPR _BidirectionalIterator
prev(_BidirectionalIterator __x, typename
iterator_traits<_BidirectionalIterator>::difference_type __n = 1)
{
// concept requirements
__glibcxx_function_requires(_BidirectionalIteratorConcept<
_BidirectionalIterator>)
std::advance(__x, -__n);
return __x;
}
#endif // C++11
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif /* _STL_ITERATOR_BASE_FUNCS_H */
@@ -0,0 +1,272 @@
// Types used in iterator implementation -*- C++ -*-
// Copyright (C) 2001-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/*
*
* Copyright (c) 1994
* Hewlett-Packard Company
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Hewlett-Packard Company makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*
*
* Copyright (c) 1996-1998
* Silicon Graphics Computer Systems, Inc.
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Silicon Graphics makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*/
/** @file bits/stl_iterator_base_types.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{iterator}
*
* This file contains all of the general iterator-related utility types,
* such as iterator_traits and struct iterator.
*/
#ifndef _STL_ITERATOR_BASE_TYPES_H
#define _STL_ITERATOR_BASE_TYPES_H 1
#pragma GCC system_header
#include <bits/c++config.h>
#if __cplusplus >= 201103L
# include <type_traits> // For __void_t, is_convertible
#endif
#if __cplusplus > 201703L && __cpp_concepts >= 201907L
# include <bits/iterator_concepts.h>
#endif
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
* @defgroup iterators Iterators
* Abstractions for uniform iterating through various underlying types.
*/
///@{
/**
* @defgroup iterator_tags Iterator Tags
* These are empty types, used to distinguish different iterators. The
* distinction is not made by what they contain, but simply by what they
* are. Different underlying algorithms can then be used based on the
* different operations supported by different iterator types.
*/
///@{
/// Marking input iterators.
struct input_iterator_tag { };
/// Marking output iterators.
struct output_iterator_tag { };
/// Forward iterators support a superset of input iterator operations.
struct forward_iterator_tag : public input_iterator_tag { };
/// Bidirectional iterators support a superset of forward iterator
/// operations.
struct bidirectional_iterator_tag : public forward_iterator_tag { };
/// Random-access iterators support a superset of bidirectional
/// iterator operations.
struct random_access_iterator_tag : public bidirectional_iterator_tag { };
#if __cplusplus > 201703L
/// Contiguous iterators point to objects stored contiguously in memory.
struct contiguous_iterator_tag : public random_access_iterator_tag { };
#endif
///@}
/**
* @brief Common %iterator class.
*
* This class does nothing but define nested typedefs. %Iterator classes
* can inherit from this class to save some work. The typedefs are then
* used in specializations and overloading.
*
* In particular, there are no default implementations of requirements
* such as @c operator++ and the like. (How could there be?)
*/
template<typename _Category, typename _Tp, typename _Distance = ptrdiff_t,
typename _Pointer = _Tp*, typename _Reference = _Tp&>
struct _GLIBCXX17_DEPRECATED iterator
{
/// One of the @link iterator_tags tag types@endlink.
typedef _Category iterator_category;
/// The type "pointed to" by the iterator.
typedef _Tp value_type;
/// Distance between iterators is represented as this type.
typedef _Distance difference_type;
/// This type represents a pointer-to-value_type.
typedef _Pointer pointer;
/// This type represents a reference-to-value_type.
typedef _Reference reference;
};
/**
* @brief Traits class for iterators.
*
* This class does nothing but define nested typedefs. The general
* version simply @a forwards the nested typedefs from the Iterator
* argument. Specialized versions for pointers and pointers-to-const
* provide tighter, more correct semantics.
*/
template<typename _Iterator>
struct iterator_traits;
#if __cplusplus >= 201103L
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 2408. SFINAE-friendly common_type/iterator_traits is missing in C++14
template<typename _Iterator, typename = __void_t<>>
struct __iterator_traits { };
#if ! __cpp_lib_concepts
template<typename _Iterator>
struct __iterator_traits<_Iterator,
__void_t<typename _Iterator::iterator_category,
typename _Iterator::value_type,
typename _Iterator::difference_type,
typename _Iterator::pointer,
typename _Iterator::reference>>
{
typedef typename _Iterator::iterator_category iterator_category;
typedef typename _Iterator::value_type value_type;
typedef typename _Iterator::difference_type difference_type;
typedef typename _Iterator::pointer pointer;
typedef typename _Iterator::reference reference;
};
#endif // ! concepts
template<typename _Iterator>
struct iterator_traits
: public __iterator_traits<_Iterator> { };
#else // ! C++11
template<typename _Iterator>
struct iterator_traits
{
typedef typename _Iterator::iterator_category iterator_category;
typedef typename _Iterator::value_type value_type;
typedef typename _Iterator::difference_type difference_type;
typedef typename _Iterator::pointer pointer;
typedef typename _Iterator::reference reference;
};
#endif // C++11
#if __cplusplus > 201703L
/// Partial specialization for object pointer types.
template<typename _Tp>
#if __cpp_concepts >= 201907L
requires is_object_v<_Tp>
#endif
struct iterator_traits<_Tp*>
{
using iterator_concept = contiguous_iterator_tag;
using iterator_category = random_access_iterator_tag;
using value_type = remove_cv_t<_Tp>;
using difference_type = ptrdiff_t;
using pointer = _Tp*;
using reference = _Tp&;
};
#else
/// Partial specialization for pointer types.
template<typename _Tp>
struct iterator_traits<_Tp*>
{
typedef random_access_iterator_tag iterator_category;
typedef _Tp value_type;
typedef ptrdiff_t difference_type;
typedef _Tp* pointer;
typedef _Tp& reference;
};
/// Partial specialization for const pointer types.
template<typename _Tp>
struct iterator_traits<const _Tp*>
{
typedef random_access_iterator_tag iterator_category;
typedef _Tp value_type;
typedef ptrdiff_t difference_type;
typedef const _Tp* pointer;
typedef const _Tp& reference;
};
#endif
/**
* This function is not a part of the C++ standard but is syntactic
* sugar for internal library use only.
*/
template<typename _Iter>
__attribute__((__always_inline__))
inline _GLIBCXX_CONSTEXPR
typename iterator_traits<_Iter>::iterator_category
__iterator_category(const _Iter&)
{ return typename iterator_traits<_Iter>::iterator_category(); }
///@}
#if __cplusplus >= 201103L
template<typename _Iter>
using __iter_category_t
= typename iterator_traits<_Iter>::iterator_category;
template<typename _InIter>
using _RequireInputIter =
__enable_if_t<is_convertible<__iter_category_t<_InIter>,
input_iterator_tag>::value>;
template<typename _It,
typename _Cat = __iter_category_t<_It>>
struct __is_random_access_iter
: is_base_of<random_access_iterator_tag, _Cat>
{
typedef is_base_of<random_access_iterator_tag, _Cat> _Base;
enum { __value = _Base::value };
};
#else
template<typename _It, typename _Traits = iterator_traits<_It>,
typename _Cat = typename _Traits::iterator_category>
struct __is_random_access_iter
{ enum { __value = __is_base_of(random_access_iterator_tag, _Cat) }; };
#endif
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif /* _STL_ITERATOR_BASE_TYPES_H */
+411
View File
@@ -0,0 +1,411 @@
// Numeric functions implementation -*- C++ -*-
// Copyright (C) 2001-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/*
*
* Copyright (c) 1994
* Hewlett-Packard Company
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Hewlett-Packard Company makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*
*
* Copyright (c) 1996,1997
* Silicon Graphics Computer Systems, Inc.
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Silicon Graphics makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*/
/** @file bits/stl_numeric.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{numeric}
*/
#ifndef _STL_NUMERIC_H
#define _STL_NUMERIC_H 1
#include <bits/concept_check.h>
#include <debug/debug.h>
#include <bits/move.h> // For _GLIBCXX_MOVE
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/** @defgroup numeric_ops Generalized Numeric operations
* @ingroup algorithms
*/
#if __cplusplus >= 201103L
/**
* @brief Create a range of sequentially increasing values.
*
* For each element in the range @p [first,last) assigns @p value and
* increments @p value as if by @p ++value.
*
* @param __first Start of range.
* @param __last End of range.
* @param __value Starting value.
* @return Nothing.
* @ingroup numeric_ops
*/
template<typename _ForwardIterator, typename _Tp>
_GLIBCXX20_CONSTEXPR
void
iota(_ForwardIterator __first, _ForwardIterator __last, _Tp __value)
{
// concept requirements
__glibcxx_function_requires(_Mutable_ForwardIteratorConcept<
_ForwardIterator>)
__glibcxx_function_requires(_ConvertibleConcept<_Tp,
typename iterator_traits<_ForwardIterator>::value_type>)
__glibcxx_requires_valid_range(__first, __last);
for (; __first != __last; ++__first)
{
*__first = __value;
++__value;
}
}
#endif
_GLIBCXX_END_NAMESPACE_VERSION
_GLIBCXX_BEGIN_NAMESPACE_ALGO
#if __cplusplus > 201703L
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 2055. std::move in std::accumulate and other algorithms
# define _GLIBCXX_MOVE_IF_20(_E) std::move(_E)
#else
# define _GLIBCXX_MOVE_IF_20(_E) _E
#endif
/// @addtogroup numeric_ops
/// @{
/**
* @brief Accumulate values in a range.
*
* Accumulates the values in the range [first,last) using operator+(). The
* initial value is @a init. The values are processed in order.
*
* @param __first Start of range.
* @param __last End of range.
* @param __init Starting value to add other values to.
* @return The final sum.
*/
template<typename _InputIterator, typename _Tp>
_GLIBCXX20_CONSTEXPR
inline _Tp
accumulate(_InputIterator __first, _InputIterator __last, _Tp __init)
{
// concept requirements
__glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
__glibcxx_requires_valid_range(__first, __last);
for (; __first != __last; ++__first)
__init = _GLIBCXX_MOVE_IF_20(__init) + *__first;
return __init;
}
/**
* @brief Accumulate values in a range with operation.
*
* Accumulates the values in the range `[first,last)` using the function
* object `__binary_op`. The initial value is `__init`. The values are
* processed in order.
*
* @param __first Start of range.
* @param __last End of range.
* @param __init Starting value to add other values to.
* @param __binary_op Function object to accumulate with.
* @return The final sum.
*/
template<typename _InputIterator, typename _Tp, typename _BinaryOperation>
_GLIBCXX20_CONSTEXPR
inline _Tp
accumulate(_InputIterator __first, _InputIterator __last, _Tp __init,
_BinaryOperation __binary_op)
{
// concept requirements
__glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
__glibcxx_requires_valid_range(__first, __last);
for (; __first != __last; ++__first)
__init = __binary_op(_GLIBCXX_MOVE_IF_20(__init), *__first);
return __init;
}
/**
* @brief Compute inner product of two ranges.
*
* Starting with an initial value of @p __init, multiplies successive
* elements from the two ranges and adds each product into the accumulated
* value using operator+(). The values in the ranges are processed in
* order.
*
* @param __first1 Start of range 1.
* @param __last1 End of range 1.
* @param __first2 Start of range 2.
* @param __init Starting value to add other values to.
* @return The final inner product.
*/
template<typename _InputIterator1, typename _InputIterator2, typename _Tp>
_GLIBCXX20_CONSTEXPR
inline _Tp
inner_product(_InputIterator1 __first1, _InputIterator1 __last1,
_InputIterator2 __first2, _Tp __init)
{
// concept requirements
__glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
__glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
__glibcxx_requires_valid_range(__first1, __last1);
for (; __first1 != __last1; ++__first1, (void)++__first2)
__init = _GLIBCXX_MOVE_IF_20(__init) + (*__first1 * *__first2);
return __init;
}
/**
* @brief Compute inner product of two ranges.
*
* Starting with an initial value of @p __init, applies @p __binary_op2 to
* successive elements from the two ranges and accumulates each result into
* the accumulated value using @p __binary_op1. The values in the ranges are
* processed in order.
*
* @param __first1 Start of range 1.
* @param __last1 End of range 1.
* @param __first2 Start of range 2.
* @param __init Starting value to add other values to.
* @param __binary_op1 Function object to accumulate with.
* @param __binary_op2 Function object to apply to pairs of input values.
* @return The final inner product.
*/
template<typename _InputIterator1, typename _InputIterator2, typename _Tp,
typename _BinaryOperation1, typename _BinaryOperation2>
_GLIBCXX20_CONSTEXPR
inline _Tp
inner_product(_InputIterator1 __first1, _InputIterator1 __last1,
_InputIterator2 __first2, _Tp __init,
_BinaryOperation1 __binary_op1,
_BinaryOperation2 __binary_op2)
{
// concept requirements
__glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
__glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
__glibcxx_requires_valid_range(__first1, __last1);
for (; __first1 != __last1; ++__first1, (void)++__first2)
__init = __binary_op1(_GLIBCXX_MOVE_IF_20(__init),
__binary_op2(*__first1, *__first2));
return __init;
}
/**
* @brief Return list of partial sums
*
* Accumulates the values in the range [first,last) using the @c + operator.
* As each successive input value is added into the total, that partial sum
* is written to @p __result. Therefore, the first value in @p __result is
* the first value of the input, the second value in @p __result is the sum
* of the first and second input values, and so on.
*
* @param __first Start of input range.
* @param __last End of input range.
* @param __result Output sum.
* @return Iterator pointing just beyond the values written to __result.
*/
template<typename _InputIterator, typename _OutputIterator>
_GLIBCXX20_CONSTEXPR
_OutputIterator
partial_sum(_InputIterator __first, _InputIterator __last,
_OutputIterator __result)
{
typedef typename iterator_traits<_InputIterator>::value_type _ValueType;
// concept requirements
__glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
__glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
_ValueType>)
__glibcxx_requires_valid_range(__first, __last);
if (__first == __last)
return __result;
_ValueType __value = *__first;
*__result = __value;
while (++__first != __last)
{
__value = _GLIBCXX_MOVE_IF_20(__value) + *__first;
*++__result = __value;
}
return ++__result;
}
/**
* @brief Return list of partial sums
*
* Accumulates the values in the range [first,last) using @p __binary_op.
* As each successive input value is added into the total, that partial sum
* is written to @p __result. Therefore, the first value in @p __result is
* the first value of the input, the second value in @p __result is the sum
* of the first and second input values, and so on.
*
* @param __first Start of input range.
* @param __last End of input range.
* @param __result Output sum.
* @param __binary_op Function object.
* @return Iterator pointing just beyond the values written to __result.
*/
template<typename _InputIterator, typename _OutputIterator,
typename _BinaryOperation>
_GLIBCXX20_CONSTEXPR
_OutputIterator
partial_sum(_InputIterator __first, _InputIterator __last,
_OutputIterator __result, _BinaryOperation __binary_op)
{
typedef typename iterator_traits<_InputIterator>::value_type _ValueType;
// concept requirements
__glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
__glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
_ValueType>)
__glibcxx_requires_valid_range(__first, __last);
if (__first == __last)
return __result;
_ValueType __value = *__first;
*__result = __value;
while (++__first != __last)
{
__value = __binary_op(_GLIBCXX_MOVE_IF_20(__value), *__first);
*++__result = __value;
}
return ++__result;
}
/**
* @brief Return differences between adjacent values.
*
* Computes the difference between adjacent values in the range
* [first,last) using operator-() and writes the result to @p __result.
*
* @param __first Start of input range.
* @param __last End of input range.
* @param __result Output sums.
* @return Iterator pointing just beyond the values written to result.
*/
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 539. partial_sum and adjacent_difference should mention requirements
template<typename _InputIterator, typename _OutputIterator>
_GLIBCXX20_CONSTEXPR
_OutputIterator
adjacent_difference(_InputIterator __first,
_InputIterator __last, _OutputIterator __result)
{
typedef typename iterator_traits<_InputIterator>::value_type _ValueType;
// concept requirements
__glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
__glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
_ValueType>)
__glibcxx_requires_valid_range(__first, __last);
if (__first == __last)
return __result;
_ValueType __value = *__first;
*__result = __value;
while (++__first != __last)
{
_ValueType __tmp = *__first;
*++__result = __tmp - _GLIBCXX_MOVE_IF_20(__value);
__value = _GLIBCXX_MOVE(__tmp);
}
return ++__result;
}
/**
* @brief Return differences between adjacent values.
*
* Computes the difference between adjacent values in the range
* [__first,__last) using the function object @p __binary_op and writes the
* result to @p __result.
*
* @param __first Start of input range.
* @param __last End of input range.
* @param __result Output sum.
* @param __binary_op Function object.
* @return Iterator pointing just beyond the values written to result.
*/
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 539. partial_sum and adjacent_difference should mention requirements
template<typename _InputIterator, typename _OutputIterator,
typename _BinaryOperation>
_GLIBCXX20_CONSTEXPR
_OutputIterator
adjacent_difference(_InputIterator __first, _InputIterator __last,
_OutputIterator __result, _BinaryOperation __binary_op)
{
typedef typename iterator_traits<_InputIterator>::value_type _ValueType;
// concept requirements
__glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
__glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
_ValueType>)
__glibcxx_requires_valid_range(__first, __last);
if (__first == __last)
return __result;
_ValueType __value = *__first;
*__result = __value;
while (++__first != __last)
{
_ValueType __tmp = *__first;
*++__result = __binary_op(__tmp, _GLIBCXX_MOVE_IF_20(__value));
__value = _GLIBCXX_MOVE(__tmp);
}
return ++__result;
}
/// @} group numeric_ops
#undef _GLIBCXX_MOVE_IF_20
_GLIBCXX_END_NAMESPACE_ALGO
} // namespace std
#endif /* _STL_NUMERIC_H */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,128 @@
// -*- C++ -*-
// Copyright (C) 2001-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/*
*
* Copyright (c) 1994
* Hewlett-Packard Company
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Hewlett-Packard Company makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*
*
* Copyright (c) 1996
* Silicon Graphics Computer Systems, Inc.
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Silicon Graphics makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*/
/** @file bits/stl_raw_storage_iter.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{memory}
*/
#ifndef _STL_RAW_STORAGE_ITERATOR_H
#define _STL_RAW_STORAGE_ITERATOR_H 1
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
// Ignore warnings about std::iterator.
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
/**
* This iterator class lets algorithms store their results into
* uninitialized memory.
*/
template <class _OutputIterator, class _Tp>
class _GLIBCXX17_DEPRECATED raw_storage_iterator
: public iterator<output_iterator_tag, void, void, void, void>
{
protected:
_OutputIterator _M_iter;
public:
explicit
raw_storage_iterator(_OutputIterator __x)
: _M_iter(__x) {}
raw_storage_iterator&
operator*() { return *this; }
raw_storage_iterator&
operator=(const _Tp& __element)
{
std::_Construct(std::__addressof(*_M_iter), __element);
return *this;
}
#if __cplusplus >= 201103L
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 2127. Move-construction with raw_storage_iterator
raw_storage_iterator&
operator=(_Tp&& __element)
{
std::_Construct(std::__addressof(*_M_iter), std::move(__element));
return *this;
}
#endif
raw_storage_iterator&
operator++()
{
++_M_iter;
return *this;
}
raw_storage_iterator
operator++(int)
{
raw_storage_iterator __tmp = *this;
++_M_iter;
return __tmp;
}
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 2454. Add raw_storage_iterator::base() member
_OutputIterator base() const { return _M_iter; }
};
#pragma GCC diagnostic pop
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif
+134
View File
@@ -0,0 +1,134 @@
// std::rel_ops implementation -*- C++ -*-
// Copyright (C) 2001-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the, 2009 Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/*
*
* Copyright (c) 1994
* Hewlett-Packard Company
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Hewlett-Packard Company makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*
* Copyright (c) 1996,1997
* Silicon Graphics
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Silicon Graphics makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*
*/
/** @file bits/stl_relops.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{utility}
*
* This file is only included by `<utility>`, which is required by the
* standard to define namespace `rel_ops` and its contents.
*/
#ifndef _STL_RELOPS_H
#define _STL_RELOPS_H 1
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
namespace rel_ops
{
/** @namespace std::rel_ops
* @brief The generated relational operators are sequestered here.
*
* Libstdc++ headers must not use the contents of `rel_ops`.
* User code should also avoid them, because unconstrained function
* templates are too greedy and can easily cause ambiguities.
*
* C++20 default comparisons are a better solution.
*/
/**
* @brief Defines @c != for arbitrary types, in terms of @c ==.
* @param __x A thing.
* @param __y Another thing.
* @return __x != __y
*
* This function uses @c == to determine its result.
*/
template <class _Tp>
inline bool
operator!=(const _Tp& __x, const _Tp& __y)
{ return !(__x == __y); }
/**
* @brief Defines @c > for arbitrary types, in terms of @c <.
* @param __x A thing.
* @param __y Another thing.
* @return __x > __y
*
* This function uses @c < to determine its result.
*/
template <class _Tp>
inline bool
operator>(const _Tp& __x, const _Tp& __y)
{ return __y < __x; }
/**
* @brief Defines @c <= for arbitrary types, in terms of @c <.
* @param __x A thing.
* @param __y Another thing.
* @return __x <= __y
*
* This function uses @c < to determine its result.
*/
template <class _Tp>
inline bool
operator<=(const _Tp& __x, const _Tp& __y)
{ return !(__y < __x); }
/**
* @brief Defines @c >= for arbitrary types, in terms of @c <.
* @param __x A thing.
* @param __y Another thing.
* @return __x >= __y
*
* This function uses @c < to determine its result.
*/
template <class _Tp>
inline bool
operator>=(const _Tp& __x, const _Tp& __y)
{ return !(__x < __y); }
} // namespace rel_ops
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif /* _STL_RELOPS_H */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,241 @@
// Components for manipulating non-owning sequences of characters -*- C++ -*-
// Copyright (C) 2013-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file include/bits/string_view.tcc
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{string_view}
*/
//
// N3762 basic_string_view library
//
#ifndef _GLIBCXX_STRING_VIEW_TCC
#define _GLIBCXX_STRING_VIEW_TCC 1
#pragma GCC system_header
#if __cplusplus >= 201703L
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _CharT, typename _Traits>
constexpr typename basic_string_view<_CharT, _Traits>::size_type
basic_string_view<_CharT, _Traits>::
find(const _CharT* __str, size_type __pos, size_type __n) const noexcept
{
__glibcxx_requires_string_len(__str, __n);
if (__n == 0)
return __pos <= _M_len ? __pos : npos;
if (__pos >= _M_len)
return npos;
const _CharT __elem0 = __str[0];
const _CharT* __first = _M_str + __pos;
const _CharT* const __last = _M_str + _M_len;
size_type __len = _M_len - __pos;
while (__len >= __n)
{
// Find the first occurrence of __elem0:
__first = traits_type::find(__first, __len - __n + 1, __elem0);
if (!__first)
return npos;
// Compare the full strings from the first occurrence of __elem0.
// We already know that __first[0] == __s[0] but compare them again
// anyway because __s is probably aligned, which helps memcmp.
if (traits_type::compare(__first, __str, __n) == 0)
return __first - _M_str;
__len = __last - ++__first;
}
return npos;
}
template<typename _CharT, typename _Traits>
constexpr typename basic_string_view<_CharT, _Traits>::size_type
basic_string_view<_CharT, _Traits>::
find(_CharT __c, size_type __pos) const noexcept
{
size_type __ret = npos;
if (__pos < this->_M_len)
{
const size_type __n = this->_M_len - __pos;
const _CharT* __p = traits_type::find(this->_M_str + __pos, __n, __c);
if (__p)
__ret = __p - this->_M_str;
}
return __ret;
}
template<typename _CharT, typename _Traits>
constexpr typename basic_string_view<_CharT, _Traits>::size_type
basic_string_view<_CharT, _Traits>::
rfind(const _CharT* __str, size_type __pos, size_type __n) const noexcept
{
__glibcxx_requires_string_len(__str, __n);
if (__n <= this->_M_len)
{
__pos = std::min(size_type(this->_M_len - __n), __pos);
do
{
if (traits_type::compare(this->_M_str + __pos, __str, __n) == 0)
return __pos;
}
while (__pos-- > 0);
}
return npos;
}
template<typename _CharT, typename _Traits>
constexpr typename basic_string_view<_CharT, _Traits>::size_type
basic_string_view<_CharT, _Traits>::
rfind(_CharT __c, size_type __pos) const noexcept
{
size_type __size = this->_M_len;
if (__size > 0)
{
if (--__size > __pos)
__size = __pos;
for (++__size; __size-- > 0; )
if (traits_type::eq(this->_M_str[__size], __c))
return __size;
}
return npos;
}
template<typename _CharT, typename _Traits>
constexpr typename basic_string_view<_CharT, _Traits>::size_type
basic_string_view<_CharT, _Traits>::
find_first_of(const _CharT* __str, size_type __pos,
size_type __n) const noexcept
{
__glibcxx_requires_string_len(__str, __n);
for (; __n && __pos < this->_M_len; ++__pos)
{
const _CharT* __p = traits_type::find(__str, __n,
this->_M_str[__pos]);
if (__p)
return __pos;
}
return npos;
}
template<typename _CharT, typename _Traits>
constexpr typename basic_string_view<_CharT, _Traits>::size_type
basic_string_view<_CharT, _Traits>::
find_last_of(const _CharT* __str, size_type __pos,
size_type __n) const noexcept
{
__glibcxx_requires_string_len(__str, __n);
size_type __size = this->size();
if (__size && __n)
{
if (--__size > __pos)
__size = __pos;
do
{
if (traits_type::find(__str, __n, this->_M_str[__size]))
return __size;
}
while (__size-- != 0);
}
return npos;
}
template<typename _CharT, typename _Traits>
constexpr typename basic_string_view<_CharT, _Traits>::size_type
basic_string_view<_CharT, _Traits>::
find_first_not_of(const _CharT* __str, size_type __pos,
size_type __n) const noexcept
{
__glibcxx_requires_string_len(__str, __n);
for (; __pos < this->_M_len; ++__pos)
if (!traits_type::find(__str, __n, this->_M_str[__pos]))
return __pos;
return npos;
}
template<typename _CharT, typename _Traits>
constexpr typename basic_string_view<_CharT, _Traits>::size_type
basic_string_view<_CharT, _Traits>::
find_first_not_of(_CharT __c, size_type __pos) const noexcept
{
for (; __pos < this->_M_len; ++__pos)
if (!traits_type::eq(this->_M_str[__pos], __c))
return __pos;
return npos;
}
template<typename _CharT, typename _Traits>
constexpr typename basic_string_view<_CharT, _Traits>::size_type
basic_string_view<_CharT, _Traits>::
find_last_not_of(const _CharT* __str, size_type __pos,
size_type __n) const noexcept
{
__glibcxx_requires_string_len(__str, __n);
size_type __size = this->_M_len;
if (__size)
{
if (--__size > __pos)
__size = __pos;
do
{
if (!traits_type::find(__str, __n, this->_M_str[__size]))
return __size;
}
while (__size--);
}
return npos;
}
template<typename _CharT, typename _Traits>
constexpr typename basic_string_view<_CharT, _Traits>::size_type
basic_string_view<_CharT, _Traits>::
find_last_not_of(_CharT __c, size_type __pos) const noexcept
{
size_type __size = this->_M_len;
if (__size)
{
if (--__size > __pos)
__size = __pos;
do
{
if (!traits_type::eq(this->_M_str[__size], __c))
return __size;
}
while (__size--);
}
return npos;
}
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif // __cplusplus <= 201402L
#endif // _GLIBCXX_STRING_VIEW_TCC
@@ -0,0 +1,931 @@
// Generated by scripts/gen_text_encoding_data.py, do not edit.
// Copyright The GNU Toolchain Authors.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/text_encoding-data.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{text_encoding}
*/
#ifndef _GLIBCXX_GET_ENCODING_DATA
# error "This is not a public header, do not include it directly"
#endif
{ 3, "US-ASCII" },
{ 3, "iso-ir-6" },
{ 3, "ANSI_X3.4-1968" },
{ 3, "ANSI_X3.4-1986" },
{ 3, "ISO_646.irv:1991" },
{ 3, "ISO646-US" },
{ 3, "us" },
{ 3, "IBM367" },
{ 3, "cp367" },
{ 3, "csASCII" },
{ 3, "ASCII" }, // libstdc++ extension
{ 4, "ISO_8859-1:1987" },
{ 4, "iso-ir-100" },
{ 4, "ISO_8859-1" },
{ 4, "ISO-8859-1" },
{ 4, "latin1" },
{ 4, "l1" },
{ 4, "IBM819" },
{ 4, "CP819" },
{ 4, "csISOLatin1" },
{ 5, "ISO_8859-2:1987" },
{ 5, "iso-ir-101" },
{ 5, "ISO_8859-2" },
{ 5, "ISO-8859-2" },
{ 5, "latin2" },
{ 5, "l2" },
{ 5, "csISOLatin2" },
{ 6, "ISO_8859-3:1988" },
{ 6, "iso-ir-109" },
{ 6, "ISO_8859-3" },
{ 6, "ISO-8859-3" },
{ 6, "latin3" },
{ 6, "l3" },
{ 6, "csISOLatin3" },
{ 7, "ISO_8859-4:1988" },
{ 7, "iso-ir-110" },
{ 7, "ISO_8859-4" },
{ 7, "ISO-8859-4" },
{ 7, "latin4" },
{ 7, "l4" },
{ 7, "csISOLatin4" },
{ 8, "ISO_8859-5:1988" },
{ 8, "iso-ir-144" },
{ 8, "ISO_8859-5" },
{ 8, "ISO-8859-5" },
{ 8, "cyrillic" },
{ 8, "csISOLatinCyrillic" },
{ 9, "ISO_8859-6:1987" },
{ 9, "iso-ir-127" },
{ 9, "ISO_8859-6" },
{ 9, "ISO-8859-6" },
{ 9, "ECMA-114" },
{ 9, "ASMO-708" },
{ 9, "arabic" },
{ 9, "csISOLatinArabic" },
{ 10, "ISO_8859-7:1987" },
{ 10, "iso-ir-126" },
{ 10, "ISO_8859-7" },
{ 10, "ISO-8859-7" },
{ 10, "ELOT_928" },
{ 10, "ECMA-118" },
{ 10, "greek" },
{ 10, "greek8" },
{ 10, "csISOLatinGreek" },
{ 11, "ISO_8859-8:1988" },
{ 11, "iso-ir-138" },
{ 11, "ISO_8859-8" },
{ 11, "ISO-8859-8" },
{ 11, "hebrew" },
{ 11, "csISOLatinHebrew" },
{ 12, "ISO_8859-9:1989" },
{ 12, "iso-ir-148" },
{ 12, "ISO_8859-9" },
{ 12, "ISO-8859-9" },
{ 12, "latin5" },
{ 12, "l5" },
{ 12, "csISOLatin5" },
{ 13, "ISO-8859-10" },
{ 13, "iso-ir-157" },
{ 13, "l6" },
{ 13, "ISO_8859-10:1992" },
{ 13, "csISOLatin6" },
{ 13, "latin6" },
{ 14, "ISO_6937-2-add" },
{ 14, "iso-ir-142" },
{ 14, "csISOTextComm" },
{ 15, "JIS_X0201" },
{ 15, "X0201" },
{ 15, "csHalfWidthKatakana" },
{ 16, "JIS_Encoding" },
{ 16, "csJISEncoding" },
{ 17, "Shift_JIS" },
{ 17, "MS_Kanji" },
{ 17, "csShiftJIS" },
{ 18, "Extended_UNIX_Code_Packed_Format_for_Japanese" },
{ 18, "csEUCPkdFmtJapanese" },
{ 18, "EUC-JP" },
{ 19, "Extended_UNIX_Code_Fixed_Width_for_Japanese" },
{ 19, "csEUCFixWidJapanese" },
{ 20, "BS_4730" },
{ 20, "iso-ir-4" },
{ 20, "ISO646-GB" },
{ 20, "gb" },
{ 20, "uk" },
{ 20, "csISO4UnitedKingdom" },
{ 21, "SEN_850200_C" },
{ 21, "iso-ir-11" },
{ 21, "ISO646-SE2" },
{ 21, "se2" },
{ 21, "csISO11SwedishForNames" },
{ 22, "IT" },
{ 22, "iso-ir-15" },
{ 22, "ISO646-IT" },
{ 22, "csISO15Italian" },
{ 23, "ES" },
{ 23, "iso-ir-17" },
{ 23, "ISO646-ES" },
{ 23, "csISO17Spanish" },
{ 24, "DIN_66003" },
{ 24, "iso-ir-21" },
{ 24, "de" },
{ 24, "ISO646-DE" },
{ 24, "csISO21German" },
{ 25, "NS_4551-1" },
{ 25, "iso-ir-60" },
{ 25, "ISO646-NO" },
{ 25, "no" },
{ 25, "csISO60DanishNorwegian" },
{ 25, "csISO60Norwegian1" },
{ 26, "NF_Z_62-010" },
{ 26, "iso-ir-69" },
{ 26, "ISO646-FR" },
{ 26, "fr" },
{ 26, "csISO69French" },
{ 27, "ISO-10646-UTF-1" },
{ 27, "csISO10646UTF1" },
{ 28, "ISO_646.basic:1983" },
{ 28, "ref" },
{ 28, "csISO646basic1983" },
{ 29, "INVARIANT" },
{ 29, "csINVARIANT" },
{ 30, "ISO_646.irv:1983" },
{ 30, "iso-ir-2" },
{ 30, "irv" },
{ 30, "csISO2IntlRefVersion" },
{ 31, "NATS-SEFI" },
{ 31, "iso-ir-8-1" },
{ 31, "csNATSSEFI" },
{ 32, "NATS-SEFI-ADD" },
{ 32, "iso-ir-8-2" },
{ 32, "csNATSSEFIADD" },
{ 35, "SEN_850200_B" },
{ 35, "iso-ir-10" },
{ 35, "FI" },
{ 35, "ISO646-FI" },
{ 35, "ISO646-SE" },
{ 35, "se" },
{ 35, "csISO10Swedish" },
{ 36, "KS_C_5601-1987" },
{ 36, "iso-ir-149" },
{ 36, "KS_C_5601-1989" },
{ 36, "KSC_5601" },
{ 36, "korean" },
{ 36, "csKSC56011987" },
{ 37, "ISO-2022-KR" },
{ 37, "csISO2022KR" },
{ 38, "EUC-KR" },
{ 38, "csEUCKR" },
{ 39, "ISO-2022-JP" },
{ 39, "csISO2022JP" },
{ 40, "ISO-2022-JP-2" },
{ 40, "csISO2022JP2" },
{ 41, "JIS_C6220-1969-jp" },
{ 41, "JIS_C6220-1969" },
{ 41, "iso-ir-13" },
{ 41, "katakana" },
{ 41, "x0201-7" },
{ 41, "csISO13JISC6220jp" },
{ 42, "JIS_C6220-1969-ro" },
{ 42, "iso-ir-14" },
{ 42, "jp" },
{ 42, "ISO646-JP" },
{ 42, "csISO14JISC6220ro" },
{ 43, "PT" },
{ 43, "iso-ir-16" },
{ 43, "ISO646-PT" },
{ 43, "csISO16Portuguese" },
{ 44, "greek7-old" },
{ 44, "iso-ir-18" },
{ 44, "csISO18Greek7Old" },
{ 45, "latin-greek" },
{ 45, "iso-ir-19" },
{ 45, "csISO19LatinGreek" },
{ 46, "NF_Z_62-010_(1973)" },
{ 46, "iso-ir-25" },
{ 46, "ISO646-FR1" },
{ 46, "csISO25French" },
{ 47, "Latin-greek-1" },
{ 47, "iso-ir-27" },
{ 47, "csISO27LatinGreek1" },
{ 48, "ISO_5427" },
{ 48, "iso-ir-37" },
{ 48, "csISO5427Cyrillic" },
{ 49, "JIS_C6226-1978" },
{ 49, "iso-ir-42" },
{ 49, "csISO42JISC62261978" },
{ 50, "BS_viewdata" },
{ 50, "iso-ir-47" },
{ 50, "csISO47BSViewdata" },
{ 51, "INIS" },
{ 51, "iso-ir-49" },
{ 51, "csISO49INIS" },
{ 52, "INIS-8" },
{ 52, "iso-ir-50" },
{ 52, "csISO50INIS8" },
{ 53, "INIS-cyrillic" },
{ 53, "iso-ir-51" },
{ 53, "csISO51INISCyrillic" },
{ 54, "ISO_5427:1981" },
{ 54, "iso-ir-54" },
{ 54, "ISO5427Cyrillic1981" },
{ 54, "csISO54271981" },
{ 55, "ISO_5428:1980" },
{ 55, "iso-ir-55" },
{ 55, "csISO5428Greek" },
{ 56, "GB_1988-80" },
{ 56, "iso-ir-57" },
{ 56, "cn" },
{ 56, "ISO646-CN" },
{ 56, "csISO57GB1988" },
{ 57, "GB_2312-80" },
{ 57, "iso-ir-58" },
{ 57, "chinese" },
{ 57, "csISO58GB231280" },
{ 58, "NS_4551-2" },
{ 58, "ISO646-NO2" },
{ 58, "iso-ir-61" },
{ 58, "no2" },
{ 58, "csISO61Norwegian2" },
{ 59, "videotex-suppl" },
{ 59, "iso-ir-70" },
{ 59, "csISO70VideotexSupp1" },
{ 60, "PT2" },
{ 60, "iso-ir-84" },
{ 60, "ISO646-PT2" },
{ 60, "csISO84Portuguese2" },
{ 61, "ES2" },
{ 61, "iso-ir-85" },
{ 61, "ISO646-ES2" },
{ 61, "csISO85Spanish2" },
{ 62, "MSZ_7795.3" },
{ 62, "iso-ir-86" },
{ 62, "ISO646-HU" },
{ 62, "hu" },
{ 62, "csISO86Hungarian" },
{ 63, "JIS_C6226-1983" },
{ 63, "iso-ir-87" },
{ 63, "x0208" },
{ 63, "JIS_X0208-1983" },
{ 63, "csISO87JISX0208" },
{ 64, "greek7" },
{ 64, "iso-ir-88" },
{ 64, "csISO88Greek7" },
{ 65, "ASMO_449" },
{ 65, "ISO_9036" },
{ 65, "arabic7" },
{ 65, "iso-ir-89" },
{ 65, "csISO89ASMO449" },
{ 66, "iso-ir-90" },
{ 66, "csISO90" },
{ 67, "JIS_C6229-1984-a" },
{ 67, "iso-ir-91" },
{ 67, "jp-ocr-a" },
{ 67, "csISO91JISC62291984a" },
{ 68, "JIS_C6229-1984-b" },
{ 68, "iso-ir-92" },
{ 68, "ISO646-JP-OCR-B" },
{ 68, "jp-ocr-b" },
{ 68, "csISO92JISC62991984b" },
{ 69, "JIS_C6229-1984-b-add" },
{ 69, "iso-ir-93" },
{ 69, "jp-ocr-b-add" },
{ 69, "csISO93JIS62291984badd" },
{ 70, "JIS_C6229-1984-hand" },
{ 70, "iso-ir-94" },
{ 70, "jp-ocr-hand" },
{ 70, "csISO94JIS62291984hand" },
{ 71, "JIS_C6229-1984-hand-add" },
{ 71, "iso-ir-95" },
{ 71, "jp-ocr-hand-add" },
{ 71, "csISO95JIS62291984handadd" },
{ 72, "JIS_C6229-1984-kana" },
{ 72, "iso-ir-96" },
{ 72, "csISO96JISC62291984kana" },
{ 73, "ISO_2033-1983" },
{ 73, "iso-ir-98" },
{ 73, "e13b" },
{ 73, "csISO2033" },
{ 74, "ANSI_X3.110-1983" },
{ 74, "iso-ir-99" },
{ 74, "CSA_T500-1983" },
{ 74, "NAPLPS" },
{ 74, "csISO99NAPLPS" },
{ 75, "T.61-7bit" },
{ 75, "iso-ir-102" },
{ 75, "csISO102T617bit" },
{ 76, "T.61-8bit" },
{ 76, "T.61" },
{ 76, "iso-ir-103" },
{ 76, "csISO103T618bit" },
{ 77, "ECMA-cyrillic" },
{ 77, "iso-ir-111" },
{ 77, "KOI8-E" },
{ 77, "csISO111ECMACyrillic" },
{ 78, "CSA_Z243.4-1985-1" },
{ 78, "iso-ir-121" },
{ 78, "ISO646-CA" },
{ 78, "csa7-1" },
{ 78, "csa71" },
{ 78, "ca" },
{ 78, "csISO121Canadian1" },
{ 79, "CSA_Z243.4-1985-2" },
{ 79, "iso-ir-122" },
{ 79, "ISO646-CA2" },
{ 79, "csa7-2" },
{ 79, "csa72" },
{ 79, "csISO122Canadian2" },
{ 80, "CSA_Z243.4-1985-gr" },
{ 80, "iso-ir-123" },
{ 80, "csISO123CSAZ24341985gr" },
{ 81, "ISO_8859-6-E" },
{ 81, "csISO88596E" },
{ 81, "ISO-8859-6-E" },
{ 82, "ISO_8859-6-I" },
{ 82, "csISO88596I" },
{ 82, "ISO-8859-6-I" },
{ 83, "T.101-G2" },
{ 83, "iso-ir-128" },
{ 83, "csISO128T101G2" },
{ 84, "ISO_8859-8-E" },
{ 84, "csISO88598E" },
{ 84, "ISO-8859-8-E" },
{ 85, "ISO_8859-8-I" },
{ 85, "csISO88598I" },
{ 85, "ISO-8859-8-I" },
{ 86, "CSN_369103" },
{ 86, "iso-ir-139" },
{ 86, "csISO139CSN369103" },
{ 87, "JUS_I.B1.002" },
{ 87, "iso-ir-141" },
{ 87, "ISO646-YU" },
{ 87, "js" },
{ 87, "yu" },
{ 87, "csISO141JUSIB1002" },
{ 88, "IEC_P27-1" },
{ 88, "iso-ir-143" },
{ 88, "csISO143IECP271" },
{ 89, "JUS_I.B1.003-serb" },
{ 89, "iso-ir-146" },
{ 89, "serbian" },
{ 89, "csISO146Serbian" },
{ 90, "JUS_I.B1.003-mac" },
{ 90, "macedonian" },
{ 90, "iso-ir-147" },
{ 90, "csISO147Macedonian" },
{ 91, "greek-ccitt" },
{ 91, "iso-ir-150" },
{ 91, "csISO150" },
{ 91, "csISO150GreekCCITT" },
{ 92, "NC_NC00-10:81" },
{ 92, "cuba" },
{ 92, "iso-ir-151" },
{ 92, "ISO646-CU" },
{ 92, "csISO151Cuba" },
{ 93, "ISO_6937-2-25" },
{ 93, "iso-ir-152" },
{ 93, "csISO6937Add" },
{ 94, "GOST_19768-74" },
{ 94, "ST_SEV_358-88" },
{ 94, "iso-ir-153" },
{ 94, "csISO153GOST1976874" },
{ 95, "ISO_8859-supp" },
{ 95, "iso-ir-154" },
{ 95, "latin1-2-5" },
{ 95, "csISO8859Supp" },
{ 96, "ISO_10367-box" },
{ 96, "iso-ir-155" },
{ 96, "csISO10367Box" },
{ 97, "latin-lap" },
{ 97, "lap" },
{ 97, "iso-ir-158" },
{ 97, "csISO158Lap" },
{ 98, "JIS_X0212-1990" },
{ 98, "x0212" },
{ 98, "iso-ir-159" },
{ 98, "csISO159JISX02121990" },
{ 99, "DS_2089" },
{ 99, "DS2089" },
{ 99, "ISO646-DK" },
{ 99, "dk" },
{ 99, "csISO646Danish" },
{ 100, "us-dk" },
{ 100, "csUSDK" },
{ 101, "dk-us" },
{ 101, "csDKUS" },
{ 102, "KSC5636" },
{ 102, "ISO646-KR" },
{ 102, "csKSC5636" },
{ 103, "UNICODE-1-1-UTF-7" },
{ 103, "csUnicode11UTF7" },
{ 104, "ISO-2022-CN" },
{ 104, "csISO2022CN" },
{ 105, "ISO-2022-CN-EXT" },
{ 105, "csISO2022CNEXT" },
#define _GLIBCXX_TEXT_ENCODING_UTF8_OFFSET 414
{ 106, "UTF-8" },
{ 106, "csUTF8" },
{ 109, "ISO-8859-13" },
{ 109, "csISO885913" },
{ 110, "ISO-8859-14" },
{ 110, "iso-ir-199" },
{ 110, "ISO_8859-14:1998" },
{ 110, "ISO_8859-14" },
{ 110, "latin8" },
{ 110, "iso-celtic" },
{ 110, "l8" },
{ 110, "csISO885914" },
{ 111, "ISO-8859-15" },
{ 111, "ISO_8859-15" },
{ 111, "Latin-9" },
{ 111, "csISO885915" },
{ 112, "ISO-8859-16" },
{ 112, "iso-ir-226" },
{ 112, "ISO_8859-16:2001" },
{ 112, "ISO_8859-16" },
{ 112, "latin10" },
{ 112, "l10" },
{ 112, "csISO885916" },
{ 113, "GBK" },
{ 113, "CP936" },
{ 113, "MS936" },
{ 113, "windows-936" },
{ 113, "csGBK" },
{ 114, "GB18030" },
{ 114, "csGB18030" },
{ 115, "OSD_EBCDIC_DF04_15" },
{ 115, "csOSDEBCDICDF0415" },
{ 116, "OSD_EBCDIC_DF03_IRV" },
{ 116, "csOSDEBCDICDF03IRV" },
{ 117, "OSD_EBCDIC_DF04_1" },
{ 117, "csOSDEBCDICDF041" },
{ 118, "ISO-11548-1" },
{ 118, "ISO_11548-1" },
{ 118, "ISO_TR_11548-1" },
{ 118, "csISO115481" },
{ 119, "KZ-1048" },
{ 119, "STRK1048-2002" },
{ 119, "RK1048" },
{ 119, "csKZ1048" },
{ 1000, "ISO-10646-UCS-2" },
{ 1000, "csUnicode" },
{ 1001, "ISO-10646-UCS-4" },
{ 1001, "csUCS4" },
{ 1002, "ISO-10646-UCS-Basic" },
{ 1002, "csUnicodeASCII" },
{ 1003, "ISO-10646-Unicode-Latin1" },
{ 1003, "csUnicodeLatin1" },
{ 1003, "ISO-10646" },
{ 1004, "ISO-10646-J-1" },
{ 1004, "csUnicodeJapanese" },
{ 1005, "ISO-Unicode-IBM-1261" },
{ 1005, "csUnicodeIBM1261" },
{ 1006, "ISO-Unicode-IBM-1268" },
{ 1006, "csUnicodeIBM1268" },
{ 1007, "ISO-Unicode-IBM-1276" },
{ 1007, "csUnicodeIBM1276" },
{ 1008, "ISO-Unicode-IBM-1264" },
{ 1008, "csUnicodeIBM1264" },
{ 1009, "ISO-Unicode-IBM-1265" },
{ 1009, "csUnicodeIBM1265" },
{ 1010, "UNICODE-1-1" },
{ 1010, "csUnicode11" },
{ 1011, "SCSU" },
{ 1011, "csSCSU" },
{ 1012, "UTF-7" },
{ 1012, "csUTF7" },
{ 1013, "UTF-16BE" },
{ 1013, "csUTF16BE" },
{ 1014, "UTF-16LE" },
{ 1014, "csUTF16LE" },
{ 1015, "UTF-16" },
{ 1015, "csUTF16" },
{ 1016, "CESU-8" },
{ 1016, "csCESU8" },
{ 1016, "csCESU-8" },
{ 1017, "UTF-32" },
{ 1017, "csUTF32" },
{ 1018, "UTF-32BE" },
{ 1018, "csUTF32BE" },
{ 1019, "UTF-32LE" },
{ 1019, "csUTF32LE" },
{ 1020, "BOCU-1" },
{ 1020, "csBOCU1" },
{ 1020, "csBOCU-1" },
{ 1021, "UTF-7-IMAP" },
{ 1021, "csUTF7IMAP" },
{ 2000, "ISO-8859-1-Windows-3.0-Latin-1" },
{ 2000, "csWindows30Latin1" },
{ 2001, "ISO-8859-1-Windows-3.1-Latin-1" },
{ 2001, "csWindows31Latin1" },
{ 2002, "ISO-8859-2-Windows-Latin-2" },
{ 2002, "csWindows31Latin2" },
{ 2003, "ISO-8859-9-Windows-Latin-5" },
{ 2003, "csWindows31Latin5" },
{ 2004, "hp-roman8" },
{ 2004, "roman8" },
{ 2004, "r8" },
{ 2004, "csHPRoman8" },
{ 2005, "Adobe-Standard-Encoding" },
{ 2005, "csAdobeStandardEncoding" },
{ 2006, "Ventura-US" },
{ 2006, "csVenturaUS" },
{ 2007, "Ventura-International" },
{ 2007, "csVenturaInternational" },
{ 2008, "DEC-MCS" },
{ 2008, "dec" },
{ 2008, "csDECMCS" },
{ 2009, "IBM850" },
{ 2009, "cp850" },
{ 2009, "850" },
{ 2009, "csPC850Multilingual" },
{ 2010, "IBM852" },
{ 2010, "cp852" },
{ 2010, "852" },
{ 2010, "csPCp852" },
{ 2011, "IBM437" },
{ 2011, "cp437" },
{ 2011, "437" },
{ 2011, "csPC8CodePage437" },
{ 2012, "PC8-Danish-Norwegian" },
{ 2012, "csPC8DanishNorwegian" },
{ 2013, "IBM862" },
{ 2013, "cp862" },
{ 2013, "862" },
{ 2013, "csPC862LatinHebrew" },
{ 2014, "PC8-Turkish" },
{ 2014, "csPC8Turkish" },
{ 2015, "IBM-Symbols" },
{ 2015, "csIBMSymbols" },
{ 2016, "IBM-Thai" },
{ 2016, "csIBMThai" },
{ 2017, "HP-Legal" },
{ 2017, "csHPLegal" },
{ 2018, "HP-Pi-font" },
{ 2018, "csHPPiFont" },
{ 2019, "HP-Math8" },
{ 2019, "csHPMath8" },
{ 2020, "Adobe-Symbol-Encoding" },
{ 2020, "csHPPSMath" },
{ 2021, "HP-DeskTop" },
{ 2021, "csHPDesktop" },
{ 2022, "Ventura-Math" },
{ 2022, "csVenturaMath" },
{ 2023, "Microsoft-Publishing" },
{ 2023, "csMicrosoftPublishing" },
{ 2024, "Windows-31J" },
{ 2024, "csWindows31J" },
{ 2025, "GB2312" },
{ 2025, "csGB2312" },
{ 2026, "Big5" },
{ 2026, "csBig5" },
{ 2027, "macintosh" },
{ 2027, "mac" },
{ 2027, "csMacintosh" },
{ 2028, "IBM037" },
{ 2028, "cp037" },
{ 2028, "ebcdic-cp-us" },
{ 2028, "ebcdic-cp-ca" },
{ 2028, "ebcdic-cp-wt" },
{ 2028, "ebcdic-cp-nl" },
{ 2028, "csIBM037" },
{ 2029, "IBM038" },
{ 2029, "EBCDIC-INT" },
{ 2029, "cp038" },
{ 2029, "csIBM038" },
{ 2030, "IBM273" },
{ 2030, "CP273" },
{ 2030, "csIBM273" },
{ 2031, "IBM274" },
{ 2031, "EBCDIC-BE" },
{ 2031, "CP274" },
{ 2031, "csIBM274" },
{ 2032, "IBM275" },
{ 2032, "EBCDIC-BR" },
{ 2032, "cp275" },
{ 2032, "csIBM275" },
{ 2033, "IBM277" },
{ 2033, "EBCDIC-CP-DK" },
{ 2033, "EBCDIC-CP-NO" },
{ 2033, "csIBM277" },
{ 2034, "IBM278" },
{ 2034, "CP278" },
{ 2034, "ebcdic-cp-fi" },
{ 2034, "ebcdic-cp-se" },
{ 2034, "csIBM278" },
{ 2035, "IBM280" },
{ 2035, "CP280" },
{ 2035, "ebcdic-cp-it" },
{ 2035, "csIBM280" },
{ 2036, "IBM281" },
{ 2036, "EBCDIC-JP-E" },
{ 2036, "cp281" },
{ 2036, "csIBM281" },
{ 2037, "IBM284" },
{ 2037, "CP284" },
{ 2037, "ebcdic-cp-es" },
{ 2037, "csIBM284" },
{ 2038, "IBM285" },
{ 2038, "CP285" },
{ 2038, "ebcdic-cp-gb" },
{ 2038, "csIBM285" },
{ 2039, "IBM290" },
{ 2039, "cp290" },
{ 2039, "EBCDIC-JP-kana" },
{ 2039, "csIBM290" },
{ 2040, "IBM297" },
{ 2040, "cp297" },
{ 2040, "ebcdic-cp-fr" },
{ 2040, "csIBM297" },
{ 2041, "IBM420" },
{ 2041, "cp420" },
{ 2041, "ebcdic-cp-ar1" },
{ 2041, "csIBM420" },
{ 2042, "IBM423" },
{ 2042, "cp423" },
{ 2042, "ebcdic-cp-gr" },
{ 2042, "csIBM423" },
{ 2043, "IBM424" },
{ 2043, "cp424" },
{ 2043, "ebcdic-cp-he" },
{ 2043, "csIBM424" },
{ 2044, "IBM500" },
{ 2044, "CP500" },
{ 2044, "ebcdic-cp-be" },
{ 2044, "ebcdic-cp-ch" },
{ 2044, "csIBM500" },
{ 2045, "IBM851" },
{ 2045, "cp851" },
{ 2045, "851" },
{ 2045, "csIBM851" },
{ 2046, "IBM855" },
{ 2046, "cp855" },
{ 2046, "855" },
{ 2046, "csIBM855" },
{ 2047, "IBM857" },
{ 2047, "cp857" },
{ 2047, "857" },
{ 2047, "csIBM857" },
{ 2048, "IBM860" },
{ 2048, "cp860" },
{ 2048, "860" },
{ 2048, "csIBM860" },
{ 2049, "IBM861" },
{ 2049, "cp861" },
{ 2049, "861" },
{ 2049, "cp-is" },
{ 2049, "csIBM861" },
{ 2050, "IBM863" },
{ 2050, "cp863" },
{ 2050, "863" },
{ 2050, "csIBM863" },
{ 2051, "IBM864" },
{ 2051, "cp864" },
{ 2051, "csIBM864" },
{ 2052, "IBM865" },
{ 2052, "cp865" },
{ 2052, "865" },
{ 2052, "csIBM865" },
{ 2053, "IBM868" },
{ 2053, "CP868" },
{ 2053, "cp-ar" },
{ 2053, "csIBM868" },
{ 2054, "IBM869" },
{ 2054, "cp869" },
{ 2054, "869" },
{ 2054, "cp-gr" },
{ 2054, "csIBM869" },
{ 2055, "IBM870" },
{ 2055, "CP870" },
{ 2055, "ebcdic-cp-roece" },
{ 2055, "ebcdic-cp-yu" },
{ 2055, "csIBM870" },
{ 2056, "IBM871" },
{ 2056, "CP871" },
{ 2056, "ebcdic-cp-is" },
{ 2056, "csIBM871" },
{ 2057, "IBM880" },
{ 2057, "cp880" },
{ 2057, "EBCDIC-Cyrillic" },
{ 2057, "csIBM880" },
{ 2058, "IBM891" },
{ 2058, "cp891" },
{ 2058, "csIBM891" },
{ 2059, "IBM903" },
{ 2059, "cp903" },
{ 2059, "csIBM903" },
{ 2060, "IBM904" },
{ 2060, "cp904" },
{ 2060, "904" },
{ 2060, "csIBBM904" },
{ 2061, "IBM905" },
{ 2061, "CP905" },
{ 2061, "ebcdic-cp-tr" },
{ 2061, "csIBM905" },
{ 2062, "IBM918" },
{ 2062, "CP918" },
{ 2062, "ebcdic-cp-ar2" },
{ 2062, "csIBM918" },
{ 2063, "IBM1026" },
{ 2063, "CP1026" },
{ 2063, "csIBM1026" },
{ 2064, "EBCDIC-AT-DE" },
{ 2064, "csIBMEBCDICATDE" },
{ 2065, "EBCDIC-AT-DE-A" },
{ 2065, "csEBCDICATDEA" },
{ 2066, "EBCDIC-CA-FR" },
{ 2066, "csEBCDICCAFR" },
{ 2067, "EBCDIC-DK-NO" },
{ 2067, "csEBCDICDKNO" },
{ 2068, "EBCDIC-DK-NO-A" },
{ 2068, "csEBCDICDKNOA" },
{ 2069, "EBCDIC-FI-SE" },
{ 2069, "csEBCDICFISE" },
{ 2070, "EBCDIC-FI-SE-A" },
{ 2070, "csEBCDICFISEA" },
{ 2071, "EBCDIC-FR" },
{ 2071, "csEBCDICFR" },
{ 2072, "EBCDIC-IT" },
{ 2072, "csEBCDICIT" },
{ 2073, "EBCDIC-PT" },
{ 2073, "csEBCDICPT" },
{ 2074, "EBCDIC-ES" },
{ 2074, "csEBCDICES" },
{ 2075, "EBCDIC-ES-A" },
{ 2075, "csEBCDICESA" },
{ 2076, "EBCDIC-ES-S" },
{ 2076, "csEBCDICESS" },
{ 2077, "EBCDIC-UK" },
{ 2077, "csEBCDICUK" },
{ 2078, "EBCDIC-US" },
{ 2078, "csEBCDICUS" },
{ 2079, "UNKNOWN-8BIT" },
{ 2079, "csUnknown8BiT" },
{ 2080, "MNEMONIC" },
{ 2080, "csMnemonic" },
{ 2081, "MNEM" },
{ 2081, "csMnem" },
{ 2082, "VISCII" },
{ 2082, "csVISCII" },
{ 2083, "VIQR" },
{ 2083, "csVIQR" },
{ 2084, "KOI8-R" },
{ 2084, "csKOI8R" },
{ 2085, "HZ-GB-2312" },
{ 2086, "IBM866" },
{ 2086, "cp866" },
{ 2086, "866" },
{ 2086, "csIBM866" },
{ 2087, "IBM775" },
{ 2087, "cp775" },
{ 2087, "csPC775Baltic" },
{ 2088, "KOI8-U" },
{ 2088, "csKOI8U" },
{ 2089, "IBM00858" },
{ 2089, "CCSID00858" },
{ 2089, "CP00858" },
{ 2089, "PC-Multilingual-850+euro" },
{ 2089, "csIBM00858" },
{ 2090, "IBM00924" },
{ 2090, "CCSID00924" },
{ 2090, "CP00924" },
{ 2090, "ebcdic-Latin9--euro" },
{ 2090, "csIBM00924" },
{ 2091, "IBM01140" },
{ 2091, "CCSID01140" },
{ 2091, "CP01140" },
{ 2091, "ebcdic-us-37+euro" },
{ 2091, "csIBM01140" },
{ 2092, "IBM01141" },
{ 2092, "CCSID01141" },
{ 2092, "CP01141" },
{ 2092, "ebcdic-de-273+euro" },
{ 2092, "csIBM01141" },
{ 2093, "IBM01142" },
{ 2093, "CCSID01142" },
{ 2093, "CP01142" },
{ 2093, "ebcdic-dk-277+euro" },
{ 2093, "ebcdic-no-277+euro" },
{ 2093, "csIBM01142" },
{ 2094, "IBM01143" },
{ 2094, "CCSID01143" },
{ 2094, "CP01143" },
{ 2094, "ebcdic-fi-278+euro" },
{ 2094, "ebcdic-se-278+euro" },
{ 2094, "csIBM01143" },
{ 2095, "IBM01144" },
{ 2095, "CCSID01144" },
{ 2095, "CP01144" },
{ 2095, "ebcdic-it-280+euro" },
{ 2095, "csIBM01144" },
{ 2096, "IBM01145" },
{ 2096, "CCSID01145" },
{ 2096, "CP01145" },
{ 2096, "ebcdic-es-284+euro" },
{ 2096, "csIBM01145" },
{ 2097, "IBM01146" },
{ 2097, "CCSID01146" },
{ 2097, "CP01146" },
{ 2097, "ebcdic-gb-285+euro" },
{ 2097, "csIBM01146" },
{ 2098, "IBM01147" },
{ 2098, "CCSID01147" },
{ 2098, "CP01147" },
{ 2098, "ebcdic-fr-297+euro" },
{ 2098, "csIBM01147" },
{ 2099, "IBM01148" },
{ 2099, "CCSID01148" },
{ 2099, "CP01148" },
{ 2099, "ebcdic-international-500+euro" },
{ 2099, "csIBM01148" },
{ 2100, "IBM01149" },
{ 2100, "CCSID01149" },
{ 2100, "CP01149" },
{ 2100, "ebcdic-is-871+euro" },
{ 2100, "csIBM01149" },
{ 2101, "Big5-HKSCS" },
{ 2101, "csBig5HKSCS" },
{ 2102, "IBM1047" },
{ 2102, "IBM-1047" },
{ 2102, "csIBM1047" },
{ 2103, "PTCP154" },
{ 2103, "csPTCP154" },
{ 2103, "PT154" },
{ 2103, "CP154" },
{ 2103, "Cyrillic-Asian" },
{ 2104, "Amiga-1251" },
{ 2104, "Ami1251" },
{ 2104, "Amiga1251" },
{ 2104, "Ami-1251" },
{ 2104, "csAmiga1251" },
{ 2104, "(Aliases" },
{ 2104, "are" },
{ 2104, "provided" },
{ 2104, "for" },
{ 2104, "historical" },
{ 2104, "reasons" },
{ 2104, "and" },
{ 2104, "should" },
{ 2104, "not" },
{ 2104, "be" },
{ 2104, "used)" },
{ 2104, "[Malyshev]" },
{ 2105, "KOI7-switched" },
{ 2105, "csKOI7switched" },
{ 2106, "BRF" },
{ 2106, "csBRF" },
{ 2107, "TSCII" },
{ 2107, "csTSCII" },
{ 2108, "CP51932" },
{ 2108, "csCP51932" },
{ 2109, "windows-874" },
{ 2109, "cswindows874" },
{ 2250, "windows-1250" },
{ 2250, "cswindows1250" },
{ 2251, "windows-1251" },
{ 2251, "cswindows1251" },
{ 2252, "windows-1252" },
{ 2252, "cswindows1252" },
{ 2253, "windows-1253" },
{ 2253, "cswindows1253" },
{ 2254, "windows-1254" },
{ 2254, "cswindows1254" },
{ 2255, "windows-1255" },
{ 2255, "cswindows1255" },
{ 2256, "windows-1256" },
{ 2256, "cswindows1256" },
{ 2257, "windows-1257" },
{ 2257, "cswindows1257" },
{ 2258, "windows-1258" },
{ 2258, "cswindows1258" },
{ 2259, "TIS-620" },
{ 2259, "csTIS620" },
{ 2259, "ISO-8859-11" },
{ 2260, "CP50220" },
{ 2260, "csCP50220" },
#undef _GLIBCXX_GET_ENCODING_DATA
@@ -0,0 +1,92 @@
// std::time_get, std::time_put implementation, generic version -*- C++ -*-
// Copyright (C) 2001-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/time_members.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{locale}
*/
//
// ISO C++ 14882: 22.2.5.1.2 - time_get functions
// ISO C++ 14882: 22.2.5.3.2 - time_put functions
//
// Written by Benjamin Kosnik <bkoz@redhat.com>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _CharT>
__timepunct<_CharT>::__timepunct(size_t __refs)
: facet(__refs), _M_data(0)
{
_M_name_timepunct = _S_get_c_name();
_M_initialize_timepunct();
}
template<typename _CharT>
__timepunct<_CharT>::__timepunct(__cache_type* __cache, size_t __refs)
: facet(__refs), _M_data(__cache)
{
_M_name_timepunct = _S_get_c_name();
_M_initialize_timepunct();
}
template<typename _CharT>
__timepunct<_CharT>::__timepunct(__c_locale __cloc, const char* __s,
size_t __refs)
: facet(__refs), _M_data(0)
{
if (__builtin_strcmp(__s, _S_get_c_name()) != 0)
{
const size_t __len = __builtin_strlen(__s) + 1;
char* __tmp = new char[__len];
__builtin_memcpy(__tmp, __s, __len);
_M_name_timepunct = __tmp;
}
else
_M_name_timepunct = _S_get_c_name();
__try
{ _M_initialize_timepunct(__cloc); }
__catch(...)
{
if (_M_name_timepunct != _S_get_c_name())
delete [] _M_name_timepunct;
__throw_exception_again;
}
}
template<typename _CharT>
__timepunct<_CharT>::~__timepunct()
{
if (_M_name_timepunct != _S_get_c_name())
delete [] _M_name_timepunct;
delete _M_data;
_S_destroy_c_locale(_M_c_locale_timepunct);
}
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
@@ -0,0 +1,476 @@
// Generated by contrib/unicode/gen_libstdcxx_unicode_data.py, do not edit.
// Copyright The GNU Toolchain Authors.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/unicode-data.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{format}
*/
#ifndef _GLIBCXX_GET_UNICODE_DATA
# error "This is not a public header, do not include it directly"
#elif _GLIBCXX_GET_UNICODE_DATA != 150100
# error "Version mismatch for Unicode static data"
#endif
// Table generated by contrib/unicode/gen_std_format_width.py,
// from EastAsianWidth.txt from the Unicode standard.
inline constexpr char32_t __width_edges[] = {
0x1100, 0x1160, 0x231a, 0x231c, 0x2329, 0x232b, 0x23e9, 0x23ed,
0x23f0, 0x23f1, 0x23f3, 0x23f4, 0x25fd, 0x25ff, 0x2614, 0x2616,
0x2648, 0x2654, 0x267f, 0x2680, 0x2693, 0x2694, 0x26a1, 0x26a2,
0x26aa, 0x26ac, 0x26bd, 0x26bf, 0x26c4, 0x26c6, 0x26ce, 0x26cf,
0x26d4, 0x26d5, 0x26ea, 0x26eb, 0x26f2, 0x26f4, 0x26f5, 0x26f6,
0x26fa, 0x26fb, 0x26fd, 0x26fe, 0x2705, 0x2706, 0x270a, 0x270c,
0x2728, 0x2729, 0x274c, 0x274d, 0x274e, 0x274f, 0x2753, 0x2756,
0x2757, 0x2758, 0x2795, 0x2798, 0x27b0, 0x27b1, 0x27bf, 0x27c0,
0x2b1b, 0x2b1d, 0x2b50, 0x2b51, 0x2b55, 0x2b56, 0x2e80, 0x2e9a,
0x2e9b, 0x2ef4, 0x2f00, 0x2fd6, 0x2ff0, 0x303f, 0x3041, 0x3097,
0x3099, 0x3100, 0x3105, 0x3130, 0x3131, 0x318f, 0x3190, 0x31e4,
0x31ef, 0x321f, 0x3220, 0x3248, 0x3250, 0xa48d, 0xa490, 0xa4c7,
0xa960, 0xa97d, 0xac00, 0xd7a4, 0xf900, 0xfb00, 0xfe10, 0xfe1a,
0xfe30, 0xfe53, 0xfe54, 0xfe67, 0xfe68, 0xfe6c, 0xff01, 0xff61,
0xffe0, 0xffe7, 0x16fe0, 0x16fe5, 0x16ff0, 0x16ff2, 0x17000, 0x187f8,
0x18800, 0x18cd6, 0x18d00, 0x18d09, 0x1aff0, 0x1aff4, 0x1aff5, 0x1affc,
0x1affd, 0x1afff, 0x1b000, 0x1b123, 0x1b132, 0x1b133, 0x1b150, 0x1b153,
0x1b155, 0x1b156, 0x1b164, 0x1b168, 0x1b170, 0x1b2fc, 0x1f004, 0x1f005,
0x1f0cf, 0x1f0d0, 0x1f18e, 0x1f18f, 0x1f191, 0x1f19b, 0x1f200, 0x1f203,
0x1f210, 0x1f23c, 0x1f240, 0x1f249, 0x1f250, 0x1f252, 0x1f260, 0x1f266,
0x1f300, 0x1f650, 0x1f680, 0x1f6c6, 0x1f6cc, 0x1f6cd, 0x1f6d0, 0x1f6d3,
0x1f6d5, 0x1f6d8, 0x1f6dc, 0x1f6e0, 0x1f6eb, 0x1f6ed, 0x1f6f4, 0x1f6fd,
0x1f7e0, 0x1f7ec, 0x1f7f0, 0x1f7f1, 0x1f900, 0x1fa00, 0x1fa70, 0x1fa7d,
0x1fa80, 0x1fa89, 0x1fa90, 0x1fabe, 0x1fabf, 0x1fac6, 0x1face, 0x1fadc,
0x1fae0, 0x1fae9, 0x1faf0, 0x1faf9, 0x20000, 0x2fffe, 0x30000, 0x3fffe,
};
enum class _Gcb_property {
_Gcb_Other = 0,
_Gcb_Control = 1,
_Gcb_LF = 2,
_Gcb_CR = 3,
_Gcb_Extend = 4,
_Gcb_Prepend = 5,
_Gcb_SpacingMark = 6,
_Gcb_L = 7,
_Gcb_V = 8,
_Gcb_T = 9,
_Gcb_ZWJ = 10,
_Gcb_LV = 11,
_Gcb_LVT = 12,
_Gcb_Regional_Indicator = 13,
};
// Values generated by contrib/unicode/gen_std_format_width.py,
// from GraphemeBreakProperty.txt from the Unicode standard.
// Entries are (code_point << shift_bits) + property.
inline constexpr int __gcb_shift_bits = 0x4;
inline constexpr uint32_t __gcb_edges[] = {
0x1, 0xa2, 0xb1, 0xd3, 0xe1, 0x200,
0x7f1, 0xa00, 0xad1, 0xae0, 0x3004, 0x3700,
0x4834, 0x48a0, 0x5914, 0x5be0, 0x5bf4, 0x5c00,
0x5c14, 0x5c30, 0x5c44, 0x5c60, 0x5c74, 0x5c80,
0x6005, 0x6060, 0x6104, 0x61b0, 0x61c1, 0x61d0,
0x64b4, 0x6600, 0x6704, 0x6710, 0x6d64, 0x6dd5,
0x6de0, 0x6df4, 0x6e50, 0x6e74, 0x6e90, 0x6ea4,
0x6ee0, 0x70f5, 0x7100, 0x7114, 0x7120, 0x7304,
0x74b0, 0x7a64, 0x7b10, 0x7eb4, 0x7f40, 0x7fd4,
0x7fe0, 0x8164, 0x81a0, 0x81b4, 0x8240, 0x8254,
0x8280, 0x8294, 0x82e0, 0x8594, 0x85c0, 0x8905,
0x8920, 0x8984, 0x8a00, 0x8ca4, 0x8e25, 0x8e34,
0x9036, 0x9040, 0x93a4, 0x93b6, 0x93c4, 0x93d0,
0x93e6, 0x9414, 0x9496, 0x94d4, 0x94e6, 0x9500,
0x9514, 0x9580, 0x9624, 0x9640, 0x9814, 0x9826,
0x9840, 0x9bc4, 0x9bd0, 0x9be4, 0x9bf6, 0x9c14,
0x9c50, 0x9c76, 0x9c90, 0x9cb6, 0x9cd4, 0x9ce0,
0x9d74, 0x9d80, 0x9e24, 0x9e40, 0x9fe4, 0x9ff0,
0xa014, 0xa036, 0xa040, 0xa3c4, 0xa3d0, 0xa3e6,
0xa414, 0xa430, 0xa474, 0xa490, 0xa4b4, 0xa4e0,
0xa514, 0xa520, 0xa704, 0xa720, 0xa754, 0xa760,
0xa814, 0xa836, 0xa840, 0xabc4, 0xabd0, 0xabe6,
0xac14, 0xac60, 0xac74, 0xac96, 0xaca0, 0xacb6,
0xacd4, 0xace0, 0xae24, 0xae40, 0xafa4, 0xb000,
0xb014, 0xb026, 0xb040, 0xb3c4, 0xb3d0, 0xb3e4,
0xb406, 0xb414, 0xb450, 0xb476, 0xb490, 0xb4b6,
0xb4d4, 0xb4e0, 0xb554, 0xb580, 0xb624, 0xb640,
0xb824, 0xb830, 0xbbe4, 0xbbf6, 0xbc04, 0xbc16,
0xbc30, 0xbc66, 0xbc90, 0xbca6, 0xbcd4, 0xbce0,
0xbd74, 0xbd80, 0xc004, 0xc016, 0xc044, 0xc050,
0xc3c4, 0xc3d0, 0xc3e4, 0xc416, 0xc450, 0xc464,
0xc490, 0xc4a4, 0xc4e0, 0xc554, 0xc570, 0xc624,
0xc640, 0xc814, 0xc826, 0xc840, 0xcbc4, 0xcbd0,
0xcbe6, 0xcbf4, 0xcc06, 0xcc24, 0xcc36, 0xcc50,
0xcc64, 0xcc76, 0xcc90, 0xcca6, 0xccc4, 0xcce0,
0xcd54, 0xcd70, 0xce24, 0xce40, 0xcf36, 0xcf40,
0xd004, 0xd026, 0xd040, 0xd3b4, 0xd3d0, 0xd3e4,
0xd3f6, 0xd414, 0xd450, 0xd466, 0xd490, 0xd4a6,
0xd4d4, 0xd4e5, 0xd4f0, 0xd574, 0xd580, 0xd624,
0xd640, 0xd814, 0xd826, 0xd840, 0xdca4, 0xdcb0,
0xdcf4, 0xdd06, 0xdd24, 0xdd50, 0xdd64, 0xdd70,
0xdd86, 0xddf4, 0xde00, 0xdf26, 0xdf40, 0xe314,
0xe320, 0xe336, 0xe344, 0xe3b0, 0xe474, 0xe4f0,
0xeb14, 0xeb20, 0xeb36, 0xeb44, 0xebd0, 0xec84,
0xecf0, 0xf184, 0xf1a0, 0xf354, 0xf360, 0xf374,
0xf380, 0xf394, 0xf3a0, 0xf3e6, 0xf400, 0xf714,
0xf7f6, 0xf804, 0xf850, 0xf864, 0xf880, 0xf8d4,
0xf980, 0xf994, 0xfbd0, 0xfc64, 0xfc70, 0x102d4,
0x10316, 0x10324, 0x10380, 0x10394, 0x103b6, 0x103d4,
0x103f0, 0x10566, 0x10584, 0x105a0, 0x105e4, 0x10610,
0x10714, 0x10750, 0x10824, 0x10830, 0x10846, 0x10854,
0x10870, 0x108d4, 0x108e0, 0x109d4, 0x109e0, 0x11007,
0x11608, 0x11a89, 0x12000, 0x135d4, 0x13600, 0x17124,
0x17156, 0x17160, 0x17324, 0x17346, 0x17350, 0x17524,
0x17540, 0x17724, 0x17740, 0x17b44, 0x17b66, 0x17b74,
0x17be6, 0x17c64, 0x17c76, 0x17c94, 0x17d40, 0x17dd4,
0x17de0, 0x180b4, 0x180e1, 0x180f4, 0x18100, 0x18854,
0x18870, 0x18a94, 0x18aa0, 0x19204, 0x19236, 0x19274,
0x19296, 0x192c0, 0x19306, 0x19324, 0x19336, 0x19394,
0x193c0, 0x1a174, 0x1a196, 0x1a1b4, 0x1a1c0, 0x1a556,
0x1a564, 0x1a576, 0x1a584, 0x1a5f0, 0x1a604, 0x1a610,
0x1a624, 0x1a630, 0x1a654, 0x1a6d6, 0x1a734, 0x1a7d0,
0x1a7f4, 0x1a800, 0x1ab04, 0x1acf0, 0x1b004, 0x1b046,
0x1b050, 0x1b344, 0x1b3b6, 0x1b3c4, 0x1b3d6, 0x1b424,
0x1b436, 0x1b450, 0x1b6b4, 0x1b740, 0x1b804, 0x1b826,
0x1b830, 0x1ba16, 0x1ba24, 0x1ba66, 0x1ba84, 0x1baa6,
0x1bab4, 0x1bae0, 0x1be64, 0x1be76, 0x1be84, 0x1bea6,
0x1bed4, 0x1bee6, 0x1bef4, 0x1bf26, 0x1bf40, 0x1c246,
0x1c2c4, 0x1c346, 0x1c364, 0x1c380, 0x1cd04, 0x1cd30,
0x1cd44, 0x1ce16, 0x1ce24, 0x1ce90, 0x1ced4, 0x1cee0,
0x1cf44, 0x1cf50, 0x1cf76, 0x1cf84, 0x1cfa0, 0x1dc04,
0x1e000, 0x200b1, 0x200c4, 0x200da, 0x200e1, 0x20100,
0x20281, 0x202f0, 0x20601, 0x20700, 0x20d04, 0x20f10,
0x2cef4, 0x2cf20, 0x2d7f4, 0x2d800, 0x2de04, 0x2e000,
0x302a4, 0x30300, 0x30994, 0x309b0, 0xa66f4, 0xa6730,
0xa6744, 0xa67e0, 0xa69e4, 0xa6a00, 0xa6f04, 0xa6f20,
0xa8024, 0xa8030, 0xa8064, 0xa8070, 0xa80b4, 0xa80c0,
0xa8236, 0xa8254, 0xa8276, 0xa8280, 0xa82c4, 0xa82d0,
0xa8806, 0xa8820, 0xa8b46, 0xa8c44, 0xa8c60, 0xa8e04,
0xa8f20, 0xa8ff4, 0xa9000, 0xa9264, 0xa92e0, 0xa9474,
0xa9526, 0xa9540, 0xa9607, 0xa97d0, 0xa9804, 0xa9836,
0xa9840, 0xa9b34, 0xa9b46, 0xa9b64, 0xa9ba6, 0xa9bc4,
0xa9be6, 0xa9c10, 0xa9e54, 0xa9e60, 0xaa294, 0xaa2f6,
0xaa314, 0xaa336, 0xaa354, 0xaa370, 0xaa434, 0xaa440,
0xaa4c4, 0xaa4d6, 0xaa4e0, 0xaa7c4, 0xaa7d0, 0xaab04,
0xaab10, 0xaab24, 0xaab50, 0xaab74, 0xaab90, 0xaabe4,
0xaac00, 0xaac14, 0xaac20, 0xaaeb6, 0xaaec4, 0xaaee6,
0xaaf00, 0xaaf56, 0xaaf64, 0xaaf70, 0xabe36, 0xabe54,
0xabe66, 0xabe84, 0xabe96, 0xabeb0, 0xabec6, 0xabed4,
0xabee0, 0xac00b, 0xac01c, 0xac1cb, 0xac1dc, 0xac38b,
0xac39c, 0xac54b, 0xac55c, 0xac70b, 0xac71c, 0xac8cb,
0xac8dc, 0xaca8b, 0xaca9c, 0xacc4b, 0xacc5c, 0xace0b,
0xace1c, 0xacfcb, 0xacfdc, 0xad18b, 0xad19c, 0xad34b,
0xad35c, 0xad50b, 0xad51c, 0xad6cb, 0xad6dc, 0xad88b,
0xad89c, 0xada4b, 0xada5c, 0xadc0b, 0xadc1c, 0xaddcb,
0xadddc, 0xadf8b, 0xadf9c, 0xae14b, 0xae15c, 0xae30b,
0xae31c, 0xae4cb, 0xae4dc, 0xae68b, 0xae69c, 0xae84b,
0xae85c, 0xaea0b, 0xaea1c, 0xaebcb, 0xaebdc, 0xaed8b,
0xaed9c, 0xaef4b, 0xaef5c, 0xaf10b, 0xaf11c, 0xaf2cb,
0xaf2dc, 0xaf48b, 0xaf49c, 0xaf64b, 0xaf65c, 0xaf80b,
0xaf81c, 0xaf9cb, 0xaf9dc, 0xafb8b, 0xafb9c, 0xafd4b,
0xafd5c, 0xaff0b, 0xaff1c, 0xb00cb, 0xb00dc, 0xb028b,
0xb029c, 0xb044b, 0xb045c, 0xb060b, 0xb061c, 0xb07cb,
0xb07dc, 0xb098b, 0xb099c, 0xb0b4b, 0xb0b5c, 0xb0d0b,
0xb0d1c, 0xb0ecb, 0xb0edc, 0xb108b, 0xb109c, 0xb124b,
0xb125c, 0xb140b, 0xb141c, 0xb15cb, 0xb15dc, 0xb178b,
0xb179c, 0xb194b, 0xb195c, 0xb1b0b, 0xb1b1c, 0xb1ccb,
0xb1cdc, 0xb1e8b, 0xb1e9c, 0xb204b, 0xb205c, 0xb220b,
0xb221c, 0xb23cb, 0xb23dc, 0xb258b, 0xb259c, 0xb274b,
0xb275c, 0xb290b, 0xb291c, 0xb2acb, 0xb2adc, 0xb2c8b,
0xb2c9c, 0xb2e4b, 0xb2e5c, 0xb300b, 0xb301c, 0xb31cb,
0xb31dc, 0xb338b, 0xb339c, 0xb354b, 0xb355c, 0xb370b,
0xb371c, 0xb38cb, 0xb38dc, 0xb3a8b, 0xb3a9c, 0xb3c4b,
0xb3c5c, 0xb3e0b, 0xb3e1c, 0xb3fcb, 0xb3fdc, 0xb418b,
0xb419c, 0xb434b, 0xb435c, 0xb450b, 0xb451c, 0xb46cb,
0xb46dc, 0xb488b, 0xb489c, 0xb4a4b, 0xb4a5c, 0xb4c0b,
0xb4c1c, 0xb4dcb, 0xb4ddc, 0xb4f8b, 0xb4f9c, 0xb514b,
0xb515c, 0xb530b, 0xb531c, 0xb54cb, 0xb54dc, 0xb568b,
0xb569c, 0xb584b, 0xb585c, 0xb5a0b, 0xb5a1c, 0xb5bcb,
0xb5bdc, 0xb5d8b, 0xb5d9c, 0xb5f4b, 0xb5f5c, 0xb610b,
0xb611c, 0xb62cb, 0xb62dc, 0xb648b, 0xb649c, 0xb664b,
0xb665c, 0xb680b, 0xb681c, 0xb69cb, 0xb69dc, 0xb6b8b,
0xb6b9c, 0xb6d4b, 0xb6d5c, 0xb6f0b, 0xb6f1c, 0xb70cb,
0xb70dc, 0xb728b, 0xb729c, 0xb744b, 0xb745c, 0xb760b,
0xb761c, 0xb77cb, 0xb77dc, 0xb798b, 0xb799c, 0xb7b4b,
0xb7b5c, 0xb7d0b, 0xb7d1c, 0xb7ecb, 0xb7edc, 0xb808b,
0xb809c, 0xb824b, 0xb825c, 0xb840b, 0xb841c, 0xb85cb,
0xb85dc, 0xb878b, 0xb879c, 0xb894b, 0xb895c, 0xb8b0b,
0xb8b1c, 0xb8ccb, 0xb8cdc, 0xb8e8b, 0xb8e9c, 0xb904b,
0xb905c, 0xb920b, 0xb921c, 0xb93cb, 0xb93dc, 0xb958b,
0xb959c, 0xb974b, 0xb975c, 0xb990b, 0xb991c, 0xb9acb,
0xb9adc, 0xb9c8b, 0xb9c9c, 0xb9e4b, 0xb9e5c, 0xba00b,
0xba01c, 0xba1cb, 0xba1dc, 0xba38b, 0xba39c, 0xba54b,
0xba55c, 0xba70b, 0xba71c, 0xba8cb, 0xba8dc, 0xbaa8b,
0xbaa9c, 0xbac4b, 0xbac5c, 0xbae0b, 0xbae1c, 0xbafcb,
0xbafdc, 0xbb18b, 0xbb19c, 0xbb34b, 0xbb35c, 0xbb50b,
0xbb51c, 0xbb6cb, 0xbb6dc, 0xbb88b, 0xbb89c, 0xbba4b,
0xbba5c, 0xbbc0b, 0xbbc1c, 0xbbdcb, 0xbbddc, 0xbbf8b,
0xbbf9c, 0xbc14b, 0xbc15c, 0xbc30b, 0xbc31c, 0xbc4cb,
0xbc4dc, 0xbc68b, 0xbc69c, 0xbc84b, 0xbc85c, 0xbca0b,
0xbca1c, 0xbcbcb, 0xbcbdc, 0xbcd8b, 0xbcd9c, 0xbcf4b,
0xbcf5c, 0xbd10b, 0xbd11c, 0xbd2cb, 0xbd2dc, 0xbd48b,
0xbd49c, 0xbd64b, 0xbd65c, 0xbd80b, 0xbd81c, 0xbd9cb,
0xbd9dc, 0xbdb8b, 0xbdb9c, 0xbdd4b, 0xbdd5c, 0xbdf0b,
0xbdf1c, 0xbe0cb, 0xbe0dc, 0xbe28b, 0xbe29c, 0xbe44b,
0xbe45c, 0xbe60b, 0xbe61c, 0xbe7cb, 0xbe7dc, 0xbe98b,
0xbe99c, 0xbeb4b, 0xbeb5c, 0xbed0b, 0xbed1c, 0xbeecb,
0xbeedc, 0xbf08b, 0xbf09c, 0xbf24b, 0xbf25c, 0xbf40b,
0xbf41c, 0xbf5cb, 0xbf5dc, 0xbf78b, 0xbf79c, 0xbf94b,
0xbf95c, 0xbfb0b, 0xbfb1c, 0xbfccb, 0xbfcdc, 0xbfe8b,
0xbfe9c, 0xc004b, 0xc005c, 0xc020b, 0xc021c, 0xc03cb,
0xc03dc, 0xc058b, 0xc059c, 0xc074b, 0xc075c, 0xc090b,
0xc091c, 0xc0acb, 0xc0adc, 0xc0c8b, 0xc0c9c, 0xc0e4b,
0xc0e5c, 0xc100b, 0xc101c, 0xc11cb, 0xc11dc, 0xc138b,
0xc139c, 0xc154b, 0xc155c, 0xc170b, 0xc171c, 0xc18cb,
0xc18dc, 0xc1a8b, 0xc1a9c, 0xc1c4b, 0xc1c5c, 0xc1e0b,
0xc1e1c, 0xc1fcb, 0xc1fdc, 0xc218b, 0xc219c, 0xc234b,
0xc235c, 0xc250b, 0xc251c, 0xc26cb, 0xc26dc, 0xc288b,
0xc289c, 0xc2a4b, 0xc2a5c, 0xc2c0b, 0xc2c1c, 0xc2dcb,
0xc2ddc, 0xc2f8b, 0xc2f9c, 0xc314b, 0xc315c, 0xc330b,
0xc331c, 0xc34cb, 0xc34dc, 0xc368b, 0xc369c, 0xc384b,
0xc385c, 0xc3a0b, 0xc3a1c, 0xc3bcb, 0xc3bdc, 0xc3d8b,
0xc3d9c, 0xc3f4b, 0xc3f5c, 0xc410b, 0xc411c, 0xc42cb,
0xc42dc, 0xc448b, 0xc449c, 0xc464b, 0xc465c, 0xc480b,
0xc481c, 0xc49cb, 0xc49dc, 0xc4b8b, 0xc4b9c, 0xc4d4b,
0xc4d5c, 0xc4f0b, 0xc4f1c, 0xc50cb, 0xc50dc, 0xc528b,
0xc529c, 0xc544b, 0xc545c, 0xc560b, 0xc561c, 0xc57cb,
0xc57dc, 0xc598b, 0xc599c, 0xc5b4b, 0xc5b5c, 0xc5d0b,
0xc5d1c, 0xc5ecb, 0xc5edc, 0xc608b, 0xc609c, 0xc624b,
0xc625c, 0xc640b, 0xc641c, 0xc65cb, 0xc65dc, 0xc678b,
0xc679c, 0xc694b, 0xc695c, 0xc6b0b, 0xc6b1c, 0xc6ccb,
0xc6cdc, 0xc6e8b, 0xc6e9c, 0xc704b, 0xc705c, 0xc720b,
0xc721c, 0xc73cb, 0xc73dc, 0xc758b, 0xc759c, 0xc774b,
0xc775c, 0xc790b, 0xc791c, 0xc7acb, 0xc7adc, 0xc7c8b,
0xc7c9c, 0xc7e4b, 0xc7e5c, 0xc800b, 0xc801c, 0xc81cb,
0xc81dc, 0xc838b, 0xc839c, 0xc854b, 0xc855c, 0xc870b,
0xc871c, 0xc88cb, 0xc88dc, 0xc8a8b, 0xc8a9c, 0xc8c4b,
0xc8c5c, 0xc8e0b, 0xc8e1c, 0xc8fcb, 0xc8fdc, 0xc918b,
0xc919c, 0xc934b, 0xc935c, 0xc950b, 0xc951c, 0xc96cb,
0xc96dc, 0xc988b, 0xc989c, 0xc9a4b, 0xc9a5c, 0xc9c0b,
0xc9c1c, 0xc9dcb, 0xc9ddc, 0xc9f8b, 0xc9f9c, 0xca14b,
0xca15c, 0xca30b, 0xca31c, 0xca4cb, 0xca4dc, 0xca68b,
0xca69c, 0xca84b, 0xca85c, 0xcaa0b, 0xcaa1c, 0xcabcb,
0xcabdc, 0xcad8b, 0xcad9c, 0xcaf4b, 0xcaf5c, 0xcb10b,
0xcb11c, 0xcb2cb, 0xcb2dc, 0xcb48b, 0xcb49c, 0xcb64b,
0xcb65c, 0xcb80b, 0xcb81c, 0xcb9cb, 0xcb9dc, 0xcbb8b,
0xcbb9c, 0xcbd4b, 0xcbd5c, 0xcbf0b, 0xcbf1c, 0xcc0cb,
0xcc0dc, 0xcc28b, 0xcc29c, 0xcc44b, 0xcc45c, 0xcc60b,
0xcc61c, 0xcc7cb, 0xcc7dc, 0xcc98b, 0xcc99c, 0xccb4b,
0xccb5c, 0xccd0b, 0xccd1c, 0xccecb, 0xccedc, 0xcd08b,
0xcd09c, 0xcd24b, 0xcd25c, 0xcd40b, 0xcd41c, 0xcd5cb,
0xcd5dc, 0xcd78b, 0xcd79c, 0xcd94b, 0xcd95c, 0xcdb0b,
0xcdb1c, 0xcdccb, 0xcdcdc, 0xcde8b, 0xcde9c, 0xce04b,
0xce05c, 0xce20b, 0xce21c, 0xce3cb, 0xce3dc, 0xce58b,
0xce59c, 0xce74b, 0xce75c, 0xce90b, 0xce91c, 0xceacb,
0xceadc, 0xcec8b, 0xcec9c, 0xcee4b, 0xcee5c, 0xcf00b,
0xcf01c, 0xcf1cb, 0xcf1dc, 0xcf38b, 0xcf39c, 0xcf54b,
0xcf55c, 0xcf70b, 0xcf71c, 0xcf8cb, 0xcf8dc, 0xcfa8b,
0xcfa9c, 0xcfc4b, 0xcfc5c, 0xcfe0b, 0xcfe1c, 0xcffcb,
0xcffdc, 0xd018b, 0xd019c, 0xd034b, 0xd035c, 0xd050b,
0xd051c, 0xd06cb, 0xd06dc, 0xd088b, 0xd089c, 0xd0a4b,
0xd0a5c, 0xd0c0b, 0xd0c1c, 0xd0dcb, 0xd0ddc, 0xd0f8b,
0xd0f9c, 0xd114b, 0xd115c, 0xd130b, 0xd131c, 0xd14cb,
0xd14dc, 0xd168b, 0xd169c, 0xd184b, 0xd185c, 0xd1a0b,
0xd1a1c, 0xd1bcb, 0xd1bdc, 0xd1d8b, 0xd1d9c, 0xd1f4b,
0xd1f5c, 0xd210b, 0xd211c, 0xd22cb, 0xd22dc, 0xd248b,
0xd249c, 0xd264b, 0xd265c, 0xd280b, 0xd281c, 0xd29cb,
0xd29dc, 0xd2b8b, 0xd2b9c, 0xd2d4b, 0xd2d5c, 0xd2f0b,
0xd2f1c, 0xd30cb, 0xd30dc, 0xd328b, 0xd329c, 0xd344b,
0xd345c, 0xd360b, 0xd361c, 0xd37cb, 0xd37dc, 0xd398b,
0xd399c, 0xd3b4b, 0xd3b5c, 0xd3d0b, 0xd3d1c, 0xd3ecb,
0xd3edc, 0xd408b, 0xd409c, 0xd424b, 0xd425c, 0xd440b,
0xd441c, 0xd45cb, 0xd45dc, 0xd478b, 0xd479c, 0xd494b,
0xd495c, 0xd4b0b, 0xd4b1c, 0xd4ccb, 0xd4cdc, 0xd4e8b,
0xd4e9c, 0xd504b, 0xd505c, 0xd520b, 0xd521c, 0xd53cb,
0xd53dc, 0xd558b, 0xd559c, 0xd574b, 0xd575c, 0xd590b,
0xd591c, 0xd5acb, 0xd5adc, 0xd5c8b, 0xd5c9c, 0xd5e4b,
0xd5e5c, 0xd600b, 0xd601c, 0xd61cb, 0xd61dc, 0xd638b,
0xd639c, 0xd654b, 0xd655c, 0xd670b, 0xd671c, 0xd68cb,
0xd68dc, 0xd6a8b, 0xd6a9c, 0xd6c4b, 0xd6c5c, 0xd6e0b,
0xd6e1c, 0xd6fcb, 0xd6fdc, 0xd718b, 0xd719c, 0xd734b,
0xd735c, 0xd750b, 0xd751c, 0xd76cb, 0xd76dc, 0xd788b,
0xd789c, 0xd7a40, 0xd7b08, 0xd7c70, 0xd7cb9, 0xd7fc0,
0xfb1e4, 0xfb1f0, 0xfe004, 0xfe100, 0xfe204, 0xfe300,
0xfeff1, 0xff000, 0xff9e4, 0xffa00, 0xfff01, 0xfffc0,
0x101fd4, 0x101fe0, 0x102e04, 0x102e10, 0x103764, 0x1037b0,
0x10a014, 0x10a040, 0x10a054, 0x10a070, 0x10a0c4, 0x10a100,
0x10a384, 0x10a3b0, 0x10a3f4, 0x10a400, 0x10ae54, 0x10ae70,
0x10d244, 0x10d280, 0x10eab4, 0x10ead0, 0x10efd4, 0x10f000,
0x10f464, 0x10f510, 0x10f824, 0x10f860, 0x110006, 0x110014,
0x110026, 0x110030, 0x110384, 0x110470, 0x110704, 0x110710,
0x110734, 0x110750, 0x1107f4, 0x110826, 0x110830, 0x110b06,
0x110b34, 0x110b76, 0x110b94, 0x110bb0, 0x110bd5, 0x110be0,
0x110c24, 0x110c30, 0x110cd5, 0x110ce0, 0x111004, 0x111030,
0x111274, 0x1112c6, 0x1112d4, 0x111350, 0x111456, 0x111470,
0x111734, 0x111740, 0x111804, 0x111826, 0x111830, 0x111b36,
0x111b64, 0x111bf6, 0x111c10, 0x111c25, 0x111c40, 0x111c94,
0x111cd0, 0x111ce6, 0x111cf4, 0x111d00, 0x1122c6, 0x1122f4,
0x112326, 0x112344, 0x112356, 0x112364, 0x112380, 0x1123e4,
0x1123f0, 0x112414, 0x112420, 0x112df4, 0x112e06, 0x112e34,
0x112eb0, 0x113004, 0x113026, 0x113040, 0x1133b4, 0x1133d0,
0x1133e4, 0x1133f6, 0x113404, 0x113416, 0x113450, 0x113476,
0x113490, 0x1134b6, 0x1134e0, 0x113574, 0x113580, 0x113626,
0x113640, 0x113664, 0x1136d0, 0x113704, 0x113750, 0x114356,
0x114384, 0x114406, 0x114424, 0x114456, 0x114464, 0x114470,
0x1145e4, 0x1145f0, 0x114b04, 0x114b16, 0x114b34, 0x114b96,
0x114ba4, 0x114bb6, 0x114bd4, 0x114be6, 0x114bf4, 0x114c16,
0x114c24, 0x114c40, 0x115af4, 0x115b06, 0x115b24, 0x115b60,
0x115b86, 0x115bc4, 0x115be6, 0x115bf4, 0x115c10, 0x115dc4,
0x115de0, 0x116306, 0x116334, 0x1163b6, 0x1163d4, 0x1163e6,
0x1163f4, 0x116410, 0x116ab4, 0x116ac6, 0x116ad4, 0x116ae6,
0x116b04, 0x116b66, 0x116b74, 0x116b80, 0x1171d4, 0x117200,
0x117224, 0x117266, 0x117274, 0x1172c0, 0x1182c6, 0x1182f4,
0x118386, 0x118394, 0x1183b0, 0x119304, 0x119316, 0x119360,
0x119376, 0x119390, 0x1193b4, 0x1193d6, 0x1193e4, 0x1193f5,
0x119406, 0x119415, 0x119426, 0x119434, 0x119440, 0x119d16,
0x119d44, 0x119d80, 0x119da4, 0x119dc6, 0x119e04, 0x119e10,
0x119e46, 0x119e50, 0x11a014, 0x11a0b0, 0x11a334, 0x11a396,
0x11a3a5, 0x11a3b4, 0x11a3f0, 0x11a474, 0x11a480, 0x11a514,
0x11a576, 0x11a594, 0x11a5c0, 0x11a845, 0x11a8a4, 0x11a976,
0x11a984, 0x11a9a0, 0x11c2f6, 0x11c304, 0x11c370, 0x11c384,
0x11c3e6, 0x11c3f4, 0x11c400, 0x11c924, 0x11ca80, 0x11ca96,
0x11caa4, 0x11cb16, 0x11cb24, 0x11cb46, 0x11cb54, 0x11cb70,
0x11d314, 0x11d370, 0x11d3a4, 0x11d3b0, 0x11d3c4, 0x11d3e0,
0x11d3f4, 0x11d465, 0x11d474, 0x11d480, 0x11d8a6, 0x11d8f0,
0x11d904, 0x11d920, 0x11d936, 0x11d954, 0x11d966, 0x11d974,
0x11d980, 0x11ef34, 0x11ef56, 0x11ef70, 0x11f004, 0x11f025,
0x11f036, 0x11f040, 0x11f346, 0x11f364, 0x11f3b0, 0x11f3e6,
0x11f404, 0x11f416, 0x11f424, 0x11f430, 0x134301, 0x134404,
0x134410, 0x134474, 0x134560, 0x16af04, 0x16af50, 0x16b304,
0x16b370, 0x16f4f4, 0x16f500, 0x16f516, 0x16f880, 0x16f8f4,
0x16f930, 0x16fe44, 0x16fe50, 0x16ff06, 0x16ff20, 0x1bc9d4,
0x1bc9f0, 0x1bca01, 0x1bca40, 0x1cf004, 0x1cf2e0, 0x1cf304,
0x1cf470, 0x1d1654, 0x1d1666, 0x1d1674, 0x1d16a0, 0x1d16d6,
0x1d16e4, 0x1d1731, 0x1d17b4, 0x1d1830, 0x1d1854, 0x1d18c0,
0x1d1aa4, 0x1d1ae0, 0x1d2424, 0x1d2450, 0x1da004, 0x1da370,
0x1da3b4, 0x1da6d0, 0x1da754, 0x1da760, 0x1da844, 0x1da850,
0x1da9b4, 0x1daa00, 0x1daa14, 0x1dab00, 0x1e0004, 0x1e0070,
0x1e0084, 0x1e0190, 0x1e01b4, 0x1e0220, 0x1e0234, 0x1e0250,
0x1e0264, 0x1e02b0, 0x1e08f4, 0x1e0900, 0x1e1304, 0x1e1370,
0x1e2ae4, 0x1e2af0, 0x1e2ec4, 0x1e2f00, 0x1e4ec4, 0x1e4f00,
0x1e8d04, 0x1e8d70, 0x1e9444, 0x1e94b0, 0x1f1e6d, 0x1f2000,
0x1f3fb4, 0x1f4000, 0xe00001, 0xe00204, 0xe00801, 0xe01004,
0xe01f01, 0xe10000,
};
inline constexpr char32_t __incb_linkers[] = {
0x094d, 0x09cd, 0x0acd, 0x0b4d, 0x0c4d, 0x0d4d,
};
enum class _InCB { _Consonant = 1, _Extend = 2 };
// Values generated by contrib/unicode/gen_std_format_width.py,
// from DerivedCoreProperties.txt from the Unicode standard.
// Entries are (code_point << 2) + property.
inline constexpr uint32_t __incb_edges[] = {
0xc02, 0xd3c, 0xd42, 0xdc0, 0x120e, 0x1220,
0x1646, 0x16f8, 0x16fe, 0x1700, 0x1706, 0x170c,
0x1712, 0x1718, 0x171e, 0x1720, 0x1842, 0x186c,
0x192e, 0x1980, 0x19c2, 0x19c4, 0x1b5a, 0x1b74,
0x1b7e, 0x1b94, 0x1b9e, 0x1ba4, 0x1baa, 0x1bb8,
0x1c46, 0x1c48, 0x1cc2, 0x1d2c, 0x1fae, 0x1fd0,
0x1ff6, 0x1ff8, 0x205a, 0x2068, 0x206e, 0x2090,
0x2096, 0x20a0, 0x20a6, 0x20b8, 0x2166, 0x2170,
0x2262, 0x2280, 0x232a, 0x2388, 0x238e, 0x2400,
0x2455, 0x24e8, 0x24f2, 0x24f4, 0x2546, 0x2554,
0x2561, 0x2580, 0x25e1, 0x2600, 0x2655, 0x26a4,
0x26a9, 0x26c4, 0x26c9, 0x26cc, 0x26d9, 0x26e8,
0x26f2, 0x26f4, 0x2771, 0x2778, 0x277d, 0x2780,
0x27c1, 0x27c8, 0x27fa, 0x27fc, 0x28f2, 0x28f4,
0x2a55, 0x2aa4, 0x2aa9, 0x2ac4, 0x2ac9, 0x2ad0,
0x2ad5, 0x2ae8, 0x2af2, 0x2af4, 0x2be5, 0x2be8,
0x2c55, 0x2ca4, 0x2ca9, 0x2cc4, 0x2cc9, 0x2cd0,
0x2cd5, 0x2ce8, 0x2cf2, 0x2cf4, 0x2d71, 0x2d78,
0x2d7d, 0x2d80, 0x2dc5, 0x2dc8, 0x3055, 0x30a4,
0x30a9, 0x30e8, 0x30f2, 0x30f4, 0x3156, 0x315c,
0x3161, 0x316c, 0x32f2, 0x32f4, 0x3455, 0x34ee,
0x34f4, 0x38e2, 0x38ec, 0x3922, 0x3930, 0x3ae2,
0x3aec, 0x3b22, 0x3b30, 0x3c62, 0x3c68, 0x3cd6,
0x3cd8, 0x3cde, 0x3ce0, 0x3ce6, 0x3ce8, 0x3dc6,
0x3dcc, 0x3dd2, 0x3dd4, 0x3dea, 0x3df8, 0x3e02,
0x3e04, 0x3e0a, 0x3e14, 0x3e1a, 0x3e20, 0x3f1a,
0x3f1c, 0x40de, 0x40e0, 0x40e6, 0x40ec, 0x4236,
0x4238, 0x4d76, 0x4d80, 0x5c52, 0x5c54, 0x5f4a,
0x5f4c, 0x5f76, 0x5f78, 0x62a6, 0x62a8, 0x64e6,
0x64f0, 0x685e, 0x6864, 0x6982, 0x6984, 0x69d6,
0x69f4, 0x69fe, 0x6a00, 0x6ac2, 0x6af8, 0x6afe,
0x6b3c, 0x6cd2, 0x6cd4, 0x6dae, 0x6dd0, 0x6eae,
0x6eb0, 0x6f9a, 0x6f9c, 0x70de, 0x70e0, 0x7342,
0x734c, 0x7352, 0x7384, 0x738a, 0x73a4, 0x73b6,
0x73b8, 0x73d2, 0x73d4, 0x73e2, 0x73e8, 0x7702,
0x7800, 0x8036, 0x8038, 0x8342, 0x8374, 0x8386,
0x8388, 0x8396, 0x83c4, 0xb3be, 0xb3c8, 0xb5fe,
0xb600, 0xb782, 0xb800, 0xc0aa, 0xc0c0, 0xc266,
0xc26c, 0x299be, 0x299c0, 0x299d2, 0x299f8, 0x29a7a,
0x29a80, 0x29bc2, 0x29bc8, 0x2a0b2, 0x2a0b4, 0x2a382,
0x2a3c8, 0x2a4ae, 0x2a4b8, 0x2a6ce, 0x2a6d0, 0x2aac2,
0x2aac4, 0x2aaca, 0x2aad4, 0x2aade, 0x2aae4, 0x2aafa,
0x2ab00, 0x2ab06, 0x2ab08, 0x2abda, 0x2abdc, 0x2afb6,
0x2afb8, 0x3ec7a, 0x3ec7c, 0x3f882, 0x3f8c0, 0x407f6,
0x407f8, 0x40b82, 0x40b84, 0x40dda, 0x40dec, 0x42836,
0x42838, 0x4283e, 0x42840, 0x428e2, 0x428ec, 0x428fe,
0x42900, 0x42b96, 0x42b9c, 0x43492, 0x434a0, 0x43aae,
0x43ab4, 0x43bf6, 0x43c00, 0x43d1a, 0x43d44, 0x43e0a,
0x43e18, 0x441c2, 0x441c4, 0x441fe, 0x44200, 0x442ea,
0x442ec, 0x44402, 0x4440c, 0x444ce, 0x444d4, 0x445ce,
0x445d0, 0x4472a, 0x4472c, 0x448da, 0x448dc, 0x44ba6,
0x44bac, 0x44cee, 0x44cf4, 0x44d9a, 0x44db4, 0x44dc2,
0x44dd4, 0x4511a, 0x4511c, 0x4517a, 0x4517c, 0x4530e,
0x45310, 0x45702, 0x45704, 0x45ade, 0x45ae0, 0x45cae,
0x45cb0, 0x460ea, 0x460ec, 0x464fa, 0x464fc, 0x4650e,
0x46510, 0x468d2, 0x468d4, 0x4691e, 0x46920, 0x46a66,
0x46a68, 0x4750a, 0x4750c, 0x47512, 0x47518, 0x4765e,
0x47660, 0x47d0a, 0x47d0c, 0x5abc2, 0x5abd4, 0x5acc2,
0x5acdc, 0x6f27a, 0x6f27c, 0x74596, 0x74598, 0x7459e,
0x745a8, 0x745ba, 0x745cc, 0x745ee, 0x7460c, 0x74616,
0x74630, 0x746aa, 0x746b8, 0x7490a, 0x74914, 0x78002,
0x7801c, 0x78022, 0x78064, 0x7806e, 0x78088, 0x7808e,
0x78094, 0x7809a, 0x780ac, 0x7823e, 0x78240, 0x784c2,
0x784dc, 0x78aba, 0x78abc, 0x78bb2, 0x78bc0, 0x793b2,
0x793c0, 0x7a342, 0x7a35c, 0x7a512, 0x7a52c,
};
// Table generated by contrib/unicode/gen_std_format_width.py,
// from emoji-data.txt from the Unicode standard.
inline constexpr char32_t __xpicto_edges[] = {
0xa9, 0xaa, 0xae, 0xaf, 0x203c, 0x203d, 0x2049, 0x204a,
0x2122, 0x2123, 0x2139, 0x213a, 0x2194, 0x219a, 0x21a9, 0x21ab,
0x231a, 0x231c, 0x2328, 0x2329, 0x2388, 0x2389, 0x23cf, 0x23d0,
0x23e9, 0x23f4, 0x23f8, 0x23fb, 0x24c2, 0x24c3, 0x25aa, 0x25ac,
0x25b6, 0x25b7, 0x25c0, 0x25c1, 0x25fb, 0x25ff, 0x2600, 0x2606,
0x2607, 0x2613, 0x2614, 0x2686, 0x2690, 0x2706, 0x2708, 0x2713,
0x2714, 0x2715, 0x2716, 0x2717, 0x271d, 0x271e, 0x2721, 0x2722,
0x2728, 0x2729, 0x2733, 0x2735, 0x2744, 0x2745, 0x2747, 0x2748,
0x274c, 0x274d, 0x274e, 0x274f, 0x2753, 0x2756, 0x2757, 0x2758,
0x2763, 0x2768, 0x2795, 0x2798, 0x27a1, 0x27a2, 0x27b0, 0x27b1,
0x27bf, 0x27c0, 0x2934, 0x2936, 0x2b05, 0x2b08, 0x2b1b, 0x2b1d,
0x2b50, 0x2b51, 0x2b55, 0x2b56, 0x3030, 0x3031, 0x303d, 0x303e,
0x3297, 0x3298, 0x3299, 0x329a, 0x1f000, 0x1f100, 0x1f10d, 0x1f110,
0x1f12f, 0x1f130, 0x1f16c, 0x1f172, 0x1f17e, 0x1f180, 0x1f18e, 0x1f18f,
0x1f191, 0x1f19b, 0x1f1ad, 0x1f1e6, 0x1f201, 0x1f210, 0x1f21a, 0x1f21b,
0x1f22f, 0x1f230, 0x1f232, 0x1f23b, 0x1f23c, 0x1f240, 0x1f249, 0x1f3fb,
0x1f400, 0x1f53e, 0x1f546, 0x1f650, 0x1f680, 0x1f700, 0x1f774, 0x1f780,
0x1f7d5, 0x1f800, 0x1f80c, 0x1f810, 0x1f848, 0x1f850, 0x1f85a, 0x1f860,
0x1f888, 0x1f890, 0x1f8ae, 0x1f900, 0x1f90c, 0x1f93b, 0x1f93c, 0x1f946,
0x1f947, 0x1fb00, 0x1fc00, 0x1fffe,
};
#undef _GLIBCXX_GET_UNICODE_DATA
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,468 @@
// Class template uniform_int_distribution -*- C++ -*-
// Copyright (C) 2009-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/**
* @file bits/uniform_int_dist.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{random}
*/
#ifndef _GLIBCXX_BITS_UNIFORM_INT_DIST_H
#define _GLIBCXX_BITS_UNIFORM_INT_DIST_H
#include <type_traits>
#include <ext/numeric_traits.h>
#if __cplusplus > 201703L
# include <concepts>
#endif
#include <bits/concept_check.h> // __glibcxx_function_requires
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
#ifdef __cpp_lib_concepts
/// Requirements for a uniform random bit generator.
/**
* @ingroup random_distributions_uniform
* @headerfile random
* @since C++20
*/
template<typename _Gen>
concept uniform_random_bit_generator
= invocable<_Gen&> && unsigned_integral<invoke_result_t<_Gen&>>
&& requires
{
{ _Gen::min() } -> same_as<invoke_result_t<_Gen&>>;
{ _Gen::max() } -> same_as<invoke_result_t<_Gen&>>;
requires bool_constant<(_Gen::min() < _Gen::max())>::value;
};
#endif
/// @cond undocumented
namespace __detail
{
// Determine whether number is a power of two.
// This is true for zero, which is OK because we want _Power_of_2(n+1)
// to be true if n==numeric_limits<_Tp>::max() and so n+1 wraps around.
template<typename _Tp>
constexpr bool
_Power_of_2(_Tp __x)
{
return ((__x - 1) & __x) == 0;
}
}
/// @endcond
/**
* @brief Uniform discrete distribution for random numbers.
* A discrete random distribution on the range @f$[min, max]@f$ with equal
* probability throughout the range.
*
* @ingroup random_distributions_uniform
* @headerfile random
* @since C++11
*/
template<typename _IntType = int>
class uniform_int_distribution
{
static_assert(std::is_integral<_IntType>::value,
"template argument must be an integral type");
public:
/** The type of the range of the distribution. */
typedef _IntType result_type;
/** Parameter type. */
struct param_type
{
typedef uniform_int_distribution<_IntType> distribution_type;
param_type() : param_type(0) { }
explicit
param_type(_IntType __a,
_IntType __b = __gnu_cxx::__int_traits<_IntType>::__max)
: _M_a(__a), _M_b(__b)
{
__glibcxx_assert(_M_a <= _M_b);
}
result_type
a() const
{ return _M_a; }
result_type
b() const
{ return _M_b; }
friend bool
operator==(const param_type& __p1, const param_type& __p2)
{ return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; }
friend bool
operator!=(const param_type& __p1, const param_type& __p2)
{ return !(__p1 == __p2); }
private:
_IntType _M_a;
_IntType _M_b;
};
public:
/**
* @brief Constructs a uniform distribution object.
*/
uniform_int_distribution() : uniform_int_distribution(0) { }
/**
* @brief Constructs a uniform distribution object.
*/
explicit
uniform_int_distribution(_IntType __a,
_IntType __b
= __gnu_cxx::__int_traits<_IntType>::__max)
: _M_param(__a, __b)
{ }
explicit
uniform_int_distribution(const param_type& __p)
: _M_param(__p)
{ }
/**
* @brief Resets the distribution state.
*
* Does nothing for the uniform integer distribution.
*/
void
reset() { }
result_type
a() const
{ return _M_param.a(); }
result_type
b() const
{ return _M_param.b(); }
/**
* @brief Returns the parameter set of the distribution.
*/
param_type
param() const
{ return _M_param; }
/**
* @brief Sets the parameter set of the distribution.
* @param __param The new parameter set of the distribution.
*/
void
param(const param_type& __param)
{ _M_param = __param; }
/**
* @brief Returns the inclusive lower bound of the distribution range.
*/
result_type
min() const
{ return this->a(); }
/**
* @brief Returns the inclusive upper bound of the distribution range.
*/
result_type
max() const
{ return this->b(); }
/**
* @brief Generating functions.
*/
template<typename _UniformRandomBitGenerator>
result_type
operator()(_UniformRandomBitGenerator& __urng)
{ return this->operator()(__urng, _M_param); }
template<typename _UniformRandomBitGenerator>
result_type
operator()(_UniformRandomBitGenerator& __urng,
const param_type& __p);
template<typename _ForwardIterator,
typename _UniformRandomBitGenerator>
void
__generate(_ForwardIterator __f, _ForwardIterator __t,
_UniformRandomBitGenerator& __urng)
{ this->__generate(__f, __t, __urng, _M_param); }
template<typename _ForwardIterator,
typename _UniformRandomBitGenerator>
void
__generate(_ForwardIterator __f, _ForwardIterator __t,
_UniformRandomBitGenerator& __urng,
const param_type& __p)
{ this->__generate_impl(__f, __t, __urng, __p); }
template<typename _UniformRandomBitGenerator>
void
__generate(result_type* __f, result_type* __t,
_UniformRandomBitGenerator& __urng,
const param_type& __p)
{ this->__generate_impl(__f, __t, __urng, __p); }
/**
* @brief Return true if two uniform integer distributions have
* the same parameters.
*/
friend bool
operator==(const uniform_int_distribution& __d1,
const uniform_int_distribution& __d2)
{ return __d1._M_param == __d2._M_param; }
private:
template<typename _ForwardIterator,
typename _UniformRandomBitGenerator>
void
__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
_UniformRandomBitGenerator& __urng,
const param_type& __p);
param_type _M_param;
// Lemire's nearly divisionless algorithm.
// Returns an unbiased random number from __g downscaled to [0,__range)
// using an unsigned type _Wp twice as wide as unsigned type _Up.
template<typename _Wp, typename _Urbg, typename _Up>
static _Up
_S_nd(_Urbg& __g, _Up __range)
{
using _Up_traits = __gnu_cxx::__int_traits<_Up>;
using _Wp_traits = __gnu_cxx::__int_traits<_Wp>;
static_assert(!_Up_traits::__is_signed, "U must be unsigned");
static_assert(!_Wp_traits::__is_signed, "W must be unsigned");
static_assert(_Wp_traits::__digits == (2 * _Up_traits::__digits),
"W must be twice as wide as U");
// reference: Fast Random Integer Generation in an Interval
// ACM Transactions on Modeling and Computer Simulation 29 (1), 2019
// https://arxiv.org/abs/1805.10941
_Wp __product = _Wp(__g()) * _Wp(__range);
_Up __low = _Up(__product);
if (__low < __range)
{
_Up __threshold = -__range % __range;
while (__low < __threshold)
{
__product = _Wp(__g()) * _Wp(__range);
__low = _Up(__product);
}
}
return __product >> _Up_traits::__digits;
}
};
template<typename _IntType>
template<typename _UniformRandomBitGenerator>
typename uniform_int_distribution<_IntType>::result_type
uniform_int_distribution<_IntType>::
operator()(_UniformRandomBitGenerator& __urng,
const param_type& __param)
{
typedef typename _UniformRandomBitGenerator::result_type _Gresult_type;
typedef typename make_unsigned<result_type>::type __utype;
typedef typename common_type<_Gresult_type, __utype>::type __uctype;
constexpr __uctype __urngmin = _UniformRandomBitGenerator::min();
constexpr __uctype __urngmax = _UniformRandomBitGenerator::max();
static_assert( __urngmin < __urngmax,
"Uniform random bit generator must define min() < max()");
constexpr __uctype __urngrange = __urngmax - __urngmin;
const __uctype __urange
= __uctype(__param.b()) - __uctype(__param.a());
__uctype __ret;
if (__urngrange > __urange)
{
// downscaling
const __uctype __uerange = __urange + 1; // __urange can be zero
#if defined __UINT64_TYPE__ && defined __UINT32_TYPE__
#if __SIZEOF_INT128__
if _GLIBCXX17_CONSTEXPR (__urngrange == __UINT64_MAX__)
{
// __urng produces values that use exactly 64-bits,
// so use 128-bit integers to downscale to desired range.
__UINT64_TYPE__ __u64erange = __uerange;
__ret = __extension__ _S_nd<unsigned __int128>(__urng,
__u64erange);
}
else
#endif
if _GLIBCXX17_CONSTEXPR (__urngrange == __UINT32_MAX__)
{
// __urng produces values that use exactly 32-bits,
// so use 64-bit integers to downscale to desired range.
__UINT32_TYPE__ __u32erange = __uerange;
__ret = _S_nd<__UINT64_TYPE__>(__urng, __u32erange);
}
else
#endif
{
// fallback case (2 divisions)
const __uctype __scaling = __urngrange / __uerange;
const __uctype __past = __uerange * __scaling;
do
__ret = __uctype(__urng()) - __urngmin;
while (__ret >= __past);
__ret /= __scaling;
}
}
else if (__urngrange < __urange)
{
// upscaling
/*
Note that every value in [0, urange]
can be written uniquely as
(urngrange + 1) * high + low
where
high in [0, urange / (urngrange + 1)]
and
low in [0, urngrange].
*/
__uctype __tmp; // wraparound control
do
{
const __uctype __uerngrange = __urngrange + 1;
__tmp = (__uerngrange * operator()
(__urng, param_type(0, __urange / __uerngrange)));
__ret = __tmp + (__uctype(__urng()) - __urngmin);
}
while (__ret > __urange || __ret < __tmp);
}
else
__ret = __uctype(__urng()) - __urngmin;
return __ret + __param.a();
}
template<typename _IntType>
template<typename _ForwardIterator,
typename _UniformRandomBitGenerator>
void
uniform_int_distribution<_IntType>::
__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
_UniformRandomBitGenerator& __urng,
const param_type& __param)
{
__glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
typedef typename _UniformRandomBitGenerator::result_type _Gresult_type;
typedef typename make_unsigned<result_type>::type __utype;
typedef typename common_type<_Gresult_type, __utype>::type __uctype;
static_assert( __urng.min() < __urng.max(),
"Uniform random bit generator must define min() < max()");
constexpr __uctype __urngmin = __urng.min();
constexpr __uctype __urngmax = __urng.max();
constexpr __uctype __urngrange = __urngmax - __urngmin;
const __uctype __urange
= __uctype(__param.b()) - __uctype(__param.a());
__uctype __ret;
if (__urngrange > __urange)
{
if (__detail::_Power_of_2(__urngrange + 1)
&& __detail::_Power_of_2(__urange + 1))
{
while (__f != __t)
{
__ret = __uctype(__urng()) - __urngmin;
*__f++ = (__ret & __urange) + __param.a();
}
}
else
{
// downscaling
const __uctype __uerange = __urange + 1; // __urange can be zero
const __uctype __scaling = __urngrange / __uerange;
const __uctype __past = __uerange * __scaling;
while (__f != __t)
{
do
__ret = __uctype(__urng()) - __urngmin;
while (__ret >= __past);
*__f++ = __ret / __scaling + __param.a();
}
}
}
else if (__urngrange < __urange)
{
// upscaling
/*
Note that every value in [0, urange]
can be written uniquely as
(urngrange + 1) * high + low
where
high in [0, urange / (urngrange + 1)]
and
low in [0, urngrange].
*/
__uctype __tmp; // wraparound control
while (__f != __t)
{
do
{
constexpr __uctype __uerngrange = __urngrange + 1;
__tmp = (__uerngrange * operator()
(__urng, param_type(0, __urange / __uerngrange)));
__ret = __tmp + (__uctype(__urng()) - __urngmin);
}
while (__ret > __urange || __ret < __tmp);
*__f++ = __ret;
}
}
else
while (__f != __t)
*__f++ = __uctype(__urng()) - __urngmin + __param.a();
}
// operator!= and operator<< and operator>> are defined in <bits/random.h>
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,202 @@
// Uses-allocator Construction -*- C++ -*-
// Copyright (C) 2010-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file include/bits/uses_allocator_args.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{memory}
*/
#ifndef _USES_ALLOCATOR_H
#define _USES_ALLOCATOR_H 1
#if __cplusplus < 201103L
# include <bits/c++0x_warning.h>
#else
#include <type_traits>
#include <bits/move.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/// @cond undocumented
// This is used for std::experimental::erased_type from Library Fundamentals.
struct __erased_type { };
// This also supports the "type-erased allocator" protocol from the
// Library Fundamentals TS, where allocator_type is erased_type.
// The second condition will always be false for types not using the TS.
template<typename _Alloc, typename _Tp>
using __is_erased_or_convertible
= __or_<is_convertible<_Alloc, _Tp>, is_same<_Tp, __erased_type>>;
/// [allocator.tag]
struct allocator_arg_t { explicit allocator_arg_t() = default; };
_GLIBCXX17_INLINE constexpr allocator_arg_t allocator_arg =
allocator_arg_t();
template<typename _Tp, typename _Alloc, typename = __void_t<>>
struct __uses_allocator_helper
: false_type { };
template<typename _Tp, typename _Alloc>
struct __uses_allocator_helper<_Tp, _Alloc,
__void_t<typename _Tp::allocator_type>>
: __is_erased_or_convertible<_Alloc, typename _Tp::allocator_type>::type
{ };
/// [allocator.uses.trait]
template<typename _Tp, typename _Alloc>
struct uses_allocator
: __uses_allocator_helper<_Tp, _Alloc>::type
{ };
struct __uses_alloc_base { };
struct __uses_alloc0 : __uses_alloc_base
{
struct _Sink { void _GLIBCXX20_CONSTEXPR operator=(const void*) { } } _M_a;
};
template<typename _Alloc>
struct __uses_alloc1 : __uses_alloc_base { const _Alloc* _M_a; };
template<typename _Alloc>
struct __uses_alloc2 : __uses_alloc_base { const _Alloc* _M_a; };
template<bool, typename _Tp, typename _Alloc, typename... _Args>
struct __uses_alloc;
template<typename _Tp, typename _Alloc, typename... _Args>
struct __uses_alloc<true, _Tp, _Alloc, _Args...>
: __conditional_t<
is_constructible<_Tp, allocator_arg_t, const _Alloc&, _Args...>::value,
__uses_alloc1<_Alloc>,
__uses_alloc2<_Alloc>>
{
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 2586. Wrong value category used in scoped_allocator_adaptor::construct
static_assert(__or_<
is_constructible<_Tp, allocator_arg_t, const _Alloc&, _Args...>,
is_constructible<_Tp, _Args..., const _Alloc&>>::value,
"construction with an allocator must be possible"
" if uses_allocator is true");
};
template<typename _Tp, typename _Alloc, typename... _Args>
struct __uses_alloc<false, _Tp, _Alloc, _Args...>
: __uses_alloc0 { };
template<typename _Tp, typename _Alloc, typename... _Args>
using __uses_alloc_t =
__uses_alloc<uses_allocator<_Tp, _Alloc>::value, _Tp, _Alloc, _Args...>;
template<typename _Tp, typename _Alloc, typename... _Args>
_GLIBCXX20_CONSTEXPR
inline __uses_alloc_t<_Tp, _Alloc, _Args...>
__use_alloc(const _Alloc& __a)
{
__uses_alloc_t<_Tp, _Alloc, _Args...> __ret;
__ret._M_a = std::__addressof(__a);
return __ret;
}
template<typename _Tp, typename _Alloc, typename... _Args>
void
__use_alloc(const _Alloc&&) = delete;
#if __cplusplus > 201402L
template <typename _Tp, typename _Alloc>
inline constexpr bool uses_allocator_v =
uses_allocator<_Tp, _Alloc>::value;
#endif // C++17
template<template<typename...> class _Predicate,
typename _Tp, typename _Alloc, typename... _Args>
struct __is_uses_allocator_predicate
: __conditional_t<uses_allocator<_Tp, _Alloc>::value,
__or_<_Predicate<_Tp, allocator_arg_t, _Alloc, _Args...>,
_Predicate<_Tp, _Args..., _Alloc>>,
_Predicate<_Tp, _Args...>> { };
template<typename _Tp, typename _Alloc, typename... _Args>
struct __is_uses_allocator_constructible
: __is_uses_allocator_predicate<is_constructible, _Tp, _Alloc, _Args...>
{ };
#if __cplusplus >= 201402L
template<typename _Tp, typename _Alloc, typename... _Args>
_GLIBCXX17_INLINE constexpr bool __is_uses_allocator_constructible_v =
__is_uses_allocator_constructible<_Tp, _Alloc, _Args...>::value;
#endif // C++14
template<typename _Tp, typename _Alloc, typename... _Args>
struct __is_nothrow_uses_allocator_constructible
: __is_uses_allocator_predicate<is_nothrow_constructible,
_Tp, _Alloc, _Args...>
{ };
#if __cplusplus >= 201402L
template<typename _Tp, typename _Alloc, typename... _Args>
_GLIBCXX17_INLINE constexpr bool
__is_nothrow_uses_allocator_constructible_v =
__is_nothrow_uses_allocator_constructible<_Tp, _Alloc, _Args...>::value;
#endif // C++14
template<typename _Tp, typename... _Args>
void __uses_allocator_construct_impl(__uses_alloc0, _Tp* __ptr,
_Args&&... __args)
{ ::new ((void*)__ptr) _Tp(std::forward<_Args>(__args)...); }
template<typename _Tp, typename _Alloc, typename... _Args>
void __uses_allocator_construct_impl(__uses_alloc1<_Alloc> __a, _Tp* __ptr,
_Args&&... __args)
{
::new ((void*)__ptr) _Tp(allocator_arg, *__a._M_a,
std::forward<_Args>(__args)...);
}
template<typename _Tp, typename _Alloc, typename... _Args>
void __uses_allocator_construct_impl(__uses_alloc2<_Alloc> __a, _Tp* __ptr,
_Args&&... __args)
{ ::new ((void*)__ptr) _Tp(std::forward<_Args>(__args)..., *__a._M_a); }
template<typename _Tp, typename _Alloc, typename... _Args>
void __uses_allocator_construct(const _Alloc& __a, _Tp* __ptr,
_Args&&... __args)
{
std::__uses_allocator_construct_impl(
std::__use_alloc<_Tp, _Alloc, _Args...>(__a), __ptr,
std::forward<_Args>(__args)...);
}
/// @endcond
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif
#endif
@@ -0,0 +1,248 @@
// Utility functions for uses-allocator construction -*- C++ -*-
// Copyright (C) 2019-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file include/bits/uses_allocator_args.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{memory}
*/
#ifndef _USES_ALLOCATOR_ARGS
#define _USES_ALLOCATOR_ARGS 1
#pragma GCC system_header
#include <bits/version.h>
#ifdef __glibcxx_make_obj_using_allocator // C++ >= 20 && concepts
#include <new> // for placement operator new
#include <tuple> // for tuple, make_tuple, make_from_tuple
#include <bits/stl_construct.h> // construct_at
#include <bits/stl_pair.h> // pair
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Tp>
concept _Std_pair = __is_pair<remove_cv_t<_Tp>>;
/** @addtogroup allocators
* @{
*/
template<typename _Tp, typename _Alloc, typename... _Args>
constexpr auto
uses_allocator_construction_args(const _Alloc& __a,
_Args&&... __args) noexcept
requires (! _Std_pair<_Tp>)
{
if constexpr (uses_allocator_v<remove_cv_t<_Tp>, _Alloc>)
{
if constexpr (is_constructible_v<_Tp, allocator_arg_t,
const _Alloc&, _Args...>)
{
return tuple<allocator_arg_t, const _Alloc&, _Args&&...>(
allocator_arg, __a, std::forward<_Args>(__args)...);
}
else
{
static_assert(is_constructible_v<_Tp, _Args..., const _Alloc&>,
"construction with an allocator must be possible"
" if uses_allocator is true");
return tuple<_Args&&..., const _Alloc&>(
std::forward<_Args>(__args)..., __a);
}
}
else
{
static_assert(is_constructible_v<_Tp, _Args...>);
return tuple<_Args&&...>(std::forward<_Args>(__args)...);
}
}
template<_Std_pair _Tp, typename _Alloc, typename _Tuple1, typename _Tuple2>
constexpr auto
uses_allocator_construction_args(const _Alloc& __a, piecewise_construct_t,
_Tuple1&& __x, _Tuple2&& __y) noexcept;
template<_Std_pair _Tp, typename _Alloc>
constexpr auto
uses_allocator_construction_args(const _Alloc&) noexcept;
template<_Std_pair _Tp, typename _Alloc, typename _Up, typename _Vp>
constexpr auto
uses_allocator_construction_args(const _Alloc&, _Up&&, _Vp&&) noexcept;
template<_Std_pair _Tp, typename _Alloc, typename _Up, typename _Vp>
constexpr auto
uses_allocator_construction_args(const _Alloc&,
const pair<_Up, _Vp>&) noexcept;
template<_Std_pair _Tp, typename _Alloc, typename _Up, typename _Vp>
constexpr auto
uses_allocator_construction_args(const _Alloc&, pair<_Up, _Vp>&&) noexcept;
#if __cplusplus > 202002L
template<_Std_pair _Tp, typename _Alloc, typename _Up, typename _Vp>
constexpr auto
uses_allocator_construction_args(const _Alloc&,
pair<_Up, _Vp>&) noexcept;
template<_Std_pair _Tp, typename _Alloc, typename _Up, typename _Vp>
constexpr auto
uses_allocator_construction_args(const _Alloc&, const pair<_Up, _Vp>&&) noexcept;
#endif // C++23
template<_Std_pair _Tp, typename _Alloc, typename _Tuple1, typename _Tuple2>
constexpr auto
uses_allocator_construction_args(const _Alloc& __a, piecewise_construct_t,
_Tuple1&& __x, _Tuple2&& __y) noexcept
{
using _Tp1 = typename _Tp::first_type;
using _Tp2 = typename _Tp::second_type;
return std::make_tuple(piecewise_construct,
std::apply([&__a](auto&&... __args1) {
return std::uses_allocator_construction_args<_Tp1>(
__a, std::forward<decltype(__args1)>(__args1)...);
}, std::forward<_Tuple1>(__x)),
std::apply([&__a](auto&&... __args2) {
return std::uses_allocator_construction_args<_Tp2>(
__a, std::forward<decltype(__args2)>(__args2)...);
}, std::forward<_Tuple2>(__y)));
}
template<_Std_pair _Tp, typename _Alloc>
constexpr auto
uses_allocator_construction_args(const _Alloc& __a) noexcept
{
using _Tp1 = typename _Tp::first_type;
using _Tp2 = typename _Tp::second_type;
return std::make_tuple(piecewise_construct,
std::uses_allocator_construction_args<_Tp1>(__a),
std::uses_allocator_construction_args<_Tp2>(__a));
}
template<_Std_pair _Tp, typename _Alloc, typename _Up, typename _Vp>
constexpr auto
uses_allocator_construction_args(const _Alloc& __a, _Up&& __u, _Vp&& __v)
noexcept
{
using _Tp1 = typename _Tp::first_type;
using _Tp2 = typename _Tp::second_type;
return std::make_tuple(piecewise_construct,
std::uses_allocator_construction_args<_Tp1>(__a,
std::forward<_Up>(__u)),
std::uses_allocator_construction_args<_Tp2>(__a,
std::forward<_Vp>(__v)));
}
template<_Std_pair _Tp, typename _Alloc, typename _Up, typename _Vp>
constexpr auto
uses_allocator_construction_args(const _Alloc& __a,
const pair<_Up, _Vp>& __pr) noexcept
{
using _Tp1 = typename _Tp::first_type;
using _Tp2 = typename _Tp::second_type;
return std::make_tuple(piecewise_construct,
std::uses_allocator_construction_args<_Tp1>(__a, __pr.first),
std::uses_allocator_construction_args<_Tp2>(__a, __pr.second));
}
template<_Std_pair _Tp, typename _Alloc, typename _Up, typename _Vp>
constexpr auto
uses_allocator_construction_args(const _Alloc& __a,
pair<_Up, _Vp>&& __pr) noexcept
{
using _Tp1 = typename _Tp::first_type;
using _Tp2 = typename _Tp::second_type;
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 3527. uses_allocator_construction_args handles rvalue pairs
// of rvalue references incorrectly
return std::make_tuple(piecewise_construct,
std::uses_allocator_construction_args<_Tp1>(__a,
std::get<0>(std::move(__pr))),
std::uses_allocator_construction_args<_Tp2>(__a,
std::get<1>(std::move(__pr))));
}
#if __cplusplus > 202002L
template<_Std_pair _Tp, typename _Alloc, typename _Up, typename _Vp>
constexpr auto
uses_allocator_construction_args(const _Alloc& __a,
pair<_Up, _Vp>& __pr) noexcept
{
using _Tp1 = typename _Tp::first_type;
using _Tp2 = typename _Tp::second_type;
return std::make_tuple(piecewise_construct,
std::uses_allocator_construction_args<_Tp1>(__a, __pr.first),
std::uses_allocator_construction_args<_Tp2>(__a, __pr.second));
}
template<_Std_pair _Tp, typename _Alloc, typename _Up, typename _Vp>
constexpr auto
uses_allocator_construction_args(const _Alloc& __a,
const pair<_Up, _Vp>&& __pr) noexcept
{
using _Tp1 = typename _Tp::first_type;
using _Tp2 = typename _Tp::second_type;
return std::make_tuple(piecewise_construct,
std::uses_allocator_construction_args<_Tp1>(__a,
std::get<0>(std::move(__pr))),
std::uses_allocator_construction_args<_Tp2>(__a,
std::get<1>(std::move(__pr))));
}
#endif // C++23
template<typename _Tp, typename _Alloc, typename... _Args>
constexpr _Tp
make_obj_using_allocator(const _Alloc& __a, _Args&&... __args)
{
return std::make_from_tuple<_Tp>(
std::uses_allocator_construction_args<_Tp>(__a,
std::forward<_Args>(__args)...));
}
template<typename _Tp, typename _Alloc, typename... _Args>
constexpr _Tp*
uninitialized_construct_using_allocator(_Tp* __p, const _Alloc& __a,
_Args&&... __args)
{
return std::apply([&](auto&&... __xs) {
return std::construct_at(__p, std::forward<decltype(__xs)>(__xs)...);
}, std::uses_allocator_construction_args<_Tp>(__a,
std::forward<_Args>(__args)...));
}
/// @}
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif // __glibcxx_make_obj_using_allocator
#endif // _USES_ALLOCATOR_ARGS
+287
View File
@@ -0,0 +1,287 @@
// Utilities used throughout the library -*- C++ -*-
// Copyright (C) 2004-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file include/bits/utility.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{utility}
*
* This file contains the parts of `<utility>` needed by other headers,
* so they don't need to include the whole of `<utility>`.
*/
#ifndef _GLIBCXX_UTILITY_H
#define _GLIBCXX_UTILITY_H 1
#pragma GCC system_header
#if __cplusplus >= 201103L
#include <type_traits>
#include <bits/move.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/// Finds the size of a given tuple type.
template<typename _Tp>
struct tuple_size;
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 2313. tuple_size should always derive from integral_constant<size_t, N>
// 2770. tuple_size<const T> specialization is not SFINAE compatible
template<typename _Tp,
typename _Up = typename remove_cv<_Tp>::type,
typename = typename enable_if<is_same<_Tp, _Up>::value>::type,
size_t = tuple_size<_Tp>::value>
using __enable_if_has_tuple_size = _Tp;
template<typename _Tp>
struct tuple_size<const __enable_if_has_tuple_size<_Tp>>
: public tuple_size<_Tp> { };
template<typename _Tp>
struct tuple_size<volatile __enable_if_has_tuple_size<_Tp>>
: public tuple_size<_Tp> { };
template<typename _Tp>
struct tuple_size<const volatile __enable_if_has_tuple_size<_Tp>>
: public tuple_size<_Tp> { };
#if __cplusplus >= 201703L
template<typename _Tp>
inline constexpr size_t tuple_size_v = tuple_size<_Tp>::value;
#endif
/// Gives the type of the ith element of a given tuple type.
template<size_t __i, typename _Tp>
struct tuple_element;
// Duplicate of C++14's tuple_element_t for internal use in C++11 mode
template<size_t __i, typename _Tp>
using __tuple_element_t = typename tuple_element<__i, _Tp>::type;
template<size_t __i, typename _Tp>
struct tuple_element<__i, const _Tp>
{
using type = const __tuple_element_t<__i, _Tp>;
};
template<size_t __i, typename _Tp>
struct tuple_element<__i, volatile _Tp>
{
using type = volatile __tuple_element_t<__i, _Tp>;
};
template<size_t __i, typename _Tp>
struct tuple_element<__i, const volatile _Tp>
{
using type = const volatile __tuple_element_t<__i, _Tp>;
};
#if __cplusplus >= 201402L
// Return the index of _Tp in _Types, if it occurs exactly once.
// Otherwise, return sizeof...(_Types).
template<typename _Tp, typename... _Types>
constexpr size_t
__find_uniq_type_in_pack()
{
constexpr size_t __sz = sizeof...(_Types);
constexpr bool __found[__sz] = { __is_same(_Tp, _Types) ... };
size_t __n = __sz;
for (size_t __i = 0; __i < __sz; ++__i)
{
if (__found[__i])
{
if (__n < __sz) // more than one _Tp found
return __sz;
__n = __i;
}
}
return __n;
}
#endif // C++14
// The standard says this macro and alias template should be in <tuple> but we
// define them here, to be available in <array>, <utility> and <ranges> too.
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 3378. tuple_size_v/tuple_element_t should be available when
// tuple_size/tuple_element are
#ifdef __glibcxx_tuple_element_t // C++ >= 14
template<size_t __i, typename _Tp>
using tuple_element_t = typename tuple_element<__i, _Tp>::type;
#endif
// Stores a tuple of indices. Used by tuple and pair, and by bind() to
// extract the elements in a tuple.
template<size_t... _Indexes> struct _Index_tuple { };
// Builds an _Index_tuple<0, 1, 2, ..., _Num-1>.
template<size_t _Num>
struct _Build_index_tuple
{
#if __has_builtin(__make_integer_seq)
template<typename, size_t... _Indices>
using _IdxTuple = _Index_tuple<_Indices...>;
// Clang defines __make_integer_seq for this purpose.
using __type = __make_integer_seq<_IdxTuple, size_t, _Num>;
#else
// For GCC and other compilers, use __integer_pack instead.
using __type = _Index_tuple<__integer_pack(_Num)...>;
#endif
};
#ifdef __glibcxx_integer_sequence // C++ >= 14
/// Class template integer_sequence
template<typename _Tp, _Tp... _Idx>
struct integer_sequence
{
#if __cplusplus >= 202002L
static_assert(is_integral_v<_Tp>);
#endif
typedef _Tp value_type;
static constexpr size_t size() noexcept { return sizeof...(_Idx); }
};
/// Alias template make_integer_sequence
template<typename _Tp, _Tp _Num>
using make_integer_sequence
#if __has_builtin(__make_integer_seq)
= __make_integer_seq<integer_sequence, _Tp, _Num>;
#else
= integer_sequence<_Tp, __integer_pack(_Num)...>;
#endif
/// Alias template index_sequence
template<size_t... _Idx>
using index_sequence = integer_sequence<size_t, _Idx...>;
/// Alias template make_index_sequence
template<size_t _Num>
using make_index_sequence = make_integer_sequence<size_t, _Num>;
/// Alias template index_sequence_for
template<typename... _Types>
using index_sequence_for = make_index_sequence<sizeof...(_Types)>;
#endif // __glibcxx_integer_sequence
#if __cplusplus >= 201703L
struct in_place_t {
explicit in_place_t() = default;
};
inline constexpr in_place_t in_place{};
template<typename _Tp> struct in_place_type_t
{
explicit in_place_type_t() = default;
};
template<typename _Tp>
inline constexpr in_place_type_t<_Tp> in_place_type{};
template<size_t _Idx> struct in_place_index_t
{
explicit in_place_index_t() = default;
};
template<size_t _Idx>
inline constexpr in_place_index_t<_Idx> in_place_index{};
template<typename>
inline constexpr bool __is_in_place_type_v = false;
template<typename _Tp>
inline constexpr bool __is_in_place_type_v<in_place_type_t<_Tp>> = true;
template<typename _Tp>
using __is_in_place_type = bool_constant<__is_in_place_type_v<_Tp>>;
template<typename>
inline constexpr bool __is_in_place_index_v = false;
template<size_t _Nm>
inline constexpr bool __is_in_place_index_v<in_place_index_t<_Nm>> = true;
#endif // C++17
#if _GLIBCXX_USE_BUILTIN_TRAIT(__type_pack_element)
template<size_t _Np, typename... _Types>
struct _Nth_type
{ using type = __type_pack_element<_Np, _Types...>; };
#else
template<size_t _Np, typename... _Types>
struct _Nth_type
{ };
template<typename _Tp0, typename... _Rest>
struct _Nth_type<0, _Tp0, _Rest...>
{ using type = _Tp0; };
template<typename _Tp0, typename _Tp1, typename... _Rest>
struct _Nth_type<1, _Tp0, _Tp1, _Rest...>
{ using type = _Tp1; };
template<typename _Tp0, typename _Tp1, typename _Tp2, typename... _Rest>
struct _Nth_type<2, _Tp0, _Tp1, _Tp2, _Rest...>
{ using type = _Tp2; };
template<size_t _Np, typename _Tp0, typename _Tp1, typename _Tp2,
typename... _Rest>
#if __cpp_concepts
requires (_Np >= 3)
#endif
struct _Nth_type<_Np, _Tp0, _Tp1, _Tp2, _Rest...>
: _Nth_type<_Np - 3, _Rest...>
{ };
#if ! __cpp_concepts // Need additional specializations to avoid ambiguities.
template<typename _Tp0, typename _Tp1, typename _Tp2, typename... _Rest>
struct _Nth_type<0, _Tp0, _Tp1, _Tp2, _Rest...>
{ using type = _Tp0; };
template<typename _Tp0, typename _Tp1, typename _Tp2, typename... _Rest>
struct _Nth_type<1, _Tp0, _Tp1, _Tp2, _Rest...>
{ using type = _Tp1; };
#endif
#endif
#if __glibcxx_ranges
namespace ranges::__detail
{
template<typename _Range>
inline constexpr bool __is_subrange = false;
} // namespace __detail
#endif
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif // C++11
#endif /* _GLIBCXX_UTILITY_H */
File diff suppressed because it is too large Load Diff