Bug 92546 - Large increase in preprocessed file sizes in C++2a mode
Summary: Large increase in preprocessed file sizes in C++2a mode
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: libstdc++ (show other bugs)
Version: 10.0
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
: 99958 (view as bug list)
Depends on:
Blocks:
 
Reported: 2019-11-17 15:49 UTC by Jonathan Wakely
Modified: 2023-05-12 14:47 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2019-11-18 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jonathan Wakely 2019-11-17 15:49:29 UTC
For <array>:

: | g++ -std=c++11 -P -E -x c++ - -include array | wc -l
5141
: | g++ -std=c++14 -P -E -x c++ - -include array | wc -l
5376
: | g++ -std=c++17 -P -E -x c++ - -include array | wc -l
5814
: | g++ -std=c++2a -P -E -x c++ - -include array | wc -l
7729

Some of this increase is due to the extra std::ranges code in <bits/range_access.h> so maybe that should be in a separate header, which is only included where needed. However, with GCC 9 <array> was 12kloc even in C++11 mode, so it's already much better (that changed with r272011).

For <vector> the increase for C++20 is much worse:

: | g++ -std=c++2a -P -E -x c++ - -include array | wc -l
7729
: | g++ -std=c++11 -P -E -x c++ - -include vector | wc -l
9191
: | g++ -std=c++14 -P -E -x c++ - -include vector | wc -l
9377
: | g++ -std=c++17 -P -E -x c++ - -include vector | wc -l
9910
: | g++ -std=c++2a -P -E -x c++ - -include vector | wc -l
18279

I think this is due to including the whole of <bits/stl_algo.h> in order to use std::remove and std::remove_if. Those two algos should be moved to another header (maybe <bits/stl_algobase.h> which is already included).
Comment 1 Jonathan Wakely 2019-11-17 16:04:26 UTC
Currently <span> includes the whole of <array>, but we might be able to avoid that so that <span> is more lightweight:

: | g++ -std=c++2a -P -E -x c++ - -include array | wc -l
7729
: | g++ -std=c++2a -P -E -x c++ - -include span | wc -l
9528
Comment 2 Jonathan Wakely 2019-11-18 14:43:17 UTC
<deque> and <string> would also benefit from moving remove and remove_if to <bits/stl_algobase.h>:

include/std/deque:#  include <bits/stl_algo.h> // For remove and remove_if
include/std/string:#  include <bits/stl_algo.h> // For remove and remove_if
include/std/vector:# include <bits/stl_algo.h> // For remove and remove_if
Comment 3 GCC Commits 2020-02-17 15:32:34 UTC
The master branch has been updated by Jonathan Wakely <redi@gcc.gnu.org>:

https://gcc.gnu.org/g:c03b53da9129ae2d5ac9629c4b874d0981a7d418

commit r10-6675-gc03b53da9129ae2d5ac9629c4b874d0981a7d418
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Mon Feb 17 14:30:02 2020 +0000

    libstdc++: Add lightweight replacement for std::numeric_limits (PR 92546)
    
    Many uses of std::numeric_limits in C++17 and C++20 features only really
    need the min(), max() and digits constants for integral types. By adding
    __detail::__int_limits we can avoid including the whole <limits> header.
    
    The <limits> header isn't especially large, but avoiding it still gives
    small savings in compilation time and memory usage for the compiler.
    
    There are also C++11 features that could benefit from this change (e.g.
    <bits/hashtable_policy.h> and <bits/uniform_int_dist.h>) but I won't
    change those until stage 1.
    
    The implementation of __int_limits assumes two's complement integers,
    which is true for all targets supported by GCC.
    
    	PR libstdc++/92546 (partial)
    	* include/Makefile.am: Add new header.
    	* include/Makefile.in: Regenerate.
    	* include/bits/int_limits.h: New header.
    	* include/bits/parse_numbers.h (__select_int::_Select_int): Replace
    	numeric_limits with __detail::__int_limits.
    	* include/std/bit (__rotl, __rotr, __countl_zero, __countl_one)
    	(__countr_zero, __countr_one, __popcount, __ceil2, __floor2, __log2p1):
    	Likewise.
    	* include/std/charconv (__to_chars_8, __from_chars_binary)
    	(__from_chars_alpha_to_num, from_chars): Likewise.
    	* include/std/memory_resource (polymorphic_allocator::allocate)
    	(polymorphic_allocator::allocate_object): Likewise.
    	* include/std/string_view (basic_string_view::_S_compare): Likewise.
    	* include/std/utility (in_range): Likewise.
    	* testsuite/20_util/integer_comparisons/in_range_neg.cc: Adjust for
    	extra error about incomplete type __int_limits<bool>.
    	* testsuite/26_numerics/bit/bit.count/countl_one.cc: Include <limits>.
    	* testsuite/26_numerics/bit/bit.count/countl_zero.cc: Likewise.
    	* testsuite/26_numerics/bit/bit.count/countr_one.cc: Likewise.
    	* testsuite/26_numerics/bit/bit.count/countr_zero.cc: Likewise.
    	* testsuite/26_numerics/bit/bit.count/popcount.cc: Likewise.
    	* testsuite/26_numerics/bit/bit.pow.two/ceil2_neg.cc: Likewise.
    	* testsuite/26_numerics/bit/bit.pow.two/ceil2.cc: Likewise.
    	* testsuite/26_numerics/bit/bit.pow.two/floor2.cc: Likewise.
    	* testsuite/26_numerics/bit/bit.pow.two/ispow2.cc: Likewise.
    	* testsuite/26_numerics/bit/bit.pow.two/log2p1.cc: Likewise.
    	* testsuite/26_numerics/bit/bit.rotate/rotl.cc: Likewise.
    	* testsuite/26_numerics/bit/bit.rotate/rotr.cc: Likewise.
Comment 4 GCC Commits 2020-02-17 15:47:15 UTC
The master branch has been updated by Jonathan Wakely <redi@gcc.gnu.org>:

https://gcc.gnu.org/g:9cd4eeefcc641dd70d026e08e9d218101b826c52

commit r10-6676-g9cd4eeefcc641dd70d026e08e9d218101b826c52
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Mon Feb 17 15:25:33 2020 +0000

    libstdc++: Reduce header dependencies for C++20 (PR 92546)
    
    In C++20 <memory> depends on <bits/ranges_unitialized.h> which
    depends on <bits/random.h> just for a single concept. Including
    <bits/random.h> also requires including <cmath>, which is huge due to
    the C++17 special functions.
    
    This change moves the concept to the <bits/uniform_int_dist.h> internal
    header that exists so that <bits/stl_algobase.h> doesn't need to include
    <bits/random.h>.
    
    	PR libstdc++/92546 (partial)
    	* include/bits/random.h (uniform_random_bit_generator): Move definition
    	to <bits/uniform_int_dist.h>.
    	* include/bits/ranges_algo.h: Include <bits/uniform_int_dist.h> instead
    	of <bits/random.h>.
    	* include/bits/ranges_algobase.h: Do not include <cmath>.
    	* include/bits/uniform_int_dist.h (uniform_random_bit_generator):
    	Move here.
    	* include/std/ranges: Do not include <limits>.
    	* testsuite/26_numerics/random/pr60037-neg.cc: Adjust dg-error lineno.
Comment 5 Jonathan Wakely 2020-02-19 13:25:44 UTC
Another way to reduce things would be to move tuple_size and tuple_element from <utility> to a new <bits/tuple.h> header, so that e.g. <ranges> doesn't need the whole of <utility>.
Comment 6 Richard Biener 2020-04-01 08:09:42 UTC
Desirable but not P1 - some "regression" is to be expected if you want to call it so (it's new features after all)
Comment 7 Jonathan Wakely 2020-04-01 08:45:56 UTC
Yes this is just a nice-to-have, not critical.

I already made some big improvements, but then some new features made the sizes jump up again. I'll take another look for low-hanging fruit, but if it doesn't happen for 10.1 it's not a big deal.
Comment 8 Jakub Jelinek 2020-05-07 11:56:25 UTC
GCC 10.1 has been released.
Comment 9 Richard Biener 2020-07-23 06:51:42 UTC
GCC 10.2 is released, adjusting target milestone.
Comment 10 Jonathan Wakely 2020-11-05 00:02:57 UTC
r11-4269 and r11-4270 made a bit difference on trunk.
Comment 11 Jonathan Wakely 2020-11-05 00:04:18 UTC
(In reply to Jonathan Wakely from comment #10)
> r11-4269 and r11-4270 made a bit difference on trunk.

s/bit/big/
Comment 12 GCC Commits 2020-11-19 13:36:26 UTC
The master branch has been updated by Jonathan Wakely <redi@gcc.gnu.org>:

https://gcc.gnu.org/g:b204d7722d30f44281dea3341070223475f1cff9

commit r11-5168-gb204d7722d30f44281dea3341070223475f1cff9
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Thu Nov 19 13:36:15 2020 +0000

    libstdc++: Move std::thread to a new header
    
    This makes it possible to use std::thread without including the whole of
    <thread>. It also makes this_thread::get_id() and this_thread::yield()
    available even when there is no gthreads support (e.g. when GCC is built
    with --disable-threads or --enable-threads=single).
    
    In order for the std::thread::id return type of this_thread::get_id() to
    be defined, std:thread itself is defined unconditionally. However the
    constructor that creates new threads is not defined for single-threaded
    builds. The thread::join() and thread::detach() member functions are
    defined inline for single-threaded builds and just throw an exception
    (because we know the thread cannot be joinable if the constructor that
    creates joinable threads doesn't exit).
    
    The thread::hardware_concurrency() member function is also defined
    inline and returns 0 (as suggested by the standard when the value "is
    not computable or well-defined").
    
    The main benefit for most targets is that other headers such as <future>
    do not need to include the whole of <thread> just to be able to create a
    std::thread. That avoids including <stop_token> and std::jthread where
    not required. This is another partial fix for PR 92546.
    
    This also means we can use this_thread::get_id() and this_thread::yield()
    in <stop_token> instead of using the gthread functions directly. This
    removes some preprocessor conditionals, simplifying the code.
    
    libstdc++-v3/ChangeLog:
    
            PR libstdc++/92546
            * include/Makefile.am: Add new <bits/std_thread.h> header.
            * include/Makefile.in: Regenerate.
            * include/std/future: Include new header instead of <thread>.
            * include/std/stop_token: Include new header instead of
            <bits/gthr.h>.
            (stop_token::_S_yield()): Use this_thread::yield().
            (_Stop_state_t::_M_requester): Change type to std::thread::id.
            (_Stop_state_t::_M_request_stop()): Use this_thread::get_id().
            (_Stop_state_t::_M_remove_callback(_Stop_cb*)): Likewise.
            Use __is_single_threaded() to decide whether to synchronize.
            * include/std/thread (thread, operator==, this_thread::get_id)
            (this_thread::yield): Move to new header.
            (operator<=>, operator!=, operator<, operator<=, operator>)
            (operator>=, hash<thread::id>, operator<<): Define even when
            gthreads not available.
            * src/c++11/thread.cc: Include <memory>.
            * include/bits/std_thread.h: New file.
            (thread, operator==, this_thread::get_id, this_thread::yield):
            Define even when gthreads not available.
            [!_GLIBCXX_HAS_GTHREADS] (thread::join, thread::detach)
            (thread::hardware_concurrency): Define inline.
Comment 13 GCC Commits 2020-11-20 13:27:41 UTC
The master branch has been updated by Jonathan Wakely <redi@gcc.gnu.org>:

https://gcc.gnu.org/g:640ebeb336050887cb57417b7568279c588088f0

commit r11-5199-g640ebeb336050887cb57417b7568279c588088f0
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Fri Nov 20 11:30:33 2020 +0000

    libstdc++: Remove <memory_resource> dependency from <regex> [PR 92546]
    
    Unlike the other headers that declare alias templates in namespace pmr,
    <regex> includes <memory_resource>. That was done because the
    pmr::string::const_iterator typedef requires pmr::string to be complete,
    which requires pmr::polymorphic_allocator<char> to be complete.
    
    By using __normal_iterator<const char*, pmr::string> instead of the
    const_iterator typedef we can avoid the completeness requirement.
    
    This makes <regex> smaller, by not requiring <memory_resource> and its
    <shared_mutex> dependency, which depends on <chrono>.  Backporting this
    will also help with PR 97876, where <stop_token> ends up being needed by
    <regex> via <memory_resource>.
    
    libstdc++-v3/ChangeLog:
    
            PR libstdc++/92546
            * include/std/regex (pmr::smatch, pmr::wsmatch): Declare using
            underlying __normal_iterator type, not nested typedef
            basic_string::const_iterator.
Comment 14 GCC Commits 2020-11-20 13:49:17 UTC
The releases/gcc-10 branch has been updated by Jonathan Wakely <redi@gcc.gnu.org>:

https://gcc.gnu.org/g:cbbc28706164873d0323d1a6c7988be3f4d971c9

commit r10-9057-gcbbc28706164873d0323d1a6c7988be3f4d971c9
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Fri Nov 20 11:30:33 2020 +0000

    libstdc++: Remove <memory_resource> dependency from <regex> [PR 92546]
    
    Unlike the other headers that declare alias templates in namespace pmr,
    <regex> includes <memory_resource>. That was done because the
    pmr::string::const_iterator typedef requires pmr::string to be complete,
    which requires pmr::polymorphic_allocator<char> to be complete.
    
    By using __normal_iterator<const char*, pmr::string> instead of the
    const_iterator typedef we can avoid the completeness requirement.
    
    This makes <regex> smaller, by not requiring <memory_resource> and its
    <shared_mutex> dependency, which depends on <chrono>.  Backporting this
    will also help with PR 97876, where <stop_token> ends up being needed by
    <regex> via <memory_resource>.
    
    libstdc++-v3/ChangeLog:
    
            PR libstdc++/92546
            * include/std/regex (pmr::smatch, pmr::wsmatch): Declare using
            underlying __normal_iterator type, not nested typedef
            basic_string::const_iterator.
    
    (cherry picked from commit 640ebeb336050887cb57417b7568279c588088f0)
Comment 15 Jonathan Wakely 2020-11-20 19:29:27 UTC
<algorithm> and <memory> got unavoidably bigger in C++20 due to the extra algos in std::ranges.

<valarray> includes <algorithm> so is larger. We can almost certainly replace <algorithm> with <bits/stl_algobase.h> and <bits/stl_algo.h> for <valarray>'s purposes, it doesn't use the ranges algos.

<chrono> got a little bigger for C++20, and will grow bigger when the timezone features are added. We should add <bits/chrono.h> with just duration, time_point, steady_clock and system_clock, for use in <thread>, <mutex> etc.

<iterator> has all the concepts stuff, and that makes a lot of other headers bigger. We might want to move common_iterator and counted_iterator out of <bits/stl_iterator.h> so they're only included by <iterator> and not the bits that <vector> etc. use.
Comment 16 Jonathan Wakely 2020-12-13 22:02:38 UTC
<functional> includes <vector> so std::boyer_moore_searcher can use std::vector, but it doesn't need it at all. Using std::unique_ptr<T[]> would do fine.
Comment 17 Jakub Jelinek 2021-01-28 16:29:53 UTC
Do we want to do further header reorganizations for GCC11 at this point, or defer to GCC12?
Comment 18 Jonathan Wakely 2021-01-28 17:07:49 UTC
Definitely defer.
I think we could remove the regression marker now too.
Comment 19 Jonathan Wakely 2021-04-08 08:47:21 UTC
(In reply to Jonathan Wakely from comment #16)
> <functional> includes <vector> so std::boyer_moore_searcher can use
> std::vector, but it doesn't need it at all. Using std::unique_ptr<T[]> would
> do fine.

We can't change that now though, because the C++17 ABI is stable. I have a patch for a lightweight vector that is ABI compatible though, so we could use that.
Comment 20 Jonathan Wakely 2021-04-08 08:50:54 UTC
As noted in PR 99958 comment 1, <algorithm> got biiiiig, because:

<string> is included by <bits/locale_classes.h> which is included by <bits/ios_base.h> which is included by <streambuf> which is included by <bits/streambuf_iterator.h> which is included by <iterator> which is included by <bits/ranges_algobase.h>.

<vector> is included by <functional>, which is included by <bits/glue_algorithm_defs.h>. That should not be including the whole of <functional>. It looks like it only needs <bits/stl_pair.h>.
Comment 21 Jonathan Wakely 2021-04-08 08:51:10 UTC
This seems to work:

diff --git a/libstdc++-v3/include/pstl/glue_algorithm_defs.h b/libstdc++-v3/include/pstl/glue_algorithm_defs.h
index 48bc56ae401..cef78e22e31 100644
--- a/libstdc++-v3/include/pstl/glue_algorithm_defs.h
+++ b/libstdc++-v3/include/pstl/glue_algorithm_defs.h
@@ -10,7 +10,7 @@
 #ifndef _PSTL_GLUE_ALGORITHM_DEFS_H
 #define _PSTL_GLUE_ALGORITHM_DEFS_H
 
-#include <functional>
+#include <bits/stl_pair.h>
 
 #include "execution_defs.h"
 
diff --git a/libstdc++-v3/include/pstl/utils.h b/libstdc++-v3/include/pstl/utils.h
index 1711f292678..69d78c3ca0f 100644
--- a/libstdc++-v3/include/pstl/utils.h
+++ b/libstdc++-v3/include/pstl/utils.h
@@ -10,8 +10,9 @@
 #ifndef _PSTL_UTILS_H
 #define _PSTL_UTILS_H
 
+#include <exception>
 #include <new>
-#include <iterator>
+#include <type_traits>
 
 namespace __pstl
 {

The <pstl/utils.h> header only requires declarations of std::bad_alloc and std::terminate(), but includes <exception> and <new> to get them. That could be reduced with some minor surgery.
Comment 22 Jonathan Wakely 2021-04-08 08:51:57 UTC
*** Bug 99958 has been marked as a duplicate of this bug. ***
Comment 23 Jonathan Wakely 2021-04-09 17:00:56 UTC
The other improvement we could make for C++20 is to replace <iterator> in <bits/ranges_algobase.h> with smaller pieces, as it doesn't need the definition of std::streambuf_iterator:

--- a/libstdc++-v3/include/bits/ranges_algobase.h
+++ b/libstdc++-v3/include/bits/ranges_algobase.h
@@ -33,7 +33,10 @@
 #if __cplusplus > 201703L
 
 #include <compare>
-#include <iterator>
+#include <bits/stl_iterator_base_types.h>
+#include <bits/stl_iterator_base_funcs.h>
+#include <bits/stl_iterator.h>
+#include <bits/range_access.h>
 #include <bits/ranges_base.h> // ranges::begin, ranges::range etc.
 #include <bits/invoke.h>      // __invoke
 #include <bits/cpp_type_traits.h> // __is_byte


And <bits/streambuf_iterator> doesn't need <streambuf>, just <iosfwd>.
Comment 24 GCC Commits 2021-10-01 19:40:12 UTC
The master branch has been updated by Jonathan Wakely <redi@gcc.gnu.org>:

https://gcc.gnu.org/g:acf3a21cbc26b39b73c0006300f35ff017ddd6cb

commit r12-4083-gacf3a21cbc26b39b73c0006300f35ff017ddd6cb
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Fri Oct 1 20:37:02 2021 +0100

    libstdc++: Reduce header dependencies for C++20 std::erase [PR92546]
    
    This reduces the preprocessed size of <deque>, <string> and <vector> by
    not including <bits/stl_algo.h> for std::remove and std::remove_if.
    
    Also unwrap iterators using __niter_base, to avoid redundant debug mode
    checks.
    
            PR libstdc++/92546
            * include/bits/erase_if.h (__erase_nodes_if): Use __niter_base to
            unwrap debug iterators.
            * include/bits/refwrap.h: Do not error if included in C++03.
            * include/bits/stl_algo.h (__remove_if): Move to ...
            * include/bits/stl_algobase.h (__remove_if): ... here.
            * include/std/deque (erase, erase_if): Use __remove_if instead of
            remove and remove_if.
            * include/std/string (erase, erase_if): Likewise.
            * include/std/vector (erase, erase_if): Likewise.
Comment 25 GCC Commits 2021-10-08 14:00:16 UTC
The master branch has been updated by Jonathan Wakely <redi@gcc.gnu.org>:

https://gcc.gnu.org/g:a1fc4075fcdf028f2e1dc00ce515a947127e2667

commit r12-4252-ga1fc4075fcdf028f2e1dc00ce515a947127e2667
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Thu Apr 8 10:01:08 2021 +0100

    libstdc++: Reduce header dependencies of <algorithm> in C++20 [PR 92546]
    
    The <bits/ranges_algobase.h> header doesn't need the stream and
    streambuf iterators, so don't include the whole of <iterator>.
    
    libstdc++-v3/ChangeLog:
    
            PR libstdc++/92546
            * include/bits/ranges_algobase.h: Replace <iterator> with a
            subset of the headers it includes.
Comment 26 GCC Commits 2022-03-17 17:52:06 UTC
The master branch has been updated by Jonathan Wakely <redi@gcc.gnu.org>:

https://gcc.gnu.org/g:00df7ee4474faca91d3460fe78a88e280c6c1126

commit r12-7691-g00df7ee4474faca91d3460fe78a88e280c6c1126
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Thu Mar 17 14:36:07 2022 +0000

    libstdc++: Avoid including <algorithm> in <filesystem> [PR92546]
    
    This only affects Windows, but reduces the preprocessed size of
    <filesystem> significantly.
    
    libstdc++-v3/ChangeLog:
    
            PR libstdc++/92546
            * include/bits/fs_path.h (path::make_preferred): Use
            handwritten loop instead of std::replace.
Comment 27 Jonathan Wakely 2022-03-18 10:42:22 UTC
pst/algorithm_impl.h includes <functional> just because it needs std::not_fn. We could move that to a separate header. Even without that, we could do:

--- a/libstdc++-v3/include/pstl/algorithm_impl.h
+++ b/libstdc++-v3/include/pstl/algorithm_impl.h
@@ -10,11 +10,12 @@
 #ifndef _PSTL_ALGORITHM_IMPL_H
 #define _PSTL_ALGORITHM_IMPL_H
 
-#include <iterator>
 #include <type_traits>
-#include <utility>
 #include <functional>
 #include <algorithm>
+#include <bits/stl_iterator_base_types.h>
+#include <bits/stl_iterator_base_funcs.h>
+#include <bits/stl_pair.h>
 
 #include "execution_impl.h"
 #include "memory_impl.h"


And similarly:

--- a/libstdc++-v3/include/pstl/glue_numeric_impl.h
+++ b/libstdc++-v3/include/pstl/glue_numeric_impl.h
@@ -10,7 +10,7 @@
 #ifndef _PSTL_GLUE_NUMERIC_IMPL_H
 #define _PSTL_GLUE_NUMERIC_IMPL_H
 
-#include <functional>
+#include <bits/stl_function.h>
 
 #include "utils.h"
 #include "numeric_fwd.h"


And:

--- a/libstdc++-v3/include/pstl/memory_impl.h
+++ b/libstdc++-v3/include/pstl/memory_impl.h
@@ -10,7 +10,8 @@
 #ifndef _PSTL_MEMORY_IMPL_H
 #define _PSTL_MEMORY_IMPL_H
 
-#include <iterator>
+#include <bits/move.h>
+#include <bits/stl_iterator_base_types.h>
 
 #include "unseq_backend_simd.h"
 

However, these headers come from upstream, so this would slightly complicate rebasing on new upstream versions.
Comment 28 GCC Commits 2022-03-18 10:46:32 UTC
The master branch has been updated by Jonathan Wakely <redi@gcc.gnu.org>:

https://gcc.gnu.org/g:ac73c944eac88f37db2767aa4acc7ff6f4983f21

commit r12-7699-gac73c944eac88f37db2767aa4acc7ff6f4983f21
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Thu Mar 17 16:45:43 2022 +0000

    libstdc++: Reduce header dependencies from PSTL headers [PR92546]
    
    This avoids including the whole of <functional> in <algorithm>, as the
    <pstl/glue_algorithm_defs.h> header only actually needs std::pair.
    
    This also avoids including <iterator> in <pstl/utils.h>, which only
    needs <type_traits>, std::bad_alloc, and std::terminate (which can be
    repalced with std::__terminate). This matters less, because
    <pstl/utils.h> is only included by the <pstl/*_impl.h> headers and they
    all use <iterator> anyway, and are only included by <execution>.
    
    libstdc++-v3/ChangeLog:
    
            PR libstdc++/92546
            * include/pstl/glue_algorithm_defs.h: Replace <functional> with
            <bits/stl_pair.h>.
            * include/pstl/utils.h: Replace <iterator> with <type_traits>.
            (__pstl::__internal::__except_handler): Use std::__terminate
            instead of std::terminate.
            * src/c++17/fs_path.cc: Include <array>.
            * testsuite/25_algorithms/adjacent_find/constexpr.cc: Include
            <functional>.
            * testsuite/25_algorithms/binary_search/constexpr.cc: Likewise.
            * testsuite/25_algorithms/clamp/constrained.cc: Likewise.
            * testsuite/25_algorithms/equal/constrained.cc: Likewise.
            * testsuite/25_algorithms/for_each/constrained.cc: Likewise.
            * testsuite/25_algorithms/includes/constrained.cc: Likewise.
            * testsuite/25_algorithms/is_heap/constexpr.cc: Likewise.
            * testsuite/25_algorithms/is_heap_until/constexpr.cc: Likewise.
            * testsuite/25_algorithms/is_permutation/constrained.cc: Include
            <iterator>.
            * testsuite/25_algorithms/is_sorted/constexpr.cc: Include
            <functional>.
            * testsuite/25_algorithms/is_sorted_until/constexpr.cc:
            Likewise.
            * testsuite/25_algorithms/lexicographical_compare/constexpr.cc:
            Likewise.
            * testsuite/25_algorithms/lexicographical_compare/constrained.cc:
            Likewise.
            * testsuite/25_algorithms/lexicographical_compare_three_way/1.cc:
            Include <array>.
            * testsuite/25_algorithms/lower_bound/constexpr.cc: Include
            <functional>.
            * testsuite/25_algorithms/max/constrained.cc: Likewise.
            * testsuite/25_algorithms/max_element/constrained.cc: Likewise.
            * testsuite/25_algorithms/min/constrained.cc: Likewise.
            * testsuite/25_algorithms/min_element/constrained.cc: Likewise.
            * testsuite/25_algorithms/minmax_element/constrained.cc:
            Likewise.
            * testsuite/25_algorithms/mismatch/constexpr.cc: Likewise.
            * testsuite/25_algorithms/move/93872.cc: Likewise.
            * testsuite/25_algorithms/move_backward/93872.cc: Include
            <iterator>.
            * testsuite/25_algorithms/nth_element/constexpr.cc: Include
            <functional>.
            * testsuite/25_algorithms/partial_sort/constexpr.cc: Likewise.
            * testsuite/25_algorithms/partial_sort_copy/constexpr.cc:
            Likewise.
            * testsuite/25_algorithms/search/constexpr.cc: Likewise.
            * testsuite/25_algorithms/search_n/constrained.cc: Likewise.
            * testsuite/25_algorithms/set_difference/constexpr.cc: Likewise.
            * testsuite/25_algorithms/set_difference/constrained.cc:
            Likewise.
            * testsuite/25_algorithms/set_intersection/constexpr.cc:
            Likewise.
            * testsuite/25_algorithms/set_intersection/constrained.cc:
            Likewise.
            * testsuite/25_algorithms/set_symmetric_difference/constexpr.cc:
            Likewise.
            * testsuite/25_algorithms/set_union/constexpr.cc: Likewise.
            * testsuite/25_algorithms/set_union/constrained.cc: Likewise.
            * testsuite/25_algorithms/sort/constexpr.cc: Likewise.
            * testsuite/25_algorithms/sort_heap/constexpr.cc: Likewise.
            * testsuite/25_algorithms/transform/constrained.cc: Likewise.
            * testsuite/25_algorithms/unique/constexpr.cc: Likewise.
            * testsuite/25_algorithms/unique/constrained.cc: Likewise.
            * testsuite/25_algorithms/unique_copy/constexpr.cc: Likewise.
            * testsuite/25_algorithms/upper_bound/constexpr.cc: Likewise.
            * testsuite/std/ranges/adaptors/elements.cc: Include <vector>.
            * testsuite/std/ranges/adaptors/lazy_split.cc: Likewise.
            * testsuite/std/ranges/adaptors/split.cc: Likewise.
Comment 29 Jonathan Wakely 2022-03-18 10:57:50 UTC
Avoiding <functional> makes a big difference:

$ : | g++-11 -std=gnu++17 -P -E -x c++ - -include algorithm | wc -l
27018
$ : | g++-11 -std=gnu++17 -P -E -x c++ - -include algorithm | wc -l
25188
$ : | g++-12 -std=gnu++17 -P -E -x c++ - -include algorithm | wc -l
12268

$ : | g++-11 -std=gnu++20 -P -E -x c++ - -include algorithm | wc -l
45780
$ : | g++-11 -std=gnu++20 -P -E -x c++ - -include algorithm | wc -l
42404
$ : | g++-12 -std=gnu++20 -P -E -x c++ - -include algorithm | wc -l
20918


Improvements still to be done (in stage 1):

- Replace std::vector in <functional> (comment 19)
- Replace std::vector in <memory_resource>
- Reduce PSTL includes (comment 27)
Comment 30 Jonathan Wakely 2022-03-18 11:00:56 UTC
(In reply to Jonathan Wakely from comment #29)
> Avoiding <functional> makes a big difference:
> 
> $ : | g++-11 -std=gnu++17 -P -E -x c++ - -include algorithm | wc -l
> 27018

Doh, pasted the wrong line, the first number is g++-10 not g++-11


> $ : | g++-11 -std=gnu++17 -P -E -x c++ - -include algorithm | wc -l
> 25188
> $ : | g++-12 -std=gnu++17 -P -E -x c++ - -include algorithm | wc -l
> 12268
> 
> $ : | g++-11 -std=gnu++20 -P -E -x c++ - -include algorithm | wc -l
> 45780

Same here

> $ : | g++-11 -std=gnu++20 -P -E -x c++ - -include algorithm | wc -l
> 42404
> $ : | g++-12 -std=gnu++20 -P -E -x c++ - -include algorithm | wc -l
> 20918
Comment 31 Jonathan Wakely 2022-03-24 22:31:12 UTC
std::construct_at and std::destroy_at are in <bits/stl_construct.h> alongside std::_Construct and std::_Destroy. But the latter need iterator category definitions for destroying sequences. std::construct_at and std::destroy_at have no dependencies. They could be moved into <bits/move.h> or <bits/memoryfwd.h> or something smaller. This would benefit <expected> (and maybe other headers).
Comment 32 Jakub Jelinek 2022-05-06 08:30:12 UTC
GCC 12.1 is being released, retargeting bugs to GCC 12.2.
Comment 33 Richard Biener 2022-08-19 08:23:36 UTC
GCC 12.2 is being released, retargeting bugs to GCC 12.3.
Comment 34 Richard Biener 2023-05-08 12:21:41 UTC
GCC 12.3 is being released, retargeting bugs to GCC 12.4.
Comment 35 Jonathan Wakely 2023-05-12 14:47:22 UTC
<random> includes <string> just so that std::random_device can do:

    random_device() { _M_init("default"); }

    explicit
    random_device(const std::string& __token) { _M_init(__token); }

If we didn't need to construct a string in the default constructor, we could avoid including all of <string> in <random> and just include <bits/stringfwd.h> instead.