June 1, 2026

BSL Support for C++23

Introduction

BSL provides an allocator-aware standard library in the bsl namespace, together with aliases for standard library types, available across all supported platforms and language modes back to C++03.

Over the past year, we have been working to align BSL with C++23. All changes described here are available as of BDE 4.38.0. Where noted, individual features are backported to older language modes; all other additions require a platform that supports the C++23 standard library (indicated by BSLS_LIBRARYFEATURES_HAS_CPP23_BASELINE_LIBRARY or one of the more specific BSLS_LIBRARYFEATURES_HAS_CPP23_* macros described below).

For C++23 features not yet available in this release, see C++23 Features Planned for Future Releases.

Notable New Features

Additional feature test macros

BDE has added a number of new BSLS_LIBRARYFEATURES_HAS_CPP23_* feature test macros (detailed in the Feature-Detection Macros section below). The most broadly useful is BSLS_LIBRARYFEATURES_HAS_CPP23_BASELINE_LIBRARY, which indicates the availability of a representative selection of C++23 standard library features and is currently set on the following platforms:

  • GCC 13 (libstdc++ 13)

  • Clang compiling against libc++ version 18

  • Visual Studio 2022 update 17.6 / MSVC 19.36

Ranges-Aware Construction and Insertion for bsl Containers

All bsl sequence containers (bsl::vector, bsl::deque, bsl::list, bsl::string), ordered associative containers (bsl::map, bsl::set, bsl::multimap, bsl::multiset), and unordered associative containers (bsl::unordered_map, bsl::unordered_set, bsl::unordered_multimap, bsl::unordered_multiset) now support C++23 ranges-aware construction and insertion, backported to all language modes back to C++03.

Containers now support the bsl::from_range tag constructor and methods such as append_range, assign_range, insert_range, and push_range, accepting any type satisfying std::ranges::range directly.

A common pre-C++23 pain point was constructing a container from a temporary range object: begin() and end() must be called on the same object, so you could not pass a temporary directly to the iterator-pair constructor — a named variable was required. The from_range constructor resolves this:

// Before: named variable required to keep the tokenizer alive
bdlb::Tokenizer tokenizer(text, " ");
bsl::vector<bsl::string_view> tokens(tokenizer.begin(), tokenizer.end());

// Now: pass directly using the from_range constructor
bsl::vector<bsl::string_view> tokens(bsl::from_range,
                                     bdlb::Tokenizer(text, " "));

In C++20 and later, lazy range pipelines produce non-common ranges (where the end sentinel type differs from the iterator type) that cannot be passed to iterator-pair constructors without first converting them via bsl::views::common. The new range-aware methods accept non-common ranges directly:

// Before: views::common required to satisfy iterator-pair constructor
auto pipeline = source | bsl::views::filter([](int x) { return x > 0; })
                       | bsl::views::common;
positives.insert(positives.end(), pipeline.begin(), pipeline.end());

// Now: append_range accepts non-common ranges directly
positives.append_range(source | bsl::views::filter([](int x) { return x > 0; }));

The container adaptors bsl::stack, bsl::queue, and bsl::priority_queue likewise gain from_range tag constructors and push_range methods.

bsl::print and bsl::println: C++23 Print Facility

<bsl_print.h> provides bsl::print and bsl::println as a backport of the C++23 <print> facility, available in all language modes back to C++03. On platforms with a C++23 standard library these delegate to the native implementation; elsewhere they are backed by BDE’s bslfmt formatter.

The following functions are provided:

  • bsl::print(fmt, args...)

  • bsl::println(fmt, args...)

  • bsl::vprint_nonunicode(fmt, args)

  • bsl::vprint_nonunicode_buffered(fmt, args)

  • bsl::vprint_unicode(fmt, args)

  • bsl::vprint_unicode_buffered(fmt, args)

BDE deviates slightly from the standard here: in C++23, <ostream> includes std::print overloads for output streams, but <bsl_ostream.h> does not include the corresponding bsl::print overloads. Those are available in the separate <bsl_print_ostream.h> header, which must be included explicitly to avoid pulling the full formatting machinery into every translation unit that uses <bsl_ostream.h>.

Monadic Operations for bsl::optional

bsl::optional now provides the C++23 monadic interface (requires C++17 or later):

  • and_then(f) – applies f to the contained value and returns its result (which must be a bsl::optional), or returns an empty optional if *this is disengaged.

  • or_else(f) – returns *this if engaged, or calls f() and returns its result otherwise.

  • transform(f) – applies f to the contained value and wraps the result in a new bsl::optional, or returns empty if disengaged.

These operations are not yet backported to C++03/11/14.

bsl::visit() for Types Derived from bsl::variant

bsl::visit() now correctly handles arguments whose static type is a class publicly derived from bsl::variant, rather than bsl::variant itself, as required by C++23.

Heterogeneous Erasure for Associative Containers

All bsl ordered and unordered associative containers now support heterogeneous erasure (C++23). When the container’s comparator or hash is tagged as transparent, erase(key) accepts any type comparable to the stored key type, eliminating unnecessary temporary key constructions.

bsl::basic_string::substr() &&

bsl::basic_string::substr() now has an rvalue-qualified overload. When called on a temporary (or explicitly moved) string, this overload can avoid a copy by moving the relevant portion of the source’s storage. This overload requires C++11 (BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS).

bsl::string::contains() and bsl::string_view::contains()

bsl::string and bsl::string_view now provide the C++23 contains() member function, testing whether the string contains a given substring, character, or string view.

bsl::string and bsl::string_view Construction from nullptr Prohibited

As required by C++23 (P2166), bsl::string and bsl::string_view now have a deleted constructor taking bsl::nullptr_t, making constructions such as:

bsl::string      s(nullptr); // error: deleted
bsl::string_view v(nullptr); // error: deleted

a compile-time error rather than silent undefined behavior.

Because the deleted constructor takes bsl::nullptr_t, overload resolution selects it for any null pointer constant — defined by the C++ standard as an integer literal with value zero or a prvalue of type std::nullptr_t. This covers nullptr, 0, NULL, and bsl::nullptr_t variables. A const char* variable is not a null pointer constant, even if its runtime value is null, and therefore does not select the deleted constructor:

bsl::string s(nullptr);     // error: deleted
bsl::string t(0);           // error: deleted
bsl::string u(NULL);        // error: deleted

const char* p = nullptr;
bsl::string v(p);           // still compiles; still undefined behavior

The deleted constructors use = delete, which requires C++11; in C++03 mode this protection is unavailable.

C++23 Features Planned for Future Releases

bsl::expected

bsl::expected<T, E> (P0323) is a vocabulary type that holds either a value of type T or an error of type E, providing a composable alternative to error codes or exceptions. A BDE-native allocator-aware implementation is in progress.

bsl::move_only_function and bsl::copyable_function

bsl::move_only_function (P0288) is a move-only general-purpose callable wrapper that avoids the unnecessary copyability requirement of bsl::function. bsl::copyable_function (P2548) is a copyable wrapper with correct const-propagating call semantics: calling a const bsl::copyable_function requires a const-qualified call operator, unlike bsl::function. Both are in progress.

bsl::flat_map, bsl::flat_set, and Variants

bsl::flat_map, bsl::flat_set, bsl::flat_multimap, and bsl::flat_multiset (P1222) are ordered associative containers backed by contiguous storage (by default bsl::vector), offering cache-friendly iteration at the cost of O(n) insertion. Their addition is deferred pending GCC 15 availability on BDE target platforms, which is required for thorough allocator-propagation testing.

For users needing flat containers today, bdlc::FlatHashMap and bdlc::FlatHashSet provide high-performance open-addressing hash tables with flat (contiguous) storage, available in all language modes back to C++03. Note that these are unordered containers and are not a direct substitute for the sorted bsl::flat_map family.

Other Deferred Features

  • constexpr support for bsl::optional, bsl::variant, and bsl::bitset — deferred pending constexpr-capable construction utilities in BDE.

  • Range formatting via bsl::format (formatting containers and views directly with "{}") — a partial backport supporting BDE containers is under investigation; full support for arbitrary ranges is expected to rely on the platform’s native C++23 std::format.

Feature-Detection Macros

The following BSLS_LIBRARYFEATURES_HAS_CPP23_* macros were introduced or are relevant to the features described in this article.

Macro

Feature guarded

BSLS_LIBRARYFEATURES_HAS_CPP23_BASELINE_LIBRARY

Core C++23 library additions: byteswap, invoke_r, is_scoped_enum, to_underlying, unreachable, as_rvalue_view, chunk_by_view, repeat_view

BSLS_LIBRARYFEATURES_HAS_CPP23_ALLOCATE_AT_LEAST

bsl::allocation_result, bsl::allocator::allocate_at_least, bsl::allocator_traits::allocate_at_least

BSLS_LIBRARYFEATURES_HAS_CPP23_BIND_BACK

bsl::bind_back

BSLS_LIBRARYFEATURES_HAS_CPP23_CONTAINERS_RANGES

bsl::from_range_t / bsl::from_range available (always provided via BDE’s own implementation when the platform standard library does not supply them)

BSLS_LIBRARYFEATURES_HAS_CPP23_FORWARD_LIKE

bsl::forward_like (aliased from std::forward_like; bslmf::Util::forward_like is always available as BDE’s own implementation)

BSLS_LIBRARYFEATURES_HAS_CPP23_GENERATOR

<bsl_generator.h> / bsl::generator

BSLS_LIBRARYFEATURES_HAS_CPP23_IS_IMPLICIT_LIFETIME

bsl::is_implicit_lifetime

BSLS_LIBRARYFEATURES_HAS_CPP23_MDSPAN

<bsl_mdspan.h> / bsl::mdspan

BSLS_LIBRARYFEATURES_HAS_CPP23_OUT_PTR

bsl::out_ptr, bsl::out_ptr_t, bsl::inout_ptr, bsl::inout_ptr_t

BSLS_LIBRARYFEATURES_HAS_CPP23_PRINT

Native <print> header with C++26 DRs applied (__cpp_lib_print >= 202403L)

BSLS_LIBRARYFEATURES_HAS_CPP23_RANGE_ADAPTOR_CLOSURE

bsl::ranges::range_adaptor_closure

BSLS_LIBRARYFEATURES_HAS_CPP23_RANGES_AS_CONST

bsl::views::as_const, bsl::basic_const_iterator, etc.

BSLS_LIBRARYFEATURES_HAS_CPP23_RANGES_CARTESIAN_PRODUCT

bsl::views::cartesian_product

BSLS_LIBRARYFEATURES_HAS_CPP23_RANGES_CHUNK

bsl::views::chunk

BSLS_LIBRARYFEATURES_HAS_CPP23_RANGES_CONTAINS

bsl::ranges::contains, bsl::ranges::contains_subrange

BSLS_LIBRARYFEATURES_HAS_CPP23_RANGES_ENUMERATE

bsl::views::enumerate

BSLS_LIBRARYFEATURES_HAS_CPP23_RANGES_FIND_LAST

bsl::ranges::find_last, find_last_if, find_last_if_not

BSLS_LIBRARYFEATURES_HAS_CPP23_RANGES_FOLD

bsl::ranges::fold_left, fold_right, etc.

BSLS_LIBRARYFEATURES_HAS_CPP23_RANGES_IOTA

bsl::ranges::iota, bsl::ranges::iota_result

BSLS_LIBRARYFEATURES_HAS_CPP23_RANGES_JOIN_WITH

bsl::views::join_with

BSLS_LIBRARYFEATURES_HAS_CPP23_RANGES_SHIFT

bsl::ranges::shift_left, bsl::ranges::shift_right

BSLS_LIBRARYFEATURES_HAS_CPP23_RANGES_SLIDE

bsl::views::slide

BSLS_LIBRARYFEATURES_HAS_CPP23_RANGES_STARTS_ENDS_WITH

bsl::ranges::starts_with, bsl::ranges::ends_with

BSLS_LIBRARYFEATURES_HAS_CPP23_RANGES_STRIDE

bsl::views::stride

BSLS_LIBRARYFEATURES_HAS_CPP23_RANGES_TO_CONTAINER

bsl::ranges::to

BSLS_LIBRARYFEATURES_HAS_CPP23_RANGES_ZIP

bsl::views::zip, adjacent, and related views

BSLS_LIBRARYFEATURES_HAS_CPP23_REFERENCE_FROM_TEMPORARY

bsl::reference_constructs_from_temporary, etc.

BSLS_LIBRARYFEATURES_HAS_CPP23_SPANSTREAM

<bsl_spanstream.h> / bsl::spanstream

BSLS_LIBRARYFEATURES_HAS_CPP23_STACKTRACE

<bsl_stacktrace.h> / bsl::stacktrace

BSLS_LIBRARYFEATURES_HAS_CPP23_START_LIFETIME_AS

bsl::start_lifetime_as, bsl::start_lifetime_as_array

Summary of C++23 Features and Backporting


Feature C++23 Backporting
C++20 C++17 C++14 C++11 C++03
Feature-detection macros (BSLS_LIBRARYFEATURES_HAS_CPP23_*)
New standard library headers aliased
(bsl_generator.h, bsl_mdspan.h, bsl_spanstream.h, bsl_stacktrace.h, bsl_stdfloat.h)
C++23 aliases added to existing bsl headers
bsl::print / bsl::println
Ranges-aware construction / insertion for containers
(from_range, append_range, insert_range, …)
Ranges-aware construction / insertion for container adaptors
(bsl::stack, bsl::queue, bsl::priority_queue)
bsl::string::contains() / bsl::string_view::contains()
bsl::basic_string::substr() &&
Heterogeneous erasure for associative containers
Monadic operations for bsl::optional
(and_then, or_else, transform)
bsl::visit() for types derived from bsl::variant
Construction from nullptr prohibited for bsl::string / bsl::string_view

 
 

Complete Description of Aliasing Changes

Aliasing: New headers added

The following headers were added to alias new C++23 standard library additions, and test drivers created:

Header file

Types aliased

bsl_generator.h


bsl::generator;

bsl_mdspan.h


bsl::mdspan;
bsl::extents;
bsl::dextents;
bsl::layout_left;
bsl::layout_right;
bsl::layout_stride;
bsl::default_accessor;

bsl_print.h


bsl::print;
bsl::println;
bsl::vprint_nonunicode;
bsl::vprint_nonunicode_buffered;
bsl::vprint_unicode;
bsl::vprint_unicode_buffered;

bsl_print_ostream.h


bsl::print; (ostream overload)
bsl::println; (ostream overload)
bsl::vprint_nonunicode;
bsl::vprint_unicode;

bsl_spanstream.h


bsl::basic_spanbuf;
bsl::basic_ispanstream;
bsl::basic_ospanstream;
bsl::basic_spanstream;
bsl::spanbuf;
bsl::ispanstream;
bsl::ospanstream;
bsl::spanstream;
bsl::wspanbuf;
bsl::wispanstream;
bsl::wospanstream;
bsl::wspanstream;

bsl_stacktrace.h


bsl::stacktrace;
bsl::stacktrace_entry;
bsl::basic_stacktrace;

bsl_stdfloat.h


bsl::float16_t;
bsl::float32_t;
bsl::float64_t;
bsl::float128_t;
bsl::bfloat16_t;

Aliasing: Additions to existing headers

The following existing headers were enhanced with aliases to new C++23 standard library additions, with test drivers enhanced accordingly:

Header file

Types aliased

bsl_algorithm.h


//BSLS_LIBRARYFEATURES_HAS_CPP23_RANGES_SHIFT
bsl::ranges::shift_left;
bsl::ranges::shift_right;
//BSLS_LIBRARYFEATURES_HAS_CPP23_RANGES_STARTS_ENDS_WITH
bsl::ranges::starts_with;
bsl::ranges::ends_with;
//BSLS_LIBRARYFEATURES_HAS_CPP23_RANGES_FIND_LAST
bsl::ranges::find_last;
bsl::ranges::find_last_if;
bsl::ranges::find_last_if_not;
//BSLS_LIBRARYFEATURES_HAS_CPP23_RANGES_CONTAINS
bsl::ranges::contains;
bsl::ranges::contains_subrange;
//BSLS_LIBRARYFEATURES_HAS_CPP23_RANGES_FOLD
bsl::ranges::fold_left;
bsl::ranges::fold_left_with_iter;
bsl::ranges::fold_left_with_iter_result;
bsl::ranges::fold_left_first;
bsl::ranges::fold_left_first_with_iter;
bsl::ranges::fold_left_first_with_iter_result;
bsl::ranges::fold_right;
bsl::ranges::fold_right_last;
bsl::ranges::in_value_result;
//BSLS_LIBRARYFEATURES_HAS_CPP23_RANGES_IOTA
bsl::ranges::out_value_result;

bsl_bit.h


//BSLS_LIBRARYFEATURES_HAS_CPP23_BASELINE_LIBRARY
bsl::byteswap;

bsl_functional.h


//BSLS_LIBRARYFEATURES_HAS_CPP23_BASELINE_LIBRARY
bsl::invoke_r;
//BSLS_LIBRARYFEATURES_HAS_CPP23_BIND_BACK
bsl::bind_back;

bsl_iosfwd.h


//BSLS_LIBRARYFEATURES_HAS_CPP23_SPANSTREAM
bsl::basic_spanbuf;
bsl::basic_ispanstream;
bsl::basic_ospanstream;
bsl::basic_spanstream;
bsl::spanbuf;
bsl::ispanstream;
bsl::ospanstream;
bsl::spanstream;
bsl::wspanbuf;
bsl::wispanstream;
bsl::wospanstream;
bsl::wspanstream;

bsl_iterator.h


//BSLS_LIBRARYFEATURES_HAS_CPP23_RANGES_AS_CONST
bsl::const_iterator;
bsl::const_sentinel;
bsl::basic_const_iterator;
bsl::make_const_iterator;
bsl::make_const_sentinel;
bsl::iter_const_reference_t;

bsl_memory.h


//BSLS_LIBRARYFEATURES_HAS_CPP23_ALLOCATE_AT_LEAST
bsl::allocation_result;
//BSLS_LIBRARYFEATURES_HAS_CPP23_OUT_PTR
bsl::out_ptr;
bsl::out_ptr_t;
bsl::inout_ptr;
bsl::inout_ptr_t;
//BSLS_LIBRARYFEATURES_HAS_CPP23_START_LIFETIME_AS
bsl::start_lifetime_as;
bsl::start_lifetime_as_array;

bsl_numeric.h


//BSLS_LIBRARYFEATURES_HAS_CPP23_RANGES_IOTA
bsl::ranges::iota;
bsl::ranges::iota_result;

bsl_ranges.h


//BSLS_LIBRARYFEATURES_HAS_CPP23_BASELINE_LIBRARY
bsl::ranges::as_rvalue_view;
bsl::ranges::chunk_by_view;
bsl::ranges::repeat_view;
bsl::views::as_rvalue;
bsl::views::chunk_by;
bsl::views::repeat;
//BSLS_LIBRARYFEATURES_HAS_CPP23_RANGES_TO_CONTAINER
bsl::ranges::to;
//BSLS_LIBRARYFEATURES_HAS_CPP23_RANGE_ADAPTOR_CLOSURE
bsl::ranges::range_adaptor_closure;
//BSLS_LIBRARYFEATURES_HAS_CPP23_RANGES_AS_CONST
bsl::ranges::const_iterator_t;
bsl::ranges::const_sentinel_t;
bsl::ranges::range_const_reference_t;
bsl::ranges::constant_range;
bsl::ranges::as_const_view;
bsl::views::as_const;
//BSLS_LIBRARYFEATURES_HAS_CPP23_RANGES_CARTESIAN_PRODUCT
bsl::ranges::cartesian_product_view;
bsl::views::cartesian_product;
//BSLS_LIBRARYFEATURES_HAS_CPP23_RANGES_CHUNK
bsl::ranges::chunk_view;
bsl::views::chunk;
//BSLS_LIBRARYFEATURES_HAS_CPP23_RANGES_ENUMERATE
bsl::ranges::enumerate_view;
bsl::views::enumerate;
//BSLS_LIBRARYFEATURES_HAS_CPP23_RANGES_JOIN_WITH
bsl::ranges::join_with_view;
bsl::views::join_with;
//BSLS_LIBRARYFEATURES_HAS_CPP23_RANGES_SLIDE
bsl::ranges::slide_view;
bsl::views::slide;
//BSLS_LIBRARYFEATURES_HAS_CPP23_RANGES_STRIDE
bsl::ranges::stride_view;
bsl::views::stride;
//BSLS_LIBRARYFEATURES_HAS_CPP23_RANGES_ZIP
bsl::ranges::adjacent_view;
bsl::ranges::adjacent_transform_view;
bsl::ranges::zip_view;
bsl::ranges::zip_transform_view;
bsl::views::adjacent;
bsl::views::adjacent_transform;
bsl::views::zip;
bsl::views::zip_transform;
//BSLS_LIBRARYFEATURES_HAS_CPP23_GENERATOR
bsl::ranges::elements_of;
//BSLS_LIBRARYFEATURES_HAS_CPP23_CONTAINERS_RANGES
bsl::from_range;
bsl::from_range_t;

bsl_type_traits.h


//BSLS_LIBRARYFEATURES_HAS_CPP23_BASELINE_LIBRARY
bsl::is_scoped_enum;
bsl::is_scoped_enum_v;
//BSLS_LIBRARYFEATURES_HAS_CPP23_IS_IMPLICIT_LIFETIME
bsl::is_implicit_lifetime;
bsl::is_implicit_lifetime_v;
//BSLS_LIBRARYFEATURES_HAS_CPP23_REFERENCE_FROM_TEMPORARY
bsl::reference_constructs_from_temporary;
bsl::reference_constructs_from_temporary_v;
bsl::reference_converts_from_temporary;
bsl::reference_converts_from_temporary_v;

bsl_utility.h


//BSLS_LIBRARYFEATURES_HAS_CPP23_BASELINE_LIBRARY
bsl::to_underlying;
bsl::unreachable;
//BSLS_LIBRARYFEATURES_HAS_CPP23_FORWARD_LIKE
bsl::forward_like;