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).
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
<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
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.
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.
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>.
Desirable but not P1 - some "regression" is to be expected if you want to call it so (it's new features after all)
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.
GCC 10.1 has been released.
GCC 10.2 is released, adjusting target milestone.
r11-4269 and r11-4270 made a bit difference on trunk.
(In reply to Jonathan Wakely from comment #10) > r11-4269 and r11-4270 made a bit difference on trunk. s/bit/big/
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.
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.
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)
<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.
<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.
Do we want to do further header reorganizations for GCC11 at this point, or defer to GCC12?
Definitely defer. I think we could remove the regression marker now too.
(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.
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>.
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.
*** Bug 99958 has been marked as a duplicate of this bug. ***
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>.
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.
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.
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.
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.
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.
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)
(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
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).
GCC 12.1 is being released, retargeting bugs to GCC 12.2.
GCC 12.2 is being released, retargeting bugs to GCC 12.3.
GCC 12.3 is being released, retargeting bugs to GCC 12.4.
<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.