# C++ 2020

In this implementation the `-std=gnu++2a` or `-std=c++2a` flag must be used to enable language and library features. See dialect options. The pre-defined symbol `__cplusplus` is used to check for the presence of the required flag.

This section describes the C++20 and library TS support in mainline GCC, not in any particular release.

The following table lists new library features that have been accepted into the C++20 working draft. The "Proposal" column provides a link to the ISO C++ committee proposal that describes the feature, while the "Status" column indicates the first version of GCC that contains an implementation of this feature (if it has been implemented). A dash (—) in the status column indicates that the changes in the proposal either do not affect the code in libstdc++, or the changes are not required for conformance. The "SD-6 Feature Test / Notes" column shows the corresponding macro or header from SD-6: Feature-testing recommendations for C++ (where applicable) or any notes about the implementation.

## C++ 2020 Library Features

Library Feature | Proposal | Status | SD-6 Feature Test / Notes
Compile-time programming
Add constexpr modifiers to functions in `<algorithm>` and `<utility>` Headers | P0202R3 | 10.1 | `__cpp_lib_constexpr_algorithms >= 201703L`
Constexpr for `swap` and swap related functions | P0879R0 | 10.1 | `__cpp_lib_constexpr_algorithms >= 201806L`
Constexpr for `std::complex` | P0415R1 | 9.1 | `__cpp_lib_constexpr_complex >= 201711L` (since 9.4, see Note 1)
P0595R2 `std::is_constant_evaluated()` | P0595R2 | 9.1 | `__cpp_lib_is_constant_evaluated >= 201811L`
More constexpr containers | P0784R7 | 10.1 | `__cpp_lib_constexpr_dynamic_alloc >= 201907L`
Making `std::string` constexpr | P0980R1 |  | `__cpp_lib_constexpr_string >= 201907L`
Making `std::vector` constexpr | P1004R2 |  | `__cpp_lib_constexpr_vector >= 201907L`
Constexpr in `std::pointer_traits` | P1006R1 | 9.1 | `__cpp_lib_constexpr_memory >= 201811L` (since 9.4, see Note 1)
constexpr for `<numeric>` algorithms | P1645R1 | 10.1 | `__cpp_lib_constexpr_numeric >= 201911L`
Constexpr iterator requirements | P0858R0 | 9.1 |

`__cpp_lib_array_constexpr >= 201803L`
`__cpp_lib_string_view >= 201803L`
(both since 9.4, see Note 1)

`constexpr` comparison operators for `std::array` | P1023R0 | 10.1 | `__cpp_lib_array_constexpr >= 201806`
Misc constexpr bits | P1032R1 | 10.1 |

`__cpp_lib_array_constexpr >= 201811L`
`__cpp_lib_constexpr_functional >= 201811L`
`__cpp_lib_constexpr_iterator >= 201811L`
`__cpp_lib_constexpr_string_view >= 201811L`
`__cpp_lib_constexpr_tuple >= 201811L`
`__cpp_lib_constexpr_utility >= 201811L`

`constexpr INVOKE` | P1065R2 | 10.1 | `__cpp_lib_constexpr_functional >= 201907L`
Transformation Trait `remove_cvref` | P0550R2 | 9.1 | `__cpp_lib_remove_cvref >= 201711L` (since 9.4, see Note 1)
Implicit conversion traits and utility functions | P0758R1 | 9.1 | `__cpp_lib_is_nothrow_convertible >= 201806L` (since 9.4, see Note 1)
The `identity` metafunction | P0887R1 | 9.1 | `__cpp_lib_type_identity >= 201806L` (since 9.4, see Note 1)
`unwrap_ref_decay` and `unwrap_reference` | P0318R1 | 9.1 | `__cpp_lib_unwrap_ref >= 201811L` (since 9.4, see Note 1)
Improving Completeness Requirements for Type Traits | P1285R0 | Partial |
Missing feature test macros | P1353R0 | 9.1 |
Making std::underlying_type SFINAE-friendly | P0340R3 | 9.1 |
Traits for [Un]bounded Arrays | P1357R1 | 9.1 | `__cpp_lib_bounded_array_traits >= 201902L`
Layout-compatibility and pointer-interconvertibility traits | P0466R5 |  |

`__cpp_lib_is_layout_compatible >= 201907L`
`__cpp_lib_is_pointer_interconvertible >= 201907L`

Integrating feature-test macros into the C++ WD | P0941R2 | 5.1 |
`<version>` | P0754R2 | 9.1 | `__has_include(<version>)`
Synchronization
Atomic Ref | P0019R8 | 10.1 | `__cpp_lib_atomic_ref >= 201806L`
Floating Point Atomic | P0020R6 | 10.1 | `__cpp_lib_atomic_float >= 201711L`
C++ Synchronized Buffered Ostream | P0053R7 |  | `__cpp_lib_syncbuf >= 201711L`
Manipulators for C++ Synchronized Buffered Ostream | P0753R2 |  | `__cpp_lib_syncbuf >= 201803L`
Make `std::memory_order` a scoped enumeration | P0439R0 | 9.1 |
The Curious Case of Padding Bits, Featuring Atomic Compare-and-Exchange | P0528R3 |  |
Atomic `shared_ptr` | P0718R2 |  | `__cpp_lib_atomic_shared_ptr >= 201711L`
std::stop_token and std::jthread | P0660R10 | 10.1 | `__cpp_lib_jthread >= 201907L`
Rename `condition_variable_any` interruptible wait methods | P1869R1 | 10.1 | `__cpp_lib_jthread >= 201911L`
Atomic waiting and notifying, std::semaphore, std::latch and std::barrier | P1135R6 |  |

`__cpp_lib_atomic_lock_free_type_aliases >= 201907L`
`__cpp_lib_atomic_flag_test >= 201907L`
`__cpp_lib_atomic_wait >= 201907L`
`__cpp_lib_semaphore >= 201907L`
`__cpp_lib_latch >= 201907L`
`__cpp_lib_barrier >= 201907L`

Fixing Atomic Initialization | P0883R2 | 10.1 | `__cpp_lib_atomic_value_initialization >= 201911L`
Ranges and Concepts
Standard Library Concepts | P0898R3 | 10.1 | `__cpp_lib_concepts >= 201806L`
Rename concepts to standard_case for C++20, while we still can | P1754R1 | 10.1 | `__cpp_lib_concepts >= 201907L`
Wording for `boolean-testable` | P1964R2 | 10.1 | `__cpp_lib_concepts >= 202002L`
The One Ranges Proposal | P0896R4 | 10.1 | `__cpp_lib_ranges >= 201811L`
Input Range Adaptors | P1035R7 | 10.1 | `__cpp_lib_ranges >= 201907L`
`ranges` compare algorithm are over-constrained | P1716R3 | 10.1 | `__cpp_lib_ranges >= 201911L`
Remove CommonReference requirement from StrictWeakOrdering (a.k.a Fixing Relations) | P1248R1 | 10.1 |
Ranges Design Cleanup | P1252R2 | 10.1 |
Time, dates, calendars, time zones
Extending chrono to Calendars and Time Zones | P0355R7 |  | `__cpp_lib_chrono >= 201803L`
Miscellaneous minor fixes for chrono | P1466R3 |  | `__cpp_lib_chrono >= 201907L`
`<chrono>` `zero()`, `min()`, and `max()` should be `noexcept` | P0972R0 | 9.1 |
Three-way comparison
Library Support for the Spaceship (Comparison) Operator | P0768R1 | 10.1 | `__cpp_lib_three_way_comparison >= 201711L`
Symmetry for spaceship | P0905R1 | 10.1 |
Adding <=> to the standard library | P1614R2 | 10.1 | `__cpp_lib_three_way_comparison >= 201907L`
Strings and text
`string::reserve` Should Not Shrink | P0966R1 |  |
`char8_t`: A type for UTF-8 characters and strings | P0482R6 | 9.1 | `__cpp_lib_char8_t >= 201811L`
`char8_t` backward compatibility remediation | P1423R3 | 10.1 | `__cpp_lib_char8_t >= 201907L`
Text formatting | P0645R10 |  | `__cpp_lib_format >= 201907L`
Integration of chrono with text formatting | P1361R2 |  | `__cpp_lib_format >= 201907L`
Printf corner cases in `std::format` | P1652R1 |  | `__cpp_lib_format >= 201907L`
String Prefix and Suffix Checking | P0457R2 | 9.1 | `__cpp_lib_starts_ends_with >= 201711L` (since 9.4, see Note 1)
Update The Reference To The Unicode Standard | P1025R1 |  |
Containers
span: bounds-safe views for sequences of objects | P0122R7 | 10.1 | `__cpp_lib_span >= 201803L`
Usability Enhancements for `std::span` | P1024R3 | 10.1 | `__cpp_lib_span >= 201902L`
Should Span be Regular? | P1085R2 | 10.1 |
Fixed-size `<span>` construction from dynamic range | P1976R2 | 10.1 | `__cpp_lib_span >= 202002L`
`std::to_array` | P0325R4 | 10.1 | `__cpp_lib_to_array >= 201907L`
Checking for Existence of an Element in Associative Containers | P0458R2 | 9.1 |
Comparing Unordered Containers | P0809R0 |  |
Heterogeneous lookup for unordered containers | P0919R3 |  | `__cpp_lib_generic_unordered_lookup >= 201811`
Adopt Consistent Container Erasure from Library Fundamentals 2 for C++20 | P1209R0 | 9.1 | `__cpp_lib_erase_if >= 201811L`
Improving the Return Value of Erase-Like Algorithms | P0646R1 | 9.1 | `__cpp_lib_list_remove_return_type >= 201806L`
Improving the Return Value of Erase-Like Algorithms II: Free `erase`/`erase_if` | P1115R3 | 9.1 |

`__cpp_lib_erase_if >= 202002L`
(defined to `201900L` for GCC 9.1 and 9.2 so use `> 201811L`)

Signed ssize() functions, unsigned size() functions | P1227R2 | 10.1 | `__cpp_lib_ssize >= 201902L`
Memory management
Utility to convert a pointer to a raw pointer | P0653R2 | 8.1 | `__cpp_lib_to_address >= 201711L` (since 9.4, see Note 1)
Extending `make_shared` to Support Arrays | P0674R1 |  | `__cpp_lib_shared_ptr_arrays >= 201707L`
Efficient sized delete for variable sized classes | P0722R3 | 9.1 | `__cpp_lib_destroying_delete >= 201806L`
Utility functions to implement uses-allocator construction | P0591R4 | 9.1 | `std::scoped_allocator_adaptor` changes missing in 9.1.0
`std::assume_aligned` | P1007R3 | 9.1 | `__cpp_lib_assume_aligned >= 201811L` (since 9.4, see Note 1)
Smart pointer creation with default initialization | P1020R1 |  | `__cpp_lib_smart_ptr_for_overwrite >= 201811L`
Make stateful allocator propagation more consistent for `operator+(basic_string)` | P1165R1 | 10.1 |
`polymorphic_allocator<>` as a vocabulary type | P0339R6 | 9.1 | `__cpp_lib_polymorphic_allocator >= 201902L` (since 9.4, see Note 1)
LWG 2511: guaranteed copy elision for piecewise construction | P0475R1 | 7.1 |
Miscellaneous
`nodiscard` in the Library | P0600R1 | 9.1 |
de-pessimize legacy algorithms with `std::move` | P0616R0 | 9.1 |
Deprecate POD | P0767R1 | 10.1 |
Treating Unnecessary `decay` | P0777R1 | 9.1 |
Thou Shalt Not Specialize std Function Templates! | P0551R3 |  |
Bit-casting object representations | P0476R2 |  | `__cpp_lib_bit_cast >= 201806L`
Integral power-of-2 operations | P0556R3 | 9.1 | `__cpp_lib_int_pow2 >= 201806L` (since 9.4, see Note 1)
On the names of low-level bit manipulation functions | P1956R1 | 10.1 | `__cpp_lib_int_pow2 >= 202002L`
Safe integral comparisons | P0586R2 | 10.1 | `__cpp_lib_integer_comparison_functions >= 202002L`
Reviewing Deprecated Facilities of C++17 for C++20 | P0619R4 |  |
`fpos` Requirements | P0759R1 | — |
Add `shift` to `<algorithm>` | P0769R2 | 10.1 | `__cpp_lib_shift >= 201806L`
Standard Library Specification in a Concepts and Contracts World | P0788R3 |  |
`explicit(bool)` | P0892R2 | — |
Eradicating unnecessarily explicit default constructors from the standard library | P0935R0 | 9.1 |
`std::function` move constructor should be `noexcept` | P0771R1 | 7.2 |
Simplified partial function application | P0356R5 | 9.1 | `__cpp_lib_bind_front >= 201811L`
`bind_front` should not unwrap `reference_wrapper` | P1651R0 | 9.3 | `__cpp_lib_bind_front >= 201907L`
`reference_wrapper` for incomplete types | P0357R3 | 9.1 |
Fixing `operator>>(basic_istream&, CharT*)` (LWG 2499) | P0487R1 |  |
`variant` and `optional` should propagate copy/move triviality | P0602R4 | 8.3 |
A sane `variant` converting constructor | P0608R3 | 10.1 |
`visit<R>`: Explicit Return Type for `visit` | P0655R1 | 9.1 |
P0899R1 - LWG 3016 is not a defect | P0899R1 | 7.1 |
Editorial Guidance for merging P0019r8 and P0528r3 | P1123R0 | — |
Cleaning up Clause 20 | P1148R0 |  |
Completing the Rebase of Library Fundamentals, Version 3, Working Draft | P1210R0 |  |
Alternative Wording for P0907R4 Signed Integers are Two's Complement | P1236R1 | — |
I Stream, You Stream, We All Stream for `istream_iterator` | P0738R2 | 10.1 |
Mandating the Standard Library: Clause 16 - Language support library | P1458R1 | — |
Mandating the Standard Library: Clause 18 - Diagnostics library | P1459R1 | — |
Mandating the Standard Library: Clause 20 - Strings library | P1462R1 | — |
Mandating the Standard Library: Clause 21 - Containers library | P1463R1 | 10.1 |
Mandating the Standard Library: Clause 22 - Iterators library | P1464R1 |  |
Make `create_directory()` Intuitive | P1164R1 | 8.3 | Treated as a DR for C++17
Target Vectorization Policies from Parallelism V2 TS to C++20 | P1001R2 | 9.1 | `__cpp_lib_execution >= 201902L` (since 9.4, see Note 1)
Merge Coroutines TS into C++20 working draft | P0912R5 | 10.1 | `__cpp_lib_coroutines >= 201902L`
Endian just Endian | P0463R1 | 8.1 | `__cpp_lib_endian >= 201907L`
Bit operations | P0553R4 | 10.1 | `__cpp_lib_bitops >= 201907L` (since 9.4, see Note 1)
Well-behaved interpolation for numbers and pointers | P0811R3 | 9.1 | `__cpp_lib_interpolate >= 201902L`
Mathematical constants | P0631R8 | 10.1 | `__cpp_lib_math_constants >= 201907L`
std::source_location | P1208R6 |  | `__cpp_lib_source_location >= 201907L`
Efficient access to std::basic_stringbuf's Buffer | P0408R7 |  |

Note 1: This feature is supported in older releases but the `__cpp_lib` macro is not defined to the right value (or not defined at all) until the version shown in parentheses.