* [committed] [1/2] libstdc++: Reduce header dependencies on <array> and <utility>
@ 2021-07-27 12:15 Jonathan Wakely
2021-07-27 12:16 ` [committed] [2/2] libstdc++: Remove unnecessary uses of <utility> Jonathan Wakely
0 siblings, 1 reply; 3+ messages in thread
From: Jonathan Wakely @ 2021-07-27 12:15 UTC (permalink / raw)
To: libstdc++, gcc-patches
[-- Attachment #1: Type: text/plain, Size: 2602 bytes --]
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.
Tested powerpc64le-linux. Committed to trunk.
[-- Attachment #2: patch.txt --]
[-- Type: text/plain, Size: 38980 bytes --]
commit 261d5a4a459bd49942e53bc83334ccc7154a09d5
Author: Jonathan Wakely <jwakely@redhat.com>
Date: Thu Jul 22 14:48:27 2021
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.
diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index 40a41ef2a1c..99eec558116 100644
--- a/libstdc++-v3/include/Makefile.am
+++ b/libstdc++-v3/include/Makefile.am
@@ -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 \
diff --git a/libstdc++-v3/include/bits/ranges_util.h b/libstdc++-v3/include/bits/ranges_util.h
index 9a07079ac13..0ca203dd4b0 100644
--- a/libstdc++-v3/include/bits/ranges_util.h
+++ b/libstdc++-v3/include/bits/ranges_util.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)
diff --git a/libstdc++-v3/include/bits/stl_pair.h b/libstdc++-v3/include/bits/stl_pair.h
index c89f377fddc..329485ce3b2 100644
--- a/libstdc++-v3/include/bits/stl_pair.h
+++ b/libstdc++-v3/include/bits/stl_pair.h
@@ -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
diff --git a/libstdc++-v3/include/bits/utility.h b/libstdc++-v3/include/bits/utility.h
new file mode 100644
index 00000000000..96d350874d9
--- /dev/null
+++ b/libstdc++-v3/include/bits/utility.h
@@ -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 */
diff --git a/libstdc++-v3/include/std/any b/libstdc++-v3/include/std/any
index a6995b79c43..1fce95730ea 100644
--- a/libstdc++-v3/include/std/any
+++ b/libstdc++-v3/include/std/any
@@ -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)
{
diff --git a/libstdc++-v3/include/std/array b/libstdc++-v3/include/std/array
index 0c6f33e3276..ea8d3cb5f2e 100644
--- a/libstdc++-v3/include/std/array
+++ b/libstdc++-v3/include/std/array
@@ -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
{ };
diff --git a/libstdc++-v3/include/std/memory_resource b/libstdc++-v3/include/std/memory_resource
index df4e806f814..cdc5e5d98b1 100644
--- a/libstdc++-v3/include/std/memory_resource
+++ b/libstdc++-v3/include/std/memory_resource
@@ -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)
diff --git a/libstdc++-v3/include/std/optional b/libstdc++-v3/include/std/optional
index 0a67ce24bbd..df9ed0736b3 100644
--- a/libstdc++-v3/include/std/optional
+++ b/libstdc++-v3/include/std/optional
@@ -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
diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple
index 8ee0d2f1ef5..1292aee45c0 100644
--- a/libstdc++-v3/include/std/tuple
+++ b/libstdc++-v3/include/std/tuple
@@ -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>
diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits
index 15ec83a06b8..0d821f9c074 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -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
diff --git a/libstdc++-v3/include/std/utility b/libstdc++-v3/include/std/utility
index 3e68f682e00..c2697f87dc5 100644
--- a/libstdc++-v3/include/std/utility
+++ b/libstdc++-v3/include/std/utility
@@ -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
diff --git a/libstdc++-v3/include/std/variant b/libstdc++-v3/include/std/variant
index a4e038e0ec8..6383cf4e502 100644
--- a/libstdc++-v3/include/std/variant
+++ b/libstdc++-v3/include/std/variant
@@ -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
diff --git a/libstdc++-v3/include/std/version b/libstdc++-v3/include/std/version
index 27bcd32cb60..d5fa38d7786 100644
--- a/libstdc++-v3/include/std/version
+++ b/libstdc++-v3/include/std/version
@@ -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
diff --git a/libstdc++-v3/testsuite/20_util/optional/84601.cc b/libstdc++-v3/testsuite/20_util/optional/84601.cc
index ddac999d49e..fbfa8fdeebf 100644
--- a/libstdc++-v3/testsuite/20_util/optional/84601.cc
+++ b/libstdc++-v3/testsuite/20_util/optional/84601.cc
@@ -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>;
diff --git a/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_fill/constrained.cc b/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_fill/constrained.cc
index bb980a91b0e..bce65cf0807 100644
--- a/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_fill/constrained.cc
+++ b/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_fill/constrained.cc
@@ -25,6 +25,7 @@
#include <span>
#include <string>
#include <vector>
+#include <utility>
#include <testsuite_hooks.h>
#include <testsuite_iterators.h>
diff --git a/libstdc++-v3/testsuite/23_containers/array/tuple_interface/get_neg.cc b/libstdc++-v3/testsuite/23_containers/array/tuple_interface/get_neg.cc
index 2875f30011b..423594dd2b3 100644
--- a/libstdc++-v3/testsuite/23_containers/array/tuple_interface/get_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/array/tuple_interface/get_neg.cc
@@ -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 }
diff --git a/libstdc++-v3/testsuite/std/ranges/access/cbegin.cc b/libstdc++-v3/testsuite/std/ranges/access/cbegin.cc
index ed80af589cf..7941563b124 100644
--- a/libstdc++-v3/testsuite/std/ranges/access/cbegin.cc
+++ b/libstdc++-v3/testsuite/std/ranges/access/cbegin.cc
@@ -19,6 +19,7 @@
// { dg-do run { target c++2a } }
#include <ranges>
+#include <utility> // as_const
#include <testsuite_hooks.h>
#include <testsuite_iterators.h>
diff --git a/libstdc++-v3/testsuite/std/ranges/access/cend.cc b/libstdc++-v3/testsuite/std/ranges/access/cend.cc
index 3e685ae9ce2..135bda80a6a 100644
--- a/libstdc++-v3/testsuite/std/ranges/access/cend.cc
+++ b/libstdc++-v3/testsuite/std/ranges/access/cend.cc
@@ -19,6 +19,7 @@
// { dg-do run { target c++2a } }
#include <ranges>
+#include <utility> // as_const
#include <testsuite_hooks.h>
#include <testsuite_iterators.h>
diff --git a/libstdc++-v3/testsuite/std/ranges/access/end.cc b/libstdc++-v3/testsuite/std/ranges/access/end.cc
index 25f21c75afc..7321a3088a4 100644
--- a/libstdc++-v3/testsuite/std/ranges/access/end.cc
+++ b/libstdc++-v3/testsuite/std/ranges/access/end.cc
@@ -19,6 +19,7 @@
// { dg-do run { target c++2a } }
#include <ranges>
+#include <utility> // as_const
#include <testsuite_hooks.h>
#include <testsuite_iterators.h>
diff --git a/libstdc++-v3/testsuite/std/ranges/single_view.cc b/libstdc++-v3/testsuite/std/ranges/single_view.cc
index f1d8e103715..fe03cccf9cc 100644
--- a/libstdc++-v3/testsuite/std/ranges/single_view.cc
+++ b/libstdc++-v3/testsuite/std/ranges/single_view.cc
@@ -19,6 +19,7 @@
// { dg-do run { target c++2a } }
#include <ranges>
+#include <utility> // as_const
#include <testsuite_hooks.h>
void
^ permalink raw reply [flat|nested] 3+ messages in thread
* [committed] [2/2] libstdc++: Remove unnecessary uses of <utility>
2021-07-27 12:15 [committed] [1/2] libstdc++: Reduce header dependencies on <array> and <utility> Jonathan Wakely
@ 2021-07-27 12:16 ` Jonathan Wakely
2021-07-27 20:38 ` [committed] [3/2] testsuite: Add missing C++ includes to tests [PR101646] Jonathan Wakely
0 siblings, 1 reply; 3+ messages in thread
From: Jonathan Wakely @ 2021-07-27 12:16 UTC (permalink / raw)
To: libstdc++, gcc-patches
[-- Attachment #1: Type: text/plain, Size: 2536 bytes --]
The <algorithm> header includes <utility>, with a comment referring to
UK-300, a National Body comment on the C++11 draft. That comment
proposed to move std::swap to <utility> and then require <algorithm> to
include <utility>. The comment was rejected, so we do not need to
implement the suggestion. For backwards compatibility with C++03 we do
want <algorithm> to define std::swap, but it does so anyway via
<bits/move.h>. We don't need the whole of <utility> to do that.
A few other headers that need std::swap can include <bits/move.h> to
get it, instead of <utility>.
There are several headers that include <utility> to get std::pair, but
they can use <bits/stl_pair.h> to get it without also including the
rel_ops namespace and other contents of <utility>.
Signed-off-by: Jonathan Wakely <jwakely@redhat.com>
libstdc++-v3/ChangeLog:
* include/std/algorithm: Do not include <utility>.
* include/std/functional: Likewise.
* include/std/regex: Include <bits/stl_pair.h> instead of
<utility>.
* include/debug/map.h: Likewise.
* include/debug/multimap.h: Likewise.
* include/debug/multiset.h: Likewise.
* include/debug/set.h: Likewise.
* include/debug/vector: Likewise.
* include/bits/fs_path.h: Likewise.
* include/bits/unique_ptr.h: Do not include <utility>.
* include/experimental/any: Likewise.
* include/experimental/executor: Likewise.
* include/experimental/memory: Likewise.
* include/experimental/optional: Likewise.
* include/experimental/socket: Use __exchange instead
of std::exchange.
* src/filesystem/ops-common.h: Likewise.
* testsuite/20_util/default_delete/48631_neg.cc: Adjust expected
errors to not use a hardcoded line number.
* testsuite/20_util/default_delete/void_neg.cc: Likewise.
* testsuite/20_util/specialized_algorithms/uninitialized_copy/constrained.cc:
Include <utility> for std::as_const.
* testsuite/20_util/specialized_algorithms/uninitialized_default_construct/constrained.cc:
Likewise.
* testsuite/20_util/specialized_algorithms/uninitialized_move/constrained.cc:
Likewise.
* testsuite/20_util/specialized_algorithms/uninitialized_value_construct/constrained.cc:
Likewise.
* testsuite/23_containers/vector/cons/destructible_debug_neg.cc:
Adjust dg-error line number.
Tested powerpc64le-linux. Committed to trunk.
[-- Attachment #2: patch.txt --]
[-- Type: text/x-patch, Size: 15274 bytes --]
commit 16158c96496b537194111526d25e19f268d613b6
Author: Jonathan Wakely <jwakely@redhat.com>
Date: Thu Jul 22 14:48:27 2021
libstdc++: Remove unnecessary uses of <utility>
The <algorithm> header includes <utility>, with a comment referring to
UK-300, a National Body comment on the C++11 draft. That comment
proposed to move std::swap to <utility> and then require <algorithm> to
include <utility>. The comment was rejected, so we do not need to
implement the suggestion. For backwards compatibility with C++03 we do
want <algorithm> to define std::swap, but it does so anyway via
<bits/move.h>. We don't need the whole of <utility> to do that.
A few other headers that need std::swap can include <bits/move.h> to
get it, instead of <utility>.
There are several headers that include <utility> to get std::pair, but
they can use <bits/stl_pair.h> to get it without also including the
rel_ops namespace and other contents of <utility>.
Signed-off-by: Jonathan Wakely <jwakely@redhat.com>
libstdc++-v3/ChangeLog:
* include/std/algorithm: Do not include <utility>.
* include/std/functional: Likewise.
* include/std/regex: Include <bits/stl_pair.h> instead of
<utility>.
* include/debug/map.h: Likewise.
* include/debug/multimap.h: Likewise.
* include/debug/multiset.h: Likewise.
* include/debug/set.h: Likewise.
* include/debug/vector: Likewise.
* include/bits/fs_path.h: Likewise.
* include/bits/unique_ptr.h: Do not include <utility>.
* include/experimental/any: Likewise.
* include/experimental/executor: Likewise.
* include/experimental/memory: Likewise.
* include/experimental/optional: Likewise.
* include/experimental/socket: Use __exchange instead
of std::exchange.
* src/filesystem/ops-common.h: Likewise.
* testsuite/20_util/default_delete/48631_neg.cc: Adjust expected
errors to not use a hardcoded line number.
* testsuite/20_util/default_delete/void_neg.cc: Likewise.
* testsuite/20_util/specialized_algorithms/uninitialized_copy/constrained.cc:
Include <utility> for std::as_const.
* testsuite/20_util/specialized_algorithms/uninitialized_default_construct/constrained.cc:
Likewise.
* testsuite/20_util/specialized_algorithms/uninitialized_move/constrained.cc:
Likewise.
* testsuite/20_util/specialized_algorithms/uninitialized_value_construct/constrained.cc:
Likewise.
* testsuite/23_containers/vector/cons/destructible_debug_neg.cc:
Adjust dg-error line number.
diff --git a/libstdc++-v3/include/bits/fs_path.h b/libstdc++-v3/include/bits/fs_path.h
index 4fcd1def92f..3151af1e901 100644
--- a/libstdc++-v3/include/bits/fs_path.h
+++ b/libstdc++-v3/include/bits/fs_path.h
@@ -32,7 +32,6 @@
#if __cplusplus >= 201703L
-#include <utility>
#include <type_traits>
#include <locale>
#include <iosfwd>
@@ -41,6 +40,7 @@
#include <string_view>
#include <system_error>
#include <bits/stl_algobase.h>
+#include <bits/stl_pair.h>
#include <bits/locale_conv.h>
#include <ext/concurrence.h>
#include <bits/shared_ptr.h>
diff --git a/libstdc++-v3/include/bits/unique_ptr.h b/libstdc++-v3/include/bits/unique_ptr.h
index 0a0667a7608..2d8b9ed3fae 100644
--- a/libstdc++-v3/include/bits/unique_ptr.h
+++ b/libstdc++-v3/include/bits/unique_ptr.h
@@ -33,7 +33,6 @@
#include <bits/c++config.h>
#include <debug/assertions.h>
#include <type_traits>
-#include <utility>
#include <tuple>
#include <bits/stl_function.h>
#include <bits/functional_hash.h>
diff --git a/libstdc++-v3/include/debug/map.h b/libstdc++-v3/include/debug/map.h
index ab34b2affd9..c0153d09abe 100644
--- a/libstdc++-v3/include/debug/map.h
+++ b/libstdc++-v3/include/debug/map.h
@@ -32,7 +32,7 @@
#include <debug/safe_sequence.h>
#include <debug/safe_container.h>
#include <debug/safe_iterator.h>
-#include <utility>
+#include <bits/stl_pair.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
diff --git a/libstdc++-v3/include/debug/multimap.h b/libstdc++-v3/include/debug/multimap.h
index 96a44f4725f..94929344a9d 100644
--- a/libstdc++-v3/include/debug/multimap.h
+++ b/libstdc++-v3/include/debug/multimap.h
@@ -32,7 +32,7 @@
#include <debug/safe_sequence.h>
#include <debug/safe_container.h>
#include <debug/safe_iterator.h>
-#include <utility>
+#include <bits/stl_pair.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
diff --git a/libstdc++-v3/include/debug/multiset.h b/libstdc++-v3/include/debug/multiset.h
index 0e76c5ff332..bb68d8c8f18 100644
--- a/libstdc++-v3/include/debug/multiset.h
+++ b/libstdc++-v3/include/debug/multiset.h
@@ -32,7 +32,7 @@
#include <debug/safe_sequence.h>
#include <debug/safe_container.h>
#include <debug/safe_iterator.h>
-#include <utility>
+#include <bits/stl_pair.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
diff --git a/libstdc++-v3/include/debug/set.h b/libstdc++-v3/include/debug/set.h
index c579de7426d..cdf35ea5396 100644
--- a/libstdc++-v3/include/debug/set.h
+++ b/libstdc++-v3/include/debug/set.h
@@ -32,7 +32,7 @@
#include <debug/safe_sequence.h>
#include <debug/safe_container.h>
#include <debug/safe_iterator.h>
-#include <utility>
+#include <bits/stl_pair.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
diff --git a/libstdc++-v3/include/debug/vector b/libstdc++-v3/include/debug/vector
index 987bba17c2b..79ccf527dd6 100644
--- a/libstdc++-v3/include/debug/vector
+++ b/libstdc++-v3/include/debug/vector
@@ -37,7 +37,6 @@ namespace std _GLIBCXX_VISIBILITY(default) { namespace __debug {
} } // namespace std::__debug
#include <vector>
-#include <utility>
#include <debug/safe_sequence.h>
#include <debug/safe_container.h>
#include <debug/safe_iterator.h>
diff --git a/libstdc++-v3/include/experimental/any b/libstdc++-v3/include/experimental/any
index 3bb3e8c4a0a..7d18f267e8b 100644
--- a/libstdc++-v3/include/experimental/any
+++ b/libstdc++-v3/include/experimental/any
@@ -36,8 +36,8 @@
#include <typeinfo>
#include <new>
-#include <utility>
#include <type_traits>
+#include <bits/move.h>
#include <experimental/bits/lfts_config.h>
namespace std _GLIBCXX_VISIBILITY(default)
diff --git a/libstdc++-v3/include/experimental/executor b/libstdc++-v3/include/experimental/executor
index c670f2739b6..4322a7f5caf 100644
--- a/libstdc++-v3/include/experimental/executor
+++ b/libstdc++-v3/include/experimental/executor
@@ -43,7 +43,6 @@
#include <thread>
#include <tuple>
#include <unordered_map>
-#include <utility>
#include <experimental/netfwd>
#include <bits/unique_ptr.h>
#include <experimental/bits/net.h>
diff --git a/libstdc++-v3/include/experimental/memory b/libstdc++-v3/include/experimental/memory
index a74b2402f7a..a89a5ecfa84 100644
--- a/libstdc++-v3/include/experimental/memory
+++ b/libstdc++-v3/include/experimental/memory
@@ -40,7 +40,6 @@
#include <memory>
#include <type_traits>
-#include <utility>
#include <experimental/bits/shared_ptr.h>
#include <bits/functional_hash.h>
diff --git a/libstdc++-v3/include/experimental/optional b/libstdc++-v3/include/experimental/optional
index ae2418f0500..431d23631cf 100644
--- a/libstdc++-v3/include/experimental/optional
+++ b/libstdc++-v3/include/experimental/optional
@@ -32,7 +32,6 @@
#if __cplusplus >= 201402L
-#include <utility>
#include <type_traits>
#include <stdexcept>
#include <new>
@@ -40,6 +39,7 @@
#include <bits/functexcept.h>
#include <bits/functional_hash.h>
#include <bits/enable_special_members.h>
+#include <bits/move.h>
#include <experimental/bits/lfts_config.h>
namespace std _GLIBCXX_VISIBILITY(default)
diff --git a/libstdc++-v3/include/experimental/socket b/libstdc++-v3/include/experimental/socket
index 9db4a245ccf..6d1c114254a 100644
--- a/libstdc++-v3/include/experimental/socket
+++ b/libstdc++-v3/include/experimental/socket
@@ -429,16 +429,16 @@ inline namespace v1
__socket_impl(__socket_impl&& __rhs)
: _M_ctx(__rhs._M_ctx),
- _M_sockfd(std::exchange(__rhs._M_sockfd, -1)),
- _M_bits(std::exchange(__rhs._M_bits, {}))
+ _M_sockfd(std::__exchange(__rhs._M_sockfd, -1)),
+ _M_bits(std::__exchange(__rhs._M_bits, {}))
{ }
__socket_impl&
operator=(__socket_impl&& __rhs)
{
_M_ctx = __rhs._M_ctx;
- _M_sockfd = std::exchange(__rhs._M_sockfd, -1);
- _M_bits = std::exchange(__rhs._M_bits, {});
+ _M_sockfd = std::__exchange(__rhs._M_sockfd, -1);
+ _M_bits = std::__exchange(__rhs._M_bits, {});
return *this;
}
@@ -615,7 +615,7 @@ inline namespace v1
{
__glibcxx_assert(is_open());
cancel(__ec);
- return std::exchange(_M_sockfd, -1);
+ return std::__exchange(_M_sockfd, -1);
}
template<typename _SettableSocketOption>
diff --git a/libstdc++-v3/include/std/algorithm b/libstdc++-v3/include/std/algorithm
index 9ce4aa8423d..c9df7eae1ff 100644
--- a/libstdc++-v3/include/std/algorithm
+++ b/libstdc++-v3/include/std/algorithm
@@ -57,7 +57,6 @@
#pragma GCC system_header
-#include <utility> // UK-300.
#include <bits/stl_algobase.h>
#include <bits/stl_algo.h>
#if __cplusplus > 201703L
diff --git a/libstdc++-v3/include/std/functional b/libstdc++-v3/include/std/functional
index f61f2ac8cfd..131e6629341 100644
--- a/libstdc++-v3/include/std/functional
+++ b/libstdc++-v3/include/std/functional
@@ -61,7 +61,6 @@
# include <unordered_map>
# include <vector>
# include <array>
-# include <utility>
# include <bits/stl_algo.h>
#endif
#if __cplusplus > 201703L
diff --git a/libstdc++-v3/include/std/regex b/libstdc++-v3/include/std/regex
index cd33f26af0d..e623a6ed498 100644
--- a/libstdc++-v3/include/std/regex
+++ b/libstdc++-v3/include/std/regex
@@ -47,7 +47,6 @@
#include <stack>
#include <stdexcept>
#include <string>
-#include <utility>
#include <vector>
#include <map>
#include <cstring>
@@ -55,6 +54,7 @@
#include <ext/aligned_buffer.h>
#include <ext/numeric_traits.h>
#include <bits/std_function.h>
+#include <bits/stl_pair.h>
#include <bits/regex_constants.h>
#include <bits/regex_error.h>
#include <bits/regex_automaton.h>
diff --git a/libstdc++-v3/src/filesystem/ops-common.h b/libstdc++-v3/src/filesystem/ops-common.h
index 529d4e09016..43311e6c38f 100644
--- a/libstdc++-v3/src/filesystem/ops-common.h
+++ b/libstdc++-v3/src/filesystem/ops-common.h
@@ -26,6 +26,7 @@
#define _GLIBCXX_OPS_COMMON_H 1
#include <chrono>
+#include <bits/move.h> // std::__exchange
#ifdef _GLIBCXX_HAVE_UNISTD_H
# include <unistd.h>
@@ -407,7 +408,7 @@ _GLIBCXX_BEGIN_NAMESPACE_FILESYSTEM
struct CloseFD {
~CloseFD() { if (fd != -1) posix::close(fd); }
- bool close() { return posix::close(std::exchange(fd, -1)) == 0; }
+ bool close() { return posix::close(std::__exchange(fd, -1)) == 0; }
int fd;
};
diff --git a/libstdc++-v3/testsuite/20_util/default_delete/48631_neg.cc b/libstdc++-v3/testsuite/20_util/default_delete/48631_neg.cc
index 5de981665d9..3e80b73603e 100644
--- a/libstdc++-v3/testsuite/20_util/default_delete/48631_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/default_delete/48631_neg.cc
@@ -26,4 +26,4 @@ struct D : B { };
D d;
std::default_delete<B[]> db;
typedef decltype(db(&d)) type; // { dg-error "no match" }
-// { dg-error "no type" "" { target *-*-* } 116 }
+// { dg-prune-output "no type named 'type' in 'struct std::enable_if" }
diff --git a/libstdc++-v3/testsuite/20_util/default_delete/void_neg.cc b/libstdc++-v3/testsuite/20_util/default_delete/void_neg.cc
index 217c39b5eb4..ac4eabc5341 100644
--- a/libstdc++-v3/testsuite/20_util/default_delete/void_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/default_delete/void_neg.cc
@@ -25,5 +25,5 @@ void test01()
{
std::default_delete<void> d;
d(nullptr); // { dg-error "here" }
- // { dg-error "incomplete" "" { target *-*-* } 81 }
+ // { dg-error "delete pointer to incomplete type" "" { target *-*-* } 0 }
}
diff --git a/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_copy/constrained.cc b/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_copy/constrained.cc
index ac9128e6a00..7946effcf3a 100644
--- a/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_copy/constrained.cc
+++ b/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_copy/constrained.cc
@@ -25,6 +25,7 @@
#include <span>
#include <string>
#include <vector>
+#include <utility>
#include <testsuite_hooks.h>
#include <testsuite_iterators.h>
diff --git a/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_default_construct/constrained.cc b/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_default_construct/constrained.cc
index 05824c021a8..7267738a4af 100644
--- a/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_default_construct/constrained.cc
+++ b/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_default_construct/constrained.cc
@@ -25,6 +25,7 @@
#include <span>
#include <string>
#include <vector>
+#include <utility>
#include <testsuite_hooks.h>
#include <testsuite_iterators.h>
diff --git a/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_move/constrained.cc b/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_move/constrained.cc
index cc8cf0beef8..8759d042bb6 100644
--- a/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_move/constrained.cc
+++ b/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_move/constrained.cc
@@ -25,6 +25,7 @@
#include <span>
#include <string>
#include <vector>
+#include <utility>
#include <testsuite_hooks.h>
#include <testsuite_iterators.h>
diff --git a/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_value_construct/constrained.cc b/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_value_construct/constrained.cc
index efcf138dd5f..164d9ca667b 100644
--- a/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_value_construct/constrained.cc
+++ b/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_value_construct/constrained.cc
@@ -25,6 +25,7 @@
#include <span>
#include <string>
#include <vector>
+#include <utility>
#include <testsuite_hooks.h>
#include <testsuite_iterators.h>
diff --git a/libstdc++-v3/testsuite/23_containers/vector/cons/destructible_debug_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/cons/destructible_debug_neg.cc
index 2283d99b260..b85199e693f 100644
--- a/libstdc++-v3/testsuite/23_containers/vector/cons/destructible_debug_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/vector/cons/destructible_debug_neg.cc
@@ -46,7 +46,7 @@ test02()
// { dg-error "value type is destructible" "" { target *-*-* } 0 }
// In Debug Mode the "required from here" errors come from <debug/vector>
-// { dg-error "required from here" "" { target *-*-* } 173 }
+// { dg-error "required from here" "" { target *-*-* } 172 }
// Needed because of PR c++/92193
// { dg-prune-output "deleted function" }
^ permalink raw reply [flat|nested] 3+ messages in thread
* [committed] [3/2] testsuite: Add missing C++ includes to tests [PR101646]
2021-07-27 12:16 ` [committed] [2/2] libstdc++: Remove unnecessary uses of <utility> Jonathan Wakely
@ 2021-07-27 20:38 ` Jonathan Wakely
0 siblings, 0 replies; 3+ messages in thread
From: Jonathan Wakely @ 2021-07-27 20:38 UTC (permalink / raw)
To: libstdc++, gcc-patches
[-- Attachment #1: Type: text/plain, Size: 280 bytes --]
These tests stopped working after some libstdc++ refactoring, because
they aren't including what they use.
I committed a blank ChangeLog (I did 'git push' when I meant to push
to the compile farm, oops) so I'll fix that tomorrow.
Tested powerpc64le-linux. Committed to trunk.
[-- Attachment #2: patch.txt --]
[-- Type: text/x-patch, Size: 1206 bytes --]
commit b7195fb01fe62a313ae5f7faede698101bdb3025
Author: Jonathan Wakely <jwakely@redhat.com>
Date: Tue Jul 27 21:29:10 2021
testsuite: Add missing C++ includes to tests [PR101646]
These tests stopped working after some libstdc++ refactoring, because
they aren't including what they use.
gcc/testsuite/ChangeLog:
PR testsuite/101646
* g++.dg/coroutines/pr99047.C:
* g++.dg/pr71655.C:
diff --git a/gcc/testsuite/g++.dg/coroutines/pr99047.C b/gcc/testsuite/g++.dg/coroutines/pr99047.C
index 124633a08e6..05ce08567b2 100644
--- a/gcc/testsuite/g++.dg/coroutines/pr99047.C
+++ b/gcc/testsuite/g++.dg/coroutines/pr99047.C
@@ -1,4 +1,5 @@
#include <optional>
+#include <utility>
#include <coroutine>
template <typename T>
diff --git a/gcc/testsuite/g++.dg/pr71655.C b/gcc/testsuite/g++.dg/pr71655.C
index 8ed33711c36..45943060bc5 100644
--- a/gcc/testsuite/g++.dg/pr71655.C
+++ b/gcc/testsuite/g++.dg/pr71655.C
@@ -5,6 +5,7 @@
#include <functional>
#include <valarray>
+#include <array>
extern int var_16, le_s5, le_s6, le_s9;
std::array<std::array<std::array<long, 8>, 4>, 24> v4;
extern std::array<std::array<int, 48>, 18> v15;
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2021-07-27 20:38 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-27 12:15 [committed] [1/2] libstdc++: Reduce header dependencies on <array> and <utility> Jonathan Wakely
2021-07-27 12:16 ` [committed] [2/2] libstdc++: Remove unnecessary uses of <utility> Jonathan Wakely
2021-07-27 20:38 ` [committed] [3/2] testsuite: Add missing C++ includes to tests [PR101646] Jonathan Wakely
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).