libstdc++: Reduce header dependencies on <array> and <utility>
This refactoring reduces the memory usage and compilation time to parse a number of headers that depend on std::pair, std::tuple or std::array. Previously the headers for these class templates were all intertwined, due to the common dependency on std::tuple_size, std::tuple_element and their std::get overloads. This decouples the headers by moving some parts of <utility> into a new <bits/utility.h> header. This means that <array> and <tuple> no longer need to include the whole of <utility>, and <tuple> no longer needs to include <array>. This decoupling benefits headers such as <thread> and <scoped_allocator> which only need std::tuple, and so no longer have to parse std::array. Some other headers such as <any>, <optional> and <variant> no longer need to include <utility> just for the std::in_place tag types, so do not have to parse the std::pair definitions. Removing direct uses of <utility> also means that the std::rel_ops namespace is not transitively declared by other headers. Signed-off-by: Jonathan Wakely <jwakely@redhat.com> libstdc++-v3/ChangeLog: * include/Makefile.am: Add bits/utility.h header. * include/Makefile.in: Regenerate. * include/bits/utility.h: New file. * include/std/utility (tuple_size, tuple_element): Move to new header. * include/std/type_traits (__is_tuple_like_impl<tuple<T...>>): Move to <tuple>. (_Index_tuple, _Build_index_tuple, integer_sequence): Likewise. (in_place_t, in_place_index_t, in_place_type_t): Likewise. * include/bits/ranges_util.h: Include new header instead of <utility>. * include/bits/stl_pair.h (tuple_size, tuple_element): Move partial specializations for std::pair here. (get): Move overloads for std::pair here. * include/std/any: Include new header instead of <utility>. * include/std/array: Likewise. * include/std/memory_resource: Likewise. * include/std/optional: Likewise. * include/std/variant: Likewise. * include/std/tuple: Likewise. (__is_tuple_like_impl<tuple<T...>>): Move here. (get) Declare overloads for std::array. * include/std/version (__cpp_lib_tuples_by_type): Change type to long. * testsuite/20_util/optional/84601.cc: Include <utility>. * testsuite/20_util/specialized_algorithms/uninitialized_fill/constrained.cc: Likewise. * testsuite/23_containers/array/tuple_interface/get_neg.cc: Adjust dg-error line numbers. * testsuite/std/ranges/access/cbegin.cc: Include <utility>. * testsuite/std/ranges/access/cend.cc: Likewise. * testsuite/std/ranges/access/end.cc: Likewise. * testsuite/std/ranges/single_view.cc: Likewise.
This commit is contained in:
parent
fcc7c6369f
commit
261d5a4a45
@ -233,6 +233,7 @@ bits_headers = \
|
||||
${bits_srcdir}/unordered_set.h \
|
||||
${bits_srcdir}/uses_allocator.h \
|
||||
${bits_srcdir}/uses_allocator_args.h \
|
||||
${bits_srcdir}/utility.h \
|
||||
${bits_srcdir}/valarray_array.h \
|
||||
${bits_srcdir}/valarray_array.tcc \
|
||||
${bits_srcdir}/valarray_before.h \
|
||||
|
@ -583,6 +583,7 @@ bits_headers = \
|
||||
${bits_srcdir}/unordered_set.h \
|
||||
${bits_srcdir}/uses_allocator.h \
|
||||
${bits_srcdir}/uses_allocator_args.h \
|
||||
${bits_srcdir}/utility.h \
|
||||
${bits_srcdir}/valarray_array.h \
|
||||
${bits_srcdir}/valarray_array.tcc \
|
||||
${bits_srcdir}/valarray_before.h \
|
||||
|
@ -32,6 +32,7 @@
|
||||
|
||||
#if __cplusplus > 201703L
|
||||
# include <bits/ranges_base.h>
|
||||
# include <bits/utility.h>
|
||||
|
||||
#ifdef __cpp_lib_ranges
|
||||
namespace std _GLIBCXX_VISIBILITY(default)
|
||||
|
@ -56,12 +56,12 @@
|
||||
#ifndef _STL_PAIR_H
|
||||
#define _STL_PAIR_H 1
|
||||
|
||||
#include <bits/move.h> // for std::move / std::forward, and std::swap
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
# include <type_traits> // for std::__decay_and_strip, std::is_reference_v
|
||||
# include <type_traits> // for std::__decay_and_strip
|
||||
# include <bits/move.h> // for std::move / std::forward, and std::swap
|
||||
# include <bits/utility.h> // for std::tuple_element, std::tuple_size
|
||||
#endif
|
||||
#if __cplusplus > 201703L
|
||||
#if __cplusplus >= 202002L
|
||||
# include <compare>
|
||||
# define __cpp_lib_constexpr_utility 201811L
|
||||
#endif
|
||||
@ -752,6 +752,153 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
|
||||
/// @}
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
// Various functions which give std::pair a tuple-like interface.
|
||||
|
||||
template<typename _T1, typename _T2>
|
||||
struct __is_tuple_like_impl<pair<_T1, _T2>> : true_type
|
||||
{ };
|
||||
|
||||
/// Partial specialization for std::pair
|
||||
template<class _Tp1, class _Tp2>
|
||||
struct tuple_size<pair<_Tp1, _Tp2>>
|
||||
: public integral_constant<size_t, 2> { };
|
||||
|
||||
/// Partial specialization for std::pair
|
||||
template<class _Tp1, class _Tp2>
|
||||
struct tuple_element<0, pair<_Tp1, _Tp2>>
|
||||
{ typedef _Tp1 type; };
|
||||
|
||||
/// Partial specialization for std::pair
|
||||
template<class _Tp1, class _Tp2>
|
||||
struct tuple_element<1, pair<_Tp1, _Tp2>>
|
||||
{ typedef _Tp2 type; };
|
||||
|
||||
/// @cond undocumented
|
||||
template<size_t _Int>
|
||||
struct __pair_get;
|
||||
|
||||
template<>
|
||||
struct __pair_get<0>
|
||||
{
|
||||
template<typename _Tp1, typename _Tp2>
|
||||
static constexpr _Tp1&
|
||||
__get(pair<_Tp1, _Tp2>& __pair) noexcept
|
||||
{ return __pair.first; }
|
||||
|
||||
template<typename _Tp1, typename _Tp2>
|
||||
static constexpr _Tp1&&
|
||||
__move_get(pair<_Tp1, _Tp2>&& __pair) noexcept
|
||||
{ return std::forward<_Tp1>(__pair.first); }
|
||||
|
||||
template<typename _Tp1, typename _Tp2>
|
||||
static constexpr const _Tp1&
|
||||
__const_get(const pair<_Tp1, _Tp2>& __pair) noexcept
|
||||
{ return __pair.first; }
|
||||
|
||||
template<typename _Tp1, typename _Tp2>
|
||||
static constexpr const _Tp1&&
|
||||
__const_move_get(const pair<_Tp1, _Tp2>&& __pair) noexcept
|
||||
{ return std::forward<const _Tp1>(__pair.first); }
|
||||
};
|
||||
|
||||
template<>
|
||||
struct __pair_get<1>
|
||||
{
|
||||
template<typename _Tp1, typename _Tp2>
|
||||
static constexpr _Tp2&
|
||||
__get(pair<_Tp1, _Tp2>& __pair) noexcept
|
||||
{ return __pair.second; }
|
||||
|
||||
template<typename _Tp1, typename _Tp2>
|
||||
static constexpr _Tp2&&
|
||||
__move_get(pair<_Tp1, _Tp2>&& __pair) noexcept
|
||||
{ return std::forward<_Tp2>(__pair.second); }
|
||||
|
||||
template<typename _Tp1, typename _Tp2>
|
||||
static constexpr const _Tp2&
|
||||
__const_get(const pair<_Tp1, _Tp2>& __pair) noexcept
|
||||
{ return __pair.second; }
|
||||
|
||||
template<typename _Tp1, typename _Tp2>
|
||||
static constexpr const _Tp2&&
|
||||
__const_move_get(const pair<_Tp1, _Tp2>&& __pair) noexcept
|
||||
{ return std::forward<const _Tp2>(__pair.second); }
|
||||
};
|
||||
/// @endcond
|
||||
|
||||
/** @{
|
||||
* std::get overloads for accessing members of std::pair
|
||||
*/
|
||||
|
||||
template<size_t _Int, class _Tp1, class _Tp2>
|
||||
constexpr typename tuple_element<_Int, pair<_Tp1, _Tp2>>::type&
|
||||
get(pair<_Tp1, _Tp2>& __in) noexcept
|
||||
{ return __pair_get<_Int>::__get(__in); }
|
||||
|
||||
template<size_t _Int, class _Tp1, class _Tp2>
|
||||
constexpr typename tuple_element<_Int, pair<_Tp1, _Tp2>>::type&&
|
||||
get(pair<_Tp1, _Tp2>&& __in) noexcept
|
||||
{ return __pair_get<_Int>::__move_get(std::move(__in)); }
|
||||
|
||||
template<size_t _Int, class _Tp1, class _Tp2>
|
||||
constexpr const typename tuple_element<_Int, pair<_Tp1, _Tp2>>::type&
|
||||
get(const pair<_Tp1, _Tp2>& __in) noexcept
|
||||
{ return __pair_get<_Int>::__const_get(__in); }
|
||||
|
||||
template<size_t _Int, class _Tp1, class _Tp2>
|
||||
constexpr const typename tuple_element<_Int, pair<_Tp1, _Tp2>>::type&&
|
||||
get(const pair<_Tp1, _Tp2>&& __in) noexcept
|
||||
{ return __pair_get<_Int>::__const_move_get(std::move(__in)); }
|
||||
|
||||
#if __cplusplus >= 201402L
|
||||
|
||||
#define __cpp_lib_tuples_by_type 201304L
|
||||
|
||||
template <typename _Tp, typename _Up>
|
||||
constexpr _Tp&
|
||||
get(pair<_Tp, _Up>& __p) noexcept
|
||||
{ return __p.first; }
|
||||
|
||||
template <typename _Tp, typename _Up>
|
||||
constexpr const _Tp&
|
||||
get(const pair<_Tp, _Up>& __p) noexcept
|
||||
{ return __p.first; }
|
||||
|
||||
template <typename _Tp, typename _Up>
|
||||
constexpr _Tp&&
|
||||
get(pair<_Tp, _Up>&& __p) noexcept
|
||||
{ return std::move(__p.first); }
|
||||
|
||||
template <typename _Tp, typename _Up>
|
||||
constexpr const _Tp&&
|
||||
get(const pair<_Tp, _Up>&& __p) noexcept
|
||||
{ return std::move(__p.first); }
|
||||
|
||||
template <typename _Tp, typename _Up>
|
||||
constexpr _Tp&
|
||||
get(pair<_Up, _Tp>& __p) noexcept
|
||||
{ return __p.second; }
|
||||
|
||||
template <typename _Tp, typename _Up>
|
||||
constexpr const _Tp&
|
||||
get(const pair<_Up, _Tp>& __p) noexcept
|
||||
{ return __p.second; }
|
||||
|
||||
template <typename _Tp, typename _Up>
|
||||
constexpr _Tp&&
|
||||
get(pair<_Up, _Tp>&& __p) noexcept
|
||||
{ return std::move(__p.second); }
|
||||
|
||||
template <typename _Tp, typename _Up>
|
||||
constexpr const _Tp&&
|
||||
get(const pair<_Up, _Tp>&& __p) noexcept
|
||||
{ return std::move(__p.second); }
|
||||
|
||||
#endif // C++14
|
||||
/// @}
|
||||
#endif // C++11
|
||||
|
||||
_GLIBCXX_END_NAMESPACE_VERSION
|
||||
} // namespace std
|
||||
|
||||
|
205
libstdc++-v3/include/bits/utility.h
Normal file
205
libstdc++-v3/include/bits/utility.h
Normal file
@ -0,0 +1,205 @@
|
||||
// Utilities used throughout the library -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2004-2021 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> { };
|
||||
|
||||
/// 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>
|
||||
{
|
||||
typedef typename add_const<__tuple_element_t<__i, _Tp>>::type type;
|
||||
};
|
||||
|
||||
template<size_t __i, typename _Tp>
|
||||
struct tuple_element<__i, volatile _Tp>
|
||||
{
|
||||
typedef typename add_volatile<__tuple_element_t<__i, _Tp>>::type type;
|
||||
};
|
||||
|
||||
template<size_t __i, typename _Tp>
|
||||
struct tuple_element<__i, const volatile _Tp>
|
||||
{
|
||||
typedef typename add_cv<__tuple_element_t<__i, _Tp>>::type type;
|
||||
};
|
||||
|
||||
#if __cplusplus >= 201402L
|
||||
// The standard says this macro and alias template should be in <tuple>
|
||||
// but we define them here, to be available in <utility> and <array> too.
|
||||
#define __cpp_lib_tuple_element_t 201402L
|
||||
|
||||
template<size_t __i, typename _Tp>
|
||||
using tuple_element_t = typename tuple_element<__i, _Tp>::type;
|
||||
#endif // C++14
|
||||
|
||||
// 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
|
||||
};
|
||||
|
||||
#if __cplusplus >= 201402L
|
||||
|
||||
#define __cpp_lib_integer_sequence 201304L
|
||||
|
||||
/// Class template integer_sequence
|
||||
template<typename _Tp, _Tp... _Idx>
|
||||
struct integer_sequence
|
||||
{
|
||||
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)>;
|
||||
|
||||
#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>
|
||||
struct __is_in_place_type_impl : false_type
|
||||
{ };
|
||||
|
||||
template<typename _Tp>
|
||||
struct __is_in_place_type_impl<in_place_type_t<_Tp>> : true_type
|
||||
{ };
|
||||
|
||||
template<typename _Tp>
|
||||
struct __is_in_place_type
|
||||
: public __is_in_place_type_impl<_Tp>
|
||||
{ };
|
||||
#endif // C++17
|
||||
#endif // C++14
|
||||
|
||||
_GLIBCXX_END_NAMESPACE_VERSION
|
||||
} // namespace
|
||||
|
||||
#endif // C++11
|
||||
#endif /* _GLIBCXX_UTILITY_H */
|
@ -33,10 +33,11 @@
|
||||
|
||||
#if __cplusplus >= 201703L
|
||||
|
||||
#include <initializer_list>
|
||||
#include <typeinfo>
|
||||
#include <new>
|
||||
#include <utility>
|
||||
#include <type_traits>
|
||||
#include <bits/utility.h> // in_place_type_t
|
||||
|
||||
namespace std _GLIBCXX_VISIBILITY(default)
|
||||
{
|
||||
|
@ -35,10 +35,14 @@
|
||||
# include <bits/c++0x_warning.h>
|
||||
#else
|
||||
|
||||
#include <utility>
|
||||
#include <compare>
|
||||
#include <initializer_list>
|
||||
|
||||
#include <type_traits>
|
||||
#include <bits/functexcept.h>
|
||||
#include <bits/stl_algobase.h>
|
||||
#include <bits/range_access.h>
|
||||
#include <bits/range_access.h> // std::begin, std::end etc.
|
||||
#include <bits/utility.h> // std::index_sequence, std::tuple_size
|
||||
#include <debug/assertions.h>
|
||||
|
||||
namespace std _GLIBCXX_VISIBILITY(default)
|
||||
@ -428,28 +432,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
|
||||
// Tuple interface to class template array.
|
||||
|
||||
/// tuple_size
|
||||
template<typename _Tp>
|
||||
struct tuple_size;
|
||||
|
||||
/// Partial specialization for std::array
|
||||
template<typename _Tp, std::size_t _Nm>
|
||||
template<typename _Tp, size_t _Nm>
|
||||
struct tuple_size<array<_Tp, _Nm>>
|
||||
: public integral_constant<std::size_t, _Nm> { };
|
||||
|
||||
/// tuple_element
|
||||
template<std::size_t _Int, typename _Tp>
|
||||
struct tuple_element;
|
||||
: public integral_constant<size_t, _Nm> { };
|
||||
|
||||
/// Partial specialization for std::array
|
||||
template<std::size_t _Int, typename _Tp, std::size_t _Nm>
|
||||
struct tuple_element<_Int, array<_Tp, _Nm>>
|
||||
template<size_t _Ind, typename _Tp, size_t _Nm>
|
||||
struct tuple_element<_Ind, array<_Tp, _Nm>>
|
||||
{
|
||||
static_assert(_Int < _Nm, "index is out of bounds");
|
||||
typedef _Tp type;
|
||||
static_assert(_Ind < _Nm, "array index is in range");
|
||||
using type = _Tp;
|
||||
};
|
||||
|
||||
template<typename _Tp, std::size_t _Nm>
|
||||
template<typename _Tp, size_t _Nm>
|
||||
struct __is_tuple_like_impl<array<_Tp, _Nm>> : true_type
|
||||
{ };
|
||||
|
||||
|
@ -38,13 +38,13 @@
|
||||
#include <shared_mutex> // shared_mutex
|
||||
#include <bits/align.h> // align
|
||||
#include <bits/functexcept.h> // __throw_bad_array_new_length
|
||||
#include <bits/uses_allocator.h> // __use_alloc
|
||||
#include <bits/uses_allocator.h> // allocator_arg_t, __use_alloc
|
||||
#include <bits/uses_allocator_args.h> // uninitialized_construct_using_alloc
|
||||
#include <ext/numeric_traits.h>
|
||||
#include <debug/assertions.h>
|
||||
|
||||
#if ! __cpp_lib_make_obj_using_allocator
|
||||
# include <utility> // pair, index_sequence
|
||||
# include <bits/utility.h> // index_sequence
|
||||
# include <tuple> // tuple, forward_as_tuple
|
||||
#endif
|
||||
|
||||
@ -338,10 +338,10 @@ namespace pmr
|
||||
{ return _M_resource; }
|
||||
|
||||
private:
|
||||
#if ! __cpp_lib_make_obj_using_allocator
|
||||
using __uses_alloc1_ = __uses_alloc1<polymorphic_allocator>;
|
||||
using __uses_alloc2_ = __uses_alloc2<polymorphic_allocator>;
|
||||
|
||||
#if ! __cpp_lib_make_obj_using_allocator
|
||||
template<typename _Ind, typename... _Args>
|
||||
static tuple<_Args&&...>
|
||||
_S_construct_p(__uses_alloc0, _Ind, tuple<_Args...>& __t)
|
||||
|
@ -33,14 +33,14 @@
|
||||
|
||||
#if __cplusplus >= 201703L
|
||||
|
||||
#include <utility>
|
||||
#include <type_traits>
|
||||
#include <exception>
|
||||
#include <new>
|
||||
#include <initializer_list>
|
||||
#include <bits/enable_special_members.h>
|
||||
#include <bits/exception_defines.h>
|
||||
#include <bits/functional_hash.h>
|
||||
#include <bits/enable_special_members.h>
|
||||
#include <bits/utility.h> // in_place_t
|
||||
#if __cplusplus > 201703L
|
||||
# include <compare>
|
||||
#endif
|
||||
|
@ -35,10 +35,10 @@
|
||||
# include <bits/c++0x_warning.h>
|
||||
#else
|
||||
|
||||
#include <utility>
|
||||
#include <array>
|
||||
#include <bits/uses_allocator.h>
|
||||
#include <bits/invoke.h>
|
||||
#include <bits/stl_pair.h> // for std::pair
|
||||
#include <bits/uses_allocator.h> // for std::allocator_arg_t
|
||||
#include <bits/utility.h> // for std::get, std::tuple_size etc.
|
||||
#include <bits/invoke.h> // for std::__invoke
|
||||
#if __cplusplus > 201703L
|
||||
# include <compare>
|
||||
# define __cpp_lib_constexpr_tuple 201811L
|
||||
@ -1415,7 +1415,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
|
||||
#if __cplusplus >= 201402L
|
||||
|
||||
#define __cpp_lib_tuples_by_type 201304
|
||||
#define __cpp_lib_tuples_by_type 201304L
|
||||
|
||||
// Return the index of _Tp in _Types, if it occurs exactly once.
|
||||
// Otherwise, return sizeof...(_Types).
|
||||
@ -1613,6 +1613,28 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
forward_as_tuple(_Elements&&... __args) noexcept
|
||||
{ return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); }
|
||||
|
||||
// Declarations of std::array and its std::get overloads, so that
|
||||
// std::tuple_cat can use them if <tuple> is included before <array>.
|
||||
|
||||
template<typename _Tp, size_t _Nm> struct array;
|
||||
|
||||
template<size_t _Int, typename _Tp, size_t _Nm>
|
||||
constexpr _Tp&
|
||||
get(array<_Tp, _Nm>&) noexcept;
|
||||
|
||||
template<size_t _Int, typename _Tp, size_t _Nm>
|
||||
constexpr _Tp&&
|
||||
get(array<_Tp, _Nm>&&) noexcept;
|
||||
|
||||
template<size_t _Int, typename _Tp, size_t _Nm>
|
||||
constexpr const _Tp&
|
||||
get(const array<_Tp, _Nm>&) noexcept;
|
||||
|
||||
template<size_t _Int, typename _Tp, size_t _Nm>
|
||||
constexpr const _Tp&&
|
||||
get(const array<_Tp, _Nm>&&) noexcept;
|
||||
|
||||
|
||||
template<size_t, typename, typename, size_t>
|
||||
struct __make_tuple_impl;
|
||||
|
||||
@ -1721,6 +1743,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
}
|
||||
};
|
||||
|
||||
template<typename... _Tps>
|
||||
struct __is_tuple_like_impl<tuple<_Tps...>> : true_type
|
||||
{ };
|
||||
|
||||
/// tuple_cat
|
||||
template<typename... _Tpls, typename = typename
|
||||
enable_if<__and_<__is_tuple_like<_Tpls>...>::value>::type>
|
||||
|
@ -41,9 +41,6 @@ namespace std _GLIBCXX_VISIBILITY(default)
|
||||
{
|
||||
_GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
|
||||
template<typename... _Elements>
|
||||
class tuple;
|
||||
|
||||
template<typename _Tp>
|
||||
class reference_wrapper;
|
||||
|
||||
@ -2680,10 +2677,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
struct __is_tuple_like_impl : false_type
|
||||
{ };
|
||||
|
||||
template<typename... _Tps>
|
||||
struct __is_tuple_like_impl<tuple<_Tps...>> : true_type
|
||||
{ };
|
||||
|
||||
// Internal type trait that allows us to sfinae-protect tuple_cat.
|
||||
template<typename _Tp>
|
||||
struct __is_tuple_like
|
||||
|
@ -60,9 +60,8 @@
|
||||
/**
|
||||
* @defgroup utilities Utilities
|
||||
*
|
||||
* Components deemed generally useful. Includes pair, tuple,
|
||||
* forward/move helpers, ratio, function object, metaprogramming and
|
||||
* type traits, time, date, and memory functions.
|
||||
* Basic function and class templates used with the rest of the library.
|
||||
* Includes pair, swap, forward/move helpers, declval, integer_sequence.
|
||||
*/
|
||||
|
||||
#include <bits/c++config.h>
|
||||
@ -71,218 +70,21 @@
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
|
||||
#include <initializer_list>
|
||||
#include <type_traits>
|
||||
#include <bits/move.h>
|
||||
#include <initializer_list>
|
||||
#include <bits/utility.h>
|
||||
|
||||
#if __cplusplus > 201703L
|
||||
#include <ext/numeric_traits.h>
|
||||
#if __cplusplus >= 202002L
|
||||
#include <ext/numeric_traits.h> // __is_standard_integer, __int_traits
|
||||
#endif
|
||||
|
||||
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> { };
|
||||
|
||||
/// 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>
|
||||
{
|
||||
typedef typename add_const<__tuple_element_t<__i, _Tp>>::type type;
|
||||
};
|
||||
|
||||
template<size_t __i, typename _Tp>
|
||||
struct tuple_element<__i, volatile _Tp>
|
||||
{
|
||||
typedef typename add_volatile<__tuple_element_t<__i, _Tp>>::type type;
|
||||
};
|
||||
|
||||
template<size_t __i, typename _Tp>
|
||||
struct tuple_element<__i, const volatile _Tp>
|
||||
{
|
||||
typedef typename add_cv<__tuple_element_t<__i, _Tp>>::type type;
|
||||
};
|
||||
|
||||
#if __cplusplus >= 201402L
|
||||
// The standard says this macro and alias template should be in <tuple>
|
||||
// but we define them here, to be available when the partial specializations
|
||||
// of tuple_element<pair<T,U>> and tuple_element<array<T,N>> are defined.
|
||||
#define __cpp_lib_tuple_element_t 201402L
|
||||
|
||||
template<size_t __i, typename _Tp>
|
||||
using tuple_element_t = typename tuple_element<__i, _Tp>::type;
|
||||
#endif
|
||||
|
||||
// Various functions which give std::pair a tuple-like interface.
|
||||
|
||||
/// Partial specialization for std::pair
|
||||
template<typename _T1, typename _T2>
|
||||
struct __is_tuple_like_impl<pair<_T1, _T2>> : true_type
|
||||
{ };
|
||||
|
||||
/// Partial specialization for std::pair
|
||||
template<class _Tp1, class _Tp2>
|
||||
struct tuple_size<pair<_Tp1, _Tp2>>
|
||||
: public integral_constant<size_t, 2> { };
|
||||
|
||||
/// Partial specialization for std::pair
|
||||
template<class _Tp1, class _Tp2>
|
||||
struct tuple_element<0, pair<_Tp1, _Tp2>>
|
||||
{ typedef _Tp1 type; };
|
||||
|
||||
/// Partial specialization for std::pair
|
||||
template<class _Tp1, class _Tp2>
|
||||
struct tuple_element<1, pair<_Tp1, _Tp2>>
|
||||
{ typedef _Tp2 type; };
|
||||
|
||||
template<size_t _Int>
|
||||
struct __pair_get;
|
||||
|
||||
template<>
|
||||
struct __pair_get<0>
|
||||
{
|
||||
template<typename _Tp1, typename _Tp2>
|
||||
static constexpr _Tp1&
|
||||
__get(pair<_Tp1, _Tp2>& __pair) noexcept
|
||||
{ return __pair.first; }
|
||||
|
||||
template<typename _Tp1, typename _Tp2>
|
||||
static constexpr _Tp1&&
|
||||
__move_get(pair<_Tp1, _Tp2>&& __pair) noexcept
|
||||
{ return std::forward<_Tp1>(__pair.first); }
|
||||
|
||||
template<typename _Tp1, typename _Tp2>
|
||||
static constexpr const _Tp1&
|
||||
__const_get(const pair<_Tp1, _Tp2>& __pair) noexcept
|
||||
{ return __pair.first; }
|
||||
|
||||
template<typename _Tp1, typename _Tp2>
|
||||
static constexpr const _Tp1&&
|
||||
__const_move_get(const pair<_Tp1, _Tp2>&& __pair) noexcept
|
||||
{ return std::forward<const _Tp1>(__pair.first); }
|
||||
};
|
||||
|
||||
template<>
|
||||
struct __pair_get<1>
|
||||
{
|
||||
template<typename _Tp1, typename _Tp2>
|
||||
static constexpr _Tp2&
|
||||
__get(pair<_Tp1, _Tp2>& __pair) noexcept
|
||||
{ return __pair.second; }
|
||||
|
||||
template<typename _Tp1, typename _Tp2>
|
||||
static constexpr _Tp2&&
|
||||
__move_get(pair<_Tp1, _Tp2>&& __pair) noexcept
|
||||
{ return std::forward<_Tp2>(__pair.second); }
|
||||
|
||||
template<typename _Tp1, typename _Tp2>
|
||||
static constexpr const _Tp2&
|
||||
__const_get(const pair<_Tp1, _Tp2>& __pair) noexcept
|
||||
{ return __pair.second; }
|
||||
|
||||
template<typename _Tp1, typename _Tp2>
|
||||
static constexpr const _Tp2&&
|
||||
__const_move_get(const pair<_Tp1, _Tp2>&& __pair) noexcept
|
||||
{ return std::forward<const _Tp2>(__pair.second); }
|
||||
};
|
||||
|
||||
template<size_t _Int, class _Tp1, class _Tp2>
|
||||
constexpr typename tuple_element<_Int, pair<_Tp1, _Tp2>>::type&
|
||||
get(pair<_Tp1, _Tp2>& __in) noexcept
|
||||
{ return __pair_get<_Int>::__get(__in); }
|
||||
|
||||
template<size_t _Int, class _Tp1, class _Tp2>
|
||||
constexpr typename tuple_element<_Int, pair<_Tp1, _Tp2>>::type&&
|
||||
get(pair<_Tp1, _Tp2>&& __in) noexcept
|
||||
{ return __pair_get<_Int>::__move_get(std::move(__in)); }
|
||||
|
||||
template<size_t _Int, class _Tp1, class _Tp2>
|
||||
constexpr const typename tuple_element<_Int, pair<_Tp1, _Tp2>>::type&
|
||||
get(const pair<_Tp1, _Tp2>& __in) noexcept
|
||||
{ return __pair_get<_Int>::__const_get(__in); }
|
||||
|
||||
template<size_t _Int, class _Tp1, class _Tp2>
|
||||
constexpr const typename tuple_element<_Int, pair<_Tp1, _Tp2>>::type&&
|
||||
get(const pair<_Tp1, _Tp2>&& __in) noexcept
|
||||
{ return __pair_get<_Int>::__const_move_get(std::move(__in)); }
|
||||
|
||||
#if __cplusplus >= 201402L
|
||||
|
||||
#define __cpp_lib_tuples_by_type 201304
|
||||
|
||||
template <typename _Tp, typename _Up>
|
||||
constexpr _Tp&
|
||||
get(pair<_Tp, _Up>& __p) noexcept
|
||||
{ return __p.first; }
|
||||
|
||||
template <typename _Tp, typename _Up>
|
||||
constexpr const _Tp&
|
||||
get(const pair<_Tp, _Up>& __p) noexcept
|
||||
{ return __p.first; }
|
||||
|
||||
template <typename _Tp, typename _Up>
|
||||
constexpr _Tp&&
|
||||
get(pair<_Tp, _Up>&& __p) noexcept
|
||||
{ return std::move(__p.first); }
|
||||
|
||||
template <typename _Tp, typename _Up>
|
||||
constexpr const _Tp&&
|
||||
get(const pair<_Tp, _Up>&& __p) noexcept
|
||||
{ return std::move(__p.first); }
|
||||
|
||||
template <typename _Tp, typename _Up>
|
||||
constexpr _Tp&
|
||||
get(pair<_Up, _Tp>& __p) noexcept
|
||||
{ return __p.second; }
|
||||
|
||||
template <typename _Tp, typename _Up>
|
||||
constexpr const _Tp&
|
||||
get(const pair<_Up, _Tp>& __p) noexcept
|
||||
{ return __p.second; }
|
||||
|
||||
template <typename _Tp, typename _Up>
|
||||
constexpr _Tp&&
|
||||
get(pair<_Up, _Tp>&& __p) noexcept
|
||||
{ return std::move(__p.second); }
|
||||
|
||||
template <typename _Tp, typename _Up>
|
||||
constexpr const _Tp&&
|
||||
get(const pair<_Up, _Tp>&& __p) noexcept
|
||||
{ return std::move(__p.second); }
|
||||
|
||||
#define __cpp_lib_exchange_function 201304
|
||||
#define __cpp_lib_exchange_function 201304L
|
||||
|
||||
/// Assign @p __new_val to @p __obj and return its previous value.
|
||||
template <typename _Tp, typename _Up = _Tp>
|
||||
@ -291,100 +93,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
exchange(_Tp& __obj, _Up&& __new_val)
|
||||
{ return std::__exchange(__obj, std::forward<_Up>(__new_val)); }
|
||||
|
||||
#endif // C++14
|
||||
#if __cplusplus >= 201703L
|
||||
|
||||
// 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
|
||||
};
|
||||
|
||||
#if __cplusplus >= 201402L
|
||||
|
||||
#define __cpp_lib_integer_sequence 201304
|
||||
|
||||
/// Class template integer_sequence
|
||||
template<typename _Tp, _Tp... _Idx>
|
||||
struct integer_sequence
|
||||
{
|
||||
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
|
||||
|
||||
#if __cplusplus > 201402L
|
||||
|
||||
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>
|
||||
struct __is_in_place_type_impl : false_type
|
||||
{ };
|
||||
|
||||
template<typename _Tp>
|
||||
struct __is_in_place_type_impl<in_place_type_t<_Tp>> : true_type
|
||||
{ };
|
||||
|
||||
template<typename _Tp>
|
||||
struct __is_in_place_type
|
||||
: public __is_in_place_type_impl<_Tp>
|
||||
{ };
|
||||
|
||||
#define __cpp_lib_as_const 201510
|
||||
#define __cpp_lib_as_const 201510L
|
||||
template<typename _Tp>
|
||||
[[nodiscard]]
|
||||
constexpr add_const_t<_Tp>&
|
||||
@ -476,6 +187,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
#endif // C++23
|
||||
#endif // C++20
|
||||
#endif // C++17
|
||||
#endif // C++14
|
||||
|
||||
_GLIBCXX_END_NAMESPACE_VERSION
|
||||
} // namespace
|
||||
|
@ -33,11 +33,10 @@
|
||||
|
||||
#if __cplusplus >= 201703L
|
||||
|
||||
#include <initializer_list>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <bits/enable_special_members.h>
|
||||
#include <bits/functexcept.h>
|
||||
#include <bits/move.h>
|
||||
#include <bits/exception_defines.h>
|
||||
#include <bits/functional_hash.h>
|
||||
#include <bits/invoke.h>
|
||||
#include <ext/aligned_buffer.h>
|
||||
@ -45,6 +44,7 @@
|
||||
#include <bits/stl_iterator_base_types.h>
|
||||
#include <bits/stl_iterator_base_funcs.h>
|
||||
#include <bits/stl_construct.h>
|
||||
#include <bits/utility.h> // in_place_index_t
|
||||
#if __cplusplus > 201703L
|
||||
# include <compare>
|
||||
#endif
|
||||
|
@ -94,7 +94,7 @@
|
||||
# define __cpp_lib_string_udls 201304
|
||||
# define __cpp_lib_transparent_operators 201510
|
||||
# define __cpp_lib_tuple_element_t 201402L
|
||||
# define __cpp_lib_tuples_by_type 201304
|
||||
# define __cpp_lib_tuples_by_type 201304L
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201703L
|
||||
|
@ -1,6 +1,7 @@
|
||||
// { dg-do compile { target c++17 } }
|
||||
|
||||
#include <optional>
|
||||
#include <utility>
|
||||
|
||||
using pair_t = std::pair<int, int>;
|
||||
using opt_t = std::optional<pair_t>;
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include <span>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
|
||||
#include <testsuite_hooks.h>
|
||||
#include <testsuite_iterators.h>
|
||||
|
@ -26,6 +26,6 @@ int n1 = std::get<1>(a);
|
||||
int n2 = std::get<1>(std::move(a));
|
||||
int n3 = std::get<1>(ca);
|
||||
|
||||
// { dg-error "static assertion failed" "" { target *-*-* } 363 }
|
||||
// { dg-error "static assertion failed" "" { target *-*-* } 371 }
|
||||
// { dg-error "static assertion failed" "" { target *-*-* } 379 }
|
||||
// { dg-error "static assertion failed" "" { target *-*-* } 367 }
|
||||
// { dg-error "static assertion failed" "" { target *-*-* } 375 }
|
||||
// { dg-error "static assertion failed" "" { target *-*-* } 383 }
|
||||
|
@ -19,6 +19,7 @@
|
||||
// { dg-do run { target c++2a } }
|
||||
|
||||
#include <ranges>
|
||||
#include <utility> // as_const
|
||||
#include <testsuite_hooks.h>
|
||||
#include <testsuite_iterators.h>
|
||||
|
||||
|
@ -19,6 +19,7 @@
|
||||
// { dg-do run { target c++2a } }
|
||||
|
||||
#include <ranges>
|
||||
#include <utility> // as_const
|
||||
#include <testsuite_hooks.h>
|
||||
#include <testsuite_iterators.h>
|
||||
|
||||
|
@ -19,6 +19,7 @@
|
||||
// { dg-do run { target c++2a } }
|
||||
|
||||
#include <ranges>
|
||||
#include <utility> // as_const
|
||||
#include <testsuite_hooks.h>
|
||||
#include <testsuite_iterators.h>
|
||||
|
||||
|
@ -19,6 +19,7 @@
|
||||
// { dg-do run { target c++2a } }
|
||||
|
||||
#include <ranges>
|
||||
#include <utility> // as_const
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
void
|
||||
|
Loading…
Reference in New Issue
Block a user