aboutsummaryrefslogtreecommitdiff
path: root/libcxx
diff options
context:
space:
mode:
Diffstat (limited to 'libcxx')
-rw-r--r--libcxx/CMakeLists.txt36
-rw-r--r--libcxx/docs/ABIGuarantees.rst10
-rw-r--r--libcxx/docs/AddingNewCIJobs.rst3
-rw-r--r--libcxx/docs/Contributing.rst63
-rw-r--r--libcxx/docs/FeatureTestMacroTable.rst2
-rw-r--r--libcxx/docs/Hardening.rst21
-rw-r--r--libcxx/docs/ReleaseNotes/22.rst12
-rw-r--r--libcxx/docs/Status/Cxx23Issues.csv2
-rw-r--r--libcxx/docs/Status/Cxx2cPapers.csv4
-rw-r--r--libcxx/docs/VendorDocumentation.rst66
-rw-r--r--libcxx/docs/index.rst2
-rw-r--r--libcxx/include/CMakeLists.txt10
-rw-r--r--libcxx/include/__algorithm/all_of.h16
-rw-r--r--libcxx/include/__algorithm/copy_n.h66
-rw-r--r--libcxx/include/__algorithm/fill_n.h57
-rw-r--r--libcxx/include/__algorithm/find.h3
-rw-r--r--libcxx/include/__algorithm/iterator_operations.h3
-rw-r--r--libcxx/include/__algorithm/none_of.h8
-rw-r--r--libcxx/include/__algorithm/ranges_copy_n.h29
-rw-r--r--libcxx/include/__algorithm/simd_utils.h26
-rw-r--r--libcxx/include/__algorithm/specialized_algorithms.h46
-rw-r--r--libcxx/include/__atomic/atomic.h2
-rw-r--r--libcxx/include/__atomic/atomic_flag.h2
-rw-r--r--libcxx/include/__atomic/atomic_ref.h2
-rw-r--r--libcxx/include/__atomic/atomic_sync.h152
-rw-r--r--libcxx/include/__atomic/contention_t.h30
-rw-r--r--libcxx/include/__bit/has_single_bit.h2
-rw-r--r--libcxx/include/__bit_reference54
-rw-r--r--libcxx/include/__charconv/from_chars_integral.h2
-rw-r--r--libcxx/include/__charconv/to_chars_integral.h1
-rw-r--r--libcxx/include/__compare/is_eq.h12
-rw-r--r--libcxx/include/__condition_variable/condition_variable.h2
-rw-r--r--libcxx/include/__config263
-rw-r--r--libcxx/include/__config_site.in5
-rw-r--r--libcxx/include/__configuration/abi.h1
-rw-r--r--libcxx/include/__configuration/availability.h68
-rw-r--r--libcxx/include/__configuration/experimental.h37
-rw-r--r--libcxx/include/__configuration/hardening.h215
-rw-r--r--libcxx/include/__configuration/language.h3
-rw-r--r--libcxx/include/__configuration/platform.h25
-rw-r--r--libcxx/include/__coroutine/coroutine_handle.h18
-rw-r--r--libcxx/include/__coroutine/noop_coroutine_handle.h10
-rw-r--r--libcxx/include/__cxx03/__fwd/ios.h2
-rw-r--r--libcxx/include/__cxx03/__locale2
-rw-r--r--libcxx/include/__cxx03/__locale_dir/locale_base_api.h2
-rw-r--r--libcxx/include/__cxx03/fstream2
-rw-r--r--libcxx/include/__cxx03/locale2
-rw-r--r--libcxx/include/__cxx03/regex6
-rw-r--r--libcxx/include/__exception/exception.h8
-rw-r--r--libcxx/include/__exception/exception_ptr.h2
-rw-r--r--libcxx/include/__exception/nested_exception.h2
-rw-r--r--libcxx/include/__exception/operations.h10
-rw-r--r--libcxx/include/__expected/expected.h3
-rw-r--r--libcxx/include/__filesystem/path.h8
-rw-r--r--libcxx/include/__filesystem/u8path.h16
-rw-r--r--libcxx/include/__flat_map/flat_map.h101
-rw-r--r--libcxx/include/__flat_map/utils.h1
-rw-r--r--libcxx/include/__flat_set/flat_set.h88
-rw-r--r--libcxx/include/__functional/bind.h24
-rw-r--r--libcxx/include/__functional/bind_back.h2
-rw-r--r--libcxx/include/__functional/bind_front.h2
-rw-r--r--libcxx/include/__functional/function.h6
-rw-r--r--libcxx/include/__functional/hash.h2
-rw-r--r--libcxx/include/__functional/mem_fn.h3
-rw-r--r--libcxx/include/__functional/reference_wrapper.h12
-rw-r--r--libcxx/include/__functional/weak_result_type.h42
-rw-r--r--libcxx/include/__fwd/ios.h2
-rw-r--r--libcxx/include/__hash_table2
-rw-r--r--libcxx/include/__iterator/wrap_iter.h4
-rw-r--r--libcxx/include/__locale5
-rw-r--r--libcxx/include/__locale_dir/locale_base_api.h26
-rw-r--r--libcxx/include/__locale_dir/locale_base_api/bsd_locale_fallbacks.h10
-rw-r--r--libcxx/include/__locale_dir/locale_base_api/ibm.h11
-rw-r--r--libcxx/include/__locale_dir/locale_base_api/musl.h31
-rw-r--r--libcxx/include/__locale_dir/messages.h2
-rw-r--r--libcxx/include/__locale_dir/num.h428
-rw-r--r--libcxx/include/__locale_dir/support/bsd_like.h19
-rw-r--r--libcxx/include/__locale_dir/support/fuchsia.h7
-rw-r--r--libcxx/include/__locale_dir/support/linux.h37
-rw-r--r--libcxx/include/__locale_dir/support/newlib.h243
-rw-r--r--libcxx/include/__locale_dir/support/no_locale/characters.h4
-rw-r--r--libcxx/include/__locale_dir/support/no_locale/strtonum.h9
-rw-r--r--libcxx/include/__locale_dir/support/windows.h29
-rw-r--r--libcxx/include/__mdspan/extents.h11
-rw-r--r--libcxx/include/__mdspan/mdspan.h43
-rw-r--r--libcxx/include/__memory/inout_ptr.h2
-rw-r--r--libcxx/include/__memory/out_ptr.h2
-rw-r--r--libcxx/include/__memory/shared_ptr.h152
-rw-r--r--libcxx/include/__memory/temp_value.h3
-rw-r--r--libcxx/include/__memory/uninitialized_algorithms.h1
-rw-r--r--libcxx/include/__memory/unique_ptr.h30
-rw-r--r--libcxx/include/__mutex/mutex.h4
-rw-r--r--libcxx/include/__mutex/once_flag.h10
-rw-r--r--libcxx/include/__random/binomial_distribution.h8
-rw-r--r--libcxx/include/__random/mersenne_twister_engine.h204
-rw-r--r--libcxx/include/__ranges/iota_view.h14
-rw-r--r--libcxx/include/__split_buffer5
-rw-r--r--libcxx/include/__support/xlocale/__strtonum_fallback.h8
-rw-r--r--libcxx/include/__system_error/error_category.h14
-rw-r--r--libcxx/include/__system_error/error_code.h10
-rw-r--r--libcxx/include/__system_error/error_condition.h8
-rw-r--r--libcxx/include/__system_error/system_error.h2
-rw-r--r--libcxx/include/__thread/thread.h8
-rw-r--r--libcxx/include/__tree156
-rw-r--r--libcxx/include/__type_traits/aligned_storage.h53
-rw-r--r--libcxx/include/__type_traits/is_array.h26
-rw-r--r--libcxx/include/__type_traits/is_bounded_array.h36
-rw-r--r--libcxx/include/__type_traits/is_floating_point.h13
-rw-r--r--libcxx/include/__type_traits/is_replaceable.h61
-rw-r--r--libcxx/include/__type_traits/is_unbounded_array.h38
-rw-r--r--libcxx/include/__utility/cmp.h14
-rw-r--r--libcxx/include/__utility/integer_sequence.h5
-rw-r--r--libcxx/include/__utility/pair.h9
-rw-r--r--libcxx/include/__vector/vector.h125
-rw-r--r--libcxx/include/any28
-rw-r--r--libcxx/include/array144
-rw-r--r--libcxx/include/barrier4
-rw-r--r--libcxx/include/bitset55
-rw-r--r--libcxx/include/ccomplex14
-rw-r--r--libcxx/include/ciso6469
-rw-r--r--libcxx/include/cstdalign13
-rw-r--r--libcxx/include/cstdbool13
-rw-r--r--libcxx/include/ctgmath13
-rw-r--r--libcxx/include/deque57
-rw-r--r--libcxx/include/ext/hash_map5
-rw-r--r--libcxx/include/ext/hash_set5
-rw-r--r--libcxx/include/forward_list28
-rw-r--r--libcxx/include/fstream17
-rw-r--r--libcxx/include/future15
-rw-r--r--libcxx/include/initializer_list12
-rw-r--r--libcxx/include/latch6
-rw-r--r--libcxx/include/limits6
-rw-r--r--libcxx/include/list52
-rw-r--r--libcxx/include/map39
-rw-r--r--libcxx/include/module.modulemap.in34
-rw-r--r--libcxx/include/mutex21
-rw-r--r--libcxx/include/optional394
-rw-r--r--libcxx/include/queue16
-rw-r--r--libcxx/include/regex6
-rw-r--r--libcxx/include/scoped_allocator4
-rw-r--r--libcxx/include/semaphore8
-rw-r--r--libcxx/include/set40
-rw-r--r--libcxx/include/span90
-rw-r--r--libcxx/include/stack6
-rw-r--r--libcxx/include/stdbool.h44
-rw-r--r--libcxx/include/stdexcept4
-rw-r--r--libcxx/include/string353
-rw-r--r--libcxx/include/string_view137
-rw-r--r--libcxx/include/tuple27
-rw-r--r--libcxx/include/type_traits2
-rw-r--r--libcxx/include/variant2
-rw-r--r--libcxx/include/version5
-rw-r--r--libcxx/lib/abi/CHANGELOG.TXT14
-rw-r--r--libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist11
-rw-r--r--libcxx/lib/abi/i686-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist11
-rw-r--r--libcxx/lib/abi/powerpc-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist11
-rw-r--r--libcxx/lib/abi/powerpc64-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist11
-rw-r--r--libcxx/lib/abi/x86_64-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist11
-rw-r--r--libcxx/lib/abi/x86_64-unknown-freebsd.libcxxabi.v1.stable.exceptions.nonew.abilist11
-rw-r--r--libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist11
-rw-r--r--libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.noexceptions.nonew.abilist11
-rw-r--r--libcxx/modules/std/optional.inc3
-rw-r--r--libcxx/src/atomic.cpp357
-rw-r--r--libcxx/src/exception.cpp12
-rw-r--r--libcxx/src/filesystem/operations.cpp11
-rw-r--r--libcxx/src/include/aligned_alloc.h (renamed from libcxx/include/__memory/aligned_alloc.h)10
-rw-r--r--libcxx/src/include/config_elast.h2
-rw-r--r--libcxx/src/include/from_chars_floating_point.h14
-rw-r--r--libcxx/src/include/refstring.h4
-rw-r--r--libcxx/src/locale.cpp50
-rw-r--r--libcxx/src/new.cpp2
-rw-r--r--libcxx/src/print.cpp10
-rw-r--r--libcxx/src/support/runtime/exception_fallback.ipp2
-rw-r--r--libcxx/src/support/runtime/exception_glibcxx.ipp3
-rw-r--r--libcxx/src/support/runtime/exception_libcxxabi.ipp8
-rw-r--r--libcxx/src/support/runtime/exception_libcxxrt.ipp2
-rw-r--r--libcxx/src/support/runtime/exception_msvc.ipp2
-rw-r--r--libcxx/src/support/runtime/exception_pointer_cxxabi.ipp19
-rw-r--r--libcxx/src/support/runtime/exception_pointer_glibcxx.ipp2
-rw-r--r--libcxx/src/support/runtime/exception_pointer_msvc.ipp1
-rw-r--r--libcxx/src/support/runtime/exception_pointer_unimplemented.ipp1
-rw-r--r--libcxx/src/thread.cpp4
-rw-r--r--libcxx/test/benchmarks/algorithms/nonmodifying/find.bench.cpp53
-rw-r--r--libcxx/test/benchmarks/containers/associative/associative_container_benchmarks.h59
-rw-r--r--libcxx/test/benchmarks/containers/associative/flat_map.bench.cpp8
-rw-r--r--libcxx/test/benchmarks/containers/associative/flat_multimap.bench.cpp8
-rw-r--r--libcxx/test/benchmarks/containers/associative/map.bench.cpp3
-rw-r--r--libcxx/test/benchmarks/containers/associative/multimap.bench.cpp3
-rw-r--r--libcxx/test/benchmarks/containers/associative/multiset.bench.cpp3
-rw-r--r--libcxx/test/benchmarks/containers/associative/set.bench.cpp3
-rw-r--r--libcxx/test/benchmarks/containers/associative/unordered_map.bench.cpp3
-rw-r--r--libcxx/test/benchmarks/containers/associative/unordered_multimap.bench.cpp3
-rw-r--r--libcxx/test/benchmarks/containers/associative/unordered_multiset.bench.cpp3
-rw-r--r--libcxx/test/benchmarks/containers/associative/unordered_set.bench.cpp3
-rw-r--r--libcxx/test/benchmarks/containers/string.bench.cpp25
-rw-r--r--libcxx/test/benchmarks/streams/ofstream.bench.cpp (renamed from libcxx/test/benchmarks/streams/fstream.bench.cpp)22
-rw-r--r--libcxx/test/extensions/gnu/hash_map/copy.pass.cpp27
-rw-r--r--libcxx/test/extensions/gnu/hash_set/copy.pass.cpp27
-rw-r--r--libcxx/test/extensions/libcxx/odr_signature.assertion_semantics.sh.cpp71
-rw-r--r--libcxx/test/extensions/libcxx/odr_signature.exceptions.sh.cpp6
-rw-r--r--libcxx/test/extensions/libcxx/odr_signature.hardening.sh.cpp10
-rw-r--r--libcxx/test/libcxx-03/algorithms/half_positive.pass.cpp12
-rw-r--r--libcxx/test/libcxx-03/algorithms/robust_against_copying_comparators.pass.cpp69
-rw-r--r--libcxx/test/libcxx-03/algorithms/robust_against_cpp20_hostile_iterators.compile.pass.cpp25
-rw-r--r--libcxx/test/libcxx-03/containers/sequences/vector/asan.pass.cpp23
-rw-r--r--libcxx/test/libcxx-03/containers/sequences/vector/asan_throw.pass.cpp37
-rw-r--r--libcxx/test/libcxx-03/depr/depr.default.allocator/allocator.members/construct.cxx20.pass.cpp53
-rw-r--r--libcxx/test/libcxx-03/input.output/string.streams/stringbuf/const_sso_buffer.pass.cpp94
-rw-r--r--libcxx/test/libcxx-03/iterators/bounded_iter/arithmetic.pass.cpp8
-rw-r--r--libcxx/test/libcxx-03/iterators/bounded_iter/comparison.pass.cpp17
-rw-r--r--libcxx/test/libcxx-03/iterators/bounded_iter/pointer_traits.pass.cpp12
-rw-r--r--libcxx/test/libcxx-03/iterators/bounded_iter/types.compile.pass.cpp23
-rw-r--r--libcxx/test/libcxx-03/iterators/contiguous_iterators.conv.compile.pass.cpp9
-rw-r--r--libcxx/test/libcxx-03/iterators/contiguous_iterators.pass.cpp89
-rw-r--r--libcxx/test/libcxx-03/iterators/predef.iterators/insert.iterators/back.insert.iter.ops/get_container.pass.cpp6
-rw-r--r--libcxx/test/libcxx-03/iterators/unwrap_iter.pass.cpp3
-rw-r--r--libcxx/test/libcxx-03/language.support/support.dynamic/libcpp_deallocate.sh.cpp7
-rw-r--r--libcxx/test/libcxx-03/libcpp_alignof.pass.cpp3
-rw-r--r--libcxx/test/libcxx-03/memory/allocation_guard.pass.cpp4
-rw-r--r--libcxx/test/libcxx-03/memory/swap_allocator.pass.cpp19
-rw-r--r--libcxx/test/libcxx-03/numerics/bit.ops.pass.cpp3
-rw-r--r--libcxx/test/libcxx-03/strings/basic.string/string.capacity/max_size.pass.cpp3
-rw-r--r--libcxx/test/libcxx-03/strings/basic.string/string.cons/copy_shrunk_long.pass.cpp8
-rw-r--r--libcxx/test/libcxx-03/strings/c.strings/constexpr_memmove.pass.cpp4
-rw-r--r--libcxx/test/libcxx-03/type_traits/is_trivially_relocatable.compile.pass.cpp52
-rw-r--r--libcxx/test/libcxx-03/utilities/function.objects/func.require/bullet_1_2_3.pass.cpp164
-rw-r--r--libcxx/test/libcxx-03/utilities/function.objects/func.require/bullet_4_5_6.pass.cpp32
-rw-r--r--libcxx/test/libcxx-03/utilities/function.objects/func.require/bullet_7.pass.cpp88
-rw-r--r--libcxx/test/libcxx-03/utilities/function.objects/func.require/invoke.pass.cpp12
-rw-r--r--libcxx/test/libcxx-03/utilities/function.objects/func.require/invoke_helpers.h17
-rw-r--r--libcxx/test/libcxx-03/utilities/is_pointer_in_range.pass.cpp17
-rw-r--r--libcxx/test/libcxx-03/utilities/is_valid_range.pass.cpp11
-rw-r--r--libcxx/test/libcxx-03/utilities/memory/pointer.conversion/to_address.pass.cpp4
-rw-r--r--libcxx/test/libcxx-03/utilities/memory/pointer.conversion/to_address_std_iterators.pass.cpp6
-rw-r--r--libcxx/test/libcxx-03/utilities/meta/is_referenceable.compile.pass.cpp108
-rw-r--r--libcxx/test/libcxx-03/utilities/no_destroy.pass.cpp5
-rw-r--r--libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/abi.non_trivial_copy_move.pass.cpp97
-rw-r--r--libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/abi.trivial_copy_move.pass.cpp105
-rw-r--r--libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/abi.trivially_copyable.compile.pass.cpp5
-rw-r--r--libcxx/test/libcxx/algorithms/alg.modifying.operations/copy_move_unwrap_reverse.pass.cpp1
-rw-r--r--libcxx/test/libcxx/assertions/semantics/assertion_semantic_incorrect_value.sh.cpp29
-rw-r--r--libcxx/test/libcxx/assertions/semantics/override_with_enforce_semantic.pass.cpp29
-rw-r--r--libcxx/test/libcxx/assertions/semantics/override_with_ignore_semantic.pass.cpp26
-rw-r--r--libcxx/test/libcxx/assertions/semantics/override_with_observe_semantic.pass.cpp27
-rw-r--r--libcxx/test/libcxx/assertions/semantics/override_with_quick_enforce_semantic.pass.cpp28
-rw-r--r--libcxx/test/libcxx/atomics/atomics.syn/wait.issue_85107.pass.cpp4
-rw-r--r--libcxx/test/libcxx/containers/views/mdspan/extents/assert.obs.pass.cpp20
-rw-r--r--libcxx/test/libcxx/containers/views/mdspan/nodiscard.verify.cpp62
-rw-r--r--libcxx/test/libcxx/containers/views/views.span/nodiscard.verify.cpp76
-rw-r--r--libcxx/test/libcxx/diagnostics/array.nodiscard.verify.cpp69
-rw-r--r--libcxx/test/libcxx/diagnostics/deque.nodiscard.verify.cpp30
-rw-r--r--libcxx/test/libcxx/diagnostics/flat_map.nodiscard.verify.cpp102
-rw-r--r--libcxx/test/libcxx/diagnostics/flat_set.nodiscard.verify.cpp88
-rw-r--r--libcxx/test/libcxx/diagnostics/forward_list.nodiscard.verify.cpp25
-rw-r--r--libcxx/test/libcxx/diagnostics/functional.nodiscard.verify.cpp52
-rw-r--r--libcxx/test/libcxx/diagnostics/list.nodiscard.verify.cpp31
-rw-r--r--libcxx/test/libcxx/diagnostics/queue.nodiscard.verify.cpp26
-rw-r--r--libcxx/test/libcxx/diagnostics/stack.nodiscard.verify.cpp9
-rw-r--r--libcxx/test/libcxx/diagnostics/string.nodiscard.verify.cpp192
-rw-r--r--libcxx/test/libcxx/diagnostics/string_view.nodiscard.verify.cpp136
-rw-r--r--libcxx/test/libcxx/diagnostics/syserr/nodiscard.verify.cpp108
-rw-r--r--libcxx/test/libcxx/diagnostics/utility.nodiscard.verify.cpp28
-rw-r--r--libcxx/test/libcxx/input.output/file.streams/fstreams/filebuf/traits_mismatch.verify.cpp2
-rw-r--r--libcxx/test/libcxx/input.output/file.streams/fstreams/traits_mismatch.verify.cpp2
-rw-r--r--libcxx/test/libcxx/language.support/nodiscard.verify.cpp129
-rw-r--r--libcxx/test/libcxx/language.support/support.dynamic/libcpp_deallocate.sh.cpp7
-rw-r--r--libcxx/test/libcxx/memory/allocation_guard.pass.cpp2
-rw-r--r--libcxx/test/libcxx/memory/uninitialized_allocator_copy.pass.cpp1
-rw-r--r--libcxx/test/libcxx/numerics/clamp_to_integral.pass.cpp1
-rw-r--r--libcxx/test/libcxx/strings/basic.string/nonnull.verify.cpp2
-rw-r--r--libcxx/test/libcxx/strings/string.view/nonnull.verify.cpp6
-rw-r--r--libcxx/test/libcxx/system_reserved_names.gen.py4
-rw-r--r--libcxx/test/libcxx/thread/nodiscard.verify.cpp144
-rw-r--r--libcxx/test/libcxx/transitive_includes.gen.py2
-rw-r--r--libcxx/test/libcxx/type_traits/is_replaceable.compile.pass.cpp353
-rw-r--r--libcxx/test/libcxx/utilities/any/nodiscard.verify.cpp45
-rw-r--r--libcxx/test/libcxx/utilities/intseq/nodiscard.verify.cpp21
-rw-r--r--libcxx/test/libcxx/utilities/optional/optional.iterator/iterator.compile.pass.cpp9
-rw-r--r--libcxx/test/libcxx/utilities/optional/optional.object/optional.object.observe/value_or.compile.pass.cpp28
-rw-r--r--libcxx/test/libcxx/utilities/smartptr/nodiscard.verify.cpp165
-rw-r--r--libcxx/test/libcxx/utilities/template.bitset/nodiscard.verify.cpp61
-rw-r--r--libcxx/test/selftest/dsl/dsl.sh.py2
-rw-r--r--libcxx/test/selftest/dsl/lit.local.cfg2
-rw-r--r--libcxx/test/std/algorithms/alg.nonmodifying/alg.contains/ranges.contains_subrange.pass.cpp1
-rw-r--r--libcxx/test/std/algorithms/alg.nonmodifying/alg.count/count.pass.cpp1
-rw-r--r--libcxx/test/std/algorithms/alg.nonmodifying/alg.count/ranges.count.pass.cpp1
-rw-r--r--libcxx/test/std/algorithms/alg.nonmodifying/alg.ends_with/ranges.ends_with.pass.cpp2
-rw-r--r--libcxx/test/std/algorithms/alg.nonmodifying/alg.starts_with/ranges.starts_with.pass.cpp1
-rw-r--r--libcxx/test/std/algorithms/alg.sorting/alg.partitions/pstl.is_partitioned.pass.cpp1
-rw-r--r--libcxx/test/std/algorithms/robust_against_nonbool.compile.pass.cpp136
-rw-r--r--libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.wait/lost_wakeup.pass.cpp57
-rw-r--r--libcxx/test/std/containers/associative/map/map.cons/dtor_noexcept.pass.cpp3
-rw-r--r--libcxx/test/std/containers/associative/multimap/multimap.cons/dtor_noexcept.pass.cpp3
-rw-r--r--libcxx/test/std/containers/associative/multiset/multiset.cons/dtor_noexcept.pass.cpp3
-rw-r--r--libcxx/test/std/containers/associative/set/set.cons/dtor_noexcept.pass.cpp3
-rw-r--r--libcxx/test/std/containers/container.adaptors/flat.map/flat.map.access/index_transparent.pass.cpp2
-rw-r--r--libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/copy_assign.pass.cpp19
-rw-r--r--libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/deduct.pass.cpp54
-rw-r--r--libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/deduct_pmr.pass.cpp28
-rw-r--r--libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/dtor_noexcept.pass.cpp1
-rw-r--r--libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/initializer_list.pass.cpp14
-rw-r--r--libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/iter_iter.pass.cpp26
-rw-r--r--libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/move_assign.pass.cpp8
-rw-r--r--libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/pmr.pass.cpp12
-rw-r--r--libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/range.pass.cpp26
-rw-r--r--libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/sorted_container.pass.cpp12
-rw-r--r--libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/sorted_initializer_list.pass.cpp16
-rw-r--r--libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/sorted_iter_iter.pass.cpp20
-rw-r--r--libcxx/test/std/containers/container.adaptors/flat.map/flat.map.modifiers/erase_key.pass.cpp12
-rw-r--r--libcxx/test/std/containers/container.adaptors/flat.map/flat.map.observers/comp.pass.cpp2
-rw-r--r--libcxx/test/std/containers/container.adaptors/flat.map/helpers.h1
-rw-r--r--libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/copy_assign.pass.cpp19
-rw-r--r--libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/deduct.pass.cpp54
-rw-r--r--libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/deduct_pmr.pass.cpp28
-rw-r--r--libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/dtor_noexcept.pass.cpp1
-rw-r--r--libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/initializer_list.pass.cpp14
-rw-r--r--libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/iter_iter.pass.cpp26
-rw-r--r--libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/move_assign.pass.cpp8
-rw-r--r--libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/pmr.pass.cpp12
-rw-r--r--libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/range.pass.cpp26
-rw-r--r--libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/sorted_container.pass.cpp28
-rw-r--r--libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/sorted_initializer_list.pass.cpp22
-rw-r--r--libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/sorted_iter_iter.pass.cpp20
-rw-r--r--libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.modifiers/erase_key.pass.cpp12
-rw-r--r--libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.observers/comp.pass.cpp2
-rw-r--r--libcxx/test/std/containers/container.adaptors/flat.multimap/helpers.h1
-rw-r--r--libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.cons/compare.pass.cpp1
-rw-r--r--libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.cons/copy_assign.pass.cpp2
-rw-r--r--libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.cons/dtor_noexcept.pass.cpp1
-rw-r--r--libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.cons/move.pass.cpp2
-rw-r--r--libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.cons/move_assign.pass.cpp9
-rw-r--r--libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.cons/sorted_iter_iter.pass.cpp4
-rw-r--r--libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.iterators/iterator.pass.cpp2
-rw-r--r--libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/copy_assign.pass.cpp1
-rw-r--r--libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/dtor_noexcept.pass.cpp1
-rw-r--r--libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/move.pass.cpp2
-rw-r--r--libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/move_assign.pass.cpp9
-rw-r--r--libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/sorted_iter_iter.pass.cpp4
-rw-r--r--libcxx/test/std/containers/container.adaptors/flat.set/flat.set.iterators/iterator.pass.cpp2
-rw-r--r--libcxx/test/std/containers/container.adaptors/stack/stack.cons/ctor_iterators.pass.cpp1
-rw-r--r--libcxx/test/std/containers/container.requirements/container.requirements.general/allocator_move.pass.cpp1
-rw-r--r--libcxx/test/std/containers/sequences/array/array.creation/to_array.verify.cpp6
-rw-r--r--libcxx/test/std/containers/sequences/deque/deque.cons/dtor_noexcept.pass.cpp3
-rw-r--r--libcxx/test/std/containers/sequences/forwardlist/forwardlist.cons/dtor_noexcept.pass.cpp3
-rw-r--r--libcxx/test/std/containers/sequences/list/list.cons/dtor_noexcept.pass.cpp3
-rw-r--r--libcxx/test/std/containers/sequences/vector.bool/assign_move.pass.cpp1
-rw-r--r--libcxx/test/std/containers/sequences/vector.bool/default_noexcept.pass.cpp3
-rw-r--r--libcxx/test/std/containers/sequences/vector.bool/dtor_noexcept.pass.cpp3
-rw-r--r--libcxx/test/std/containers/sequences/vector.bool/move_assign_noexcept.pass.cpp3
-rw-r--r--libcxx/test/std/containers/sequences/vector.bool/move_noexcept.pass.cpp3
-rw-r--r--libcxx/test/std/containers/sequences/vector/vector.cons/dtor_noexcept.pass.cpp3
-rw-r--r--libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/dtor_noexcept.pass.cpp3
-rw-r--r--libcxx/test/std/containers/unord/unord.map/unord.map.modifiers/erase_range.pass.cpp22
-rw-r--r--libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/dtor_noexcept.pass.cpp3
-rw-r--r--libcxx/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/erase_range.pass.cpp22
-rw-r--r--libcxx/test/std/containers/unord/unord.multiset/erase_range.pass.cpp22
-rw-r--r--libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/dtor_noexcept.pass.cpp3
-rw-r--r--libcxx/test/std/containers/unord/unord.set/erase_range.pass.cpp22
-rw-r--r--libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/dtor_noexcept.pass.cpp3
-rw-r--r--libcxx/test/std/depr/depr.cpp.headers/ccomplex.verify.cpp11
-rw-r--r--libcxx/test/std/depr/depr.cpp.headers/ciso646.verify.cpp8
-rw-r--r--libcxx/test/std/depr/depr.cpp.headers/cstdalign.verify.cpp11
-rw-r--r--libcxx/test/std/depr/depr.cpp.headers/cstdbool.verify.cpp11
-rw-r--r--libcxx/test/std/depr/depr.cpp.headers/ctgmath.verify.cpp11
-rw-r--r--libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/generic_category.pass.cpp2
-rw-r--r--libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/system_category.pass.cpp2
-rw-r--r--libcxx/test/std/input.output/file.streams/c.files/gets-removed.verify.cpp (renamed from libcxx/test/std/input.output/file.streams/c.files/gets.compile.fail.cpp)10
-rw-r--r--libcxx/test/std/input.output/file.streams/fstreams/ifstream.members/xsgetn.pass.cpp73
-rw-r--r--libcxx/test/std/input.output/file.streams/fstreams/ifstream.members/xsgetn.test.dat1
-rw-r--r--libcxx/test/std/input.output/filesystems/class.path/path.member/path.append.pass.cpp1
-rw-r--r--libcxx/test/std/input.output/filesystems/class.path/path.member/path.concat.pass.cpp1
-rw-r--r--libcxx/test/std/language.support/support.dynamic/hardware_inference_size.compile.pass.cpp1
-rw-r--r--libcxx/test/std/language.support/support.limits/limits/numeric.limits.members/traps.pass.cpp20
-rw-r--r--libcxx/test/std/language.support/support.limits/support.limits.general/optional.version.compile.pass.cpp4
-rw-r--r--libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp4
-rw-r--r--libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_long.pass.cpp246
-rw-r--r--libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_unsigned_int.pass.cpp11
-rw-r--r--libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_unsigned_long.pass.cpp11
-rw-r--r--libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_unsigned_long_long.pass.cpp11
-rw-r--r--libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_unsigned_short.pass.cpp11
-rw-r--r--libcxx/test/std/numerics/c.math/isnormal.pass.cpp1
-rw-r--r--libcxx/test/std/numerics/c.math/signbit.pass.cpp1
-rw-r--r--libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer/increment.pass.cpp50
-rw-r--r--libcxx/test/std/ranges/range.factories/range.iota.view/indices.pass.cpp4
-rw-r--r--libcxx/test/std/ranges/range.factories/range.iota.view/iterator/member_typedefs.compile.pass.cpp9
-rw-r--r--libcxx/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/array.compile.fail.cpp40
-rw-r--r--libcxx/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/init.compile.fail.cpp37
-rw-r--r--libcxx/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/int.compile.fail.cpp36
-rw-r--r--libcxx/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/temporary-objects.verify.cpp72
-rw-r--r--libcxx/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/vector.compile.fail.cpp41
-rw-r--r--libcxx/test/std/re/re.results/re.results.const/move.pass.cpp4
-rw-r--r--libcxx/test/std/strings/basic.string/string.cons/dtor.pass.cpp5
-rw-r--r--libcxx/test/std/strings/basic.string/string.cons/iter_alloc_deduction.pass.cpp1
-rw-r--r--libcxx/test/std/strings/basic.string/string.cons/string_view_deduction.pass.cpp13
-rw-r--r--libcxx/test/std/strings/basic.string/string.cons/string_view_size_size_deduction.pass.cpp11
-rw-r--r--libcxx/test/std/thread/thread.jthread/nodiscard.verify.cpp29
-rw-r--r--libcxx/test/std/time/time.clock/time.clock.gps/types.compile.pass.cpp1
-rw-r--r--libcxx/test/std/time/time.clock/time.clock.tai/types.compile.pass.cpp1
-rw-r--r--libcxx/test/std/time/time.clock/time.clock.utc/types.compile.pass.cpp1
-rw-r--r--libcxx/test/std/utilities/any/any.nonmembers/any.cast/any_cast_pointer.pass.cpp237
-rw-r--r--libcxx/test/std/utilities/any/any.nonmembers/any.cast/any_cast_reference.pass.cpp483
-rw-r--r--libcxx/test/std/utilities/any/any.nonmembers/any.cast/any_cast_request_invalid_value_category.verify.cpp62
-rw-r--r--libcxx/test/std/utilities/any/any.nonmembers/any.cast/const_correctness.verify.cpp20
-rw-r--r--libcxx/test/std/utilities/any/any.nonmembers/any.cast/not_copy_constructible.verify.cpp30
-rw-r--r--libcxx/test/std/utilities/any/any.nonmembers/any.cast/reference_types.verify.cpp41
-rw-r--r--libcxx/test/std/utilities/any/any.nonmembers/any.cast/void.verify.cpp4
-rw-r--r--libcxx/test/std/utilities/function.objects/refwrap/refwrap.invoke/robust_against_adl.pass.cpp34
-rw-r--r--libcxx/test/std/utilities/memory/allocator.uses/allocator.uses.construction/make_obj_using_allocator.pass.cpp1
-rw-r--r--libcxx/test/std/utilities/memory/allocator.uses/allocator.uses.construction/uninitialized_construct_using_allocator.pass.cpp1
-rw-r--r--libcxx/test/std/utilities/memory/allocator.uses/allocator.uses.construction/uses_allocator_construction_args.pass.cpp2
-rw-r--r--libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/unique_ptr.pass.cpp4
-rw-r--r--libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.obs/unique.deprecated_in_cxx17.verify.cpp2
-rw-r--r--libcxx/test/std/utilities/optional/optional.iterator/begin.pass.cpp7
-rw-r--r--libcxx/test/std/utilities/optional/optional.iterator/borrowed_range.compile.pass.cpp34
-rw-r--r--libcxx/test/std/utilities/optional/optional.iterator/end.pass.cpp8
-rw-r--r--libcxx/test/std/utilities/optional/optional.iterator/iterator.pass.cpp40
-rw-r--r--libcxx/test/std/utilities/optional/optional.monadic/and_then.pass.cpp87
-rw-r--r--libcxx/test/std/utilities/optional/optional.monadic/or_else.pass.cpp26
-rw-r--r--libcxx/test/std/utilities/optional/optional.monadic/transform.pass.cpp131
-rw-r--r--libcxx/test/std/utilities/optional/optional.object/optional.object.assign/assign_value.pass.cpp56
-rw-r--r--libcxx/test/std/utilities/optional/optional.object/optional.object.assign/emplace.pass.cpp27
-rw-r--r--libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/U.pass.cpp184
-rw-r--r--libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/const_T.pass.cpp179
-rw-r--r--libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/const_optional_U.pass.cpp118
-rw-r--r--libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/copy.pass.cpp274
-rw-r--r--libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/ctor.verify.cpp37
-rw-r--r--libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/deduct.pass.cpp45
-rw-r--r--libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/deduct.verify.cpp27
-rw-r--r--libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/default.pass.cpp85
-rw-r--r--libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/empty_in_place_t_does_not_clobber.pass.cpp2
-rw-r--r--libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/explicit_const_optional_U.pass.cpp113
-rw-r--r--libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/explicit_optional_U.pass.cpp94
-rw-r--r--libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/in_place_t.pass.cpp194
-rw-r--r--libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/initializer_list.pass.cpp140
-rw-r--r--libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/move.pass.cpp351
-rw-r--r--libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/nullopt_t.pass.cpp69
-rw-r--r--libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/optional_U.pass.cpp99
-rw-r--r--libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/ref_constructs_from_temporary.verify.cpp35
-rw-r--r--libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/ref_t.pass.cpp75
-rw-r--r--libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/rvalue_T.pass.cpp217
-rw-r--r--libcxx/test/std/utilities/optional/optional.object/optional.object.dtor/dtor.pass.cpp22
-rw-r--r--libcxx/test/std/utilities/optional/optional.object/optional.object.mod/reset.pass.cpp13
-rw-r--r--libcxx/test/std/utilities/optional/optional.object/optional.object.observe/dereference.pass.cpp14
-rw-r--r--libcxx/test/std/utilities/optional/optional.object/optional.object.observe/dereference_const.pass.cpp19
-rw-r--r--libcxx/test/std/utilities/optional/optional.object/optional.object.observe/has_value.pass.cpp9
-rw-r--r--libcxx/test/std/utilities/optional/optional.object/optional.object.observe/op_arrow.pass.cpp30
-rw-r--r--libcxx/test/std/utilities/optional/optional.object/optional.object.observe/op_arrow_const.pass.cpp19
-rw-r--r--libcxx/test/std/utilities/optional/optional.object/optional.object.observe/value.pass.cpp8
-rw-r--r--libcxx/test/std/utilities/optional/optional.object/optional.object.observe/value_or.pass.cpp8
-rw-r--r--libcxx/test/std/utilities/optional/optional.object/optional.object.observe/value_or_const.pass.cpp10
-rw-r--r--libcxx/test/std/utilities/optional/optional.object/optional.object.swap/swap.pass.cpp77
-rw-r--r--libcxx/test/std/utilities/optional/optional.object/optional_requires_destructible_object.verify.cpp12
-rw-r--r--libcxx/test/std/utilities/optional/optional.object/types.pass.cpp9
-rw-r--r--libcxx/test/std/utilities/optional/optional.specalg/make_optional.pass.cpp4
-rw-r--r--libcxx/test/std/utilities/optional/optional.specalg/make_optional_explicit.pass.cpp29
-rw-r--r--libcxx/test/std/utilities/optional/optional.specalg/swap.pass.cpp76
-rw-r--r--libcxx/test/std/utilities/tuple/tuple.tuple/tuple.apply/make_from_tuple.verify.cpp7
-rw-r--r--libcxx/test/std/utilities/utility/utility.intcmp/intcmp.cmp_greater/cmp_greater.pass.cpp1
-rw-r--r--libcxx/test/std/utilities/utility/utility.intcmp/intcmp.cmp_less/cmp_less.pass.cpp1
-rw-r--r--libcxx/test/std/utilities/utility/utility.intcmp/intcmp.cmp_less_equal/cmp_less_equal.pass.cpp1
-rw-r--r--libcxx/test/support/module.modulemap10
-rw-r--r--libcxx/test/support/platform_support.h2
-rw-r--r--libcxx/test/support/test.support/test_check_assertion.pass.cpp10
-rw-r--r--libcxx/utils/ci/Dockerfile329
-rw-r--r--libcxx/utils/ci/buildkite-pipeline.yml30
-rw-r--r--libcxx/utils/ci/docker-compose.yml40
-rw-r--r--libcxx/utils/ci/docker/android-builder.dockerfile114
-rw-r--r--libcxx/utils/ci/docker/docker-compose.yml38
-rw-r--r--libcxx/utils/ci/docker/linux-builder-base.dockerfile141
-rw-r--r--libcxx/utils/ci/docker/linux-builder.dockerfile38
-rwxr-xr-xlibcxx/utils/ci/run-buildbot104
-rwxr-xr-xlibcxx/utils/ci/run-buildbot-container4
-rw-r--r--libcxx/utils/generate_feature_test_macro_components.py3
-rw-r--r--libcxx/utils/libcxx/test/config.py21
-rw-r--r--libcxx/utils/libcxx/test/dsl.py2
-rw-r--r--libcxx/utils/libcxx/test/features.py920
-rw-r--r--libcxx/utils/libcxx/test/features/__init__.py21
-rw-r--r--libcxx/utils/libcxx/test/features/availability.py199
-rw-r--r--libcxx/utils/libcxx/test/features/compiler.py82
-rw-r--r--libcxx/utils/libcxx/test/features/gdb.py50
-rw-r--r--libcxx/utils/libcxx/test/features/libcxx_macros.py76
-rw-r--r--libcxx/utils/libcxx/test/features/localization.py142
-rw-r--r--libcxx/utils/libcxx/test/features/misc.py299
-rw-r--r--libcxx/utils/libcxx/test/features/platform.py132
-rw-r--r--libcxx/utils/libcxx/test/format.py2
-rw-r--r--libcxx/utils/libcxx/test/modules.py3
-rw-r--r--libcxx/utils/libcxx/test/params.py2
487 files changed, 10362 insertions, 8037 deletions
diff --git a/libcxx/CMakeLists.txt b/libcxx/CMakeLists.txt
index a119850..8b4cd26 100644
--- a/libcxx/CMakeLists.txt
+++ b/libcxx/CMakeLists.txt
@@ -66,6 +66,19 @@ if (NOT "${LIBCXX_HARDENING_MODE}" IN_LIST LIBCXX_SUPPORTED_HARDENING_MODES)
message(FATAL_ERROR
"Unsupported hardening mode: '${LIBCXX_HARDENING_MODE}'. Supported values are ${LIBCXX_SUPPORTED_HARDENING_MODES}.")
endif()
+set(LIBCXX_SUPPORTED_ASSERTION_SEMANTICS hardening_dependent ignore observe quick_enforce enforce)
+set(LIBCXX_ASSERTION_SEMANTIC "hardening_dependent" CACHE STRING
+ "Specify the default assertion semantic to use. This semantic will be used
+ inside the compiled library and will be the default when compiling user code.
+ Note that users can override this setting in their own code. This does not
+ affect the ABI. Supported values are ${LIBCXX_SUPPORTED_ASSERTION_SEMANTICS}.
+ `hardening_dependent` is a special value that instructs the library to select
+ the assertion semantic based on the hardening mode in effect.")
+
+if (NOT "${LIBCXX_ASSERTION_SEMANTIC}" IN_LIST LIBCXX_SUPPORTED_ASSERTION_SEMANTICS)
+ message(FATAL_ERROR
+ "Unsupported assertion semantic: '${LIBCXX_ASSERTION_SEMANTIC}'. Supported values are ${LIBCXX_SUPPORTED_ASSERTION_SEMANTICS}.")
+endif()
set(LIBCXX_ASSERTION_HANDLER_FILE
"vendor/llvm/default_assertion_handler.in"
CACHE STRING
@@ -750,6 +763,18 @@ config_define(${LIBCXX_ENABLE_WIDE_CHARACTERS} _LIBCPP_HAS_WIDE_CHARACTERS)
config_define(${LIBCXX_ENABLE_TIME_ZONE_DATABASE} _LIBCPP_HAS_TIME_ZONE_DATABASE)
config_define(${LIBCXX_ENABLE_VENDOR_AVAILABILITY_ANNOTATIONS} _LIBCPP_HAS_VENDOR_AVAILABILITY_ANNOTATIONS)
+# Set C library in use
+if (RUNTIMES_USE_LIBC STREQUAL "picolibc")
+ config_define(1 _LIBCPP_LIBC_PICOLIBC)
+ # picolibc is derived from newlib and behaves the same in regards to libc++
+ # so setting both here:
+ # * _LIBCPP_LIBC_NEWLIB is used now
+ # * _LIBCPP_LIBC_PICOLIBC can be used for further customizations later
+ config_define(1 _LIBCPP_LIBC_NEWLIB)
+elseif (RUNTIMES_USE_LIBC STREQUAL "newlib")
+ config_define(1 _LIBCPP_LIBC_NEWLIB)
+endif()
+
# TODO: Remove in LLVM 21. We're leaving an error to make this fail explicitly.
if (LIBCXX_ENABLE_ASSERTIONS)
message(FATAL_ERROR "LIBCXX_ENABLE_ASSERTIONS has been removed. Please use LIBCXX_HARDENING_MODE instead.")
@@ -763,6 +788,17 @@ elseif (LIBCXX_HARDENING_MODE STREQUAL "extensive")
elseif (LIBCXX_HARDENING_MODE STREQUAL "debug")
config_define(8 _LIBCPP_HARDENING_MODE_DEFAULT)
endif()
+if (LIBCXX_ASSERTION_SEMANTIC STREQUAL "hardening_dependent")
+ config_define(2 _LIBCPP_ASSERTION_SEMANTIC_DEFAULT)
+elseif (LIBCXX_ASSERTION_SEMANTIC STREQUAL "ignore")
+ config_define(4 _LIBCPP_ASSERTION_SEMANTIC_DEFAULT)
+elseif (LIBCXX_ASSERTION_SEMANTIC STREQUAL "observe")
+ config_define(8 _LIBCPP_ASSERTION_SEMANTIC_DEFAULT)
+elseif (LIBCXX_ASSERTION_SEMANTIC STREQUAL "quick_enforce")
+ config_define(16 _LIBCPP_ASSERTION_SEMANTIC_DEFAULT)
+elseif (LIBCXX_ASSERTION_SEMANTIC STREQUAL "enforce")
+ config_define(32 _LIBCPP_ASSERTION_SEMANTIC_DEFAULT)
+endif()
if (LIBCXX_PSTL_BACKEND STREQUAL "serial")
config_define(1 _LIBCPP_PSTL_BACKEND_SERIAL)
diff --git a/libcxx/docs/ABIGuarantees.rst b/libcxx/docs/ABIGuarantees.rst
index 4d4674c..e680f54 100644
--- a/libcxx/docs/ABIGuarantees.rst
+++ b/libcxx/docs/ABIGuarantees.rst
@@ -205,6 +205,16 @@ This flag fixes the implementation of CityHash used for ``hash<fundamental-type>
CityHash has the problem that it drops some bits on the floor. Fixing the implementation changes the hash of values,
resulting in an ABI break.
+``_LIBCPP_ABI_ATOMIC_WAIT_NATIVE_BY_SIZE``
+------------------------------------------
+This flag changes the implementation of ``atomic::wait()`` and ``atomic::notify_one()/notify_all()`` to use the
+native atomic wait/notify operations on platforms that support them based on the size of the atomic type, instead
+of the type itself. This means for example that a type with ``sizeof(T) == 4`` on Linux that doesn't have padding
+bytes would be able to use the underlying platform's atomic wait primitive, which is otherwise only used for ``int32_t``.
+Since the whole program must use the same implementation for correctness, changing this is an ABI break since libc++
+supports linking against TUs that were compiled against older versions of the library.
+
+
inline namespaces
=================
Inline namespaces which contain types that are observable by the user need to be kept the same, since they affect
diff --git a/libcxx/docs/AddingNewCIJobs.rst b/libcxx/docs/AddingNewCIJobs.rst
index 9d749c0..7a12728 100644
--- a/libcxx/docs/AddingNewCIJobs.rst
+++ b/libcxx/docs/AddingNewCIJobs.rst
@@ -28,6 +28,9 @@ An example of a job definition is:
- label: "C++11"
command: "libcxx/utils/ci/run-buildbot generic-cxx11"
+ env:
+ CC: clang
+ CXX: clang++
artifact_paths:
- "**/test-results.xml"
agents:
diff --git a/libcxx/docs/Contributing.rst b/libcxx/docs/Contributing.rst
index 4e9d1ba..e660dae 100644
--- a/libcxx/docs/Contributing.rst
+++ b/libcxx/docs/Contributing.rst
@@ -269,12 +269,12 @@ Updating the CI testing container images
----------------------------------------
The libcxx linux premerge testing can run on one of three sets of runner
-groups. The three runner group names are "llvm-premerge-libcxx-runners",
-"llvm-premerge-libcxx-release-runners" and "llvm-premerge-libcxx-next-runners".
-Which runner set to use is controlled by the contents of
+groups. The three runner group names are ``llvm-premerge-libcxx-runners``,
+``llvm-premerge-libcxx-release-runners`` and ``llvm-premerge-libcxx-next-runners``.
+The runner set to use is controlled by the contents of
https://github.com/llvm/llvm-project/blob/main/.github/workflows/libcxx-build-and-test.yaml.
-By default, it uses "llvm-premerge-libcxx-runners". To switch to one of the
-other runner sets, just replace all uses of "llvm-premerge-libcxx-runners" in
+By default, it uses ``llvm-premerge-libcxx-runners``. To switch to one of the
+other runner sets, just replace all uses of ``llvm-premerge-libcxx-runners`` in
the yaml file with the desired runner set.
Which container image is used by these three runner sets is controlled
@@ -282,7 +282,7 @@ and set by the variable values in
https://github.com/llvm/llvm-zorg/blob/main/premerge/premerge_resources/variables.tf.
The table below shows the variable names and
the runner sets to which they correspond. To see their values, follow the
-link above (to variables.tf in llvm-zorg).
+link above (to ``variables.tf`` in llvm-zorg).
+------------------------------------+---------------------------+
|Runner Set |Variable |
@@ -295,39 +295,24 @@ link above (to variables.tf in llvm-zorg).
+------------------------------------+---------------------------+
-When updating the container image you can either update just the
-runner binary (the part the connects to Github), or you can update
-everything (tools, etc.). Whether to update just the runner or to update
-everything is controlled by the value of ``ACTIONS_BASE_IMAGE``, under
-``actions-builder`` in ``libcxx/utils/ci/docker-compose.yml``.
-
-To update just the runner binary, change the value of ``ACTIONS_BASE_IMAGE``
-to be a modified version of one of the libcxx runner variable images from
-https://github.com/llvm/llvm-zorg/blob/main/premerge/premerge_resources/variables.tf,
-as follows: Find the libcxx runner image name you want to use from the
-variables.tf file. The name will be something like
-``ghcr.io/llvm/libcxx-linux-builder:<some-commit-SHA>``. Replace
-``libcxx-linux-builder`` with ``libcxx-linux-builder-base``. Use this new image
-name as the value you assign to ``ACTIONS_BASE_IMAGE``.
-
-To update the entire container image, set the value of ``ACTIONS_BASE_IMAGE``
-to ``builder-base``. If the value is already ``builder-base`` (there
-have been no just-the-runner updates since the last complete update), then you
-need to find the line containing ``RUN echo "Last forced update executed on``
-in ``libcxx/utils/ci/Dockerfile`` and update the date to be the current date.
-
-Once you have created and merged a PR with those changes, a new image
-will be created, and a link to it can be found at
-https://github.com/llvm/llvm-project/pkgs/container/libcxx-linux-builder,
-where the actual image name should be
-``ghcr.io/llvm/libcxx-linux-builder:<SHA-of-committed-change-from-PR>``.
-
-Lastly you need to create a PR in the llvm-zorg repository,
-updating the the value of the appropriate libcxx runner variable in
-the variables.tf file mentioned above to the name of your newly created
-image (see above paragraph about finding the image name). Once that change
-has been merged, an LLVM premerge maintainer (a Google employee) must use
-terraform to apply the change to the running GKE cluster.
+When updating the container image you can either update just the runner binary (the part
+that connects to Github), or you can update everything (tools, etc.). To update the runner
+binary, bump the value of ``GITHUB_RUNNER_VERSION`` in ``libcxx/utils/ci/docker/docker-compose.yml``.
+To update all of the tools, bump ``BASE_IMAGE_VERSION`` to a newer version of the ``libcxx-linux-builder-base``
+image. You can see all versions of that image at https://github.com/llvm/llvm-project/pkgs/container/libcxx-linux-builder-base.
+
+On push to ``main``, a new version of both the ``libcxx-linux-builder`` and the ``libcxx-android-builder``
+images will be built and pushed to https://github.com/llvm/llvm-project/packages.
+
+You can then update the image used by the actual runners by changing the sha associated
+to ``libcxx_runner_image``, ``libcxx_release_runner_image`` or ``libcxx_next_runner_image``
+in `the Terraform configuration file <https://github.com/llvm/llvm-zorg/blob/main/premerge/premerge_resources/variables.tf>`_.
+To do so, you will need to create a PR in the llvm-zorg repository and wait for it to be
+merged. Once that change has been merged, an LLVM premerge maintainer (a Google employee)
+must use terraform to apply the change to the running GKE cluster.
+
+.. note:: When you update the ``libcxx_runner_image``, also make sure to update the
+ ``libcxx/utils/ci/run-buildbot-container`` script to contain the new image.
Monitoring premerge testing performance
diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst
index d5ed918..756bdf7 100644
--- a/libcxx/docs/FeatureTestMacroTable.rst
+++ b/libcxx/docs/FeatureTestMacroTable.rst
@@ -486,6 +486,8 @@ Status
---------------------------------------------------------- -----------------
``__cpp_lib_not_fn`` ``202306L``
---------------------------------------------------------- -----------------
+ ``__cpp_lib_optional`` ``202506L``
+ ---------------------------------------------------------- -----------------
``__cpp_lib_optional_range_support`` ``202406L``
---------------------------------------------------------- -----------------
``__cpp_lib_out_ptr`` ``202311L``
diff --git a/libcxx/docs/Hardening.rst b/libcxx/docs/Hardening.rst
index 1cdb360..1360518 100644
--- a/libcxx/docs/Hardening.rst
+++ b/libcxx/docs/Hardening.rst
@@ -328,6 +328,20 @@ following options to the compiler:
All the :ref:`same notes <notes-for-users>` apply to setting this macro as for
setting ``_LIBCPP_HARDENING_MODE``.
+Notes for vendors
+-----------------
+
+Similarly to hardening modes, vendors can set the default assertion semantic by
+providing ``LIBCXX_ASSERTION_SEMANTIC`` as a configuration option, with the
+possible values of ``hardening_dependent``, ``ignore``, ``observe``,
+``quick_enforce`` and ``enforce``. The default value is ``hardening_dependent``
+which is a special value that instructs the library to select the semantic based
+on the hardening mode in effect (the mapping is described in
+:ref:`the main section on assertion semantics <assertion-semantics>`).
+
+This option controls both the assertion semantic that the precompiled library is
+built with and the default assertion semantic that users will build with.
+
.. _override-assertion-handler:
Overriding the assertion failure handler
@@ -447,6 +461,13 @@ The first character of an ABI tag encodes the hardening mode:
- ``d`` -- [d]ebug mode;
- ``n`` -- [n]one mode.
+The second character of an ABI tag encodes the assertion semantic:
+
+- ``i`` -- [i]gnore semantic;
+- ``o`` -- [o]bserve semantic;
+- ``q`` -- [q]uick-enforce semantic;
+- ``e`` -- [e]nforce semantic.
+
Hardened containers status
==========================
diff --git a/libcxx/docs/ReleaseNotes/22.rst b/libcxx/docs/ReleaseNotes/22.rst
index a6a0ac8..9f1e3d5 100644
--- a/libcxx/docs/ReleaseNotes/22.rst
+++ b/libcxx/docs/ReleaseNotes/22.rst
@@ -40,6 +40,7 @@ Implemented Papers
- P2321R2: ``zip`` (`Github <https://llvm.org/PR105169>`__) (The paper is partially implemented. ``zip_transform_view``
is implemented in this release)
+- P2988R12: ``std::optional<T&>`` (`Github <https://llvm.org/PR148131>`__)
- P3044R2: sub-``string_view`` from ``string`` (`Github <https://llvm.org/PR148140>`__)
- P3223R2: Making ``std::istream::ignore`` less surprising (`Github <https://llvm.org/PR148178>`__)
- P3060R3: Add ``std::views::indices(n)`` (`Github <https://llvm.org/PR148175>`__)
@@ -66,8 +67,8 @@ Improvements and New Features
by up to 2.5x
- The performance of ``erase(iterator, iterator)`` in the unordered containers has been improved by up to 1.9x
- The performance of ``map::insert_or_assign`` has been improved by up to 2x
-- ``ofstream::write`` and ``ifstream::read`` have been optimized to pass through large reads and writes to system calls
- directly instead of copying them in chunks.
+- ``ofstream::write`` has been optimized to pass through large strings to system calls directly instead of copying them
+ in chunks into a buffer.
- Multiple internal types have been refactored to use ``[[no_unique_address]]``, resulting in faster compile times and
reduced debug information.
@@ -81,6 +82,10 @@ Improvements and New Features
- The ``std::{generate, generate_n}`` and ``std::ranges::generate_n`` algorithms have been optimized for segmented
iterators, resulting in a performance improvement for ``std::deque<short>`` and
``std::join_view<vector<vector<short>>>`` iterators.
+- ``std::atomic::wait`` has been refactored to accept more types to use platform native wait functions directly.
+ This is guarded behind the ABI Macro ``_LIBCPP_ABI_ATOMIC_WAIT_NATIVE_BY_SIZE``.
+
+- The ``num_get::do_get`` integral overloads have been optimized, resulting in a performance improvement of up to 2.8x.
Deprecations and Removals
-------------------------
@@ -113,5 +118,8 @@ ABI Affecting Changes
potentially inheriting from the types they wrap. At this point in time we are not aware of any ABI changes caused by
this.
+- ``ranges::iota_view`` is now aware of ``__int128``. This causes ``iota_view::difference_type`` to change from
+ ``long long`` to ``__int128`` in some cases.
+
Build System Changes
--------------------
diff --git a/libcxx/docs/Status/Cxx23Issues.csv b/libcxx/docs/Status/Cxx23Issues.csv
index 5a68b51..389e1ad 100644
--- a/libcxx/docs/Status/Cxx23Issues.csv
+++ b/libcxx/docs/Status/Cxx23Issues.csv
@@ -58,7 +58,7 @@
"`LWG3495 <https://wg21.link/LWG3495>`__","``constexpr launder`` makes pointers to inactive members of unions usable","2021-02 (Virtual)","|Nothing To Do|","","`#104316 <https://github.com/llvm/llvm-project/issues/104316>`__",""
"`LWG3500 <https://wg21.link/LWG3500>`__","``join_view::iterator::operator->()`` is bogus","2021-02 (Virtual)","|Complete|","14","`#104318 <https://github.com/llvm/llvm-project/issues/104318>`__",""
"`LWG3502 <https://wg21.link/LWG3502>`__","``elements_view`` should not be allowed to return dangling reference","2021-02 (Virtual)","|Complete|","16","`#104319 <https://github.com/llvm/llvm-project/issues/104319>`__",""
-"`LWG3505 <https://wg21.link/LWG3505>`__","``split_view::outer-iterator::operator++`` misspecified","2021-02 (Virtual)","","","`#104320 <https://github.com/llvm/llvm-project/issues/104320>`__",""
+"`LWG3505 <https://wg21.link/LWG3505>`__","``split_view::outer-iterator::operator++`` misspecified","2021-02 (Virtual)","|Complete|","15","`#104320 <https://github.com/llvm/llvm-project/issues/104320>`__",""
"","","","","","",""
"`LWG2774 <https://wg21.link/LWG2774>`__","``std::function`` construction vs assignment","2021-06 (Virtual)","","","`#104321 <https://github.com/llvm/llvm-project/issues/104321>`__",""
"`LWG2818 <https://wg21.link/LWG2818>`__","``::std::`` everywhere rule needs tweaking","2021-06 (Virtual)","|Nothing To Do|","","`#104322 <https://github.com/llvm/llvm-project/issues/104322>`__",""
diff --git a/libcxx/docs/Status/Cxx2cPapers.csv b/libcxx/docs/Status/Cxx2cPapers.csv
index e0e47b8..0455643 100644
--- a/libcxx/docs/Status/Cxx2cPapers.csv
+++ b/libcxx/docs/Status/Cxx2cPapers.csv
@@ -81,7 +81,7 @@
"`P3379R0 <https://wg21.link/P3379R0>`__","Constrain ``std::expected`` equality operators","2024-11 (Wrocław)","|Complete|","21","`#118135 <https://github.com/llvm/llvm-project/issues/118135>`__",""
"`P2862R1 <https://wg21.link/P2862R1>`__","``text_encoding::name()`` should never return null values","2024-11 (Wrocław)","","","`#118371 <https://github.com/llvm/llvm-project/issues/118371>`__",""
"`P2897R7 <https://wg21.link/P2897R7>`__","``aligned_accessor``: An ``mdspan`` accessor expressing pointer over-alignment","2024-11 (Wrocław)","|Complete|","21","`#118372 <https://github.com/llvm/llvm-project/issues/118372>`__",""
-"`P3355R1 <https://wg21.link/P3355R1>`__","Fix ``submdspan`` for C++26","2024-11 (Wrocław)","","","`#118373 <https://github.com/llvm/llvm-project/issues/118373>`__",""
+"`P3355R2 <https://wg21.link/P3355R2>`__","Fix ``submdspan`` for C++26","2024-11 (Wrocław)","","","`#118373 <https://github.com/llvm/llvm-project/issues/118373>`__",""
"`P3222R0 <https://wg21.link/P3222R0>`__","Fix C++26 by adding transposed special cases for P2642 layouts","2024-11 (Wrocław)","","","`#118374 <https://github.com/llvm/llvm-project/issues/118374>`__",""
"`P3050R2 <https://wg21.link/P3050R2>`__","Fix C++26 by optimizing ``linalg::conjugated`` for noncomplex value types","2024-11 (Wrocław)","","","`#118375 <https://github.com/llvm/llvm-project/issues/118375>`__",""
"`P3396R1 <https://wg21.link/P3396R1>`__","``std::execution`` wording fixes","2024-11 (Wrocław)","","","`#118376 <https://github.com/llvm/llvm-project/issues/118376>`__",""
@@ -122,7 +122,7 @@
"`P3293R3 <https://wg21.link/P3293R3>`__","Splicing a base class subobject","2025-06 (Sofia)","","","`#148125 <https://github.com/llvm/llvm-project/issues/148125>`__",""
"`P3491R3 <https://wg21.link/P3491R3>`__","``define_static_{string,object,array}``","2025-06 (Sofia)","","","`#148126 <https://github.com/llvm/llvm-project/issues/148126>`__",""
"`P3096R12 <https://wg21.link/P3096R12>`__","Function Parameter Reflection in Reflection for C++26","2025-06 (Sofia)","","","`#148127 <https://github.com/llvm/llvm-project/issues/148127>`__",""
-"`P2988R12 <https://wg21.link/P2988R12>`__","``std::optional<T&>``","2025-06 (Sofia)","","","`#148131 <https://github.com/llvm/llvm-project/issues/148131>`__",""
+"`P2988R12 <https://wg21.link/P2988R12>`__","``std::optional<T&>``","2025-06 (Sofia)","|Complete|","22","`#148131 <https://github.com/llvm/llvm-project/issues/148131>`__",""
"`P3348R4 <https://wg21.link/P3348R4>`__","C++26 should refer to C23 not C17","2025-06 (Sofia)","","","`#148133 <https://github.com/llvm/llvm-project/issues/148133>`__",""
"`P3037R6 <https://wg21.link/P3037R6>`__","``constexpr`` ``std::shared_ptr`` and friends","2025-06 (Sofia)","","","`#148135 <https://github.com/llvm/llvm-project/issues/148135>`__",""
"`P3284R4 <https://wg21.link/P3284R4>`__","``write_env`` and ``unstoppable`` Sender Adaptors","2025-06 (Sofia)","","","`#148136 <https://github.com/llvm/llvm-project/issues/148136>`__",""
diff --git a/libcxx/docs/VendorDocumentation.rst b/libcxx/docs/VendorDocumentation.rst
index 7eba598..05dc341 100644
--- a/libcxx/docs/VendorDocumentation.rst
+++ b/libcxx/docs/VendorDocumentation.rst
@@ -81,12 +81,14 @@ CMake invocation at ``<monorepo>/llvm``:
.. code-block:: bash
$ mkdir build
- $ cmake -G Ninja -S llvm -B build -DLLVM_ENABLE_PROJECTS="clang" \ # Configure
- -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi;libunwind" \
- -DLLVM_RUNTIME_TARGETS="<target-triple>"
- $ ninja -C build runtimes # Build
- $ ninja -C build check-runtimes # Test
- $ ninja -C build install-runtimes # Install
+ $ cmake -G Ninja -S llvm -B build \
+ -DCMAKE_BUILD_TYPE=RelWithDebInfo \
+ -DLLVM_ENABLE_PROJECTS="clang" \ # Configure
+ -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi;libunwind;compiler-rt" \
+ -DLLVM_RUNTIME_TARGETS="<target-triple>"
+ $ ninja -C build runtimes # Build
+ $ ninja -C build check-runtimes # Test
+ $ ninja -C build install-runtimes # Install
.. note::
- This type of build is also commonly called a "Runtimes build", but we would like to move
@@ -162,10 +164,10 @@ General purpose options
.. option:: LIBCXX_ENABLE_FILESYSTEM:BOOL
- **Default**: ``ON`` except on Windows when using MSVC.
+ **Default**: ``ON``
This option can be used to enable or disable the filesystem components on
- platforms that may not support them. For example on Windows when using MSVC.
+ platforms that may not support them.
.. option:: LIBCXX_ENABLE_WIDE_CHARACTERS:BOOL
@@ -376,6 +378,12 @@ newer (19.14) is required.
Libc++ also supports being built with clang targeting MinGW environments.
+Libc++ supports Windows 7 or newer. However, the minimum runtime version
+of the build is determined by the ``_WIN32_WINNT`` define, which in many
+SDKs defaults to the latest version. To build a version that runs on an
+older version, define e.g. ``_WIN32_WINNT=0x601`` while building libc++,
+to target Windows 7.
+
CMake + Visual Studio
---------------------
@@ -587,3 +595,45 @@ libc++'s ABI guarantees
=======================
Libc++ provides several ABI guarantees, which are documented :ref:`here <ABIGuarantees>`.
+
+Availability Markup
+===================
+
+Libc++ is shipped by various vendors. In particular, it is used as a system library on macOS, iOS and other Apple
+platforms. In order for users to be able to compile a binary that is intended to be deployed to an older version of a
+platform, Clang provides `availability attributes <https://clang.llvm.org/docs/AttributeReference.html#availability>`_.
+These attributes can be placed on declarations and are used to describe the life cycle of a symbol in the library.
+
+The main goal is to ensure a compile-time error if a symbol that hasn't been introduced in a previously released library
+is used in a program that targets that previously released library. Normally, this would be a load-time error when one
+tries to launch the program against the older library.
+
+For example, the filesystem library was introduced in the dylib in LLVM 9. On Apple platforms, this corresponds to
+macOS 10.15. If a user compiles on a macOS 10.15 host but targets macOS 10.13 with their program, the compiler would
+normally not complain (because the required declarations are in the headers), but the dynamic loader would fail to find
+the symbols when actually trying to launch the program on macOS 10.13. To turn this into a compile-time issue instead,
+declarations are annotated with when they were introduced, and the compiler can produce a diagnostic if the program
+references something that isn't available on the deployment target.
+
+This mechanism is general in nature, and any vendor can add their markup to the library (see below). Whenever a new
+feature is added that requires support in the shared library, two macros are added below to allow marking the feature as
+unavailable:
+
+1. A macro named ``_LIBCPP_AVAILABILITY_HAS_<feature>`` which must be defined to ``_LIBCPP_INTRODUCED_IN_<version>`` for
+ the appropriate LLVM version.
+
+2. A macro named ``_LIBCPP_AVAILABILITY_<feature>``, which must be defined to ``_LIBCPP_INTRODUCED_IN_<version>_MARKUP``
+ for the appropriate LLVM version.
+
+When vendors decide to ship the feature as part of their shared library, they can update the
+``_LIBCPP_INTRODUCED_IN_<version>`` macro (and the markup counterpart) based on the platform version they shipped that
+version of LLVM in. The library will then use this markup to provide an optimal user experience on these platforms.
+
+Furthermore, many features in the standard library have corresponding feature-test macros. The
+``_LIBCPP_AVAILABILITY_HAS_<feature>`` macros are checked by the corresponding feature-test macros generated by
+``generate_feature_test_macro_components.py`` to ensure that the library doesn't announce a feature as being implemented
+if it is unavailable on the deployment target.
+
+Note that this mechanism is disabled by default in the "upstream" libc++. Availability annotations are only meaningful
+when shipping libc++ inside a platform (i.e. as a system library), and so vendors that want them should turn those
+annotations on at CMake configuration time.
diff --git a/libcxx/docs/index.rst b/libcxx/docs/index.rst
index 03dfb9d..d006b52 100644
--- a/libcxx/docs/index.rst
+++ b/libcxx/docs/index.rst
@@ -147,7 +147,7 @@ macOS 10.13+ i386, x86_64, arm64
FreeBSD 12+ i386, x86_64, arm
Linux i386, x86_64, arm, arm64 Only glibc-2.24 and later and no other libc is officially supported
Android 5.0+ i386, x86_64, arm, arm64
-Windows i386, x86_64, arm64 Both MSVC and MinGW style environments, ABI in MSVC environments is :doc:`unstable <DesignDocs/ABIVersioning>`
+Windows 7+ i386, x86_64, arm64 Both MSVC and MinGW style environments, ABI in MSVC environments is :doc:`unstable <DesignDocs/ABIVersioning>`
AIX 7.2TL5+ powerpc, powerpc64
Embedded (picolibc) arm
===================== ========================= ============================
diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index 09d4552..cbcd764 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -194,6 +194,7 @@ set(files
__algorithm/simd_utils.h
__algorithm/sort.h
__algorithm/sort_heap.h
+ __algorithm/specialized_algorithms.h
__algorithm/stable_partition.h
__algorithm/stable_sort.h
__algorithm/swap_ranges.h
@@ -328,6 +329,8 @@ set(files
__configuration/abi.h
__configuration/availability.h
__configuration/compiler.h
+ __configuration/experimental.h
+ __configuration/hardening.h
__configuration/language.h
__configuration/platform.h
__coroutine/coroutine_handle.h
@@ -518,7 +521,6 @@ set(files
__locale_dir/locale_base_api.h
__locale_dir/locale_base_api/bsd_locale_fallbacks.h
__locale_dir/locale_base_api/ibm.h
- __locale_dir/locale_base_api/musl.h
__locale_dir/locale_base_api/openbsd.h
__locale_dir/messages.h
__locale_dir/money.h
@@ -531,6 +533,7 @@ set(files
__locale_dir/support/fuchsia.h
__locale_dir/support/linux.h
__locale_dir/support/netbsd.h
+ __locale_dir/support/newlib.h
__locale_dir/support/no_locale/characters.h
__locale_dir/support/no_locale/strtonum.h
__locale_dir/support/windows.h
@@ -568,7 +571,6 @@ set(files
__mdspan/mdspan.h
__memory/addressof.h
__memory/align.h
- __memory/aligned_alloc.h
__memory/allocate_at_least.h
__memory/allocation_guard.h
__memory/allocator.h
@@ -820,7 +822,6 @@ set(files
__type_traits/is_array.h
__type_traits/is_assignable.h
__type_traits/is_base_of.h
- __type_traits/is_bounded_array.h
__type_traits/is_callable.h
__type_traits/is_char_like_type.h
__type_traits/is_class.h
@@ -857,7 +858,6 @@ set(files
__type_traits/is_reference.h
__type_traits/is_reference_wrapper.h
__type_traits/is_referenceable.h
- __type_traits/is_replaceable.h
__type_traits/is_same.h
__type_traits/is_scalar.h
__type_traits/is_signed.h
@@ -871,7 +871,6 @@ set(files
__type_traits/is_trivially_destructible.h
__type_traits/is_trivially_lexicographically_comparable.h
__type_traits/is_trivially_relocatable.h
- __type_traits/is_unbounded_array.h
__type_traits/is_union.h
__type_traits/is_unqualified.h
__type_traits/is_unsigned.h
@@ -1065,7 +1064,6 @@ set(files
sstream
stack
stdatomic.h
- stdbool.h
stddef.h
stdexcept
stdio.h
diff --git a/libcxx/include/__algorithm/all_of.h b/libcxx/include/__algorithm/all_of.h
index 6acc117..9bdb20a 100644
--- a/libcxx/include/__algorithm/all_of.h
+++ b/libcxx/include/__algorithm/all_of.h
@@ -10,24 +10,28 @@
#ifndef _LIBCPP___ALGORITHM_ALL_OF_H
#define _LIBCPP___ALGORITHM_ALL_OF_H
+#include <__algorithm/any_of.h>
#include <__config>
#include <__functional/identity.h>
#include <__type_traits/invoke.h>
+#include <__utility/forward.h>
+#include <__utility/move.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _Iter, class _Sent, class _Proj, class _Pred>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
__all_of(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) {
- for (; __first != __last; ++__first) {
- if (!std::__invoke(__pred, std::__invoke(__proj, *__first)))
- return false;
- }
- return true;
+ using _Ref = decltype(std::__invoke(__proj, *__first));
+ auto __negated_pred = [&__pred](_Ref __arg) -> bool { return !std::__invoke(__pred, std::forward<_Ref>(__arg)); };
+ return !std::__any_of(std::move(__first), std::move(__last), __negated_pred, __proj);
}
template <class _InputIterator, class _Predicate>
@@ -39,4 +43,6 @@ all_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) {
_LIBCPP_END_NAMESPACE_STD
+_LIBCPP_POP_MACROS
+
#endif // _LIBCPP___ALGORITHM_ALL_OF_H
diff --git a/libcxx/include/__algorithm/copy_n.h b/libcxx/include/__algorithm/copy_n.h
index f93f392..56fb448 100644
--- a/libcxx/include/__algorithm/copy_n.h
+++ b/libcxx/include/__algorithm/copy_n.h
@@ -10,31 +10,63 @@
#define _LIBCPP___ALGORITHM_COPY_N_H
#include <__algorithm/copy.h>
+#include <__algorithm/iterator_operations.h>
#include <__config>
#include <__iterator/iterator_traits.h>
#include <__type_traits/enable_if.h>
#include <__utility/convert_to_integral.h>
+#include <__utility/move.h>
+#include <__utility/pair.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
_LIBCPP_BEGIN_NAMESPACE_STD
+template <class _AlgPolicy,
+ class _InIter,
+ class _OutIter,
+ __enable_if_t<__has_random_access_iterator_category<_InIter>::value, int> = 0>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InIter, _OutIter>
+__copy_n(_InIter __first, typename _IterOps<_AlgPolicy>::template __difference_type<_InIter> __n, _OutIter __result) {
+ return std::__copy(__first, __first + __n, std::move(__result));
+}
+
+template <class _AlgPolicy,
+ class _InIter,
+ class _OutIter,
+ __enable_if_t<!__has_random_access_iterator_category<_InIter>::value, int> = 0>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InIter, _OutIter>
+__copy_n(_InIter __first, typename _IterOps<_AlgPolicy>::template __difference_type<_InIter> __n, _OutIter __result) {
+ while (__n != 0) {
+ *__result = *__first;
+ ++__first;
+ ++__result;
+ --__n;
+ }
+ return std::make_pair(std::move(__first), std::move(__result));
+}
+
+// The InputIterator case is handled specially here because it's been written in a way to avoid incrementing __first
+// if not absolutely required. This was done to allow its use with istream_iterator and we want to avoid breaking
+// people, at least currently.
+// See https://github.com/llvm/llvm-project/commit/99847d2bf132854fffa019bab19818768102ccad
template <class _InputIterator,
class _Size,
class _OutputIterator,
- __enable_if_t<__has_input_iterator_category<_InputIterator>::value &&
- !__has_random_access_iterator_category<_InputIterator>::value,
- int> = 0>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
-copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result) {
- typedef decltype(std::__convert_to_integral(__orig_n)) _IntegralSize;
- _IntegralSize __n = __orig_n;
- if (__n > 0) {
+ __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> = 0>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
+copy_n(_InputIterator __first, _Size __n, _OutputIterator __result) {
+ using _IntegralSize = decltype(std::__convert_to_integral(__n));
+ _IntegralSize __converted = __n;
+ if (__converted > 0) {
*__result = *__first;
++__result;
- for (--__n; __n > 0; --__n) {
+ for (--__converted; __converted > 0; --__converted) {
++__first;
*__result = *__first;
++__result;
@@ -46,15 +78,17 @@ copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result) {
template <class _InputIterator,
class _Size,
class _OutputIterator,
- __enable_if_t<__has_random_access_iterator_category<_InputIterator>::value, int> = 0>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
-copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result) {
- typedef typename iterator_traits<_InputIterator>::difference_type difference_type;
- typedef decltype(std::__convert_to_integral(__orig_n)) _IntegralSize;
- _IntegralSize __n = __orig_n;
- return std::copy(__first, __first + difference_type(__n), __result);
+ __enable_if_t<!__has_exactly_input_iterator_category<_InputIterator>::value, int> = 0>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
+copy_n(_InputIterator __first, _Size __n, _OutputIterator __result) {
+ using _IntegralSize = decltype(std::__convert_to_integral(__n));
+ _IntegralSize __converted = __n;
+ return std::__copy_n<_ClassicAlgPolicy>(__first, __iterator_difference_type<_InputIterator>(__converted), __result)
+ .second;
}
_LIBCPP_END_NAMESPACE_STD
+_LIBCPP_POP_MACROS
+
#endif // _LIBCPP___ALGORITHM_COPY_N_H
diff --git a/libcxx/include/__algorithm/fill_n.h b/libcxx/include/__algorithm/fill_n.h
index 426fe22..3d06ea4 100644
--- a/libcxx/include/__algorithm/fill_n.h
+++ b/libcxx/include/__algorithm/fill_n.h
@@ -10,13 +10,13 @@
#define _LIBCPP___ALGORITHM_FILL_N_H
#include <__algorithm/for_each_n_segment.h>
-#include <__algorithm/min.h>
+#include <__algorithm/specialized_algorithms.h>
#include <__config>
-#include <__fwd/bit_reference.h>
#include <__iterator/iterator_traits.h>
#include <__iterator/segmented_iterator.h>
-#include <__memory/pointer_traits.h>
+#include <__type_traits/enable_if.h>
#include <__utility/convert_to_integral.h>
+#include <__utility/move.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -29,7 +29,12 @@ _LIBCPP_BEGIN_NAMESPACE_STD
// fill_n isn't specialized for std::memset, because the compiler already optimizes the loop to a call to std::memset.
-template <class _OutputIterator, class _Size, class _Tp>
+template <
+ class _OutputIterator,
+ class _Size,
+ class _Tp,
+ __enable_if_t<!__specialized_algorithm<_Algorithm::__fill_n, __single_iterator<_OutputIterator> >::__has_algorithm,
+ int> = 0>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
__fill_n(_OutputIterator __first, _Size __n, const _Tp& __value) {
#ifndef _LIBCPP_CXX03_LANG
@@ -47,42 +52,14 @@ __fill_n(_OutputIterator __first, _Size __n, const _Tp& __value) {
return __first;
}
-template <bool _FillVal, class _Cp>
-_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
-__fill_n_bool(__bit_iterator<_Cp, false> __first, typename __size_difference_type_traits<_Cp>::size_type __n) {
- using _It = __bit_iterator<_Cp, false>;
- using __storage_type = typename _It::__storage_type;
-
- const int __bits_per_word = _It::__bits_per_word;
- // do first partial word
- if (__first.__ctz_ != 0) {
- __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_);
- __storage_type __dn = std::min(__clz_f, __n);
- std::__fill_masked_range(std::__to_address(__first.__seg_), __clz_f - __dn, __first.__ctz_, _FillVal);
- __n -= __dn;
- ++__first.__seg_;
- }
- // do middle whole words
- __storage_type __nw = __n / __bits_per_word;
- std::__fill_n(std::__to_address(__first.__seg_), __nw, _FillVal ? static_cast<__storage_type>(-1) : 0);
- __n -= __nw * __bits_per_word;
- // do last partial word
- if (__n > 0) {
- __first.__seg_ += __nw;
- std::__fill_masked_range(std::__to_address(__first.__seg_), __bits_per_word - __n, 0u, _FillVal);
- }
-}
-
-template <class _Cp, class _Size>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator<_Cp, false>
-__fill_n(__bit_iterator<_Cp, false> __first, _Size __n, const bool& __value) {
- if (__n > 0) {
- if (__value)
- std::__fill_n_bool<true>(__first, __n);
- else
- std::__fill_n_bool<false>(__first, __n);
- }
- return __first + __n;
+template <class _OutIter,
+ class _Size,
+ class _Tp,
+ __enable_if_t<__specialized_algorithm<_Algorithm::__fill_n, __single_iterator<_OutIter> >::__has_algorithm,
+ int> = 0>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutIter __fill_n(_OutIter __first, _Size __n, const _Tp& __value) {
+ return __specialized_algorithm<_Algorithm::__fill_n, __single_iterator<_OutIter> >()(
+ std::move(__first), __n, __value);
}
template <class _OutputIterator, class _Size, class _Tp>
diff --git a/libcxx/include/__algorithm/find.h b/libcxx/include/__algorithm/find.h
index 10379d7..d03421b 100644
--- a/libcxx/include/__algorithm/find.h
+++ b/libcxx/include/__algorithm/find.h
@@ -230,7 +230,8 @@ struct __find_segment {
template <class _InputIterator, class _Proj>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _InputIterator
operator()(_InputIterator __first, _InputIterator __last, _Proj& __proj) const {
- return std::__find(__first, __last, __value_, __proj);
+ return std::__rewrap_iter(
+ __first, std::__find(std::__unwrap_iter(__first), std::__unwrap_iter(__last), __value_, __proj));
}
};
diff --git a/libcxx/include/__algorithm/iterator_operations.h b/libcxx/include/__algorithm/iterator_operations.h
index e5c89c1..1aa2f8d16 100644
--- a/libcxx/include/__algorithm/iterator_operations.h
+++ b/libcxx/include/__algorithm/iterator_operations.h
@@ -219,6 +219,9 @@ private:
template <class _AlgPolicy, class _Iter>
using __policy_iter_diff_t _LIBCPP_NODEBUG = typename _IterOps<_AlgPolicy>::template __difference_type<_Iter>;
+template <class _AlgPolicy, class _Iter>
+using __policy_value_type _LIBCPP_NODEBUG = typename _IterOps<_AlgPolicy>::template __value_type<_Iter>;
+
_LIBCPP_END_NAMESPACE_STD
_LIBCPP_POP_MACROS
diff --git a/libcxx/include/__algorithm/none_of.h b/libcxx/include/__algorithm/none_of.h
index e6bd197..1e1c8d1a 100644
--- a/libcxx/include/__algorithm/none_of.h
+++ b/libcxx/include/__algorithm/none_of.h
@@ -10,7 +10,9 @@
#ifndef _LIBCPP___ALGORITHM_NONE_OF_H
#define _LIBCPP___ALGORITHM_NONE_OF_H
+#include <__algorithm/any_of.h>
#include <__config>
+#include <__functional/identity.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -21,10 +23,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD
template <class _InputIterator, class _Predicate>
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
none_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) {
- for (; __first != __last; ++__first)
- if (__pred(*__first))
- return false;
- return true;
+ __identity __proj;
+ return !std::__any_of(__first, __last, __pred, __proj);
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/ranges_copy_n.h b/libcxx/include/__algorithm/ranges_copy_n.h
index 1fbc616..6bee4c3 100644
--- a/libcxx/include/__algorithm/ranges_copy_n.h
+++ b/libcxx/include/__algorithm/ranges_copy_n.h
@@ -9,16 +9,12 @@
#ifndef _LIBCPP___ALGORITHM_RANGES_COPY_N_H
#define _LIBCPP___ALGORITHM_RANGES_COPY_N_H
-#include <__algorithm/copy.h>
+#include <__algorithm/copy_n.h>
#include <__algorithm/in_out_result.h>
#include <__algorithm/iterator_operations.h>
-#include <__algorithm/ranges_copy.h>
#include <__config>
-#include <__functional/identity.h>
#include <__iterator/concepts.h>
#include <__iterator/incrementable_traits.h>
-#include <__iterator/unreachable_sentinel.h>
-#include <__iterator/wrap_iter.h>
#include <__utility/move.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -37,32 +33,13 @@ namespace ranges {
template <class _Ip, class _Op>
using copy_n_result = in_out_result<_Ip, _Op>;
-// TODO: Merge this with copy_n
struct __copy_n {
- template <class _InIter, class _DiffType, class _OutIter>
- _LIBCPP_HIDE_FROM_ABI constexpr static copy_n_result<_InIter, _OutIter>
- __go(_InIter __first, _DiffType __n, _OutIter __result) {
- while (__n != 0) {
- *__result = *__first;
- ++__first;
- ++__result;
- --__n;
- }
- return {std::move(__first), std::move(__result)};
- }
-
- template <random_access_iterator _InIter, class _DiffType, random_access_iterator _OutIter>
- _LIBCPP_HIDE_FROM_ABI constexpr static copy_n_result<_InIter, _OutIter>
- __go(_InIter __first, _DiffType __n, _OutIter __result) {
- auto __ret = std::__copy(__first, __first + __n, __result);
- return {__ret.first, __ret.second};
- }
-
template <input_iterator _Ip, weakly_incrementable _Op>
requires indirectly_copyable<_Ip, _Op>
_LIBCPP_HIDE_FROM_ABI constexpr copy_n_result<_Ip, _Op>
operator()(_Ip __first, iter_difference_t<_Ip> __n, _Op __result) const {
- return __go(std::move(__first), __n, std::move(__result));
+ auto __res = std::__copy_n<_RangeAlgPolicy>(std::move(__first), __n, std::move(__result));
+ return {std::move(__res.first), std::move(__res.second)};
}
};
diff --git a/libcxx/include/__algorithm/simd_utils.h b/libcxx/include/__algorithm/simd_utils.h
index aaeb8a8..f73c9ea 100644
--- a/libcxx/include/__algorithm/simd_utils.h
+++ b/libcxx/include/__algorithm/simd_utils.h
@@ -114,6 +114,27 @@ template <class _VecT, class _Iter>
}(make_index_sequence<__simd_vector_size_v<_VecT>>{});
}
+// Load the first _Np elements, zero the rest
+_LIBCPP_DIAGNOSTIC_PUSH
+_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wpsabi")
+template <class _VecT, size_t _Np, class _Iter>
+[[__nodiscard__]] _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _VecT __partial_load(_Iter __iter) noexcept {
+ return [=]<size_t... _LoadIndices, size_t... _ZeroIndices>(
+ index_sequence<_LoadIndices...>, index_sequence<_ZeroIndices...>) _LIBCPP_ALWAYS_INLINE noexcept {
+ return _VecT{__iter[_LoadIndices]..., ((void)_ZeroIndices, 0)...};
+ }(make_index_sequence<_Np>{}, make_index_sequence<__simd_vector_size_v<_VecT> - _Np>{});
+}
+
+// Create a vector where every elements is __val
+template <class _VecT>
+[[__nodiscard__]] _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _VecT
+__broadcast(__simd_vector_underlying_type_t<_VecT> __val) {
+ return [&]<std::size_t... _Indices>(index_sequence<_Indices...>) {
+ return _VecT{((void)_Indices, __val)...};
+ }(make_index_sequence<__simd_vector_size_v<_VecT>>());
+}
+_LIBCPP_DIAGNOSTIC_POP
+
template <class _Tp, size_t _Np>
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool __any_of(__simd_vector<_Tp, _Np> __vec) noexcept {
return __builtin_reduce_or(__builtin_convertvector(__vec, __simd_vector<bool, _Np>));
@@ -125,6 +146,11 @@ template <class _Tp, size_t _Np>
}
template <class _Tp, size_t _Np>
+[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool __none_of(__simd_vector<_Tp, _Np> __vec) noexcept {
+ return !__builtin_reduce_or(__builtin_convertvector(__vec, __simd_vector<bool, _Np>));
+}
+
+template <class _Tp, size_t _Np>
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t __find_first_set(__simd_vector<_Tp, _Np> __vec) noexcept {
using __mask_vec = __simd_vector<bool, _Np>;
diff --git a/libcxx/include/__algorithm/specialized_algorithms.h b/libcxx/include/__algorithm/specialized_algorithms.h
new file mode 100644
index 0000000..a2ffd36
--- /dev/null
+++ b/libcxx/include/__algorithm/specialized_algorithms.h
@@ -0,0 +1,46 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_SPECIALIZED_ALGORITHMS_H
+#define _LIBCPP___ALGORITHM_SPECIALIZED_ALGORITHMS_H
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace _Algorithm {
+struct __fill_n {};
+} // namespace _Algorithm
+
+template <class>
+struct __single_iterator;
+
+// This struct allows specializing algorithms for specific arguments. This is useful when we know a more efficient
+// algorithm implementation for e.g. library-defined iterators. _Alg is one of tags defined inside the _Algorithm
+// namespace above. _Ranges is an essentially arbitrary subset of the arguments to the algorithm that are used for
+// dispatching. This set is specific to the algorithm: look at each algorithm to see which arguments they use for
+// dispatching to specialized algorithms.
+//
+// A specialization of `__specialized_algorithm` has to define `__has_algorithm` to true for the specialized algorithm
+// to be used. This is intended for cases where iterators can do generic unwrapping and forward to a different
+// specialization of `__specialized_algorithm`.
+//
+// If __has_algorithm is true, there has to be an operator() which will get called with the actual arguments to the
+// algorithm.
+template <class _Alg, class... _Ranges>
+struct __specialized_algorithm {
+ static const bool __has_algorithm = false;
+};
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___ALGORITHM_SPECIALIZED_ALGORITHMS_H
diff --git a/libcxx/include/__atomic/atomic.h b/libcxx/include/__atomic/atomic.h
index 4483582..554c111 100644
--- a/libcxx/include/__atomic/atomic.h
+++ b/libcxx/include/__atomic/atomic.h
@@ -206,6 +206,8 @@ struct __atomic_base<_Tp, true> : public __atomic_base<_Tp, false> {
// __atomic_base<int, false>. So specializing __atomic_base<_Tp> does not work
template <class _Tp, bool _IsIntegral>
struct __atomic_waitable_traits<__atomic_base<_Tp, _IsIntegral> > {
+ using __value_type _LIBCPP_NODEBUG = _Tp;
+
static _LIBCPP_HIDE_FROM_ABI _Tp __atomic_load(const __atomic_base<_Tp, _IsIntegral>& __a, memory_order __order) {
return __a.load(__order);
}
diff --git a/libcxx/include/__atomic/atomic_flag.h b/libcxx/include/__atomic/atomic_flag.h
index 28ed2d5..321a628 100644
--- a/libcxx/include/__atomic/atomic_flag.h
+++ b/libcxx/include/__atomic/atomic_flag.h
@@ -76,6 +76,8 @@ struct atomic_flag {
template <>
struct __atomic_waitable_traits<atomic_flag> {
+ using __value_type _LIBCPP_NODEBUG = _LIBCPP_ATOMIC_FLAG_TYPE;
+
static _LIBCPP_HIDE_FROM_ABI _LIBCPP_ATOMIC_FLAG_TYPE __atomic_load(const atomic_flag& __a, memory_order __order) {
return std::__cxx_atomic_load(&__a.__a_, __order);
}
diff --git a/libcxx/include/__atomic/atomic_ref.h b/libcxx/include/__atomic/atomic_ref.h
index ec5ae2c..9a36aaa 100644
--- a/libcxx/include/__atomic/atomic_ref.h
+++ b/libcxx/include/__atomic/atomic_ref.h
@@ -233,6 +233,8 @@ protected:
template <class _Tp>
struct __atomic_waitable_traits<__atomic_ref_base<_Tp>> {
+ using __value_type _LIBCPP_NODEBUG = _Tp;
+
static _LIBCPP_HIDE_FROM_ABI _Tp __atomic_load(const __atomic_ref_base<_Tp>& __a, memory_order __order) {
return __a.load(__order);
}
diff --git a/libcxx/include/__atomic/atomic_sync.h b/libcxx/include/__atomic/atomic_sync.h
index 93953df..d0119ab 100644
--- a/libcxx/include/__atomic/atomic_sync.h
+++ b/libcxx/include/__atomic/atomic_sync.h
@@ -18,7 +18,10 @@
#include <__thread/poll_with_backoff.h>
#include <__type_traits/conjunction.h>
#include <__type_traits/decay.h>
+#include <__type_traits/has_unique_object_representation.h>
#include <__type_traits/invoke.h>
+#include <__type_traits/is_same.h>
+#include <__type_traits/is_trivially_copyable.h>
#include <__type_traits/void_t.h>
#include <__utility/declval.h>
#include <cstring>
@@ -38,6 +41,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD
// The below implementations look ugly to support C++03
template <class _Tp, class = void>
struct __atomic_waitable_traits {
+ using __value_type _LIBCPP_NODEBUG = void;
+
template <class _AtomicWaitable>
static void __atomic_load(_AtomicWaitable&&, memory_order) = delete;
@@ -58,6 +63,9 @@ struct __atomic_waitable< _Tp,
#if _LIBCPP_STD_VER >= 20
# if _LIBCPP_HAS_THREADS
+# if !_LIBCPP_AVAILABILITY_HAS_NEW_SYNC
+
+// old dylib interface kept for backwards compatibility
_LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(void const volatile*) _NOEXCEPT;
_LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all(void const volatile*) _NOEXCEPT;
_LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t __libcpp_atomic_monitor(void const volatile*) _NOEXCEPT;
@@ -69,6 +77,114 @@ _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t
__libcpp_atomic_monitor(__cxx_atomic_contention_t const volatile*) _NOEXCEPT;
_LIBCPP_EXPORTED_FROM_ABI void
__libcpp_atomic_wait(__cxx_atomic_contention_t const volatile*, __cxx_contention_t) _NOEXCEPT;
+# endif // !_LIBCPP_AVAILABILITY_HAS_NEW_SYNC
+
+// new dylib interface
+
+// return the global contention state's current value for the address
+_LIBCPP_AVAILABILITY_NEW_SYNC _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t
+__atomic_monitor_global(void const* __address) _NOEXCEPT;
+
+// wait on the global contention state to be changed from the given value for the address
+_LIBCPP_AVAILABILITY_NEW_SYNC _LIBCPP_EXPORTED_FROM_ABI void
+__atomic_wait_global_table(void const* __address, __cxx_contention_t __monitor_value) _NOEXCEPT;
+
+// notify one waiter waiting on the global contention state for the address
+_LIBCPP_AVAILABILITY_NEW_SYNC _LIBCPP_EXPORTED_FROM_ABI void __atomic_notify_one_global_table(void const*) _NOEXCEPT;
+
+// notify all waiters waiting on the global contention state for the address
+_LIBCPP_AVAILABILITY_NEW_SYNC _LIBCPP_EXPORTED_FROM_ABI void __atomic_notify_all_global_table(void const*) _NOEXCEPT;
+
+// wait on the address directly with the native platform wait
+template <std::size_t _Size>
+_LIBCPP_AVAILABILITY_NEW_SYNC _LIBCPP_EXPORTED_FROM_ABI void
+__atomic_wait_native(void const* __address, void const* __old_value) _NOEXCEPT;
+
+// notify one waiter waiting on the address directly with the native platform wait
+template <std::size_t _Size>
+_LIBCPP_AVAILABILITY_NEW_SYNC _LIBCPP_EXPORTED_FROM_ABI void __atomic_notify_one_native(const void*) _NOEXCEPT;
+
+// notify all waiters waiting on the address directly with the native platform wait
+template <std::size_t _Size>
+_LIBCPP_AVAILABILITY_NEW_SYNC _LIBCPP_EXPORTED_FROM_ABI void __atomic_notify_all_native(const void*) _NOEXCEPT;
+
+# ifdef __linux__
+# define _LIBCPP_NATIVE_PLATFORM_WAIT_SIZES(_APPLY) _APPLY(4)
+# elif defined(__APPLE__)
+# define _LIBCPP_NATIVE_PLATFORM_WAIT_SIZES(_APPLY) \
+ _APPLY(4) \
+ _APPLY(8)
+# elif defined(__FreeBSD__) && __SIZEOF_LONG__ == 8
+# define _LIBCPP_NATIVE_PLATFORM_WAIT_SIZES(_APPLY) _APPLY(8)
+# elif defined(_WIN32)
+# define _LIBCPP_NATIVE_PLATFORM_WAIT_SIZES(_APPLY) _APPLY(8)
+# else
+# define _LIBCPP_NATIVE_PLATFORM_WAIT_SIZES(_APPLY) _APPLY(sizeof(__cxx_contention_t))
+# endif // __linux__
+
+// concepts defines the types are supported natively by the platform's wait
+
+# if defined(_LIBCPP_ABI_ATOMIC_WAIT_NATIVE_BY_SIZE)
+
+_LIBCPP_HIDE_FROM_ABI constexpr bool __has_native_atomic_wait_impl(size_t __size) {
+ switch (__size) {
+# define _LIBCPP_MAKE_CASE(n) \
+ case n: \
+ return true;
+ _LIBCPP_NATIVE_PLATFORM_WAIT_SIZES(_LIBCPP_MAKE_CASE)
+ default:
+ return false;
+# undef _LIBCPP_MAKE_CASE
+ };
+}
+
+template <class _Tp>
+concept __has_native_atomic_wait =
+ has_unique_object_representations_v<_Tp> && is_trivially_copyable_v<_Tp> &&
+ __has_native_atomic_wait_impl(sizeof(_Tp));
+
+# else // _LIBCPP_ABI_ATOMIC_WAIT_NATIVE_BY_SIZE
+
+template <class _Tp>
+concept __has_native_atomic_wait = is_same_v<_Tp, __cxx_contention_t>;
+
+# endif // _LIBCPP_ABI_ATOMIC_WAIT_NATIVE_BY_SIZE
+
+# if _LIBCPP_AVAILABILITY_HAS_NEW_SYNC
+
+template <class _AtomicWaitable, class _Poll>
+struct __atomic_wait_backoff_impl {
+ const _AtomicWaitable& __a_;
+ _Poll __poll_;
+ memory_order __order_;
+
+ using __waitable_traits _LIBCPP_NODEBUG = __atomic_waitable_traits<__decay_t<_AtomicWaitable> >;
+ using __value_type _LIBCPP_NODEBUG = typename __waitable_traits::__value_type;
+
+ _LIBCPP_HIDE_FROM_ABI bool operator()(chrono::nanoseconds __elapsed) const {
+ if (__elapsed > chrono::microseconds(4)) {
+ auto __contention_address = const_cast<const void*>(
+ static_cast<const volatile void*>(__waitable_traits::__atomic_contention_address(__a_)));
+
+ if constexpr (__has_native_atomic_wait<__value_type>) {
+ auto __atomic_value = __waitable_traits::__atomic_load(__a_, __order_);
+ if (__poll_(__atomic_value))
+ return true;
+ std::__atomic_wait_native<sizeof(__value_type)>(__contention_address, std::addressof(__atomic_value));
+ } else {
+ __cxx_contention_t __monitor_val = std::__atomic_monitor_global(__contention_address);
+ auto __atomic_value = __waitable_traits::__atomic_load(__a_, __order_);
+ if (__poll_(__atomic_value))
+ return true;
+ std::__atomic_wait_global_table(__contention_address, __monitor_val);
+ }
+ } else {
+ } // poll
+ return false;
+ }
+};
+
+# else // _LIBCPP_AVAILABILITY_HAS_NEW_SYNC
template <class _AtomicWaitable, class _Poll>
struct __atomic_wait_backoff_impl {
@@ -112,6 +228,8 @@ struct __atomic_wait_backoff_impl {
}
};
+# endif // _LIBCPP_AVAILABILITY_HAS_NEW_SYNC
+
// The semantics of this function are similar to `atomic`'s
// `.wait(T old, std::memory_order order)`, but instead of having a hardcoded
// predicate (is the loaded value unequal to `old`?), the predicate function is
@@ -133,6 +251,38 @@ _LIBCPP_HIDE_FROM_ABI void __atomic_wait_unless(const _AtomicWaitable& __a, memo
/* backoff */ __backoff_fn);
}
+# if _LIBCPP_AVAILABILITY_HAS_NEW_SYNC
+
+template <class _AtomicWaitable>
+_LIBCPP_HIDE_FROM_ABI void __atomic_notify_one(const _AtomicWaitable& __a) {
+ static_assert(__atomic_waitable<_AtomicWaitable>::value, "");
+ using __value_type _LIBCPP_NODEBUG = typename __atomic_waitable_traits<__decay_t<_AtomicWaitable> >::__value_type;
+ using __waitable_traits _LIBCPP_NODEBUG = __atomic_waitable_traits<__decay_t<_AtomicWaitable> >;
+ auto __contention_address =
+ const_cast<const void*>(static_cast<const volatile void*>(__waitable_traits::__atomic_contention_address(__a)));
+ if constexpr (__has_native_atomic_wait<__value_type>) {
+ std::__atomic_notify_one_native<sizeof(__value_type)>(__contention_address);
+ } else {
+ std::__atomic_notify_one_global_table(__contention_address);
+ }
+}
+
+template <class _AtomicWaitable>
+_LIBCPP_HIDE_FROM_ABI void __atomic_notify_all(const _AtomicWaitable& __a) {
+ static_assert(__atomic_waitable<_AtomicWaitable>::value, "");
+ using __value_type _LIBCPP_NODEBUG = typename __atomic_waitable_traits<__decay_t<_AtomicWaitable> >::__value_type;
+ using __waitable_traits _LIBCPP_NODEBUG = __atomic_waitable_traits<__decay_t<_AtomicWaitable> >;
+ auto __contention_address =
+ const_cast<const void*>(static_cast<const volatile void*>(__waitable_traits::__atomic_contention_address(__a)));
+ if constexpr (__has_native_atomic_wait<__value_type>) {
+ std::__atomic_notify_all_native<sizeof(__value_type)>(__contention_address);
+ } else {
+ std::__atomic_notify_all_global_table(__contention_address);
+ }
+}
+
+# else // _LIBCPP_AVAILABILITY_HAS_NEW_SYNC
+
template <class _AtomicWaitable>
_LIBCPP_HIDE_FROM_ABI void __atomic_notify_one(const _AtomicWaitable& __a) {
static_assert(__atomic_waitable<_AtomicWaitable>::value, "");
@@ -145,6 +295,8 @@ _LIBCPP_HIDE_FROM_ABI void __atomic_notify_all(const _AtomicWaitable& __a) {
std::__cxx_atomic_notify_all(__atomic_waitable_traits<__decay_t<_AtomicWaitable> >::__atomic_contention_address(__a));
}
+# endif
+
# else // _LIBCPP_HAS_THREADS
template <class _AtomicWaitable, class _Poll>
diff --git a/libcxx/include/__atomic/contention_t.h b/libcxx/include/__atomic/contention_t.h
index 5b42a01..b7e3704 100644
--- a/libcxx/include/__atomic/contention_t.h
+++ b/libcxx/include/__atomic/contention_t.h
@@ -19,11 +19,35 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if defined(__linux__) || (defined(_AIX) && !defined(__64BIT__))
+// The original definition of `__cxx_contention_t` seemed a bit arbitrary.
+// When we enable the _LIBCPP_ABI_ATOMIC_WAIT_NATIVE_BY_SIZE ABI,
+// use definitions that are based on what the underlying platform supports
+// instead.
+#if defined(_LIBCPP_ABI_ATOMIC_WAIT_NATIVE_BY_SIZE)
+
+# ifdef __linux__
+using __cxx_contention_t _LIBCPP_NODEBUG = int32_t;
+# elif defined(__APPLE__)
+using __cxx_contention_t _LIBCPP_NODEBUG = int64_t;
+# elif defined(__FreeBSD__) && __SIZEOF_LONG__ == 8
+using __cxx_contention_t _LIBCPP_NODEBUG = int64_t;
+# elif defined(_AIX) && !defined(__64BIT__)
+using __cxx_contention_t _LIBCPP_NODEBUG = int32_t;
+# elif defined(_WIN32)
+using __cxx_contention_t _LIBCPP_NODEBUG = int64_t;
+# else
+using __cxx_contention_t _LIBCPP_NODEBUG = int64_t;
+# endif // __linux__
+
+#else // _LIBCPP_ABI_ATOMIC_WAIT_NATIVE_BY_SIZE
+
+# if defined(__linux__) || (defined(_AIX) && !defined(__64BIT__))
using __cxx_contention_t _LIBCPP_NODEBUG = int32_t;
-#else
+# else
using __cxx_contention_t _LIBCPP_NODEBUG = int64_t;
-#endif // __linux__ || (_AIX && !__64BIT__)
+# endif // __linux__ || (_AIX && !__64BIT__)
+
+#endif // _LIBCPP_ABI_ATOMIC_WAIT_NATIVE_BY_SIZE
using __cxx_atomic_contention_t _LIBCPP_NODEBUG = __cxx_atomic_impl<__cxx_contention_t>;
diff --git a/libcxx/include/__bit/has_single_bit.h b/libcxx/include/__bit/has_single_bit.h
index d10ab7d..c49c518 100644
--- a/libcxx/include/__bit/has_single_bit.h
+++ b/libcxx/include/__bit/has_single_bit.h
@@ -25,7 +25,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
template <__unsigned_integer _Tp>
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool has_single_bit(_Tp __t) noexcept {
- return __t != 0 && ((__t & (__t - 1)) == 0);
+ return __builtin_popcountg(__t) == 1;
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__bit_reference b/libcxx/include/__bit_reference
index a3e6def..00bbc41 100644
--- a/libcxx/include/__bit_reference
+++ b/libcxx/include/__bit_reference
@@ -15,8 +15,10 @@
#include <__algorithm/copy_backward.h>
#include <__algorithm/copy_n.h>
#include <__algorithm/equal.h>
+#include <__algorithm/fill_n.h>
#include <__algorithm/min.h>
#include <__algorithm/rotate.h>
+#include <__algorithm/specialized_algorithms.h>
#include <__algorithm/swap_ranges.h>
#include <__assert>
#include <__bit/countr.h>
@@ -137,7 +139,7 @@ public:
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 operator bool() const _NOEXCEPT {
return static_cast<bool>(*__seg_ & __mask_);
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool operator~() const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool operator~() const _NOEXCEPT {
return !static_cast<bool>(*this);
}
@@ -467,10 +469,6 @@ private:
template <class _Dp>
friend struct __bit_array;
- template <bool _FillVal, class _Dp>
- _LIBCPP_CONSTEXPR_SINCE_CXX20 friend void
- __fill_n_bool(__bit_iterator<_Dp, false> __first, typename __size_difference_type_traits<_Dp>::size_type __n);
-
template <class _Dp, bool _IC>
_LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Dp, false> __copy_aligned(
__bit_iterator<_Dp, _IC> __first, __bit_iterator<_Dp, _IC> __last, __bit_iterator<_Dp, false> __result);
@@ -537,6 +535,52 @@ private:
template <bool _ToCount, class _Dp, bool _IC>
friend typename __bit_iterator<_Dp, _IC>::difference_type _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
__count_bool(__bit_iterator<_Dp, _IC>, typename __size_difference_type_traits<_Dp>::size_type);
+
+ template <class, class...>
+ friend struct __specialized_algorithm;
+};
+
+template <class _Cp>
+struct __specialized_algorithm<_Algorithm::__fill_n, __single_iterator<__bit_iterator<_Cp, false> > > {
+ static const bool __has_algorithm = true;
+
+ template <bool _FillVal>
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static void
+ __impl(__bit_iterator<_Cp, false> __first, typename __size_difference_type_traits<_Cp>::size_type __n) {
+ using _It = __bit_iterator<_Cp, false>;
+ using __storage_type = typename _It::__storage_type;
+
+ const int __bits_per_word = _It::__bits_per_word;
+ // do first partial word
+ if (__first.__ctz_ != 0) {
+ __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_);
+ __storage_type __dn = std::min(__clz_f, __n);
+ std::__fill_masked_range(std::__to_address(__first.__seg_), __clz_f - __dn, __first.__ctz_, _FillVal);
+ __n -= __dn;
+ ++__first.__seg_;
+ }
+ // do middle whole words
+ __storage_type __nw = __n / __bits_per_word;
+ std::__fill_n(std::__to_address(__first.__seg_), __nw, _FillVal ? static_cast<__storage_type>(-1) : 0);
+ __n -= __nw * __bits_per_word;
+ // do last partial word
+ if (__n > 0) {
+ __first.__seg_ += __nw;
+ std::__fill_masked_range(std::__to_address(__first.__seg_), __bits_per_word - __n, 0u, _FillVal);
+ }
+ }
+
+ template <class _Size, class _Tp>
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static __bit_iterator<_Cp, false>
+ operator()(__bit_iterator<_Cp, false> __first, _Size __n, const _Tp& __value) {
+ if (__n > 0) {
+ if (__value)
+ __impl<true>(__first, __n);
+ else
+ __impl<false>(__first, __n);
+ }
+ return __first + __n;
+ }
};
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__charconv/from_chars_integral.h b/libcxx/include/__charconv/from_chars_integral.h
index c1f033b..903e892 100644
--- a/libcxx/include/__charconv/from_chars_integral.h
+++ b/libcxx/include/__charconv/from_chars_integral.h
@@ -18,8 +18,8 @@
#include <__memory/addressof.h>
#include <__system_error/errc.h>
#include <__type_traits/enable_if.h>
-#include <__type_traits/integral_constant.h>
#include <__type_traits/is_integral.h>
+#include <__type_traits/is_signed.h>
#include <__type_traits/is_unsigned.h>
#include <__type_traits/make_unsigned.h>
#include <limits>
diff --git a/libcxx/include/__charconv/to_chars_integral.h b/libcxx/include/__charconv/to_chars_integral.h
index f10cc35..6d42513 100644
--- a/libcxx/include/__charconv/to_chars_integral.h
+++ b/libcxx/include/__charconv/to_chars_integral.h
@@ -24,6 +24,7 @@
#include <__type_traits/integral_constant.h>
#include <__type_traits/is_integral.h>
#include <__type_traits/is_same.h>
+#include <__type_traits/is_signed.h>
#include <__type_traits/make_32_64_or_128_bit.h>
#include <__type_traits/make_unsigned.h>
#include <__utility/unreachable.h>
diff --git a/libcxx/include/__compare/is_eq.h b/libcxx/include/__compare/is_eq.h
index 9a82df1..ee4d11b 100644
--- a/libcxx/include/__compare/is_eq.h
+++ b/libcxx/include/__compare/is_eq.h
@@ -20,12 +20,12 @@ _LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER >= 20
-_LIBCPP_HIDE_FROM_ABI inline constexpr bool is_eq(partial_ordering __c) noexcept { return __c == 0; }
-_LIBCPP_HIDE_FROM_ABI inline constexpr bool is_neq(partial_ordering __c) noexcept { return __c != 0; }
-_LIBCPP_HIDE_FROM_ABI inline constexpr bool is_lt(partial_ordering __c) noexcept { return __c < 0; }
-_LIBCPP_HIDE_FROM_ABI inline constexpr bool is_lteq(partial_ordering __c) noexcept { return __c <= 0; }
-_LIBCPP_HIDE_FROM_ABI inline constexpr bool is_gt(partial_ordering __c) noexcept { return __c > 0; }
-_LIBCPP_HIDE_FROM_ABI inline constexpr bool is_gteq(partial_ordering __c) noexcept { return __c >= 0; }
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr bool is_eq(partial_ordering __c) noexcept { return __c == 0; }
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr bool is_neq(partial_ordering __c) noexcept { return __c != 0; }
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr bool is_lt(partial_ordering __c) noexcept { return __c < 0; }
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr bool is_lteq(partial_ordering __c) noexcept { return __c <= 0; }
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr bool is_gt(partial_ordering __c) noexcept { return __c > 0; }
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr bool is_gteq(partial_ordering __c) noexcept { return __c >= 0; }
#endif // _LIBCPP_STD_VER >= 20
diff --git a/libcxx/include/__condition_variable/condition_variable.h b/libcxx/include/__condition_variable/condition_variable.h
index 1e8edd5..b715193 100644
--- a/libcxx/include/__condition_variable/condition_variable.h
+++ b/libcxx/include/__condition_variable/condition_variable.h
@@ -170,7 +170,7 @@ public:
wait_for(unique_lock<mutex>& __lk, const chrono::duration<_Rep, _Period>& __d, _Predicate __pred);
typedef __libcpp_condvar_t* native_handle_type;
- _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() { return &__cv_; }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() { return &__cv_; }
private:
void
diff --git a/libcxx/include/__config b/libcxx/include/__config
index 357f77b..e758acf 100644
--- a/libcxx/include/__config
+++ b/libcxx/include/__config
@@ -14,6 +14,8 @@
#include <__configuration/abi.h>
#include <__configuration/availability.h>
#include <__configuration/compiler.h>
+#include <__configuration/experimental.h>
+#include <__configuration/hardening.h>
#include <__configuration/language.h>
#include <__configuration/platform.h>
@@ -38,195 +40,6 @@
# define _LIBCPP_FREESTANDING
# endif
-// NOLINTNEXTLINE(libcpp-cpp-version-check)
-# if __cplusplus < 201103L
-# define _LIBCPP_CXX03_LANG
-# endif
-
-# if __has_feature(experimental_library)
-# ifndef _LIBCPP_ENABLE_EXPERIMENTAL
-# define _LIBCPP_ENABLE_EXPERIMENTAL
-# endif
-# endif
-
-// Incomplete features get their own specific disabling flags. This makes it
-// easier to grep for target specific flags once the feature is complete.
-# if defined(_LIBCPP_ENABLE_EXPERIMENTAL) || defined(_LIBCPP_BUILDING_LIBRARY)
-# define _LIBCPP_HAS_EXPERIMENTAL_LIBRARY 1
-# else
-# define _LIBCPP_HAS_EXPERIMENTAL_LIBRARY 0
-# endif
-
-# define _LIBCPP_HAS_EXPERIMENTAL_PSTL _LIBCPP_HAS_EXPERIMENTAL_LIBRARY
-# define _LIBCPP_HAS_EXPERIMENTAL_TZDB _LIBCPP_HAS_EXPERIMENTAL_LIBRARY
-# define _LIBCPP_HAS_EXPERIMENTAL_SYNCSTREAM _LIBCPP_HAS_EXPERIMENTAL_LIBRARY
-# define _LIBCPP_HAS_EXPERIMENTAL_HARDENING_OBSERVE_SEMANTIC _LIBCPP_HAS_EXPERIMENTAL_LIBRARY
-
-// HARDENING {
-
-// TODO(LLVM 23): Remove this. We're making these an error to catch folks who might not have migrated.
-// Since hardening went through several changes (many of which impacted user-facing macros),
-// we're keeping these checks around for a bit longer than usual. Failure to properly configure
-// hardening results in checks being dropped silently, which is a pretty big deal.
-# if defined(_LIBCPP_ENABLE_ASSERTIONS)
-# error "_LIBCPP_ENABLE_ASSERTIONS has been removed, please use _LIBCPP_HARDENING_MODE=<mode> instead (see docs)"
-# endif
-# if defined(_LIBCPP_ENABLE_HARDENED_MODE)
-# error "_LIBCPP_ENABLE_HARDENED_MODE has been removed, please use _LIBCPP_HARDENING_MODE=<mode> instead (see docs)"
-# endif
-# if defined(_LIBCPP_ENABLE_SAFE_MODE)
-# error "_LIBCPP_ENABLE_SAFE_MODE has been removed, please use _LIBCPP_HARDENING_MODE=<mode> instead (see docs)"
-# endif
-# if defined(_LIBCPP_ENABLE_DEBUG_MODE)
-# error "_LIBCPP_ENABLE_DEBUG_MODE has been removed, please use _LIBCPP_HARDENING_MODE=<mode> instead (see docs)"
-# endif
-
-// The library provides the macro `_LIBCPP_HARDENING_MODE` which can be set to one of the following values:
-//
-// - `_LIBCPP_HARDENING_MODE_NONE`;
-// - `_LIBCPP_HARDENING_MODE_FAST`;
-// - `_LIBCPP_HARDENING_MODE_EXTENSIVE`;
-// - `_LIBCPP_HARDENING_MODE_DEBUG`.
-//
-// These values have the following effects:
-//
-// - `_LIBCPP_HARDENING_MODE_NONE` -- sets the hardening mode to "none" which disables all runtime hardening checks;
-//
-// - `_LIBCPP_HARDENING_MODE_FAST` -- sets that hardening mode to "fast". The fast mode enables security-critical checks
-// that can be done with relatively little runtime overhead in constant time;
-//
-// - `_LIBCPP_HARDENING_MODE_EXTENSIVE` -- sets the hardening mode to "extensive". The extensive mode is a superset of
-// the fast mode that additionally enables checks that are relatively cheap and prevent common types of logic errors
-// but are not necessarily security-critical;
-//
-// - `_LIBCPP_HARDENING_MODE_DEBUG` -- sets the hardening mode to "debug". The debug mode is a superset of the extensive
-// mode and enables all checks available in the library, including internal assertions. Checks that are part of the
-// debug mode can be very expensive and thus the debug mode is intended to be used for testing, not in production.
-
-// Inside the library, assertions are categorized so they can be cherry-picked based on the chosen hardening mode. These
-// macros are only for internal use -- users should only pick one of the high-level hardening modes described above.
-//
-// - `_LIBCPP_ASSERT_VALID_INPUT_RANGE` -- checks that ranges (whether expressed as an iterator pair, an iterator and
-// a sentinel, an iterator and a count, or a `std::range`) given as input to library functions are valid:
-// - the sentinel is reachable from the begin iterator;
-// - TODO(hardening): both iterators refer to the same container.
-//
-// - `_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS` -- checks that any attempts to access a container element, whether through
-// the container object or through an iterator, are valid and do not attempt to go out of bounds or otherwise access
-// a non-existent element. For iterator checks to work, bounded iterators must be enabled in the ABI. Types like
-// `optional` and `function` are considered one-element containers for the purposes of this check.
-//
-// - `_LIBCPP_ASSERT_NON_NULL` -- checks that the pointer being dereferenced is not null. On most modern platforms zero
-// address does not refer to an actual location in memory, so a null pointer dereference would not compromize the
-// memory security of a program (however, it is still undefined behavior that can result in strange errors due to
-// compiler optimizations).
-//
-// - `_LIBCPP_ASSERT_NON_OVERLAPPING_RANGES` -- for functions that take several ranges as arguments, checks that the
-// given ranges do not overlap.
-//
-// - `_LIBCPP_ASSERT_VALID_DEALLOCATION` -- checks that an attempt to deallocate memory is valid (e.g. the given object
-// was allocated by the given allocator). Violating this category typically results in a memory leak.
-//
-// - `_LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL` -- checks that a call to an external API doesn't fail in
-// an unexpected manner. This includes triggering documented cases of undefined behavior in an external library (like
-// attempting to unlock an unlocked mutex in pthreads). Any API external to the library falls under this category
-// (from system calls to compiler intrinsics). We generally don't expect these failures to compromize memory safety or
-// otherwise create an immediate security issue.
-//
-// - `_LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR` -- checks any operations that exchange nodes between containers to make sure
-// the containers have compatible allocators.
-//
-// - `_LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN` -- checks that the given argument is within the domain of valid arguments
-// for the function. Violating this typically produces an incorrect result (e.g. the clamp algorithm returns the
-// original value without clamping it due to incorrect functors) or puts an object into an invalid state (e.g.
-// a string view where only a subset of elements is possible to access). This category is for assertions violating
-// which doesn't cause any immediate issues in the library -- whatever the consequences are, they will happen in the
-// user code.
-//
-// - `_LIBCPP_ASSERT_PEDANTIC` -- checks prerequisites which are imposed by the Standard, but violating which happens to
-// be benign in our implementation.
-//
-// - `_LIBCPP_ASSERT_SEMANTIC_REQUIREMENT` -- checks that the given argument satisfies the semantic requirements imposed
-// by the Standard. Typically, there is no simple way to completely prove that a semantic requirement is satisfied;
-// thus, this would often be a heuristic check and it might be quite expensive.
-//
-// - `_LIBCPP_ASSERT_INTERNAL` -- checks that internal invariants of the library hold. These assertions don't depend on
-// user input.
-//
-// - `_LIBCPP_ASSERT_UNCATEGORIZED` -- for assertions that haven't been properly classified yet.
-
-// clang-format off
-# define _LIBCPP_HARDENING_MODE_NONE (1 << 1)
-# define _LIBCPP_HARDENING_MODE_FAST (1 << 2)
-# define _LIBCPP_HARDENING_MODE_EXTENSIVE (1 << 4) // Deliberately not ordered.
-# define _LIBCPP_HARDENING_MODE_DEBUG (1 << 3)
-// clang-format on
-
-# ifndef _LIBCPP_HARDENING_MODE
-
-# ifndef _LIBCPP_HARDENING_MODE_DEFAULT
-# error _LIBCPP_HARDENING_MODE_DEFAULT is not defined. This definition should be set at configuration time in the \
-`__config_site` header, please make sure your installation of libc++ is not broken.
-# endif
-
-# define _LIBCPP_HARDENING_MODE _LIBCPP_HARDENING_MODE_DEFAULT
-# endif
-
-# if _LIBCPP_HARDENING_MODE != _LIBCPP_HARDENING_MODE_NONE && \
- _LIBCPP_HARDENING_MODE != _LIBCPP_HARDENING_MODE_FAST && \
- _LIBCPP_HARDENING_MODE != _LIBCPP_HARDENING_MODE_EXTENSIVE && \
- _LIBCPP_HARDENING_MODE != _LIBCPP_HARDENING_MODE_DEBUG
-# error _LIBCPP_HARDENING_MODE must be set to one of the following values: \
-_LIBCPP_HARDENING_MODE_NONE, \
-_LIBCPP_HARDENING_MODE_FAST, \
-_LIBCPP_HARDENING_MODE_EXTENSIVE, \
-_LIBCPP_HARDENING_MODE_DEBUG
-# endif
-
-// Hardening assertion semantics generally mirror the evaluation semantics of C++26 Contracts:
-// - `ignore` evaluates the assertion but doesn't do anything if it fails (note that it differs from the Contracts
-// `ignore` semantic which wouldn't evaluate the assertion at all);
-// - `observe` logs an error (indicating, if possible, that the error is fatal) and continues execution;
-// - `quick-enforce` terminates the program as fast as possible (via trapping);
-// - `enforce` logs an error and then terminates the program.
-//
-// Notes:
-// - Continuing execution after a hardening check fails results in undefined behavior; the `observe` semantic is meant
-// to make adopting hardening easier but should not be used outside of this scenario;
-// - C++26 wording for Library Hardening precludes a conforming Hardened implementation from using the Contracts
-// `ignore` semantic when evaluating hardened preconditions in the Library. Libc++ allows using this semantic for
-// hardened preconditions, however, be aware that using `ignore` does not produce a conforming "Hardened"
-// implementation, unlike the other semantics above.
-// clang-format off
-# define _LIBCPP_ASSERTION_SEMANTIC_IGNORE (1 << 1)
-# define _LIBCPP_ASSERTION_SEMANTIC_OBSERVE (1 << 2)
-# define _LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE (1 << 3)
-# define _LIBCPP_ASSERTION_SEMANTIC_ENFORCE (1 << 4)
-// clang-format on
-
-// Allow users to define an arbitrary assertion semantic; otherwise, use the default mapping from modes to semantics.
-// The default is for production-capable modes to use `quick-enforce` (i.e., trap) and for the `debug` mode to use
-// `enforce` (i.e., log and abort).
-# ifndef _LIBCPP_ASSERTION_SEMANTIC
-
-# if _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG
-# define _LIBCPP_ASSERTION_SEMANTIC _LIBCPP_ASSERTION_SEMANTIC_ENFORCE
-# else
-# define _LIBCPP_ASSERTION_SEMANTIC _LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE
-# endif
-
-# else
-# if !_LIBCPP_HAS_EXPERIMENTAL_LIBRARY
-# error "Assertion semantics are an experimental feature."
-# endif
-# if defined(_LIBCPP_CXX03_LANG)
-# error "Assertion semantics are not available in the C++03 mode."
-# endif
-
-# endif // _LIBCPP_ASSERTION_SEMANTIC
-
-// } HARDENING
-
# define _LIBCPP_TOSTRING2(x) #x
# define _LIBCPP_TOSTRING(x) _LIBCPP_TOSTRING2(x)
@@ -339,7 +152,7 @@ _LIBCPP_HARDENING_MODE_DEBUG
# ifndef _LIBCPP_CXX03_LANG
-# define _LIBCPP_ALIGNOF(_Tp) alignof(_Tp)
+# define _LIBCPP_ALIGNOF(...) alignof(__VA_ARGS__)
# define _ALIGNAS_TYPE(x) alignas(x)
# define _ALIGNAS(x) alignas(x)
# define _NOEXCEPT noexcept
@@ -348,7 +161,7 @@ _LIBCPP_HARDENING_MODE_DEBUG
# else
-# define _LIBCPP_ALIGNOF(_Tp) _Alignof(_Tp)
+# define _LIBCPP_ALIGNOF(...) _Alignof(__VA_ARGS__)
# define _ALIGNAS_TYPE(x) __attribute__((__aligned__(_LIBCPP_ALIGNOF(x))))
# define _ALIGNAS(x) __attribute__((__aligned__(x)))
# define nullptr __nullptr
@@ -478,6 +291,16 @@ typedef __char32_t char32_t;
# define _LIBCPP_HARDENING_SIG n // "none"
# endif
+# if _LIBCPP_ASSERTION_SEMANTIC == _LIBCPP_ASSERTION_SEMANTIC_OBSERVE
+# define _LIBCPP_ASSERTION_SEMANTIC_SIG o
+# elif _LIBCPP_ASSERTION_SEMANTIC == _LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE
+# define _LIBCPP_ASSERTION_SEMANTIC_SIG q
+# elif _LIBCPP_ASSERTION_SEMANTIC == _LIBCPP_ASSERTION_SEMANTIC_ENFORCE
+# define _LIBCPP_ASSERTION_SEMANTIC_SIG e
+# else
+# define _LIBCPP_ASSERTION_SEMANTIC_SIG i // `ignore`
+# endif
+
# if !_LIBCPP_HAS_EXCEPTIONS
# define _LIBCPP_EXCEPTIONS_SIG n
# else
@@ -485,7 +308,9 @@ typedef __char32_t char32_t;
# endif
# define _LIBCPP_ODR_SIGNATURE \
- _LIBCPP_CONCAT(_LIBCPP_CONCAT(_LIBCPP_HARDENING_SIG, _LIBCPP_EXCEPTIONS_SIG), _LIBCPP_VERSION)
+ _LIBCPP_CONCAT( \
+ _LIBCPP_CONCAT(_LIBCPP_CONCAT(_LIBCPP_HARDENING_SIG, _LIBCPP_ASSERTION_SEMANTIC_SIG), _LIBCPP_EXCEPTIONS_SIG), \
+ _LIBCPP_VERSION)
// This macro marks a symbol as being hidden from libc++'s ABI. This is achieved
// on two levels:
@@ -670,27 +495,6 @@ typedef __char32_t char32_t;
# define _LIBCPP_HAS_ALIGNED_ALLOCATION 1
# endif
-// It is not yet possible to use aligned_alloc() on all Apple platforms since
-// 10.15 was the first version to ship an implementation of aligned_alloc().
-# if defined(__APPLE__)
-# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && \
- __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101500) || \
- (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && \
- __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 130000) || \
- (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && \
- __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 60000) || \
- (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 130000)
-# define _LIBCPP_HAS_C11_ALIGNED_ALLOC 0
-# else
-# define _LIBCPP_HAS_C11_ALIGNED_ALLOC 1
-# endif
-# elif defined(__ANDROID__) && __ANDROID_API__ < 28
-// Android only provides aligned_alloc when targeting API 28 or higher.
-# define _LIBCPP_HAS_C11_ALIGNED_ALLOC 0
-# else
-# define _LIBCPP_HAS_C11_ALIGNED_ALLOC 1
-# endif
-
# if defined(__APPLE__) || defined(__FreeBSD__)
# define _LIBCPP_WCTYPE_IS_MASK
# endif
@@ -721,6 +525,15 @@ typedef __char32_t char32_t;
# define _LIBCPP_DEPRECATED_(m)
# endif
+// FIXME: using `#warning` causes diagnostics from system headers which include deprecated headers. This can only be
+// enabled again once https://github.com/llvm/llvm-project/pull/168041 (or a similar feature) has landed, since that
+// allows suppression in system headers.
+# if defined(__DEPRECATED) && __DEPRECATED && !defined(_LIBCPP_DISABLE_DEPRECATION_WARNINGS) && 0
+# define _LIBCPP_DIAGNOSE_DEPRECATED_HEADERS 1
+# else
+# define _LIBCPP_DIAGNOSE_DEPRECATED_HEADERS 0
+# endif
+
# if !defined(_LIBCPP_CXX03_LANG)
# define _LIBCPP_DEPRECATED_IN_CXX11 _LIBCPP_DEPRECATED
# else
@@ -844,18 +657,10 @@ typedef __char32_t char32_t;
# endif // _LIBCPP_HAS_THREAD_API
# endif // _LIBCPP_HAS_THREADS
-# if _LIBCPP_HAS_THREAD_API_PTHREAD
-# if defined(__ANDROID__) && __ANDROID_API__ >= 30
-# define _LIBCPP_HAS_COND_CLOCKWAIT 1
-# elif defined(_LIBCPP_GLIBC_PREREQ)
-# if _LIBCPP_GLIBC_PREREQ(2, 30)
-# define _LIBCPP_HAS_COND_CLOCKWAIT 1
-# else
-# define _LIBCPP_HAS_COND_CLOCKWAIT 0
-# endif
-# else
-# define _LIBCPP_HAS_COND_CLOCKWAIT 0
-# endif
+# if !_LIBCPP_HAS_THREAD_API_PTHREAD
+# define _LIBCPP_HAS_COND_CLOCKWAIT 0
+# elif (defined(__ANDROID__) && __ANDROID_API__ >= 30) || _LIBCPP_GLIBC_PREREQ(2, 30)
+# define _LIBCPP_HAS_COND_CLOCKWAIT 1
# else
# define _LIBCPP_HAS_COND_CLOCKWAIT 0
# endif
@@ -1021,12 +826,8 @@ typedef __char32_t char32_t;
// the latter depends on internal GNU libc details that are not appropriate
// to depend on here, so any declarations present when __cpp_char8_t is not
// defined are ignored.
-# if defined(_LIBCPP_GLIBC_PREREQ)
-# if _LIBCPP_GLIBC_PREREQ(2, 36) && defined(__cpp_char8_t)
-# define _LIBCPP_HAS_C8RTOMB_MBRTOC8 1
-# else
-# define _LIBCPP_HAS_C8RTOMB_MBRTOC8 0
-# endif
+# if _LIBCPP_GLIBC_PREREQ(2, 36) && defined(__cpp_char8_t)
+# define _LIBCPP_HAS_C8RTOMB_MBRTOC8 1
# else
# define _LIBCPP_HAS_C8RTOMB_MBRTOC8 0
# endif
diff --git a/libcxx/include/__config_site.in b/libcxx/include/__config_site.in
index b68c0c8..b09ca807 100644
--- a/libcxx/include/__config_site.in
+++ b/libcxx/include/__config_site.in
@@ -40,6 +40,11 @@
// Hardening.
#cmakedefine _LIBCPP_HARDENING_MODE_DEFAULT @_LIBCPP_HARDENING_MODE_DEFAULT@
+#cmakedefine _LIBCPP_ASSERTION_SEMANTIC_DEFAULT @_LIBCPP_ASSERTION_SEMANTIC_DEFAULT@
+
+// C libraries
+#cmakedefine01 _LIBCPP_LIBC_PICOLIBC
+#cmakedefine01 _LIBCPP_LIBC_NEWLIB
// __USE_MINGW_ANSI_STDIO gets redefined on MinGW
#ifdef __clang__
diff --git a/libcxx/include/__configuration/abi.h b/libcxx/include/__configuration/abi.h
index 38b85c6..f30d0a5 100644
--- a/libcxx/include/__configuration/abi.h
+++ b/libcxx/include/__configuration/abi.h
@@ -63,6 +63,7 @@
// These flags are documented in ABIGuarantees.rst
# define _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
+# define _LIBCPP_ABI_ATOMIC_WAIT_NATIVE_BY_SIZE
# define _LIBCPP_ABI_DO_NOT_EXPORT_BASIC_STRING_COMMON
# define _LIBCPP_ABI_DO_NOT_EXPORT_VECTOR_BASE_COMMON
# define _LIBCPP_ABI_DO_NOT_EXPORT_TO_CHARS_BASE_10
diff --git a/libcxx/include/__configuration/availability.h b/libcxx/include/__configuration/availability.h
index 5433df8..a5bd266 100644
--- a/libcxx/include/__configuration/availability.h
+++ b/libcxx/include/__configuration/availability.h
@@ -17,55 +17,10 @@
# pragma GCC system_header
#endif
-// Libc++ is shipped by various vendors. In particular, it is used as a system
-// library on macOS, iOS and other Apple platforms. In order for users to be
-// able to compile a binary that is intended to be deployed to an older version
-// of a platform, Clang provides availability attributes [1]. These attributes
-// can be placed on declarations and are used to describe the life cycle of a
-// symbol in the library.
-//
-// The main goal is to ensure a compile-time error if a symbol that hasn't been
-// introduced in a previously released library is used in a program that targets
-// that previously released library. Normally, this would be a load-time error
-// when one tries to launch the program against the older library.
-//
-// For example, the filesystem library was introduced in the dylib in LLVM 9.
-// On Apple platforms, this corresponds to macOS 10.15. If a user compiles on
-// a macOS 10.15 host but targets macOS 10.13 with their program, the compiler
-// would normally not complain (because the required declarations are in the
-// headers), but the dynamic loader would fail to find the symbols when actually
-// trying to launch the program on macOS 10.13. To turn this into a compile-time
-// issue instead, declarations are annotated with when they were introduced, and
-// the compiler can produce a diagnostic if the program references something that
-// isn't available on the deployment target.
-//
-// This mechanism is general in nature, and any vendor can add their markup to
-// the library (see below). Whenever a new feature is added that requires support
-// in the shared library, two macros are added below to allow marking the feature
-// as unavailable:
-// 1. A macro named `_LIBCPP_AVAILABILITY_HAS_<feature>` which must be defined
-// to `_LIBCPP_INTRODUCED_IN_<version>` for the appropriate LLVM version.
-// 2. A macro named `_LIBCPP_AVAILABILITY_<feature>`, which must be defined to
-// `_LIBCPP_INTRODUCED_IN_<version>_MARKUP` for the appropriate LLVM version.
-//
-// When vendors decide to ship the feature as part of their shared library, they
-// can update the `_LIBCPP_INTRODUCED_IN_<version>` macro (and the markup counterpart)
-// based on the platform version they shipped that version of LLVM in. The library
-// will then use this markup to provide an optimal user experience on these platforms.
-//
-// Furthermore, many features in the standard library have corresponding
-// feature-test macros. The `_LIBCPP_AVAILABILITY_HAS_<feature>` macros
-// are checked by the corresponding feature-test macros generated by
-// generate_feature_test_macro_components.py to ensure that the library
-// doesn't announce a feature as being implemented if it is unavailable on
-// the deployment target.
-//
-// Note that this mechanism is disabled by default in the "upstream" libc++.
-// Availability annotations are only meaningful when shipping libc++ inside
-// a platform (i.e. as a system library), and so vendors that want them should
-// turn those annotations on at CMake configuration time.
-//
-// [1]: https://clang.llvm.org/docs/AttributeReference.html#availability
+// This file defines a framework that can be used by vendors to encode the version of an operating system that various
+// features of libc++ has been shipped in. This is primarily intended to allow safely deploying an executable built with
+// a new version of the library on a platform containing an older version of the built library.
+// Detailed documentation for this can be found at https://libcxx.llvm.org/VendorDocumentation.html#availability-markup
// Availability markup is disabled when building the library, or when a non-Clang
// compiler is used because only Clang supports the necessary attributes.
@@ -84,6 +39,9 @@
// in all versions of the library are available.
#if !_LIBCPP_HAS_VENDOR_AVAILABILITY_ANNOTATIONS
+# define _LIBCPP_INTRODUCED_IN_LLVM_22 1
+# define _LIBCPP_INTRODUCED_IN_LLVM_22_ATTRIBUTE /* nothing */
+
# define _LIBCPP_INTRODUCED_IN_LLVM_21 1
# define _LIBCPP_INTRODUCED_IN_LLVM_21_ATTRIBUTE /* nothing */
@@ -112,6 +70,11 @@
// clang-format off
+// LLVM 22
+// TODO: Fill this in
+# define _LIBCPP_INTRODUCED_IN_LLVM_22 0
+# define _LIBCPP_INTRODUCED_IN_LLVM_22_ATTRIBUTE __attribute__((unavailable))
+
// LLVM 21
// TODO: Fill this in
# define _LIBCPP_INTRODUCED_IN_LLVM_21 0
@@ -242,6 +205,13 @@
#endif
+// This controls the availability of new implementation of std::atomic's
+// wait, notify_one and notify_all. The new implementation uses
+// the native atomic wait/notify operations on platforms that support them
+// based on the size of the atomic type, instead of the type itself.
+#define _LIBCPP_AVAILABILITY_HAS_NEW_SYNC _LIBCPP_INTRODUCED_IN_LLVM_22
+#define _LIBCPP_AVAILABILITY_NEW_SYNC _LIBCPP_INTRODUCED_IN_LLVM_22_ATTRIBUTE
+
// Enable additional explicit instantiations of iostreams components. This
// reduces the number of weak definitions generated in programs that use
// iostreams by providing a single strong definition in the shared library.
diff --git a/libcxx/include/__configuration/experimental.h b/libcxx/include/__configuration/experimental.h
new file mode 100644
index 0000000..d14df3e
--- /dev/null
+++ b/libcxx/include/__configuration/experimental.h
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___CONFIGURATION_EXPERIMENTAL_H
+#define _LIBCPP___CONFIGURATION_EXPERIMENTAL_H
+
+#include <__config_site>
+
+#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
+# pragma GCC system_header
+#endif
+
+#if __has_feature(experimental_library)
+# ifndef _LIBCPP_ENABLE_EXPERIMENTAL
+# define _LIBCPP_ENABLE_EXPERIMENTAL
+# endif
+#endif
+
+// Incomplete features get their own specific disabling flags. This makes it
+// easier to grep for target specific flags once the feature is complete.
+#if defined(_LIBCPP_ENABLE_EXPERIMENTAL) || defined(_LIBCPP_BUILDING_LIBRARY)
+# define _LIBCPP_HAS_EXPERIMENTAL_LIBRARY 1
+#else
+# define _LIBCPP_HAS_EXPERIMENTAL_LIBRARY 0
+#endif
+
+#define _LIBCPP_HAS_EXPERIMENTAL_PSTL _LIBCPP_HAS_EXPERIMENTAL_LIBRARY
+#define _LIBCPP_HAS_EXPERIMENTAL_TZDB _LIBCPP_HAS_EXPERIMENTAL_LIBRARY
+#define _LIBCPP_HAS_EXPERIMENTAL_SYNCSTREAM _LIBCPP_HAS_EXPERIMENTAL_LIBRARY
+#define _LIBCPP_HAS_EXPERIMENTAL_HARDENING_OBSERVE_SEMANTIC _LIBCPP_HAS_EXPERIMENTAL_LIBRARY
+
+#endif // _LIBCPP___CONFIGURATION_EXPERIMENTAL_H
diff --git a/libcxx/include/__configuration/hardening.h b/libcxx/include/__configuration/hardening.h
new file mode 100644
index 0000000..5723f5a
--- /dev/null
+++ b/libcxx/include/__configuration/hardening.h
@@ -0,0 +1,215 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___CONFIGURATION_HARDENING_H
+#define _LIBCPP___CONFIGURATION_HARDENING_H
+
+#include <__config_site>
+#include <__configuration/experimental.h>
+#include <__configuration/language.h>
+
+#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
+# pragma GCC system_header
+#endif
+
+// TODO(LLVM 23): Remove this. We're making these an error to catch folks who might not have migrated.
+// Since hardening went through several changes (many of which impacted user-facing macros),
+// we're keeping these checks around for a bit longer than usual. Failure to properly configure
+// hardening results in checks being dropped silently, which is a pretty big deal.
+#if defined(_LIBCPP_ENABLE_ASSERTIONS)
+# error "_LIBCPP_ENABLE_ASSERTIONS has been removed, please use _LIBCPP_HARDENING_MODE=<mode> instead (see docs)"
+#endif
+#if defined(_LIBCPP_ENABLE_HARDENED_MODE)
+# error "_LIBCPP_ENABLE_HARDENED_MODE has been removed, please use _LIBCPP_HARDENING_MODE=<mode> instead (see docs)"
+#endif
+#if defined(_LIBCPP_ENABLE_SAFE_MODE)
+# error "_LIBCPP_ENABLE_SAFE_MODE has been removed, please use _LIBCPP_HARDENING_MODE=<mode> instead (see docs)"
+#endif
+#if defined(_LIBCPP_ENABLE_DEBUG_MODE)
+# error "_LIBCPP_ENABLE_DEBUG_MODE has been removed, please use _LIBCPP_HARDENING_MODE=<mode> instead (see docs)"
+#endif
+
+// The library provides the macro `_LIBCPP_HARDENING_MODE` which can be set to one of the following values:
+//
+// - `_LIBCPP_HARDENING_MODE_NONE`;
+// - `_LIBCPP_HARDENING_MODE_FAST`;
+// - `_LIBCPP_HARDENING_MODE_EXTENSIVE`;
+// - `_LIBCPP_HARDENING_MODE_DEBUG`.
+//
+// These values have the following effects:
+//
+// - `_LIBCPP_HARDENING_MODE_NONE` -- sets the hardening mode to "none" which disables all runtime hardening checks;
+//
+// - `_LIBCPP_HARDENING_MODE_FAST` -- sets that hardening mode to "fast". The fast mode enables security-critical checks
+// that can be done with relatively little runtime overhead in constant time;
+//
+// - `_LIBCPP_HARDENING_MODE_EXTENSIVE` -- sets the hardening mode to "extensive". The extensive mode is a superset of
+// the fast mode that additionally enables checks that are relatively cheap and prevent common types of logic errors
+// but are not necessarily security-critical;
+//
+// - `_LIBCPP_HARDENING_MODE_DEBUG` -- sets the hardening mode to "debug". The debug mode is a superset of the extensive
+// mode and enables all checks available in the library, including internal assertions. Checks that are part of the
+// debug mode can be very expensive and thus the debug mode is intended to be used for testing, not in production.
+
+// Inside the library, assertions are categorized so they can be cherry-picked based on the chosen hardening mode. These
+// macros are only for internal use -- users should only pick one of the high-level hardening modes described above.
+//
+// - `_LIBCPP_ASSERT_VALID_INPUT_RANGE` -- checks that ranges (whether expressed as an iterator pair, an iterator and
+// a sentinel, an iterator and a count, or a `std::range`) given as input to library functions are valid:
+// - the sentinel is reachable from the begin iterator;
+// - TODO(hardening): both iterators refer to the same container.
+//
+// - `_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS` -- checks that any attempts to access a container element, whether through
+// the container object or through an iterator, are valid and do not attempt to go out of bounds or otherwise access
+// a non-existent element. For iterator checks to work, bounded iterators must be enabled in the ABI. Types like
+// `optional` and `function` are considered one-element containers for the purposes of this check.
+//
+// - `_LIBCPP_ASSERT_NON_NULL` -- checks that the pointer being dereferenced is not null. On most modern platforms zero
+// address does not refer to an actual location in memory, so a null pointer dereference would not compromize the
+// memory security of a program (however, it is still undefined behavior that can result in strange errors due to
+// compiler optimizations).
+//
+// - `_LIBCPP_ASSERT_NON_OVERLAPPING_RANGES` -- for functions that take several ranges as arguments, checks that the
+// given ranges do not overlap.
+//
+// - `_LIBCPP_ASSERT_VALID_DEALLOCATION` -- checks that an attempt to deallocate memory is valid (e.g. the given object
+// was allocated by the given allocator). Violating this category typically results in a memory leak.
+//
+// - `_LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL` -- checks that a call to an external API doesn't fail in
+// an unexpected manner. This includes triggering documented cases of undefined behavior in an external library (like
+// attempting to unlock an unlocked mutex in pthreads). Any API external to the library falls under this category
+// (from system calls to compiler intrinsics). We generally don't expect these failures to compromize memory safety or
+// otherwise create an immediate security issue.
+//
+// - `_LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR` -- checks any operations that exchange nodes between containers to make sure
+// the containers have compatible allocators.
+//
+// - `_LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN` -- checks that the given argument is within the domain of valid arguments
+// for the function. Violating this typically produces an incorrect result (e.g. the clamp algorithm returns the
+// original value without clamping it due to incorrect functors) or puts an object into an invalid state (e.g.
+// a string view where only a subset of elements is possible to access). This category is for assertions violating
+// which doesn't cause any immediate issues in the library -- whatever the consequences are, they will happen in the
+// user code.
+//
+// - `_LIBCPP_ASSERT_PEDANTIC` -- checks prerequisites which are imposed by the Standard, but violating which happens to
+// be benign in our implementation.
+//
+// - `_LIBCPP_ASSERT_SEMANTIC_REQUIREMENT` -- checks that the given argument satisfies the semantic requirements imposed
+// by the Standard. Typically, there is no simple way to completely prove that a semantic requirement is satisfied;
+// thus, this would often be a heuristic check and it might be quite expensive.
+//
+// - `_LIBCPP_ASSERT_INTERNAL` -- checks that internal invariants of the library hold. These assertions don't depend on
+// user input.
+//
+// - `_LIBCPP_ASSERT_UNCATEGORIZED` -- for assertions that haven't been properly classified yet.
+
+// clang-format off
+# define _LIBCPP_HARDENING_MODE_NONE (1 << 1)
+# define _LIBCPP_HARDENING_MODE_FAST (1 << 2)
+# define _LIBCPP_HARDENING_MODE_EXTENSIVE (1 << 4) // Deliberately not ordered.
+# define _LIBCPP_HARDENING_MODE_DEBUG (1 << 3)
+// clang-format on
+
+#ifndef _LIBCPP_HARDENING_MODE
+
+# ifndef _LIBCPP_HARDENING_MODE_DEFAULT
+# error _LIBCPP_HARDENING_MODE_DEFAULT is not defined. This definition should be set at configuration time in the \
+`__config_site` header, please make sure your installation of libc++ is not broken.
+# endif
+
+# define _LIBCPP_HARDENING_MODE _LIBCPP_HARDENING_MODE_DEFAULT
+#endif
+
+#if _LIBCPP_HARDENING_MODE != _LIBCPP_HARDENING_MODE_NONE && _LIBCPP_HARDENING_MODE != _LIBCPP_HARDENING_MODE_FAST && \
+ _LIBCPP_HARDENING_MODE != _LIBCPP_HARDENING_MODE_EXTENSIVE && \
+ _LIBCPP_HARDENING_MODE != _LIBCPP_HARDENING_MODE_DEBUG
+# error _LIBCPP_HARDENING_MODE must be set to one of the following values: \
+_LIBCPP_HARDENING_MODE_NONE, \
+_LIBCPP_HARDENING_MODE_FAST, \
+_LIBCPP_HARDENING_MODE_EXTENSIVE, \
+_LIBCPP_HARDENING_MODE_DEBUG
+#endif
+
+// The library provides the macro `_LIBCPP_ASSERTION_SEMANTIC` for configuring the assertion semantic used by hardening;
+// it can be set to one of the following values:
+//
+// - `_LIBCPP_ASSERTION_SEMANTIC_IGNORE`;
+// - `_LIBCPP_ASSERTION_SEMANTIC_OBSERVE`;
+// - `_LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE`;
+// - `_LIBCPP_ASSERTION_SEMANTIC_ENFORCE`.
+//
+// libc++ assertion semantics generally mirror the evaluation semantics of C++26 Contracts:
+// - `ignore` evaluates the assertion but doesn't do anything if it fails (note that it differs from the Contracts
+// `ignore` semantic which wouldn't evaluate the assertion at all);
+// - `observe` logs an error (indicating, if possible, that the error is fatal) and continues execution;
+// - `quick-enforce` terminates the program as fast as possible (via trapping);
+// - `enforce` logs an error and then terminates the program.
+//
+// Additionally, a special `hardening-dependent` value selects the assertion semantic based on the hardening mode in
+// effect: the production-capable modes (`fast` and `extensive`) map to `quick_enforce` and the `debug` mode maps to
+// `enforce`. The `hardening-dependent` semantic cannot be selected explicitly, it is only used when no assertion
+// semantic is provided by the user _and_ the library's default semantic is configured to be dependent on hardening.
+//
+// Notes:
+// - Continuing execution after a hardening check fails results in undefined behavior; the `observe` semantic is meant
+// to make adopting hardening easier but should not be used outside of this scenario;
+// - C++26 wording for Library Hardening precludes a conforming Hardened implementation from using the Contracts
+// `ignore` semantic when evaluating hardened preconditions in the Library. Libc++ allows using this semantic for
+// hardened preconditions, however, be aware that using `ignore` does not produce a conforming "Hardened"
+// implementation, unlike the other semantics above.
+// clang-format off
+# define _LIBCPP_ASSERTION_SEMANTIC_HARDENING_DEPENDENT (1 << 1)
+# define _LIBCPP_ASSERTION_SEMANTIC_IGNORE (1 << 2)
+# define _LIBCPP_ASSERTION_SEMANTIC_OBSERVE (1 << 3)
+# define _LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE (1 << 4)
+# define _LIBCPP_ASSERTION_SEMANTIC_ENFORCE (1 << 5)
+// clang-format on
+
+// If the user attempts to configure the assertion semantic, check that it is allowed in the current environment.
+#if defined(_LIBCPP_ASSERTION_SEMANTIC)
+# if !_LIBCPP_HAS_EXPERIMENTAL_LIBRARY
+# error "Assertion semantics are an experimental feature."
+# endif
+# if defined(_LIBCPP_CXX03_LANG)
+# error "Assertion semantics are not available in the C++03 mode."
+# endif
+#endif // defined(_LIBCPP_ASSERTION_SEMANTIC)
+
+// User-provided semantic takes top priority -- don't override if set.
+#ifndef _LIBCPP_ASSERTION_SEMANTIC
+
+# ifndef _LIBCPP_ASSERTION_SEMANTIC_DEFAULT
+# error _LIBCPP_ASSERTION_SEMANTIC_DEFAULT is not defined. This definition should be set at configuration time in \
+the `__config_site` header, please make sure your installation of libc++ is not broken.
+# endif
+
+# if _LIBCPP_ASSERTION_SEMANTIC_DEFAULT != _LIBCPP_ASSERTION_SEMANTIC_HARDENING_DEPENDENT
+# define _LIBCPP_ASSERTION_SEMANTIC _LIBCPP_ASSERTION_SEMANTIC_DEFAULT
+# else
+# if _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG
+# define _LIBCPP_ASSERTION_SEMANTIC _LIBCPP_ASSERTION_SEMANTIC_ENFORCE
+# else
+# define _LIBCPP_ASSERTION_SEMANTIC _LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE
+# endif
+# endif // _LIBCPP_ASSERTION_SEMANTIC_DEFAULT != _LIBCPP_ASSERTION_SEMANTIC_HARDENING_DEPENDENT
+
+#endif // #ifndef _LIBCPP_ASSERTION_SEMANTIC
+
+// Finally, validate the selected semantic (in case the user tries setting it to an incorrect value):
+#if _LIBCPP_ASSERTION_SEMANTIC != _LIBCPP_ASSERTION_SEMANTIC_IGNORE && \
+ _LIBCPP_ASSERTION_SEMANTIC != _LIBCPP_ASSERTION_SEMANTIC_OBSERVE && \
+ _LIBCPP_ASSERTION_SEMANTIC != _LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE && \
+ _LIBCPP_ASSERTION_SEMANTIC != _LIBCPP_ASSERTION_SEMANTIC_ENFORCE
+# error _LIBCPP_ASSERTION_SEMANTIC must be set to one of the following values: \
+_LIBCPP_ASSERTION_SEMANTIC_IGNORE, \
+_LIBCPP_ASSERTION_SEMANTIC_OBSERVE, \
+_LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE, \
+_LIBCPP_ASSERTION_SEMANTIC_ENFORCE
+#endif
+
+#endif // _LIBCPP___CONFIGURATION_HARDENING_H
diff --git a/libcxx/include/__configuration/language.h b/libcxx/include/__configuration/language.h
index 9c224dfa..26e87f8 100644
--- a/libcxx/include/__configuration/language.h
+++ b/libcxx/include/__configuration/language.h
@@ -18,6 +18,9 @@
// NOLINTBEGIN(libcpp-cpp-version-check)
#ifdef __cplusplus
+# if __cplusplus < 201103L
+# define _LIBCPP_CXX03_LANG
+# endif
# if __cplusplus <= 201103L
# define _LIBCPP_STD_VER 11
# elif __cplusplus <= 201402L
diff --git a/libcxx/include/__configuration/platform.h b/libcxx/include/__configuration/platform.h
index f3c199d..644fe17 100644
--- a/libcxx/include/__configuration/platform.h
+++ b/libcxx/include/__configuration/platform.h
@@ -31,22 +31,15 @@
#endif
// Need to detect which libc we're using if we're on Linux.
-#if defined(__linux__) || defined(__AMDGPU__) || defined(__NVPTX__)
-# if __has_include(<features.h>)
-# include <features.h>
-# if defined(__GLIBC_PREREQ)
-# define _LIBCPP_GLIBC_PREREQ(a, b) __GLIBC_PREREQ(a, b)
-# else
-# define _LIBCPP_GLIBC_PREREQ(a, b) 0
-# endif // defined(__GLIBC_PREREQ)
-# endif
-#endif
-
-// This is required in order for _NEWLIB_VERSION to be defined in places where we use it.
-// TODO: We shouldn't be including arbitrarily-named headers from libc++ since this can break valid
-// user code. Move code paths that need _NEWLIB_VERSION to another customization mechanism.
-#if __has_include(<picolibc.h>)
-# include <picolibc.h>
+#if (defined(__linux__) || defined(__AMDGPU__) || defined(__NVPTX__)) && __has_include(<features.h>)
+# include <features.h>
+# if defined(__GLIBC_PREREQ)
+# define _LIBCPP_GLIBC_PREREQ(a, b) __GLIBC_PREREQ(a, b)
+# else
+# define _LIBCPP_GLIBC_PREREQ(a, b) 0
+# endif // defined(__GLIBC_PREREQ)
+#else
+# define _LIBCPP_GLIBC_PREREQ(a, b) 0
#endif
#ifndef __BYTE_ORDER__
diff --git a/libcxx/include/__coroutine/coroutine_handle.h b/libcxx/include/__coroutine/coroutine_handle.h
index b7add25..b26a650 100644
--- a/libcxx/include/__coroutine/coroutine_handle.h
+++ b/libcxx/include/__coroutine/coroutine_handle.h
@@ -44,9 +44,9 @@ public:
}
// [coroutine.handle.export.import], export/import
- _LIBCPP_HIDE_FROM_ABI constexpr void* address() const noexcept { return __handle_; }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr void* address() const noexcept { return __handle_; }
- _LIBCPP_HIDE_FROM_ABI static constexpr coroutine_handle from_address(void* __addr) noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr coroutine_handle from_address(void* __addr) noexcept {
coroutine_handle __tmp;
__tmp.__handle_ = __addr;
return __tmp;
@@ -55,7 +55,7 @@ public:
// [coroutine.handle.observers], observers
_LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const noexcept { return __handle_ != nullptr; }
- _LIBCPP_HIDE_FROM_ABI bool done() const {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool done() const {
_LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL(__is_suspended(), "done() can be called only on suspended coroutines");
return __builtin_coro_done(__handle_);
}
@@ -100,7 +100,7 @@ public:
_LIBCPP_HIDE_FROM_ABI constexpr coroutine_handle(nullptr_t) noexcept {}
- _LIBCPP_HIDE_FROM_ABI static coroutine_handle from_promise(_Promise& __promise) {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static coroutine_handle from_promise(_Promise& __promise) {
using _RawPromise = __remove_cv_t<_Promise>;
coroutine_handle __tmp;
__tmp.__handle_ =
@@ -114,9 +114,9 @@ public:
}
// [coroutine.handle.export.import], export/import
- _LIBCPP_HIDE_FROM_ABI constexpr void* address() const noexcept { return __handle_; }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr void* address() const noexcept { return __handle_; }
- _LIBCPP_HIDE_FROM_ABI static constexpr coroutine_handle from_address(void* __addr) noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr coroutine_handle from_address(void* __addr) noexcept {
coroutine_handle __tmp;
__tmp.__handle_ = __addr;
return __tmp;
@@ -130,7 +130,7 @@ public:
// [coroutine.handle.observers], observers
_LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const noexcept { return __handle_ != nullptr; }
- _LIBCPP_HIDE_FROM_ABI bool done() const {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool done() const {
_LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL(__is_suspended(), "done() can be called only on suspended coroutines");
return __builtin_coro_done(__handle_);
}
@@ -150,7 +150,7 @@ public:
}
// [coroutine.handle.promise], promise access
- _LIBCPP_HIDE_FROM_ABI _Promise& promise() const {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _Promise& promise() const {
return *static_cast<_Promise*>(__builtin_coro_promise(this->__handle_, alignof(_Promise), false));
}
@@ -165,7 +165,7 @@ private:
// [coroutine.handle.hash]
template <class _Tp>
struct hash<coroutine_handle<_Tp>> {
- _LIBCPP_HIDE_FROM_ABI size_t operator()(const coroutine_handle<_Tp>& __v) const noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI size_t operator()(const coroutine_handle<_Tp>& __v) const noexcept {
return hash<void*>()(__v.address());
}
};
diff --git a/libcxx/include/__coroutine/noop_coroutine_handle.h b/libcxx/include/__coroutine/noop_coroutine_handle.h
index 692398a..b9c54d3 100644
--- a/libcxx/include/__coroutine/noop_coroutine_handle.h
+++ b/libcxx/include/__coroutine/noop_coroutine_handle.h
@@ -35,7 +35,7 @@ public:
// [coroutine.handle.noop.observers], observers
_LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const noexcept { return true; }
- _LIBCPP_HIDE_FROM_ABI constexpr bool done() const noexcept { return false; }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool done() const noexcept { return false; }
// [coroutine.handle.noop.resumption], resumption
_LIBCPP_HIDE_FROM_ABI constexpr void operator()() const noexcept {}
@@ -43,13 +43,13 @@ public:
_LIBCPP_HIDE_FROM_ABI constexpr void destroy() const noexcept {}
// [coroutine.handle.noop.promise], promise access
- _LIBCPP_HIDE_FROM_ABI noop_coroutine_promise& promise() const noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI noop_coroutine_promise& promise() const noexcept {
return *static_cast<noop_coroutine_promise*>(
__builtin_coro_promise(this->__handle_, alignof(noop_coroutine_promise), false));
}
// [coroutine.handle.noop.address], address
- _LIBCPP_HIDE_FROM_ABI constexpr void* address() const noexcept { return __handle_; }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr void* address() const noexcept { return __handle_; }
private:
_LIBCPP_HIDE_FROM_ABI friend coroutine_handle<noop_coroutine_promise> noop_coroutine() noexcept;
@@ -86,7 +86,9 @@ inline noop_coroutine_handle::__noop_coroutine_frame_ty_ noop_coroutine_handle::
# endif
// [coroutine.noop.coroutine]
-inline _LIBCPP_HIDE_FROM_ABI noop_coroutine_handle noop_coroutine() noexcept { return noop_coroutine_handle(); }
+[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI noop_coroutine_handle noop_coroutine() noexcept {
+ return noop_coroutine_handle();
+}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__cxx03/__fwd/ios.h b/libcxx/include/__cxx03/__fwd/ios.h
index dc03e8c..3b33b25b 100644
--- a/libcxx/include/__cxx03/__fwd/ios.h
+++ b/libcxx/include/__cxx03/__fwd/ios.h
@@ -31,7 +31,7 @@ using wios = basic_ios<wchar_t>;
template <class _CharT, class _Traits>
class _LIBCPP_PREFERRED_NAME(ios) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wios)) basic_ios;
-#if defined(_NEWLIB_VERSION)
+#if _LIBCPP_LIBC_NEWLIB
// On newlib, off_t is 'long int'
using streamoff = long int; // for char_traits in <string>
#else
diff --git a/libcxx/include/__cxx03/__locale b/libcxx/include/__cxx03/__locale
index 70dd1e6..e9cbc1f 100644
--- a/libcxx/include/__cxx03/__locale
+++ b/libcxx/include/__cxx03/__locale
@@ -384,7 +384,7 @@ public:
static const mask xdigit = _ISXDIGIT;
static const mask blank = _ISBLANK;
static const mask __regex_word = 0x8000;
-#elif defined(_NEWLIB_VERSION)
+#elif _LIBCPP_LIBC_NEWLIB
// Same type as Newlib's _ctype_ array in newlib/libc/include/ctype.h.
typedef char mask;
// In case char is signed, static_cast is needed to avoid warning on
diff --git a/libcxx/include/__cxx03/__locale_dir/locale_base_api.h b/libcxx/include/__cxx03/__locale_dir/locale_base_api.h
index a20f095..3dbce82 100644
--- a/libcxx/include/__cxx03/__locale_dir/locale_base_api.h
+++ b/libcxx/include/__cxx03/__locale_dir/locale_base_api.h
@@ -17,7 +17,7 @@
# include <__cxx03/__locale_dir/locale_base_api/android.h>
#elif defined(__sun__)
# include <__cxx03/__locale_dir/locale_base_api/solaris.h>
-#elif defined(_NEWLIB_VERSION)
+#elif _LIBCPP_LIBC_NEWLIB
# include <__cxx03/__locale_dir/locale_base_api/newlib.h>
#elif defined(__OpenBSD__)
# include <__cxx03/__locale_dir/locale_base_api/openbsd.h>
diff --git a/libcxx/include/__cxx03/fstream b/libcxx/include/__cxx03/fstream
index 65c2c3e..124619c 100644
--- a/libcxx/include/__cxx03/fstream
+++ b/libcxx/include/__cxx03/fstream
@@ -210,7 +210,7 @@ typedef basic_fstream<wchar_t> wfstream;
_LIBCPP_PUSH_MACROS
#include <__cxx03/__undef_macros>
-#if defined(_LIBCPP_MSVCRT) || defined(_NEWLIB_VERSION)
+#if defined(_LIBCPP_MSVCRT) || _LIBCPP_LIBC_NEWLIB
# define _LIBCPP_HAS_NO_OFF_T_FUNCTIONS
#endif
diff --git a/libcxx/include/__cxx03/locale b/libcxx/include/__cxx03/locale
index 79cd50e..4771539 100644
--- a/libcxx/include/__cxx03/locale
+++ b/libcxx/include/__cxx03/locale
@@ -220,7 +220,7 @@ template <class charT> class messages_byname;
# if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
// Most unix variants have catopen. These are the specific ones that don't.
-# if !defined(__BIONIC__) && !defined(_NEWLIB_VERSION) && !defined(__EMSCRIPTEN__)
+# if !defined(__BIONIC__) && !_LIBCPP_LIBC_NEWLIB && !defined(__EMSCRIPTEN__)
# define _LIBCPP_HAS_CATOPEN 1
# include <nl_types.h>
# endif
diff --git a/libcxx/include/__cxx03/regex b/libcxx/include/__cxx03/regex
index b6a78f2..bbd6eee 100644
--- a/libcxx/include/__cxx03/regex
+++ b/libcxx/include/__cxx03/regex
@@ -984,7 +984,7 @@ public:
typedef _CharT char_type;
typedef basic_string<char_type> string_type;
typedef locale locale_type;
-#if defined(__BIONIC__) || defined(_NEWLIB_VERSION)
+#if defined(__BIONIC__) || _LIBCPP_LIBC_NEWLIB
// Originally bionic's ctype_base used its own ctype masks because the
// builtin ctype implementation wasn't in libc++ yet. Bionic's ctype mask
// was only 8 bits wide and already saturated, so it used a wider type here
@@ -993,9 +993,7 @@ public:
// implementation, but this was not updated to match. Since then Android has
// needed to maintain a stable libc++ ABI, and this can't be changed without
// an ABI break.
- // We also need this workaround for newlib since _NEWLIB_VERSION is not
- // defined yet inside __config, so we can't set the
- // _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE macro. Additionally, newlib is
+ // We also need this workaround for newlib since newlib is
// often used for space constrained environments, so it makes sense not to
// duplicate the ctype table.
typedef uint16_t char_class_type;
diff --git a/libcxx/include/__exception/exception.h b/libcxx/include/__exception/exception.h
index 161cc49..ddc34b0 100644
--- a/libcxx/include/__exception/exception.h
+++ b/libcxx/include/__exception/exception.h
@@ -54,7 +54,9 @@ public:
virtual ~exception() _NOEXCEPT {}
- virtual char const* what() const _NOEXCEPT { return __data_._What ? __data_._What : "Unknown exception"; }
+ [[__nodiscard__]] virtual char const* what() const _NOEXCEPT {
+ return __data_._What ? __data_._What : "Unknown exception";
+ }
private:
__std_exception_data __data_;
@@ -76,7 +78,7 @@ public:
_LIBCPP_HIDE_FROM_ABI exception& operator=(const exception&) _NOEXCEPT = default;
virtual ~exception() _NOEXCEPT;
- virtual const char* what() const _NOEXCEPT;
+ [[__nodiscard__]] virtual const char* what() const _NOEXCEPT;
};
class _LIBCPP_EXPORTED_FROM_ABI bad_exception : public exception {
@@ -85,7 +87,7 @@ public:
_LIBCPP_HIDE_FROM_ABI bad_exception(const bad_exception&) _NOEXCEPT = default;
_LIBCPP_HIDE_FROM_ABI bad_exception& operator=(const bad_exception&) _NOEXCEPT = default;
~bad_exception() _NOEXCEPT override;
- const char* what() const _NOEXCEPT override;
+ [[__nodiscard__]] const char* what() const _NOEXCEPT override;
};
#endif // !_LIBCPP_ABI_VCRUNTIME
diff --git a/libcxx/include/__exception/exception_ptr.h b/libcxx/include/__exception/exception_ptr.h
index aef036a..92ff5c7 100644
--- a/libcxx/include/__exception/exception_ptr.h
+++ b/libcxx/include/__exception/exception_ptr.h
@@ -75,9 +75,7 @@ class _LIBCPP_EXPORTED_FROM_ABI exception_ptr {
public:
// exception_ptr is basically a COW string so it is trivially relocatable.
- // It is also replaceable because assignment has normal value semantics.
using __trivially_relocatable _LIBCPP_NODEBUG = exception_ptr;
- using __replaceable _LIBCPP_NODEBUG = exception_ptr;
_LIBCPP_HIDE_FROM_ABI exception_ptr() _NOEXCEPT : __ptr_() {}
_LIBCPP_HIDE_FROM_ABI exception_ptr(nullptr_t) _NOEXCEPT : __ptr_() {}
diff --git a/libcxx/include/__exception/nested_exception.h b/libcxx/include/__exception/nested_exception.h
index dc3266a..dd84efb 100644
--- a/libcxx/include/__exception/nested_exception.h
+++ b/libcxx/include/__exception/nested_exception.h
@@ -40,7 +40,7 @@ public:
// access functions
[[__noreturn__]] void rethrow_nested() const;
- _LIBCPP_HIDE_FROM_ABI exception_ptr nested_ptr() const _NOEXCEPT { return __ptr_; }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI exception_ptr nested_ptr() const _NOEXCEPT { return __ptr_; }
};
template <class _Tp>
diff --git a/libcxx/include/__exception/operations.h b/libcxx/include/__exception/operations.h
index 29d5c69..2b93ad2 100644
--- a/libcxx/include/__exception/operations.h
+++ b/libcxx/include/__exception/operations.h
@@ -20,22 +20,22 @@ _LIBCPP_BEGIN_UNVERSIONED_NAMESPACE_STD
defined(_LIBCPP_BUILDING_LIBRARY)
using unexpected_handler = void (*)();
_LIBCPP_EXPORTED_FROM_ABI unexpected_handler set_unexpected(unexpected_handler) _NOEXCEPT;
-_LIBCPP_EXPORTED_FROM_ABI unexpected_handler get_unexpected() _NOEXCEPT;
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI unexpected_handler get_unexpected() _NOEXCEPT;
[[__noreturn__]] _LIBCPP_EXPORTED_FROM_ABI void unexpected();
#endif
using terminate_handler = void (*)();
_LIBCPP_EXPORTED_FROM_ABI terminate_handler set_terminate(terminate_handler) _NOEXCEPT;
-_LIBCPP_EXPORTED_FROM_ABI terminate_handler get_terminate() _NOEXCEPT;
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI terminate_handler get_terminate() _NOEXCEPT;
#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_UNCAUGHT_EXCEPTION)
-_LIBCPP_EXPORTED_FROM_ABI _LIBCPP_DEPRECATED_IN_CXX17 bool uncaught_exception() _NOEXCEPT;
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_DEPRECATED_IN_CXX17 bool uncaught_exception() _NOEXCEPT;
#endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_UNCAUGHT_EXCEPTION)
-_LIBCPP_EXPORTED_FROM_ABI int uncaught_exceptions() _NOEXCEPT;
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI int uncaught_exceptions() _NOEXCEPT;
class _LIBCPP_EXPORTED_FROM_ABI exception_ptr;
-_LIBCPP_EXPORTED_FROM_ABI exception_ptr current_exception() _NOEXCEPT;
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI exception_ptr current_exception() _NOEXCEPT;
[[__noreturn__]] _LIBCPP_EXPORTED_FROM_ABI void rethrow_exception(exception_ptr);
_LIBCPP_END_UNVERSIONED_NAMESPACE_STD
diff --git a/libcxx/include/__expected/expected.h b/libcxx/include/__expected/expected.h
index 8b3eeeb..be37e8a 100644
--- a/libcxx/include/__expected/expected.h
+++ b/libcxx/include/__expected/expected.h
@@ -30,7 +30,6 @@
#include <__type_traits/is_nothrow_assignable.h>
#include <__type_traits/is_nothrow_constructible.h>
#include <__type_traits/is_reference.h>
-#include <__type_traits/is_replaceable.h>
#include <__type_traits/is_same.h>
#include <__type_traits/is_swappable.h>
#include <__type_traits/is_trivially_constructible.h>
@@ -472,8 +471,6 @@ public:
__conditional_t<__libcpp_is_trivially_relocatable<_Tp>::value && __libcpp_is_trivially_relocatable<_Err>::value,
expected,
void>;
- using __replaceable _LIBCPP_NODEBUG =
- __conditional_t<__is_replaceable_v<_Tp> && __is_replaceable_v<_Err>, expected, void>;
template <class _Up>
using rebind = expected<_Up, error_type>;
diff --git a/libcxx/include/__filesystem/path.h b/libcxx/include/__filesystem/path.h
index b3f3243..990ab6f 100644
--- a/libcxx/include/__filesystem/path.h
+++ b/libcxx/include/__filesystem/path.h
@@ -324,6 +324,7 @@ struct _PathCVT<char> {
}
};
+# if _LIBCPP_HAS_LOCALIZATION
template <class _ECharT>
struct _PathExport {
typedef __narrow_to_utf8<sizeof(wchar_t) * __CHAR_BIT__> _Narrower;
@@ -364,7 +365,7 @@ struct _PathExport<char16_t> {
}
};
-# if _LIBCPP_HAS_CHAR8_T
+# if _LIBCPP_HAS_CHAR8_T
template <>
struct _PathExport<char8_t> {
typedef __narrow_to_utf8<sizeof(wchar_t) * __CHAR_BIT__> _Narrower;
@@ -374,8 +375,9 @@ struct _PathExport<char8_t> {
_Narrower()(back_inserter(__dest), __src.data(), __src.data() + __src.size());
}
};
-# endif // _LIBCPP_HAS_CHAR8_T
-# endif /* _LIBCPP_WIN32API */
+# endif // _LIBCPP_HAS_CHAR8_T
+# endif // _LIBCPP_HAS_LOCALIZATION
+# endif // _LIBCPP_WIN32API
class _LIBCPP_EXPORTED_FROM_ABI path {
template <class _SourceOrIter, class _Tp = path&>
diff --git a/libcxx/include/__filesystem/u8path.h b/libcxx/include/__filesystem/u8path.h
index 885372b..ebdd51b 100644
--- a/libcxx/include/__filesystem/u8path.h
+++ b/libcxx/include/__filesystem/u8path.h
@@ -24,28 +24,30 @@
_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
+# if !defined(_LIBCPP_WIN32API) || _LIBCPP_HAS_LOCALIZATION
template <class _InputIt, __enable_if_t<__is_pathable<_InputIt>::value, int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_WITH_CHAR8_T path u8path(_InputIt __f, _InputIt __l) {
static_assert(
-# if _LIBCPP_HAS_CHAR8_T
+# if _LIBCPP_HAS_CHAR8_T
is_same<typename __is_pathable<_InputIt>::__char_type, char8_t>::value ||
-# endif
+# endif
is_same<typename __is_pathable<_InputIt>::__char_type, char>::value,
"u8path(Iter, Iter) requires Iter have a value_type of type 'char'"
" or 'char8_t'");
-# if defined(_LIBCPP_WIN32API)
+# if defined(_LIBCPP_WIN32API)
string __tmp(__f, __l);
using _CVT = __widen_from_utf8<sizeof(wchar_t) * __CHAR_BIT__>;
std::wstring __w;
__w.reserve(__tmp.size());
_CVT()(back_inserter(__w), __tmp.data(), __tmp.data() + __tmp.size());
return path(__w);
-# else
+# else
return path(__f, __l);
-# endif /* !_LIBCPP_WIN32API */
+# endif // defined(_LIBCPP_WIN32API)
}
+# endif // !defined(_LIBCPP_WIN32API) || _LIBCPP_HAS_LOCALIZATION
-# if defined(_LIBCPP_WIN32API)
+# if defined(_LIBCPP_WIN32API) && _LIBCPP_HAS_LOCALIZATION
template <class _InputIt, __enable_if_t<__is_pathable<_InputIt>::value, int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_WITH_CHAR8_T path u8path(_InputIt __f, _NullSentinel) {
static_assert(
@@ -65,7 +67,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_WITH_CHAR8_T path u8path(_InputIt __f,
_CVT()(back_inserter(__w), __tmp.data(), __tmp.data() + __tmp.size());
return path(__w);
}
-# endif /* _LIBCPP_WIN32API */
+# endif // defined(_LIBCPP_WIN32API) && _LIBCPP_HAS_LOCALIZATION
template <class _Source, __enable_if_t<__is_pathable<_Source>::value, int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_WITH_CHAR8_T path u8path(const _Source& __s) {
diff --git a/libcxx/include/__flat_map/flat_map.h b/libcxx/include/__flat_map/flat_map.h
index 159e652..84b60cd 100644
--- a/libcxx/include/__flat_map/flat_map.h
+++ b/libcxx/include/__flat_map/flat_map.h
@@ -409,41 +409,45 @@ public:
}
// iterators
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator begin() noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator begin() noexcept {
return iterator(__containers_.keys.begin(), __containers_.values.begin());
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator begin() const noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator begin() const noexcept {
return const_iterator(__containers_.keys.begin(), __containers_.values.begin());
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator end() noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator end() noexcept {
return iterator(__containers_.keys.end(), __containers_.values.end());
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator end() const noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator end() const noexcept {
return const_iterator(__containers_.keys.end(), __containers_.values.end());
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 reverse_iterator rbegin() noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 reverse_iterator rbegin() noexcept {
return reverse_iterator(end());
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator rbegin() const noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator rbegin() const noexcept {
return const_reverse_iterator(end());
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 reverse_iterator rend() noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 reverse_iterator rend() noexcept {
return reverse_iterator(begin());
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator rend() const noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator rend() const noexcept {
return const_reverse_iterator(begin());
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator cbegin() const noexcept { return begin(); }
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator cend() const noexcept { return end(); }
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator crbegin() const noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator cbegin() const noexcept {
+ return begin();
+ }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator cend() const noexcept {
+ return end();
+ }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator crbegin() const noexcept {
return const_reverse_iterator(end());
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator crend() const noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator crend() const noexcept {
return const_reverse_iterator(begin());
}
@@ -452,22 +456,22 @@ public:
return __containers_.keys.empty();
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type size() const noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type size() const noexcept {
return __containers_.keys.size();
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type max_size() const noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type max_size() const noexcept {
return std::min<size_type>(__containers_.keys.max_size(), __containers_.values.max_size());
}
// [flat.map.access], element access
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 mapped_type& operator[](const key_type& __x)
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 mapped_type& operator[](const key_type& __x)
requires is_constructible_v<mapped_type>
{
return try_emplace(__x).first->second;
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 mapped_type& operator[](key_type&& __x)
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 mapped_type& operator[](key_type&& __x)
requires is_constructible_v<mapped_type>
{
return try_emplace(std::move(__x)).first->second;
@@ -476,11 +480,11 @@ public:
template <class _Kp>
requires(__is_compare_transparent && is_constructible_v<key_type, _Kp> && is_constructible_v<mapped_type> &&
!is_convertible_v<_Kp &&, const_iterator> && !is_convertible_v<_Kp &&, iterator>)
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 mapped_type& operator[](_Kp&& __x) {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 mapped_type& operator[](_Kp&& __x) {
return try_emplace(std::forward<_Kp>(__x)).first->second;
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 mapped_type& at(const key_type& __x) {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 mapped_type& at(const key_type& __x) {
auto __it = find(__x);
if (__it == end()) {
std::__throw_out_of_range("flat_map::at(const key_type&): Key does not exist");
@@ -488,7 +492,7 @@ public:
return __it->second;
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const mapped_type& at(const key_type& __x) const {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const mapped_type& at(const key_type& __x) const {
auto __it = find(__x);
if (__it == end()) {
std::__throw_out_of_range("flat_map::at(const key_type&) const: Key does not exist");
@@ -498,7 +502,7 @@ public:
template <class _Kp>
requires __is_compare_transparent
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 mapped_type& at(const _Kp& __x) {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 mapped_type& at(const _Kp& __x) {
auto __it = find(__x);
if (__it == end()) {
std::__throw_out_of_range("flat_map::at(const K&): Key does not exist");
@@ -508,7 +512,7 @@ public:
template <class _Kp>
requires __is_compare_transparent
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const mapped_type& at(const _Kp& __x) const {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const mapped_type& at(const _Kp& __x) const {
auto __it = find(__x);
if (__it == end()) {
std::__throw_out_of_range("flat_map::at(const K&) const: Key does not exist");
@@ -596,7 +600,7 @@ public:
insert(sorted_unique, __il.begin(), __il.end());
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 containers extract() && {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 containers extract() && {
auto __guard = std::__make_scope_guard([&]() noexcept { clear() /* noexcept */; });
auto __ret = std::move(__containers_);
return __ret;
@@ -753,116 +757,121 @@ public:
}
// observers
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 key_compare key_comp() const { return __compare_; }
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 value_compare value_comp() const {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 key_compare key_comp() const { return __compare_; }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 value_compare value_comp() const {
return value_compare(__compare_);
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const key_container_type& keys() const noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const key_container_type& keys() const noexcept {
return __containers_.keys;
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const mapped_container_type& values() const noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const mapped_container_type&
+ values() const noexcept {
return __containers_.values;
}
// map operations
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator find(const key_type& __x) {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator find(const key_type& __x) {
return __find_impl(*this, __x);
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator find(const key_type& __x) const {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator find(const key_type& __x) const {
return __find_impl(*this, __x);
}
template <class _Kp>
requires __is_compare_transparent
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator find(const _Kp& __x) {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator find(const _Kp& __x) {
return __find_impl(*this, __x);
}
template <class _Kp>
requires __is_compare_transparent
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator find(const _Kp& __x) const {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator find(const _Kp& __x) const {
return __find_impl(*this, __x);
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type count(const key_type& __x) const {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type count(const key_type& __x) const {
return contains(__x) ? 1 : 0;
}
template <class _Kp>
requires __is_compare_transparent
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type count(const _Kp& __x) const {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type count(const _Kp& __x) const {
return contains(__x) ? 1 : 0;
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool contains(const key_type& __x) const {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool contains(const key_type& __x) const {
return find(__x) != end();
}
template <class _Kp>
requires __is_compare_transparent
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool contains(const _Kp& __x) const {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool contains(const _Kp& __x) const {
return find(__x) != end();
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator lower_bound(const key_type& __x) {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator lower_bound(const key_type& __x) {
return __lower_bound<iterator>(*this, __x);
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator lower_bound(const key_type& __x) const {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator
+ lower_bound(const key_type& __x) const {
return __lower_bound<const_iterator>(*this, __x);
}
template <class _Kp>
requires __is_compare_transparent
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator lower_bound(const _Kp& __x) {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator lower_bound(const _Kp& __x) {
return __lower_bound<iterator>(*this, __x);
}
template <class _Kp>
requires __is_compare_transparent
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator lower_bound(const _Kp& __x) const {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator lower_bound(const _Kp& __x) const {
return __lower_bound<const_iterator>(*this, __x);
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator upper_bound(const key_type& __x) {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator upper_bound(const key_type& __x) {
return __upper_bound<iterator>(*this, __x);
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator upper_bound(const key_type& __x) const {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator
+ upper_bound(const key_type& __x) const {
return __upper_bound<const_iterator>(*this, __x);
}
template <class _Kp>
requires __is_compare_transparent
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator upper_bound(const _Kp& __x) {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator upper_bound(const _Kp& __x) {
return __upper_bound<iterator>(*this, __x);
}
template <class _Kp>
requires __is_compare_transparent
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator upper_bound(const _Kp& __x) const {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator upper_bound(const _Kp& __x) const {
return __upper_bound<const_iterator>(*this, __x);
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, iterator> equal_range(const key_type& __x) {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, iterator>
+ equal_range(const key_type& __x) {
return __equal_range_impl(*this, __x);
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<const_iterator, const_iterator>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<const_iterator, const_iterator>
equal_range(const key_type& __x) const {
return __equal_range_impl(*this, __x);
}
template <class _Kp>
requires __is_compare_transparent
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, iterator> equal_range(const _Kp& __x) {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, iterator>
+ equal_range(const _Kp& __x) {
return __equal_range_impl(*this, __x);
}
template <class _Kp>
requires __is_compare_transparent
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<const_iterator, const_iterator>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<const_iterator, const_iterator>
equal_range(const _Kp& __x) const {
return __equal_range_impl(*this, __x);
}
diff --git a/libcxx/include/__flat_map/utils.h b/libcxx/include/__flat_map/utils.h
index 3a05c71..4b07e38 100644
--- a/libcxx/include/__flat_map/utils.h
+++ b/libcxx/include/__flat_map/utils.h
@@ -16,6 +16,7 @@
#include <__utility/exception_guard.h>
#include <__utility/forward.h>
#include <__utility/move.h>
+#include <__vector/container_traits.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/libcxx/include/__flat_set/flat_set.h b/libcxx/include/__flat_set/flat_set.h
index 0c8fdb5..1be38f1 100644
--- a/libcxx/include/__flat_set/flat_set.h
+++ b/libcxx/include/__flat_set/flat_set.h
@@ -339,38 +339,42 @@ public:
}
// iterators
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator begin() noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator begin() noexcept {
return iterator(std::as_const(__keys_).begin());
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator begin() const noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator begin() const noexcept {
return const_iterator(__keys_.begin());
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator end() noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator end() noexcept {
return iterator(std::as_const(__keys_).end());
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator end() const noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator end() const noexcept {
return const_iterator(__keys_.end());
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 reverse_iterator rbegin() noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 reverse_iterator rbegin() noexcept {
return reverse_iterator(end());
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator rbegin() const noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator rbegin() const noexcept {
return const_reverse_iterator(end());
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 reverse_iterator rend() noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 reverse_iterator rend() noexcept {
return reverse_iterator(begin());
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator rend() const noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator rend() const noexcept {
return const_reverse_iterator(begin());
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator cbegin() const noexcept { return begin(); }
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator cend() const noexcept { return end(); }
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator crbegin() const noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator cbegin() const noexcept {
+ return begin();
+ }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator cend() const noexcept {
+ return end();
+ }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator crbegin() const noexcept {
return const_reverse_iterator(end());
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator crend() const noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator crend() const noexcept {
return const_reverse_iterator(begin());
}
@@ -379,9 +383,13 @@ public:
return __keys_.empty();
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type size() const noexcept { return __keys_.size(); }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type size() const noexcept {
+ return __keys_.size();
+ }
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type max_size() const noexcept { return __keys_.max_size(); }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type max_size() const noexcept {
+ return __keys_.max_size();
+ }
// [flat.set.modifiers], modifiers
template <class... _Args>
@@ -466,7 +474,7 @@ public:
insert(sorted_unique, __il.begin(), __il.end());
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 container_type extract() && {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 container_type extract() && {
auto __guard = std::__make_scope_guard([&]() noexcept { clear() /* noexcept */; });
auto __ret = std::move(__keys_);
return __ret;
@@ -528,111 +536,117 @@ public:
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void clear() noexcept { __keys_.clear(); }
// observers
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 key_compare key_comp() const { return __compare_; }
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 value_compare value_comp() const { return __compare_; }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 key_compare key_comp() const { return __compare_; }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 value_compare value_comp() const {
+ return __compare_;
+ }
// set operations
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator find(const key_type& __x) {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator find(const key_type& __x) {
return __find_impl(*this, __x);
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator find(const key_type& __x) const {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator find(const key_type& __x) const {
return __find_impl(*this, __x);
}
template <class _Kp>
requires __is_transparent_v<_Compare>
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator find(const _Kp& __x) {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator find(const _Kp& __x) {
return __find_impl(*this, __x);
}
template <class _Kp>
requires __is_transparent_v<_Compare>
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator find(const _Kp& __x) const {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator find(const _Kp& __x) const {
return __find_impl(*this, __x);
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type count(const key_type& __x) const {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type count(const key_type& __x) const {
return contains(__x) ? 1 : 0;
}
template <class _Kp>
requires __is_transparent_v<_Compare>
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type count(const _Kp& __x) const {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type count(const _Kp& __x) const {
return contains(__x) ? 1 : 0;
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool contains(const key_type& __x) const {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool contains(const key_type& __x) const {
return find(__x) != end();
}
template <class _Kp>
requires __is_transparent_v<_Compare>
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool contains(const _Kp& __x) const {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool contains(const _Kp& __x) const {
return find(__x) != end();
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator lower_bound(const key_type& __x) {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator lower_bound(const key_type& __x) {
const auto& __keys = __keys_;
return iterator(std::lower_bound(__keys.begin(), __keys.end(), __x, __compare_));
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator lower_bound(const key_type& __x) const {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator
+ lower_bound(const key_type& __x) const {
return const_iterator(std::lower_bound(__keys_.begin(), __keys_.end(), __x, __compare_));
}
template <class _Kp>
requires __is_transparent_v<_Compare>
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator lower_bound(const _Kp& __x) {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator lower_bound(const _Kp& __x) {
const auto& __keys = __keys_;
return iterator(std::lower_bound(__keys.begin(), __keys.end(), __x, __compare_));
}
template <class _Kp>
requires __is_transparent_v<_Compare>
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator lower_bound(const _Kp& __x) const {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator lower_bound(const _Kp& __x) const {
return const_iterator(std::lower_bound(__keys_.begin(), __keys_.end(), __x, __compare_));
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator upper_bound(const key_type& __x) {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator upper_bound(const key_type& __x) {
const auto& __keys = __keys_;
return iterator(std::upper_bound(__keys.begin(), __keys.end(), __x, __compare_));
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator upper_bound(const key_type& __x) const {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator
+ upper_bound(const key_type& __x) const {
return const_iterator(std::upper_bound(__keys_.begin(), __keys_.end(), __x, __compare_));
}
template <class _Kp>
requires __is_transparent_v<_Compare>
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator upper_bound(const _Kp& __x) {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator upper_bound(const _Kp& __x) {
const auto& __keys = __keys_;
return iterator(std::upper_bound(__keys.begin(), __keys.end(), __x, __compare_));
}
template <class _Kp>
requires __is_transparent_v<_Compare>
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator upper_bound(const _Kp& __x) const {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator upper_bound(const _Kp& __x) const {
return const_iterator(std::upper_bound(__keys_.begin(), __keys_.end(), __x, __compare_));
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, iterator> equal_range(const key_type& __x) {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, iterator>
+ equal_range(const key_type& __x) {
return __equal_range_impl(*this, __x);
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<const_iterator, const_iterator>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<const_iterator, const_iterator>
equal_range(const key_type& __x) const {
return __equal_range_impl(*this, __x);
}
template <class _Kp>
requires __is_transparent_v<_Compare>
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, iterator> equal_range(const _Kp& __x) {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, iterator>
+ equal_range(const _Kp& __x) {
return __equal_range_impl(*this, __x);
}
template <class _Kp>
requires __is_transparent_v<_Compare>
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<const_iterator, const_iterator>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<const_iterator, const_iterator>
equal_range(const _Kp& __x) const {
return __equal_range_impl(*this, __x);
}
diff --git a/libcxx/include/__functional/bind.h b/libcxx/include/__functional/bind.h
index def9e4c..cbe8660 100644
--- a/libcxx/include/__functional/bind.h
+++ b/libcxx/include/__functional/bind.h
@@ -81,16 +81,12 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp& __mu(reference_w
return __t.get();
}
-template <class _Ti, class... _Uj, size_t... _Indx>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __invoke_result_t<_Ti&, _Uj...>
-__mu_expand(_Ti& __ti, tuple<_Uj...>& __uj, __index_sequence<_Indx...>) {
- return __ti(std::forward<_Uj>(std::get<_Indx>(__uj))...);
-}
-
template <class _Ti, class... _Uj, __enable_if_t<is_bind_expression<_Ti>::value, int> = 0>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __invoke_result_t<_Ti&, _Uj...>
__mu(_Ti& __ti, tuple<_Uj...>& __uj) {
- return std::__mu_expand(__ti, __uj, __make_index_sequence<sizeof...(_Uj)>());
+ return [&]<size_t... _Indices>(__index_sequence<_Indices...>) -> __invoke_result_t<_Ti&, _Uj...> {
+ return __ti(std::forward<_Uj>(std::get<_Indices>(__uj))...);
+ }(__index_sequence_for<_Uj...>{});
}
template <bool _IsPh, class _Ti, class _Uj>
@@ -217,10 +213,7 @@ public:
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 typename __bind_return<_Fd, _Td, tuple<_Args&&...> >::type
operator()(_Args&&... __args) {
return std::__apply_functor(
- __f_,
- __bound_args_,
- __make_index_sequence<sizeof...(_BoundArgs)>(),
- tuple<_Args&&...>(std::forward<_Args>(__args)...));
+ __f_, __bound_args_, __index_sequence_for<_BoundArgs...>(), tuple<_Args&&...>(std::forward<_Args>(__args)...));
}
template <class... _Args>
@@ -228,10 +221,7 @@ public:
typename __bind_return<const _Fd, const _Td, tuple<_Args&&...> >::type
operator()(_Args&&... __args) const {
return std::__apply_functor(
- __f_,
- __bound_args_,
- __make_index_sequence<sizeof...(_BoundArgs)>(),
- tuple<_Args&&...>(std::forward<_Args>(__args)...));
+ __f_, __bound_args_, __index_sequence_for<_BoundArgs...>(), tuple<_Args&&...>(std::forward<_Args>(__args)...));
}
};
@@ -278,14 +268,14 @@ template <class _Rp, class _Fp, class... _BoundArgs>
struct is_bind_expression<__bind_r<_Rp, _Fp, _BoundArgs...> > : public true_type {};
template <class _Fp, class... _BoundArgs>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bind<_Fp, _BoundArgs...>
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bind<_Fp, _BoundArgs...>
bind(_Fp&& __f, _BoundArgs&&... __bound_args) {
typedef __bind<_Fp, _BoundArgs...> type;
return type(std::forward<_Fp>(__f), std::forward<_BoundArgs>(__bound_args)...);
}
template <class _Rp, class _Fp, class... _BoundArgs>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bind_r<_Rp, _Fp, _BoundArgs...>
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bind_r<_Rp, _Fp, _BoundArgs...>
bind(_Fp&& __f, _BoundArgs&&... __bound_args) {
typedef __bind_r<_Rp, _Fp, _BoundArgs...> type;
return type(std::forward<_Fp>(__f), std::forward<_BoundArgs>(__bound_args)...);
diff --git a/libcxx/include/__functional/bind_back.h b/libcxx/include/__functional/bind_back.h
index e44768d..4117714 100644
--- a/libcxx/include/__functional/bind_back.h
+++ b/libcxx/include/__functional/bind_back.h
@@ -64,7 +64,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr auto __bind_back(_Fn&& __f, _Args&&... __args) n
# if _LIBCPP_STD_VER >= 23
template <class _Fn, class... _Args>
-_LIBCPP_HIDE_FROM_ABI constexpr auto bind_back(_Fn&& __f, _Args&&... __args) {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto bind_back(_Fn&& __f, _Args&&... __args) {
static_assert(is_constructible_v<decay_t<_Fn>, _Fn>, "bind_back requires decay_t<F> to be constructible from F");
static_assert(is_move_constructible_v<decay_t<_Fn>>, "bind_back requires decay_t<F> to be move constructible");
static_assert((is_constructible_v<decay_t<_Args>, _Args> && ...),
diff --git a/libcxx/include/__functional/bind_front.h b/libcxx/include/__functional/bind_front.h
index 87ef3af..427accf 100644
--- a/libcxx/include/__functional/bind_front.h
+++ b/libcxx/include/__functional/bind_front.h
@@ -43,7 +43,7 @@ struct __bind_front_t : __perfect_forward<__bind_front_op, _Fn, _BoundArgs...> {
template <class _Fn, class... _Args>
requires is_constructible_v<decay_t<_Fn>, _Fn> && is_move_constructible_v<decay_t<_Fn>> &&
(is_constructible_v<decay_t<_Args>, _Args> && ...) && (is_move_constructible_v<decay_t<_Args>> && ...)
-_LIBCPP_HIDE_FROM_ABI constexpr auto bind_front(_Fn&& __f, _Args&&... __args) {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto bind_front(_Fn&& __f, _Args&&... __args) {
return __bind_front_t<decay_t<_Fn>, decay_t<_Args>...>(std::forward<_Fn>(__f), std::forward<_Args>(__args)...);
}
diff --git a/libcxx/include/__functional/function.h b/libcxx/include/__functional/function.h
index c768fd9..121417f 100644
--- a/libcxx/include/__functional/function.h
+++ b/libcxx/include/__functional/function.h
@@ -672,11 +672,11 @@ public:
# if _LIBCPP_HAS_RTTI
// function target access:
- _LIBCPP_HIDE_FROM_ABI const std::type_info& target_type() const _NOEXCEPT;
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const std::type_info& target_type() const _NOEXCEPT;
template <typename _Tp>
- _LIBCPP_HIDE_FROM_ABI _Tp* target() _NOEXCEPT;
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _Tp* target() _NOEXCEPT;
template <typename _Tp>
- _LIBCPP_HIDE_FROM_ABI const _Tp* target() const _NOEXCEPT;
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const _Tp* target() const _NOEXCEPT;
# endif // _LIBCPP_HAS_RTTI
};
diff --git a/libcxx/include/__functional/hash.h b/libcxx/include/__functional/hash.h
index f74f25f..d81ff1a 100644
--- a/libcxx/include/__functional/hash.h
+++ b/libcxx/include/__functional/hash.h
@@ -435,7 +435,7 @@ struct hash : public __hash_impl<_Tp> {};
template <>
struct hash<nullptr_t> : public __unary_function<nullptr_t, size_t> {
- _LIBCPP_HIDE_FROM_ABI size_t operator()(nullptr_t) const _NOEXCEPT { return 662607004ull; }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t operator()(nullptr_t) const _NOEXCEPT { return 662607004ull; }
};
#ifndef _LIBCPP_CXX03_LANG
diff --git a/libcxx/include/__functional/mem_fn.h b/libcxx/include/__functional/mem_fn.h
index 6903939..1c9340c 100644
--- a/libcxx/include/__functional/mem_fn.h
+++ b/libcxx/include/__functional/mem_fn.h
@@ -43,7 +43,8 @@ public:
};
template <class _Rp, class _Tp>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __mem_fn<_Rp _Tp::*> mem_fn(_Rp _Tp::*__pm) _NOEXCEPT {
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __mem_fn<_Rp _Tp::*>
+mem_fn(_Rp _Tp::* __pm) _NOEXCEPT {
return __mem_fn<_Rp _Tp::*>(__pm);
}
diff --git a/libcxx/include/__functional/reference_wrapper.h b/libcxx/include/__functional/reference_wrapper.h
index 148703b..b1efd9f 100644
--- a/libcxx/include/__functional/reference_wrapper.h
+++ b/libcxx/include/__functional/reference_wrapper.h
@@ -58,7 +58,7 @@ public:
// access
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 operator type&() const _NOEXCEPT { return *__f_; }
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 type& get() const _NOEXCEPT { return *__f_; }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 type& get() const _NOEXCEPT { return *__f_; }
// invoke
template <class... _ArgTypes>
@@ -128,23 +128,25 @@ reference_wrapper(_Tp&) -> reference_wrapper<_Tp>;
#endif
template <class _Tp>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper<_Tp> ref(_Tp& __t) _NOEXCEPT {
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI
+_LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper<_Tp> ref(_Tp& __t) _NOEXCEPT {
return reference_wrapper<_Tp>(__t);
}
template <class _Tp>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper<_Tp>
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper<_Tp>
ref(reference_wrapper<_Tp> __t) _NOEXCEPT {
return __t;
}
template <class _Tp>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper<const _Tp> cref(const _Tp& __t) _NOEXCEPT {
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper<const _Tp>
+cref(const _Tp& __t) _NOEXCEPT {
return reference_wrapper<const _Tp>(__t);
}
template <class _Tp>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper<const _Tp>
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper<const _Tp>
cref(reference_wrapper<_Tp> __t) _NOEXCEPT {
return __t;
}
diff --git a/libcxx/include/__functional/weak_result_type.h b/libcxx/include/__functional/weak_result_type.h
index aa462e4..4232bdc 100644
--- a/libcxx/include/__functional/weak_result_type.h
+++ b/libcxx/include/__functional/weak_result_type.h
@@ -13,9 +13,9 @@
#include <__config>
#include <__functional/binary_function.h>
#include <__functional/unary_function.h>
-#include <__type_traits/integral_constant.h>
#include <__type_traits/invoke.h>
#include <__type_traits/is_same.h>
+#include <__type_traits/void_t.h>
#include <__utility/declval.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -24,50 +24,36 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-template <class _Tp>
-struct __has_result_type {
-private:
- template <class _Up>
- static false_type __test(...);
- template <class _Up>
- static true_type __test(typename _Up::result_type* = 0);
+template <class _Tp, class = void>
+inline const bool __has_result_type_v = false;
-public:
- static const bool value = decltype(__test<_Tp>(0))::value;
-};
+template <class _Tp>
+inline const bool __has_result_type_v<_Tp, __void_t<typename _Tp::result_type*> > = true;
// __weak_result_type
template <class _Tp>
struct __derives_from_unary_function {
private:
- struct __two {
- char __lx;
- char __lxx;
- };
- static __two __test(...);
+ static void __find_base(...);
template <class _Ap, class _Rp>
- static __unary_function<_Ap, _Rp> __test(const volatile __unary_function<_Ap, _Rp>*);
+ static __unary_function<_Ap, _Rp> __find_base(const volatile __unary_function<_Ap, _Rp>*);
public:
- static const bool value = !is_same<decltype(__test((_Tp*)0)), __two>::value;
- typedef decltype(__test((_Tp*)0)) type;
+ using type = decltype(__find_base(static_cast<_Tp*>(nullptr)));
+ static const bool value = !is_same<type, void>::value;
};
template <class _Tp>
struct __derives_from_binary_function {
private:
- struct __two {
- char __lx;
- char __lxx;
- };
- static __two __test(...);
+ static void __find_base(...);
template <class _A1, class _A2, class _Rp>
- static __binary_function<_A1, _A2, _Rp> __test(const volatile __binary_function<_A1, _A2, _Rp>*);
+ static __binary_function<_A1, _A2, _Rp> __find_base(const volatile __binary_function<_A1, _A2, _Rp>*);
public:
- static const bool value = !is_same<decltype(__test((_Tp*)0)), __two>::value;
- typedef decltype(__test((_Tp*)0)) type;
+ using type = decltype(__find_base(static_cast<_Tp*>(nullptr)));
+ static const bool value = !is_same<type, void>::value;
};
template <class _Tp, bool = __derives_from_unary_function<_Tp>::value>
@@ -85,7 +71,7 @@ struct __maybe_derive_from_binary_function // bool is true
template <class _Tp>
struct __maybe_derive_from_binary_function<_Tp, false> {};
-template <class _Tp, bool = __has_result_type<_Tp>::value>
+template <class _Tp, bool = __has_result_type_v<_Tp> >
struct __weak_result_type_imp // bool is true
: public __maybe_derive_from_unary_function<_Tp>,
public __maybe_derive_from_binary_function<_Tp> {
diff --git a/libcxx/include/__fwd/ios.h b/libcxx/include/__fwd/ios.h
index 831624f..fd6738a 100644
--- a/libcxx/include/__fwd/ios.h
+++ b/libcxx/include/__fwd/ios.h
@@ -31,7 +31,7 @@ using wios = basic_ios<wchar_t>;
template <class _CharT, class _Traits>
class _LIBCPP_PREFERRED_NAME(ios) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wios)) basic_ios;
-#if defined(_NEWLIB_VERSION)
+#if _LIBCPP_LIBC_NEWLIB
// On newlib, off_t is 'long int'
using streamoff = long int; // for char_traits in <string>
#else
diff --git a/libcxx/include/__hash_table b/libcxx/include/__hash_table
index e189794..ef487fb 100644
--- a/libcxx/include/__hash_table
+++ b/libcxx/include/__hash_table
@@ -1910,6 +1910,8 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::erase(const_iterator __first, const_it
__bucket_list_[__next_chash] = __before_first;
__chash = __next_chash;
}
+ } else { // When __next is a nullptr we've fully erased the last bucket. Update the bucket list accordingly.
+ __bucket_list_[__chash] = nullptr;
}
}
diff --git a/libcxx/include/__iterator/wrap_iter.h b/libcxx/include/__iterator/wrap_iter.h
index d18d968..98745f6 100644
--- a/libcxx/include/__iterator/wrap_iter.h
+++ b/libcxx/include/__iterator/wrap_iter.h
@@ -117,8 +117,8 @@ private:
friend class span;
template <class _Tp, size_t _Size>
friend struct array;
- template <class _Tp>
- friend class optional;
+ template <class _Tp, class>
+ friend struct __optional_iterator;
};
template <class _Iter1>
diff --git a/libcxx/include/__locale b/libcxx/include/__locale
index eb7b778..c2602af 100644
--- a/libcxx/include/__locale
+++ b/libcxx/include/__locale
@@ -57,9 +57,8 @@ _LIBCPP_HIDE_FROM_ABI const _Facet& use_facet(const locale&);
class _LIBCPP_EXPORTED_FROM_ABI locale {
public:
// locale is essentially a shared_ptr that doesn't support weak_ptrs and never got a move constructor,
- // so it is trivially relocatable. Like shared_ptr, it is also replaceable.
+ // so it is trivially relocatable.
using __trivially_relocatable _LIBCPP_NODEBUG = locale;
- using __replaceable _LIBCPP_NODEBUG = locale;
// types:
class _LIBCPP_EXPORTED_FROM_ABI facet;
@@ -389,7 +388,7 @@ public:
static const mask xdigit = _ISXDIGIT;
static const mask blank = _ISBLANK;
static const mask __regex_word = 0x8000;
-# elif defined(_NEWLIB_VERSION)
+# elif _LIBCPP_LIBC_NEWLIB
// Same type as Newlib's _ctype_ array in newlib/libc/include/ctype.h.
typedef char mask;
// In case char is signed, static_cast is needed to avoid warning on
diff --git a/libcxx/include/__locale_dir/locale_base_api.h b/libcxx/include/__locale_dir/locale_base_api.h
index 8c8f000..a5849df 100644
--- a/libcxx/include/__locale_dir/locale_base_api.h
+++ b/libcxx/include/__locale_dir/locale_base_api.h
@@ -57,15 +57,11 @@
// float __strtof(const char*, char**, __locale_t);
// double __strtod(const char*, char**, __locale_t);
// long double __strtold(const char*, char**, __locale_t);
-// long long __strtoll(const char*, char**, __locale_t);
-// unsigned long long __strtoull(const char*, char**, __locale_t);
// }
//
// Character manipulation functions
// --------------------------------
// namespace __locale {
-// int __isdigit(int, __locale_t); // required by the headers
-// int __isxdigit(int, __locale_t); // required by the headers
// int __toupper(int, __locale_t);
// int __tolower(int, __locale_t);
// int __strcoll(const char*, const char*, __locale_t);
@@ -106,7 +102,6 @@
//
// int __snprintf(char*, size_t, __locale_t, const char*, ...); // required by the headers
// int __asprintf(char**, __locale_t, const char*, ...); // required by the headers
-// int __sscanf(const char*, __locale_t, const char*, ...); // required by the headers
// }
#if _LIBCPP_HAS_LOCALIZATION
@@ -123,6 +118,8 @@
# include <__locale_dir/support/fuchsia.h>
# elif defined(__linux__)
# include <__locale_dir/support/linux.h>
+# elif _LIBCPP_LIBC_NEWLIB
+# include <__locale_dir/support/newlib.h>
# else
// TODO: This is a temporary definition to bridge between the old way we defined the locale base API
@@ -133,8 +130,6 @@
# include <__locale_dir/locale_base_api/ibm.h>
# elif defined(__OpenBSD__)
# include <__locale_dir/locale_base_api/openbsd.h>
-# elif defined(__wasi__) || _LIBCPP_HAS_MUSL_LIBC
-# include <__locale_dir/locale_base_api/musl.h>
# endif
# include <__locale_dir/locale_base_api/bsd_locale_fallbacks.h>
@@ -194,21 +189,9 @@ inline _LIBCPP_HIDE_FROM_ABI long double __strtold(const char* __nptr, char** __
return strtold_l(__nptr, __endptr, __loc);
}
-inline _LIBCPP_HIDE_FROM_ABI long long __strtoll(const char* __nptr, char** __endptr, int __base, __locale_t __loc) {
- return strtoll_l(__nptr, __endptr, __base, __loc);
-}
-
-inline _LIBCPP_HIDE_FROM_ABI unsigned long long
-__strtoull(const char* __nptr, char** __endptr, int __base, __locale_t __loc) {
- return strtoull_l(__nptr, __endptr, __base, __loc);
-}
-
//
// Character manipulation functions
//
-inline _LIBCPP_HIDE_FROM_ABI int __isdigit(int __ch, __locale_t __loc) { return isdigit_l(__ch, __loc); }
-inline _LIBCPP_HIDE_FROM_ABI int __isxdigit(int __ch, __locale_t __loc) { return isxdigit_l(__ch, __loc); }
-
# if defined(_LIBCPP_BUILDING_LIBRARY)
inline _LIBCPP_HIDE_FROM_ABI int __strcoll(const char* __s1, const char* __s2, __locale_t __loc) {
return strcoll_l(__s1, __s2, __loc);
@@ -304,11 +287,6 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT(__printf__, 3, 4) int __
char** __s, __locale_t __loc, const char* __format, _Args&&... __args) {
return std::__libcpp_asprintf_l(__s, __loc, __format, std::forward<_Args>(__args)...);
}
-template <class... _Args>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT(__scanf__, 3, 4) int __sscanf(
- const char* __s, __locale_t __loc, const char* __format, _Args&&... __args) {
- return std::__libcpp_sscanf_l(__s, __loc, __format, std::forward<_Args>(__args)...);
-}
_LIBCPP_DIAGNOSTIC_POP
# undef _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT
diff --git a/libcxx/include/__locale_dir/locale_base_api/bsd_locale_fallbacks.h b/libcxx/include/__locale_dir/locale_base_api/bsd_locale_fallbacks.h
index b62a1b7..8cdbe0c 100644
--- a/libcxx/include/__locale_dir/locale_base_api/bsd_locale_fallbacks.h
+++ b/libcxx/include/__locale_dir/locale_base_api/bsd_locale_fallbacks.h
@@ -125,16 +125,6 @@ inline _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 3, 4) int __libcpp_asprintf_l(
return __res;
}
-inline _LIBCPP_ATTRIBUTE_FORMAT(__scanf__, 3, 4) int __libcpp_sscanf_l(
- const char* __s, locale_t __l, const char* __format, ...) {
- va_list __va;
- va_start(__va, __format);
- __locale_guard __current(__l);
- int __res = vsscanf(__s, __format, __va);
- va_end(__va);
- return __res;
-}
-
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_BSD_LOCALE_FALLBACKS_H
diff --git a/libcxx/include/__locale_dir/locale_base_api/ibm.h b/libcxx/include/__locale_dir/locale_base_api/ibm.h
index 1d1d15d..47a83ea 100644
--- a/libcxx/include/__locale_dir/locale_base_api/ibm.h
+++ b/libcxx/include/__locale_dir/locale_base_api/ibm.h
@@ -53,11 +53,6 @@ private:
// The following are not POSIX routines. These are quick-and-dirty hacks
// to make things pretend to work
-inline _LIBCPP_HIDE_FROM_ABI long long strtoll_l(const char* __nptr, char** __endptr, int __base, locale_t locale) {
- __setAndRestore __newloc(locale);
- return ::strtoll(__nptr, __endptr, __base);
-}
-
inline _LIBCPP_HIDE_FROM_ABI double strtod_l(const char* __nptr, char** __endptr, locale_t locale) {
__setAndRestore __newloc(locale);
return ::strtod(__nptr, __endptr);
@@ -73,12 +68,6 @@ inline _LIBCPP_HIDE_FROM_ABI long double strtold_l(const char* __nptr, char** __
return ::strtold(__nptr, __endptr);
}
-inline _LIBCPP_HIDE_FROM_ABI unsigned long long
-strtoull_l(const char* __nptr, char** __endptr, int __base, locale_t locale) {
- __setAndRestore __newloc(locale);
- return ::strtoull(__nptr, __endptr, __base);
-}
-
inline _LIBCPP_HIDE_FROM_ABI
_LIBCPP_ATTRIBUTE_FORMAT(__printf__, 2, 0) int vasprintf(char** strp, const char* fmt, va_list ap) {
const size_t buff_size = 256;
diff --git a/libcxx/include/__locale_dir/locale_base_api/musl.h b/libcxx/include/__locale_dir/locale_base_api/musl.h
deleted file mode 100644
index 1653214..0000000
--- a/libcxx/include/__locale_dir/locale_base_api/musl.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// -*- C++ -*-
-//===-----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-// This adds support for the extended locale functions that are currently
-// missing from the Musl C library.
-//
-// This only works when the specified locale is "C" or "POSIX", but that's
-// about as good as we can do without implementing full xlocale support
-// in Musl.
-//===----------------------------------------------------------------------===//
-
-#ifndef _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_MUSL_H
-#define _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_MUSL_H
-
-#include <cstdlib>
-#include <cwchar>
-
-inline _LIBCPP_HIDE_FROM_ABI long long strtoll_l(const char* __nptr, char** __endptr, int __base, locale_t) {
- return ::strtoll(__nptr, __endptr, __base);
-}
-
-inline _LIBCPP_HIDE_FROM_ABI unsigned long long strtoull_l(const char* __nptr, char** __endptr, int __base, locale_t) {
- return ::strtoull(__nptr, __endptr, __base);
-}
-
-#endif // _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_MUSL_H
diff --git a/libcxx/include/__locale_dir/messages.h b/libcxx/include/__locale_dir/messages.h
index c04bf04..686f472 100644
--- a/libcxx/include/__locale_dir/messages.h
+++ b/libcxx/include/__locale_dir/messages.h
@@ -22,7 +22,7 @@
# if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
// Most unix variants have catopen. These are the specific ones that don't.
-# if !defined(__BIONIC__) && !defined(_NEWLIB_VERSION) && !defined(__EMSCRIPTEN__)
+# if !defined(__BIONIC__) && !_LIBCPP_LIBC_NEWLIB && !defined(__EMSCRIPTEN__)
# define _LIBCPP_HAS_CATOPEN 1
# include <nl_types.h>
# else
diff --git a/libcxx/include/__locale_dir/num.h b/libcxx/include/__locale_dir/num.h
index ff357cd..b7ea02e 100644
--- a/libcxx/include/__locale_dir/num.h
+++ b/libcxx/include/__locale_dir/num.h
@@ -12,6 +12,7 @@
#include <__algorithm/copy.h>
#include <__algorithm/find.h>
#include <__algorithm/reverse.h>
+#include <__algorithm/simd_utils.h>
#include <__charconv/to_chars_integral.h>
#include <__charconv/traits.h>
#include <__config>
@@ -23,6 +24,7 @@
#include <__locale_dir/scan_keyword.h>
#include <__memory/unique_ptr.h>
#include <__system_error/errc.h>
+#include <__type_traits/is_signed.h>
#include <cerrno>
#include <ios>
#include <streambuf>
@@ -47,9 +49,9 @@ struct _LIBCPP_EXPORTED_FROM_ABI __num_get_base {
static int __get_base(ios_base&);
static const char __src[33]; // "0123456789abcdefABCDEFxX+-pPiInN"
// count of leading characters in __src used for parsing integers ("012..X+-")
- static const size_t __int_chr_cnt = 26;
+ static inline const size_t __int_chr_cnt = 26;
// count of leading characters in __src used for parsing floating-point values ("012..-pP")
- static const size_t __fp_chr_cnt = 28;
+ static inline const size_t __fp_chr_cnt = 28;
};
template <class _CharT>
@@ -72,7 +74,8 @@ struct __num_get : protected __num_get_base {
[[__deprecated__("This exists only for ABI compatibility")]] static string
__stage2_int_prep(ios_base& __iob, _CharT* __atoms, _CharT& __thousands_sep);
- static int __stage2_int_loop(
+
+ [[__deprecated__("This exists only for ABI compatibility")]] static int __stage2_int_loop(
_CharT __ct,
int __base,
char* __a,
@@ -84,11 +87,24 @@ struct __num_get : protected __num_get_base {
unsigned*& __g_end,
_CharT* __atoms);
- _LIBCPP_HIDE_FROM_ABI static string __stage2_int_prep(ios_base& __iob, _CharT& __thousands_sep) {
- locale __loc = __iob.getloc();
- const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
- __thousands_sep = __np.thousands_sep();
- return __np.grouping();
+ _LIBCPP_HIDE_FROM_ABI static ptrdiff_t __atoms_offset(const _CharT* __atoms, _CharT __val) {
+ // TODO: Remove the manual vectorization once https://llvm.org/PR168551 is resolved
+# if _LIBCPP_HAS_ALGORITHM_VECTOR_UTILS
+ if constexpr (is_same<_CharT, char>::value) {
+ // TODO(LLVM 24): This can be removed, since -Wpsabi doesn't warn on [[gnu::always_inline]] functions anymore.
+ _LIBCPP_DIAGNOSTIC_PUSH
+ _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wpsabi")
+ using __vec = __simd_vector<char, 32>;
+ __vec __chars = std::__broadcast<__vec>(__val);
+ __vec __cmp = std::__partial_load<__vec, __int_chr_cnt>(__atoms);
+ auto __res = __chars == __cmp;
+ if (std::__none_of(__res))
+ return __int_chr_cnt;
+ return std::min(__int_chr_cnt, std::__find_first_set(__res));
+ _LIBCPP_DIAGNOSTIC_POP
+ }
+# endif
+ return std::find(__atoms, __atoms + __int_chr_cnt, __val) - __atoms;
}
_LIBCPP_HIDE_FROM_ABI const _CharT* __do_widen(ios_base& __iob, _CharT* __atoms) const {
@@ -122,54 +138,6 @@ string __num_get<_CharT>::__stage2_float_prep(
}
template <class _CharT>
-int __num_get<_CharT>::__stage2_int_loop(
- _CharT __ct,
- int __base,
- char* __a,
- char*& __a_end,
- unsigned& __dc,
- _CharT __thousands_sep,
- const string& __grouping,
- unsigned* __g,
- unsigned*& __g_end,
- _CharT* __atoms) {
- if (__a_end == __a && (__ct == __atoms[24] || __ct == __atoms[25])) {
- *__a_end++ = __ct == __atoms[24] ? '+' : '-';
- __dc = 0;
- return 0;
- }
- if (__grouping.size() != 0 && __ct == __thousands_sep) {
- if (__g_end - __g < __num_get_buf_sz) {
- *__g_end++ = __dc;
- __dc = 0;
- }
- return 0;
- }
- ptrdiff_t __f = std::find(__atoms, __atoms + __int_chr_cnt, __ct) - __atoms;
- if (__f >= 24)
- return -1;
- switch (__base) {
- case 8:
- case 10:
- if (__f >= __base)
- return -1;
- break;
- case 16:
- if (__f < 22)
- break;
- if (__a_end != __a && __a_end - __a <= 2 && __a_end[-1] == '0') {
- __dc = 0;
- *__a_end++ = __src[__f];
- return 0;
- }
- return -1;
- }
- *__a_end++ = __src[__f];
- ++__dc;
- return 0;
-}
-
-template <class _CharT>
int __num_get<_CharT>::__stage2_float_loop(
_CharT __ct,
bool& __in_units,
@@ -273,65 +241,6 @@ _LIBCPP_HIDE_FROM_ABI _Tp __num_get_float(const char* __a, const char* __a_end,
return 0;
}
-template <class _Tp>
-_LIBCPP_HIDE_FROM_ABI _Tp
-__num_get_signed_integral(const char* __a, const char* __a_end, ios_base::iostate& __err, int __base) {
- if (__a != __a_end) {
- __libcpp_remove_reference_t<decltype(errno)> __save_errno = errno;
- errno = 0;
- char* __p2;
- long long __ll = __locale::__strtoll(__a, &__p2, __base, _LIBCPP_GET_C_LOCALE);
- __libcpp_remove_reference_t<decltype(errno)> __current_errno = errno;
- if (__current_errno == 0)
- errno = __save_errno;
- if (__p2 != __a_end) {
- __err = ios_base::failbit;
- return 0;
- } else if (__current_errno == ERANGE || __ll < numeric_limits<_Tp>::min() || numeric_limits<_Tp>::max() < __ll) {
- __err = ios_base::failbit;
- if (__ll > 0)
- return numeric_limits<_Tp>::max();
- else
- return numeric_limits<_Tp>::min();
- }
- return static_cast<_Tp>(__ll);
- }
- __err = ios_base::failbit;
- return 0;
-}
-
-template <class _Tp>
-_LIBCPP_HIDE_FROM_ABI _Tp
-__num_get_unsigned_integral(const char* __a, const char* __a_end, ios_base::iostate& __err, int __base) {
- if (__a != __a_end) {
- const bool __negate = *__a == '-';
- if (__negate && ++__a == __a_end) {
- __err = ios_base::failbit;
- return 0;
- }
- __libcpp_remove_reference_t<decltype(errno)> __save_errno = errno;
- errno = 0;
- char* __p2;
- unsigned long long __ll = __locale::__strtoull(__a, &__p2, __base, _LIBCPP_GET_C_LOCALE);
- __libcpp_remove_reference_t<decltype(errno)> __current_errno = errno;
- if (__current_errno == 0)
- errno = __save_errno;
- if (__p2 != __a_end) {
- __err = ios_base::failbit;
- return 0;
- } else if (__current_errno == ERANGE || numeric_limits<_Tp>::max() < __ll) {
- __err = ios_base::failbit;
- return numeric_limits<_Tp>::max();
- }
- _Tp __res = static_cast<_Tp>(__ll);
- if (__negate)
- __res = -__res;
- return __res;
- }
- __err = ios_base::failbit;
- return 0;
-}
-
template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
class num_get : public locale::facet, private __num_get<_CharT> {
public:
@@ -469,137 +378,196 @@ protected:
return __b;
}
- template <class _Signed>
- _LIBCPP_HIDE_FROM_ABI iter_type
- __do_get_signed(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, _Signed& __v) const {
+ template <class _MaybeSigned>
+ iter_type __do_get_integral(
+ iter_type __first, iter_type __last, ios_base& __iob, ios_base::iostate& __err, _MaybeSigned& __v) const {
+ using _Unsigned = __make_unsigned_t<_MaybeSigned>;
+
// Stage 1
int __base = this->__get_base(__iob);
- // Stage 2
- char_type __thousands_sep;
- const int __atoms_size = __num_get_base::__int_chr_cnt;
- char_type __atoms1[__atoms_size];
- const char_type* __atoms = this->__do_widen(__iob, __atoms1);
- string __grouping = this->__stage2_int_prep(__iob, __thousands_sep);
- string __buf;
- __buf.resize(__buf.capacity());
- char* __a = &__buf[0];
- char* __a_end = __a;
+
+ // Stages 2 & 3
+ // These are combined into a single step where we parse the characters and calculate the value in one go instead of
+ // storing the relevant characters first (in an allocated buffer) and parse the characters after we extracted them.
+ // This makes the whole process significantly faster, since we avoid potential allocations and copies.
+
+ const auto& __numpunct = use_facet<numpunct<_CharT> >(__iob.getloc());
+ char_type __thousands_sep = __numpunct.thousands_sep();
+ string __grouping = __numpunct.grouping();
+
+ char_type __atoms_buffer[__num_get_base::__int_chr_cnt];
+ const char_type* __atoms = this->__do_widen(__iob, __atoms_buffer);
unsigned __g[__num_get_base::__num_get_buf_sz];
unsigned* __g_end = __g;
unsigned __dc = 0;
- for (; __b != __e; ++__b) {
- if (__a_end == __a + __buf.size()) {
- size_t __tmp = __buf.size();
- __buf.resize(2 * __buf.size());
- __buf.resize(__buf.capacity());
- __a = &__buf[0];
- __a_end = __a + __tmp;
+
+ if (__first == __last) {
+ __err |= ios_base::eofbit | ios_base::failbit;
+ __v = 0;
+ return __first;
+ }
+
+ while (!__grouping.empty() && *__first == __thousands_sep) {
+ ++__first;
+ if (__g_end - __g < this->__num_get_buf_sz)
+ *__g_end++ = 0;
+ }
+
+ bool __negate = false;
+ // __c == '+' || __c == '-'
+ if (auto __c = *__first; __c == __atoms[24] || __c == __atoms[25]) {
+ __negate = __c == __atoms[25];
+ ++__first;
+ }
+
+ if (__first == __last) {
+ __err |= ios_base::eofbit | ios_base::failbit;
+ __v = 0;
+ return __first;
+ }
+
+ bool __parsed_num = false;
+
+ // If we don't have a pre-set base, figure it out and swallow any prefix
+ if (__base == 0) {
+ auto __c = *__first;
+ // __c == '0'
+ if (__c == __atoms[0]) {
+ ++__first;
+ if (__first == __last) {
+ __err |= ios_base::eofbit;
+ __v = 0;
+ return __first;
+ }
+ // __c2 == 'x' || __c2 == 'X'
+ if (auto __c2 = *__first; __c2 == __atoms[22] || __c2 == __atoms[23]) {
+ __base = 16;
+ ++__first;
+ } else {
+ __base = 8;
+ __parsed_num = true; // We only swallowed '0', so we've started to parse a number
+ }
+ } else {
+ __base = 10;
+ }
+
+ // If the base has been specified explicitly, try to swallow the appropriate prefix. We only need to do something
+ // special for hex, since decimal has no prefix and octal's prefix is '0', which doesn't change the value that
+ // we'll parse if we don't swallow it.
+ } else if (__base == 16) {
+ // Try to swallow '0x'
+
+ // *__first == '0'
+ if (*__first == __atoms[0]) {
+ ++__first;
+ if (__first == __last) {
+ __err |= ios_base::eofbit;
+ __v = 0;
+ return __first;
+ }
+ // __c == 'x' || __c == 'X'
+ if (auto __c = *__first; __c == __atoms[22] || __c == __atoms[23])
+ ++__first;
+ else
+ __parsed_num = true; // We only swallowed '0', so we've started to parse a number
}
- if (this->__stage2_int_loop(
- *__b,
- __base,
- __a,
- __a_end,
- __dc,
- __thousands_sep,
- __grouping,
- __g,
- __g_end,
- const_cast<char_type*>(__atoms)))
- break;
}
- if (__grouping.size() != 0 && __g_end - __g < __num_get_base::__num_get_buf_sz)
- *__g_end++ = __dc;
- // Stage 3
- __v = std::__num_get_signed_integral<_Signed>(__a, __a_end, __err, __base);
- // Digit grouping checked
- __check_grouping(__grouping, __g, __g_end, __err);
- // EOF checked
- if (__b == __e)
- __err |= ios_base::eofbit;
- return __b;
- }
- template <class _Unsigned>
- _LIBCPP_HIDE_FROM_ABI iter_type
- __do_get_unsigned(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, _Unsigned& __v) const {
- // Stage 1
- int __base = this->__get_base(__iob);
- // Stage 2
- char_type __thousands_sep;
- const int __atoms_size = __num_get_base::__int_chr_cnt;
- char_type __atoms1[__atoms_size];
- const char_type* __atoms = this->__do_widen(__iob, __atoms1);
- string __grouping = this->__stage2_int_prep(__iob, __thousands_sep);
- string __buf;
- __buf.resize(__buf.capacity());
- char* __a = &__buf[0];
- char* __a_end = __a;
- unsigned __g[__num_get_base::__num_get_buf_sz];
- unsigned* __g_end = __g;
- unsigned __dc = 0;
- for (; __b != __e; ++__b) {
- if (__a_end == __a + __buf.size()) {
- size_t __tmp = __buf.size();
- __buf.resize(2 * __buf.size());
- __buf.resize(__buf.capacity());
- __a = &__buf[0];
- __a_end = __a + __tmp;
+ // Calculate the actual number
+ _Unsigned __val = 0;
+ bool __overflowed = false;
+ for (; __first != __last; ++__first) {
+ auto __c = *__first;
+ if (!__grouping.empty() && __c == __thousands_sep) {
+ if (__g_end - __g < this->__num_get_buf_sz) {
+ *__g_end++ = __dc;
+ __dc = 0;
+ }
+ continue;
}
- if (this->__stage2_int_loop(
- *__b,
- __base,
- __a,
- __a_end,
- __dc,
- __thousands_sep,
- __grouping,
- __g,
- __g_end,
- const_cast<char_type*>(__atoms)))
+ auto __offset = this->__atoms_offset(__atoms, __c);
+ if (__offset >= 22) // Not a valid integer character
break;
+
+ if (__base == 16 && __offset >= 16)
+ __offset -= 6;
+ if (__offset >= __base)
+ break;
+ // __val = (__val * __base) + __offset
+ __overflowed |= __builtin_mul_overflow(__val, __base, std::addressof(__val)) ||
+ __builtin_add_overflow(__val, __offset, std::addressof(__val));
+ __parsed_num = true;
+ ++__dc;
+ }
+
+ if (!__parsed_num) {
+ __err |= ios_base::failbit;
+ __v = 0;
+ } else if (__overflowed) {
+ __err |= ios_base::failbit;
+ __v = is_signed<_MaybeSigned>::value && __negate
+ ? numeric_limits<_MaybeSigned>::min()
+ : numeric_limits<_MaybeSigned>::max();
+ } else if (!__negate) {
+ if (__val > static_cast<_Unsigned>(numeric_limits<_MaybeSigned>::max())) {
+ __err |= ios_base::failbit;
+ __v = numeric_limits<_MaybeSigned>::max();
+ } else {
+ __v = __val;
+ }
+ } else if (is_signed<_MaybeSigned>::value) {
+ if (__val > static_cast<_Unsigned>(numeric_limits<_MaybeSigned>::max()) + 1) {
+ __err |= ios_base::failbit;
+ __v = numeric_limits<_MaybeSigned>::min();
+ } else if (__val == static_cast<_Unsigned>(numeric_limits<_MaybeSigned>::max()) + 1) {
+ __v = numeric_limits<_MaybeSigned>::min();
+ } else {
+ __v = -__val;
+ }
+ } else {
+ __v = -__val;
}
+
if (__grouping.size() != 0 && __g_end - __g < __num_get_base::__num_get_buf_sz)
*__g_end++ = __dc;
- // Stage 3
- __v = std::__num_get_unsigned_integral<_Unsigned>(__a, __a_end, __err, __base);
+
// Digit grouping checked
__check_grouping(__grouping, __g, __g_end, __err);
// EOF checked
- if (__b == __e)
+ if (__first == __last)
__err |= ios_base::eofbit;
- return __b;
+ return __first;
}
virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, bool& __v) const;
virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, long& __v) const {
- return this->__do_get_signed(__b, __e, __iob, __err, __v);
+ return this->__do_get_integral(__b, __e, __iob, __err, __v);
}
virtual iter_type
do_get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, long long& __v) const {
- return this->__do_get_signed(__b, __e, __iob, __err, __v);
+ return this->__do_get_integral(__b, __e, __iob, __err, __v);
}
virtual iter_type
do_get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, unsigned short& __v) const {
- return this->__do_get_unsigned(__b, __e, __iob, __err, __v);
+ return this->__do_get_integral(__b, __e, __iob, __err, __v);
}
virtual iter_type
do_get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, unsigned int& __v) const {
- return this->__do_get_unsigned(__b, __e, __iob, __err, __v);
+ return this->__do_get_integral(__b, __e, __iob, __err, __v);
}
virtual iter_type
do_get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, unsigned long& __v) const {
- return this->__do_get_unsigned(__b, __e, __iob, __err, __v);
+ return this->__do_get_integral(__b, __e, __iob, __err, __v);
}
virtual iter_type
do_get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, unsigned long long& __v) const {
- return this->__do_get_unsigned(__b, __e, __iob, __err, __v);
+ return this->__do_get_integral(__b, __e, __iob, __err, __v);
}
virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, float& __v) const {
@@ -653,40 +621,13 @@ _InputIterator num_get<_CharT, _InputIterator>::do_get(
template <class _CharT, class _InputIterator>
_InputIterator num_get<_CharT, _InputIterator>::do_get(
iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, void*& __v) const {
- // Stage 1
- int __base = 16;
- // Stage 2
- char_type __atoms[__num_get_base::__int_chr_cnt];
- char_type __thousands_sep = char_type();
- string __grouping;
- std::use_facet<ctype<_CharT> >(__iob.getloc())
- .widen(__num_get_base::__src, __num_get_base::__src + __num_get_base::__int_chr_cnt, __atoms);
- string __buf;
- __buf.resize(__buf.capacity());
- char* __a = &__buf[0];
- char* __a_end = __a;
- unsigned __g[__num_get_base::__num_get_buf_sz];
- unsigned* __g_end = __g;
- unsigned __dc = 0;
- for (; __b != __e; ++__b) {
- if (__a_end == __a + __buf.size()) {
- size_t __tmp = __buf.size();
- __buf.resize(2 * __buf.size());
- __buf.resize(__buf.capacity());
- __a = &__buf[0];
- __a_end = __a + __tmp;
- }
- if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc, __thousands_sep, __grouping, __g, __g_end, __atoms))
- break;
- }
- // Stage 3
- __buf.resize(__a_end - __a);
- if (__locale::__sscanf(__buf.c_str(), _LIBCPP_GET_C_LOCALE, "%p", &__v) != 1)
- __err = ios_base::failbit;
- // EOF checked
- if (__b == __e)
- __err |= ios_base::eofbit;
- return __b;
+ auto __flags = __iob.flags();
+ __iob.flags((__flags & ~ios_base::basefield & ~ios_base::uppercase) | ios_base::hex);
+ uintptr_t __ptr;
+ auto __res = __do_get_integral(__b, __e, __iob, __err, __ptr);
+ __iob.flags(__flags);
+ __v = reinterpret_cast<void*>(__ptr);
+ return __res;
}
extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS num_get<char>;
@@ -749,6 +690,13 @@ void __num_put<_CharT>::__widen_and_group_int(
__op = __ob + (__np - __nb);
}
+_LIBCPP_HIDE_FROM_ABI inline bool __isdigit(char __c) { return __c >= '0' && __c <= '9'; }
+
+_LIBCPP_HIDE_FROM_ABI inline bool __isxdigit(char __c) {
+ auto __lower = __c | 0x20;
+ return std::__isdigit(__c) || (__lower >= 'a' && __lower <= 'f');
+}
+
template <class _CharT>
void __num_put<_CharT>::__widen_and_group_float(
char* __nb, char* __np, char* __ne, _CharT* __ob, _CharT*& __op, _CharT*& __oe, const locale& __loc) {
@@ -764,11 +712,11 @@ void __num_put<_CharT>::__widen_and_group_float(
*__oe++ = __ct.widen(*__nf++);
*__oe++ = __ct.widen(*__nf++);
for (__ns = __nf; __ns < __ne; ++__ns)
- if (!__locale::__isxdigit(*__ns, _LIBCPP_GET_C_LOCALE))
+ if (!std::__isxdigit(*__ns))
break;
} else {
for (__ns = __nf; __ns < __ne; ++__ns)
- if (!__locale::__isdigit(*__ns, _LIBCPP_GET_C_LOCALE))
+ if (!std::__isdigit(*__ns))
break;
}
if (__grouping.empty()) {
diff --git a/libcxx/include/__locale_dir/support/bsd_like.h b/libcxx/include/__locale_dir/support/bsd_like.h
index 9d4bdd1..6f533b4e 100644
--- a/libcxx/include/__locale_dir/support/bsd_like.h
+++ b/libcxx/include/__locale_dir/support/bsd_like.h
@@ -79,22 +79,9 @@ inline _LIBCPP_HIDE_FROM_ABI long double __strtold(const char* __nptr, char** __
return ::strtold_l(__nptr, __endptr, __loc);
}
-inline _LIBCPP_HIDE_FROM_ABI long long __strtoll(const char* __nptr, char** __endptr, int __base, __locale_t __loc) {
- return ::strtoll_l(__nptr, __endptr, __base, __loc);
-}
-
-inline _LIBCPP_HIDE_FROM_ABI unsigned long long
-__strtoull(const char* __nptr, char** __endptr, int __base, __locale_t __loc) {
- return ::strtoull_l(__nptr, __endptr, __base, __loc);
-}
-
//
// Character manipulation functions
//
-inline _LIBCPP_HIDE_FROM_ABI int __isdigit(int __c, __locale_t __loc) { return ::isdigit_l(__c, __loc); }
-
-inline _LIBCPP_HIDE_FROM_ABI int __isxdigit(int __c, __locale_t __loc) { return ::isxdigit_l(__c, __loc); }
-
#if defined(_LIBCPP_BUILDING_LIBRARY)
inline _LIBCPP_HIDE_FROM_ABI int __toupper(int __c, __locale_t __loc) { return ::toupper_l(__c, __loc); }
@@ -215,12 +202,6 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT(__printf__, 3, 4) int __
char** __s, __locale_t __loc, const char* __format, _Args&&... __args) {
return ::asprintf_l(__s, __loc, __format, std::forward<_Args>(__args)...); // non-standard
}
-
-template <class... _Args>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT(__scanf__, 3, 4) int __sscanf(
- const char* __s, __locale_t __loc, const char* __format, _Args&&... __args) {
- return ::sscanf_l(__s, __loc, __format, std::forward<_Args>(__args)...);
-}
_LIBCPP_DIAGNOSTIC_POP
#undef _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT
diff --git a/libcxx/include/__locale_dir/support/fuchsia.h b/libcxx/include/__locale_dir/support/fuchsia.h
index 4b9e63f..528bfeb 100644
--- a/libcxx/include/__locale_dir/support/fuchsia.h
+++ b/libcxx/include/__locale_dir/support/fuchsia.h
@@ -141,13 +141,6 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT(__printf__, 3, 4) int __
__locale_guard __current(__loc);
return ::asprintf(__s, __format, std::forward<_Args>(__args)...); // non-standard
}
-template <class... _Args>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT(__scanf__, 3, 4) int __sscanf(
- const char* __s, __locale_t __loc, const char* __format, _Args&&... __args) {
- __locale_guard __current(__loc);
- return std::sscanf(__s, __format, std::forward<_Args>(__args)...);
-}
-
_LIBCPP_DIAGNOSTIC_POP
#undef _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT
diff --git a/libcxx/include/__locale_dir/support/linux.h b/libcxx/include/__locale_dir/support/linux.h
index 23bcf44..1a589be 100644
--- a/libcxx/include/__locale_dir/support/linux.h
+++ b/libcxx/include/__locale_dir/support/linux.h
@@ -94,32 +94,9 @@ inline _LIBCPP_HIDE_FROM_ABI long double __strtold(const char* __nptr, char** __
return ::strtold_l(__nptr, __endptr, __loc);
}
-inline _LIBCPP_HIDE_FROM_ABI long long __strtoll(const char* __nptr, char** __endptr, int __base, __locale_t __loc) {
-#if !_LIBCPP_HAS_MUSL_LIBC
- return ::strtoll_l(__nptr, __endptr, __base, __loc);
-#else
- (void)__loc;
- return ::strtoll(__nptr, __endptr, __base);
-#endif
-}
-
-inline _LIBCPP_HIDE_FROM_ABI unsigned long long
-__strtoull(const char* __nptr, char** __endptr, int __base, __locale_t __loc) {
-#if !_LIBCPP_HAS_MUSL_LIBC
- return ::strtoull_l(__nptr, __endptr, __base, __loc);
-#else
- (void)__loc;
- return ::strtoull(__nptr, __endptr, __base);
-#endif
-}
-
//
// Character manipulation functions
//
-inline _LIBCPP_HIDE_FROM_ABI int __isdigit(int __c, __locale_t __loc) { return isdigit_l(__c, __loc); }
-
-inline _LIBCPP_HIDE_FROM_ABI int __isxdigit(int __c, __locale_t __loc) { return isxdigit_l(__c, __loc); }
-
#if defined(_LIBCPP_BUILDING_LIBRARY)
inline _LIBCPP_HIDE_FROM_ABI int __toupper(int __c, __locale_t __loc) { return toupper_l(__c, __loc); }
@@ -261,20 +238,6 @@ inline _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 3, 4) int __asprintf(
va_end(__va);
return __res;
}
-
-#ifndef _LIBCPP_COMPILER_GCC // GCC complains that this can't be always_inline due to C-style varargs
-_LIBCPP_HIDE_FROM_ABI
-#endif
-inline _LIBCPP_ATTRIBUTE_FORMAT(__scanf__, 3, 4) int __sscanf(
- const char* __s, __locale_t __loc, const char* __format, ...) {
- va_list __va;
- va_start(__va, __format);
- __locale_guard __current(__loc);
- int __res = std::vsscanf(__s, __format, __va);
- va_end(__va);
- return __res;
-}
-
} // namespace __locale
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__locale_dir/support/newlib.h b/libcxx/include/__locale_dir/support/newlib.h
new file mode 100644
index 0000000..05c8a44
--- /dev/null
+++ b/libcxx/include/__locale_dir/support/newlib.h
@@ -0,0 +1,243 @@
+//===-----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___LOCALE_DIR_SUPPORT_NEWLIB_H
+#define _LIBCPP___LOCALE_DIR_SUPPORT_NEWLIB_H
+
+#include <__config>
+#include <__cstddef/size_t.h>
+#include <__std_mbstate_t.h>
+#include <clocale> // std::lconv
+#include <cstdio>
+#include <cstdlib>
+#include <ctype.h>
+#include <stdarg.h>
+#include <string.h>
+#include <time.h>
+#if _LIBCPP_HAS_WIDE_CHARACTERS
+# include <cwchar>
+# include <wctype.h>
+#endif
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+namespace __locale {
+
+struct __locale_guard {
+ _LIBCPP_HIDE_FROM_ABI __locale_guard(locale_t& __loc) : __old_loc_(::uselocale(__loc)) {}
+
+ _LIBCPP_HIDE_FROM_ABI ~__locale_guard() {
+ if (__old_loc_)
+ ::uselocale(__old_loc_);
+ }
+
+ locale_t __old_loc_;
+
+ __locale_guard(__locale_guard const&) = delete;
+ __locale_guard& operator=(__locale_guard const&) = delete;
+};
+
+//
+// Locale management
+//
+#define _LIBCPP_COLLATE_MASK LC_COLLATE_MASK
+#define _LIBCPP_CTYPE_MASK LC_CTYPE_MASK
+#define _LIBCPP_MONETARY_MASK LC_MONETARY_MASK
+#define _LIBCPP_NUMERIC_MASK LC_NUMERIC_MASK
+#define _LIBCPP_TIME_MASK LC_TIME_MASK
+#define _LIBCPP_MESSAGES_MASK LC_MESSAGES_MASK
+#define _LIBCPP_ALL_MASK LC_ALL_MASK
+#define _LIBCPP_LC_ALL LC_ALL
+
+using __locale_t _LIBCPP_NODEBUG = ::locale_t;
+
+#if defined(_LIBCPP_BUILDING_LIBRARY)
+using __lconv_t _LIBCPP_NODEBUG = std::lconv;
+
+inline _LIBCPP_HIDE_FROM_ABI __locale_t __newlocale(int __category_mask, const char* __locale, __locale_t __base) {
+ return ::newlocale(__category_mask, __locale, __base);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI void __freelocale(__locale_t __loc) { ::freelocale(__loc); }
+
+inline _LIBCPP_HIDE_FROM_ABI char* __setlocale(int __category, char const* __locale) {
+ return ::setlocale(__category, __locale);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI __lconv_t* __localeconv(__locale_t& __loc) {
+ __locale_guard __current(__loc);
+ return std::localeconv();
+}
+#endif // _LIBCPP_BUILDING_LIBRARY
+
+//
+// Strtonum functions
+//
+inline _LIBCPP_HIDE_FROM_ABI float __strtof(const char* __nptr, char** __endptr, __locale_t __loc) {
+ return ::strtof_l(__nptr, __endptr, __loc);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI double __strtod(const char* __nptr, char** __endptr, __locale_t __loc) {
+ return ::strtod_l(__nptr, __endptr, __loc);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI long double __strtold(const char* __nptr, char** __endptr, __locale_t __loc) {
+ return ::strtold_l(__nptr, __endptr, __loc);
+}
+
+//
+// Character manipulation functions
+//
+#if defined(_LIBCPP_BUILDING_LIBRARY)
+inline _LIBCPP_HIDE_FROM_ABI int __toupper(int __c, __locale_t __loc) { return toupper_l(__c, __loc); }
+
+inline _LIBCPP_HIDE_FROM_ABI int __tolower(int __c, __locale_t __loc) { return tolower_l(__c, __loc); }
+
+inline _LIBCPP_HIDE_FROM_ABI int __strcoll(const char* __s1, const char* __s2, __locale_t __loc) {
+ return strcoll_l(__s1, __s2, __loc);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI size_t __strxfrm(char* __dest, const char* __src, size_t __n, __locale_t __loc) {
+ return strxfrm_l(__dest, __src, __n, __loc);
+}
+
+# if _LIBCPP_HAS_WIDE_CHARACTERS
+inline _LIBCPP_HIDE_FROM_ABI int __iswctype(wint_t __c, wctype_t __type, __locale_t __loc) {
+ return iswctype_l(__c, __type, __loc);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI int __iswspace(wint_t __c, __locale_t __loc) { return iswspace_l(__c, __loc); }
+
+inline _LIBCPP_HIDE_FROM_ABI int __iswprint(wint_t __c, __locale_t __loc) { return iswprint_l(__c, __loc); }
+
+inline _LIBCPP_HIDE_FROM_ABI int __iswcntrl(wint_t __c, __locale_t __loc) { return iswcntrl_l(__c, __loc); }
+
+inline _LIBCPP_HIDE_FROM_ABI int __iswupper(wint_t __c, __locale_t __loc) { return iswupper_l(__c, __loc); }
+
+inline _LIBCPP_HIDE_FROM_ABI int __iswlower(wint_t __c, __locale_t __loc) { return iswlower_l(__c, __loc); }
+
+inline _LIBCPP_HIDE_FROM_ABI int __iswalpha(wint_t __c, __locale_t __loc) { return iswalpha_l(__c, __loc); }
+
+inline _LIBCPP_HIDE_FROM_ABI int __iswblank(wint_t __c, __locale_t __loc) { return iswblank_l(__c, __loc); }
+
+inline _LIBCPP_HIDE_FROM_ABI int __iswdigit(wint_t __c, __locale_t __loc) { return iswdigit_l(__c, __loc); }
+
+inline _LIBCPP_HIDE_FROM_ABI int __iswpunct(wint_t __c, __locale_t __loc) { return iswpunct_l(__c, __loc); }
+
+inline _LIBCPP_HIDE_FROM_ABI int __iswxdigit(wint_t __c, __locale_t __loc) { return iswxdigit_l(__c, __loc); }
+
+inline _LIBCPP_HIDE_FROM_ABI wint_t __towupper(wint_t __c, __locale_t __loc) { return towupper_l(__c, __loc); }
+
+inline _LIBCPP_HIDE_FROM_ABI wint_t __towlower(wint_t __c, __locale_t __loc) { return towlower_l(__c, __loc); }
+
+inline _LIBCPP_HIDE_FROM_ABI int __wcscoll(const wchar_t* __ws1, const wchar_t* __ws2, __locale_t __loc) {
+ return wcscoll_l(__ws1, __ws2, __loc);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI size_t __wcsxfrm(wchar_t* __dest, const wchar_t* __src, size_t __n, __locale_t __loc) {
+ return wcsxfrm_l(__dest, __src, __n, __loc);
+}
+# endif // _LIBCPP_HAS_WIDE_CHARACTERS
+
+inline _LIBCPP_HIDE_FROM_ABI
+size_t __strftime(char* __s, size_t __max, const char* __format, const struct tm* __tm, __locale_t __loc) {
+ return strftime_l(__s, __max, __format, __tm, __loc);
+}
+
+//
+// Other functions
+//
+inline _LIBCPP_HIDE_FROM_ABI decltype(MB_CUR_MAX) __mb_len_max(__locale_t __loc) {
+ __locale_guard __current(__loc);
+ return MB_CUR_MAX;
+}
+
+# if _LIBCPP_HAS_WIDE_CHARACTERS
+inline _LIBCPP_HIDE_FROM_ABI wint_t __btowc(int __c, __locale_t __loc) {
+ __locale_guard __current(__loc);
+ return std::btowc(__c);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI int __wctob(wint_t __c, __locale_t __loc) {
+ __locale_guard __current(__loc);
+ return std::wctob(__c);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI size_t
+__wcsnrtombs(char* __dest, const wchar_t** __src, size_t __nwc, size_t __len, mbstate_t* __ps, __locale_t __loc) {
+ __locale_guard __current(__loc);
+ return ::wcsnrtombs(__dest, __src, __nwc, __len, __ps); // non-standard
+}
+
+inline _LIBCPP_HIDE_FROM_ABI size_t __wcrtomb(char* __s, wchar_t __wc, mbstate_t* __ps, __locale_t __loc) {
+ __locale_guard __current(__loc);
+ return std::wcrtomb(__s, __wc, __ps);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI size_t
+__mbsnrtowcs(wchar_t* __dest, const char** __src, size_t __nms, size_t __len, mbstate_t* __ps, __locale_t __loc) {
+ __locale_guard __current(__loc);
+ return ::mbsnrtowcs(__dest, __src, __nms, __len, __ps); // non-standard
+}
+
+inline _LIBCPP_HIDE_FROM_ABI size_t
+__mbrtowc(wchar_t* __pwc, const char* __s, size_t __n, mbstate_t* __ps, __locale_t __loc) {
+ __locale_guard __current(__loc);
+ return std::mbrtowc(__pwc, __s, __n, __ps);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI int __mbtowc(wchar_t* __pwc, const char* __pmb, size_t __max, __locale_t __loc) {
+ __locale_guard __current(__loc);
+ return std::mbtowc(__pwc, __pmb, __max);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI size_t __mbrlen(const char* __s, size_t __n, mbstate_t* __ps, __locale_t __loc) {
+ __locale_guard __current(__loc);
+ return std::mbrlen(__s, __n, __ps);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI size_t
+__mbsrtowcs(wchar_t* __dest, const char** __src, size_t __len, mbstate_t* __ps, __locale_t __loc) {
+ __locale_guard __current(__loc);
+ return std::mbsrtowcs(__dest, __src, __len, __ps);
+}
+# endif // _LIBCPP_HAS_WIDE_CHARACTERS
+#endif // _LIBCPP_BUILDING_LIBRARY
+
+#ifndef _LIBCPP_COMPILER_GCC // GCC complains that this can't be always_inline due to C-style varargs
+_LIBCPP_HIDE_FROM_ABI
+#endif
+inline _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 4, 5) int __snprintf(
+ char* __s, size_t __n, __locale_t __loc, const char* __format, ...) {
+ va_list __va;
+ va_start(__va, __format);
+ __locale_guard __current(__loc);
+ int __res = std::vsnprintf(__s, __n, __format, __va);
+ va_end(__va);
+ return __res;
+}
+
+#ifndef _LIBCPP_COMPILER_GCC // GCC complains that this can't be always_inline due to C-style varargs
+_LIBCPP_HIDE_FROM_ABI
+#endif
+inline _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 3, 4) int __asprintf(
+ char** __s, __locale_t __loc, const char* __format, ...) {
+ va_list __va;
+ va_start(__va, __format);
+ __locale_guard __current(__loc);
+ int __res = ::vasprintf(__s, __format, __va); // non-standard
+ va_end(__va);
+ return __res;
+}
+} // namespace __locale
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___LOCALE_DIR_SUPPORT_NEWLIB_H
diff --git a/libcxx/include/__locale_dir/support/no_locale/characters.h b/libcxx/include/__locale_dir/support/no_locale/characters.h
index 1281b8b..73eba3e 100644
--- a/libcxx/include/__locale_dir/support/no_locale/characters.h
+++ b/libcxx/include/__locale_dir/support/no_locale/characters.h
@@ -29,10 +29,6 @@ namespace __locale {
//
// Character manipulation functions
//
-inline _LIBCPP_HIDE_FROM_ABI int __isdigit(int __c, __locale_t) { return std::isdigit(__c); }
-
-inline _LIBCPP_HIDE_FROM_ABI int __isxdigit(int __c, __locale_t) { return std::isxdigit(__c); }
-
#if defined(_LIBCPP_BUILDING_LIBRARY)
inline _LIBCPP_HIDE_FROM_ABI int __toupper(int __c, __locale_t) { return std::toupper(__c); }
diff --git a/libcxx/include/__locale_dir/support/no_locale/strtonum.h b/libcxx/include/__locale_dir/support/no_locale/strtonum.h
index 0e7a329..59544e1 100644
--- a/libcxx/include/__locale_dir/support/no_locale/strtonum.h
+++ b/libcxx/include/__locale_dir/support/no_locale/strtonum.h
@@ -34,15 +34,6 @@ inline _LIBCPP_HIDE_FROM_ABI long double __strtold(const char* __nptr, char** __
return std::strtold(__nptr, __endptr);
}
-inline _LIBCPP_HIDE_FROM_ABI long long __strtoll(const char* __nptr, char** __endptr, int __base, __locale_t) {
- return std::strtoll(__nptr, __endptr, __base);
-}
-
-inline _LIBCPP_HIDE_FROM_ABI unsigned long long
-__strtoull(const char* __nptr, char** __endptr, int __base, __locale_t) {
- return std::strtoull(__nptr, __endptr, __base);
-}
-
} // namespace __locale
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__locale_dir/support/windows.h b/libcxx/include/__locale_dir/support/windows.h
index 0df8709..644ef68 100644
--- a/libcxx/include/__locale_dir/support/windows.h
+++ b/libcxx/include/__locale_dir/support/windows.h
@@ -186,21 +186,9 @@ inline _LIBCPP_HIDE_FROM_ABI double __strtod(const char* __nptr, char** __endptr
return ::_strtod_l(__nptr, __endptr, __loc);
}
-inline _LIBCPP_HIDE_FROM_ABI long long __strtoll(const char* __nptr, char** __endptr, int __base, __locale_t __loc) {
- return ::_strtoi64_l(__nptr, __endptr, __base, __loc);
-}
-inline _LIBCPP_HIDE_FROM_ABI unsigned long long
-__strtoull(const char* __nptr, char** __endptr, int __base, __locale_t __loc) {
- return ::_strtoui64_l(__nptr, __endptr, __base, __loc);
-}
-
//
// Character manipulation functions
//
-inline _LIBCPP_HIDE_FROM_ABI int __isdigit(int __c, __locale_t __loc) { return _isdigit_l(__c, __loc); }
-
-inline _LIBCPP_HIDE_FROM_ABI int __isxdigit(int __c, __locale_t __loc) { return _isxdigit_l(__c, __loc); }
-
#if defined(_LIBCPP_BUILDING_LIBRARY)
inline _LIBCPP_HIDE_FROM_ABI int __toupper(int __c, __locale_t __loc) { return ::_toupper_l(__c, __loc); }
@@ -280,23 +268,6 @@ _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 4, 5) int __snpri
_LIBCPP_EXPORTED_FROM_ABI
_LIBCPP_ATTRIBUTE_FORMAT(__printf__, 3, 4) int __asprintf(char** __ret, __locale_t __loc, const char* __format, ...);
-_LIBCPP_DIAGNOSTIC_PUSH
-_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wgcc-compat")
-_LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wformat-nonliteral") // GCC doesn't support [[gnu::format]] on variadic templates
-#ifdef _LIBCPP_COMPILER_CLANG_BASED
-# define _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT(...) _LIBCPP_ATTRIBUTE_FORMAT(__VA_ARGS__)
-#else
-# define _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT(...) /* nothing */
-#endif
-
-template <class... _Args>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT(__scanf__, 3, 4) int __sscanf(
- const char* __dest, __locale_t __loc, const char* __format, _Args&&... __args) {
- return ::_sscanf_l(__dest, __format, __loc, std::forward<_Args>(__args)...);
-}
-_LIBCPP_DIAGNOSTIC_POP
-#undef _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT
-
#if defined(_LIBCPP_BUILDING_LIBRARY)
struct __locale_guard {
_LIBCPP_HIDE_FROM_ABI __locale_guard(__locale_t __l) : __status(_configthreadlocale(_ENABLE_PER_THREAD_LOCALE)) {
diff --git a/libcxx/include/__mdspan/extents.h b/libcxx/include/__mdspan/extents.h
index 99b54ba..d16bbd2 100644
--- a/libcxx/include/__mdspan/extents.h
+++ b/libcxx/include/__mdspan/extents.h
@@ -25,6 +25,7 @@
#include <__type_traits/integer_traits.h>
#include <__type_traits/is_convertible.h>
#include <__type_traits/is_nothrow_constructible.h>
+#include <__type_traits/is_signed.h>
#include <__type_traits/make_unsigned.h>
#include <__utility/integer_sequence.h>
#include <__utility/unreachable.h>
@@ -298,11 +299,13 @@ private:
public:
// [mdspan.extents.obs], observers of multidimensional index space
- _LIBCPP_HIDE_FROM_ABI static constexpr rank_type rank() noexcept { return __rank_; }
- _LIBCPP_HIDE_FROM_ABI static constexpr rank_type rank_dynamic() noexcept { return __rank_dynamic_; }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr rank_type rank() noexcept { return __rank_; }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr rank_type rank_dynamic() noexcept { return __rank_dynamic_; }
- _LIBCPP_HIDE_FROM_ABI constexpr index_type extent(rank_type __r) const noexcept { return __vals_.__value(__r); }
- _LIBCPP_HIDE_FROM_ABI static constexpr size_t static_extent(rank_type __r) noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr index_type extent(rank_type __r) const noexcept {
+ return __vals_.__value(__r);
+ }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr size_t static_extent(rank_type __r) noexcept {
return _Values::__static_value(__r);
}
diff --git a/libcxx/include/__mdspan/mdspan.h b/libcxx/include/__mdspan/mdspan.h
index c0f2767..9f3139a 100644
--- a/libcxx/include/__mdspan/mdspan.h
+++ b/libcxx/include/__mdspan/mdspan.h
@@ -87,12 +87,14 @@ public:
using data_handle_type = typename accessor_type::data_handle_type;
using reference = typename accessor_type::reference;
- _LIBCPP_HIDE_FROM_ABI static constexpr rank_type rank() noexcept { return extents_type::rank(); }
- _LIBCPP_HIDE_FROM_ABI static constexpr rank_type rank_dynamic() noexcept { return extents_type::rank_dynamic(); }
- _LIBCPP_HIDE_FROM_ABI static constexpr size_t static_extent(rank_type __r) noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr rank_type rank() noexcept { return extents_type::rank(); }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr rank_type rank_dynamic() noexcept {
+ return extents_type::rank_dynamic();
+ }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr size_t static_extent(rank_type __r) noexcept {
return extents_type::static_extent(__r);
}
- _LIBCPP_HIDE_FROM_ABI constexpr index_type extent(rank_type __r) const noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr index_type extent(rank_type __r) const noexcept {
return __map_.extents().extent(__r);
};
@@ -185,7 +187,7 @@ public:
requires((is_convertible_v<_OtherIndexTypes, index_type> && ...) &&
(is_nothrow_constructible_v<index_type, _OtherIndexTypes> && ...) &&
(sizeof...(_OtherIndexTypes) == rank()))
- _LIBCPP_HIDE_FROM_ABI constexpr reference operator[](_OtherIndexTypes... __indices) const {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr reference operator[](_OtherIndexTypes... __indices) const {
// Note the standard layouts would also check this, but user provided ones may not, so we
// check the precondition here
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__mdspan_detail::__is_multidimensional_index_in(extents(), __indices...),
@@ -196,7 +198,8 @@ public:
template <class _OtherIndexType>
requires(is_convertible_v<const _OtherIndexType&, index_type> &&
is_nothrow_constructible_v<index_type, const _OtherIndexType&>)
- _LIBCPP_HIDE_FROM_ABI constexpr reference operator[](const array< _OtherIndexType, rank()>& __indices) const {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr reference
+ operator[](const array< _OtherIndexType, rank()>& __indices) const {
return __acc_.access(__ptr_, [&]<size_t... _Idxs>(index_sequence<_Idxs...>) {
return __map_(__indices[_Idxs]...);
}(make_index_sequence<rank()>()));
@@ -205,7 +208,7 @@ public:
template <class _OtherIndexType>
requires(is_convertible_v<const _OtherIndexType&, index_type> &&
is_nothrow_constructible_v<index_type, const _OtherIndexType&>)
- _LIBCPP_HIDE_FROM_ABI constexpr reference operator[](span<_OtherIndexType, rank()> __indices) const {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr reference operator[](span<_OtherIndexType, rank()> __indices) const {
return __acc_.access(__ptr_, [&]<size_t... _Idxs>(index_sequence<_Idxs...>) {
return __map_(__indices[_Idxs]...);
}(make_index_sequence<rank()>()));
@@ -237,24 +240,28 @@ public:
swap(__x.__acc_, __y.__acc_);
}
- _LIBCPP_HIDE_FROM_ABI constexpr const extents_type& extents() const noexcept { return __map_.extents(); };
- _LIBCPP_HIDE_FROM_ABI constexpr const data_handle_type& data_handle() const noexcept { return __ptr_; };
- _LIBCPP_HIDE_FROM_ABI constexpr const mapping_type& mapping() const noexcept { return __map_; };
- _LIBCPP_HIDE_FROM_ABI constexpr const accessor_type& accessor() const noexcept { return __acc_; };
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const extents_type& extents() const noexcept {
+ return __map_.extents();
+ };
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const data_handle_type& data_handle() const noexcept { return __ptr_; };
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const mapping_type& mapping() const noexcept { return __map_; };
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const accessor_type& accessor() const noexcept { return __acc_; };
// per LWG-4021 "mdspan::is_always_meow() should be noexcept"
- _LIBCPP_HIDE_FROM_ABI static constexpr bool is_always_unique() noexcept { return mapping_type::is_always_unique(); };
- _LIBCPP_HIDE_FROM_ABI static constexpr bool is_always_exhaustive() noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr bool is_always_unique() noexcept {
+ return mapping_type::is_always_unique();
+ };
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr bool is_always_exhaustive() noexcept {
return mapping_type::is_always_exhaustive();
};
- _LIBCPP_HIDE_FROM_ABI static constexpr bool is_always_strided() noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr bool is_always_strided() noexcept {
return mapping_type::is_always_strided();
};
- _LIBCPP_HIDE_FROM_ABI constexpr bool is_unique() const { return __map_.is_unique(); };
- _LIBCPP_HIDE_FROM_ABI constexpr bool is_exhaustive() const { return __map_.is_exhaustive(); };
- _LIBCPP_HIDE_FROM_ABI constexpr bool is_strided() const { return __map_.is_strided(); };
- _LIBCPP_HIDE_FROM_ABI constexpr index_type stride(rank_type __r) const { return __map_.stride(__r); };
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool is_unique() const { return __map_.is_unique(); };
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool is_exhaustive() const { return __map_.is_exhaustive(); };
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool is_strided() const { return __map_.is_strided(); };
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr index_type stride(rank_type __r) const { return __map_.stride(__r); };
private:
_LIBCPP_NO_UNIQUE_ADDRESS data_handle_type __ptr_{};
diff --git a/libcxx/include/__memory/inout_ptr.h b/libcxx/include/__memory/inout_ptr.h
index ef345fe..0fa685a 100644
--- a/libcxx/include/__memory/inout_ptr.h
+++ b/libcxx/include/__memory/inout_ptr.h
@@ -96,7 +96,7 @@ private:
};
template <class _Pointer = void, class _Smart, class... _Args>
-_LIBCPP_HIDE_FROM_ABI auto inout_ptr(_Smart& __s, _Args&&... __args) {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI auto inout_ptr(_Smart& __s, _Args&&... __args) {
using _Ptr = conditional_t<is_void_v<_Pointer>, __pointer_of_t<_Smart>, _Pointer>;
return std::inout_ptr_t<_Smart, _Ptr, _Args&&...>(__s, std::forward<_Args>(__args)...);
}
diff --git a/libcxx/include/__memory/out_ptr.h b/libcxx/include/__memory/out_ptr.h
index e498e33..23a77f6 100644
--- a/libcxx/include/__memory/out_ptr.h
+++ b/libcxx/include/__memory/out_ptr.h
@@ -88,7 +88,7 @@ private:
};
template <class _Pointer = void, class _Smart, class... _Args>
-_LIBCPP_HIDE_FROM_ABI auto out_ptr(_Smart& __s, _Args&&... __args) {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI auto out_ptr(_Smart& __s, _Args&&... __args) {
using _Ptr = conditional_t<is_void_v<_Pointer>, __pointer_of_t<_Smart>, _Pointer>;
return std::out_ptr_t<_Smart, _Ptr, _Args&&...>(__s, std::forward<_Args>(__args)...);
}
diff --git a/libcxx/include/__memory/shared_ptr.h b/libcxx/include/__memory/shared_ptr.h
index e90db58..4fbd0af 100644
--- a/libcxx/include/__memory/shared_ptr.h
+++ b/libcxx/include/__memory/shared_ptr.h
@@ -41,13 +41,11 @@
#include <__type_traits/enable_if.h>
#include <__type_traits/integral_constant.h>
#include <__type_traits/is_array.h>
-#include <__type_traits/is_bounded_array.h>
#include <__type_traits/is_constructible.h>
#include <__type_traits/is_convertible.h>
#include <__type_traits/is_function.h>
#include <__type_traits/is_reference.h>
#include <__type_traits/is_same.h>
-#include <__type_traits/is_unbounded_array.h>
#include <__type_traits/nat.h>
#include <__type_traits/negation.h>
#include <__type_traits/remove_cv.h>
@@ -79,7 +77,7 @@ public:
_LIBCPP_HIDE_FROM_ABI bad_weak_ptr(const bad_weak_ptr&) _NOEXCEPT = default;
_LIBCPP_HIDE_FROM_ABI bad_weak_ptr& operator=(const bad_weak_ptr&) _NOEXCEPT = default;
~bad_weak_ptr() _NOEXCEPT override;
- const char* what() const _NOEXCEPT override;
+ [[__nodiscard__]] const char* what() const _NOEXCEPT override;
};
[[__noreturn__]] inline _LIBCPP_HIDE_FROM_ABI void __throw_bad_weak_ptr() {
@@ -317,10 +315,8 @@ public:
#endif
// A shared_ptr contains only two raw pointers which point to the heap and move constructing already doesn't require
- // any bookkeeping, so it's always trivially relocatable. It is also replaceable because assignment just rebinds the
- // shared_ptr to manage a different object.
+ // any bookkeeping, so it's always trivially relocatable.
using __trivially_relocatable _LIBCPP_NODEBUG = shared_ptr;
- using __replaceable _LIBCPP_NODEBUG = shared_ptr;
private:
element_type* __ptr_;
@@ -487,45 +483,16 @@ public:
template <class _Yp,
class _Dp,
- __enable_if_t<!is_lvalue_reference<_Dp>::value && __compatible_with<_Yp, _Tp>::value &&
+ __enable_if_t<__compatible_with<_Yp, _Tp>::value &&
is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
int> = 0>
_LIBCPP_HIDE_FROM_ABI shared_ptr(unique_ptr<_Yp, _Dp>&& __r) : __ptr_(__r.get()) {
-#if _LIBCPP_STD_VER >= 14
- if (__ptr_ == nullptr)
- __cntrl_ = nullptr;
- else
-#endif
- {
- typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;
- typedef __shared_ptr_pointer<typename unique_ptr<_Yp, _Dp>::pointer, _Dp, _AllocT> _CntrlBlk;
- __cntrl_ = new _CntrlBlk(__r.get(), std::move(__r.get_deleter()), _AllocT());
- __enable_weak_this(__r.get(), __r.get());
- }
- __r.release();
- }
+ using _AllocT = typename __shared_ptr_default_allocator<_Yp>::type;
+ using _Deleter = _If<is_lvalue_reference<_Dp>::value, reference_wrapper<__libcpp_remove_reference_t<_Dp> >, _Dp>;
+ using _CntrlBlk = __shared_ptr_pointer<typename unique_ptr<_Yp, _Dp>::pointer, _Deleter, _AllocT>;
- template <class _Yp,
- class _Dp,
- class = void,
- __enable_if_t<is_lvalue_reference<_Dp>::value && __compatible_with<_Yp, _Tp>::value &&
- is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
- int> = 0>
- _LIBCPP_HIDE_FROM_ABI shared_ptr(unique_ptr<_Yp, _Dp>&& __r) : __ptr_(__r.get()) {
-#if _LIBCPP_STD_VER >= 14
- if (__ptr_ == nullptr)
- __cntrl_ = nullptr;
- else
-#endif
- {
- typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;
- typedef __shared_ptr_pointer<typename unique_ptr<_Yp, _Dp>::pointer,
- reference_wrapper<__libcpp_remove_reference_t<_Dp> >,
- _AllocT>
- _CntrlBlk;
- __cntrl_ = new _CntrlBlk(__r.get(), std::ref(__r.get_deleter()), _AllocT());
- __enable_weak_this(__r.get(), __r.get());
- }
+ __cntrl_ = __ptr_ ? new _CntrlBlk(__r.get(), std::forward<_Dp>(__r.get_deleter()), _AllocT()) : nullptr;
+ __enable_weak_this(__r.get(), __r.get());
__r.release();
}
@@ -601,37 +568,43 @@ public:
shared_ptr(__p, __d, __a).swap(*this);
}
- _LIBCPP_HIDE_FROM_ABI element_type* get() const _NOEXCEPT { return __ptr_; }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI element_type* get() const _NOEXCEPT { return __ptr_; }
- _LIBCPP_HIDE_FROM_ABI __add_lvalue_reference_t<element_type> operator*() const _NOEXCEPT { return *__ptr_; }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI __add_lvalue_reference_t<element_type> operator*() const _NOEXCEPT {
+ return *__ptr_;
+ }
_LIBCPP_HIDE_FROM_ABI element_type* operator->() const _NOEXCEPT {
static_assert(!is_array<_Tp>::value, "std::shared_ptr<T>::operator-> is only valid when T is not an array type.");
return __ptr_;
}
- _LIBCPP_HIDE_FROM_ABI long use_count() const _NOEXCEPT { return __cntrl_ ? __cntrl_->use_count() : 0; }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI long use_count() const _NOEXCEPT {
+ return __cntrl_ ? __cntrl_->use_count() : 0;
+ }
#if _LIBCPP_STD_VER < 20 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_SHARED_PTR_UNIQUE)
- _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_HIDE_FROM_ABI bool unique() const _NOEXCEPT { return use_count() == 1; }
+ [[__nodiscard__]] _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_HIDE_FROM_ABI bool unique() const _NOEXCEPT {
+ return use_count() == 1;
+ }
#endif
_LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return get() != nullptr; }
template <class _Up>
- _LIBCPP_HIDE_FROM_ABI bool owner_before(shared_ptr<_Up> const& __p) const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool owner_before(shared_ptr<_Up> const& __p) const _NOEXCEPT {
return __cntrl_ < __p.__cntrl_;
}
template <class _Up>
- _LIBCPP_HIDE_FROM_ABI bool owner_before(weak_ptr<_Up> const& __p) const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool owner_before(weak_ptr<_Up> const& __p) const _NOEXCEPT {
return __cntrl_ < __p.__cntrl_;
}
_LIBCPP_HIDE_FROM_ABI bool __owner_equivalent(const shared_ptr& __p) const { return __cntrl_ == __p.__cntrl_; }
#if _LIBCPP_STD_VER >= 17
- _LIBCPP_HIDE_FROM_ABI __add_lvalue_reference_t<element_type> operator[](ptrdiff_t __i) const {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI __add_lvalue_reference_t<element_type> operator[](ptrdiff_t __i) const {
static_assert(is_array<_Tp>::value, "std::shared_ptr<T>::operator[] is only valid when T is an array type.");
return __ptr_[__i];
}
@@ -702,7 +675,7 @@ shared_ptr(unique_ptr<_Tp, _Dp>) -> shared_ptr<_Tp>;
// std::allocate_shared and std::make_shared
//
template <class _Tp, class _Alloc, class... _Args, __enable_if_t<!is_array<_Tp>::value, int> = 0>
-_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared(const _Alloc& __a, _Args&&... __args) {
+[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared(const _Alloc& __a, _Args&&... __args) {
using _ControlBlock = __shared_ptr_emplace<_Tp, _Alloc>;
using _ControlBlockAllocator = typename __allocator_traits_rebind<_Alloc, _ControlBlock>::type;
__allocation_guard<_ControlBlockAllocator> __guard(__a, 1);
@@ -713,21 +686,21 @@ _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared(const _Alloc& __a, _Args&&
}
template <class _Tp, class... _Args, __enable_if_t<!is_array<_Tp>::value, int> = 0>
-_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared(_Args&&... __args) {
+[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared(_Args&&... __args) {
return std::allocate_shared<_Tp>(allocator<__remove_cv_t<_Tp> >(), std::forward<_Args>(__args)...);
}
#if _LIBCPP_STD_VER >= 20
template <class _Tp, class _Alloc, __enable_if_t<!is_array<_Tp>::value, int> = 0>
-_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared_for_overwrite(const _Alloc& __a) {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared_for_overwrite(const _Alloc& __a) {
using _ForOverwriteAllocator = __allocator_traits_rebind_t<_Alloc, __for_overwrite_tag>;
_ForOverwriteAllocator __alloc(__a);
return std::allocate_shared<_Tp>(__alloc);
}
template <class _Tp, __enable_if_t<!is_array<_Tp>::value, int> = 0>
-_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared_for_overwrite() {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared_for_overwrite() {
return std::allocate_shared_for_overwrite<_Tp>(allocator<__remove_cv_t<_Tp>>());
}
@@ -919,67 +892,69 @@ _LIBCPP_HIDE_FROM_ABI shared_ptr<_Array> __allocate_shared_bounded_array(const _
// bounded array variants
template <class _Tp, class _Alloc, __enable_if_t<is_bounded_array<_Tp>::value, int> = 0>
-_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared(const _Alloc& __a) {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared(const _Alloc& __a) {
return std::__allocate_shared_bounded_array<_Tp>(__a);
}
template <class _Tp, class _Alloc, __enable_if_t<is_bounded_array<_Tp>::value, int> = 0>
-_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared(const _Alloc& __a, const remove_extent_t<_Tp>& __u) {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp>
+allocate_shared(const _Alloc& __a, const remove_extent_t<_Tp>& __u) {
return std::__allocate_shared_bounded_array<_Tp>(__a, __u);
}
template <class _Tp, class _Alloc, __enable_if_t<is_bounded_array<_Tp>::value, int> = 0>
-_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared_for_overwrite(const _Alloc& __a) {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared_for_overwrite(const _Alloc& __a) {
using _ForOverwriteAllocator = __allocator_traits_rebind_t<_Alloc, __for_overwrite_tag>;
_ForOverwriteAllocator __alloc(__a);
return std::__allocate_shared_bounded_array<_Tp>(__alloc);
}
template <class _Tp, __enable_if_t<is_bounded_array<_Tp>::value, int> = 0>
-_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared() {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared() {
return std::__allocate_shared_bounded_array<_Tp>(allocator<_Tp>());
}
template <class _Tp, __enable_if_t<is_bounded_array<_Tp>::value, int> = 0>
-_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared(const remove_extent_t<_Tp>& __u) {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared(const remove_extent_t<_Tp>& __u) {
return std::__allocate_shared_bounded_array<_Tp>(allocator<_Tp>(), __u);
}
template <class _Tp, __enable_if_t<is_bounded_array<_Tp>::value, int> = 0>
-_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared_for_overwrite() {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared_for_overwrite() {
return std::__allocate_shared_bounded_array<_Tp>(allocator<__for_overwrite_tag>());
}
// unbounded array variants
template <class _Tp, class _Alloc, __enable_if_t<is_unbounded_array<_Tp>::value, int> = 0>
-_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared(const _Alloc& __a, size_t __n) {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared(const _Alloc& __a, size_t __n) {
return std::__allocate_shared_unbounded_array<_Tp>(__a, __n);
}
template <class _Tp, class _Alloc, __enable_if_t<is_unbounded_array<_Tp>::value, int> = 0>
-_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared(const _Alloc& __a, size_t __n, const remove_extent_t<_Tp>& __u) {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp>
+allocate_shared(const _Alloc& __a, size_t __n, const remove_extent_t<_Tp>& __u) {
return std::__allocate_shared_unbounded_array<_Tp>(__a, __n, __u);
}
template <class _Tp, class _Alloc, __enable_if_t<is_unbounded_array<_Tp>::value, int> = 0>
-_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared_for_overwrite(const _Alloc& __a, size_t __n) {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared_for_overwrite(const _Alloc& __a, size_t __n) {
using _ForOverwriteAllocator = __allocator_traits_rebind_t<_Alloc, __for_overwrite_tag>;
_ForOverwriteAllocator __alloc(__a);
return std::__allocate_shared_unbounded_array<_Tp>(__alloc, __n);
}
template <class _Tp, __enable_if_t<is_unbounded_array<_Tp>::value, int> = 0>
-_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared(size_t __n) {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared(size_t __n) {
return std::__allocate_shared_unbounded_array<_Tp>(allocator<_Tp>(), __n);
}
template <class _Tp, __enable_if_t<is_unbounded_array<_Tp>::value, int> = 0>
-_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared(size_t __n, const remove_extent_t<_Tp>& __u) {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared(size_t __n, const remove_extent_t<_Tp>& __u) {
return std::__allocate_shared_unbounded_array<_Tp>(allocator<_Tp>(), __n, __u);
}
template <class _Tp, __enable_if_t<is_unbounded_array<_Tp>::value, int> = 0>
-_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared_for_overwrite(size_t __n) {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared_for_overwrite(size_t __n) {
return std::__allocate_shared_unbounded_array<_Tp>(allocator<__for_overwrite_tag>(), __n);
}
@@ -1108,7 +1083,8 @@ inline _LIBCPP_HIDE_FROM_ABI void swap(shared_ptr<_Tp>& __x, shared_ptr<_Tp>& __
}
template <class _Tp, class _Up>
-inline _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> static_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT {
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp>
+static_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT {
return shared_ptr<_Tp>(__r, static_cast< typename shared_ptr<_Tp>::element_type*>(__r.get()));
}
@@ -1116,13 +1092,14 @@ inline _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> static_pointer_cast(const shared_pt
// We don't backport because it is an evolutionary change.
#if _LIBCPP_STD_VER >= 20
template <class _Tp, class _Up>
-_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> static_pointer_cast(shared_ptr<_Up>&& __r) noexcept {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> static_pointer_cast(shared_ptr<_Up>&& __r) noexcept {
return shared_ptr<_Tp>(std::move(__r), static_cast<typename shared_ptr<_Tp>::element_type*>(__r.get()));
}
#endif
template <class _Tp, class _Up>
-inline _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> dynamic_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT {
+[[__nodiscard__]] inline
+ _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> dynamic_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT {
typedef typename shared_ptr<_Tp>::element_type _ET;
_ET* __p = dynamic_cast<_ET*>(__r.get());
return __p ? shared_ptr<_Tp>(__r, __p) : shared_ptr<_Tp>();
@@ -1132,14 +1109,14 @@ inline _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> dynamic_pointer_cast(const shared_p
// We don't backport because it is an evolutionary change.
#if _LIBCPP_STD_VER >= 20
template <class _Tp, class _Up>
-_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> dynamic_pointer_cast(shared_ptr<_Up>&& __r) noexcept {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> dynamic_pointer_cast(shared_ptr<_Up>&& __r) noexcept {
auto* __p = dynamic_cast<typename shared_ptr<_Tp>::element_type*>(__r.get());
return __p ? shared_ptr<_Tp>(std::move(__r), __p) : shared_ptr<_Tp>();
}
#endif
template <class _Tp, class _Up>
-_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> const_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT {
+[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> const_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT {
typedef typename shared_ptr<_Tp>::element_type _RTp;
return shared_ptr<_Tp>(__r, const_cast<_RTp*>(__r.get()));
}
@@ -1148,13 +1125,13 @@ _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> const_pointer_cast(const shared_ptr<_Up>&
// We don't backport because it is an evolutionary change.
#if _LIBCPP_STD_VER >= 20
template <class _Tp, class _Up>
-_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> const_pointer_cast(shared_ptr<_Up>&& __r) noexcept {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> const_pointer_cast(shared_ptr<_Up>&& __r) noexcept {
return shared_ptr<_Tp>(std::move(__r), const_cast<typename shared_ptr<_Tp>::element_type*>(__r.get()));
}
#endif
template <class _Tp, class _Up>
-_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> reinterpret_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT {
+[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> reinterpret_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT {
return shared_ptr<_Tp>(__r, reinterpret_cast< typename shared_ptr<_Tp>::element_type*>(__r.get()));
}
@@ -1162,7 +1139,7 @@ _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> reinterpret_pointer_cast(const shared_ptr<
// We don't backport because it is an evolutionary change.
#if _LIBCPP_STD_VER >= 20
template <class _Tp, class _Up>
-_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> reinterpret_pointer_cast(shared_ptr<_Up>&& __r) noexcept {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> reinterpret_pointer_cast(shared_ptr<_Up>&& __r) noexcept {
return shared_ptr<_Tp>(std::move(__r), reinterpret_cast<typename shared_ptr<_Tp>::element_type*>(__r.get()));
}
#endif
@@ -1170,7 +1147,7 @@ _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> reinterpret_pointer_cast(shared_ptr<_Up>&&
#if _LIBCPP_HAS_RTTI
template <class _Dp, class _Tp>
-inline _LIBCPP_HIDE_FROM_ABI _Dp* get_deleter(const shared_ptr<_Tp>& __p) _NOEXCEPT {
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _Dp* get_deleter(const shared_ptr<_Tp>& __p) _NOEXCEPT {
return __p.template __get_deleter<_Dp>();
}
@@ -1186,9 +1163,8 @@ public:
#endif
// A weak_ptr contains only two raw pointers which point to the heap and move constructing already doesn't require
- // any bookkeeping, so it's always trivially relocatable. It's also replaceable for the same reason.
+ // any bookkeeping, so it's always trivially relocatable.
using __trivially_relocatable _LIBCPP_NODEBUG = weak_ptr;
- using __replaceable _LIBCPP_NODEBUG = weak_ptr;
private:
element_type* __ptr_;
@@ -1226,15 +1202,19 @@ public:
_LIBCPP_HIDE_FROM_ABI void swap(weak_ptr& __r) _NOEXCEPT;
_LIBCPP_HIDE_FROM_ABI void reset() _NOEXCEPT;
- _LIBCPP_HIDE_FROM_ABI long use_count() const _NOEXCEPT { return __cntrl_ ? __cntrl_->use_count() : 0; }
- _LIBCPP_HIDE_FROM_ABI bool expired() const _NOEXCEPT { return __cntrl_ == nullptr || __cntrl_->use_count() == 0; }
- _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> lock() const _NOEXCEPT;
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI long use_count() const _NOEXCEPT {
+ return __cntrl_ ? __cntrl_->use_count() : 0;
+ }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool expired() const _NOEXCEPT {
+ return __cntrl_ == nullptr || __cntrl_->use_count() == 0;
+ }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> lock() const _NOEXCEPT;
template <class _Up>
- _LIBCPP_HIDE_FROM_ABI bool owner_before(const shared_ptr<_Up>& __r) const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool owner_before(const shared_ptr<_Up>& __r) const _NOEXCEPT {
return __cntrl_ < __r.__cntrl_;
}
template <class _Up>
- _LIBCPP_HIDE_FROM_ABI bool owner_before(const weak_ptr<_Up>& __r) const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool owner_before(const weak_ptr<_Up>& __r) const _NOEXCEPT {
return __cntrl_ < __r.__cntrl_;
}
@@ -1418,13 +1398,15 @@ protected:
_LIBCPP_HIDE_FROM_ABI ~enable_shared_from_this() {}
public:
- _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> shared_from_this() { return shared_ptr<_Tp>(__weak_this_); }
- _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp const> shared_from_this() const { return shared_ptr<const _Tp>(__weak_this_); }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> shared_from_this() { return shared_ptr<_Tp>(__weak_this_); }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp const> shared_from_this() const {
+ return shared_ptr<const _Tp>(__weak_this_);
+ }
#if _LIBCPP_STD_VER >= 17
- _LIBCPP_HIDE_FROM_ABI weak_ptr<_Tp> weak_from_this() _NOEXCEPT { return __weak_this_; }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI weak_ptr<_Tp> weak_from_this() _NOEXCEPT { return __weak_this_; }
- _LIBCPP_HIDE_FROM_ABI weak_ptr<const _Tp> weak_from_this() const _NOEXCEPT { return __weak_this_; }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI weak_ptr<const _Tp> weak_from_this() const _NOEXCEPT { return __weak_this_; }
#endif // _LIBCPP_STD_VER >= 17
template <class _Up>
@@ -1441,7 +1423,7 @@ struct hash<shared_ptr<_Tp> > {
_LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
#endif
- _LIBCPP_HIDE_FROM_ABI size_t operator()(const shared_ptr<_Tp>& __ptr) const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t operator()(const shared_ptr<_Tp>& __ptr) const _NOEXCEPT {
return hash<typename shared_ptr<_Tp>::element_type*>()(__ptr.get());
}
};
diff --git a/libcxx/include/__memory/temp_value.h b/libcxx/include/__memory/temp_value.h
index 4a133b3..5285bcab 100644
--- a/libcxx/include/__memory/temp_value.h
+++ b/libcxx/include/__memory/temp_value.h
@@ -12,7 +12,6 @@
#include <__config>
#include <__memory/addressof.h>
#include <__memory/allocator_traits.h>
-#include <__type_traits/aligned_storage.h>
#include <__utility/forward.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -26,7 +25,7 @@ struct __temp_value {
typedef allocator_traits<_Alloc> _Traits;
#ifdef _LIBCPP_CXX03_LANG
- typename aligned_storage<sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)>::type __v;
+ _ALIGNAS_TYPE(_Tp) char __v[sizeof(_Tp)];
#else
union {
_Tp __v;
diff --git a/libcxx/include/__memory/uninitialized_algorithms.h b/libcxx/include/__memory/uninitialized_algorithms.h
index 34d065d..9182db4 100644
--- a/libcxx/include/__memory/uninitialized_algorithms.h
+++ b/libcxx/include/__memory/uninitialized_algorithms.h
@@ -32,7 +32,6 @@
#include <__type_traits/is_trivially_assignable.h>
#include <__type_traits/is_trivially_constructible.h>
#include <__type_traits/is_trivially_relocatable.h>
-#include <__type_traits/is_unbounded_array.h>
#include <__type_traits/remove_const.h>
#include <__type_traits/remove_extent.h>
#include <__utility/exception_guard.h>
diff --git a/libcxx/include/__memory/unique_ptr.h b/libcxx/include/__memory/unique_ptr.h
index eff2454..6a4ec0a 100644
--- a/libcxx/include/__memory/unique_ptr.h
+++ b/libcxx/include/__memory/unique_ptr.h
@@ -32,18 +32,15 @@
#include <__type_traits/integral_constant.h>
#include <__type_traits/is_array.h>
#include <__type_traits/is_assignable.h>
-#include <__type_traits/is_bounded_array.h>
#include <__type_traits/is_constant_evaluated.h>
#include <__type_traits/is_constructible.h>
#include <__type_traits/is_convertible.h>
#include <__type_traits/is_function.h>
#include <__type_traits/is_pointer.h>
#include <__type_traits/is_reference.h>
-#include <__type_traits/is_replaceable.h>
#include <__type_traits/is_same.h>
#include <__type_traits/is_swappable.h>
#include <__type_traits/is_trivially_relocatable.h>
-#include <__type_traits/is_unbounded_array.h>
#include <__type_traits/is_void.h>
#include <__type_traits/remove_extent.h>
#include <__type_traits/type_identity.h>
@@ -145,8 +142,6 @@ public:
__libcpp_is_trivially_relocatable<pointer>::value && __libcpp_is_trivially_relocatable<deleter_type>::value,
unique_ptr,
void>;
- using __replaceable _LIBCPP_NODEBUG =
- __conditional_t<__is_replaceable_v<pointer> && __is_replaceable_v<deleter_type>, unique_ptr, void>;
private:
_LIBCPP_COMPRESSED_PAIR(pointer, __ptr_, deleter_type, __deleter_);
@@ -263,14 +258,17 @@ public:
return *this;
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 __add_lvalue_reference_t<_Tp> operator*() const
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 __add_lvalue_reference_t<_Tp> operator*() const
_NOEXCEPT_(_NOEXCEPT_(*std::declval<pointer>())) {
return *__ptr_;
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer operator->() const _NOEXCEPT { return __ptr_; }
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer get() const _NOEXCEPT { return __ptr_; }
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 deleter_type& get_deleter() _NOEXCEPT { return __deleter_; }
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 const deleter_type& get_deleter() const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer get() const _NOEXCEPT { return __ptr_; }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 deleter_type& get_deleter() _NOEXCEPT {
+ return __deleter_;
+ }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 const deleter_type&
+ get_deleter() const _NOEXCEPT {
return __deleter_;
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 explicit operator bool() const _NOEXCEPT {
@@ -413,8 +411,6 @@ public:
__libcpp_is_trivially_relocatable<pointer>::value && __libcpp_is_trivially_relocatable<deleter_type>::value,
unique_ptr,
void>;
- using __replaceable _LIBCPP_NODEBUG =
- __conditional_t<__is_replaceable_v<pointer> && __is_replaceable_v<deleter_type>, unique_ptr, void>;
private:
template <class _Up, class _OtherDeleter>
@@ -755,12 +751,13 @@ operator<=>(const unique_ptr<_T1, _D1>& __x, nullptr_t) {
#if _LIBCPP_STD_VER >= 14
template <class _Tp, class... _Args, enable_if_t<!is_array<_Tp>::value, int> = 0>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr<_Tp> make_unique(_Args&&... __args) {
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI
+_LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr<_Tp> make_unique(_Args&&... __args) {
return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...));
}
template <class _Tp, enable_if_t<__is_unbounded_array_v<_Tp>, int> = 0>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr<_Tp> make_unique(size_t __n) {
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr<_Tp> make_unique(size_t __n) {
typedef __remove_extent_t<_Tp> _Up;
return unique_ptr<_Tp>(__private_constructor_tag(), new _Up[__n](), __n);
}
@@ -773,12 +770,13 @@ void make_unique(_Args&&...) = delete;
#if _LIBCPP_STD_VER >= 20
template <class _Tp, enable_if_t<!is_array_v<_Tp>, int> = 0>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr<_Tp> make_unique_for_overwrite() {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr<_Tp> make_unique_for_overwrite() {
return unique_ptr<_Tp>(new _Tp);
}
template <class _Tp, enable_if_t<is_unbounded_array_v<_Tp>, int> = 0>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr<_Tp> make_unique_for_overwrite(size_t __n) {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr<_Tp>
+make_unique_for_overwrite(size_t __n) {
return unique_ptr<_Tp>(__private_constructor_tag(), new __remove_extent_t<_Tp>[__n], __n);
}
@@ -802,7 +800,7 @@ struct hash<__enable_hash_helper< unique_ptr<_Tp, _Dp>, typename unique_ptr<_Tp,
_LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
#endif
- _LIBCPP_HIDE_FROM_ABI size_t operator()(const unique_ptr<_Tp, _Dp>& __ptr) const {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t operator()(const unique_ptr<_Tp, _Dp>& __ptr) const {
typedef typename unique_ptr<_Tp, _Dp>::pointer pointer;
return hash<pointer>()(__ptr.get());
}
diff --git a/libcxx/include/__mutex/mutex.h b/libcxx/include/__mutex/mutex.h
index 68c8842..e9cedf8 100644
--- a/libcxx/include/__mutex/mutex.h
+++ b/libcxx/include/__mutex/mutex.h
@@ -37,11 +37,11 @@ public:
# endif
_LIBCPP_ACQUIRE_CAPABILITY() void lock();
- _LIBCPP_TRY_ACQUIRE_CAPABILITY(true) bool try_lock() _NOEXCEPT;
+ [[__nodiscard__]] _LIBCPP_TRY_ACQUIRE_CAPABILITY(true) bool try_lock() _NOEXCEPT;
_LIBCPP_RELEASE_CAPABILITY void unlock() _NOEXCEPT;
typedef __libcpp_mutex_t* native_handle_type;
- _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() { return &__m_; }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() { return &__m_; }
};
static_assert(is_nothrow_default_constructible<mutex>::value, "the default constructor for std::mutex must be nothrow");
diff --git a/libcxx/include/__mutex/once_flag.h b/libcxx/include/__mutex/once_flag.h
index 808b1ea..ad15b2e 100644
--- a/libcxx/include/__mutex/once_flag.h
+++ b/libcxx/include/__mutex/once_flag.h
@@ -86,12 +86,10 @@ class __call_once_param {
public:
_LIBCPP_HIDE_FROM_ABI explicit __call_once_param(_Fp& __f) : __f_(__f) {}
- _LIBCPP_HIDE_FROM_ABI void operator()() { __execute(__make_index_sequence<tuple_size<_Fp>::value>()); }
-
-private:
- template <size_t... _Indices>
- _LIBCPP_HIDE_FROM_ABI void __execute(__index_sequence<_Indices...>) {
- std::__invoke(std::get<_Indices>(std::move(__f_))...);
+ _LIBCPP_HIDE_FROM_ABI void operator()() {
+ [&]<size_t... _Indices>(__index_sequence<_Indices...>) -> void {
+ std::__invoke(std::get<_Indices>(std::move(__f_))...);
+ }(__make_index_sequence<tuple_size<_Fp>::value>());
}
};
diff --git a/libcxx/include/__random/binomial_distribution.h b/libcxx/include/__random/binomial_distribution.h
index bada8cf..0712e4ef 100644
--- a/libcxx/include/__random/binomial_distribution.h
+++ b/libcxx/include/__random/binomial_distribution.h
@@ -98,13 +98,7 @@ public:
};
// Some libc declares the math functions to be `noexcept`.
-#if defined(_LIBCPP_GLIBC_PREREQ)
-# if _LIBCPP_GLIBC_PREREQ(2, 8)
-# define _LIBCPP_LGAMMA_R_NOEXCEPT _NOEXCEPT
-# else
-# define _LIBCPP_LGAMMA_R_NOEXCEPT
-# endif
-#elif defined(__LLVM_LIBC__)
+#if _LIBCPP_GLIBC_PREREQ(2, 8) || defined(__LLVM_LIBC__)
# define _LIBCPP_LGAMMA_R_NOEXCEPT _NOEXCEPT
#else
# define _LIBCPP_LGAMMA_R_NOEXCEPT
diff --git a/libcxx/include/__random/mersenne_twister_engine.h b/libcxx/include/__random/mersenne_twister_engine.h
index c60fe15..332e830 100644
--- a/libcxx/include/__random/mersenne_twister_engine.h
+++ b/libcxx/include/__random/mersenne_twister_engine.h
@@ -62,24 +62,6 @@ _LIBCPP_HIDE_FROM_ABI bool
operator==(const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, _Bp, _Tp, _Cp, _Lp, _Fp>& __x,
const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, _Bp, _Tp, _Cp, _Lp, _Fp>& __y);
-template <class _UInt,
- size_t _Wp,
- size_t _Np,
- size_t _Mp,
- size_t _Rp,
- _UInt _Ap,
- size_t _Up,
- _UInt _Dp,
- size_t _Sp,
- _UInt _Bp,
- size_t _Tp,
- _UInt _Cp,
- size_t _Lp,
- _UInt _Fp>
-_LIBCPP_HIDE_FROM_ABI bool
-operator!=(const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, _Bp, _Tp, _Cp, _Lp, _Fp>& __x,
- const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, _Bp, _Tp, _Cp, _Lp, _Fp>& __y);
-
template <class _CharT,
class _Traits,
class _UInt,
@@ -194,14 +176,31 @@ public:
_LIBCPP_HIDE_FROM_ABI explicit mersenne_twister_engine(_Sseq& __q) {
seed(__q);
}
- _LIBCPP_HIDE_FROM_ABI void seed(result_type __sd = default_seed);
+ _LIBCPP_HIDE_FROM_ABI void seed(result_type __sd = default_seed) _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK {
+ __x_[0] = __sd & _Max;
+ for (size_t __i = 1; __i < __n; ++__i)
+ __x_[__i] = (__f * (__x_[__i - 1] ^ __rshift<__w - 2>(__x_[__i - 1])) + __i) & _Max;
+ __i_ = 0;
+ }
template <class _Sseq, __enable_if_t<__is_seed_sequence<_Sseq, mersenne_twister_engine>::value, int> = 0>
_LIBCPP_HIDE_FROM_ABI void seed(_Sseq& __q) {
__seed(__q, integral_constant<unsigned, 1 + (__w - 1) / 32>());
}
// generating functions
- _LIBCPP_HIDE_FROM_ABI result_type operator()();
+ _LIBCPP_HIDE_FROM_ABI result_type operator()() {
+ const size_t __j = (__i_ + 1) % __n;
+ const result_type __mask = __r == _Dt ? result_type(~0) : (result_type(1) << __r) - result_type(1);
+ const result_type __yp = (__x_[__i_] & ~__mask) | (__x_[__j] & __mask);
+ const size_t __k = (__i_ + __m) % __n;
+ __x_[__i_] = __x_[__k] ^ __rshift<1>(__yp) ^ (__a * (__yp & 1));
+ result_type __z = __x_[__i_] ^ (__rshift<__u>(__x_[__i_]) & __d);
+ __i_ = __j;
+ __z ^= __lshift<__s>(__z) & __b;
+ __z ^= __lshift<__t>(__z) & __c;
+ return __z ^ __rshift<__l>(__z);
+ }
+
_LIBCPP_HIDE_FROM_ABI void discard(unsigned long long __z) {
for (; __z; --__z)
operator()();
@@ -225,24 +224,6 @@ public:
const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, _Bp, _Tp, _Cp, _Lp, _Fp>& __x,
const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, _Bp, _Tp, _Cp, _Lp, _Fp>& __y);
- template <class _UInt,
- size_t _Wp,
- size_t _Np,
- size_t _Mp,
- size_t _Rp,
- _UInt _Ap,
- size_t _Up,
- _UInt _Dp,
- size_t _Sp,
- _UInt _Bp,
- size_t _Tp,
- _UInt _Cp,
- size_t _Lp,
- _UInt _Fp>
- friend bool operator!=(
- const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, _Bp, _Tp, _Cp, _Lp, _Fp>& __x,
- const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, _Bp, _Tp, _Cp, _Lp, _Fp>& __y);
-
template <class _CharT,
class _Traits,
class _UInt,
@@ -285,9 +266,38 @@ public:
private:
template <class _Sseq>
- _LIBCPP_HIDE_FROM_ABI void __seed(_Sseq& __q, integral_constant<unsigned, 1>);
+ _LIBCPP_HIDE_FROM_ABI void __seed(_Sseq& __q, integral_constant<unsigned, 1>) {
+ const unsigned __k = 1;
+ uint32_t __ar[__n * __k];
+ __q.generate(__ar, __ar + __n * __k);
+ for (size_t __i = 0; __i < __n; ++__i)
+ __x_[__i] = static_cast<result_type>(__ar[__i] & _Max);
+ const result_type __mask = __r == _Dt ? result_type(~0) : (result_type(1) << __r) - result_type(1);
+ __i_ = 0;
+ if ((__x_[0] & ~__mask) == 0) {
+ for (size_t __i = 1; __i < __n; ++__i)
+ if (__x_[__i] != 0)
+ return;
+ __x_[0] = result_type(1) << (__w - 1);
+ }
+ }
+
template <class _Sseq>
- _LIBCPP_HIDE_FROM_ABI void __seed(_Sseq& __q, integral_constant<unsigned, 2>);
+ _LIBCPP_HIDE_FROM_ABI void __seed(_Sseq& __q, integral_constant<unsigned, 2>) {
+ const unsigned __k = 2;
+ uint32_t __ar[__n * __k];
+ __q.generate(__ar, __ar + __n * __k);
+ for (size_t __i = 0; __i < __n; ++__i)
+ __x_[__i] = static_cast<result_type>((__ar[2 * __i] + ((uint64_t)__ar[2 * __i + 1] << 32)) & _Max);
+ const result_type __mask = __r == _Dt ? result_type(~0) : (result_type(1) << __r) - result_type(1);
+ __i_ = 0;
+ if ((__x_[0] & ~__mask) == 0) {
+ for (size_t __i = 1; __i < __n; ++__i)
+ if (__x_[__i] != 0)
+ return;
+ __x_[0] = result_type(1) << (__w - 1);
+ }
+ }
template <size_t __count,
__enable_if_t<__count< __w, int> = 0> _LIBCPP_HIDE_FROM_ABI static result_type __lshift(result_type __x) {
@@ -310,120 +320,6 @@ private:
}
};
-template <class _UIntType,
- size_t __w,
- size_t __n,
- size_t __m,
- size_t __r,
- _UIntType __a,
- size_t __u,
- _UIntType __d,
- size_t __s,
- _UIntType __b,
- size_t __t,
- _UIntType __c,
- size_t __l,
- _UIntType __f>
-void mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::seed(
- result_type __sd) _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK { // __w >= 2
- __x_[0] = __sd & _Max;
- for (size_t __i = 1; __i < __n; ++__i)
- __x_[__i] = (__f * (__x_[__i - 1] ^ __rshift<__w - 2>(__x_[__i - 1])) + __i) & _Max;
- __i_ = 0;
-}
-
-template <class _UIntType,
- size_t __w,
- size_t __n,
- size_t __m,
- size_t __r,
- _UIntType __a,
- size_t __u,
- _UIntType __d,
- size_t __s,
- _UIntType __b,
- size_t __t,
- _UIntType __c,
- size_t __l,
- _UIntType __f>
-template <class _Sseq>
-void mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::__seed(
- _Sseq& __q, integral_constant<unsigned, 1>) {
- const unsigned __k = 1;
- uint32_t __ar[__n * __k];
- __q.generate(__ar, __ar + __n * __k);
- for (size_t __i = 0; __i < __n; ++__i)
- __x_[__i] = static_cast<result_type>(__ar[__i] & _Max);
- const result_type __mask = __r == _Dt ? result_type(~0) : (result_type(1) << __r) - result_type(1);
- __i_ = 0;
- if ((__x_[0] & ~__mask) == 0) {
- for (size_t __i = 1; __i < __n; ++__i)
- if (__x_[__i] != 0)
- return;
- __x_[0] = result_type(1) << (__w - 1);
- }
-}
-
-template <class _UIntType,
- size_t __w,
- size_t __n,
- size_t __m,
- size_t __r,
- _UIntType __a,
- size_t __u,
- _UIntType __d,
- size_t __s,
- _UIntType __b,
- size_t __t,
- _UIntType __c,
- size_t __l,
- _UIntType __f>
-template <class _Sseq>
-void mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::__seed(
- _Sseq& __q, integral_constant<unsigned, 2>) {
- const unsigned __k = 2;
- uint32_t __ar[__n * __k];
- __q.generate(__ar, __ar + __n * __k);
- for (size_t __i = 0; __i < __n; ++__i)
- __x_[__i] = static_cast<result_type>((__ar[2 * __i] + ((uint64_t)__ar[2 * __i + 1] << 32)) & _Max);
- const result_type __mask = __r == _Dt ? result_type(~0) : (result_type(1) << __r) - result_type(1);
- __i_ = 0;
- if ((__x_[0] & ~__mask) == 0) {
- for (size_t __i = 1; __i < __n; ++__i)
- if (__x_[__i] != 0)
- return;
- __x_[0] = result_type(1) << (__w - 1);
- }
-}
-
-template <class _UIntType,
- size_t __w,
- size_t __n,
- size_t __m,
- size_t __r,
- _UIntType __a,
- size_t __u,
- _UIntType __d,
- size_t __s,
- _UIntType __b,
- size_t __t,
- _UIntType __c,
- size_t __l,
- _UIntType __f>
-_UIntType
-mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::operator()() {
- const size_t __j = (__i_ + 1) % __n;
- const result_type __mask = __r == _Dt ? result_type(~0) : (result_type(1) << __r) - result_type(1);
- const result_type __yp = (__x_[__i_] & ~__mask) | (__x_[__j] & __mask);
- const size_t __k = (__i_ + __m) % __n;
- __x_[__i_] = __x_[__k] ^ __rshift<1>(__yp) ^ (__a * (__yp & 1));
- result_type __z = __x_[__i_] ^ (__rshift<__u>(__x_[__i_]) & __d);
- __i_ = __j;
- __z ^= __lshift<__s>(__z) & __b;
- __z ^= __lshift<__t>(__z) & __c;
- return __z ^ __rshift<__l>(__z);
-}
-
template <class _UInt,
size_t _Wp,
size_t _Np,
diff --git a/libcxx/include/__ranges/iota_view.h b/libcxx/include/__ranges/iota_view.h
index 22adc22..f66f3f9 100644
--- a/libcxx/include/__ranges/iota_view.h
+++ b/libcxx/include/__ranges/iota_view.h
@@ -58,11 +58,17 @@ struct __get_wider_signed {
return type_identity<int>{};
else if constexpr (sizeof(_Int) < sizeof(long))
return type_identity<long>{};
- else
+ else if constexpr (sizeof(_Int) < sizeof(long long))
return type_identity<long long>{};
-
- static_assert(
- sizeof(_Int) <= sizeof(long long), "Found integer-like type that is bigger than largest integer like type.");
+# if _LIBCPP_HAS_INT128
+ else if constexpr (sizeof(_Int) <= sizeof(__int128))
+ return type_identity<__int128>{};
+# else
+ else if constexpr (sizeof(_Int) <= sizeof(long long))
+ return type_identity<long long>{};
+# endif
+ else
+ static_assert(false, "Found integer-like type that is bigger than the largest integer like type.");
}
using type = typename decltype(__call())::type;
diff --git a/libcxx/include/__split_buffer b/libcxx/include/__split_buffer
index 15368a3..1e05e4d 100644
--- a/libcxx/include/__split_buffer
+++ b/libcxx/include/__split_buffer
@@ -30,7 +30,6 @@
#include <__type_traits/integral_constant.h>
#include <__type_traits/is_nothrow_assignable.h>
#include <__type_traits/is_nothrow_constructible.h>
-#include <__type_traits/is_replaceable.h>
#include <__type_traits/is_swappable.h>
#include <__type_traits/is_trivially_destructible.h>
#include <__type_traits/is_trivially_relocatable.h>
@@ -484,10 +483,6 @@ public:
__libcpp_is_trivially_relocatable<pointer>::value && __libcpp_is_trivially_relocatable<allocator_type>::value,
__split_buffer,
void>;
- using __replaceable _LIBCPP_NODEBUG =
- __conditional_t<__is_replaceable_v<pointer> && __container_allocator_is_replaceable<__alloc_traits>::value,
- __split_buffer,
- void>;
__split_buffer(const __split_buffer&) = delete;
__split_buffer& operator=(const __split_buffer&) = delete;
diff --git a/libcxx/include/__support/xlocale/__strtonum_fallback.h b/libcxx/include/__support/xlocale/__strtonum_fallback.h
index 5275aea..90bd59d 100644
--- a/libcxx/include/__support/xlocale/__strtonum_fallback.h
+++ b/libcxx/include/__support/xlocale/__strtonum_fallback.h
@@ -34,12 +34,4 @@ inline _LIBCPP_HIDE_FROM_ABI long double strtold_l(const char* __nptr, char** __
return ::strtold(__nptr, __endptr);
}
-inline _LIBCPP_HIDE_FROM_ABI long long strtoll_l(const char* __nptr, char** __endptr, int __base, locale_t) {
- return ::strtoll(__nptr, __endptr, __base);
-}
-
-inline _LIBCPP_HIDE_FROM_ABI unsigned long long strtoull_l(const char* __nptr, char** __endptr, int __base, locale_t) {
- return ::strtoull(__nptr, __endptr, __base);
-}
-
#endif // _LIBCPP___SUPPORT_XLOCALE_STRTONUM_FALLBACK_H
diff --git a/libcxx/include/__system_error/error_category.h b/libcxx/include/__system_error/error_category.h
index 191f4d8..7f7c735 100644
--- a/libcxx/include/__system_error/error_category.h
+++ b/libcxx/include/__system_error/error_category.h
@@ -37,11 +37,11 @@ public:
error_category(const error_category&) = delete;
error_category& operator=(const error_category&) = delete;
- virtual const char* name() const _NOEXCEPT = 0;
- virtual error_condition default_error_condition(int __ev) const _NOEXCEPT;
- virtual bool equivalent(int __code, const error_condition& __condition) const _NOEXCEPT;
- virtual bool equivalent(const error_code& __code, int __condition) const _NOEXCEPT;
- virtual string message(int __ev) const = 0;
+ [[__nodiscard__]] virtual const char* name() const _NOEXCEPT = 0;
+ [[__nodiscard__]] virtual error_condition default_error_condition(int __ev) const _NOEXCEPT;
+ [[__nodiscard__]] virtual bool equivalent(int __code, const error_condition& __condition) const _NOEXCEPT;
+ [[__nodiscard__]] virtual bool equivalent(const error_code& __code, int __condition) const _NOEXCEPT;
+ [[__nodiscard__]] virtual string message(int __ev) const = 0;
_LIBCPP_HIDE_FROM_ABI bool operator==(const error_category& __rhs) const _NOEXCEPT { return this == &__rhs; }
@@ -67,8 +67,8 @@ public:
string message(int __ev) const override;
};
-[[__gnu__::__const__]] _LIBCPP_EXPORTED_FROM_ABI const error_category& generic_category() _NOEXCEPT;
-[[__gnu__::__const__]] _LIBCPP_EXPORTED_FROM_ABI const error_category& system_category() _NOEXCEPT;
+[[__gnu__::__const__]] [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI const error_category& generic_category() _NOEXCEPT;
+[[__gnu__::__const__]] [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI const error_category& system_category() _NOEXCEPT;
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__system_error/error_code.h b/libcxx/include/__system_error/error_code.h
index f6ea40d..e904376 100644
--- a/libcxx/include/__system_error/error_code.h
+++ b/libcxx/include/__system_error/error_code.h
@@ -71,20 +71,20 @@ public:
__cat_ = &system_category();
}
- _LIBCPP_HIDE_FROM_ABI int value() const _NOEXCEPT { return __val_; }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI int value() const _NOEXCEPT { return __val_; }
- _LIBCPP_HIDE_FROM_ABI const error_category& category() const _NOEXCEPT { return *__cat_; }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const error_category& category() const _NOEXCEPT { return *__cat_; }
- _LIBCPP_HIDE_FROM_ABI error_condition default_error_condition() const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI error_condition default_error_condition() const _NOEXCEPT {
return __cat_->default_error_condition(__val_);
}
- string message() const;
+ [[__nodiscard__]] string message() const;
_LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return __val_ != 0; }
};
-inline _LIBCPP_HIDE_FROM_ABI error_code make_error_code(errc __e) _NOEXCEPT {
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI error_code make_error_code(errc __e) _NOEXCEPT {
return error_code(static_cast<int>(__e), generic_category());
}
diff --git a/libcxx/include/__system_error/error_condition.h b/libcxx/include/__system_error/error_condition.h
index 34819f4..be7deab 100644
--- a/libcxx/include/__system_error/error_condition.h
+++ b/libcxx/include/__system_error/error_condition.h
@@ -80,15 +80,15 @@ public:
__cat_ = &generic_category();
}
- _LIBCPP_HIDE_FROM_ABI int value() const _NOEXCEPT { return __val_; }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI int value() const _NOEXCEPT { return __val_; }
- _LIBCPP_HIDE_FROM_ABI const error_category& category() const _NOEXCEPT { return *__cat_; }
- string message() const;
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const error_category& category() const _NOEXCEPT { return *__cat_; }
+ [[__nodiscard__]] string message() const;
_LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return __val_ != 0; }
};
-inline _LIBCPP_HIDE_FROM_ABI error_condition make_error_condition(errc __e) _NOEXCEPT {
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI error_condition make_error_condition(errc __e) _NOEXCEPT {
return error_condition(static_cast<int>(__e), generic_category());
}
diff --git a/libcxx/include/__system_error/system_error.h b/libcxx/include/__system_error/system_error.h
index 36ccf94..74427d8 100644
--- a/libcxx/include/__system_error/system_error.h
+++ b/libcxx/include/__system_error/system_error.h
@@ -36,7 +36,7 @@ public:
_LIBCPP_HIDE_FROM_ABI system_error(const system_error&) _NOEXCEPT = default;
~system_error() _NOEXCEPT override;
- _LIBCPP_HIDE_FROM_ABI const error_code& code() const _NOEXCEPT { return __ec_; }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const error_code& code() const _NOEXCEPT { return __ec_; }
};
// __ev is expected to be an error in the generic_category domain (e.g. from
diff --git a/libcxx/include/__thread/thread.h b/libcxx/include/__thread/thread.h
index a3b672b..561f092 100644
--- a/libcxx/include/__thread/thread.h
+++ b/libcxx/include/__thread/thread.h
@@ -242,13 +242,13 @@ public:
_LIBCPP_HIDE_FROM_ABI void swap(thread& __t) _NOEXCEPT { std::swap(__t_, __t.__t_); }
- _LIBCPP_HIDE_FROM_ABI bool joinable() const _NOEXCEPT { return !__libcpp_thread_isnull(&__t_); }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool joinable() const _NOEXCEPT { return !__libcpp_thread_isnull(&__t_); }
void join();
void detach();
- _LIBCPP_HIDE_FROM_ABI id get_id() const _NOEXCEPT { return __libcpp_thread_get_id(&__t_); }
- _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() _NOEXCEPT { return __t_; }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI id get_id() const _NOEXCEPT { return __libcpp_thread_get_id(&__t_); }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() _NOEXCEPT { return __t_; }
- static unsigned hardware_concurrency() _NOEXCEPT;
+ [[__nodiscard__]] static unsigned hardware_concurrency() _NOEXCEPT;
};
inline _LIBCPP_HIDE_FROM_ABI void swap(thread& __x, thread& __y) _NOEXCEPT { __x.swap(__y); }
diff --git a/libcxx/include/__tree b/libcxx/include/__tree
index 6947969..ceae22b 100644
--- a/libcxx/include/__tree
+++ b/libcxx/include/__tree
@@ -887,6 +887,18 @@ public:
}
_LIBCPP_HIDE_FROM_ABI __tree(const __tree& __t);
+
+ _LIBCPP_HIDE_FROM_ABI __tree(const __tree& __other, const allocator_type& __alloc)
+ : __begin_node_(__end_node()), __node_alloc_(__alloc), __size_(0), __value_comp_(__other.value_comp()) {
+ if (__other.size() == 0)
+ return;
+
+ *__root_ptr() = static_cast<__node_base_pointer>(__copy_construct_tree(__other.__root()));
+ __root()->__parent_ = __end_node();
+ __begin_node_ = static_cast<__end_node_pointer>(std::__tree_min(__end_node()->__left_));
+ __size_ = __other.size();
+ }
+
_LIBCPP_HIDE_FROM_ABI __tree& operator=(const __tree& __t);
template <class _ForwardIterator>
_LIBCPP_HIDE_FROM_ABI void __assign_unique(_ForwardIterator __first, _ForwardIterator __last);
@@ -995,27 +1007,6 @@ public:
std::forward<_Args>(__args)...);
}
- template <class _ValueT = _Tp, __enable_if_t<__is_tree_value_type_v<_ValueT>, int> = 0>
- _LIBCPP_HIDE_FROM_ABI void
- __insert_unique_from_orphaned_node(const_iterator __p, __get_node_value_type_t<_Tp>&& __value) {
- __emplace_hint_unique(__p, const_cast<key_type&&>(__value.first), std::move(__value.second));
- }
-
- template <class _ValueT = _Tp, __enable_if_t<!__is_tree_value_type_v<_ValueT>, int> = 0>
- _LIBCPP_HIDE_FROM_ABI void __insert_unique_from_orphaned_node(const_iterator __p, _Tp&& __value) {
- __emplace_hint_unique(__p, std::move(__value));
- }
-
- template <class _ValueT = _Tp, __enable_if_t<__is_tree_value_type_v<_ValueT>, int> = 0>
- _LIBCPP_HIDE_FROM_ABI void __insert_multi_from_orphaned_node(const_iterator __p, value_type&& __value) {
- __emplace_hint_multi(__p, const_cast<key_type&&>(__value.first), std::move(__value.second));
- }
-
- template <class _ValueT = _Tp, __enable_if_t<!__is_tree_value_type_v<_ValueT>, int> = 0>
- _LIBCPP_HIDE_FROM_ABI void __insert_multi_from_orphaned_node(const_iterator __p, _Tp&& __value) {
- __emplace_hint_multi(__p, std::move(__value));
- }
-
template <class _InIter, class _Sent>
_LIBCPP_HIDE_FROM_ABI void __insert_range_multi(_InIter __first, _Sent __last) {
if (__first == __last)
@@ -1388,19 +1379,19 @@ private:
// copy the exact structure 1:1. Since this is for copy construction _only_ we know that we get a correct tree. If we
// didn't get a correct tree, the invariants of __tree are broken and we have a much bigger problem than an improperly
// balanced tree.
+ template <class _NodeConstructor>
#ifdef _LIBCPP_COMPILER_CLANG_BASED // FIXME: GCC complains about not being able to always_inline a recursive function
_LIBCPP_HIDE_FROM_ABI
#endif
- __node_pointer
- __copy_construct_tree(__node_pointer __src) {
+ __node_pointer __construct_from_tree(__node_pointer __src, _NodeConstructor __construct) {
if (!__src)
return nullptr;
- __node_holder __new_node = __construct_node(__src->__get_value());
+ __node_holder __new_node = __construct(__src->__get_value());
unique_ptr<__node, __tree_deleter> __left(
- __copy_construct_tree(static_cast<__node_pointer>(__src->__left_)), __node_alloc_);
- __node_pointer __right = __copy_construct_tree(static_cast<__node_pointer>(__src->__right_));
+ __construct_from_tree(static_cast<__node_pointer>(__src->__left_), __construct), __node_alloc_);
+ __node_pointer __right = __construct_from_tree(static_cast<__node_pointer>(__src->__right_), __construct);
__node_pointer __new_node_ptr = __new_node.release();
@@ -1414,46 +1405,85 @@ private:
return __new_node_ptr;
}
+ _LIBCPP_HIDE_FROM_ABI __node_pointer __copy_construct_tree(__node_pointer __src) {
+ return __construct_from_tree(__src, [this](const value_type& __val) { return __construct_node(__val); });
+ }
+
+ template <class _ValueT = _Tp, __enable_if_t<__is_tree_value_type_v<_ValueT>, int> = 0>
+ _LIBCPP_HIDE_FROM_ABI __node_pointer __move_construct_tree(__node_pointer __src) {
+ return __construct_from_tree(__src, [this](value_type& __val) {
+ return __construct_node(const_cast<key_type&&>(__val.first), std::move(__val.second));
+ });
+ }
+
+ template <class _ValueT = _Tp, __enable_if_t<!__is_tree_value_type_v<_ValueT>, int> = 0>
+ _LIBCPP_HIDE_FROM_ABI __node_pointer __move_construct_tree(__node_pointer __src) {
+ return __construct_from_tree(__src, [this](value_type& __val) { return __construct_node(std::move(__val)); });
+ }
+
+ template <class _Assignment, class _ConstructionAlg>
// This copy assignment will always produce a correct red-black-tree assuming the incoming tree is correct, since our
// own tree is a red-black-tree and the incoming tree is a red-black-tree. The invariants of a red-black-tree are
// temporarily not met until all of the incoming red-black tree is copied.
#ifdef _LIBCPP_COMPILER_CLANG_BASED // FIXME: GCC complains about not being able to always_inline a recursive function
_LIBCPP_HIDE_FROM_ABI
#endif
- __node_pointer
- __copy_assign_tree(__node_pointer __dest, __node_pointer __src) {
+ __node_pointer __assign_from_tree(
+ __node_pointer __dest, __node_pointer __src, _Assignment __assign, _ConstructionAlg __construct_subtree) {
if (!__src) {
destroy(__dest);
return nullptr;
}
- __assign_value(__dest->__get_value(), __src->__get_value());
+ __assign(__dest->__get_value(), __src->__get_value());
__dest->__is_black_ = __src->__is_black_;
// If we already have a left node in the destination tree, reuse it and copy-assign recursively
if (__dest->__left_) {
- __dest->__left_ = static_cast<__node_base_pointer>(__copy_assign_tree(
- static_cast<__node_pointer>(__dest->__left_), static_cast<__node_pointer>(__src->__left_)));
+ __dest->__left_ = static_cast<__node_base_pointer>(__assign_from_tree(
+ static_cast<__node_pointer>(__dest->__left_),
+ static_cast<__node_pointer>(__src->__left_),
+ __assign,
+ __construct_subtree));
// Otherwise, we must create new nodes; copy-construct from here on
} else if (__src->__left_) {
- auto __new_left = __copy_construct_tree(static_cast<__node_pointer>(__src->__left_));
+ auto __new_left = __construct_subtree(static_cast<__node_pointer>(__src->__left_));
__dest->__left_ = static_cast<__node_base_pointer>(__new_left);
__new_left->__parent_ = static_cast<__end_node_pointer>(__dest);
}
// Identical to the left case above, just for the right nodes
if (__dest->__right_) {
- __dest->__right_ = static_cast<__node_base_pointer>(__copy_assign_tree(
- static_cast<__node_pointer>(__dest->__right_), static_cast<__node_pointer>(__src->__right_)));
+ __dest->__right_ = static_cast<__node_base_pointer>(__assign_from_tree(
+ static_cast<__node_pointer>(__dest->__right_),
+ static_cast<__node_pointer>(__src->__right_),
+ __assign,
+ __construct_subtree));
} else if (__src->__right_) {
- auto __new_right = __copy_construct_tree(static_cast<__node_pointer>(__src->__right_));
+ auto __new_right = __construct_subtree(static_cast<__node_pointer>(__src->__right_));
__dest->__right_ = static_cast<__node_base_pointer>(__new_right);
__new_right->__parent_ = static_cast<__end_node_pointer>(__dest);
}
return __dest;
}
+
+ _LIBCPP_HIDE_FROM_ABI __node_pointer __copy_assign_tree(__node_pointer __dest, __node_pointer __src) {
+ return __assign_from_tree(
+ __dest,
+ __src,
+ [](value_type& __lhs, const value_type& __rhs) { __assign_value(__lhs, __rhs); },
+ [this](__node_pointer __nd) { return __copy_construct_tree(__nd); });
+ }
+
+ _LIBCPP_HIDE_FROM_ABI __node_pointer __move_assign_tree(__node_pointer __dest, __node_pointer __src) {
+ return __assign_from_tree(
+ __dest,
+ __src,
+ [](value_type& __lhs, value_type& __rhs) { __assign_value(__lhs, std::move(__rhs)); },
+ [this](__node_pointer __nd) { return __move_construct_tree(__nd); });
+ }
};
// Precondition: __size_ != 0
@@ -1594,21 +1624,26 @@ __tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t) _NOEXCEPT_(
template <class _Tp, class _Compare, class _Allocator>
__tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t, const allocator_type& __a)
- : __node_alloc_(__node_allocator(__a)), __size_(0), __value_comp_(std::move(__t.value_comp())) {
+ : __begin_node_(__end_node()),
+ __node_alloc_(__node_allocator(__a)),
+ __size_(0),
+ __value_comp_(std::move(__t.value_comp())) {
+ if (__t.size() == 0)
+ return;
if (__a == __t.__alloc()) {
- if (__t.__size_ == 0)
- __begin_node_ = __end_node();
- else {
- __begin_node_ = __t.__begin_node_;
- __end_node()->__left_ = __t.__end_node()->__left_;
- __end_node()->__left_->__parent_ = static_cast<__end_node_pointer>(__end_node());
- __size_ = __t.__size_;
- __t.__begin_node_ = __t.__end_node();
- __t.__end_node()->__left_ = nullptr;
- __t.__size_ = 0;
- }
+ __begin_node_ = __t.__begin_node_;
+ __end_node()->__left_ = __t.__end_node()->__left_;
+ __end_node()->__left_->__parent_ = static_cast<__end_node_pointer>(__end_node());
+ __size_ = __t.__size_;
+ __t.__begin_node_ = __t.__end_node();
+ __t.__end_node()->__left_ = nullptr;
+ __t.__size_ = 0;
} else {
- __begin_node_ = __end_node();
+ *__root_ptr() = static_cast<__node_base_pointer>(__move_construct_tree(__t.__root()));
+ __root()->__parent_ = __end_node();
+ __begin_node_ = static_cast<__end_node_pointer>(std::__tree_min(__end_node()->__left_));
+ __size_ = __t.size();
+ __t.clear(); // Ensure that __t is in a valid state after moving out the keys
}
}
@@ -1633,22 +1668,21 @@ void __tree<_Tp, _Compare, _Allocator>::__move_assign(__tree& __t, true_type)
template <class _Tp, class _Compare, class _Allocator>
void __tree<_Tp, _Compare, _Allocator>::__move_assign(__tree& __t, false_type) {
- if (__node_alloc() == __t.__node_alloc())
+ if (__node_alloc() == __t.__node_alloc()) {
__move_assign(__t, true_type());
- else {
- value_comp() = std::move(__t.value_comp());
- const_iterator __e = end();
+ } else {
+ value_comp() = std::move(__t.value_comp());
if (__size_ != 0) {
- _DetachedTreeCache __cache(this);
- while (__cache.__get() != nullptr && __t.__size_ != 0) {
- __assign_value(__cache.__get()->__get_value(), std::move(__t.remove(__t.begin())->__get_value()));
- __node_insert_multi(__cache.__get());
- __cache.__advance();
- }
- }
- while (__t.__size_ != 0) {
- __insert_multi_from_orphaned_node(__e, std::move(__t.remove(__t.begin())->__get_value()));
+ *__root_ptr() = static_cast<__node_base_pointer>(__move_assign_tree(__root(), __t.__root()));
+ } else {
+ *__root_ptr() = static_cast<__node_base_pointer>(__move_construct_tree(__t.__root()));
+ if (__root())
+ __root()->__parent_ = __end_node();
}
+ __begin_node_ =
+ __end_node()->__left_ ? static_cast<__end_node_pointer>(std::__tree_min(__end_node()->__left_)) : __end_node();
+ __size_ = __t.size();
+ __t.clear(); // Ensure that __t is in a valid state after moving out the keys
}
}
diff --git a/libcxx/include/__type_traits/aligned_storage.h b/libcxx/include/__type_traits/aligned_storage.h
index 5c2208a..33c0368 100644
--- a/libcxx/include/__type_traits/aligned_storage.h
+++ b/libcxx/include/__type_traits/aligned_storage.h
@@ -11,8 +11,6 @@
#include <__config>
#include <__cstddef/size_t.h>
-#include <__type_traits/integral_constant.h>
-#include <__type_traits/type_list.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -21,10 +19,10 @@
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _Tp>
-struct __align_type {
- static const size_t value = _LIBCPP_PREFERRED_ALIGNOF(_Tp);
- typedef _Tp type;
-};
+struct _ALIGNAS(_LIBCPP_PREFERRED_ALIGNOF(_Tp)) _AlignedAsT {};
+
+template <class... _Args>
+struct __max_align_impl : _AlignedAsT<_Args>... {};
struct __struct_double {
long double __lx;
@@ -33,41 +31,16 @@ struct __struct_double4 {
double __lx[4];
};
-using __all_types _LIBCPP_NODEBUG =
- __type_list<__align_type<unsigned char>,
- __align_type<unsigned short>,
- __align_type<unsigned int>,
- __align_type<unsigned long>,
- __align_type<unsigned long long>,
- __align_type<double>,
- __align_type<long double>,
- __align_type<__struct_double>,
- __align_type<__struct_double4>,
- __align_type<int*> >;
-
-template <class _TL, size_t _Len>
-struct __find_max_align;
-
-template <class _Head, size_t _Len>
-struct __find_max_align<__type_list<_Head>, _Len> : public integral_constant<size_t, _Head::value> {};
-
-template <size_t _Len, size_t _A1, size_t _A2>
-struct __select_align {
-private:
- static const size_t __min = _A2 < _A1 ? _A2 : _A1;
- static const size_t __max = _A1 < _A2 ? _A2 : _A1;
-
-public:
- static const size_t value = _Len < __max ? __min : __max;
-};
+inline const size_t __aligned_storage_max_align =
+ _LIBCPP_ALIGNOF(__max_align_impl<unsigned long long, double, long double, __struct_double, __struct_double4, int*>);
-template <class _Head, class... _Tail, size_t _Len>
-struct __find_max_align<__type_list<_Head, _Tail...>, _Len>
- : public integral_constant<
- size_t,
- __select_align<_Len, _Head::value, __find_max_align<__type_list<_Tail...>, _Len>::value>::value> {};
+template <size_t _Len>
+inline const size_t __aligned_storage_alignment =
+ _Len > __aligned_storage_max_align
+ ? __aligned_storage_max_align
+ : size_t(1) << ((sizeof(size_t) * __CHAR_BIT__) - __builtin_clzg(_Len) - 1);
-template <size_t _Len, size_t _Align = __find_max_align<__all_types, _Len>::value>
+template <size_t _Len, size_t _Align = __aligned_storage_alignment<_Len> >
struct _LIBCPP_DEPRECATED_IN_CXX23 _LIBCPP_NO_SPECIALIZATIONS aligned_storage {
union _ALIGNAS(_Align) type {
unsigned char __data[(_Len + _Align - 1) / _Align * _Align];
@@ -77,7 +50,7 @@ struct _LIBCPP_DEPRECATED_IN_CXX23 _LIBCPP_NO_SPECIALIZATIONS aligned_storage {
#if _LIBCPP_STD_VER >= 14
_LIBCPP_SUPPRESS_DEPRECATED_PUSH
-template <size_t _Len, size_t _Align = __find_max_align<__all_types, _Len>::value>
+template <size_t _Len, size_t _Align = __aligned_storage_alignment<_Len> >
using aligned_storage_t _LIBCPP_DEPRECATED_IN_CXX23 = typename aligned_storage<_Len, _Align>::type;
_LIBCPP_SUPPRESS_DEPRECATED_POP
diff --git a/libcxx/include/__type_traits/is_array.h b/libcxx/include/__type_traits/is_array.h
index e734d1a..62dd378 100644
--- a/libcxx/include/__type_traits/is_array.h
+++ b/libcxx/include/__type_traits/is_array.h
@@ -26,6 +26,32 @@ template <class _Tp>
_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_array_v = __is_array(_Tp);
#endif
+template <class _Tp>
+inline const bool __is_bounded_array_v = __is_bounded_array(_Tp);
+
+#if _LIBCPP_STD_VER >= 20
+
+template <class _Tp>
+struct _LIBCPP_NO_SPECIALIZATIONS is_bounded_array : bool_constant<__is_bounded_array(_Tp)> {};
+
+template <class _Tp>
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_bounded_array_v = __is_bounded_array(_Tp);
+
+#endif
+
+template <class _Tp>
+inline const bool __is_unbounded_array_v = __is_unbounded_array(_Tp);
+
+#if _LIBCPP_STD_VER >= 20
+
+template <class _Tp>
+struct _LIBCPP_NO_SPECIALIZATIONS is_unbounded_array : bool_constant<__is_unbounded_array(_Tp)> {};
+
+template <class _Tp>
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_unbounded_array_v = __is_unbounded_array(_Tp);
+
+#endif
+
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___TYPE_TRAITS_IS_ARRAY_H
diff --git a/libcxx/include/__type_traits/is_bounded_array.h b/libcxx/include/__type_traits/is_bounded_array.h
deleted file mode 100644
index 8a41e07..0000000
--- a/libcxx/include/__type_traits/is_bounded_array.h
+++ /dev/null
@@ -1,36 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef _LIBCPP___TYPE_TRAITS_IS_BOUNDED_ARRAY_H
-#define _LIBCPP___TYPE_TRAITS_IS_BOUNDED_ARRAY_H
-
-#include <__config>
-#include <__type_traits/integral_constant.h>
-
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-# pragma GCC system_header
-#endif
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-template <class _Tp>
-inline const bool __is_bounded_array_v = __is_bounded_array(_Tp);
-
-#if _LIBCPP_STD_VER >= 20
-
-template <class _Tp>
-struct _LIBCPP_NO_SPECIALIZATIONS is_bounded_array : bool_constant<__is_bounded_array(_Tp)> {};
-
-template <class _Tp>
-_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_bounded_array_v = __is_bounded_array(_Tp);
-
-#endif
-
-_LIBCPP_END_NAMESPACE_STD
-
-#endif // _LIBCPP___TYPE_TRAITS_IS_BOUNDED_ARRAY_H
diff --git a/libcxx/include/__type_traits/is_floating_point.h b/libcxx/include/__type_traits/is_floating_point.h
index b87363f..586fce6 100644
--- a/libcxx/include/__type_traits/is_floating_point.h
+++ b/libcxx/include/__type_traits/is_floating_point.h
@@ -20,18 +20,19 @@
_LIBCPP_BEGIN_NAMESPACE_STD
// clang-format off
-template <class _Tp> struct __libcpp_is_floating_point : false_type {};
-template <> struct __libcpp_is_floating_point<float> : true_type {};
-template <> struct __libcpp_is_floating_point<double> : true_type {};
-template <> struct __libcpp_is_floating_point<long double> : true_type {};
+template <class _Tp> inline const bool __is_floating_point_impl = false;
+template <> inline const bool __is_floating_point_impl<float> = true;
+template <> inline const bool __is_floating_point_impl<double> = true;
+template <> inline const bool __is_floating_point_impl<long double> = true;
// clang-format on
template <class _Tp>
-struct _LIBCPP_NO_SPECIALIZATIONS is_floating_point : __libcpp_is_floating_point<__remove_cv_t<_Tp> > {};
+struct _LIBCPP_NO_SPECIALIZATIONS is_floating_point
+ : integral_constant<bool, __is_floating_point_impl<__remove_cv_t<_Tp> > > {};
#if _LIBCPP_STD_VER >= 17
template <class _Tp>
-_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_floating_point_v = is_floating_point<_Tp>::value;
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_floating_point_v = __is_floating_point_impl<__remove_cv_t<_Tp>>;
#endif
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__type_traits/is_replaceable.h b/libcxx/include/__type_traits/is_replaceable.h
deleted file mode 100644
index e1d17c0..0000000
--- a/libcxx/include/__type_traits/is_replaceable.h
+++ /dev/null
@@ -1,61 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef _LIBCPP___TYPE_TRAITS_IS_REPLACEABLE_H
-#define _LIBCPP___TYPE_TRAITS_IS_REPLACEABLE_H
-
-#include <__config>
-#include <__type_traits/enable_if.h>
-#include <__type_traits/integral_constant.h>
-#include <__type_traits/is_same.h>
-#include <__type_traits/is_trivially_copyable.h>
-
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-# pragma GCC system_header
-#endif
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-// A type is replaceable if, with `x` and `y` being different objects, `x = std::move(y)` is equivalent to:
-//
-// std::destroy_at(&x)
-// std::construct_at(&x, std::move(y))
-//
-// This allows turning a move-assignment into a sequence of destroy + move-construct, which
-// is often more efficient. This is especially relevant when the move-construct is in fact
-// part of a trivial relocation from somewhere else, in which case there is a huge win.
-//
-// Note that this requires language support in order to be really effective, but we
-// currently emulate the base template with something very conservative.
-template <class _Tp, class = void>
-struct __is_replaceable : is_trivially_copyable<_Tp> {};
-
-template <class _Tp>
-struct __is_replaceable<_Tp, __enable_if_t<is_same<_Tp, typename _Tp::__replaceable>::value> > : true_type {};
-
-template <class _Tp>
-inline const bool __is_replaceable_v = __is_replaceable<_Tp>::value;
-
-// Determines whether an allocator member of a container is replaceable.
-//
-// First, we require the allocator type to be considered replaceable. If not, then something fishy might be
-// happening. Assuming the allocator type is replaceable, we conclude replaceability of the allocator as a
-// member of the container if the allocator always compares equal (in which case propagation doesn't matter),
-// or if the allocator always propagates on assignment, which is required in order for move construction and
-// assignment to be equivalent.
-template <class _AllocatorTraits>
-struct __container_allocator_is_replaceable
- : integral_constant<bool,
- __is_replaceable_v<typename _AllocatorTraits::allocator_type> &&
- (_AllocatorTraits::is_always_equal::value ||
- (_AllocatorTraits::propagate_on_container_move_assignment::value &&
- _AllocatorTraits::propagate_on_container_copy_assignment::value))> {};
-
-_LIBCPP_END_NAMESPACE_STD
-
-#endif // _LIBCPP___TYPE_TRAITS_IS_REPLACEABLE_H
diff --git a/libcxx/include/__type_traits/is_unbounded_array.h b/libcxx/include/__type_traits/is_unbounded_array.h
deleted file mode 100644
index e14809e..0000000
--- a/libcxx/include/__type_traits/is_unbounded_array.h
+++ /dev/null
@@ -1,38 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef _LIBCPP___TYPE_TRAITS_IS_UNBOUNDED_ARRAY_H
-#define _LIBCPP___TYPE_TRAITS_IS_UNBOUNDED_ARRAY_H
-
-#include <__config>
-#include <__type_traits/integral_constant.h>
-
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-# pragma GCC system_header
-#endif
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-template <class>
-inline const bool __is_unbounded_array_v = false;
-template <class _Tp>
-inline const bool __is_unbounded_array_v<_Tp[]> = true;
-
-#if _LIBCPP_STD_VER >= 20
-
-template <class _Tp>
-struct _LIBCPP_NO_SPECIALIZATIONS is_unbounded_array : bool_constant<__is_unbounded_array_v<_Tp>> {};
-
-template <class _Tp>
-_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_unbounded_array_v = __is_unbounded_array_v<_Tp>;
-
-#endif
-
-_LIBCPP_END_NAMESPACE_STD
-
-#endif // _LIBCPP___TYPE_TRAITS_IS_UNBOUNDED_ARRAY_H
diff --git a/libcxx/include/__utility/cmp.h b/libcxx/include/__utility/cmp.h
index 68864e2..7cfe640 100644
--- a/libcxx/include/__utility/cmp.h
+++ b/libcxx/include/__utility/cmp.h
@@ -31,7 +31,7 @@ concept __comparison_can_promote_to =
sizeof(_Tp) < sizeof(_Ip) || (sizeof(_Tp) == sizeof(_Ip) && __signed_integer<_Tp>);
template <__signed_or_unsigned_integer _Tp, __signed_or_unsigned_integer _Up>
-_LIBCPP_HIDE_FROM_ABI constexpr bool cmp_equal(_Tp __t, _Up __u) noexcept {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool cmp_equal(_Tp __t, _Up __u) noexcept {
if constexpr (is_signed_v<_Tp> == is_signed_v<_Up>)
return __t == __u;
else if constexpr (__comparison_can_promote_to<_Tp, int> && __comparison_can_promote_to<_Up, int>)
@@ -45,12 +45,12 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool cmp_equal(_Tp __t, _Up __u) noexcept {
}
template <__signed_or_unsigned_integer _Tp, __signed_or_unsigned_integer _Up>
-_LIBCPP_HIDE_FROM_ABI constexpr bool cmp_not_equal(_Tp __t, _Up __u) noexcept {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool cmp_not_equal(_Tp __t, _Up __u) noexcept {
return !std::cmp_equal(__t, __u);
}
template <__signed_or_unsigned_integer _Tp, __signed_or_unsigned_integer _Up>
-_LIBCPP_HIDE_FROM_ABI constexpr bool cmp_less(_Tp __t, _Up __u) noexcept {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool cmp_less(_Tp __t, _Up __u) noexcept {
if constexpr (is_signed_v<_Tp> == is_signed_v<_Up>)
return __t < __u;
else if constexpr (__comparison_can_promote_to<_Tp, int> && __comparison_can_promote_to<_Up, int>)
@@ -64,22 +64,22 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool cmp_less(_Tp __t, _Up __u) noexcept {
}
template <__signed_or_unsigned_integer _Tp, __signed_or_unsigned_integer _Up>
-_LIBCPP_HIDE_FROM_ABI constexpr bool cmp_greater(_Tp __t, _Up __u) noexcept {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool cmp_greater(_Tp __t, _Up __u) noexcept {
return std::cmp_less(__u, __t);
}
template <__signed_or_unsigned_integer _Tp, __signed_or_unsigned_integer _Up>
-_LIBCPP_HIDE_FROM_ABI constexpr bool cmp_less_equal(_Tp __t, _Up __u) noexcept {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool cmp_less_equal(_Tp __t, _Up __u) noexcept {
return !std::cmp_greater(__t, __u);
}
template <__signed_or_unsigned_integer _Tp, __signed_or_unsigned_integer _Up>
-_LIBCPP_HIDE_FROM_ABI constexpr bool cmp_greater_equal(_Tp __t, _Up __u) noexcept {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool cmp_greater_equal(_Tp __t, _Up __u) noexcept {
return !std::cmp_less(__t, __u);
}
template <__signed_or_unsigned_integer _Tp, __signed_or_unsigned_integer _Up>
-_LIBCPP_HIDE_FROM_ABI constexpr bool in_range(_Up __u) noexcept {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool in_range(_Up __u) noexcept {
return std::cmp_less_equal(__u, numeric_limits<_Tp>::max()) &&
std::cmp_greater_equal(__u, numeric_limits<_Tp>::min());
}
diff --git a/libcxx/include/__utility/integer_sequence.h b/libcxx/include/__utility/integer_sequence.h
index 329826a..9450d52 100644
--- a/libcxx/include/__utility/integer_sequence.h
+++ b/libcxx/include/__utility/integer_sequence.h
@@ -33,7 +33,7 @@ template <class _Tp, _Tp... _Indices>
struct __integer_sequence {
using value_type = _Tp;
static_assert(is_integral<_Tp>::value, "std::integer_sequence can only be instantiated with an integral type");
- static _LIBCPP_HIDE_FROM_ABI constexpr size_t size() noexcept { return sizeof...(_Indices); }
+ [[__nodiscard__]] static _LIBCPP_HIDE_FROM_ABI constexpr size_t size() noexcept { return sizeof...(_Indices); }
};
template <size_t... _Indices>
@@ -42,6 +42,9 @@ using __index_sequence _LIBCPP_NODEBUG = __integer_sequence<size_t, _Indices...>
template <size_t _SequenceSize>
using __make_index_sequence _LIBCPP_NODEBUG = __make_integer_sequence_impl<__integer_sequence, size_t, _SequenceSize>;
+template <class... _Args>
+using __index_sequence_for _LIBCPP_NODEBUG = __make_index_sequence<sizeof...(_Args)>;
+
# if _LIBCPP_STD_VER >= 14
template <class _Tp, _Tp... _Indices>
diff --git a/libcxx/include/__utility/pair.h b/libcxx/include/__utility/pair.h
index 33694c52..d3914f6 100644
--- a/libcxx/include/__utility/pair.h
+++ b/libcxx/include/__utility/pair.h
@@ -31,8 +31,6 @@
#include <__type_traits/is_implicitly_default_constructible.h>
#include <__type_traits/is_nothrow_assignable.h>
#include <__type_traits/is_nothrow_constructible.h>
-#include <__type_traits/is_replaceable.h>
-#include <__type_traits/is_same.h>
#include <__type_traits/is_swappable.h>
#include <__type_traits/is_trivially_relocatable.h>
#include <__type_traits/nat.h>
@@ -102,7 +100,6 @@ struct pair
__conditional_t<__libcpp_is_trivially_relocatable<_T1>::value && __libcpp_is_trivially_relocatable<_T2>::value,
pair,
void>;
- using __replaceable _LIBCPP_NODEBUG = __conditional_t<__is_replaceable_v<_T1> && __is_replaceable_v<_T2>, pair, void>;
_LIBCPP_HIDE_FROM_ABI pair(pair const&) = default;
_LIBCPP_HIDE_FROM_ABI pair(pair&&) = default;
@@ -222,11 +219,7 @@ struct pair
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
pair(piecewise_construct_t __pc, tuple<_Args1...> __first_args, tuple<_Args2...> __second_args) noexcept(
is_nothrow_constructible<first_type, _Args1...>::value && is_nothrow_constructible<second_type, _Args2...>::value)
- : pair(__pc,
- __first_args,
- __second_args,
- __make_index_sequence<sizeof...(_Args1)>(),
- __make_index_sequence<sizeof...(_Args2)>()) {}
+ : pair(__pc, __first_args, __second_args, __index_sequence_for<_Args1...>(), __index_sequence_for<_Args2...>()) {}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair&
operator=(__conditional_t<is_copy_assignable<first_type>::value && is_copy_assignable<second_type>::value,
diff --git a/libcxx/include/__vector/vector.h b/libcxx/include/__vector/vector.h
index 316d3a9..4961a5f 100644
--- a/libcxx/include/__vector/vector.h
+++ b/libcxx/include/__vector/vector.h
@@ -12,11 +12,11 @@
#include <__algorithm/copy.h>
#include <__algorithm/copy_n.h>
#include <__algorithm/fill_n.h>
+#include <__algorithm/iterator_operations.h>
#include <__algorithm/max.h>
#include <__algorithm/min.h>
#include <__algorithm/move.h>
#include <__algorithm/move_backward.h>
-#include <__algorithm/ranges_copy_n.h>
#include <__algorithm/rotate.h>
#include <__assert>
#include <__config>
@@ -54,7 +54,6 @@
#include <__type_traits/is_nothrow_assignable.h>
#include <__type_traits/is_nothrow_constructible.h>
#include <__type_traits/is_pointer.h>
-#include <__type_traits/is_replaceable.h>
#include <__type_traits/is_same.h>
#include <__type_traits/is_trivially_relocatable.h>
#include <__type_traits/type_identity.h>
@@ -123,10 +122,6 @@ public:
__libcpp_is_trivially_relocatable<pointer>::value && __libcpp_is_trivially_relocatable<allocator_type>::value,
vector,
void>;
- using __replaceable _LIBCPP_NODEBUG =
- __conditional_t<__is_replaceable_v<pointer> && __container_allocator_is_replaceable<__alloc_traits>::value,
- vector,
- void>;
static_assert(__check_valid_allocator<allocator_type>::value, "");
static_assert(is_same<typename allocator_type::value_type, value_type>::value,
@@ -319,7 +314,7 @@ public:
is_constructible<value_type, typename iterator_traits<_ForwardIterator>::reference>::value,
int> = 0>
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void assign(_ForwardIterator __first, _ForwardIterator __last) {
- __assign_with_size(__first, __last, std::distance(__first, __last));
+ __assign_with_size<_ClassicAlgPolicy>(__first, __last, std::distance(__first, __last));
}
#if _LIBCPP_STD_VER >= 23
@@ -327,7 +322,7 @@ public:
_LIBCPP_HIDE_FROM_ABI constexpr void assign_range(_Range&& __range) {
if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) {
auto __n = static_cast<size_type>(ranges::distance(__range));
- __assign_with_size(ranges::begin(__range), ranges::end(__range), __n);
+ __assign_with_size<_RangeAlgPolicy>(ranges::begin(__range), ranges::end(__range), __n);
} else {
__assign_with_sentinel(ranges::begin(__range), ranges::end(__range));
@@ -523,7 +518,7 @@ public:
int> = 0>
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator
insert(const_iterator __position, _ForwardIterator __first, _ForwardIterator __last) {
- return __insert_with_size(__position, __first, __last, std::distance(__first, __last));
+ return __insert_with_size<_ClassicAlgPolicy>(__position, __first, __last, std::distance(__first, __last));
}
#if _LIBCPP_STD_VER >= 23
@@ -531,7 +526,7 @@ public:
_LIBCPP_HIDE_FROM_ABI constexpr iterator insert_range(const_iterator __position, _Range&& __range) {
if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) {
auto __n = static_cast<size_type>(ranges::distance(__range));
- return __insert_with_size(__position, ranges::begin(__range), ranges::end(__range), __n);
+ return __insert_with_size<_RangeAlgPolicy>(__position, ranges::begin(__range), ranges::end(__range), __n);
} else {
return __insert_with_sentinel(__position, ranges::begin(__range), ranges::end(__range));
@@ -624,12 +619,13 @@ private:
// The `_Iterator` in `*_with_size` functions can be input-only only if called from `*_range` (since C++23).
// Otherwise, `_Iterator` is a forward iterator.
- template <class _Iterator, class _Sentinel>
+ template <class _AlgPolicy, class _Iterator, class _Sentinel>
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
__assign_with_size(_Iterator __first, _Sentinel __last, difference_type __n);
- template <class _Iterator,
- __enable_if_t<!is_same<decltype(*std::declval<_Iterator&>())&&, value_type&&>::value, int> = 0>
+ template <class _AlgPolicy,
+ class _Iterator,
+ __enable_if_t<!is_same<__policy_value_type<_AlgPolicy, _Iterator>, value_type>::value, int> = 0>
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
__insert_assign_n_unchecked(_Iterator __first, difference_type __n, pointer __position) {
for (pointer __end_position = __position + __n; __position != __end_position; ++__position, (void)++__first) {
@@ -638,25 +634,19 @@ private:
}
}
- template <class _Iterator,
- __enable_if_t<is_same<decltype(*std::declval<_Iterator&>())&&, value_type&&>::value, int> = 0>
+ template <class _AlgPolicy,
+ class _Iterator,
+ __enable_if_t<is_same<__policy_value_type<_AlgPolicy, _Iterator>, value_type>::value, int> = 0>
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
__insert_assign_n_unchecked(_Iterator __first, difference_type __n, pointer __position) {
-#if _LIBCPP_STD_VER >= 23
- if constexpr (!forward_iterator<_Iterator>) { // Handles input-only sized ranges for insert_range
- ranges::copy_n(std::move(__first), __n, __position);
- } else
-#endif
- {
- std::copy_n(__first, __n, __position);
- }
+ std::__copy_n<_AlgPolicy>(std::move(__first), __n, __position);
}
template <class _InputIterator, class _Sentinel>
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator
__insert_with_sentinel(const_iterator __position, _InputIterator __first, _Sentinel __last);
- template <class _Iterator, class _Sentinel>
+ template <class _AlgPolicy, class _Iterator, class _Sentinel>
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator
__insert_with_size(const_iterator __position, _Iterator __first, _Sentinel __last, difference_type __n);
@@ -664,9 +654,6 @@ private:
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
__construct_at_end(_InputIterator __first, _Sentinel __last, size_type __n);
- _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __append(size_type __n);
- _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __append(size_type __n, const_reference __x);
-
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator __make_iter(pointer __p) _NOEXCEPT {
#ifdef _LIBCPP_ABI_BOUNDED_ITERATORS_IN_VECTOR
// Bound the iterator according to the capacity, rather than the size.
@@ -971,36 +958,6 @@ vector<_Tp, _Allocator>::__construct_at_end(_InputIterator __first, _Sentinel __
__tx.__pos_ = std::__uninitialized_allocator_copy(this->__alloc_, std::move(__first), std::move(__last), __tx.__pos_);
}
-// Default constructs __n objects starting at __end_
-// throws if construction throws
-// Postcondition: size() == size() + __n
-// Exception safety: strong.
-template <class _Tp, class _Allocator>
-_LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::__append(size_type __n) {
- if (static_cast<size_type>(this->__cap_ - this->__end_) >= __n)
- this->__construct_at_end(__n);
- else {
- __split_buffer<value_type, allocator_type&> __v(__recommend(size() + __n), size(), this->__alloc_);
- __v.__construct_at_end(__n);
- __swap_out_circular_buffer(__v);
- }
-}
-
-// Default constructs __n objects starting at __end_
-// throws if construction throws
-// Postcondition: size() == size() + __n
-// Exception safety: strong.
-template <class _Tp, class _Allocator>
-_LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::__append(size_type __n, const_reference __x) {
- if (static_cast<size_type>(this->__cap_ - this->__end_) >= __n)
- this->__construct_at_end(__n, __x);
- else {
- __split_buffer<value_type, allocator_type&> __v(__recommend(size() + __n), size(), this->__alloc_);
- __v.__construct_at_end(__n, __x);
- __swap_out_circular_buffer(__v);
- }
-}
-
template <class _Tp, class _Allocator>
_LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI vector<_Tp, _Allocator>::vector(vector&& __x)
#if _LIBCPP_STD_VER >= 17
@@ -1077,20 +1034,14 @@ vector<_Tp, _Allocator>::__assign_with_sentinel(_Iterator __first, _Sentinel __l
}
template <class _Tp, class _Allocator>
-template <class _Iterator, class _Sentinel>
+template <class _AlgPolicy, class _Iterator, class _Sentinel>
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
vector<_Tp, _Allocator>::__assign_with_size(_Iterator __first, _Sentinel __last, difference_type __n) {
size_type __new_size = static_cast<size_type>(__n);
if (__new_size <= capacity()) {
if (__new_size > size()) {
-#if _LIBCPP_STD_VER >= 23
- auto __mid = ranges::copy_n(std::move(__first), size(), this->__begin_).in;
+ auto __mid = std::__copy_n<_AlgPolicy>(std::move(__first), size(), this->__begin_).first;
__construct_at_end(std::move(__mid), std::move(__last), __new_size - size());
-#else
- _Iterator __mid = std::next(__first, size());
- std::copy(__first, __mid, this->__begin_);
- __construct_at_end(__mid, __last, __new_size - size());
-#endif
} else {
pointer __m = std::__copy(std::move(__first), __last, this->__begin_).second;
this->__destruct_at_end(__m);
@@ -1364,7 +1315,7 @@ vector<_Tp, _Allocator>::__insert_with_sentinel(const_iterator __position, _Inpu
}
template <class _Tp, class _Allocator>
-template <class _Iterator, class _Sentinel>
+template <class _AlgPolicy, class _Iterator, class _Sentinel>
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI typename vector<_Tp, _Allocator>::iterator
vector<_Tp, _Allocator>::__insert_with_size(
const_iterator __position, _Iterator __first, _Sentinel __last, difference_type __n) {
@@ -1385,12 +1336,12 @@ vector<_Tp, _Allocator>::__insert_with_size(
__construct_at_end(__m, __last, __n - __dx);
if (__dx > 0) {
__move_range(__p, __old_last, __p + __n);
- __insert_assign_n_unchecked(__first, __dx, __p);
+ __insert_assign_n_unchecked<_AlgPolicy>(__first, __dx, __p);
}
}
} else {
__move_range(__p, __old_last, __p + __n);
- __insert_assign_n_unchecked(std::move(__first), __n, __p);
+ __insert_assign_n_unchecked<_AlgPolicy>(std::move(__first), __n, __p);
}
} else {
__split_buffer<value_type, allocator_type&> __v(__recommend(size() + __n), __p - this->__begin_, this->__alloc_);
@@ -1402,21 +1353,35 @@ vector<_Tp, _Allocator>::__insert_with_size(
}
template <class _Tp, class _Allocator>
-_LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::resize(size_type __sz) {
- size_type __cs = size();
- if (__cs < __sz)
- this->__append(__sz - __cs);
- else if (__cs > __sz)
- this->__destruct_at_end(this->__begin_ + __sz);
+_LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::resize(size_type __new_size) {
+ size_type __current_size = size();
+ if (__current_size < __new_size) {
+ if (__new_size <= capacity()) {
+ __construct_at_end(__new_size - __current_size);
+ } else {
+ __split_buffer<value_type, allocator_type&> __v(__recommend(__new_size), __current_size, __alloc_);
+ __v.__construct_at_end(__new_size - __current_size);
+ __swap_out_circular_buffer(__v);
+ }
+ } else if (__current_size > __new_size) {
+ this->__destruct_at_end(this->__begin_ + __new_size);
+ }
}
template <class _Tp, class _Allocator>
-_LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::resize(size_type __sz, const_reference __x) {
- size_type __cs = size();
- if (__cs < __sz)
- this->__append(__sz - __cs, __x);
- else if (__cs > __sz)
- this->__destruct_at_end(this->__begin_ + __sz);
+_LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::resize(size_type __new_size, const_reference __x) {
+ size_type __current_size = size();
+ if (__current_size < __new_size) {
+ if (__new_size <= capacity())
+ __construct_at_end(__new_size - __current_size, __x);
+ else {
+ __split_buffer<value_type, allocator_type&> __v(__recommend(__new_size), __current_size, __alloc_);
+ __v.__construct_at_end(__new_size - __current_size, __x);
+ __swap_out_circular_buffer(__v);
+ }
+ } else if (__current_size > __new_size) {
+ this->__destruct_at_end(this->__begin_ + __new_size);
+ }
}
template <class _Tp, class _Allocator>
diff --git a/libcxx/include/any b/libcxx/include/any
index 148fb16..5c779e3 100644
--- a/libcxx/include/any
+++ b/libcxx/include/any
@@ -88,7 +88,6 @@ namespace std {
# include <__new/allocate.h>
# include <__type_traits/add_cv_quals.h>
# include <__type_traits/add_pointer.h>
-# include <__type_traits/aligned_storage.h>
# include <__type_traits/conditional.h>
# include <__type_traits/decay.h>
# include <__type_traits/enable_if.h>
@@ -147,14 +146,13 @@ template <class _ValueType>
_LIBCPP_HIDE_FROM_ABI add_pointer_t<_ValueType> any_cast(any*) _NOEXCEPT;
namespace __any_imp {
-_LIBCPP_SUPPRESS_DEPRECATED_PUSH
-using _Buffer _LIBCPP_NODEBUG = aligned_storage_t<3 * sizeof(void*), alignof(void*)>;
-_LIBCPP_SUPPRESS_DEPRECATED_POP
+inline constexpr size_t __small_buffer_size = 3 * sizeof(void*);
+inline constexpr size_t __small_buffer_alignment = alignof(void*);
template <class _Tp>
using _IsSmallObject _LIBCPP_NODEBUG =
integral_constant<bool,
- sizeof(_Tp) <= sizeof(_Buffer) && alignof(_Buffer) % alignof(_Tp) == 0 &&
+ sizeof(_Tp) <= __small_buffer_size && alignof(_Tp) <= __small_buffer_alignment &&
is_nothrow_move_constructible<_Tp>::value >;
enum class _Action { _Destroy, _Copy, _Move, _Get, _TypeInfo };
@@ -264,10 +262,10 @@ public:
_LIBCPP_HIDE_FROM_ABI void swap(any& __rhs) _NOEXCEPT;
// 6.3.4 any observers
- _LIBCPP_HIDE_FROM_ABI bool has_value() const _NOEXCEPT { return __h_ != nullptr; }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool has_value() const _NOEXCEPT { return __h_ != nullptr; }
# if _LIBCPP_HAS_RTTI
- _LIBCPP_HIDE_FROM_ABI const type_info& type() const _NOEXCEPT {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI const type_info& type() const _NOEXCEPT {
if (__h_) {
return *static_cast<type_info const*>(this->__call(_Action::_TypeInfo));
} else {
@@ -284,7 +282,7 @@ private:
union _Storage {
_LIBCPP_HIDE_FROM_ABI constexpr _Storage() : __ptr(nullptr) {}
void* __ptr;
- __any_imp::_Buffer __buf;
+ alignas(__any_imp::__small_buffer_alignment) char __buf[__any_imp::__small_buffer_size];
};
_LIBCPP_HIDE_FROM_ABI void*
@@ -494,17 +492,17 @@ inline _LIBCPP_HIDE_FROM_ABI void any::swap(any& __rhs) _NOEXCEPT {
inline _LIBCPP_HIDE_FROM_ABI void swap(any& __lhs, any& __rhs) _NOEXCEPT { __lhs.swap(__rhs); }
template <class _Tp, class... _Args>
-inline _LIBCPP_HIDE_FROM_ABI any make_any(_Args&&... __args) {
+[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI any make_any(_Args&&... __args) {
return any(in_place_type<_Tp>, std::forward<_Args>(__args)...);
}
template <class _Tp, class _Up, class... _Args>
-inline _LIBCPP_HIDE_FROM_ABI any make_any(initializer_list<_Up> __il, _Args&&... __args) {
+[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI any make_any(initializer_list<_Up> __il, _Args&&... __args) {
return any(in_place_type<_Tp>, __il, std::forward<_Args>(__args)...);
}
template <class _ValueType>
-inline _LIBCPP_HIDE_FROM_ABI _ValueType any_cast(any const& __v) {
+[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI _ValueType any_cast(any const& __v) {
using _RawValueType = __remove_cvref_t<_ValueType>;
static_assert(is_constructible<_ValueType, _RawValueType const&>::value,
"ValueType is required to be a const lvalue reference "
@@ -516,7 +514,7 @@ inline _LIBCPP_HIDE_FROM_ABI _ValueType any_cast(any const& __v) {
}
template <class _ValueType>
-inline _LIBCPP_HIDE_FROM_ABI _ValueType any_cast(any& __v) {
+[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI _ValueType any_cast(any& __v) {
using _RawValueType = __remove_cvref_t<_ValueType>;
static_assert(is_constructible<_ValueType, _RawValueType&>::value,
"ValueType is required to be an lvalue reference "
@@ -528,7 +526,7 @@ inline _LIBCPP_HIDE_FROM_ABI _ValueType any_cast(any& __v) {
}
template <class _ValueType>
-inline _LIBCPP_HIDE_FROM_ABI _ValueType any_cast(any&& __v) {
+[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI _ValueType any_cast(any&& __v) {
using _RawValueType = __remove_cvref_t<_ValueType>;
static_assert(is_constructible<_ValueType, _RawValueType>::value,
"ValueType is required to be an rvalue reference "
@@ -540,7 +538,7 @@ inline _LIBCPP_HIDE_FROM_ABI _ValueType any_cast(any&& __v) {
}
template <class _ValueType>
-inline _LIBCPP_HIDE_FROM_ABI add_pointer_t<add_const_t<_ValueType>> any_cast(any const* __any) _NOEXCEPT {
+[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI add_pointer_t<add_const_t<_ValueType>> any_cast(any const* __any) _NOEXCEPT {
static_assert(!is_void_v<_ValueType>, "_ValueType may not be void.");
static_assert(!is_reference<_ValueType>::value, "_ValueType may not be a reference.");
return std::any_cast<_ValueType>(const_cast<any*>(__any));
@@ -557,7 +555,7 @@ inline _LIBCPP_HIDE_FROM_ABI _RetType __pointer_or_func_cast(void*, /*IsFunction
}
template <class _ValueType>
-_LIBCPP_HIDE_FROM_ABI add_pointer_t<_ValueType> any_cast(any* __any) _NOEXCEPT {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI add_pointer_t<_ValueType> any_cast(any* __any) _NOEXCEPT {
using __any_imp::_Action;
static_assert(!is_void_v<_ValueType>, "_ValueType may not be void.");
static_assert(!is_reference<_ValueType>::value, "_ValueType may not be a reference.");
diff --git a/libcxx/include/array b/libcxx/include/array
index 9643fc1..0b0c854 100644
--- a/libcxx/include/array
+++ b/libcxx/include/array
@@ -134,7 +134,6 @@ template <size_t I, class T, size_t N> const T&& get(const array<T, N>&&) noexce
# include <__type_traits/is_const.h>
# include <__type_traits/is_constructible.h>
# include <__type_traits/is_nothrow_constructible.h>
-# include <__type_traits/is_replaceable.h>
# include <__type_traits/is_same.h>
# include <__type_traits/is_swappable.h>
# include <__type_traits/is_trivially_relocatable.h>
@@ -176,7 +175,6 @@ template <class _Tp, size_t _Size>
struct array {
using __trivially_relocatable _LIBCPP_NODEBUG =
__conditional_t<__libcpp_is_trivially_relocatable<_Tp>::value, array, void>;
- using __replaceable _LIBCPP_NODEBUG = __conditional_t<__is_replaceable_v<_Tp>, array, void>;
// types:
using __self _LIBCPP_NODEBUG = array;
@@ -212,28 +210,28 @@ struct array {
}
// iterators:
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 iterator begin() _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 iterator begin() _NOEXCEPT {
# if defined(_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STD_ARRAY)
return std::__make_static_bounded_iter<_Size>(data(), data());
# else
return iterator(data());
# endif
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator begin() const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator begin() const _NOEXCEPT {
# if defined(_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STD_ARRAY)
return std::__make_static_bounded_iter<_Size>(data(), data());
# else
return const_iterator(data());
# endif
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 iterator end() _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 iterator end() _NOEXCEPT {
# if defined(_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STD_ARRAY)
return std::__make_static_bounded_iter<_Size>(data() + _Size, data());
# else
return iterator(data() + _Size);
# endif
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator end() const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator end() const _NOEXCEPT {
# if defined(_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STD_ARRAY)
return std::__make_static_bounded_iter<_Size>(data() + _Size, data());
# else
@@ -241,62 +239,81 @@ struct array {
# endif
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator rbegin() _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator rbegin() _NOEXCEPT {
return reverse_iterator(end());
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator rbegin() const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator
+ rbegin() const _NOEXCEPT {
return const_reverse_iterator(end());
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator rend() _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator rend() _NOEXCEPT {
return reverse_iterator(begin());
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator rend() const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator rend() const _NOEXCEPT {
return const_reverse_iterator(begin());
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator cbegin() const _NOEXCEPT { return begin(); }
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator cend() const _NOEXCEPT { return end(); }
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator crbegin() const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator cbegin() const _NOEXCEPT {
+ return begin();
+ }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator cend() const _NOEXCEPT {
+ return end();
+ }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator
+ crbegin() const _NOEXCEPT {
return rbegin();
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator crend() const _NOEXCEPT { return rend(); }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator crend() const _NOEXCEPT {
+ return rend();
+ }
// capacity:
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR size_type size() const _NOEXCEPT { return _Size; }
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR size_type max_size() const _NOEXCEPT { return _Size; }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR size_type size() const _NOEXCEPT { return _Size; }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR size_type max_size() const _NOEXCEPT { return _Size; }
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool empty() const _NOEXCEPT { return _Size == 0; }
// element access:
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference operator[](size_type __n) _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference operator[](size_type __n) _NOEXCEPT {
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < _Size, "out-of-bounds access in std::array<T, N>");
return __elems_[__n];
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference operator[](size_type __n) const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference
+ operator[](size_type __n) const _NOEXCEPT {
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < _Size, "out-of-bounds access in std::array<T, N>");
return __elems_[__n];
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference at(size_type __n) {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference at(size_type __n) {
if (__n >= _Size)
std::__throw_out_of_range("array::at");
return __elems_[__n];
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference at(size_type __n) const {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference at(size_type __n) const {
if (__n >= _Size)
std::__throw_out_of_range("array::at");
return __elems_[__n];
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference front() _NOEXCEPT { return (*this)[0]; }
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference front() const _NOEXCEPT { return (*this)[0]; }
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference back() _NOEXCEPT { return (*this)[_Size - 1]; }
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference back() const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference front() _NOEXCEPT {
+ return (*this)[0];
+ }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference front() const _NOEXCEPT {
+ return (*this)[0];
+ }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference back() _NOEXCEPT {
+ return (*this)[_Size - 1];
+ }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference back() const _NOEXCEPT {
return (*this)[_Size - 1];
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 value_type* data() _NOEXCEPT { return __elems_; }
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const value_type* data() const _NOEXCEPT { return __elems_; }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 value_type* data() _NOEXCEPT {
+ return __elems_;
+ }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const value_type* data() const _NOEXCEPT {
+ return __elems_;
+ }
};
template <class _Tp>
@@ -330,8 +347,10 @@ struct array<_Tp, 0> {
};
_ALIGNAS_TYPE(_ArrayInStructT) _EmptyType __elems_[sizeof(_ArrayInStructT)];
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 value_type* data() _NOEXCEPT { return nullptr; }
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const value_type* data() const _NOEXCEPT { return nullptr; }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 value_type* data() _NOEXCEPT { return nullptr; }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const value_type* data() const _NOEXCEPT {
+ return nullptr;
+ }
// No explicit construct/copy/destroy for aggregate type
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void fill(const value_type&) {
@@ -343,28 +362,28 @@ struct array<_Tp, 0> {
}
// iterators:
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 iterator begin() _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 iterator begin() _NOEXCEPT {
# if defined(_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STD_ARRAY)
return std::__make_static_bounded_iter<0>(data(), data());
# else
return iterator(data());
# endif
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator begin() const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator begin() const _NOEXCEPT {
# if defined(_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STD_ARRAY)
return std::__make_static_bounded_iter<0>(data(), data());
# else
return const_iterator(data());
# endif
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 iterator end() _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 iterator end() _NOEXCEPT {
# if defined(_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STD_ARRAY)
return std::__make_static_bounded_iter<0>(data(), data());
# else
return iterator(data());
# endif
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator end() const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator end() const _NOEXCEPT {
# if defined(_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STD_ARRAY)
return std::__make_static_bounded_iter<0>(data(), data());
# else
@@ -372,68 +391,77 @@ struct array<_Tp, 0> {
# endif
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator rbegin() _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator rbegin() _NOEXCEPT {
return reverse_iterator(end());
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator rbegin() const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator
+ rbegin() const _NOEXCEPT {
return const_reverse_iterator(end());
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator rend() _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator rend() _NOEXCEPT {
return reverse_iterator(begin());
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator rend() const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator rend() const _NOEXCEPT {
return const_reverse_iterator(begin());
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator cbegin() const _NOEXCEPT { return begin(); }
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator cend() const _NOEXCEPT { return end(); }
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator crbegin() const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator cbegin() const _NOEXCEPT {
+ return begin();
+ }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator cend() const _NOEXCEPT {
+ return end();
+ }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator
+ crbegin() const _NOEXCEPT {
return rbegin();
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator crend() const _NOEXCEPT { return rend(); }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator crend() const _NOEXCEPT {
+ return rend();
+ }
// capacity:
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR size_type size() const _NOEXCEPT { return 0; }
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR size_type max_size() const _NOEXCEPT { return 0; }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR size_type size() const _NOEXCEPT { return 0; }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR size_type max_size() const _NOEXCEPT { return 0; }
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool empty() const _NOEXCEPT { return true; }
// element access:
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference operator[](size_type) _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference operator[](size_type) _NOEXCEPT {
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array<T, 0>::operator[] on a zero-sized array");
__libcpp_unreachable();
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference operator[](size_type) const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference
+ operator[](size_type) const _NOEXCEPT {
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array<T, 0>::operator[] on a zero-sized array");
__libcpp_unreachable();
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference at(size_type) {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference at(size_type) {
std::__throw_out_of_range("array<T, 0>::at");
__libcpp_unreachable();
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference at(size_type) const {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference at(size_type) const {
std::__throw_out_of_range("array<T, 0>::at");
__libcpp_unreachable();
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference front() _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference front() _NOEXCEPT {
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array<T, 0>::front() on a zero-sized array");
__libcpp_unreachable();
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference front() const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference front() const _NOEXCEPT {
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array<T, 0>::front() on a zero-sized array");
__libcpp_unreachable();
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference back() _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference back() _NOEXCEPT {
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array<T, 0>::back() on a zero-sized array");
__libcpp_unreachable();
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference back() const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference back() const _NOEXCEPT {
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array<T, 0>::back() on a zero-sized array");
__libcpp_unreachable();
}
@@ -503,25 +531,29 @@ struct tuple_element<_Ip, array<_Tp, _Size> > {
};
template <size_t _Ip, class _Tp, size_t _Size>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp& get(array<_Tp, _Size>& __a) _NOEXCEPT {
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp&
+get(array<_Tp, _Size>& __a) _NOEXCEPT {
static_assert(_Ip < _Size, "Index out of bounds in std::get<> (std::array)");
return __a.__elems_[_Ip];
}
template <size_t _Ip, class _Tp, size_t _Size>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Tp& get(const array<_Tp, _Size>& __a) _NOEXCEPT {
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Tp&
+get(const array<_Tp, _Size>& __a) _NOEXCEPT {
static_assert(_Ip < _Size, "Index out of bounds in std::get<> (const std::array)");
return __a.__elems_[_Ip];
}
template <size_t _Ip, class _Tp, size_t _Size>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp&& get(array<_Tp, _Size>&& __a) _NOEXCEPT {
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp&&
+get(array<_Tp, _Size>&& __a) _NOEXCEPT {
static_assert(_Ip < _Size, "Index out of bounds in std::get<> (std::array &&)");
return std::move(__a.__elems_[_Ip]);
}
template <size_t _Ip, class _Tp, size_t _Size>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Tp&& get(const array<_Tp, _Size>&& __a) _NOEXCEPT {
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Tp&&
+get(const array<_Tp, _Size>&& __a) _NOEXCEPT {
static_assert(_Ip < _Size, "Index out of bounds in std::get<> (const std::array &&)");
return std::move(__a.__elems_[_Ip]);
}
@@ -541,7 +573,7 @@ __to_array_rvalue_impl(_Tp (&&__arr)[_Size], index_sequence<_Index...>) {
}
template <typename _Tp, size_t _Size>
-_LIBCPP_HIDE_FROM_ABI constexpr array<remove_cv_t<_Tp>, _Size>
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr array<remove_cv_t<_Tp>, _Size>
to_array(_Tp (&__arr)[_Size]) noexcept(is_nothrow_constructible_v<_Tp, _Tp&>) {
static_assert(!is_array_v<_Tp>, "[array.creation]/1: to_array does not accept multidimensional arrays.");
static_assert(is_constructible_v<_Tp, _Tp&>, "[array.creation]/1: to_array requires copy constructible elements.");
@@ -549,7 +581,7 @@ to_array(_Tp (&__arr)[_Size]) noexcept(is_nothrow_constructible_v<_Tp, _Tp&>) {
}
template <typename _Tp, size_t _Size>
-_LIBCPP_HIDE_FROM_ABI constexpr array<remove_cv_t<_Tp>, _Size>
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr array<remove_cv_t<_Tp>, _Size>
to_array(_Tp (&&__arr)[_Size]) noexcept(is_nothrow_move_constructible_v<_Tp>) {
static_assert(!is_array_v<_Tp>, "[array.creation]/4: to_array does not accept multidimensional arrays.");
static_assert(is_move_constructible_v<_Tp>, "[array.creation]/4: to_array requires move constructible elements.");
diff --git a/libcxx/include/barrier b/libcxx/include/barrier
index 41fbfb3..5f9b471 100644
--- a/libcxx/include/barrier
+++ b/libcxx/include/barrier
@@ -158,7 +158,9 @@ class barrier {
public:
using arrival_token = typename __barrier_base<_CompletionF>::arrival_token;
- static _LIBCPP_HIDE_FROM_ABI constexpr ptrdiff_t max() noexcept { return __barrier_base<_CompletionF>::max(); }
+ [[nodiscard]] static _LIBCPP_HIDE_FROM_ABI constexpr ptrdiff_t max() noexcept {
+ return __barrier_base<_CompletionF>::max();
+ }
_LIBCPP_HIDE_FROM_ABI explicit barrier(ptrdiff_t __count, _CompletionF __completion = _CompletionF())
: __b_(__count, std::move(__completion)) {
diff --git a/libcxx/include/bitset b/libcxx/include/bitset
index 3453c2f..271e63b 100644
--- a/libcxx/include/bitset
+++ b/libcxx/include/bitset
@@ -675,53 +675,62 @@ public:
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset& set(size_t __pos, bool __val = true);
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset& reset() _NOEXCEPT;
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset& reset(size_t __pos);
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset operator~() const _NOEXCEPT;
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset operator~() const _NOEXCEPT;
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset& flip() _NOEXCEPT;
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset& flip(size_t __pos);
// element access:
# ifdef _LIBCPP_ABI_BITSET_VECTOR_BOOL_CONST_SUBSCRIPT_RETURN_BOOL
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool operator[](size_t __p) const {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool operator[](size_t __p) const {
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__p < _Size, "bitset::operator[] index out of bounds");
return __base::__make_ref(__p);
}
# else
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __const_reference operator[](size_t __p) const {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __const_reference operator[](size_t __p) const {
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__p < _Size, "bitset::operator[] index out of bounds");
return __base::__make_ref(__p);
}
# endif
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 reference operator[](size_t __p) {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 reference operator[](size_t __p) {
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__p < _Size, "bitset::operator[] index out of bounds");
return __base::__make_ref(__p);
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long to_ulong() const { return __base::to_ulong(); }
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long to_ullong() const {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long to_ulong() const {
+ return __base::to_ulong();
+ }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long to_ullong() const {
return __base::to_ullong();
}
template <class _CharT, class _Traits, class _Allocator>
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 basic_string<_CharT, _Traits, _Allocator>
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 basic_string<_CharT, _Traits, _Allocator>
to_string(_CharT __zero = _CharT('0'), _CharT __one = _CharT('1')) const;
template <class _CharT, class _Traits>
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 basic_string<_CharT, _Traits, allocator<_CharT> >
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI
+ _LIBCPP_CONSTEXPR_SINCE_CXX23 basic_string<_CharT, _Traits, allocator<_CharT> >
to_string(_CharT __zero = _CharT('0'), _CharT __one = _CharT('1')) const;
template <class _CharT>
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 basic_string<_CharT, char_traits<_CharT>, allocator<_CharT> >
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI
+ _LIBCPP_CONSTEXPR_SINCE_CXX23 basic_string<_CharT, char_traits<_CharT>, allocator<_CharT> >
to_string(_CharT __zero = _CharT('0'), _CharT __one = _CharT('1')) const;
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 basic_string<char, char_traits<char>, allocator<char> >
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI
+ _LIBCPP_CONSTEXPR_SINCE_CXX23 basic_string<char, char_traits<char>, allocator<char> >
to_string(char __zero = '0', char __one = '1') const;
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 size_t count() const _NOEXCEPT;
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR size_t size() const _NOEXCEPT { return _Size; }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 size_t count() const _NOEXCEPT;
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR size_t size() const _NOEXCEPT { return _Size; }
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool operator==(const bitset& __rhs) const _NOEXCEPT;
# if _LIBCPP_STD_VER <= 17
_LIBCPP_HIDE_FROM_ABI bool operator!=(const bitset& __rhs) const _NOEXCEPT;
# endif
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool test(size_t __pos) const;
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool all() const _NOEXCEPT { return __base::all(); }
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool any() const _NOEXCEPT { return __base::any(); }
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool none() const _NOEXCEPT { return !any(); }
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset operator<<(size_t __pos) const _NOEXCEPT;
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset operator>>(size_t __pos) const _NOEXCEPT;
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool test(size_t __pos) const;
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool all() const _NOEXCEPT {
+ return __base::all();
+ }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool any() const _NOEXCEPT {
+ return __base::any();
+ }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool none() const _NOEXCEPT { return !any(); }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset operator<<(size_t __pos) const _NOEXCEPT;
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset operator>>(size_t __pos) const _NOEXCEPT;
private:
template <class _CharT, class _Traits>
@@ -919,7 +928,7 @@ bitset<_Size>::operator>>(size_t __pos) const _NOEXCEPT {
}
template <size_t _Size>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset<_Size>
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset<_Size>
operator&(const bitset<_Size>& __x, const bitset<_Size>& __y) _NOEXCEPT {
bitset<_Size> __r = __x;
__r &= __y;
@@ -927,7 +936,7 @@ operator&(const bitset<_Size>& __x, const bitset<_Size>& __y) _NOEXCEPT {
}
template <size_t _Size>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset<_Size>
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset<_Size>
operator|(const bitset<_Size>& __x, const bitset<_Size>& __y) _NOEXCEPT {
bitset<_Size> __r = __x;
__r |= __y;
@@ -935,7 +944,7 @@ operator|(const bitset<_Size>& __x, const bitset<_Size>& __y) _NOEXCEPT {
}
template <size_t _Size>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset<_Size>
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset<_Size>
operator^(const bitset<_Size>& __x, const bitset<_Size>& __y) _NOEXCEPT {
bitset<_Size> __r = __x;
__r ^= __y;
@@ -944,7 +953,9 @@ operator^(const bitset<_Size>& __x, const bitset<_Size>& __y) _NOEXCEPT {
template <size_t _Size>
struct hash<bitset<_Size> > : public __unary_function<bitset<_Size>, size_t> {
- _LIBCPP_HIDE_FROM_ABI size_t operator()(const bitset<_Size>& __bs) const _NOEXCEPT { return __bs.__hash_code(); }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t operator()(const bitset<_Size>& __bs) const _NOEXCEPT {
+ return __bs.__hash_code();
+ }
};
template <class _CharT, class _Traits, size_t _Size>
diff --git a/libcxx/include/ccomplex b/libcxx/include/ccomplex
index ee7e088..c1cb039 100644
--- a/libcxx/include/ccomplex
+++ b/libcxx/include/ccomplex
@@ -26,18 +26,10 @@
# pragma GCC system_header
# endif
-# if _LIBCPP_STD_VER >= 20
-
-using __standard_header_ccomplex
- _LIBCPP_DEPRECATED_("removed in C++20. Include <complex> instead.") _LIBCPP_NODEBUG = void;
-using __use_standard_header_ccomplex _LIBCPP_NODEBUG = __standard_header_ccomplex;
-
-# elif _LIBCPP_STD_VER >= 17
-
-using __standard_header_ccomplex _LIBCPP_DEPRECATED_("Include <complex> instead.") _LIBCPP_NODEBUG = void;
-using __use_standard_header_ccomplex _LIBCPP_NODEBUG = __standard_header_ccomplex;
-
+# if _LIBCPP_STD_VER >= 17 && !__building_module(std) && _LIBCPP_DIAGNOSE_DEPRECATED_HEADERS
+# warning <ccomplex> is deprecated in C++17 and removed in C++20. Include <complex> instead.
# endif
+
#endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
#endif // _LIBCPP_CCOMPLEX
diff --git a/libcxx/include/ciso646 b/libcxx/include/ciso646
index 3416436..d9eae41 100644
--- a/libcxx/include/ciso646
+++ b/libcxx/include/ciso646
@@ -24,13 +24,10 @@
# pragma GCC system_header
# endif
-# if _LIBCPP_STD_VER >= 20
-
-using __standard_header_ciso646
- _LIBCPP_DEPRECATED_("removed in C++20. Include <version> instead.") _LIBCPP_NODEBUG = void;
-using __use_standard_header_ciso646 _LIBCPP_NODEBUG = __standard_header_ciso646;
-
+# if _LIBCPP_STD_VER >= 20 && !__building_module(std) && _LIBCPP_DIAGNOSE_DEPRECATED_HEADERS
+# warning <ciso646> is removed in C++20. Include <version> instead.
# endif
+
#endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
#endif // _LIBCPP_CISO646
diff --git a/libcxx/include/cstdalign b/libcxx/include/cstdalign
index 7f8dd1e..7aa8cc8 100644
--- a/libcxx/include/cstdalign
+++ b/libcxx/include/cstdalign
@@ -43,17 +43,10 @@ Macros:
# undef __alignof_is_defined
# define __alignof_is_defined 1
-# if _LIBCPP_STD_VER >= 20
-
-using __standard_header_cstdalign _LIBCPP_DEPRECATED_("removed in C++20.") _LIBCPP_NODEBUG = void;
-using __use_standard_header_cstdalign _LIBCPP_NODEBUG = __standard_header_cstdalign;
-
-# elif _LIBCPP_STD_VER >= 17
-
-using __standard_header_cstdalign _LIBCPP_DEPRECATED _LIBCPP_NODEBUG = void;
-using __use_standard_header_cstdalign _LIBCPP_NODEBUG = __standard_header_cstdalign;
-
+# if _LIBCPP_STD_VER >= 17 && !__building_module(std) && _LIBCPP_DIAGNOSE_DEPRECATED_HEADERS
+# warning <cstdalign> is deprecated in C++17 and removed in C++20.
# endif
+
#endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
#endif // _LIBCPP_CSTDALIGN
diff --git a/libcxx/include/cstdbool b/libcxx/include/cstdbool
index a432d5f..805a287 100644
--- a/libcxx/include/cstdbool
+++ b/libcxx/include/cstdbool
@@ -31,17 +31,10 @@ Macros:
# undef __bool_true_false_are_defined
# define __bool_true_false_are_defined 1
-# if _LIBCPP_STD_VER >= 20
-
-using __standard_header_cstdbool _LIBCPP_DEPRECATED_("removed in C++20.") _LIBCPP_NODEBUG = void;
-using __use_standard_header_cstdbool _LIBCPP_NODEBUG = __standard_header_cstdbool;
-
-# elif _LIBCPP_STD_VER >= 17
-
-using __standard_header_cstdbool _LIBCPP_DEPRECATED _LIBCPP_NODEBUG = void;
-using __use_standard_header_cstdbool _LIBCPP_NODEBUG = __standard_header_cstdbool;
-
+# if _LIBCPP_STD_VER >= 17 && !__building_module(std) && _LIBCPP_DIAGNOSE_DEPRECATED_HEADERS
+# warning <cstdbool> is deprecated in C++17 and removed in C++20.
# endif
+
#endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
#endif // _LIBCPP_CSTDBOOL
diff --git a/libcxx/include/ctgmath b/libcxx/include/ctgmath
index db0786f..13b7a96 100644
--- a/libcxx/include/ctgmath
+++ b/libcxx/include/ctgmath
@@ -28,17 +28,8 @@
# pragma GCC system_header
# endif
-# if _LIBCPP_STD_VER >= 20
-
-using __standard_header_ctgmath
- _LIBCPP_DEPRECATED_("removed in C++20. Include <cmath> and <complex> instead.") _LIBCPP_NODEBUG = void;
-using __use_standard_header_ctgmath _LIBCPP_NODEBUG = __standard_header_ctgmath;
-
-# elif _LIBCPP_STD_VER >= 17
-
-using __standard_header_ctgmath _LIBCPP_DEPRECATED_("Include <cmath> and <complex> instead.") _LIBCPP_NODEBUG = void;
-using __use_standard_header_ctgmath _LIBCPP_NODEBUG = __standard_header_ctgmath;
-
+# if _LIBCPP_STD_VER >= 17 && !__building_module(std) && _LIBCPP_DIAGNOSE_DEPRECATED_HEADERS
+# warning <ctgmath> is deprecated in C++17 and removed in C++20. Include <cmath> and <complex> instead.
# endif
#endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
diff --git a/libcxx/include/deque b/libcxx/include/deque
index cbf4b98..ad2d759 100644
--- a/libcxx/include/deque
+++ b/libcxx/include/deque
@@ -227,7 +227,6 @@ template <class T, class Allocator, class Predicate>
# include <__type_traits/is_convertible.h>
# include <__type_traits/is_nothrow_assignable.h>
# include <__type_traits/is_nothrow_constructible.h>
-# include <__type_traits/is_replaceable.h>
# include <__type_traits/is_same.h>
# include <__type_traits/is_swappable.h>
# include <__type_traits/is_trivially_relocatable.h>
@@ -531,10 +530,6 @@ public:
__libcpp_is_trivially_relocatable<__map>::value && __libcpp_is_trivially_relocatable<allocator_type>::value,
deque,
void>;
- using __replaceable _LIBCPP_NODEBUG =
- __conditional_t<__is_replaceable_v<__map> && __container_allocator_is_replaceable<__alloc_traits>::value,
- deque,
- void>;
static_assert(is_nothrow_default_constructible<allocator_type>::value ==
is_nothrow_default_constructible<__pointer_allocator>::value,
@@ -720,45 +715,53 @@ public:
// iterators:
- _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT {
__map_pointer __mp = __map_.begin() + __start_ / __block_size;
return iterator(__mp, __map_.empty() ? 0 : *__mp + __start_ % __block_size);
}
- _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT {
__map_const_pointer __mp = static_cast<__map_const_pointer>(__map_.begin() + __start_ / __block_size);
return const_iterator(__mp, __map_.empty() ? 0 : *__mp + __start_ % __block_size);
}
- _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT {
size_type __p = size() + __start_;
__map_pointer __mp = __map_.begin() + __p / __block_size;
return iterator(__mp, __map_.empty() ? 0 : *__mp + __p % __block_size);
}
- _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT {
size_type __p = size() + __start_;
__map_const_pointer __mp = static_cast<__map_const_pointer>(__map_.begin() + __p / __block_size);
return const_iterator(__mp, __map_.empty() ? 0 : *__mp + __p % __block_size);
}
- _LIBCPP_HIDE_FROM_ABI reverse_iterator rbegin() _NOEXCEPT { return reverse_iterator(end()); }
- _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rbegin() const _NOEXCEPT { return const_reverse_iterator(end()); }
- _LIBCPP_HIDE_FROM_ABI reverse_iterator rend() _NOEXCEPT { return reverse_iterator(begin()); }
- _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rend() const _NOEXCEPT { return const_reverse_iterator(begin()); }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI reverse_iterator rbegin() _NOEXCEPT { return reverse_iterator(end()); }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rbegin() const _NOEXCEPT {
+ return const_reverse_iterator(end());
+ }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI reverse_iterator rend() _NOEXCEPT { return reverse_iterator(begin()); }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rend() const _NOEXCEPT {
+ return const_reverse_iterator(begin());
+ }
- _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT { return begin(); }
- _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT { return end(); }
- _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crbegin() const _NOEXCEPT { return const_reverse_iterator(end()); }
- _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crend() const _NOEXCEPT { return const_reverse_iterator(begin()); }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT { return begin(); }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT { return end(); }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crbegin() const _NOEXCEPT {
+ return const_reverse_iterator(end());
+ }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crend() const _NOEXCEPT {
+ return const_reverse_iterator(begin());
+ }
// capacity:
- _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __size(); }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __size(); }
_LIBCPP_HIDE_FROM_ABI size_type& __size() _NOEXCEPT { return __size_; }
_LIBCPP_HIDE_FROM_ABI const size_type& __size() const _NOEXCEPT { return __size_; }
- _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT {
return std::min<size_type>(__alloc_traits::max_size(__alloc()), numeric_limits<difference_type>::max());
}
_LIBCPP_HIDE_FROM_ABI void resize(size_type __n);
@@ -767,14 +770,14 @@ public:
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool empty() const _NOEXCEPT { return size() == 0; }
// element access:
- _LIBCPP_HIDE_FROM_ABI reference operator[](size_type __i) _NOEXCEPT;
- _LIBCPP_HIDE_FROM_ABI const_reference operator[](size_type __i) const _NOEXCEPT;
- _LIBCPP_HIDE_FROM_ABI reference at(size_type __i);
- _LIBCPP_HIDE_FROM_ABI const_reference at(size_type __i) const;
- _LIBCPP_HIDE_FROM_ABI reference front() _NOEXCEPT;
- _LIBCPP_HIDE_FROM_ABI const_reference front() const _NOEXCEPT;
- _LIBCPP_HIDE_FROM_ABI reference back() _NOEXCEPT;
- _LIBCPP_HIDE_FROM_ABI const_reference back() const _NOEXCEPT;
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI reference operator[](size_type __i) _NOEXCEPT;
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reference operator[](size_type __i) const _NOEXCEPT;
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI reference at(size_type __i);
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reference at(size_type __i) const;
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI reference front() _NOEXCEPT;
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reference front() const _NOEXCEPT;
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI reference back() _NOEXCEPT;
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reference back() const _NOEXCEPT;
// 23.2.2.3 modifiers:
_LIBCPP_HIDE_FROM_ABI void push_front(const value_type& __v);
diff --git a/libcxx/include/ext/hash_map b/libcxx/include/ext/hash_map
index 01ca749..09c9811 100644
--- a/libcxx/include/ext/hash_map
+++ b/libcxx/include/ext/hash_map
@@ -570,10 +570,7 @@ hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(
}
template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
-hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(const hash_map& __u) : __table_(__u.__table_) {
- __table_.__rehash_unique(__u.bucket_count());
- insert(__u.begin(), __u.end());
-}
+hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(const hash_map& __u) : __table_(__u.__table_) {}
template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
typename hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder
diff --git a/libcxx/include/ext/hash_set b/libcxx/include/ext/hash_set
index 2796774..56aa4d8 100644
--- a/libcxx/include/ext/hash_set
+++ b/libcxx/include/ext/hash_set
@@ -356,10 +356,7 @@ hash_set<_Value, _Hash, _Pred, _Alloc>::hash_set(
}
template <class _Value, class _Hash, class _Pred, class _Alloc>
-hash_set<_Value, _Hash, _Pred, _Alloc>::hash_set(const hash_set& __u) : __table_(__u.__table_) {
- __table_.__rehash_unique(__u.bucket_count());
- insert(__u.begin(), __u.end());
-}
+hash_set<_Value, _Hash, _Pred, _Alloc>::hash_set(const hash_set& __u) : __table_(__u.__table_) {}
template <class _Value, class _Hash, class _Pred, class _Alloc>
template <class _InputIterator>
diff --git a/libcxx/include/forward_list b/libcxx/include/forward_list
index 272e52d..56c45d0 100644
--- a/libcxx/include/forward_list
+++ b/libcxx/include/forward_list
@@ -732,50 +732,52 @@ public:
_LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void assign(size_type __n, const value_type& __v);
- _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT {
return allocator_type(this->__alloc_);
}
- _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT {
return iterator(__base::__before_begin()->__next_);
}
- _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT {
return const_iterator(__base::__before_begin()->__next_);
}
- _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { return iterator(nullptr); }
- _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT {
+ return iterator(nullptr);
+ }
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT {
return const_iterator(nullptr);
}
- _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT {
return const_iterator(__base::__before_begin()->__next_);
}
- _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT {
return const_iterator(nullptr);
}
- _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI iterator before_begin() _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI iterator before_begin() _NOEXCEPT {
return iterator(__base::__before_begin());
}
- _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator before_begin() const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator before_begin() const _NOEXCEPT {
return const_iterator(__base::__before_begin());
}
- _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator cbefore_begin() const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator cbefore_begin() const _NOEXCEPT {
return const_iterator(__base::__before_begin());
}
[[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI bool empty() const _NOEXCEPT {
return __base::__before_begin()->__next_ == nullptr;
}
- _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT {
return std::min<size_type>(__node_traits::max_size(this->__alloc_), numeric_limits<difference_type>::max());
}
- _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI reference front() {
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI reference front() {
_LIBCPP_ASSERT_NON_NULL(!empty(), "forward_list::front called on an empty list");
return __base::__before_begin()->__next_->__get_value();
}
- _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_reference front() const {
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_reference front() const {
_LIBCPP_ASSERT_NON_NULL(!empty(), "forward_list::front called on an empty list");
return __base::__before_begin()->__next_->__get_value();
}
diff --git a/libcxx/include/fstream b/libcxx/include/fstream
index b07ca63..fbe579a 100644
--- a/libcxx/include/fstream
+++ b/libcxx/include/fstream
@@ -308,19 +308,6 @@ protected:
return basic_streambuf<_CharT, _Traits>::xsputn(__str, __len);
}
- _LIBCPP_HIDE_FROM_ABI_VIRTUAL streamsize xsgetn(char_type* __str, streamsize __len) override {
- if (__always_noconv_) {
- const streamsize __n = std::min(this->egptr() - this->gptr(), __len);
- if (__n != 0) {
- traits_type::copy(__str, this->gptr(), __n);
- this->__gbump_ptrdiff(__n);
- }
- if (__len - __n >= this->egptr() - this->eback())
- return std::fread(__str + __n, sizeof(char_type), __len - __n, __file_);
- }
- return basic_streambuf<_CharT, _Traits>::xsgetn(__str, __len);
- }
-
private:
char* __extbuf_;
const char* __extbufnext_;
@@ -999,7 +986,7 @@ template <class _CharT, class _Traits>
int basic_filebuf<_CharT, _Traits>::__fseek(FILE* __file, pos_type __offset, int __whence) {
# if defined(_LIBCPP_MSVCRT_LIKE)
return _fseeki64(__file, __offset, __whence);
-# elif defined(_NEWLIB_VERSION)
+# elif _LIBCPP_LIBC_NEWLIB
return fseek(__file, __offset, __whence);
# else
return ::fseeko(__file, __offset, __whence);
@@ -1010,7 +997,7 @@ template <class _CharT, class _Traits>
typename basic_filebuf<_CharT, _Traits>::pos_type basic_filebuf<_CharT, _Traits>::__ftell(FILE* __file) {
# if defined(_LIBCPP_MSVCRT_LIKE)
return _ftelli64(__file);
-# elif defined(_NEWLIB_VERSION)
+# elif _LIBCPP_LIBC_NEWLIB
return ftell(__file);
# else
return ftello(__file);
diff --git a/libcxx/include/future b/libcxx/include/future
index 4b7c098..c249bc5 100644
--- a/libcxx/include/future
+++ b/libcxx/include/future
@@ -584,12 +584,9 @@ inline future_status __assoc_sub_state::wait_for(const chrono::duration<_Rep, _P
template <class _Rp>
class _LIBCPP_HIDDEN __assoc_state : public __assoc_sub_state {
typedef __assoc_sub_state base;
- _LIBCPP_SUPPRESS_DEPRECATED_PUSH
- typedef typename aligned_storage<sizeof(_Rp), _LIBCPP_ALIGNOF(_Rp)>::type _Up;
- _LIBCPP_SUPPRESS_DEPRECATED_POP
protected:
- _Up __value_;
+ _ALIGNAS_TYPE(_Rp) char __value_[sizeof(_Rp)];
_LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override;
@@ -1836,12 +1833,10 @@ public:
_LIBCPP_HIDE_FROM_ABI __async_func(__async_func&& __f) : __f_(std::move(__f.__f_)) {}
- _LIBCPP_HIDE_FROM_ABI _Rp operator()() { return __execute(__make_index_sequence<sizeof...(_Args) + 1>()); }
-
-private:
- template <size_t... _Indices>
- _LIBCPP_HIDE_FROM_ABI _Rp __execute(__index_sequence<_Indices...>) {
- return std::__invoke(std::move(std::get<_Indices>(__f_))...);
+ _LIBCPP_HIDE_FROM_ABI _Rp operator()() {
+ return [&]<size_t... _Indices>(__index_sequence<_Indices...>) -> _Rp {
+ return std::__invoke(std::move(std::get<_Indices>(__f_))...);
+ }(__index_sequence_for<_Fp, _Args...>{});
}
};
diff --git a/libcxx/include/initializer_list b/libcxx/include/initializer_list
index 00e0d4e..44cd456 100644
--- a/libcxx/include/initializer_list
+++ b/libcxx/include/initializer_list
@@ -78,11 +78,17 @@ public:
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 initializer_list() _NOEXCEPT : __begin_(nullptr), __size_(0) {}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 size_t size() const _NOEXCEPT { return __size_; }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 size_t size() const _NOEXCEPT {
+ return __size_;
+ }
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Ep* begin() const _NOEXCEPT { return __begin_; }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Ep* begin() const _NOEXCEPT {
+ return __begin_;
+ }
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Ep* end() const _NOEXCEPT { return __begin_ + __size_; }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Ep* end() const _NOEXCEPT {
+ return __begin_ + __size_;
+ }
};
template <class _Ep>
diff --git a/libcxx/include/latch b/libcxx/include/latch
index c3b8f62..33268d9 100644
--- a/libcxx/include/latch
+++ b/libcxx/include/latch
@@ -70,7 +70,9 @@ class latch {
atomic<ptrdiff_t> __a_;
public:
- static _LIBCPP_HIDE_FROM_ABI constexpr ptrdiff_t max() noexcept { return numeric_limits<ptrdiff_t>::max(); }
+ [[nodiscard]] static _LIBCPP_HIDE_FROM_ABI constexpr ptrdiff_t max() noexcept {
+ return numeric_limits<ptrdiff_t>::max();
+ }
inline _LIBCPP_HIDE_FROM_ABI constexpr explicit latch(ptrdiff_t __expected) : __a_(__expected) {
_LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(
@@ -97,7 +99,7 @@ public:
if (__old == __update)
__a_.notify_all();
}
- inline _LIBCPP_HIDE_FROM_ABI bool try_wait() const noexcept {
+ [[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI bool try_wait() const noexcept {
auto __value = __a_.load(memory_order_acquire);
return try_wait_impl(__value);
}
diff --git a/libcxx/include/limits b/libcxx/include/limits
index e8581cf..ff40d20 100644
--- a/libcxx/include/limits
+++ b/libcxx/include/limits
@@ -107,7 +107,7 @@ template<> class numeric_limits<cv long double>;
#else
# include <__config>
# include <__type_traits/is_arithmetic.h>
-# include <__type_traits/is_signed.h>
+# include <__type_traits/is_same.h>
# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -217,10 +217,10 @@ protected:
static _LIBCPP_CONSTEXPR const bool is_iec559 = false;
static _LIBCPP_CONSTEXPR const bool is_bounded = true;
- static _LIBCPP_CONSTEXPR const bool is_modulo = !std::is_signed<_Tp>::value;
+ static _LIBCPP_CONSTEXPR const bool is_modulo = !is_signed;
# if defined(__i386__) || defined(__x86_64__) || defined(__wasm__)
- static _LIBCPP_CONSTEXPR const bool traps = true;
+ static _LIBCPP_CONSTEXPR const bool traps = is_same<decltype(+_Tp(0)), _Tp>::value;
# else
static _LIBCPP_CONSTEXPR const bool traps = false;
# endif
diff --git a/libcxx/include/list b/libcxx/include/list
index 2898a45..a5c84ca 100644
--- a/libcxx/include/list
+++ b/libcxx/include/list
@@ -774,57 +774,71 @@ public:
_LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void assign(size_type __n, const value_type& __x);
- _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT;
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT;
- _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return this->__size_; }
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT {
+ return this->__size_;
+ }
[[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI bool empty() const _NOEXCEPT {
return __base::empty();
}
- _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT {
return std::min<size_type>(this->__node_alloc_max_size(), numeric_limits<difference_type >::max());
}
- _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { return __base::begin(); }
- _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { return __base::begin(); }
- _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { return __base::end(); }
- _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { return __base::end(); }
- _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT {
+ return __base::begin();
+ }
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT {
+ return __base::begin();
+ }
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT {
+ return __base::end();
+ }
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT {
+ return __base::end();
+ }
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT {
return __base::begin();
}
- _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT { return __base::end(); }
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT {
+ return __base::end();
+ }
- _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI reverse_iterator rbegin() _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI reverse_iterator rbegin() _NOEXCEPT {
return reverse_iterator(end());
}
- _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rbegin() const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator
+ rbegin() const _NOEXCEPT {
return const_reverse_iterator(end());
}
- _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI reverse_iterator rend() _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI reverse_iterator rend() _NOEXCEPT {
return reverse_iterator(begin());
}
- _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rend() const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rend() const _NOEXCEPT {
return const_reverse_iterator(begin());
}
- _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crbegin() const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator
+ crbegin() const _NOEXCEPT {
return const_reverse_iterator(end());
}
- _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crend() const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crend() const _NOEXCEPT {
return const_reverse_iterator(begin());
}
- _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI reference front() {
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI reference front() {
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "list::front called on empty list");
return __base::__end_.__next_->__as_node()->__get_value();
}
- _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_reference front() const {
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_reference front() const {
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "list::front called on empty list");
return __base::__end_.__next_->__as_node()->__get_value();
}
- _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI reference back() {
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI reference back() {
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "list::back called on empty list");
return __base::__end_.__prev_->__as_node()->__get_value();
}
- _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_reference back() const {
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_reference back() const {
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "list::back called on empty list");
return __base::__end_.__prev_->__as_node()->__get_value();
}
diff --git a/libcxx/include/map b/libcxx/include/map
index cc8b876..0dca11c 100644
--- a/libcxx/include/map
+++ b/libcxx/include/map
@@ -995,7 +995,7 @@ public:
_LIBCPP_HIDE_FROM_ABI map(map&& __m) = default;
- _LIBCPP_HIDE_FROM_ABI map(map&& __m, const allocator_type& __a);
+ _LIBCPP_HIDE_FROM_ABI map(map&& __m, const allocator_type& __a) : __tree_(std::move(__m.__tree_), __a) {}
_LIBCPP_HIDE_FROM_ABI map& operator=(map&& __m) = default;
@@ -1023,10 +1023,7 @@ public:
_LIBCPP_HIDE_FROM_ABI explicit map(const allocator_type& __a) : __tree_(typename __base::allocator_type(__a)) {}
- _LIBCPP_HIDE_FROM_ABI map(const map& __m, const allocator_type& __a)
- : __tree_(__m.__tree_.value_comp(), typename __base::allocator_type(__a)) {
- insert(__m.begin(), __m.end());
- }
+ _LIBCPP_HIDE_FROM_ABI map(const map& __m, const allocator_type& __alloc) : __tree_(__m.__tree_, __alloc) {}
_LIBCPP_HIDE_FROM_ABI ~map() { static_assert(sizeof(std::__diagnose_non_const_comparator<_Key, _Compare>()), ""); }
@@ -1427,18 +1424,6 @@ map(initializer_list<pair<_Key, _Tp>>, _Allocator)
# ifndef _LIBCPP_CXX03_LANG
template <class _Key, class _Tp, class _Compare, class _Allocator>
-map<_Key, _Tp, _Compare, _Allocator>::map(map&& __m, const allocator_type& __a)
- : __tree_(std::move(__m.__tree_), typename __base::allocator_type(__a)) {
- if (__a != __m.get_allocator()) {
- const_iterator __e = cend();
- while (!__m.empty()) {
- __tree_.__insert_unique_from_orphaned_node(
- __e.__i_, std::move(__m.__tree_.remove(__m.begin().__i_)->__get_value()));
- }
- }
-}
-
-template <class _Key, class _Tp, class _Compare, class _Allocator>
_Tp& map<_Key, _Tp, _Compare, _Allocator>::operator[](const key_type& __k) {
return __tree_.__emplace_unique(std::piecewise_construct, std::forward_as_tuple(__k), std::forward_as_tuple())
.first->second;
@@ -1683,7 +1668,7 @@ public:
_LIBCPP_HIDE_FROM_ABI multimap(multimap&& __m) = default;
- _LIBCPP_HIDE_FROM_ABI multimap(multimap&& __m, const allocator_type& __a);
+ _LIBCPP_HIDE_FROM_ABI multimap(multimap&& __m, const allocator_type& __a) : __tree_(std::move(__m.__tree_), __a) {}
_LIBCPP_HIDE_FROM_ABI multimap& operator=(multimap&& __m) = default;
@@ -1712,10 +1697,7 @@ public:
_LIBCPP_HIDE_FROM_ABI explicit multimap(const allocator_type& __a) : __tree_(typename __base::allocator_type(__a)) {}
- _LIBCPP_HIDE_FROM_ABI multimap(const multimap& __m, const allocator_type& __a)
- : __tree_(__m.__tree_.value_comp(), typename __base::allocator_type(__a)) {
- insert(__m.begin(), __m.end());
- }
+ _LIBCPP_HIDE_FROM_ABI multimap(const multimap& __m, const allocator_type& __a) : __tree_(__m.__tree_, __a) {}
_LIBCPP_HIDE_FROM_ABI ~multimap() {
static_assert(sizeof(std::__diagnose_non_const_comparator<_Key, _Compare>()), "");
@@ -1990,19 +1972,6 @@ multimap(initializer_list<pair<_Key, _Tp>>, _Allocator)
-> multimap<remove_const_t<_Key>, _Tp, less<remove_const_t<_Key>>, _Allocator>;
# endif
-# ifndef _LIBCPP_CXX03_LANG
-template <class _Key, class _Tp, class _Compare, class _Allocator>
-multimap<_Key, _Tp, _Compare, _Allocator>::multimap(multimap&& __m, const allocator_type& __a)
- : __tree_(std::move(__m.__tree_), typename __base::allocator_type(__a)) {
- if (__a != __m.get_allocator()) {
- const_iterator __e = cend();
- while (!__m.empty())
- __tree_.__insert_multi_from_orphaned_node(
- __e.__i_, std::move(__m.__tree_.remove(__m.begin().__i_)->__get_value()));
- }
-}
-# endif
-
template <class _Key, class _Tp, class _Compare, class _Allocator>
inline _LIBCPP_HIDE_FROM_ABI bool
operator==(const multimap<_Key, _Tp, _Compare, _Allocator>& __x, const multimap<_Key, _Tp, _Compare, _Allocator>& __y) {
diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in
index 2266a1d..bbc2617 100644
--- a/libcxx/include/module.modulemap.in
+++ b/libcxx/include/module.modulemap.in
@@ -6,6 +6,8 @@ module std_config [system] {
textual header "__configuration/abi.h"
textual header "__configuration/availability.h"
textual header "__configuration/compiler.h"
+ textual header "__configuration/experimental.h"
+ textual header "__configuration/hardening.h"
textual header "__configuration/language.h"
textual header "__configuration/platform.h"
textual header "version"
@@ -124,10 +126,6 @@ module std_core [system] {
header "__type_traits/is_base_of.h"
export std_core.type_traits.integral_constant
}
- module is_bounded_array {
- header "__type_traits/is_bounded_array.h"
- export std_core.type_traits.integral_constant
- }
module is_callable {
header "__type_traits/is_callable.h"
export std_core.type_traits.integral_constant
@@ -269,10 +267,6 @@ module std_core [system] {
header "__type_traits/is_referenceable.h"
export std_core.type_traits.integral_constant
}
- module is_replaceable {
- header "__type_traits/is_replaceable.h"
- export std_core.type_traits.integral_constant
- }
module is_same {
header "__type_traits/is_same.h"
export std_core.type_traits.integral_constant
@@ -325,10 +319,6 @@ module std_core [system] {
header "__type_traits/is_trivially_relocatable.h"
export std_core.type_traits.integral_constant
}
- module is_unbounded_array {
- header "__type_traits/is_unbounded_array.h"
- export std_core.type_traits.integral_constant
- }
module is_union {
header "__type_traits/is_union.h"
export std_core.type_traits.integral_constant
@@ -839,6 +829,7 @@ module std [system] {
module simd_utils { header "__algorithm/simd_utils.h" }
module sort_heap { header "__algorithm/sort_heap.h" }
module sort { header "__algorithm/sort.h" }
+ module specialized_algorithms { header "__algorithm/specialized_algorithms.h" }
module stable_partition { header "__algorithm/stable_partition.h" }
module stable_sort {
header "__algorithm/stable_sort.h"
@@ -1593,6 +1584,7 @@ module std [system] {
textual header "__locale_dir/support/fuchsia.h"
textual header "__locale_dir/support/linux.h"
textual header "__locale_dir/support/netbsd.h"
+ textual header "__locale_dir/support/newlib.h"
textual header "__locale_dir/support/no_locale/characters.h"
textual header "__locale_dir/support/no_locale/strtonum.h"
textual header "__locale_dir/support/windows.h"
@@ -1601,7 +1593,6 @@ module std [system] {
module locale_base_api {
textual header "__locale_dir/locale_base_api/bsd_locale_fallbacks.h"
textual header "__locale_dir/locale_base_api/ibm.h"
- textual header "__locale_dir/locale_base_api/musl.h"
textual header "__locale_dir/locale_base_api/openbsd.h"
}
export *
@@ -1639,7 +1630,6 @@ module std [system] {
module memory {
module addressof { header "__memory/addressof.h" }
module align { header "__memory/align.h" }
- module aligned_alloc { header "__memory/aligned_alloc.h" }
module allocate_at_least { header "__memory/allocate_at_least.h" }
module allocation_guard { header "__memory/allocation_guard.h" }
module allocator {
@@ -1671,7 +1661,10 @@ module std [system] {
}
module raw_storage_iterator { header "__memory/raw_storage_iterator.h" }
module shared_count { header "__memory/shared_count.h" }
- module shared_ptr { header "__memory/shared_ptr.h" }
+ module shared_ptr {
+ header "__memory/shared_ptr.h"
+ export std.functional.hash
+ }
module swap_allocator { header "__memory/swap_allocator.h" }
module temp_value { header "__memory/temp_value.h" }
module temporary_buffer {
@@ -1684,6 +1677,7 @@ module std [system] {
}
module unique_ptr {
header "__memory/unique_ptr.h"
+ export std.functional.hash
}
module unique_temporary_buffer {
header "__memory/unique_temporary_buffer.h"
@@ -2363,7 +2357,10 @@ module std [system] {
module hash_table { header "__hash_table" }
module node_handle { header "__node_handle" }
module split_buffer { header "__split_buffer" }
- module tree { header "__tree" }
+ module tree {
+ header "__tree"
+ export std.memory.unique_ptr
+ }
module std_mbstate_t {
header "__std_mbstate_t.h"
export *
@@ -2399,6 +2396,7 @@ module std [system] {
header "coroutine"
export *
+ export std.functional.hash
}
} // module std
@@ -2439,10 +2437,6 @@ module std_stdatomic_h [system] {
header "stdatomic.h"
export *
}
-module std_stdbool_h [system] {
- // <stdbool.h>'s __bool_true_false_are_defined macro requires textual inclusion.
- textual header "stdbool.h"
-}
module std_stddef_h [system] {
// <stddef.h> supports being included multiple times with different pre-defined macros
textual header "stddef.h"
diff --git a/libcxx/include/mutex b/libcxx/include/mutex
index 0b81f1b..bec0185 100644
--- a/libcxx/include/mutex
+++ b/libcxx/include/mutex
@@ -229,12 +229,12 @@ public:
recursive_mutex& operator=(const recursive_mutex&) = delete;
void lock();
- bool try_lock() _NOEXCEPT;
+ [[__nodiscard__]] bool try_lock() _NOEXCEPT;
void unlock() _NOEXCEPT;
typedef __libcpp_recursive_mutex_t* native_handle_type;
- _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() { return &__m_; }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() { return &__m_; }
};
class _LIBCPP_EXPORTED_FROM_ABI timed_mutex {
@@ -251,14 +251,14 @@ public:
public:
void lock();
- bool try_lock() _NOEXCEPT;
+ [[__nodiscard__]] bool try_lock() _NOEXCEPT;
template <class _Rep, class _Period>
- _LIBCPP_HIDE_FROM_ABI bool try_lock_for(const chrono::duration<_Rep, _Period>& __d) {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool try_lock_for(const chrono::duration<_Rep, _Period>& __d) {
return try_lock_until(chrono::steady_clock::now() + __d);
}
template <class _Clock, class _Duration>
- _LIBCPP_HIDE_FROM_ABI bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __t) {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __t) {
using namespace chrono;
unique_lock<mutex> __lk(__m_);
bool __no_timeout = _Clock::now() < __t;
@@ -288,14 +288,14 @@ public:
recursive_timed_mutex& operator=(const recursive_timed_mutex&) = delete;
void lock();
- bool try_lock() _NOEXCEPT;
+ [[__nodiscard__]] bool try_lock() _NOEXCEPT;
template <class _Rep, class _Period>
- _LIBCPP_HIDE_FROM_ABI bool try_lock_for(const chrono::duration<_Rep, _Period>& __d) {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool try_lock_for(const chrono::duration<_Rep, _Period>& __d) {
return try_lock_until(chrono::steady_clock::now() + __d);
}
template <class _Clock, class _Duration>
- _LIBCPP_HIDE_FROM_ABI bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __t) {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __t) {
using namespace chrono;
__thread_id __id = this_thread::get_id();
unique_lock<mutex> __lk(__m_);
@@ -320,7 +320,7 @@ public:
};
template <class _L0, class _L1>
-_LIBCPP_NO_THREAD_SAFETY_ANALYSIS _LIBCPP_HIDE_FROM_ABI int try_lock(_L0& __l0, _L1& __l1) {
+[[__nodiscard__]] _LIBCPP_NO_THREAD_SAFETY_ANALYSIS _LIBCPP_HIDE_FROM_ABI int try_lock(_L0& __l0, _L1& __l1) {
unique_lock<_L0> __u0(__l0, try_to_lock_t());
if (__u0.owns_lock()) {
if (__l1.try_lock()) {
@@ -335,7 +335,8 @@ _LIBCPP_NO_THREAD_SAFETY_ANALYSIS _LIBCPP_HIDE_FROM_ABI int try_lock(_L0& __l0,
# ifndef _LIBCPP_CXX03_LANG
template <class _L0, class _L1, class _L2, class... _L3>
-_LIBCPP_NO_THREAD_SAFETY_ANALYSIS _LIBCPP_HIDE_FROM_ABI int try_lock(_L0& __l0, _L1& __l1, _L2& __l2, _L3&... __l3) {
+[[__nodiscard__]] _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
+ _LIBCPP_HIDE_FROM_ABI int try_lock(_L0& __l0, _L1& __l1, _L2& __l2, _L3&... __l3) {
int __r = 0;
unique_lock<_L0> __u0(__l0, try_to_lock);
if (__u0.owns_lock()) {
diff --git a/libcxx/include/optional b/libcxx/include/optional
index ef1bfd3..7b979d3d 100644
--- a/libcxx/include/optional
+++ b/libcxx/include/optional
@@ -186,6 +186,71 @@ namespace std {
template<class T>
optional(T) -> optional<T>;
+ template<class T>
+ class optional<T&> { // since C++26
+ public:
+ using value_type = T;
+ using iterator = implementation-defined; // see [optional.ref.iterators]
+
+ public:
+ // [optional.ref.ctor], constructors
+ constexpr optional() noexcept = default;
+ constexpr optional(nullopt_t) noexcept : optional() {}
+ constexpr optional(const optional& rhs) noexcept = default;
+
+ template<class Arg>
+ constexpr explicit optional(in_place_t, Arg&& arg);
+ template<class U>
+ constexpr explicit(see below) optional(U&& u) noexcept(see below);
+ template<class U>
+ constexpr explicit(see below) optional(optional<U>& rhs) noexcept(see below);
+ template<class U>
+ constexpr explicit(see below) optional(const optional<U>& rhs) noexcept(see below);
+ template<class U>
+ constexpr explicit(see below) optional(optional<U>&& rhs) noexcept(see below);
+ template<class U>
+ constexpr explicit(see below) optional(const optional<U>&& rhs) noexcept(see below);
+
+ constexpr ~optional() = default;
+
+ // [optional.ref.assign], assignment
+ constexpr optional& operator=(nullopt_t) noexcept;
+ constexpr optional& operator=(const optional& rhs) noexcept = default;
+
+ template<class U> constexpr T& emplace(U&& u) noexcept(see below);
+
+ // [optional.ref.swap], swap
+ constexpr void swap(optional& rhs) noexcept;
+
+ // [optional.ref.iterators], iterator support
+ constexpr iterator begin() const noexcept;
+ constexpr iterator end() const noexcept;
+
+ // [optional.ref.observe], observers
+ constexpr T* operator->() const noexcept;
+ constexpr T& operator*() const noexcept;
+ constexpr explicit operator bool() const noexcept;
+ constexpr bool has_value() const noexcept;
+ constexpr T& value() const; // freestanding-deleted
+ template<class U = remove_cv_t<T>>
+ constexpr remove_cv_t<T> value_or(U&& u) const;
+
+ // [optional.ref.monadic], monadic operations
+ template<class F> constexpr auto and_then(F&& f) const;
+ template<class F> constexpr optional<invoke_result_t<F, T&>> transform(F&& f) const;
+ template<class F> constexpr optional or_else(F&& f) const;
+
+ // [optional.ref.mod], modifiers
+ constexpr void reset() noexcept;
+
+ private:
+ T* val = nullptr; // exposition only
+
+ // [optional.ref.expos], exposition only helper functions
+ template<class U>
+ constexpr void convert-ref-init-val(U&& u); // exposition only
+ };
+
} // namespace std
*/
@@ -210,6 +275,7 @@ namespace std {
# include <__iterator/wrap_iter.h>
# include <__memory/addressof.h>
# include <__memory/construct_at.h>
+# include <__ranges/enable_borrowed_range.h>
# include <__ranges/enable_view.h>
# include <__tuple/sfinae_helpers.h>
# include <__type_traits/add_pointer.h>
@@ -230,7 +296,6 @@ namespace std {
# include <__type_traits/is_nothrow_constructible.h>
# include <__type_traits/is_object.h>
# include <__type_traits/is_reference.h>
-# include <__type_traits/is_replaceable.h>
# include <__type_traits/is_same.h>
# include <__type_traits/is_scalar.h>
# include <__type_traits/is_swappable.h>
@@ -238,8 +303,8 @@ namespace std {
# include <__type_traits/is_trivially_constructible.h>
# include <__type_traits/is_trivially_destructible.h>
# include <__type_traits/is_trivially_relocatable.h>
-# include <__type_traits/is_unbounded_array.h>
# include <__type_traits/negation.h>
+# include <__type_traits/reference_constructs_from_temporary.h>
# include <__type_traits/remove_const.h>
# include <__type_traits/remove_cv.h>
# include <__type_traits/remove_cvref.h>
@@ -410,39 +475,30 @@ struct __optional_storage_base : __optional_destruct_base<_Tp> {
__construct(std::forward<_That>(__opt).__get());
}
}
+
+ template <class _Up>
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __assign_from_val(_Up&& __val) {
+ this->__get() = std::forward<_Up>(__val);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __swap(__optional_storage_base& __rhs) {
+ using std::swap;
+ swap(this->__get(), __rhs.__get());
+ }
};
-// optional<T&> is currently required to be ill-formed. However, it may
-// be allowed in the future. For this reason, it has already been implemented
-// to ensure we can make the change in an ABI-compatible manner.
template <class _Tp>
struct __optional_storage_base<_Tp, true> {
using value_type = _Tp;
using __raw_type _LIBCPP_NODEBUG = remove_reference_t<_Tp>;
__raw_type* __value_;
- template <class _Up>
- static _LIBCPP_HIDE_FROM_ABI constexpr bool __can_bind_reference() {
- using _RawUp = __libcpp_remove_reference_t<_Up>;
- using _UpPtr = _RawUp*;
- using _RawTp = __libcpp_remove_reference_t<_Tp>;
- using _TpPtr = _RawTp*;
- using _CheckLValueArg =
- integral_constant<bool,
- (is_lvalue_reference<_Up>::value && is_convertible<_UpPtr, _TpPtr>::value) ||
- is_same<_RawUp, reference_wrapper<_RawTp>>::value ||
- is_same<_RawUp, reference_wrapper<__remove_const_t<_RawTp>>>::value >;
- return (is_lvalue_reference<_Tp>::value && _CheckLValueArg::value) ||
- (is_rvalue_reference<_Tp>::value && !is_lvalue_reference<_Up>::value &&
- is_convertible<_UpPtr, _TpPtr>::value);
- }
-
_LIBCPP_HIDE_FROM_ABI constexpr __optional_storage_base() noexcept : __value_(nullptr) {}
template <class _UArg>
_LIBCPP_HIDE_FROM_ABI constexpr explicit __optional_storage_base(in_place_t, _UArg&& __uarg)
: __value_(std::addressof(__uarg)) {
- static_assert(__can_bind_reference<_UArg>(),
+ static_assert(!__reference_constructs_from_temporary_v<_Tp, _UArg>,
"Attempted to construct a reference element in tuple from a "
"possible temporary");
}
@@ -458,7 +514,7 @@ struct __optional_storage_base<_Tp, true> {
template <class _UArg>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __construct(_UArg&& __val) {
_LIBCPP_ASSERT_INTERNAL(!has_value(), "__construct called for engaged __optional_storage");
- static_assert(__can_bind_reference<_UArg>(),
+ static_assert(!__reference_constructs_from_temporary_v<_Tp, _UArg>,
"Attempted to construct a reference element in tuple from a "
"possible temporary");
__value_ = std::addressof(__val);
@@ -482,6 +538,15 @@ struct __optional_storage_base<_Tp, true> {
__construct(std::forward<_That>(__opt).__get());
}
}
+
+ template <class _Up>
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __assign_from_val(_Up&& __val) noexcept {
+ __value_ = std::addressof(__val);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __swap(__optional_storage_base& __rhs) noexcept {
+ std::swap(__value_, __rhs.__value_);
+ }
};
template <class _Tp, bool = is_trivially_copy_constructible<_Tp>::value>
@@ -593,6 +658,10 @@ constexpr bool ranges::enable_view<optional<_Tp>> = true;
template <class _Tp>
constexpr range_format format_kind<optional<_Tp>> = range_format::disabled;
+
+template <class _Tp>
+constexpr bool ranges::enable_borrowed_range<optional<_Tp&>> = true;
+
# endif
# if _LIBCPP_STD_VER >= 20
@@ -607,19 +676,19 @@ struct __is_std_optional : false_type {};
template <class _Tp>
struct __is_std_optional<optional<_Tp>> : true_type {};
-template <class _Tp>
-class _LIBCPP_DECLSPEC_EMPTY_BASES optional
- : private __optional_move_assign_base<_Tp>,
- private __optional_sfinae_ctor_base_t<_Tp>,
- private __optional_sfinae_assign_base_t<_Tp> {
- using __base _LIBCPP_NODEBUG = __optional_move_assign_base<_Tp>;
+template <class _Tp, class = void>
+struct __optional_iterator {};
- using __pointer _LIBCPP_NODEBUG = std::add_pointer_t<_Tp>;
- using __const_pointer _LIBCPP_NODEBUG = std::add_pointer_t<const _Tp>;
+template <class _Tp>
+struct __optional_iterator<
+ _Tp,
+ enable_if_t<!(is_lvalue_reference_v<_Tp> && is_function_v<__libcpp_remove_reference_t<_Tp>>) &&
+ !(is_lvalue_reference_v<_Tp> && is_array_v<__libcpp_remove_reference_t<_Tp>>)> > {
+private:
+ using __pointer _LIBCPP_NODEBUG = add_pointer_t<remove_reference_t<_Tp>>;
+ using __const_pointer _LIBCPP_NODEBUG = add_pointer_t<const remove_reference_t<_Tp>>;
public:
- using value_type = _Tp;
-
# if _LIBCPP_STD_VER >= 26
# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS_IN_OPTIONAL
using iterator = __bounded_iter<__wrap_iter<__pointer>>;
@@ -628,20 +697,86 @@ public:
using iterator = __wrap_iter<__pointer>;
using const_iterator = __wrap_iter<__const_pointer>;
# endif
+
+ // [optional.iterators], iterator support
+ _LIBCPP_HIDE_FROM_ABI constexpr iterator begin() noexcept {
+ auto& __derived_self = static_cast<optional<_Tp>&>(*this);
+ auto __ptr = [&__derived_self]() {
+ if constexpr (is_lvalue_reference_v<_Tp>) {
+ return __derived_self.has_value() ? std::addressof(__derived_self.__get()) : nullptr;
+ }
+ return std::addressof(__derived_self.__get());
+ }();
+
+# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS_IN_OPTIONAL
+ return std::__make_bounded_iter(
+ __wrap_iter<__pointer>(__ptr),
+ __wrap_iter<__pointer>(__ptr),
+ __wrap_iter<__pointer>(__ptr) + (__derived_self.has_value() ? 1 : 0));
+# else
+ return iterator(__ptr);
+# endif
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr const_iterator begin() const noexcept {
+ auto& __derived_self = static_cast<const optional<_Tp>&>(*this);
+ auto* __ptr = [&__derived_self]() {
+ if constexpr (is_lvalue_reference_v<_Tp>) {
+ return __derived_self.has_value() ? std::addressof(__derived_self.__get()) : nullptr;
+ }
+ return std::addressof(__derived_self.__get());
+ }();
+
+# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS_IN_OPTIONAL
+ return std::__make_bounded_iter(
+ __wrap_iter<__const_pointer>(__ptr),
+ __wrap_iter<__const_pointer>(__ptr),
+ __wrap_iter<__const_pointer>(__ptr) + (__derived_self.has_value() ? 1 : 0));
+# else
+ return const_iterator(__ptr);
+# endif
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr iterator end() noexcept {
+ return begin() + (static_cast<optional<_Tp>&>(*this).has_value() ? 1 : 0);
+ }
+ _LIBCPP_HIDE_FROM_ABI constexpr const_iterator end() const noexcept {
+ return begin() + (static_cast<const optional<_Tp>&>(*this).has_value() ? 1 : 0);
+ }
# endif
+};
+
+template <class _Tp>
+class _LIBCPP_DECLSPEC_EMPTY_BASES optional
+ : private __optional_move_assign_base<_Tp>,
+ private __optional_sfinae_ctor_base_t<_Tp>,
+ private __optional_sfinae_assign_base_t<_Tp>,
+ public __optional_iterator<_Tp> {
+ using __base _LIBCPP_NODEBUG = __optional_move_assign_base<_Tp>;
+
+public:
+ using value_type = __libcpp_remove_reference_t<_Tp>;
+
using __trivially_relocatable _LIBCPP_NODEBUG =
conditional_t<__libcpp_is_trivially_relocatable<_Tp>::value, optional, void>;
- using __replaceable _LIBCPP_NODEBUG = conditional_t<__is_replaceable_v<_Tp>, optional, void>;
private:
- // Disable the reference extension using this static assert.
- static_assert(!is_same_v<__remove_cvref_t<value_type>, in_place_t>,
+ static_assert(!is_same_v<__remove_cvref_t<_Tp>, in_place_t>,
"instantiation of optional with in_place_t is ill-formed");
- static_assert(!is_same_v<__remove_cvref_t<value_type>, nullopt_t>,
- "instantiation of optional with nullopt_t is ill-formed");
- static_assert(!is_reference_v<value_type>, "instantiation of optional with a reference type is ill-formed");
- static_assert(is_destructible_v<value_type>, "instantiation of optional with a non-destructible type is ill-formed");
- static_assert(!is_array_v<value_type>, "instantiation of optional with an array type is ill-formed");
+ static_assert(!is_same_v<__remove_cvref_t<_Tp>, nullopt_t>, "instantiation of optional with nullopt_t is ill-formed");
+# if _LIBCPP_STD_VER >= 26
+ static_assert(!is_rvalue_reference_v<_Tp>, "instantiation of optional with an rvalue reference type is ill-formed");
+# else
+ static_assert(!is_reference_v<_Tp>, "instantiation of optional with a reference type is ill-formed");
+# endif
+ static_assert(is_destructible_v<_Tp>, "instantiation of optional with a non-destructible type is ill-formed");
+ static_assert(!is_array_v<_Tp>, "instantiation of optional with an array type is ill-formed");
+
+# if _LIBCPP_STD_VER >= 26
+ template <class _Up>
+ constexpr static bool __libcpp_opt_ref_ctor_deleted =
+ is_lvalue_reference_v<_Tp> && reference_constructs_from_temporary_v<_Tp, _Up>;
+# endif
// LWG2756: conditionally explicit conversion from _Up
struct _CheckOptionalArgsConstructor {
@@ -716,18 +851,15 @@ public:
template <class _InPlaceT,
class... _Args,
- enable_if_t<_And<_IsSame<_InPlaceT, in_place_t>, is_constructible<value_type, _Args...>>::value, int> = 0>
+ enable_if_t<_And<_IsSame<_InPlaceT, in_place_t>, is_constructible<_Tp, _Args...>>::value, int> = 0>
_LIBCPP_HIDE_FROM_ABI constexpr explicit optional(_InPlaceT, _Args&&... __args)
: __base(in_place, std::forward<_Args>(__args)...) {}
- template <class _Up,
- class... _Args,
- enable_if_t<is_constructible_v<value_type, initializer_list<_Up>&, _Args...>, int> = 0>
+ template <class _Up, class... _Args, enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>, int> = 0>
_LIBCPP_HIDE_FROM_ABI constexpr explicit optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
: __base(in_place, __il, std::forward<_Args>(__args)...) {}
- template <class _Up = value_type,
- enable_if_t<_CheckOptionalArgsCtor<_Up>::template __enable_implicit<_Up>(), int> = 0>
+ template <class _Up = _Tp, enable_if_t<_CheckOptionalArgsCtor<_Up>::template __enable_implicit<_Up>(), int> = 0>
_LIBCPP_HIDE_FROM_ABI constexpr optional(_Up&& __v) : __base(in_place, std::forward<_Up>(__v)) {}
template <class _Up = remove_cv_t<_Tp>,
@@ -754,6 +886,38 @@ public:
this->__construct_from(std::move(__v));
}
+ // deleted optional<T&> constructors
+# if _LIBCPP_STD_VER >= 26
+ template <class _Up, class... _Args, enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>, int> = 0>
+ requires __libcpp_opt_ref_ctor_deleted<_Up>
+ explicit optional(in_place_t, initializer_list<_Up>, _Args&&...) = delete;
+
+ template <class _Up = _Tp, enable_if_t<_CheckOptionalArgsCtor<_Up>::template __enable_implicit<_Up>(), int> = 0>
+ requires __libcpp_opt_ref_ctor_deleted<_Up>
+ optional(_Up&&) = delete;
+
+ template <class _Up = remove_cv_t<_Tp>,
+ enable_if_t<_CheckOptionalArgsCtor<_Up>::template __enable_explicit<_Up>(), int> = 0>
+ requires __libcpp_opt_ref_ctor_deleted<_Up>
+ explicit optional(_Up&&) = delete;
+
+ template <class _Up, enable_if_t<_CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_implicit<_Up>(), int> = 0>
+ requires __libcpp_opt_ref_ctor_deleted<_Up>
+ optional(const optional<_Up>&) = delete;
+
+ template <class _Up, enable_if_t<_CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_explicit<_Up>(), int> = 0>
+ requires __libcpp_opt_ref_ctor_deleted<_Up>
+ explicit optional(const optional<_Up>&) = delete;
+
+ template <class _Up, enable_if_t<_CheckOptionalLikeCtor<_Up, _Up&&>::template __enable_implicit<_Up>(), int> = 0>
+ requires __libcpp_opt_ref_ctor_deleted<_Up>
+ optional(optional<_Up>&&) = delete;
+
+ template <class _Up, enable_if_t<_CheckOptionalLikeCtor<_Up, _Up&&>::template __enable_explicit<_Up>(), int> = 0>
+ requires __libcpp_opt_ref_ctor_deleted<_Up>
+ explicit optional(optional<_Up>&&) = delete;
+# endif
+
# if _LIBCPP_STD_VER >= 23
template <class _Tag,
class _Fp,
@@ -772,15 +936,15 @@ public:
_LIBCPP_HIDE_FROM_ABI constexpr optional& operator=(optional&&) = default;
// LWG2756
- template <class _Up = remove_cv_t<value_type>,
+ template <class _Up = remove_cv_t<_Tp>,
enable_if_t<_And<_IsNotSame<__remove_cvref_t<_Up>, optional>,
- _Or<_IsNotSame<__remove_cvref_t<_Up>, value_type>, _Not<is_scalar<value_type>>>,
- is_constructible<value_type, _Up>,
- is_assignable<value_type&, _Up>>::value,
+ _Or<_IsNotSame<__remove_cvref_t<_Up>, _Tp>, _Not<is_scalar<_Tp>>>,
+ is_constructible<_Tp, _Up>,
+ is_assignable<_Tp&, _Up>>::value,
int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 optional& operator=(_Up&& __v) {
if (this->has_value())
- this->__get() = std::forward<_Up>(__v);
+ this->__assign_from_val(std::forward<_Up>(__v));
else
this->__construct(std::forward<_Up>(__v));
return *this;
@@ -800,7 +964,7 @@ public:
return *this;
}
- template <class... _Args, enable_if_t<is_constructible_v<value_type, _Args...>, int> = 0>
+ template <class... _Args, enable_if_t<is_constructible_v<_Tp, _Args...>, int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp& emplace(_Args&&... __args) {
reset();
this->__construct(std::forward<_Args>(__args)...);
@@ -809,7 +973,12 @@ public:
template <class _Up,
class... _Args,
- enable_if_t<is_constructible_v<value_type, initializer_list<_Up>&, _Args...>, int> = 0>
+ enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>
+# if _LIBCPP_STD_VER >= 26
+ && !reference_constructs_from_temporary_v<_Tp&, _Up>
+# endif
+ ,
+ int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp& emplace(initializer_list<_Up> __il, _Args&&... __args) {
reset();
this->__construct(__il, std::forward<_Args>(__args)...);
@@ -817,11 +986,10 @@ public:
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
- swap(optional& __opt) noexcept(is_nothrow_move_constructible_v<value_type> && is_nothrow_swappable_v<value_type>) {
+ swap(optional& __opt) noexcept(is_nothrow_move_constructible_v<_Tp> && is_nothrow_swappable_v<_Tp>) {
if (this->has_value() == __opt.has_value()) {
- using std::swap;
if (this->has_value())
- swap(this->__get(), __opt.__get());
+ this->__swap(__opt);
} else {
if (this->has_value()) {
__opt.__construct(std::move(this->__get()));
@@ -833,60 +1001,32 @@ public:
}
}
-# if _LIBCPP_STD_VER >= 26
- // [optional.iterators], iterator support
- _LIBCPP_HIDE_FROM_ABI constexpr iterator begin() noexcept {
-# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS_IN_OPTIONAL
- return std::__make_bounded_iter(
- std::__wrap_iter<__pointer>(std::addressof(this->__get())),
- std::__wrap_iter<__pointer>(std::addressof(this->__get())),
- std::__wrap_iter<__pointer>(std::addressof(this->__get()) + (this->has_value() ? 1 : 0)));
-# else
- return iterator(std::addressof(this->__get()));
-# endif
- }
-
- _LIBCPP_HIDE_FROM_ABI constexpr const_iterator begin() const noexcept {
-# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS_IN_OPTIONAL
- return std::__make_bounded_iter(
- std::__wrap_iter<__const_pointer>(std::addressof(this->__get())),
- std::__wrap_iter<__const_pointer>(std::addressof(this->__get())),
- std::__wrap_iter<__const_pointer>(std::addressof(this->__get()) + (this->has_value() ? 1 : 0)));
-# else
- return const_iterator(std::addressof(this->__get()));
-# endif
- }
-
- _LIBCPP_HIDE_FROM_ABI constexpr iterator end() noexcept { return begin() + (this->has_value() ? 1 : 0); }
- _LIBCPP_HIDE_FROM_ABI constexpr const_iterator end() const noexcept { return begin() + (this->has_value() ? 1 : 0); }
-# endif
-
- _LIBCPP_HIDE_FROM_ABI constexpr add_pointer_t<value_type const> operator->() const noexcept {
+ _LIBCPP_HIDE_FROM_ABI constexpr add_pointer_t<_Tp const> operator->() const noexcept {
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator-> called on a disengaged value");
return std::addressof(this->__get());
}
- _LIBCPP_HIDE_FROM_ABI constexpr add_pointer_t<value_type> operator->() noexcept {
+ _LIBCPP_HIDE_FROM_ABI constexpr add_pointer_t<_Tp> operator->() noexcept {
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator-> called on a disengaged value");
return std::addressof(this->__get());
}
- _LIBCPP_HIDE_FROM_ABI constexpr const value_type& operator*() const& noexcept {
+ _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& operator*() const& noexcept {
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator* called on a disengaged value");
return this->__get();
}
- _LIBCPP_HIDE_FROM_ABI constexpr value_type& operator*() & noexcept {
+ _LIBCPP_HIDE_FROM_ABI constexpr _Tp& operator*() & noexcept {
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator* called on a disengaged value");
return this->__get();
}
- _LIBCPP_HIDE_FROM_ABI constexpr value_type&& operator*() && noexcept {
+ _LIBCPP_HIDE_FROM_ABI constexpr _Tp&& operator*() && noexcept {
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator* called on a disengaged value");
return std::move(this->__get());
}
- _LIBCPP_HIDE_FROM_ABI constexpr const value_type&& operator*() const&& noexcept {
+ _LIBCPP_HIDE_FROM_ABI constexpr const _Tp&& operator*() const&& noexcept {
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator* called on a disengaged value");
return std::move(this->__get());
}
@@ -896,48 +1036,66 @@ public:
using __base::__get;
using __base::has_value;
- _LIBCPP_HIDE_FROM_ABI constexpr value_type const& value() const& {
+ _LIBCPP_HIDE_FROM_ABI constexpr _Tp const& value() const& {
if (!this->has_value())
std::__throw_bad_optional_access();
return this->__get();
}
- _LIBCPP_HIDE_FROM_ABI constexpr value_type& value() & {
+ _LIBCPP_HIDE_FROM_ABI constexpr _Tp& value() & {
if (!this->has_value())
std::__throw_bad_optional_access();
return this->__get();
}
- _LIBCPP_HIDE_FROM_ABI constexpr value_type&& value() && {
+ _LIBCPP_HIDE_FROM_ABI constexpr _Tp&& value() && {
if (!this->has_value())
std::__throw_bad_optional_access();
return std::move(this->__get());
}
- _LIBCPP_HIDE_FROM_ABI constexpr value_type const&& value() const&& {
+ _LIBCPP_HIDE_FROM_ABI constexpr _Tp const&& value() const&& {
if (!this->has_value())
std::__throw_bad_optional_access();
return std::move(this->__get());
}
template <class _Up = remove_cv_t<_Tp>>
- _LIBCPP_HIDE_FROM_ABI constexpr value_type value_or(_Up&& __v) const& {
- static_assert(is_copy_constructible_v<value_type>, "optional<T>::value_or: T must be copy constructible");
- static_assert(is_convertible_v<_Up, value_type>, "optional<T>::value_or: U must be convertible to T");
- return this->has_value() ? this->__get() : static_cast<value_type>(std::forward<_Up>(__v));
+# if _LIBCPP_STD_VER >= 26
+ requires(!(is_lvalue_reference_v<_Tp> && is_function_v<__libcpp_remove_reference_t<_Tp>>) &&
+ !(is_lvalue_reference_v<_Tp> && is_array_v<__libcpp_remove_reference_t<_Tp>>))
+# endif
+ _LIBCPP_HIDE_FROM_ABI constexpr _Tp value_or(_Up&& __v) const& {
+ static_assert(is_copy_constructible_v<_Tp>, "optional<T>::value_or: T must be copy constructible");
+ static_assert(is_convertible_v<_Up, _Tp>, "optional<T>::value_or: U must be convertible to T");
+ return this->has_value() ? this->__get() : static_cast<_Tp>(std::forward<_Up>(__v));
+ }
+
+ template <class _Up = remove_cv_t<_Tp>>
+# if _LIBCPP_STD_VER >= 26
+ requires(!is_lvalue_reference_v<_Tp>)
+# endif
+ _LIBCPP_HIDE_FROM_ABI constexpr _Tp value_or(_Up&& __v) && {
+ static_assert(is_move_constructible_v<_Tp>, "optional<T>::value_or: T must be move constructible");
+ static_assert(is_convertible_v<_Up, _Tp>, "optional<T>::value_or: U must be convertible to T");
+ return this->has_value() ? std::move(this->__get()) : static_cast<_Tp>(std::forward<_Up>(__v));
}
+# if _LIBCPP_STD_VER >= 26
template <class _Up = remove_cv_t<_Tp>>
- _LIBCPP_HIDE_FROM_ABI constexpr value_type value_or(_Up&& __v) && {
- static_assert(is_move_constructible_v<value_type>, "optional<T>::value_or: T must be move constructible");
- static_assert(is_convertible_v<_Up, value_type>, "optional<T>::value_or: U must be convertible to T");
- return this->has_value() ? std::move(this->__get()) : static_cast<value_type>(std::forward<_Up>(__v));
+ requires(is_lvalue_reference_v<_Tp> &&
+ !(is_function_v<__libcpp_remove_reference_t<_Tp>> || is_array_v<__libcpp_remove_reference_t<_Tp>>))
+ _LIBCPP_HIDE_FROM_ABI constexpr _Tp value_or(_Up&& __v) && {
+ static_assert(is_move_constructible_v<_Tp>, "optional<T>::value_or: T must be move constructible");
+ static_assert(is_convertible_v<_Up, _Tp>, "optional<T>::value_or: U must be convertible to T");
+ return this->has_value() ? this->__get() : static_cast<_Tp>(std::forward<_Up>(__v));
}
+# endif
# if _LIBCPP_STD_VER >= 23
template <class _Func>
_LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) & {
- using _Up = invoke_result_t<_Func, value_type&>;
+ using _Up = invoke_result_t<_Func, _Tp&>;
static_assert(__is_std_optional<remove_cvref_t<_Up>>::value,
"Result of f(value()) must be a specialization of std::optional");
if (*this)
@@ -947,7 +1105,7 @@ public:
template <class _Func>
_LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const& {
- using _Up = invoke_result_t<_Func, const value_type&>;
+ using _Up = invoke_result_t<_Func, const _Tp&>;
static_assert(__is_std_optional<remove_cvref_t<_Up>>::value,
"Result of f(value()) must be a specialization of std::optional");
if (*this)
@@ -957,7 +1115,7 @@ public:
template <class _Func>
_LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) && {
- using _Up = invoke_result_t<_Func, value_type&&>;
+ using _Up = invoke_result_t<_Func, _Tp&&>;
static_assert(__is_std_optional<remove_cvref_t<_Up>>::value,
"Result of f(std::move(value())) must be a specialization of std::optional");
if (*this)
@@ -967,7 +1125,7 @@ public:
template <class _Func>
_LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const&& {
- using _Up = invoke_result_t<_Func, const value_type&&>;
+ using _Up = invoke_result_t<_Func, const _Tp&&>;
static_assert(__is_std_optional<remove_cvref_t<_Up>>::value,
"Result of f(std::move(value())) must be a specialization of std::optional");
if (*this)
@@ -977,7 +1135,7 @@ public:
template <class _Func>
_LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) & {
- using _Up = remove_cv_t<invoke_result_t<_Func, value_type&>>;
+ using _Up = remove_cv_t<invoke_result_t<_Func, _Tp&>>;
static_assert(!is_array_v<_Up>, "Result of f(value()) should not be an Array");
static_assert(!is_same_v<_Up, in_place_t>, "Result of f(value()) should not be std::in_place_t");
static_assert(!is_same_v<_Up, nullopt_t>, "Result of f(value()) should not be std::nullopt_t");
@@ -989,7 +1147,7 @@ public:
template <class _Func>
_LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) const& {
- using _Up = remove_cv_t<invoke_result_t<_Func, const value_type&>>;
+ using _Up = remove_cv_t<invoke_result_t<_Func, const _Tp&>>;
static_assert(!is_array_v<_Up>, "Result of f(value()) should not be an Array");
static_assert(!is_same_v<_Up, in_place_t>, "Result of f(value()) should not be std::in_place_t");
static_assert(!is_same_v<_Up, nullopt_t>, "Result of f(value()) should not be std::nullopt_t");
@@ -1001,7 +1159,7 @@ public:
template <class _Func>
_LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) && {
- using _Up = remove_cv_t<invoke_result_t<_Func, value_type&&>>;
+ using _Up = remove_cv_t<invoke_result_t<_Func, _Tp&&>>;
static_assert(!is_array_v<_Up>, "Result of f(std::move(value())) should not be an Array");
static_assert(!is_same_v<_Up, in_place_t>, "Result of f(std::move(value())) should not be std::in_place_t");
static_assert(!is_same_v<_Up, nullopt_t>, "Result of f(std::move(value())) should not be std::nullopt_t");
@@ -1013,7 +1171,7 @@ public:
template <class _Func>
_LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) const&& {
- using _Up = remove_cvref_t<invoke_result_t<_Func, const value_type&&>>;
+ using _Up = remove_cvref_t<invoke_result_t<_Func, const _Tp&&>>;
static_assert(!is_array_v<_Up>, "Result of f(std::move(value())) should not be an Array");
static_assert(!is_same_v<_Up, in_place_t>, "Result of f(std::move(value())) should not be std::in_place_t");
static_assert(!is_same_v<_Up, nullopt_t>, "Result of f(std::move(value())) should not be std::nullopt_t");
@@ -1025,7 +1183,7 @@ public:
template <invocable _Func>
_LIBCPP_HIDE_FROM_ABI constexpr optional or_else(_Func&& __f) const&
- requires is_copy_constructible_v<value_type>
+ requires is_copy_constructible_v<_Tp>
{
static_assert(is_same_v<remove_cvref_t<invoke_result_t<_Func>>, optional>,
"Result of f() should be the same type as this optional");
@@ -1036,7 +1194,7 @@ public:
template <invocable _Func>
_LIBCPP_HIDE_FROM_ABI constexpr optional or_else(_Func&& __f) &&
- requires is_move_constructible_v<value_type>
+ requires is_move_constructible_v<_Tp>
{
static_assert(is_same_v<remove_cvref_t<invoke_result_t<_Func>>, optional>,
"Result of f() should be the same type as this optional");
@@ -1338,7 +1496,15 @@ swap(optional<_Tp>& __x, optional<_Tp>& __y) noexcept(noexcept(__x.swap(__y))) {
__x.swap(__y);
}
-template <class _Tp>
+struct __make_optional_barrier_tag {
+ explicit __make_optional_barrier_tag() = default;
+};
+
+template <
+# if _LIBCPP_STD_VER >= 26
+ __make_optional_barrier_tag = __make_optional_barrier_tag{},
+# endif
+ class _Tp>
_LIBCPP_HIDE_FROM_ABI constexpr optional<decay_t<_Tp>> make_optional(_Tp&& __v) {
return optional<decay_t<_Tp>>(std::forward<_Tp>(__v));
}
diff --git a/libcxx/include/queue b/libcxx/include/queue
index b4b79fb..a1686bc 100644
--- a/libcxx/include/queue
+++ b/libcxx/include/queue
@@ -376,12 +376,12 @@ public:
# endif // _LIBCPP_CXX03_LANG
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool empty() const { return c.empty(); }
- _LIBCPP_HIDE_FROM_ABI size_type size() const { return c.size(); }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type size() const { return c.size(); }
- _LIBCPP_HIDE_FROM_ABI reference front() { return c.front(); }
- _LIBCPP_HIDE_FROM_ABI const_reference front() const { return c.front(); }
- _LIBCPP_HIDE_FROM_ABI reference back() { return c.back(); }
- _LIBCPP_HIDE_FROM_ABI const_reference back() const { return c.back(); }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI reference front() { return c.front(); }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reference front() const { return c.front(); }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI reference back() { return c.back(); }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reference back() const { return c.back(); }
_LIBCPP_HIDE_FROM_ABI void push(const value_type& __v) { c.push_back(__v); }
# ifndef _LIBCPP_CXX03_LANG
@@ -664,8 +664,10 @@ public:
# endif
[[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI bool empty() const { return c.empty(); }
- _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI size_type size() const { return c.size(); }
- _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_reference top() const { return c.front(); }
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI size_type size() const { return c.size(); }
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_reference top() const {
+ return c.front();
+ }
_LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void push(const value_type& __v);
# ifndef _LIBCPP_CXX03_LANG
diff --git a/libcxx/include/regex b/libcxx/include/regex
index 9bbc3a6..b6c1951 100644
--- a/libcxx/include/regex
+++ b/libcxx/include/regex
@@ -1004,7 +1004,7 @@ public:
typedef _CharT char_type;
typedef basic_string<char_type> string_type;
typedef locale locale_type;
-# if defined(__BIONIC__) || defined(_NEWLIB_VERSION)
+# if defined(__BIONIC__) || _LIBCPP_LIBC_NEWLIB
// Originally bionic's ctype_base used its own ctype masks because the
// builtin ctype implementation wasn't in libc++ yet. Bionic's ctype mask
// was only 8 bits wide and already saturated, so it used a wider type here
@@ -1013,9 +1013,7 @@ public:
// implementation, but this was not updated to match. Since then Android has
// needed to maintain a stable libc++ ABI, and this can't be changed without
// an ABI break.
- // We also need this workaround for newlib since _NEWLIB_VERSION is not
- // defined yet inside __config, so we can't set the
- // _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE macro. Additionally, newlib is
+ // We also need this workaround for newlib since newlib is
// often used for space constrained environments, so it makes sense not to
// duplicate the ctype table.
typedef uint16_t char_class_type;
diff --git a/libcxx/include/scoped_allocator b/libcxx/include/scoped_allocator
index 74effc5..c72c470 100644
--- a/libcxx/include/scoped_allocator
+++ b/libcxx/include/scoped_allocator
@@ -434,10 +434,10 @@ public:
piecewise_construct,
__transform_tuple(typename __uses_alloc_ctor< _T1, inner_allocator_type&, _Args1... >::type(),
std::move(__x),
- __make_index_sequence<sizeof...(_Args1)>()),
+ __index_sequence_for<_Args1...>()),
__transform_tuple(typename __uses_alloc_ctor< _T2, inner_allocator_type&, _Args2... >::type(),
std::move(__y),
- __make_index_sequence<sizeof...(_Args2)>()));
+ __index_sequence_for<_Args2...>()));
}
template <class _T1, class _T2>
diff --git a/libcxx/include/semaphore b/libcxx/include/semaphore
index 99c4ad2..1f19d50 100644
--- a/libcxx/include/semaphore
+++ b/libcxx/include/semaphore
@@ -133,7 +133,7 @@ class counting_semaphore {
public:
static_assert(__least_max_value >= 0, "The least maximum value must be a positive number");
- static constexpr ptrdiff_t max() noexcept { return __least_max_value; }
+ [[nodiscard]] static constexpr ptrdiff_t max() noexcept { return __least_max_value; }
_LIBCPP_HIDE_FROM_ABI constexpr explicit counting_semaphore(ptrdiff_t __count) : __semaphore_(__count) {
_LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(
@@ -156,12 +156,12 @@ public:
}
_LIBCPP_HIDE_FROM_ABI void acquire() { __semaphore_.acquire(); }
template <class _Rep, class _Period>
- _LIBCPP_HIDE_FROM_ABI bool try_acquire_for(chrono::duration<_Rep, _Period> const& __rel_time) {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool try_acquire_for(chrono::duration<_Rep, _Period> const& __rel_time) {
return __semaphore_.try_acquire_for(chrono::duration_cast<chrono::nanoseconds>(__rel_time));
}
- _LIBCPP_HIDE_FROM_ABI bool try_acquire() { return __semaphore_.try_acquire(); }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool try_acquire() { return __semaphore_.try_acquire(); }
template <class _Clock, class _Duration>
- _LIBCPP_HIDE_FROM_ABI bool try_acquire_until(chrono::time_point<_Clock, _Duration> const& __abs_time) {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool try_acquire_until(chrono::time_point<_Clock, _Duration> const& __abs_time) {
auto const __current = _Clock::now();
if (__current >= __abs_time)
return try_acquire();
diff --git a/libcxx/include/set b/libcxx/include/set
index d58b6e9..3d6f571 100644
--- a/libcxx/include/set
+++ b/libcxx/include/set
@@ -671,12 +671,10 @@ public:
_LIBCPP_HIDE_FROM_ABI explicit set(const allocator_type& __a) : __tree_(__a) {}
- _LIBCPP_HIDE_FROM_ABI set(const set& __s, const allocator_type& __a) : __tree_(__s.__tree_.value_comp(), __a) {
- insert(__s.begin(), __s.end());
- }
+ _LIBCPP_HIDE_FROM_ABI set(const set& __s, const allocator_type& __alloc) : __tree_(__s.__tree_, __alloc) {}
# ifndef _LIBCPP_CXX03_LANG
- _LIBCPP_HIDE_FROM_ABI set(set&& __s, const allocator_type& __a);
+ _LIBCPP_HIDE_FROM_ABI set(set&& __s, const allocator_type& __alloc) : __tree_(std::move(__s.__tree_), __alloc) {}
_LIBCPP_HIDE_FROM_ABI set(initializer_list<value_type> __il, const value_compare& __comp = value_compare())
: __tree_(__comp) {
@@ -946,19 +944,6 @@ template <class _Key, class _Allocator, class = enable_if_t<__is_allocator_v<_Al
set(initializer_list<_Key>, _Allocator) -> set<_Key, less<_Key>, _Allocator>;
# endif
-# ifndef _LIBCPP_CXX03_LANG
-
-template <class _Key, class _Compare, class _Allocator>
-set<_Key, _Compare, _Allocator>::set(set&& __s, const allocator_type& __a) : __tree_(std::move(__s.__tree_), __a) {
- if (__a != __s.get_allocator()) {
- const_iterator __e = cend();
- while (!__s.empty())
- insert(__e, std::move(__s.__tree_.remove(__s.begin())->__get_value()));
- }
-}
-
-# endif // _LIBCPP_CXX03_LANG
-
template <class _Key, class _Compare, class _Allocator>
inline _LIBCPP_HIDE_FROM_ABI bool
operator==(const set<_Key, _Compare, _Allocator>& __x, const set<_Key, _Compare, _Allocator>& __y) {
@@ -1128,13 +1113,10 @@ public:
# ifndef _LIBCPP_CXX03_LANG
_LIBCPP_HIDE_FROM_ABI multiset(multiset&& __s) = default;
- _LIBCPP_HIDE_FROM_ABI multiset(multiset&& __s, const allocator_type& __a);
+ _LIBCPP_HIDE_FROM_ABI multiset(multiset&& __s, const allocator_type& __a) : __tree_(std::move(__s.__tree_), __a) {}
# endif // _LIBCPP_CXX03_LANG
_LIBCPP_HIDE_FROM_ABI explicit multiset(const allocator_type& __a) : __tree_(__a) {}
- _LIBCPP_HIDE_FROM_ABI multiset(const multiset& __s, const allocator_type& __a)
- : __tree_(__s.__tree_.value_comp(), __a) {
- insert(__s.begin(), __s.end());
- }
+ _LIBCPP_HIDE_FROM_ABI multiset(const multiset& __s, const allocator_type& __a) : __tree_(__s.__tree_, __a) {}
# ifndef _LIBCPP_CXX03_LANG
_LIBCPP_HIDE_FROM_ABI multiset(initializer_list<value_type> __il, const value_compare& __comp = value_compare())
@@ -1407,20 +1389,6 @@ template <class _Key, class _Allocator, class = enable_if_t<__is_allocator_v<_Al
multiset(initializer_list<_Key>, _Allocator) -> multiset<_Key, less<_Key>, _Allocator>;
# endif
-# ifndef _LIBCPP_CXX03_LANG
-
-template <class _Key, class _Compare, class _Allocator>
-multiset<_Key, _Compare, _Allocator>::multiset(multiset&& __s, const allocator_type& __a)
- : __tree_(std::move(__s.__tree_), __a) {
- if (__a != __s.get_allocator()) {
- const_iterator __e = cend();
- while (!__s.empty())
- insert(__e, std::move(__s.__tree_.remove(__s.begin())->__get_value()));
- }
-}
-
-# endif // _LIBCPP_CXX03_LANG
-
template <class _Key, class _Compare, class _Allocator>
inline _LIBCPP_HIDE_FROM_ABI bool
operator==(const multiset<_Key, _Compare, _Allocator>& __x, const multiset<_Key, _Compare, _Allocator>& __y) {
diff --git a/libcxx/include/span b/libcxx/include/span
index 3d4f9e4..1911bad 100644
--- a/libcxx/include/span
+++ b/libcxx/include/span
@@ -310,30 +310,32 @@ public:
}
template <size_t _Count>
- _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, _Count> first() const noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, _Count> first() const noexcept {
static_assert(_Count <= _Extent, "span<T, N>::first<Count>(): Count out of range");
return span<element_type, _Count>{data(), _Count};
}
template <size_t _Count>
- _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, _Count> last() const noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, _Count> last() const noexcept {
static_assert(_Count <= _Extent, "span<T, N>::last<Count>(): Count out of range");
return span<element_type, _Count>{data() + size() - _Count, _Count};
}
- _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, dynamic_extent> first(size_type __count) const noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, dynamic_extent>
+ first(size_type __count) const noexcept {
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__count <= size(), "span<T, N>::first(count): count out of range");
return {data(), __count};
}
- _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, dynamic_extent> last(size_type __count) const noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, dynamic_extent>
+ last(size_type __count) const noexcept {
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__count <= size(), "span<T, N>::last(count): count out of range");
return {data() + size() - __count, __count};
}
template <size_t _Offset, size_t _Count = dynamic_extent>
- _LIBCPP_HIDE_FROM_ABI constexpr auto
- subspan() const noexcept -> span<element_type, _Count != dynamic_extent ? _Count : _Extent - _Offset> {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto subspan() const noexcept
+ -> span<element_type, _Count != dynamic_extent ? _Count : _Extent - _Offset> {
static_assert(_Offset <= _Extent, "span<T, N>::subspan<Offset, Count>(): Offset out of range");
static_assert(_Count == dynamic_extent || _Count <= _Extent - _Offset,
"span<T, N>::subspan<Offset, Count>(): Offset + Count out of range");
@@ -342,7 +344,7 @@ public:
return _ReturnType{data() + _Offset, _Count == dynamic_extent ? size() - _Offset : _Count};
}
- _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, dynamic_extent>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, dynamic_extent>
subspan(size_type __offset, size_type __count = dynamic_extent) const noexcept {
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__offset <= size(), "span<T, N>::subspan(offset, count): offset out of range");
if (__count == dynamic_extent)
@@ -352,52 +354,58 @@ public:
return {data() + __offset, __count};
}
- _LIBCPP_HIDE_FROM_ABI constexpr size_type size() const noexcept { return _Extent; }
- _LIBCPP_HIDE_FROM_ABI constexpr size_type size_bytes() const noexcept { return _Extent * sizeof(element_type); }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr size_type size() const noexcept { return _Extent; }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr size_type size_bytes() const noexcept {
+ return _Extent * sizeof(element_type);
+ }
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty() const noexcept { return _Extent == 0; }
- _LIBCPP_HIDE_FROM_ABI constexpr reference operator[](size_type __idx) const noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr reference operator[](size_type __idx) const noexcept {
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__idx < size(), "span<T, N>::operator[](index): index out of range");
return __data_[__idx];
}
# if _LIBCPP_STD_VER >= 26
- _LIBCPP_HIDE_FROM_ABI constexpr reference at(size_type __index) const {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr reference at(size_type __index) const {
if (__index >= size())
std::__throw_out_of_range("span");
return __data_[__index];
}
# endif
- _LIBCPP_HIDE_FROM_ABI constexpr reference front() const noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr reference front() const noexcept {
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "span<T, N>::front() on empty span");
return __data_[0];
}
- _LIBCPP_HIDE_FROM_ABI constexpr reference back() const noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr reference back() const noexcept {
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "span<T, N>::back() on empty span");
return __data_[size() - 1];
}
- _LIBCPP_HIDE_FROM_ABI constexpr pointer data() const noexcept { return __data_; }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr pointer data() const noexcept { return __data_; }
// [span.iter], span iterator support
- _LIBCPP_HIDE_FROM_ABI constexpr iterator begin() const noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr iterator begin() const noexcept {
# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS
return std::__make_bounded_iter(data(), data(), data() + size());
# else
return iterator(data());
# endif
}
- _LIBCPP_HIDE_FROM_ABI constexpr iterator end() const noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr iterator end() const noexcept {
# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS
return std::__make_bounded_iter(data() + size(), data(), data() + size());
# else
return iterator(data() + size());
# endif
}
- _LIBCPP_HIDE_FROM_ABI constexpr reverse_iterator rbegin() const noexcept { return reverse_iterator(end()); }
- _LIBCPP_HIDE_FROM_ABI constexpr reverse_iterator rend() const noexcept { return reverse_iterator(begin()); }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr reverse_iterator rbegin() const noexcept {
+ return reverse_iterator(end());
+ }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr reverse_iterator rend() const noexcept {
+ return reverse_iterator(begin());
+ }
_LIBCPP_HIDE_FROM_ABI span<const byte, _Extent * sizeof(element_type)> __as_bytes() const noexcept {
return span<const byte, _Extent * sizeof(element_type)>{reinterpret_cast<const byte*>(data()), size_bytes()};
@@ -478,36 +486,38 @@ public:
: __data_{__other.data()}, __size_{__other.size()} {}
template <size_t _Count>
- _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, _Count> first() const noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, _Count> first() const noexcept {
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Count <= size(), "span<T>::first<Count>(): Count out of range");
return span<element_type, _Count>{data(), _Count};
}
template <size_t _Count>
- _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, _Count> last() const noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, _Count> last() const noexcept {
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Count <= size(), "span<T>::last<Count>(): Count out of range");
return span<element_type, _Count>{data() + size() - _Count, _Count};
}
- _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, dynamic_extent> first(size_type __count) const noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, dynamic_extent>
+ first(size_type __count) const noexcept {
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__count <= size(), "span<T>::first(count): count out of range");
return {data(), __count};
}
- _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, dynamic_extent> last(size_type __count) const noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, dynamic_extent>
+ last(size_type __count) const noexcept {
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__count <= size(), "span<T>::last(count): count out of range");
return {data() + size() - __count, __count};
}
template <size_t _Offset, size_t _Count = dynamic_extent>
- _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, _Count> subspan() const noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, _Count> subspan() const noexcept {
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Offset <= size(), "span<T>::subspan<Offset, Count>(): Offset out of range");
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Count == dynamic_extent || _Count <= size() - _Offset,
"span<T>::subspan<Offset, Count>(): Offset + Count out of range");
return span<element_type, _Count>{data() + _Offset, _Count == dynamic_extent ? size() - _Offset : _Count};
}
- constexpr span<element_type, dynamic_extent> _LIBCPP_HIDE_FROM_ABI
+ [[nodiscard]] constexpr span<element_type, dynamic_extent> _LIBCPP_HIDE_FROM_ABI
subspan(size_type __offset, size_type __count = dynamic_extent) const noexcept {
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__offset <= size(), "span<T>::subspan(offset, count): offset out of range");
if (__count == dynamic_extent)
@@ -517,52 +527,58 @@ public:
return {data() + __offset, __count};
}
- _LIBCPP_HIDE_FROM_ABI constexpr size_type size() const noexcept { return __size_; }
- _LIBCPP_HIDE_FROM_ABI constexpr size_type size_bytes() const noexcept { return __size_ * sizeof(element_type); }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr size_type size() const noexcept { return __size_; }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr size_type size_bytes() const noexcept {
+ return __size_ * sizeof(element_type);
+ }
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty() const noexcept { return __size_ == 0; }
- _LIBCPP_HIDE_FROM_ABI constexpr reference operator[](size_type __idx) const noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr reference operator[](size_type __idx) const noexcept {
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__idx < size(), "span<T>::operator[](index): index out of range");
return __data_[__idx];
}
# if _LIBCPP_STD_VER >= 26
- _LIBCPP_HIDE_FROM_ABI constexpr reference at(size_type __index) const {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr reference at(size_type __index) const {
if (__index >= size())
std::__throw_out_of_range("span");
return __data_[__index];
}
# endif
- _LIBCPP_HIDE_FROM_ABI constexpr reference front() const noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr reference front() const noexcept {
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "span<T>::front() on empty span");
return __data_[0];
}
- _LIBCPP_HIDE_FROM_ABI constexpr reference back() const noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr reference back() const noexcept {
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "span<T>::back() on empty span");
return __data_[size() - 1];
}
- _LIBCPP_HIDE_FROM_ABI constexpr pointer data() const noexcept { return __data_; }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr pointer data() const noexcept { return __data_; }
// [span.iter], span iterator support
- _LIBCPP_HIDE_FROM_ABI constexpr iterator begin() const noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr iterator begin() const noexcept {
# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS
return std::__make_bounded_iter(data(), data(), data() + size());
# else
return iterator(data());
# endif
}
- _LIBCPP_HIDE_FROM_ABI constexpr iterator end() const noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr iterator end() const noexcept {
# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS
return std::__make_bounded_iter(data() + size(), data(), data() + size());
# else
return iterator(data() + size());
# endif
}
- _LIBCPP_HIDE_FROM_ABI constexpr reverse_iterator rbegin() const noexcept { return reverse_iterator(end()); }
- _LIBCPP_HIDE_FROM_ABI constexpr reverse_iterator rend() const noexcept { return reverse_iterator(begin()); }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr reverse_iterator rbegin() const noexcept {
+ return reverse_iterator(end());
+ }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr reverse_iterator rend() const noexcept {
+ return reverse_iterator(begin());
+ }
_LIBCPP_HIDE_FROM_ABI span<const byte, dynamic_extent> __as_bytes() const noexcept {
return {reinterpret_cast<const byte*>(data()), size_bytes()};
@@ -585,13 +601,13 @@ inline constexpr bool ranges::enable_view<span<_ElementType, _Extent>> = true;
// as_bytes & as_writable_bytes
template <class _Tp, size_t _Extent>
-_LIBCPP_HIDE_FROM_ABI auto as_bytes(span<_Tp, _Extent> __s) noexcept {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI auto as_bytes(span<_Tp, _Extent> __s) noexcept {
return __s.__as_bytes();
}
template <class _Tp, size_t _Extent>
requires(!is_const_v<_Tp>)
-_LIBCPP_HIDE_FROM_ABI auto as_writable_bytes(span<_Tp, _Extent> __s) noexcept {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI auto as_writable_bytes(span<_Tp, _Extent> __s) noexcept {
return __s.__as_writable_bytes();
}
diff --git a/libcxx/include/stack b/libcxx/include/stack
index a2f285c..537b822 100644
--- a/libcxx/include/stack
+++ b/libcxx/include/stack
@@ -235,9 +235,9 @@ public:
# endif
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool empty() const { return c.empty(); }
- _LIBCPP_HIDE_FROM_ABI size_type size() const { return c.size(); }
- _LIBCPP_HIDE_FROM_ABI reference top() { return c.back(); }
- _LIBCPP_HIDE_FROM_ABI const_reference top() const { return c.back(); }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type size() const { return c.size(); }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI reference top() { return c.back(); }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reference top() const { return c.back(); }
_LIBCPP_HIDE_FROM_ABI void push(const value_type& __v) { c.push_back(__v); }
# ifndef _LIBCPP_CXX03_LANG
diff --git a/libcxx/include/stdbool.h b/libcxx/include/stdbool.h
deleted file mode 100644
index 768d082..0000000
--- a/libcxx/include/stdbool.h
+++ /dev/null
@@ -1,44 +0,0 @@
-// -*- C++ -*-
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef _LIBCPP_STDBOOL_H
-#define _LIBCPP_STDBOOL_H
-
-/*
- stdbool.h synopsis
-
-Macros:
-
- __bool_true_false_are_defined
-
-*/
-
-#if defined(__cplusplus) && __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
-# include <__cxx03/__config>
-#else
-# include <__config>
-#endif
-
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-# pragma GCC system_header
-#endif
-
-#if __has_include_next(<stdbool.h>)
-# include_next <stdbool.h>
-#endif
-
-#ifdef __cplusplus
-# undef bool
-# undef true
-# undef false
-# undef __bool_true_false_are_defined
-# define __bool_true_false_are_defined 1
-#endif
-
-#endif // _LIBCPP_STDBOOL_H
diff --git a/libcxx/include/stdexcept b/libcxx/include/stdexcept
index 85e1162..d01de5c 100644
--- a/libcxx/include/stdexcept
+++ b/libcxx/include/stdexcept
@@ -91,7 +91,7 @@ public:
~logic_error() _NOEXCEPT override;
- const char* what() const _NOEXCEPT override;
+ [[__nodiscard__]] const char* what() const _NOEXCEPT override;
# else
public:
@@ -115,7 +115,7 @@ public:
~runtime_error() _NOEXCEPT override;
- const char* what() const _NOEXCEPT override;
+ [[__nodiscard__]] const char* what() const _NOEXCEPT override;
# else
public:
diff --git a/libcxx/include/string b/libcxx/include/string
index ede4246..2b3ba6d 100644
--- a/libcxx/include/string
+++ b/libcxx/include/string
@@ -632,7 +632,6 @@ basic_string<char32_t> operator""s( const char32_t *str, size_t len );
# include <__type_traits/is_generic_transparent_comparator.h>
# include <__type_traits/is_nothrow_assignable.h>
# include <__type_traits/is_nothrow_constructible.h>
-# include <__type_traits/is_replaceable.h>
# include <__type_traits/is_same.h>
# include <__type_traits/is_standard_layout.h>
# include <__type_traits/is_trivially_constructible.h>
@@ -757,9 +756,6 @@ public:
// external memory. In such cases, the destructor is responsible for unpoisoning
// the memory to avoid triggering false positives.
// Therefore it's crucial to ensure the destructor is called.
- //
- // However, it is replaceable since implementing move-assignment as a destroy + move-construct
- // will maintain the right ASAN state.
using __trivially_relocatable = void;
# else
using __trivially_relocatable _LIBCPP_NODEBUG = __conditional_t<
@@ -767,10 +763,6 @@ public:
basic_string,
void>;
# endif
- using __replaceable _LIBCPP_NODEBUG =
- __conditional_t<__is_replaceable_v<pointer> && __container_allocator_is_replaceable<__alloc_traits>::value,
- basic_string,
- void>;
# if __has_feature(address_sanitizer) && _LIBCPP_INSTRUMENTED_WITH_ASAN
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pointer __asan_volatile_wrapper(pointer const& __ptr) const {
@@ -1253,45 +1245,55 @@ public:
# endif
_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& operator=(value_type __c);
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator begin() _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator begin() _NOEXCEPT {
return __make_iterator(__get_pointer());
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_iterator begin() const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_iterator begin() const _NOEXCEPT {
return __make_const_iterator(__get_pointer());
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator end() _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator end() _NOEXCEPT {
return __make_iterator(__get_pointer() + size());
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_iterator end() const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_iterator end() const _NOEXCEPT {
return __make_const_iterator(__get_pointer() + size());
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reverse_iterator rbegin() _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reverse_iterator rbegin() _NOEXCEPT {
return reverse_iterator(end());
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reverse_iterator rbegin() const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reverse_iterator
+ rbegin() const _NOEXCEPT {
return const_reverse_iterator(end());
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reverse_iterator rend() _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reverse_iterator rend() _NOEXCEPT {
return reverse_iterator(begin());
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reverse_iterator rend() const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reverse_iterator rend() const _NOEXCEPT {
return const_reverse_iterator(begin());
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_iterator cbegin() const _NOEXCEPT { return begin(); }
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_iterator cend() const _NOEXCEPT { return end(); }
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reverse_iterator crbegin() const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_iterator cbegin() const _NOEXCEPT {
+ return begin();
+ }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_iterator cend() const _NOEXCEPT {
+ return end();
+ }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reverse_iterator
+ crbegin() const _NOEXCEPT {
return rbegin();
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reverse_iterator crend() const _NOEXCEPT { return rend(); }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reverse_iterator crend() const _NOEXCEPT {
+ return rend();
+ }
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type size() const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type size() const _NOEXCEPT {
return __is_long() ? __get_long_size() : __get_short_size();
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type length() const _NOEXCEPT { return size(); }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type length() const _NOEXCEPT {
+ return size();
+ }
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type max_size() const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type max_size() const _NOEXCEPT {
if (size_type __m = __alloc_traits::max_size(__alloc_); __m <= std::numeric_limits<size_type>::max() / 2) {
size_type __res = __m - __alignment;
@@ -1309,7 +1311,7 @@ public:
}
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type capacity() const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type capacity() const _NOEXCEPT {
return (__is_long() ? __get_long_cap() : static_cast<size_type>(__min_cap)) - 1;
}
@@ -1344,7 +1346,8 @@ public:
return size() == 0;
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference operator[](size_type __pos) const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference
+ operator[](size_type __pos) const _NOEXCEPT {
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__pos <= size(), "string index out of bounds");
if (__builtin_constant_p(__pos) && !__fits_in_sso(__pos)) {
return *(__get_long_pointer() + __pos);
@@ -1352,7 +1355,8 @@ public:
return *(data() + __pos);
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference operator[](size_type __pos) _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference
+ operator[](size_type __pos) _NOEXCEPT {
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__pos <= size(), "string index out of bounds");
if (__builtin_constant_p(__pos) && !__fits_in_sso(__pos)) {
return *(__get_long_pointer() + __pos);
@@ -1360,8 +1364,8 @@ public:
return *(__get_pointer() + __pos);
}
- _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference at(size_type __n) const;
- _LIBCPP_CONSTEXPR_SINCE_CXX20 reference at(size_type __n);
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference at(size_type __n) const;
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 reference at(size_type __n);
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& operator+=(const basic_string& __str) {
return append(__str);
@@ -1473,22 +1477,22 @@ public:
_LIBCPP_CONSTEXPR_SINCE_CXX20 void push_back(value_type __c);
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void pop_back();
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference front() _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference front() _NOEXCEPT {
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string::front(): string is empty");
return *__get_pointer();
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference front() const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference front() const _NOEXCEPT {
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string::front(): string is empty");
return *data();
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference back() _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference back() _NOEXCEPT {
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string::back(): string is empty");
return *(__get_pointer() + size() - 1);
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference back() const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference back() const _NOEXCEPT {
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string::back(): string is empty");
return *(data() + size() - 1);
}
@@ -1761,16 +1765,16 @@ public:
_LIBCPP_CONSTEXPR_SINCE_CXX20 size_type copy(value_type* __s, size_type __n, size_type __pos = 0) const;
# if _LIBCPP_STD_VER <= 20
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string
- substr(size_type __pos = 0, size_type __n = npos) const {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string substr(size_type __pos = 0, size_type __n = npos) const {
return basic_string(*this, __pos, __n);
}
# else
- _LIBCPP_HIDE_FROM_ABI constexpr basic_string substr(size_type __pos = 0, size_type __n = npos) const& {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr basic_string substr(size_type __pos = 0, size_type __n = npos) const& {
return basic_string(*this, __pos, __n);
}
- _LIBCPP_HIDE_FROM_ABI constexpr basic_string substr(size_type __pos = 0, size_type __n = npos) && {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr basic_string substr(size_type __pos = 0, size_type __n = npos) && {
return basic_string(std::move(*this), __pos, __n);
}
# endif
@@ -1790,231 +1794,238 @@ public:
// [string.ops]
// ------------
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const value_type* c_str() const _NOEXCEPT { return data(); }
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const value_type* data() const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const value_type* c_str() const _NOEXCEPT {
+ return data();
+ }
+
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const value_type* data() const _NOEXCEPT {
return std::__to_address(__get_pointer());
}
# if _LIBCPP_STD_VER >= 17
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 value_type* data() _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 value_type* data() _NOEXCEPT {
return std::__to_address(__get_pointer());
}
# endif
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 allocator_type get_allocator() const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 allocator_type get_allocator() const _NOEXCEPT {
return __alloc_;
}
// find
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
find(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT {
return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __str.data(), __pos, __str.size());
}
template <class _Tp, __enable_if_t<__can_be_converted_to_string_view_v<_CharT, _Traits, _Tp>, int> = 0>
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
find(const _Tp& __t, size_type __pos = 0) const _NOEXCEPT {
__self_view __sv = __t;
return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __sv.data(), __pos, __sv.size());
}
- _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type find(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
+ find(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT
_LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") {
_LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::find(): received nullptr");
return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
find(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s, size_type __pos = 0) const _NOEXCEPT {
_LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::find(): received nullptr");
return std::__str_find<value_type, size_type, traits_type, npos>(
data(), size(), __s, __pos, traits_type::length(__s));
}
- _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type find(value_type __c, size_type __pos = 0) const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type find(value_type __c, size_type __pos = 0) const _NOEXCEPT {
return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __c, __pos);
}
// rfind
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
rfind(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT {
return std::__str_rfind<value_type, size_type, traits_type, npos>(
data(), size(), __str.data(), __pos, __str.size());
}
template <class _Tp, __enable_if_t<__can_be_converted_to_string_view_v<_CharT, _Traits, _Tp>, int> = 0>
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
rfind(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT {
__self_view __sv = __t;
return std::__str_rfind<value_type, size_type, traits_type, npos>(data(), size(), __sv.data(), __pos, __sv.size());
}
- _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type rfind(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
+ rfind(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT
_LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") {
_LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::rfind(): received nullptr");
return std::__str_rfind<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
rfind(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s, size_type __pos = npos) const _NOEXCEPT {
_LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::rfind(): received nullptr");
return std::__str_rfind<value_type, size_type, traits_type, npos>(
data(), size(), __s, __pos, traits_type::length(__s));
}
- _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type rfind(value_type __c, size_type __pos = npos) const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
+ rfind(value_type __c, size_type __pos = npos) const _NOEXCEPT {
return std::__str_rfind<value_type, size_type, traits_type, npos>(data(), size(), __c, __pos);
}
// find_first_of
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
find_first_of(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT {
return std::__str_find_first_of<value_type, size_type, traits_type, npos>(
data(), size(), __str.data(), __pos, __str.size());
}
template <class _Tp, __enable_if_t<__can_be_converted_to_string_view_v<_CharT, _Traits, _Tp>, int> = 0>
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
find_first_of(const _Tp& __t, size_type __pos = 0) const _NOEXCEPT {
__self_view __sv = __t;
return std::__str_find_first_of<value_type, size_type, traits_type, npos>(
data(), size(), __sv.data(), __pos, __sv.size());
}
- _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
find_first_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT
_LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") {
_LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::find_first_of(): received nullptr");
return std::__str_find_first_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
find_first_of(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s, size_type __pos = 0) const _NOEXCEPT {
_LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::find_first_of(): received nullptr");
return std::__str_find_first_of<value_type, size_type, traits_type, npos>(
data(), size(), __s, __pos, traits_type::length(__s));
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
find_first_of(value_type __c, size_type __pos = 0) const _NOEXCEPT {
return find(__c, __pos);
}
// find_last_of
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
find_last_of(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT {
return std::__str_find_last_of<value_type, size_type, traits_type, npos>(
data(), size(), __str.data(), __pos, __str.size());
}
template <class _Tp, __enable_if_t<__can_be_converted_to_string_view_v<_CharT, _Traits, _Tp>, int> = 0>
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
find_last_of(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT {
__self_view __sv = __t;
return std::__str_find_last_of<value_type, size_type, traits_type, npos>(
data(), size(), __sv.data(), __pos, __sv.size());
}
- _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
find_last_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT
_LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") {
_LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::find_last_of(): received nullptr");
return std::__str_find_last_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
find_last_of(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s, size_type __pos = npos) const _NOEXCEPT {
_LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::find_last_of(): received nullptr");
return std::__str_find_last_of<value_type, size_type, traits_type, npos>(
data(), size(), __s, __pos, traits_type::length(__s));
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
find_last_of(value_type __c, size_type __pos = npos) const _NOEXCEPT {
return rfind(__c, __pos);
}
// find_first_not_of
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
find_first_not_of(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT {
return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>(
data(), size(), __str.data(), __pos, __str.size());
}
template <class _Tp, __enable_if_t<__can_be_converted_to_string_view_v<_CharT, _Traits, _Tp>, int> = 0>
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
find_first_not_of(const _Tp& __t, size_type __pos = 0) const _NOEXCEPT {
__self_view __sv = __t;
return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>(
data(), size(), __sv.data(), __pos, __sv.size());
}
- _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
find_first_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT
_LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") {
_LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::find_first_not_of(): received nullptr");
return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
find_first_not_of(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s, size_type __pos = 0) const _NOEXCEPT {
_LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::find_first_not_of(): received nullptr");
return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>(
data(), size(), __s, __pos, traits_type::length(__s));
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
find_first_not_of(value_type __c, size_type __pos = 0) const _NOEXCEPT {
return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>(data(), size(), __c, __pos);
}
// find_last_not_of
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
find_last_not_of(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT {
return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>(
data(), size(), __str.data(), __pos, __str.size());
}
template <class _Tp, __enable_if_t<__can_be_converted_to_string_view_v<_CharT, _Traits, _Tp>, int> = 0>
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
find_last_not_of(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT {
__self_view __sv = __t;
return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>(
data(), size(), __sv.data(), __pos, __sv.size());
}
- _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
find_last_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT
_LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") {
_LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::find_last_not_of(): received nullptr");
return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
find_last_not_of(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s, size_type __pos = npos) const _NOEXCEPT {
_LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::find_last_not_of(): received nullptr");
return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>(
data(), size(), __s, __pos, traits_type::length(__s));
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
find_last_not_of(value_type __c, size_type __pos = npos) const _NOEXCEPT {
return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>(data(), size(), __c, __pos);
}
// compare
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 int compare(const basic_string& __str) const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 int
+ compare(const basic_string& __str) const _NOEXCEPT {
return compare(__self_view(__str));
}
template <class _Tp, __enable_if_t<__can_be_converted_to_string_view_v<_CharT, _Traits, _Tp>, int> = 0>
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 int compare(const _Tp& __t) const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 int compare(const _Tp& __t) const _NOEXCEPT {
__self_view __sv = __t;
size_t __lhs_sz = size();
size_t __rhs_sz = __sv.size();
@@ -2029,18 +2040,18 @@ public:
}
template <class _Tp, __enable_if_t<__can_be_converted_to_string_view_v<_CharT, _Traits, _Tp>, int> = 0>
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 int
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 int
compare(size_type __pos1, size_type __n1, const _Tp& __t) const {
__self_view __sv = __t;
return compare(__pos1, __n1, __sv.data(), __sv.size());
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 int
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 int
compare(size_type __pos1, size_type __n1, const basic_string& __str) const {
return compare(__pos1, __n1, __str.data(), __str.size());
}
- _LIBCPP_CONSTEXPR_SINCE_CXX20 int
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 int
compare(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2 = npos) const {
return compare(__pos1, __n1, __self_view(__str), __pos2, __n2);
}
@@ -2049,53 +2060,56 @@ public:
__enable_if_t<__can_be_converted_to_string_view_v<_CharT, _Traits, _Tp> &&
!is_same<__remove_cvref_t<_Tp>, basic_string>::value,
int> = 0>
- inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 int
+ [[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 int
compare(size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2 = npos) const {
__self_view __sv = __t;
return __self_view(*this).substr(__pos1, __n1).compare(__sv.substr(__pos2, __n2));
}
- _LIBCPP_CONSTEXPR_SINCE_CXX20 int compare(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s) const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 int
+ compare(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s) const _NOEXCEPT {
_LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::compare(): received nullptr");
return compare(0, npos, __s, traits_type::length(__s));
}
- _LIBCPP_CONSTEXPR_SINCE_CXX20 int
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 int
compare(size_type __pos1, size_type __n1, const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s) const {
_LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::compare(): received nullptr");
return compare(__pos1, __n1, __s, traits_type::length(__s));
}
- _LIBCPP_CONSTEXPR_SINCE_CXX20 int
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 int
compare(size_type __pos1, size_type __n1, const value_type* __s, size_type __n2) const
_LIBCPP_DIAGNOSE_NULLPTR_IF(__n2 != 0 && __s == nullptr, " if n2 is not zero");
// starts_with
# if _LIBCPP_STD_VER >= 20
- constexpr _LIBCPP_HIDE_FROM_ABI bool starts_with(__self_view __sv) const noexcept {
+ [[__nodiscard__]] constexpr _LIBCPP_HIDE_FROM_ABI bool starts_with(__self_view __sv) const noexcept {
return __self_view(typename __self_view::__assume_valid(), data(), size()).starts_with(__sv);
}
- constexpr _LIBCPP_HIDE_FROM_ABI bool starts_with(value_type __c) const noexcept {
+ [[__nodiscard__]] constexpr _LIBCPP_HIDE_FROM_ABI bool starts_with(value_type __c) const noexcept {
return !empty() && _Traits::eq(front(), __c);
}
- constexpr _LIBCPP_HIDE_FROM_ABI bool starts_with(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s) const noexcept {
+ [[__nodiscard__]] constexpr _LIBCPP_HIDE_FROM_ABI bool
+ starts_with(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s) const noexcept {
return starts_with(__self_view(__s));
}
// ends_with
- constexpr _LIBCPP_HIDE_FROM_ABI bool ends_with(__self_view __sv) const noexcept {
+ [[__nodiscard__]] constexpr _LIBCPP_HIDE_FROM_ABI bool ends_with(__self_view __sv) const noexcept {
return __self_view(typename __self_view::__assume_valid(), data(), size()).ends_with(__sv);
}
- constexpr _LIBCPP_HIDE_FROM_ABI bool ends_with(value_type __c) const noexcept {
+ [[__nodiscard__]] constexpr _LIBCPP_HIDE_FROM_ABI bool ends_with(value_type __c) const noexcept {
return !empty() && _Traits::eq(back(), __c);
}
- constexpr _LIBCPP_HIDE_FROM_ABI bool ends_with(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s) const noexcept {
+ [[__nodiscard__]] constexpr _LIBCPP_HIDE_FROM_ABI bool
+ ends_with(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s) const noexcept {
return ends_with(__self_view(__s));
}
# endif
@@ -2103,15 +2117,16 @@ public:
// contains
# if _LIBCPP_STD_VER >= 23
- constexpr _LIBCPP_HIDE_FROM_ABI bool contains(__self_view __sv) const noexcept {
+ [[__nodiscard__]] constexpr _LIBCPP_HIDE_FROM_ABI bool contains(__self_view __sv) const noexcept {
return __self_view(typename __self_view::__assume_valid(), data(), size()).contains(__sv);
}
- constexpr _LIBCPP_HIDE_FROM_ABI bool contains(value_type __c) const noexcept {
+ [[__nodiscard__]] constexpr _LIBCPP_HIDE_FROM_ABI bool contains(value_type __c) const noexcept {
return __self_view(typename __self_view::__assume_valid(), data(), size()).contains(__c);
}
- constexpr _LIBCPP_HIDE_FROM_ABI bool contains(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s) const {
+ [[__nodiscard__]] constexpr _LIBCPP_HIDE_FROM_ABI bool
+ contains(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s) const {
return __self_view(typename __self_view::__assume_valid(), data(), size()).contains(__s);
}
# endif
@@ -2258,7 +2273,9 @@ private:
// Allocate a buffer of __capacity size with __alloc and return it
_LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX20 __long
__allocate_long_buffer(_Allocator& __alloc, size_type __capacity) {
- auto __buffer = std::__allocate_at_least(__alloc, __recommend(__capacity) + 1);
+ _LIBCPP_ASSERT_INTERNAL(!__fits_in_sso(__capacity),
+ "Trying to allocate long buffer for a capacity what would fit into the small buffer");
+ auto __buffer = std::__allocate_at_least(__alloc, __align_allocation_size(__capacity));
if (__libcpp_is_constant_evaluated()) {
for (size_type __i = 0; __i != __buffer.count; ++__i)
@@ -2350,19 +2367,36 @@ private:
return (__s + (__a - 1)) & ~(__a - 1);
}
enum { __alignment = 8 };
- static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type __recommend(size_type __s) _NOEXCEPT {
- if (__s < __min_cap) {
- return static_cast<size_type>(__min_cap) - 1;
- }
+
+ // This makes sure that we're using a capacity with some extra alignment, since allocators almost always over-align
+ // the allocations anyways, improving memory usage. More importantly, this ensures that the lowest bit is never set
+ // if __endian_factor == 2, allowing us to store whether we're in the long string inside the lowest bit.
+ _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
+ __align_allocation_size(size_type __size) _NOEXCEPT {
+ _LIBCPP_ASSERT_INTERNAL(
+ !__fits_in_sso(__size), "Trying to align allocation of a size which would fit into the SSO");
const size_type __boundary = sizeof(value_type) < __alignment ? __alignment / sizeof(value_type) : __endian_factor;
- size_type __guess = __align_it<__boundary>(__s + 1) - 1;
- if (__guess == __min_cap)
+ size_type __guess = __align_it<__boundary>(__size + 1);
+ if (__guess == __min_cap + 1)
__guess += __endian_factor;
- _LIBCPP_ASSERT_INTERNAL(__guess >= __s, "recommendation is below the requested size");
+ _LIBCPP_ASSERT_INTERNAL(__guess >= __size, "aligned allocation size is below the requested size");
return __guess;
}
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
+ __get_amortized_growth_capacity(size_type __required_capacity) {
+ size_type __max_size = max_size();
+ if (__required_capacity > __max_size)
+ __throw_length_error();
+ size_type __current_cap = capacity();
+ _LIBCPP_ASSERT_INTERNAL(
+ __current_cap < __required_capacity, "Trying to grow string even though there is enough capacity already?");
+ if (__current_cap > __max_size / 2 - __alignment)
+ return __max_size;
+ return std::max(__required_capacity, 2 * __current_cap);
+ }
+
inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void __init(const value_type* __s, size_type __sz);
inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void __init(size_type __n, value_type __c);
@@ -2693,15 +2727,10 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::__
size_type __n_del,
size_type __n_add,
const value_type* __p_new_stuff) {
- size_type __ms = max_size();
- if (__delta_cap > __ms - __old_cap)
- __throw_length_error();
+ __long __buffer = __allocate_long_buffer(__alloc_, __get_amortized_growth_capacity(__old_cap + __delta_cap));
pointer __old_p = __get_pointer();
- size_type __cap =
- __old_cap < __ms / 2 - __alignment ? __recommend(std::max(__old_cap + __delta_cap, 2 * __old_cap)) : __ms;
__annotate_delete();
- auto __guard = std::__make_scope_guard(__annotate_new_size(*this));
- __long __buffer = __allocate_long_buffer(__alloc_, __cap);
+ auto __guard = std::__make_scope_guard(__annotate_new_size(*this));
if (__n_copy != 0)
traits_type::copy(std::__to_address(__buffer.__data_), std::__to_address(__old_p), __n_copy);
if (__n_add != 0)
@@ -2731,13 +2760,8 @@ _LIBCPP_DEPRECATED_("use __grow_by_without_replace") basic_string<_CharT, _Trait
size_type __n_copy,
size_type __n_del,
size_type __n_add) {
- size_type __ms = max_size();
- if (__delta_cap > __ms - __old_cap)
- this->__throw_length_error();
+ __long __buffer = __allocate_long_buffer(__alloc_, __get_amortized_growth_capacity(__old_cap + __delta_cap));
pointer __old_p = __get_pointer();
- size_type __cap =
- __old_cap < __ms / 2 - __alignment ? __recommend(std::max(__old_cap + __delta_cap, 2 * __old_cap)) : __ms;
- __long __buffer = __allocate_long_buffer(__alloc_, __cap);
if (__n_copy != 0)
traits_type::copy(std::__to_address(__buffer.__data_), std::__to_address(__old_p), __n_copy);
size_type __sec_cp_sz = __old_sz - __n_del - __n_copy;
@@ -3402,18 +3426,15 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::re
template <class _CharT, class _Traits, class _Allocator>
inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::shrink_to_fit() _NOEXCEPT {
- size_type __target_capacity = __recommend(size());
- if (__target_capacity == capacity())
+ if (!__is_long())
return;
- _LIBCPP_ASSERT_INTERNAL(__is_long(), "Trying to shrink small string");
-
- // We're a long string and we're shrinking into the small buffer.
const auto __ptr = __get_long_pointer();
const auto __size = __get_long_size();
const auto __cap = __get_long_cap();
- if (__fits_in_sso(__target_capacity)) {
+ // We're a long string and we're shrinking into the small buffer.
+ if (__fits_in_sso(__size)) {
__annotation_guard __g(*this);
__set_short_size(__size);
traits_type::copy(std::__to_address(__get_short_pointer()), std::__to_address(__ptr), __size + 1);
@@ -3421,6 +3442,9 @@ inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocat
return;
}
+ if (__align_allocation_size(__size) == __cap)
+ return;
+
# if _LIBCPP_HAS_EXCEPTIONS
try {
# endif // _LIBCPP_HAS_EXCEPTIONS
@@ -3827,46 +3851,52 @@ swap(basic_string<_CharT, _Traits, _Allocator>& __lhs, basic_string<_CharT, _Tra
__lhs.swap(__rhs);
}
-_LIBCPP_EXPORTED_FROM_ABI int stoi(const string& __str, size_t* __idx = nullptr, int __base = 10);
-_LIBCPP_EXPORTED_FROM_ABI long stol(const string& __str, size_t* __idx = nullptr, int __base = 10);
-_LIBCPP_EXPORTED_FROM_ABI unsigned long stoul(const string& __str, size_t* __idx = nullptr, int __base = 10);
-_LIBCPP_EXPORTED_FROM_ABI long long stoll(const string& __str, size_t* __idx = nullptr, int __base = 10);
-_LIBCPP_EXPORTED_FROM_ABI unsigned long long stoull(const string& __str, size_t* __idx = nullptr, int __base = 10);
-
-_LIBCPP_EXPORTED_FROM_ABI float stof(const string& __str, size_t* __idx = nullptr);
-_LIBCPP_EXPORTED_FROM_ABI double stod(const string& __str, size_t* __idx = nullptr);
-_LIBCPP_EXPORTED_FROM_ABI long double stold(const string& __str, size_t* __idx = nullptr);
-
-_LIBCPP_EXPORTED_FROM_ABI string to_string(int __val);
-_LIBCPP_EXPORTED_FROM_ABI string to_string(unsigned __val);
-_LIBCPP_EXPORTED_FROM_ABI string to_string(long __val);
-_LIBCPP_EXPORTED_FROM_ABI string to_string(unsigned long __val);
-_LIBCPP_EXPORTED_FROM_ABI string to_string(long long __val);
-_LIBCPP_EXPORTED_FROM_ABI string to_string(unsigned long long __val);
-_LIBCPP_EXPORTED_FROM_ABI string to_string(float __val);
-_LIBCPP_EXPORTED_FROM_ABI string to_string(double __val);
-_LIBCPP_EXPORTED_FROM_ABI string to_string(long double __val);
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI int stoi(const string& __str, size_t* __idx = nullptr, int __base = 10);
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI unsigned long
+stoul(const string& __str, size_t* __idx = nullptr, int __base = 10);
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI long stol(const string& __str, size_t* __idx = nullptr, int __base = 10);
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI long long
+stoll(const string& __str, size_t* __idx = nullptr, int __base = 10);
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI unsigned long long
+stoull(const string& __str, size_t* __idx = nullptr, int __base = 10);
+
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI float stof(const string& __str, size_t* __idx = nullptr);
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI double stod(const string& __str, size_t* __idx = nullptr);
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI long double stold(const string& __str, size_t* __idx = nullptr);
+
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(int __val);
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(unsigned __val);
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(long __val);
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(unsigned long __val);
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(long long __val);
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(unsigned long long __val);
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(float __val);
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(double __val);
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(long double __val);
# if _LIBCPP_HAS_WIDE_CHARACTERS
-_LIBCPP_EXPORTED_FROM_ABI int stoi(const wstring& __str, size_t* __idx = nullptr, int __base = 10);
-_LIBCPP_EXPORTED_FROM_ABI long stol(const wstring& __str, size_t* __idx = nullptr, int __base = 10);
-_LIBCPP_EXPORTED_FROM_ABI unsigned long stoul(const wstring& __str, size_t* __idx = nullptr, int __base = 10);
-_LIBCPP_EXPORTED_FROM_ABI long long stoll(const wstring& __str, size_t* __idx = nullptr, int __base = 10);
-_LIBCPP_EXPORTED_FROM_ABI unsigned long long stoull(const wstring& __str, size_t* __idx = nullptr, int __base = 10);
-
-_LIBCPP_EXPORTED_FROM_ABI float stof(const wstring& __str, size_t* __idx = nullptr);
-_LIBCPP_EXPORTED_FROM_ABI double stod(const wstring& __str, size_t* __idx = nullptr);
-_LIBCPP_EXPORTED_FROM_ABI long double stold(const wstring& __str, size_t* __idx = nullptr);
-
-_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(int __val);
-_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned __val);
-_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long __val);
-_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned long __val);
-_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long long __val);
-_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned long long __val);
-_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(float __val);
-_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(double __val);
-_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long double __val);
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI int stoi(const wstring& __str, size_t* __idx = nullptr, int __base = 10);
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI long stol(const wstring& __str, size_t* __idx = nullptr, int __base = 10);
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI unsigned long
+stoul(const wstring& __str, size_t* __idx = nullptr, int __base = 10);
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI long long
+stoll(const wstring& __str, size_t* __idx = nullptr, int __base = 10);
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI unsigned long long
+stoull(const wstring& __str, size_t* __idx = nullptr, int __base = 10);
+
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI float stof(const wstring& __str, size_t* __idx = nullptr);
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI double stod(const wstring& __str, size_t* __idx = nullptr);
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI long double stold(const wstring& __str, size_t* __idx = nullptr);
+
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(int __val);
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned __val);
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long __val);
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned long __val);
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long long __val);
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned long long __val);
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(float __val);
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(double __val);
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long double __val);
# endif // _LIBCPP_HAS_WIDE_CHARACTERS
template <class _CharT, class _Traits, class _Allocator>
@@ -3875,7 +3905,7 @@ _LIBCPP_TEMPLATE_DATA_VIS const typename basic_string<_CharT, _Traits, _Allocato
template <class _CharT, class _Allocator>
struct __string_hash : public __unary_function<basic_string<_CharT, char_traits<_CharT>, _Allocator>, size_t> {
- _LIBCPP_HIDE_FROM_ABI size_t
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t
operator()(const basic_string<_CharT, char_traits<_CharT>, _Allocator>& __val) const _NOEXCEPT {
return std::__do_string_hash(__val.data(), __val.data() + __val.size());
}
@@ -3946,30 +3976,31 @@ erase_if(basic_string<_CharT, _Traits, _Allocator>& __str, _Predicate __pred) {
// Literal suffixes for basic_string [basic.string.literals]
inline namespace literals {
inline namespace string_literals {
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<char>
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<char>
operator""s(const char* __str, size_t __len) {
return basic_string<char>(__str, __len);
}
# if _LIBCPP_HAS_WIDE_CHARACTERS
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<wchar_t>
-operator""s(const wchar_t* __str, size_t __len) {
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI
+_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<wchar_t> operator""s(const wchar_t* __str, size_t __len) {
return basic_string<wchar_t>(__str, __len);
}
# endif
# if _LIBCPP_HAS_CHAR8_T
-inline _LIBCPP_HIDE_FROM_ABI constexpr basic_string<char8_t> operator""s(const char8_t* __str, size_t __len) {
+[[__nodiscard__]] inline
+ _LIBCPP_HIDE_FROM_ABI constexpr basic_string<char8_t> operator""s(const char8_t* __str, size_t __len) {
return basic_string<char8_t>(__str, __len);
}
# endif
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<char16_t>
-operator""s(const char16_t* __str, size_t __len) {
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI
+_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<char16_t> operator""s(const char16_t* __str, size_t __len) {
return basic_string<char16_t>(__str, __len);
}
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<char32_t>
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<char32_t>
operator""s(const char32_t* __str, size_t __len) {
return basic_string<char32_t>(__str, __len);
}
diff --git a/libcxx/include/string_view b/libcxx/include/string_view
index 5ecaa3d..5dd04a9 100644
--- a/libcxx/include/string_view
+++ b/libcxx/include/string_view
@@ -362,11 +362,11 @@ public:
# endif
// [string.view.iterators], iterators
- _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { return cbegin(); }
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { return cbegin(); }
- _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { return cend(); }
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { return cend(); }
- _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT {
# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS
return std::__make_bounded_iter(data(), data(), data() + size());
# else
@@ -374,7 +374,7 @@ public:
# endif
}
- _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT {
# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS
return std::__make_bounded_iter(data() + size(), data(), data() + size());
# else
@@ -382,51 +382,54 @@ public:
# endif
}
- _LIBCPP_CONSTEXPR_SINCE_CXX17 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rbegin() const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX17 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator
+ rbegin() const _NOEXCEPT {
return const_reverse_iterator(cend());
}
- _LIBCPP_CONSTEXPR_SINCE_CXX17 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rend() const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX17 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rend() const _NOEXCEPT {
return const_reverse_iterator(cbegin());
}
- _LIBCPP_CONSTEXPR_SINCE_CXX17 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crbegin() const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX17 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator
+ crbegin() const _NOEXCEPT {
return const_reverse_iterator(cend());
}
- _LIBCPP_CONSTEXPR_SINCE_CXX17 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crend() const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX17 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crend() const _NOEXCEPT {
return const_reverse_iterator(cbegin());
}
// [string.view.capacity], capacity
- _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __size_; }
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __size_; }
- _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI size_type length() const _NOEXCEPT { return __size_; }
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI size_type length() const _NOEXCEPT { return __size_; }
- _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT {
return numeric_limits<size_type>::max() / sizeof(value_type);
}
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool empty() const _NOEXCEPT { return __size_ == 0; }
// [string.view.access], element access
- _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_reference operator[](size_type __pos) const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_reference
+ operator[](size_type __pos) const _NOEXCEPT {
return _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__pos < size(), "string_view[] index out of bounds"), __data_[__pos];
}
- _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_reference at(size_type __pos) const {
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_reference at(size_type __pos) const {
return __pos >= size() ? (__throw_out_of_range("string_view::at"), __data_[0]) : __data_[__pos];
}
- _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_reference front() const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_reference front() const _NOEXCEPT {
return _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string_view::front(): string is empty"), __data_[0];
}
- _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_reference back() const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_reference back() const _NOEXCEPT {
return _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string_view::back(): string is empty"), __data_[__size_ - 1];
}
- _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_pointer data() const _NOEXCEPT { return __data_; }
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_pointer data() const _NOEXCEPT { return __data_; }
// [string.view.modifiers], modifiers:
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI void remove_prefix(size_type __n) _NOEXCEPT {
@@ -459,7 +462,8 @@ public:
return __rlen;
}
- _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI basic_string_view substr(size_type __pos = 0, size_type __n = npos) const {
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI basic_string_view
+ substr(size_type __pos = 0, size_type __n = npos) const {
// Use the `__assume_valid` form of the constructor to avoid an unnecessary check. Any substring of a view is a
// valid view. In particular, `size()` is known to be smaller than `numeric_limits<difference_type>::max()`, so the
// new size is also smaller. See also https://llvm.org/PR91634.
@@ -474,7 +478,7 @@ public:
}
# endif
- _LIBCPP_CONSTEXPR_SINCE_CXX14 int compare(basic_string_view __sv) const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 int compare(basic_string_view __sv) const _NOEXCEPT {
size_type __rlen = std::min(size(), __sv.size());
int __retval = _Traits::compare(data(), __sv.data(), __rlen);
if (__retval == 0) // first __rlen chars matched
@@ -482,50 +486,51 @@ public:
return __retval;
}
- _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI int
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI int
compare(size_type __pos1, size_type __n1, basic_string_view __sv) const {
return substr(__pos1, __n1).compare(__sv);
}
- _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI int
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI int
compare(size_type __pos1, size_type __n1, basic_string_view __sv, size_type __pos2, size_type __n2) const {
return substr(__pos1, __n1).compare(__sv.substr(__pos2, __n2));
}
- _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI int
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI int
compare(const _CharT* _LIBCPP_DIAGNOSE_NULLPTR __s) const _NOEXCEPT {
return compare(basic_string_view(__s));
}
- _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI int
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI int
compare(size_type __pos1, size_type __n1, const _CharT* _LIBCPP_DIAGNOSE_NULLPTR __s) const {
return substr(__pos1, __n1).compare(basic_string_view(__s));
}
- _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI int
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI int
compare(size_type __pos1, size_type __n1, const _CharT* __s, size_type __n2) const
_LIBCPP_DIAGNOSE_NULLPTR_IF(__n2 != 0 && __s == nullptr, " if n2 is not zero") {
return substr(__pos1, __n1).compare(basic_string_view(__s, __n2));
}
// find
- _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
find(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT {
return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __s.data(), __pos, __s.size());
}
- _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type find(_CharT __c, size_type __pos = 0) const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
+ find(_CharT __c, size_type __pos = 0) const _NOEXCEPT {
return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __c, __pos);
}
- _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
find(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT
_LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") {
_LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string_view::find(): received nullptr");
return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
}
- _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
find(const _CharT* _LIBCPP_DIAGNOSE_NULLPTR __s, size_type __pos = 0) const _NOEXCEPT {
_LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string_view::find(): received nullptr");
return std::__str_find<value_type, size_type, traits_type, npos>(
@@ -533,24 +538,24 @@ public:
}
// rfind
- _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
rfind(basic_string_view __s, size_type __pos = npos) const _NOEXCEPT {
return std::__str_rfind<value_type, size_type, traits_type, npos>(data(), size(), __s.data(), __pos, __s.size());
}
- _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
rfind(_CharT __c, size_type __pos = npos) const _NOEXCEPT {
return std::__str_rfind<value_type, size_type, traits_type, npos>(data(), size(), __c, __pos);
}
- _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
rfind(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT
_LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") {
_LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string_view::rfind(): received nullptr");
return std::__str_rfind<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
}
- _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
rfind(const _CharT* _LIBCPP_DIAGNOSE_NULLPTR __s, size_type __pos = npos) const _NOEXCEPT {
_LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string_view::rfind(): received nullptr");
return std::__str_rfind<value_type, size_type, traits_type, npos>(
@@ -558,25 +563,25 @@ public:
}
// find_first_of
- _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
find_first_of(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT {
return std::__str_find_first_of<value_type, size_type, traits_type, npos>(
data(), size(), __s.data(), __pos, __s.size());
}
- _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
find_first_of(_CharT __c, size_type __pos = 0) const _NOEXCEPT {
return find(__c, __pos);
}
- _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
find_first_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT
_LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") {
_LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string_view::find_first_of(): received nullptr");
return std::__str_find_first_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
}
- _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
find_first_of(const _CharT* _LIBCPP_DIAGNOSE_NULLPTR __s, size_type __pos = 0) const _NOEXCEPT {
_LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string_view::find_first_of(): received nullptr");
return std::__str_find_first_of<value_type, size_type, traits_type, npos>(
@@ -584,25 +589,25 @@ public:
}
// find_last_of
- _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
find_last_of(basic_string_view __s, size_type __pos = npos) const _NOEXCEPT {
return std::__str_find_last_of<value_type, size_type, traits_type, npos>(
data(), size(), __s.data(), __pos, __s.size());
}
- _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
find_last_of(_CharT __c, size_type __pos = npos) const _NOEXCEPT {
return rfind(__c, __pos);
}
- _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
find_last_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT
_LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") {
_LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string_view::find_last_of(): received nullptr");
return std::__str_find_last_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
}
- _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
find_last_of(const _CharT* _LIBCPP_DIAGNOSE_NULLPTR __s, size_type __pos = npos) const _NOEXCEPT {
_LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string_view::find_last_of(): received nullptr");
return std::__str_find_last_of<value_type, size_type, traits_type, npos>(
@@ -610,25 +615,25 @@ public:
}
// find_first_not_of
- _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
find_first_not_of(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT {
return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>(
data(), size(), __s.data(), __pos, __s.size());
}
- _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
find_first_not_of(_CharT __c, size_type __pos = 0) const _NOEXCEPT {
return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>(data(), size(), __c, __pos);
}
- _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT
_LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") {
_LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string_view::find_first_not_of(): received nullptr");
return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
}
- _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
find_first_not_of(const _CharT* _LIBCPP_DIAGNOSE_NULLPTR __s, size_type __pos = 0) const _NOEXCEPT {
_LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string_view::find_first_not_of(): received nullptr");
return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>(
@@ -636,25 +641,25 @@ public:
}
// find_last_not_of
- _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
find_last_not_of(basic_string_view __s, size_type __pos = npos) const _NOEXCEPT {
return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>(
data(), size(), __s.data(), __pos, __s.size());
}
- _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
find_last_not_of(_CharT __c, size_type __pos = npos) const _NOEXCEPT {
return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>(data(), size(), __c, __pos);
}
- _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT
_LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") {
_LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string_view::find_last_not_of(): received nullptr");
return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
}
- _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
find_last_not_of(const _CharT* _LIBCPP_DIAGNOSE_NULLPTR __s, size_type __pos = npos) const _NOEXCEPT {
_LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string_view::find_last_not_of(): received nullptr");
return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>(
@@ -662,37 +667,43 @@ public:
}
# if _LIBCPP_STD_VER >= 20
- constexpr _LIBCPP_HIDE_FROM_ABI bool starts_with(basic_string_view __s) const noexcept {
+ [[nodiscard]] constexpr _LIBCPP_HIDE_FROM_ABI bool starts_with(basic_string_view __s) const noexcept {
return size() >= __s.size() && compare(0, __s.size(), __s) == 0;
}
- constexpr _LIBCPP_HIDE_FROM_ABI bool starts_with(value_type __c) const noexcept {
+ [[nodiscard]] constexpr _LIBCPP_HIDE_FROM_ABI bool starts_with(value_type __c) const noexcept {
return !empty() && _Traits::eq(front(), __c);
}
- constexpr _LIBCPP_HIDE_FROM_ABI bool starts_with(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s) const noexcept {
+ [[nodiscard]] constexpr _LIBCPP_HIDE_FROM_ABI bool
+ starts_with(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s) const noexcept {
return starts_with(basic_string_view(__s));
}
- constexpr _LIBCPP_HIDE_FROM_ABI bool ends_with(basic_string_view __s) const noexcept {
+ [[nodiscard]] constexpr _LIBCPP_HIDE_FROM_ABI bool ends_with(basic_string_view __s) const noexcept {
return size() >= __s.size() && compare(size() - __s.size(), npos, __s) == 0;
}
- constexpr _LIBCPP_HIDE_FROM_ABI bool ends_with(value_type __c) const noexcept {
+ [[nodiscard]] constexpr _LIBCPP_HIDE_FROM_ABI bool ends_with(value_type __c) const noexcept {
return !empty() && _Traits::eq(back(), __c);
}
- constexpr _LIBCPP_HIDE_FROM_ABI bool ends_with(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s) const noexcept {
+ [[nodiscard]] constexpr _LIBCPP_HIDE_FROM_ABI bool
+ ends_with(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s) const noexcept {
return ends_with(basic_string_view(__s));
}
# endif
# if _LIBCPP_STD_VER >= 23
- constexpr _LIBCPP_HIDE_FROM_ABI bool contains(basic_string_view __sv) const noexcept { return find(__sv) != npos; }
+ [[nodiscard]] constexpr _LIBCPP_HIDE_FROM_ABI bool contains(basic_string_view __sv) const noexcept {
+ return find(__sv) != npos;
+ }
- constexpr _LIBCPP_HIDE_FROM_ABI bool contains(value_type __c) const noexcept { return find(__c) != npos; }
+ [[nodiscard]] constexpr _LIBCPP_HIDE_FROM_ABI bool contains(value_type __c) const noexcept {
+ return find(__c) != npos;
+ }
- constexpr _LIBCPP_HIDE_FROM_ABI bool contains(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s) const {
+ [[nodiscard]] constexpr _LIBCPP_HIDE_FROM_ABI bool contains(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s) const {
return find(__s) != npos;
}
# endif
@@ -897,7 +908,8 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, basic_string_view<_CharT, _Trai
// [string.view.hash]
template <class _CharT>
struct __string_view_hash : public __unary_function<basic_string_view<_CharT, char_traits<_CharT> >, size_t> {
- _LIBCPP_HIDE_FROM_ABI size_t operator()(const basic_string_view<_CharT, char_traits<_CharT> > __val) const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t
+ operator()(const basic_string_view<_CharT, char_traits<_CharT> > __val) const _NOEXCEPT {
return std::__do_string_hash(__val.data(), __val.data() + __val.size());
}
};
@@ -924,30 +936,31 @@ struct hash<basic_string_view<wchar_t, char_traits<wchar_t> > > : __string_view_
# if _LIBCPP_STD_VER >= 14
inline namespace literals {
inline namespace string_view_literals {
-inline _LIBCPP_HIDE_FROM_ABI constexpr basic_string_view<char> operator""sv(const char* __str, size_t __len) noexcept {
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI constexpr basic_string_view<char>
+operator""sv(const char* __str, size_t __len) noexcept {
return basic_string_view<char>(__str, __len);
}
# if _LIBCPP_HAS_WIDE_CHARACTERS
-inline _LIBCPP_HIDE_FROM_ABI constexpr basic_string_view<wchar_t>
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI constexpr basic_string_view<wchar_t>
operator""sv(const wchar_t* __str, size_t __len) noexcept {
return basic_string_view<wchar_t>(__str, __len);
}
# endif
# if _LIBCPP_HAS_CHAR8_T
-inline _LIBCPP_HIDE_FROM_ABI constexpr basic_string_view<char8_t>
+[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI constexpr basic_string_view<char8_t>
operator""sv(const char8_t* __str, size_t __len) noexcept {
return basic_string_view<char8_t>(__str, __len);
}
# endif
-inline _LIBCPP_HIDE_FROM_ABI constexpr basic_string_view<char16_t>
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI constexpr basic_string_view<char16_t>
operator""sv(const char16_t* __str, size_t __len) noexcept {
return basic_string_view<char16_t>(__str, __len);
}
-inline _LIBCPP_HIDE_FROM_ABI constexpr basic_string_view<char32_t>
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI constexpr basic_string_view<char32_t>
operator""sv(const char32_t* __str, size_t __len) noexcept {
return basic_string_view<char32_t>(__str, __len);
}
diff --git a/libcxx/include/tuple b/libcxx/include/tuple
index 0cfcd9a..670b90f 100644
--- a/libcxx/include/tuple
+++ b/libcxx/include/tuple
@@ -252,7 +252,6 @@ template <class... Types>
# include <__type_traits/is_nothrow_assignable.h>
# include <__type_traits/is_nothrow_constructible.h>
# include <__type_traits/is_reference.h>
-# include <__type_traits/is_replaceable.h>
# include <__type_traits/is_same.h>
# include <__type_traits/is_swappable.h>
# include <__type_traits/is_trivially_relocatable.h>
@@ -577,7 +576,7 @@ __memberwise_forward_assign(_Dest& __dest, _Source&& __source, __type_list<_Up..
template <class... _Tp>
class _LIBCPP_NO_SPECIALIZATIONS tuple {
- typedef __tuple_impl<__make_index_sequence<sizeof...(_Tp)>, _Tp...> _BaseT;
+ typedef __tuple_impl<__index_sequence_for<_Tp...>, _Tp...> _BaseT;
_BaseT __base_;
@@ -596,7 +595,6 @@ class _LIBCPP_NO_SPECIALIZATIONS tuple {
public:
using __trivially_relocatable _LIBCPP_NODEBUG =
__conditional_t<_And<__libcpp_is_trivially_relocatable<_Tp>...>::value, tuple, void>;
- using __replaceable _LIBCPP_NODEBUG = __conditional_t<_And<__is_replaceable<_Tp>...>::value, tuple, void>;
// [tuple.cnstr]
@@ -860,7 +858,7 @@ public:
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 tuple&
operator=(_If<_And<is_copy_assignable<_Tp>...>::value, tuple, __nat> const& __tuple) noexcept(
_And<is_nothrow_copy_assignable<_Tp>...>::value) {
- std::__memberwise_copy_assign(*this, __tuple, __make_index_sequence<sizeof...(_Tp)>());
+ std::__memberwise_copy_assign(*this, __tuple, __index_sequence_for<_Tp...>());
return *this;
}
@@ -868,15 +866,14 @@ public:
_LIBCPP_HIDE_FROM_ABI constexpr const tuple& operator=(tuple const& __tuple) const
requires(_And<is_copy_assignable<const _Tp>...>::value)
{
- std::__memberwise_copy_assign(*this, __tuple, __make_index_sequence<sizeof...(_Tp)>());
+ std::__memberwise_copy_assign(*this, __tuple, __index_sequence_for<_Tp...>());
return *this;
}
_LIBCPP_HIDE_FROM_ABI constexpr const tuple& operator=(tuple&& __tuple) const
requires(_And<is_assignable<const _Tp&, _Tp>...>::value)
{
- std::__memberwise_forward_assign(
- *this, std::move(__tuple), __type_list<_Tp...>(), __make_index_sequence<sizeof...(_Tp)>());
+ std::__memberwise_forward_assign(*this, std::move(__tuple), __type_list<_Tp...>(), __index_sequence_for<_Tp...>());
return *this;
}
# endif // _LIBCPP_STD_VER >= 23
@@ -884,8 +881,7 @@ public:
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 tuple&
operator=(_If<_And<is_move_assignable<_Tp>...>::value, tuple, __nat>&& __tuple) noexcept(
_And<is_nothrow_move_assignable<_Tp>...>::value) {
- std::__memberwise_forward_assign(
- *this, std::move(__tuple), __type_list<_Tp...>(), __make_index_sequence<sizeof...(_Tp)>());
+ std::__memberwise_forward_assign(*this, std::move(__tuple), __type_list<_Tp...>(), __index_sequence_for<_Tp...>());
return *this;
}
@@ -895,7 +891,7 @@ public:
int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 tuple&
operator=(tuple<_Up...> const& __tuple) noexcept(_And<is_nothrow_assignable<_Tp&, _Up const&>...>::value) {
- std::__memberwise_copy_assign(*this, __tuple, __make_index_sequence<sizeof...(_Tp)>());
+ std::__memberwise_copy_assign(*this, __tuple, __index_sequence_for<_Tp...>());
return *this;
}
@@ -904,8 +900,7 @@ public:
int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 tuple&
operator=(tuple<_Up...>&& __tuple) noexcept(_And<is_nothrow_assignable<_Tp&, _Up>...>::value) {
- std::__memberwise_forward_assign(
- *this, std::move(__tuple), __type_list<_Up...>(), __make_index_sequence<sizeof...(_Tp)>());
+ std::__memberwise_forward_assign(*this, std::move(__tuple), __type_list<_Up...>(), __index_sequence_for<_Tp...>());
return *this;
}
@@ -914,7 +909,7 @@ public:
enable_if_t< _And<_BoolConstant<sizeof...(_Tp) == sizeof...(_UTypes)>,
is_assignable<const _Tp&, const _UTypes&>...>::value>* = nullptr>
_LIBCPP_HIDE_FROM_ABI constexpr const tuple& operator=(const tuple<_UTypes...>& __u) const {
- std::__memberwise_copy_assign(*this, __u, __make_index_sequence<sizeof...(_Tp)>());
+ std::__memberwise_copy_assign(*this, __u, index_sequence_for<_Tp...>());
return *this;
}
@@ -922,7 +917,7 @@ public:
enable_if_t< _And<_BoolConstant<sizeof...(_Tp) == sizeof...(_UTypes)>,
is_assignable<const _Tp&, _UTypes>...>::value>* = nullptr>
_LIBCPP_HIDE_FROM_ABI constexpr const tuple& operator=(tuple<_UTypes...>&& __u) const {
- std::__memberwise_forward_assign(*this, __u, __type_list<_UTypes...>(), __make_index_sequence<sizeof...(_Tp)>());
+ std::__memberwise_forward_assign(*this, __u, __type_list<_UTypes...>(), index_sequence_for<_Tp...>());
return *this;
}
# endif // _LIBCPP_STD_VER >= 23
@@ -988,7 +983,7 @@ public:
__enable_if_t< _And< _BoolConstant<_Np == sizeof...(_Tp)>, is_assignable<_Tp&, _Up const&>... >::value, int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 tuple&
operator=(array<_Up, _Np> const& __array) noexcept(_And<is_nothrow_assignable<_Tp&, _Up const&>...>::value) {
- std::__memberwise_copy_assign(*this, __array, __make_index_sequence<sizeof...(_Tp)>());
+ std::__memberwise_copy_assign(*this, __array, __index_sequence_for<_Tp...>());
return *this;
}
@@ -1000,7 +995,7 @@ public:
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 tuple&
operator=(array<_Up, _Np>&& __array) noexcept(_And<is_nothrow_assignable<_Tp&, _Up>...>::value) {
std::__memberwise_forward_assign(
- *this, std::move(__array), __type_list<_If<true, _Up, _Tp>...>(), __make_index_sequence<sizeof...(_Tp)>());
+ *this, std::move(__array), __type_list<_If<true, _Up, _Tp>...>(), __index_sequence_for<_Tp...>());
return *this;
}
diff --git a/libcxx/include/type_traits b/libcxx/include/type_traits
index dab0c06..f3e397e 100644
--- a/libcxx/include/type_traits
+++ b/libcxx/include/type_traits
@@ -550,9 +550,7 @@ namespace std
# if _LIBCPP_STD_VER >= 20
# include <__type_traits/common_reference.h>
-# include <__type_traits/is_bounded_array.h>
# include <__type_traits/is_constant_evaluated.h>
-# include <__type_traits/is_unbounded_array.h>
# include <__type_traits/type_identity.h>
# include <__type_traits/unwrap_ref.h>
# endif
diff --git a/libcxx/include/variant b/libcxx/include/variant
index 8e95858..df587cc 100644
--- a/libcxx/include/variant
+++ b/libcxx/include/variant
@@ -247,7 +247,6 @@ namespace std {
# include <__type_traits/is_nothrow_assignable.h>
# include <__type_traits/is_nothrow_constructible.h>
# include <__type_traits/is_reference.h>
-# include <__type_traits/is_replaceable.h>
# include <__type_traits/is_same.h>
# include <__type_traits/is_swappable.h>
# include <__type_traits/is_trivially_assignable.h>
@@ -1172,7 +1171,6 @@ class _LIBCPP_DECLSPEC_EMPTY_BASES _LIBCPP_NO_SPECIALIZATIONS variant
public:
using __trivially_relocatable _LIBCPP_NODEBUG =
conditional_t<_And<__libcpp_is_trivially_relocatable<_Types>...>::value, variant, void>;
- using __replaceable _LIBCPP_NODEBUG = conditional_t<_And<__is_replaceable<_Types>...>::value, variant, void>;
template <bool _Dummy = true,
enable_if_t<__dependent_type<is_default_constructible<__first_type>, _Dummy>::value, int> = 0>
diff --git a/libcxx/include/version b/libcxx/include/version
index b003060..05532ea 100644
--- a/libcxx/include/version
+++ b/libcxx/include/version
@@ -187,7 +187,8 @@ __cpp_lib_nonmember_container_access 201411L <array> <deque>
__cpp_lib_not_fn 202306L <functional>
201603L // C++17
__cpp_lib_null_iterators 201304L <iterator>
-__cpp_lib_optional 202110L <optional>
+__cpp_lib_optional 202506L <optional>
+ 202110L // C++23
202106L // C++20
201606L // C++17
__cpp_lib_optional_range_support 202406L <optional>
@@ -594,6 +595,8 @@ __cpp_lib_void_t 201411L <type_traits>
# define __cpp_lib_mdspan 202406L
# undef __cpp_lib_not_fn
# define __cpp_lib_not_fn 202306L
+# undef __cpp_lib_optional
+# define __cpp_lib_optional 202506L
# define __cpp_lib_optional_range_support 202406L
# undef __cpp_lib_out_ptr
# define __cpp_lib_out_ptr 202311L
diff --git a/libcxx/lib/abi/CHANGELOG.TXT b/libcxx/lib/abi/CHANGELOG.TXT
index 968dc7a..990c0a6 100644
--- a/libcxx/lib/abi/CHANGELOG.TXT
+++ b/libcxx/lib/abi/CHANGELOG.TXT
@@ -16,6 +16,20 @@ New entries should be added directly below the "Version" header.
Version 22.0
------------
+* [libc++] Allows any types of size 4 and 8 to use native platform ulock_wait
+
+ This patch added symbols for platform wait functions with the size of the type
+
+ All platforms
+ -------------
+ Symbol added: __ZNSt3__123__atomic_monitor_globalEPKv
+ Symbol added: __ZNSt3__126__atomic_wait_global_tableEPKvx
+ Symbol added: __ZNSt3__126__atomic_notify_one_nativeILm8EEEvPKv
+ Symbol added: __ZNSt3__132__atomic_notify_all_global_tableEPKv
+ Symbol added: __ZNSt3__120__atomic_wait_nativeILm8EEEvPKvS2_
+ Symbol added: __ZNSt3__126__atomic_notify_all_nativeILm8EEEvPKv
+ Symbol added: __ZNSt3__132__atomic_notify_one_global_tableEPKv
+
* [libc++] Remove __time_get_storage::{__analyze,init} from the ABI
These functions have never been used outside the dylib, so there is no point in exporting them.
diff --git a/libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist
index 3a1d895..0910243 100644
--- a/libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -534,6 +534,7 @@
{'is_defined': True, 'name': '__ZNKSt3__115basic_streambufIwNS_11char_traitsIwEEE6getlocEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNKSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNKSt3__115error_condition7messageEv', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNKSt3__117bad_function_call4whatEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNKSt3__117moneypunct_bynameIcLb0EE11do_groupingEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNKSt3__117moneypunct_bynameIcLb0EE13do_neg_formatEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNKSt3__117moneypunct_bynameIcLb0EE13do_pos_formatEv', 'type': 'FUNC'}
@@ -1125,6 +1126,7 @@
{'is_defined': True, 'name': '__ZNSt3__112system_errorD0Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__112system_errorD1Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__112system_errorD2Ev', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNSt3__113__hash_memoryEPKvm', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__113basic_filebufIcNS_11char_traitsIcEEE11__read_modeEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__113basic_filebufIcNS_11char_traitsIcEEE12__write_modeEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__113basic_filebufIcNS_11char_traitsIcEEE4openEPKcj', 'type': 'FUNC'}
@@ -1305,7 +1307,6 @@
{'is_defined': True, 'name': '__ZNSt3__113shared_futureIvED1Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__113shared_futureIvED2Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__113shared_futureIvEaSERKS1_', 'type': 'FUNC'}
-{'is_defined': True, 'name': '__ZNSt3__113__hash_memoryEPKvm', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__114__num_get_base10__get_baseERNS_8ios_baseE', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__114__num_get_base5__srcE', 'size': 0, 'type': 'OBJECT'}
{'is_defined': True, 'name': '__ZNSt3__114__num_put_base12__format_intEPcPKcbj', 'type': 'FUNC'}
@@ -1508,7 +1509,6 @@
{'is_defined': True, 'name': '__ZNSt3__117bad_function_callD0Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__117bad_function_callD1Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__117bad_function_callD2Ev', 'type': 'FUNC'}
-{'is_defined': True, 'name': '__ZNKSt3__117bad_function_call4whatEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__117iostream_categoryEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__117moneypunct_bynameIcLb0EE4initEPKc', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__117moneypunct_bynameIcLb1EE4initEPKc', 'type': 'FUNC'}
@@ -1558,6 +1558,7 @@
{'is_defined': True, 'name': '__ZNSt3__119__thread_local_dataEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__119basic_istringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEaSEOS5_', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__119basic_ostringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEaSEOS5_', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNSt3__120__atomic_wait_nativeILm8EEEvPKvS2_', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__120__get_collation_nameEPKc', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__120__libcpp_atomic_waitEPVKNS_17__cxx_atomic_implIxNS_22__cxx_atomic_base_implIxEEEEx', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__120__libcpp_atomic_waitEPVKvx', 'type': 'FUNC'}
@@ -1571,6 +1572,7 @@
{'is_defined': True, 'name': '__ZNSt3__121recursive_timed_mutexD1Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__121recursive_timed_mutexD2Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__122__libcpp_verbose_abortEPKcz', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNSt3__123__atomic_monitor_globalEPKv', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__123__cxx_atomic_notify_allEPVKNS_17__cxx_atomic_implIxNS_22__cxx_atomic_base_implIxEEEE', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__123__cxx_atomic_notify_allEPVKv', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__123__cxx_atomic_notify_oneEPVKNS_17__cxx_atomic_implIxNS_22__cxx_atomic_base_implIxEEEE', 'type': 'FUNC'}
@@ -1578,9 +1580,14 @@
{'is_defined': True, 'name': '__ZNSt3__123__libcpp_atomic_monitorEPVKNS_17__cxx_atomic_implIxNS_22__cxx_atomic_base_implIxEEEE', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__123__libcpp_atomic_monitorEPVKv', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__125notify_all_at_thread_exitERNS_18condition_variableENS_11unique_lockINS_5mutexEEE', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNSt3__126__atomic_notify_all_nativeILm8EEEvPKv', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNSt3__126__atomic_notify_one_nativeILm8EEEvPKv', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNSt3__126__atomic_wait_global_tableEPKvx', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__127__from_chars_floating_pointIdEENS_19__from_chars_resultIT_EEPKcS5_NS_12chars_formatE', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__127__from_chars_floating_pointIfEENS_19__from_chars_resultIT_EEPKcS5_NS_12chars_formatE', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__131__arrive_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseEh', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNSt3__132__atomic_notify_all_global_tableEPKv', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNSt3__132__atomic_notify_one_global_tableEPKv', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__132__destroy_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseE', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__134__construct_barrier_algorithm_baseERl', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__13cinE', 'size': 0, 'type': 'OBJECT'}
diff --git a/libcxx/lib/abi/i686-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/i686-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist
index 313de84..881914d 100644
--- a/libcxx/lib/abi/i686-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/i686-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -170,6 +170,7 @@
{'is_defined': True, 'name': '_ZNKSt6__ndk115basic_streambufIwNS_11char_traitsIwEEE6getlocEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNKSt6__ndk115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNKSt6__ndk115error_condition7messageEv', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNKSt6__ndk117bad_function_call4whatEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNKSt6__ndk117moneypunct_bynameIcLb0EE11do_groupingEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNKSt6__ndk117moneypunct_bynameIcLb0EE13do_neg_formatEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNKSt6__ndk117moneypunct_bynameIcLb0EE13do_pos_formatEv', 'type': 'FUNC'}
@@ -761,6 +762,7 @@
{'is_defined': True, 'name': '_ZNSt6__ndk112system_errorD0Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk112system_errorD1Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk112system_errorD2Ev', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt6__ndk113__hash_memoryEPKvj', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk113basic_filebufIcNS_11char_traitsIcEEE11__read_modeEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk113basic_filebufIcNS_11char_traitsIcEEE12__write_modeEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk113basic_filebufIcNS_11char_traitsIcEEE4openEPKcj', 'type': 'FUNC'}
@@ -941,7 +943,6 @@
{'is_defined': True, 'name': '_ZNSt6__ndk113shared_futureIvED1Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk113shared_futureIvED2Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk113shared_futureIvEaSERKS1_', 'type': 'FUNC'}
-{'is_defined': True, 'name': '_ZNSt6__ndk113__hash_memoryEPKvj', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk114__num_get_base10__get_baseERNS_8ios_baseE', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk114__num_get_base5__srcE', 'size': 33, 'type': 'OBJECT'}
{'is_defined': True, 'name': '_ZNSt6__ndk114__num_put_base12__format_intEPcPKcbj', 'type': 'FUNC'}
@@ -1144,7 +1145,6 @@
{'is_defined': True, 'name': '_ZNSt6__ndk117bad_function_callD0Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk117bad_function_callD1Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk117bad_function_callD2Ev', 'type': 'FUNC'}
-{'is_defined': True, 'name': '_ZNKSt6__ndk117bad_function_call4whatEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk117iostream_categoryEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk117moneypunct_bynameIcLb0EE4initEPKc', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk117moneypunct_bynameIcLb1EE4initEPKc', 'type': 'FUNC'}
@@ -1194,6 +1194,7 @@
{'is_defined': True, 'name': '_ZNSt6__ndk119__thread_local_dataEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk119basic_istringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEaSEOS5_', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk119basic_ostringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEaSEOS5_', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt6__ndk120__atomic_wait_nativeILj4EEEvPKvS2_', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk120__get_collation_nameEPKc', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk120__libcpp_atomic_waitEPVKNS_17__cxx_atomic_implIiNS_22__cxx_atomic_base_implIiEEEEi', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk120__libcpp_atomic_waitEPVKvi', 'type': 'FUNC'}
@@ -1207,6 +1208,7 @@
{'is_defined': True, 'name': '_ZNSt6__ndk121recursive_timed_mutexD1Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk121recursive_timed_mutexD2Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk122__libcpp_verbose_abortEPKcz', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt6__ndk123__atomic_monitor_globalEPKv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk123__cxx_atomic_notify_allEPVKNS_17__cxx_atomic_implIiNS_22__cxx_atomic_base_implIiEEEE', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk123__cxx_atomic_notify_allEPVKv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk123__cxx_atomic_notify_oneEPVKNS_17__cxx_atomic_implIiNS_22__cxx_atomic_base_implIiEEEE', 'type': 'FUNC'}
@@ -1214,9 +1216,14 @@
{'is_defined': True, 'name': '_ZNSt6__ndk123__libcpp_atomic_monitorEPVKNS_17__cxx_atomic_implIiNS_22__cxx_atomic_base_implIiEEEE', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk123__libcpp_atomic_monitorEPVKv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk125notify_all_at_thread_exitERNS_18condition_variableENS_11unique_lockINS_5mutexEEE', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt6__ndk126__atomic_notify_all_nativeILj4EEEvPKv', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt6__ndk126__atomic_notify_one_nativeILj4EEEvPKv', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt6__ndk126__atomic_wait_global_tableEPKvi', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk127__from_chars_floating_pointIdEENS_19__from_chars_resultIT_EEPKcS5_NS_12chars_formatE', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk127__from_chars_floating_pointIfEENS_19__from_chars_resultIT_EEPKcS5_NS_12chars_formatE', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk131__arrive_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseEh', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt6__ndk132__atomic_notify_all_global_tableEPKv', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt6__ndk132__atomic_notify_one_global_tableEPKv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk132__destroy_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseE', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk134__construct_barrier_algorithm_baseERi', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk13cinE', 'size': 148, 'type': 'OBJECT'}
diff --git a/libcxx/lib/abi/powerpc-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/powerpc-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
index 99cde72..bce5dab 100644
--- a/libcxx/lib/abi/powerpc-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/powerpc-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -96,6 +96,7 @@
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__115__codecvt_utf16IwLb1EE6do_outERPcPKwS5_RS5_S2_S2_S3_', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__115__codecvt_utf16IwLb1EE9do_lengthERPcPKcS5_m', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__115error_condition7messageEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__117bad_function_call4whatEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__118__time_get_storageIcE15__do_date_orderEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__118__time_get_storageIwE15__do_date_orderEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__119__shared_weak_count13__get_deleterERKSt9type_info', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
@@ -410,6 +411,7 @@
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__112system_errorD0Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__112system_errorD1Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__112system_errorD2Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__113__hash_memoryEPKvm', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__113random_deviceC1ERKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__113random_deviceC2ERKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__113random_deviceD1Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
@@ -418,7 +420,6 @@
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__113shared_futureIvED1Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__113shared_futureIvED2Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__113shared_futureIvEaSERKS1_', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
-{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__113__hash_memoryEPKvm', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__114__num_get_base10__get_baseERNS_8ios_baseE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__114__num_get_base5__srcE', 'storage_mapping_class': 'RO', 'type': 'OBJECT'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__114__num_put_base12__format_intEPcPKcbj', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
@@ -503,7 +504,6 @@
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__117bad_function_callD0Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__117bad_function_callD1Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__117bad_function_callD2Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
-{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__117bad_function_call4whatEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__117iostream_categoryEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__117moneypunct_bynameIcLb0EE4initEPKc', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__117moneypunct_bynameIcLb1EE4initEPKc', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
@@ -559,6 +559,7 @@
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__121recursive_timed_mutexC2Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__121recursive_timed_mutexD1Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__121recursive_timed_mutexD2Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__123__atomic_monitor_globalEPKv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__123__cxx_atomic_notify_allEPVKNS_17__cxx_atomic_implIiNS_22__cxx_atomic_base_implIiEEEE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__123__cxx_atomic_notify_allEPVKv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__123__cxx_atomic_notify_oneEPVKNS_17__cxx_atomic_implIiNS_22__cxx_atomic_base_implIiEEEE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
@@ -566,7 +567,10 @@
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__123__libcpp_atomic_monitorEPVKNS_17__cxx_atomic_implIiNS_22__cxx_atomic_base_implIiEEEE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__123__libcpp_atomic_monitorEPVKv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__125notify_all_at_thread_exitERNS_18condition_variableENS_11unique_lockINS_5mutexEEE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__126__atomic_wait_global_tableEPKvi', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__131__arrive_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseEh', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__132__atomic_notify_all_global_tableEPKv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__132__atomic_notify_one_global_tableEPKv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__132__destroy_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__134__construct_barrier_algorithm_baseERl', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__13cinE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
@@ -1705,7 +1709,10 @@
{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEaSEOS5_', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__119basic_istringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEaSEOS5_', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__119basic_ostringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEaSEOS5_', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__120__atomic_wait_nativeILm4EEEvPKvS2_', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__122__libcpp_verbose_abortEPKcz', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__126__atomic_notify_all_nativeILm4EEEvPKv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__126__atomic_notify_one_nativeILm4EEEvPKv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__127__from_chars_floating_pointIdEENS_19__from_chars_resultIT_EEPKcS5_NS_12chars_formatE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__127__from_chars_floating_pointIfEENS_19__from_chars_resultIT_EEPKcS5_NS_12chars_formatE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__14__fs10filesystem16_FilesystemClock9is_steadyE', 'storage_mapping_class': 'RO', 'type': 'OBJECT'}
diff --git a/libcxx/lib/abi/powerpc64-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/powerpc64-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
index 577d6cf..36eb5b8 100644
--- a/libcxx/lib/abi/powerpc64-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/powerpc64-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -96,6 +96,7 @@
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__115__codecvt_utf16IwLb1EE6do_outERPcPKwS5_RS5_S2_S2_S3_', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__115__codecvt_utf16IwLb1EE9do_lengthERPcPKcS5_m', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__115error_condition7messageEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__117bad_function_call4whatEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__118__time_get_storageIcE15__do_date_orderEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__118__time_get_storageIwE15__do_date_orderEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__119__shared_weak_count13__get_deleterERKSt9type_info', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
@@ -410,6 +411,7 @@
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__112system_errorD0Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__112system_errorD1Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__112system_errorD2Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__113__hash_memoryEPKvm', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__113random_deviceC1ERKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__113random_deviceC2ERKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__113random_deviceD1Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
@@ -418,7 +420,6 @@
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__113shared_futureIvED1Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__113shared_futureIvED2Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__113shared_futureIvEaSERKS1_', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
-{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__113__hash_memoryEPKvm', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__114__num_get_base10__get_baseERNS_8ios_baseE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__114__num_get_base5__srcE', 'storage_mapping_class': 'RO', 'type': 'OBJECT'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__114__num_put_base12__format_intEPcPKcbj', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
@@ -503,7 +504,6 @@
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__117bad_function_callD0Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__117bad_function_callD1Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__117bad_function_callD2Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
-{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__117bad_function_call4whatEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__117iostream_categoryEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__117moneypunct_bynameIcLb0EE4initEPKc', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__117moneypunct_bynameIcLb1EE4initEPKc', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
@@ -559,6 +559,7 @@
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__121recursive_timed_mutexC2Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__121recursive_timed_mutexD1Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__121recursive_timed_mutexD2Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__123__atomic_monitor_globalEPKv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__123__cxx_atomic_notify_allEPVKNS_17__cxx_atomic_implIlNS_22__cxx_atomic_base_implIlEEEE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__123__cxx_atomic_notify_allEPVKv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__123__cxx_atomic_notify_oneEPVKNS_17__cxx_atomic_implIlNS_22__cxx_atomic_base_implIlEEEE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
@@ -566,7 +567,10 @@
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__123__libcpp_atomic_monitorEPVKNS_17__cxx_atomic_implIlNS_22__cxx_atomic_base_implIlEEEE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__123__libcpp_atomic_monitorEPVKv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__125notify_all_at_thread_exitERNS_18condition_variableENS_11unique_lockINS_5mutexEEE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__126__atomic_wait_global_tableEPKvl', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__131__arrive_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseEh', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__132__atomic_notify_all_global_tableEPKv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__132__atomic_notify_one_global_tableEPKv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__132__destroy_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__134__construct_barrier_algorithm_baseERl', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__13cinE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
@@ -1705,7 +1709,10 @@
{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEaSEOS5_', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__119basic_istringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEaSEOS5_', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__119basic_ostringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEaSEOS5_', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__120__atomic_wait_nativeILm8EEEvPKvS2_', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__122__libcpp_verbose_abortEPKcz', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__126__atomic_notify_all_nativeILm8EEEvPKv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__126__atomic_notify_one_nativeILm8EEEvPKv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__127__from_chars_floating_pointIdEENS_19__from_chars_resultIT_EEPKcS5_NS_12chars_formatE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__127__from_chars_floating_pointIfEENS_19__from_chars_resultIT_EEPKcS5_NS_12chars_formatE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__14__fs10filesystem16_FilesystemClock9is_steadyE', 'storage_mapping_class': 'RO', 'type': 'OBJECT'}
diff --git a/libcxx/lib/abi/x86_64-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/x86_64-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist
index 1be7d8a..154b7cc 100644
--- a/libcxx/lib/abi/x86_64-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/x86_64-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -170,6 +170,7 @@
{'is_defined': True, 'name': '_ZNKSt6__ndk115basic_streambufIwNS_11char_traitsIwEEE6getlocEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNKSt6__ndk115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNKSt6__ndk115error_condition7messageEv', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNKSt6__ndk117bad_function_call4whatEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNKSt6__ndk117moneypunct_bynameIcLb0EE11do_groupingEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNKSt6__ndk117moneypunct_bynameIcLb0EE13do_neg_formatEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNKSt6__ndk117moneypunct_bynameIcLb0EE13do_pos_formatEv', 'type': 'FUNC'}
@@ -761,6 +762,7 @@
{'is_defined': True, 'name': '_ZNSt6__ndk112system_errorD0Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk112system_errorD1Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk112system_errorD2Ev', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt6__ndk113__hash_memoryEPKvm', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk113basic_filebufIcNS_11char_traitsIcEEE11__read_modeEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk113basic_filebufIcNS_11char_traitsIcEEE12__write_modeEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk113basic_filebufIcNS_11char_traitsIcEEE4openEPKcj', 'type': 'FUNC'}
@@ -941,7 +943,6 @@
{'is_defined': True, 'name': '_ZNSt6__ndk113shared_futureIvED1Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk113shared_futureIvED2Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk113shared_futureIvEaSERKS1_', 'type': 'FUNC'}
-{'is_defined': True, 'name': '_ZNSt6__ndk113__hash_memoryEPKvm', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk114__num_get_base10__get_baseERNS_8ios_baseE', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk114__num_get_base5__srcE', 'size': 33, 'type': 'OBJECT'}
{'is_defined': True, 'name': '_ZNSt6__ndk114__num_put_base12__format_intEPcPKcbj', 'type': 'FUNC'}
@@ -1144,7 +1145,6 @@
{'is_defined': True, 'name': '_ZNSt6__ndk117bad_function_callD0Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk117bad_function_callD1Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk117bad_function_callD2Ev', 'type': 'FUNC'}
-{'is_defined': True, 'name': '_ZNKSt6__ndk117bad_function_call4whatEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk117iostream_categoryEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk117moneypunct_bynameIcLb0EE4initEPKc', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk117moneypunct_bynameIcLb1EE4initEPKc', 'type': 'FUNC'}
@@ -1194,6 +1194,7 @@
{'is_defined': True, 'name': '_ZNSt6__ndk119__thread_local_dataEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk119basic_istringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEaSEOS5_', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk119basic_ostringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEaSEOS5_', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt6__ndk120__atomic_wait_nativeILm4EEEvPKvS2_', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk120__get_collation_nameEPKc', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk120__libcpp_atomic_waitEPVKNS_17__cxx_atomic_implIiNS_22__cxx_atomic_base_implIiEEEEi', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk120__libcpp_atomic_waitEPVKvi', 'type': 'FUNC'}
@@ -1207,6 +1208,7 @@
{'is_defined': True, 'name': '_ZNSt6__ndk121recursive_timed_mutexD1Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk121recursive_timed_mutexD2Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk122__libcpp_verbose_abortEPKcz', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt6__ndk123__atomic_monitor_globalEPKv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk123__cxx_atomic_notify_allEPVKNS_17__cxx_atomic_implIiNS_22__cxx_atomic_base_implIiEEEE', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk123__cxx_atomic_notify_allEPVKv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk123__cxx_atomic_notify_oneEPVKNS_17__cxx_atomic_implIiNS_22__cxx_atomic_base_implIiEEEE', 'type': 'FUNC'}
@@ -1214,9 +1216,14 @@
{'is_defined': True, 'name': '_ZNSt6__ndk123__libcpp_atomic_monitorEPVKNS_17__cxx_atomic_implIiNS_22__cxx_atomic_base_implIiEEEE', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk123__libcpp_atomic_monitorEPVKv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk125notify_all_at_thread_exitERNS_18condition_variableENS_11unique_lockINS_5mutexEEE', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt6__ndk126__atomic_notify_all_nativeILm4EEEvPKv', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt6__ndk126__atomic_notify_one_nativeILm4EEEvPKv', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt6__ndk126__atomic_wait_global_tableEPKvi', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk127__from_chars_floating_pointIdEENS_19__from_chars_resultIT_EEPKcS5_NS_12chars_formatE', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk127__from_chars_floating_pointIfEENS_19__from_chars_resultIT_EEPKcS5_NS_12chars_formatE', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk131__arrive_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseEh', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt6__ndk132__atomic_notify_all_global_tableEPKv', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt6__ndk132__atomic_notify_one_global_tableEPKv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk132__destroy_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseE', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk134__construct_barrier_algorithm_baseERl', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk13cinE', 'size': 280, 'type': 'OBJECT'}
diff --git a/libcxx/lib/abi/x86_64-unknown-freebsd.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/x86_64-unknown-freebsd.libcxxabi.v1.stable.exceptions.nonew.abilist
index 40ae625..685d2a4 100644
--- a/libcxx/lib/abi/x86_64-unknown-freebsd.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/x86_64-unknown-freebsd.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -227,6 +227,7 @@
{'is_defined': True, 'name': '_ZNKSt3__115basic_streambufIwNS_11char_traitsIwEEE6getlocEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNKSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNKSt3__115error_condition7messageEv', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNKSt3__117bad_function_call4whatEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNKSt3__117moneypunct_bynameIcLb0EE11do_groupingEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNKSt3__117moneypunct_bynameIcLb0EE13do_neg_formatEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNKSt3__117moneypunct_bynameIcLb0EE13do_pos_formatEv', 'type': 'FUNC'}
@@ -775,6 +776,7 @@
{'is_defined': True, 'name': '_ZNSt3__112system_errorD0Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__112system_errorD1Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__112system_errorD2Ev', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__113__hash_memoryEPKvm', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__113basic_filebufIcNS_11char_traitsIcEEE11__read_modeEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__113basic_filebufIcNS_11char_traitsIcEEE12__write_modeEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__113basic_filebufIcNS_11char_traitsIcEEE4openEPKcj', 'type': 'FUNC'}
@@ -955,7 +957,6 @@
{'is_defined': True, 'name': '_ZNSt3__113shared_futureIvED1Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__113shared_futureIvED2Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__113shared_futureIvEaSERKS1_', 'type': 'FUNC'}
-{'is_defined': True, 'name': '_ZNSt3__113__hash_memoryEPKvm', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__114__num_get_base10__get_baseERNS_8ios_baseE', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__114__num_get_base5__srcE', 'size': 33, 'type': 'OBJECT'}
{'is_defined': True, 'name': '_ZNSt3__114__num_put_base12__format_intEPcPKcbj', 'type': 'FUNC'}
@@ -1158,7 +1159,6 @@
{'is_defined': True, 'name': '_ZNSt3__117bad_function_callD0Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__117bad_function_callD1Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__117bad_function_callD2Ev', 'type': 'FUNC'}
-{'is_defined': True, 'name': '_ZNKSt3__117bad_function_call4whatEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__117iostream_categoryEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__117moneypunct_bynameIcLb0EE4initEPKc', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__117moneypunct_bynameIcLb1EE4initEPKc', 'type': 'FUNC'}
@@ -1208,6 +1208,7 @@
{'is_defined': True, 'name': '_ZNSt3__119__thread_local_dataEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__119basic_istringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEaSEOS5_', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__119basic_ostringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEaSEOS5_', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__120__atomic_wait_nativeILm8EEEvPKvS2_', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__120__get_collation_nameEPKc', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__120__libcpp_atomic_waitEPVKNS_17__cxx_atomic_implIlNS_22__cxx_atomic_base_implIlEEEEl', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__120__libcpp_atomic_waitEPVKvl', 'type': 'FUNC'}
@@ -1221,6 +1222,7 @@
{'is_defined': True, 'name': '_ZNSt3__121recursive_timed_mutexD1Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__121recursive_timed_mutexD2Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__122__libcpp_verbose_abortEPKcz', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__123__atomic_monitor_globalEPKv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__123__cxx_atomic_notify_allEPVKNS_17__cxx_atomic_implIlNS_22__cxx_atomic_base_implIlEEEE', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__123__cxx_atomic_notify_allEPVKv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__123__cxx_atomic_notify_oneEPVKNS_17__cxx_atomic_implIlNS_22__cxx_atomic_base_implIlEEEE', 'type': 'FUNC'}
@@ -1228,9 +1230,14 @@
{'is_defined': True, 'name': '_ZNSt3__123__libcpp_atomic_monitorEPVKNS_17__cxx_atomic_implIlNS_22__cxx_atomic_base_implIlEEEE', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__123__libcpp_atomic_monitorEPVKv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__125notify_all_at_thread_exitERNS_18condition_variableENS_11unique_lockINS_5mutexEEE', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__126__atomic_notify_all_nativeILm8EEEvPKv', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__126__atomic_notify_one_nativeILm8EEEvPKv', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__126__atomic_wait_global_tableEPKvl', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__127__from_chars_floating_pointIdEENS_19__from_chars_resultIT_EEPKcS5_NS_12chars_formatE', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__127__from_chars_floating_pointIfEENS_19__from_chars_resultIT_EEPKcS5_NS_12chars_formatE', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__131__arrive_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseEh', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__132__atomic_notify_all_global_tableEPKv', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__132__atomic_notify_one_global_tableEPKv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__132__destroy_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseE', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__134__construct_barrier_algorithm_baseERl', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__13cinE', 'size': 400, 'type': 'OBJECT'}
diff --git a/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist
index 9016607..5732ed7 100644
--- a/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -225,6 +225,7 @@
{'is_defined': True, 'name': '_ZNKSt3__115basic_streambufIwNS_11char_traitsIwEEE6getlocEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNKSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNKSt3__115error_condition7messageEv', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNKSt3__117bad_function_call4whatEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNKSt3__117moneypunct_bynameIcLb0EE11do_groupingEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNKSt3__117moneypunct_bynameIcLb0EE13do_neg_formatEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNKSt3__117moneypunct_bynameIcLb0EE13do_pos_formatEv', 'type': 'FUNC'}
@@ -773,6 +774,7 @@
{'is_defined': True, 'name': '_ZNSt3__112system_errorD0Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__112system_errorD1Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__112system_errorD2Ev', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__113__hash_memoryEPKvm', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__113basic_filebufIcNS_11char_traitsIcEEE11__read_modeEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__113basic_filebufIcNS_11char_traitsIcEEE12__write_modeEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__113basic_filebufIcNS_11char_traitsIcEEE4openEPKcj', 'type': 'FUNC'}
@@ -953,7 +955,6 @@
{'is_defined': True, 'name': '_ZNSt3__113shared_futureIvED1Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__113shared_futureIvED2Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__113shared_futureIvEaSERKS1_', 'type': 'FUNC'}
-{'is_defined': True, 'name': '_ZNSt3__113__hash_memoryEPKvm', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__114__num_get_base10__get_baseERNS_8ios_baseE', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__114__num_get_base5__srcE', 'size': 33, 'type': 'OBJECT'}
{'is_defined': True, 'name': '_ZNSt3__114__num_put_base12__format_intEPcPKcbj', 'type': 'FUNC'}
@@ -1156,7 +1157,6 @@
{'is_defined': True, 'name': '_ZNSt3__117bad_function_callD0Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__117bad_function_callD1Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__117bad_function_callD2Ev', 'type': 'FUNC'}
-{'is_defined': True, 'name': '_ZNKSt3__117bad_function_call4whatEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__117iostream_categoryEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__117moneypunct_bynameIcLb0EE4initEPKc', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__117moneypunct_bynameIcLb1EE4initEPKc', 'type': 'FUNC'}
@@ -1206,6 +1206,7 @@
{'is_defined': True, 'name': '_ZNSt3__119__thread_local_dataEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__119basic_istringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEaSEOS5_', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__119basic_ostringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEaSEOS5_', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__120__atomic_wait_nativeILm4EEEvPKvS2_', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__120__get_collation_nameEPKc', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__120__libcpp_atomic_waitEPVKNS_17__cxx_atomic_implIiNS_22__cxx_atomic_base_implIiEEEEi', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__120__libcpp_atomic_waitEPVKvi', 'type': 'FUNC'}
@@ -1219,6 +1220,7 @@
{'is_defined': True, 'name': '_ZNSt3__121recursive_timed_mutexD1Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__121recursive_timed_mutexD2Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__122__libcpp_verbose_abortEPKcz', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__123__atomic_monitor_globalEPKv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__123__cxx_atomic_notify_allEPVKNS_17__cxx_atomic_implIiNS_22__cxx_atomic_base_implIiEEEE', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__123__cxx_atomic_notify_allEPVKv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__123__cxx_atomic_notify_oneEPVKNS_17__cxx_atomic_implIiNS_22__cxx_atomic_base_implIiEEEE', 'type': 'FUNC'}
@@ -1226,9 +1228,14 @@
{'is_defined': True, 'name': '_ZNSt3__123__libcpp_atomic_monitorEPVKNS_17__cxx_atomic_implIiNS_22__cxx_atomic_base_implIiEEEE', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__123__libcpp_atomic_monitorEPVKv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__125notify_all_at_thread_exitERNS_18condition_variableENS_11unique_lockINS_5mutexEEE', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__126__atomic_notify_all_nativeILm4EEEvPKv', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__126__atomic_notify_one_nativeILm4EEEvPKv', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__126__atomic_wait_global_tableEPKvi', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__127__from_chars_floating_pointIdEENS_19__from_chars_resultIT_EEPKcS5_NS_12chars_formatE', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__127__from_chars_floating_pointIfEENS_19__from_chars_resultIT_EEPKcS5_NS_12chars_formatE', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__131__arrive_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseEh', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__132__atomic_notify_all_global_tableEPKv', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__132__atomic_notify_one_global_tableEPKv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__132__destroy_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseE', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__134__construct_barrier_algorithm_baseERl', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__13cinE', 'size': 280, 'type': 'OBJECT'}
diff --git a/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.noexceptions.nonew.abilist b/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.noexceptions.nonew.abilist
index 5855c17..c7183c2 100644
--- a/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.noexceptions.nonew.abilist
+++ b/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.noexceptions.nonew.abilist
@@ -196,6 +196,7 @@
{'is_defined': True, 'name': '_ZNKSt3__115basic_streambufIwNS_11char_traitsIwEEE6getlocEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNKSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNKSt3__115error_condition7messageEv', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNKSt3__117bad_function_call4whatEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNKSt3__117moneypunct_bynameIcLb0EE11do_groupingEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNKSt3__117moneypunct_bynameIcLb0EE13do_neg_formatEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNKSt3__117moneypunct_bynameIcLb0EE13do_pos_formatEv', 'type': 'FUNC'}
@@ -744,6 +745,7 @@
{'is_defined': True, 'name': '_ZNSt3__112system_errorD0Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__112system_errorD1Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__112system_errorD2Ev', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__113__hash_memoryEPKvm', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__113basic_filebufIcNS_11char_traitsIcEEE11__read_modeEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__113basic_filebufIcNS_11char_traitsIcEEE12__write_modeEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__113basic_filebufIcNS_11char_traitsIcEEE4openEPKcj', 'type': 'FUNC'}
@@ -923,7 +925,6 @@
{'is_defined': True, 'name': '_ZNSt3__113random_deviceclEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__113shared_futureIvED1Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__113shared_futureIvED2Ev', 'type': 'FUNC'}
-{'is_defined': True, 'name': '_ZNSt3__113__hash_memoryEPKvm', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__113shared_futureIvEaSERKS1_', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__114__num_get_base10__get_baseERNS_8ios_baseE', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__114__num_get_base5__srcE', 'size': 33, 'type': 'OBJECT'}
@@ -1127,7 +1128,6 @@
{'is_defined': True, 'name': '_ZNSt3__117bad_function_callD0Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__117bad_function_callD1Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__117bad_function_callD2Ev', 'type': 'FUNC'}
-{'is_defined': True, 'name': '_ZNKSt3__117bad_function_call4whatEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__117iostream_categoryEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__117moneypunct_bynameIcLb0EE4initEPKc', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__117moneypunct_bynameIcLb1EE4initEPKc', 'type': 'FUNC'}
@@ -1177,6 +1177,7 @@
{'is_defined': True, 'name': '_ZNSt3__119__thread_local_dataEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__119basic_istringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEaSEOS5_', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__119basic_ostringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEaSEOS5_', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__120__atomic_wait_nativeILm4EEEvPKvS2_', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__120__get_collation_nameEPKc', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__120__libcpp_atomic_waitEPVKNS_17__cxx_atomic_implIiNS_22__cxx_atomic_base_implIiEEEEi', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__120__libcpp_atomic_waitEPVKvi', 'type': 'FUNC'}
@@ -1190,6 +1191,7 @@
{'is_defined': True, 'name': '_ZNSt3__121recursive_timed_mutexD1Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__121recursive_timed_mutexD2Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__122__libcpp_verbose_abortEPKcz', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__123__atomic_monitor_globalEPKv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__123__cxx_atomic_notify_allEPVKNS_17__cxx_atomic_implIiNS_22__cxx_atomic_base_implIiEEEE', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__123__cxx_atomic_notify_allEPVKv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__123__cxx_atomic_notify_oneEPVKNS_17__cxx_atomic_implIiNS_22__cxx_atomic_base_implIiEEEE', 'type': 'FUNC'}
@@ -1197,9 +1199,14 @@
{'is_defined': True, 'name': '_ZNSt3__123__libcpp_atomic_monitorEPVKNS_17__cxx_atomic_implIiNS_22__cxx_atomic_base_implIiEEEE', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__123__libcpp_atomic_monitorEPVKv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__125notify_all_at_thread_exitERNS_18condition_variableENS_11unique_lockINS_5mutexEEE', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__126__atomic_notify_all_nativeILm4EEEvPKv', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__126__atomic_notify_one_nativeILm4EEEvPKv', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__126__atomic_wait_global_tableEPKvi', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__127__from_chars_floating_pointIdEENS_19__from_chars_resultIT_EEPKcS5_NS_12chars_formatE', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__127__from_chars_floating_pointIfEENS_19__from_chars_resultIT_EEPKcS5_NS_12chars_formatE', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__131__arrive_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseEh', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__132__atomic_notify_all_global_tableEPKv', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__132__atomic_notify_one_global_tableEPKv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__132__destroy_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseE', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__134__construct_barrier_algorithm_baseERl', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__13cinE', 'size': 280, 'type': 'OBJECT'}
diff --git a/libcxx/modules/std/optional.inc b/libcxx/modules/std/optional.inc
index 9ee5111..88de0bb 100644
--- a/libcxx/modules/std/optional.inc
+++ b/libcxx/modules/std/optional.inc
@@ -13,8 +13,9 @@ export namespace std {
#if _LIBCPP_STD_VER >= 26
// [optional.iterators], iterator support
namespace ranges {
+ using std::ranges::enable_borrowed_range;
using std::ranges::enable_view;
- }
+ } // namespace ranges
#endif
// [optional.nullopt], no-value state indicator
using std::nullopt;
diff --git a/libcxx/src/atomic.cpp b/libcxx/src/atomic.cpp
index b214ba1..2b1ebfa 100644
--- a/libcxx/src/atomic.cpp
+++ b/libcxx/src/atomic.cpp
@@ -9,8 +9,12 @@
#include <__thread/timed_backoff_policy.h>
#include <atomic>
#include <climits>
+#include <cstddef>
+#include <cstring>
#include <functional>
+#include <new>
#include <thread>
+#include <type_traits>
#include "include/apple_availability.h"
@@ -41,6 +45,11 @@
// OpenBSD has no indirect syscalls
# define _LIBCPP_FUTEX(...) futex(__VA_ARGS__)
+#elif defined(_WIN32)
+
+# include <memory>
+# include <windows.h>
+
#else // <- Add other operating systems here
// Baseline needs no new headers
@@ -53,13 +62,18 @@ _LIBCPP_BEGIN_NAMESPACE_STD
#ifdef __linux__
-static void
-__libcpp_platform_wait_on_address(__cxx_atomic_contention_t const volatile* __ptr, __cxx_contention_t __val) {
+template <std::size_t _Size>
+static void __platform_wait_on_address(void const* __ptr, void const* __val) {
+ static_assert(_Size == 4, "Can only wait on 4 bytes value");
+ char buffer[_Size];
+ std::memcpy(&buffer, const_cast<const void*>(__val), _Size);
static constexpr timespec __timeout = {2, 0};
- _LIBCPP_FUTEX(__ptr, FUTEX_WAIT_PRIVATE, __val, &__timeout, 0, 0);
+ _LIBCPP_FUTEX(__ptr, FUTEX_WAIT_PRIVATE, *reinterpret_cast<__cxx_contention_t const*>(&buffer), &__timeout, 0, 0);
}
-static void __libcpp_platform_wake_by_address(__cxx_atomic_contention_t const volatile* __ptr, bool __notify_one) {
+template <std::size_t _Size>
+static void __platform_wake_by_address(void const* __ptr, bool __notify_one) {
+ static_assert(_Size == 4, "Can only wake up on 4 bytes value");
_LIBCPP_FUTEX(__ptr, FUTEX_WAKE_PRIVATE, __notify_one ? 1 : INT_MAX, 0, 0, 0);
}
@@ -70,19 +84,29 @@ extern "C" int __ulock_wait(
extern "C" int __ulock_wake(uint32_t operation, void* addr, uint64_t wake_value);
// https://github.com/apple/darwin-xnu/blob/2ff845c2e033bd0ff64b5b6aa6063a1f8f65aa32/bsd/sys/ulock.h#L82
+# define UL_COMPARE_AND_WAIT 1
# define UL_COMPARE_AND_WAIT64 5
# define ULF_WAKE_ALL 0x00000100
-static void
-__libcpp_platform_wait_on_address(__cxx_atomic_contention_t const volatile* __ptr, __cxx_contention_t __val) {
- static_assert(sizeof(__cxx_atomic_contention_t) == 8, "Waiting on 8 bytes value");
- __ulock_wait(UL_COMPARE_AND_WAIT64, const_cast<__cxx_atomic_contention_t*>(__ptr), __val, 0);
+template <std::size_t _Size>
+static void __platform_wait_on_address(void const* __ptr, void const* __val) {
+ static_assert(_Size == 8 || _Size == 4, "Can only wait on 8 bytes or 4 bytes value");
+ char buffer[_Size];
+ std::memcpy(&buffer, const_cast<const void*>(__val), _Size);
+ if constexpr (_Size == 4)
+ __ulock_wait(UL_COMPARE_AND_WAIT, const_cast<void*>(__ptr), *reinterpret_cast<uint32_t const*>(&buffer), 0);
+ else
+ __ulock_wait(UL_COMPARE_AND_WAIT64, const_cast<void*>(__ptr), *reinterpret_cast<uint64_t const*>(&buffer), 0);
}
-static void __libcpp_platform_wake_by_address(__cxx_atomic_contention_t const volatile* __ptr, bool __notify_one) {
- static_assert(sizeof(__cxx_atomic_contention_t) == 8, "Waking up on 8 bytes value");
- __ulock_wake(
- UL_COMPARE_AND_WAIT64 | (__notify_one ? 0 : ULF_WAKE_ALL), const_cast<__cxx_atomic_contention_t*>(__ptr), 0);
+template <std::size_t _Size>
+static void __platform_wake_by_address(void const* __ptr, bool __notify_one) {
+ static_assert(_Size == 8 || _Size == 4, "Can only wake up on 8 bytes or 4 bytes value");
+
+ if constexpr (_Size == 4)
+ __ulock_wake(UL_COMPARE_AND_WAIT | (__notify_one ? 0 : ULF_WAKE_ALL), const_cast<void*>(__ptr), 0);
+ else
+ __ulock_wake(UL_COMPARE_AND_WAIT64 | (__notify_one ? 0 : ULF_WAKE_ALL), const_cast<void*>(__ptr), 0);
}
#elif defined(__FreeBSD__) && __SIZEOF_LONG__ == 8
@@ -92,119 +116,298 @@ static void __libcpp_platform_wake_by_address(__cxx_atomic_contention_t const vo
* limit its use to architectures where long and int64_t are synonyms.
*/
-static void
-__libcpp_platform_wait_on_address(__cxx_atomic_contention_t const volatile* __ptr, __cxx_contention_t __val) {
- _umtx_op(const_cast<__cxx_atomic_contention_t*>(__ptr), UMTX_OP_WAIT, __val, nullptr, nullptr);
+template <std::size_t _Size>
+static void __platform_wait_on_address(void const* __ptr, void const* __val) {
+ static_assert(_Size == 8, "Can only wait on 8 bytes value");
+ char buffer[_Size];
+ std::memcpy(&buffer, const_cast<const void*>(__val), _Size);
+ _umtx_op(const_cast<void*>(__ptr), UMTX_OP_WAIT, *reinterpret_cast<__cxx_contention_t*>(&buffer), nullptr, nullptr);
}
-static void __libcpp_platform_wake_by_address(__cxx_atomic_contention_t const volatile* __ptr, bool __notify_one) {
- _umtx_op(const_cast<__cxx_atomic_contention_t*>(__ptr), UMTX_OP_WAKE, __notify_one ? 1 : INT_MAX, nullptr, nullptr);
+template <std::size_t _Size>
+static void __platform_wake_by_address(void const* __ptr, bool __notify_one) {
+ static_assert(_Size == 8, "Can only wake up on 8 bytes value");
+ _umtx_op(const_cast<void*>(__ptr), UMTX_OP_WAKE, __notify_one ? 1 : INT_MAX, nullptr, nullptr);
+}
+
+#elif defined(_WIN32)
+
+static void* win32_get_synch_api_function(const char* function_name) {
+ // Attempt to load the API set. Note that as per the Microsoft STL implementation, we assume this API is already
+ // loaded and accessible. While this isn't explicitly guaranteed by publicly available Win32 API documentation, it is
+ // true in practice, and may be guaranteed by internal documentation not released publicly. In any case the fact that
+ // the Microsoft STL made this assumption is reasonable basis to say that we can too. The alternative to this would be
+ // to use LoadLibrary, but then leak the module handle. We can't call FreeLibrary, as this would have to be triggered
+ // by a global static destructor, which would hang off DllMain, and calling FreeLibrary from DllMain is explicitly
+ // mentioned as not being allowed:
+ // https://learn.microsoft.com/en-us/windows/win32/dlls/dllmain
+ // Given the range of bad options here, we have chosen to mirror what Microsoft did, as it seems fair to assume that
+ // Microsoft will guarantee compatibility for us, as we are exposed to the same conditions as all existing Windows
+ // apps using the Microsoft STL VS2015/2017/2019/2022 runtimes, where Windows 7 support has not been excluded at
+ // compile time.
+ static auto module_handle = GetModuleHandleW(L"api-ms-win-core-synch-l1-2-0.dll");
+ if (module_handle == nullptr) {
+ return nullptr;
+ }
+
+ // Attempt to locate the function in the API and return the result to the caller. Note that the NULL return from this
+ // method is documented as being interchangeable with nullptr.
+ // https://devblogs.microsoft.com/oldnewthing/20180307-00/?p=98175
+ return reinterpret_cast<void*>(GetProcAddress(module_handle, function_name));
+}
+
+template <std::size_t _Size>
+static void __platform_wait_on_address(void const* __ptr, void const* __val) {
+ static_assert(_Size == 8, "Can only wait on 8 bytes value");
+ // WaitOnAddress was added in Windows 8 (build 9200)
+ static auto wait_on_address =
+ reinterpret_cast<BOOL(WINAPI*)(void*, PVOID, SIZE_T, DWORD)>(win32_get_synch_api_function("WaitOnAddress"));
+ if (wait_on_address != nullptr) {
+ wait_on_address(const_cast<void*>(__ptr), const_cast<void*>(__val), _Size, INFINITE);
+ } else {
+ __libcpp_thread_poll_with_backoff(
+ [=]() -> bool { return std::memcmp(const_cast<const void*>(__ptr), __val, _Size) != 0; },
+ __libcpp_timed_backoff_policy());
+ }
+}
+
+template <std::size_t _Size>
+static void __platform_wake_by_address(void const* __ptr, bool __notify_one) {
+ static_assert(_Size == 8, "Can only wake up on 8 bytes value");
+ if (__notify_one) {
+ // WakeByAddressSingle was added in Windows 8 (build 9200)
+ static auto wake_by_address_single =
+ reinterpret_cast<void(WINAPI*)(PVOID)>(win32_get_synch_api_function("WakeByAddressSingle"));
+ if (wake_by_address_single != nullptr) {
+ wake_by_address_single(const_cast<void*>(__ptr));
+ } else {
+ // The fallback implementation of waking does nothing, as the fallback wait implementation just does polling, so
+ // there's nothing to do here.
+ }
+ } else {
+ // WakeByAddressAll was added in Windows 8 (build 9200)
+ static auto wake_by_address_all =
+ reinterpret_cast<void(WINAPI*)(PVOID)>(win32_get_synch_api_function("WakeByAddressAll"));
+ if (wake_by_address_all != nullptr) {
+ wake_by_address_all(const_cast<void*>(__ptr));
+ } else {
+ // The fallback implementation of waking does nothing, as the fallback wait implementation just does polling, so
+ // there's nothing to do here.
+ }
+ }
}
#else // <- Add other operating systems here
// Baseline is just a timed backoff
-static void
-__libcpp_platform_wait_on_address(__cxx_atomic_contention_t const volatile* __ptr, __cxx_contention_t __val) {
+template <std::size_t _Size>
+static void __platform_wait_on_address(void const* __ptr, void const* __val) {
__libcpp_thread_poll_with_backoff(
- [=]() -> bool { return !__cxx_nonatomic_compare_equal(__cxx_atomic_load(__ptr, memory_order_relaxed), __val); },
+ [=]() -> bool { return std::memcmp(const_cast<const void*>(__ptr), __val, _Size) != 0; },
__libcpp_timed_backoff_policy());
}
-static void __libcpp_platform_wake_by_address(__cxx_atomic_contention_t const volatile*, bool) {}
+template <std::size_t _Size>
+static void __platform_wake_by_address(void const*, bool) {}
#endif // __linux__
-static constexpr size_t __libcpp_contention_table_size = (1 << 8); /* < there's no magic in this number */
-
-struct alignas(64) /* aim to avoid false sharing */ __libcpp_contention_table_entry {
- __cxx_atomic_contention_t __contention_state;
- __cxx_atomic_contention_t __platform_state;
- inline constexpr __libcpp_contention_table_entry() : __contention_state(0), __platform_state(0) {}
-};
-
-static __libcpp_contention_table_entry __libcpp_contention_table[__libcpp_contention_table_size];
-
-static hash<void const volatile*> __libcpp_contention_hasher;
-
-static __libcpp_contention_table_entry* __libcpp_contention_state(void const volatile* p) {
- return &__libcpp_contention_table[__libcpp_contention_hasher(p) & (__libcpp_contention_table_size - 1)];
-}
+// =============================
+// Local hidden helper functions
+// =============================
/* Given an atomic to track contention and an atomic to actually wait on, which may be
the same atomic, we try to detect contention to avoid spuriously calling the platform. */
-static void __libcpp_contention_notify(__cxx_atomic_contention_t volatile* __contention_state,
- __cxx_atomic_contention_t const volatile* __platform_state,
- bool __notify_one) {
- if (0 != __cxx_atomic_load(__contention_state, memory_order_seq_cst))
+template <std::size_t _Size>
+static void
+__contention_notify(__cxx_atomic_contention_t* __waiter_count, void const* __address_to_notify, bool __notify_one) {
+ if (0 != __cxx_atomic_load(__waiter_count, memory_order_seq_cst))
// We only call 'wake' if we consumed a contention bit here.
- __libcpp_platform_wake_by_address(__platform_state, __notify_one);
-}
-static __cxx_contention_t
-__libcpp_contention_monitor_for_wait(__cxx_atomic_contention_t volatile* /*__contention_state*/,
- __cxx_atomic_contention_t const volatile* __platform_state) {
- // We will monitor this value.
- return __cxx_atomic_load(__platform_state, memory_order_acquire);
-}
-static void __libcpp_contention_wait(__cxx_atomic_contention_t volatile* __contention_state,
- __cxx_atomic_contention_t const volatile* __platform_state,
- __cxx_contention_t __old_value) {
- __cxx_atomic_fetch_add(__contention_state, __cxx_contention_t(1), memory_order_relaxed);
+ __platform_wake_by_address<_Size>(__address_to_notify, __notify_one);
+}
+
+template <std::size_t _Size>
+static void
+__contention_wait(__cxx_atomic_contention_t* __waiter_count, void const* __address_to_wait, void const* __old_value) {
+ __cxx_atomic_fetch_add(__waiter_count, __cxx_contention_t(1), memory_order_relaxed);
// https://llvm.org/PR109290
// There are no platform guarantees of a memory barrier in the platform wait implementation
__cxx_atomic_thread_fence(memory_order_seq_cst);
// We sleep as long as the monitored value hasn't changed.
- __libcpp_platform_wait_on_address(__platform_state, __old_value);
- __cxx_atomic_fetch_sub(__contention_state, __cxx_contention_t(1), memory_order_release);
+ __platform_wait_on_address<_Size>(__address_to_wait, __old_value);
+ __cxx_atomic_fetch_sub(__waiter_count, __cxx_contention_t(1), memory_order_release);
+}
+
+#if defined(__APPLE__) && defined(__aarch64__)
+static constexpr size_t __cache_line_size = 128;
+#elif defined(__cpp_lib_hardware_interference_size)
+static constexpr size_t __cache_line_size = std::hardware_constructive_interference_size;
+#else
+static constexpr size_t __cache_line_size = 64;
+#endif
+
+static constexpr size_t __contention_table_size = (1 << 8); /* < there's no magic in this number */
+
+static constexpr hash<void const*> __contention_hasher;
+
+// Waiter count table for all atomics with the correct size that use itself as the wait/notify address.
+
+struct alignas(__cache_line_size) /* aim to avoid false sharing */ __contention_state_native {
+ __cxx_atomic_contention_t __waiter_count;
+ constexpr __contention_state_native() : __waiter_count(0) {}
+};
+
+static __contention_state_native __contention_table_native[__contention_table_size];
+
+static __cxx_atomic_contention_t* __get_native_waiter_count(void const* p) {
+ return &__contention_table_native[__contention_hasher(p) & (__contention_table_size - 1)].__waiter_count;
+}
+
+// Global contention table for all atomics with the wrong size that use the global table's atomic as wait/notify
+// address.
+
+struct alignas(__cache_line_size) /* aim to avoid false sharing */ __contention_state_global {
+ __cxx_atomic_contention_t __waiter_count;
+ __cxx_atomic_contention_t __platform_state;
+ constexpr __contention_state_global() : __waiter_count(0), __platform_state(0) {}
+};
+
+static __contention_state_global __contention_table_global[__contention_table_size];
+
+static __contention_state_global* __get_global_contention_state(void const* p) {
+ return &__contention_table_global[__contention_hasher(p) & (__contention_table_size - 1)];
}
/* When the incoming atomic is the wrong size for the platform wait size, need to
launder the value sequence through an atomic from our table. */
-static void __libcpp_atomic_notify(void const volatile* __location) {
- auto const __entry = __libcpp_contention_state(__location);
+static void __atomic_notify_global_table(void const* __location) {
+ auto const __entry = __get_global_contention_state(__location);
// The value sequence laundering happens on the next line below.
__cxx_atomic_fetch_add(&__entry->__platform_state, __cxx_contention_t(1), memory_order_seq_cst);
- __libcpp_contention_notify(
- &__entry->__contention_state,
- &__entry->__platform_state,
- false /* when laundering, we can't handle notify_one */);
+ __contention_notify<sizeof(__cxx_atomic_contention_t)>(
+ &__entry->__waiter_count, &__entry->__platform_state, false /* when laundering, we can't handle notify_one */);
}
+
+// =============================
+// New dylib exported symbols
+// =============================
+
+// global
+_LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t __atomic_monitor_global(void const* __location) noexcept {
+ auto const __entry = __get_global_contention_state(__location);
+ return __cxx_atomic_load(&__entry->__platform_state, memory_order_acquire);
+}
+
+_LIBCPP_EXPORTED_FROM_ABI void
+__atomic_wait_global_table(void const* __location, __cxx_contention_t __old_value) noexcept {
+ auto const __entry = __get_global_contention_state(__location);
+ __contention_wait<sizeof(__cxx_atomic_contention_t)>(
+ &__entry->__waiter_count, &__entry->__platform_state, &__old_value);
+}
+
+_LIBCPP_EXPORTED_FROM_ABI void __atomic_notify_one_global_table(void const* __location) noexcept {
+ __atomic_notify_global_table(__location);
+}
+
+_LIBCPP_EXPORTED_FROM_ABI void __atomic_notify_all_global_table(void const* __location) noexcept {
+ __atomic_notify_global_table(__location);
+}
+
+// native
+
+template <std::size_t _Size>
+_LIBCPP_EXPORTED_FROM_ABI void __atomic_wait_native(void const* __address, void const* __old_value) noexcept {
+ __contention_wait<_Size>(__get_native_waiter_count(__address), __address, __old_value);
+}
+
+template <std::size_t _Size>
+_LIBCPP_EXPORTED_FROM_ABI void __atomic_notify_one_native(void const* __location) noexcept {
+ __contention_notify<_Size>(__get_native_waiter_count(__location), __location, true);
+}
+
+template <std::size_t _Size>
+_LIBCPP_EXPORTED_FROM_ABI void __atomic_notify_all_native(void const* __location) noexcept {
+ __contention_notify<_Size>(__get_native_waiter_count(__location), __location, false);
+}
+
+// ==================================================
+// Instantiation of the templates with supported size
+// ==================================================
+
+#if defined(_LIBCPP_ABI_ATOMIC_WAIT_NATIVE_BY_SIZE)
+
+# define _INSTANTIATE(_SIZE) \
+ template _LIBCPP_EXPORTED_FROM_ABI void __atomic_wait_native<_SIZE>(void const*, void const*) noexcept; \
+ template _LIBCPP_EXPORTED_FROM_ABI void __atomic_notify_one_native<_SIZE>(void const*) noexcept; \
+ template _LIBCPP_EXPORTED_FROM_ABI void __atomic_notify_all_native<_SIZE>(void const*) noexcept;
+
+_LIBCPP_NATIVE_PLATFORM_WAIT_SIZES(_INSTANTIATE)
+
+# undef _INSTANTIATE
+
+#else // _LIBCPP_ABI_ATOMIC_WAIT_NATIVE_BY_SIZE
+
+template _LIBCPP_EXPORTED_FROM_ABI void
+__atomic_wait_native<sizeof(__cxx_contention_t)>(void const* __address, void const* __old_value) noexcept;
+
+template _LIBCPP_EXPORTED_FROM_ABI void
+__atomic_notify_one_native<sizeof(__cxx_contention_t)>(void const* __location) noexcept;
+
+template _LIBCPP_EXPORTED_FROM_ABI void
+__atomic_notify_all_native<sizeof(__cxx_contention_t)>(void const* __location) noexcept;
+
+#endif // _LIBCPP_ABI_ATOMIC_WAIT_NATIVE_BY_SIZE
+
+// =============================================================
+// Old dylib exported symbols, for backwards compatibility
+// =============================================================
+
_LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(void const volatile* __location) noexcept {
- __libcpp_atomic_notify(__location);
+ __atomic_notify_global_table(const_cast<void const*>(__location));
}
+
_LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all(void const volatile* __location) noexcept {
- __libcpp_atomic_notify(__location);
+ __atomic_notify_global_table(const_cast<void const*>(__location));
}
+
_LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t __libcpp_atomic_monitor(void const volatile* __location) noexcept {
- auto const __entry = __libcpp_contention_state(__location);
- return __libcpp_contention_monitor_for_wait(&__entry->__contention_state, &__entry->__platform_state);
+ auto const __entry = __get_global_contention_state(const_cast<void const*>(__location));
+ return __cxx_atomic_load(&__entry->__platform_state, memory_order_acquire);
}
+
_LIBCPP_EXPORTED_FROM_ABI void
__libcpp_atomic_wait(void const volatile* __location, __cxx_contention_t __old_value) noexcept {
- auto const __entry = __libcpp_contention_state(__location);
- __libcpp_contention_wait(&__entry->__contention_state, &__entry->__platform_state, __old_value);
+ auto const __entry = __get_global_contention_state(const_cast<void const*>(__location));
+ __contention_wait<sizeof(__cxx_atomic_contention_t)>(
+ &__entry->__waiter_count, &__entry->__platform_state, &__old_value);
}
-/* When the incoming atomic happens to be the platform wait size, we still need to use the
- table for the contention detection, but we can use the atomic directly for the wait. */
-
_LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(__cxx_atomic_contention_t const volatile* __location) noexcept {
- __libcpp_contention_notify(&__libcpp_contention_state(__location)->__contention_state, __location, true);
+ auto __location_cast = const_cast<const void*>(static_cast<const volatile void*>(__location));
+ __contention_notify<sizeof(__cxx_atomic_contention_t)>(
+ __get_native_waiter_count(__location_cast), __location_cast, true);
}
+
_LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all(__cxx_atomic_contention_t const volatile* __location) noexcept {
- __libcpp_contention_notify(&__libcpp_contention_state(__location)->__contention_state, __location, false);
-}
-// This function is never used, but still exported for ABI compatibility.
-_LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t
-__libcpp_atomic_monitor(__cxx_atomic_contention_t const volatile* __location) noexcept {
- return __libcpp_contention_monitor_for_wait(&__libcpp_contention_state(__location)->__contention_state, __location);
+ auto __location_cast = const_cast<const void*>(static_cast<const volatile void*>(__location));
+ __contention_notify<sizeof(__cxx_atomic_contention_t)>(
+ __get_native_waiter_count(__location_cast), __location_cast, false);
}
+
_LIBCPP_EXPORTED_FROM_ABI void
__libcpp_atomic_wait(__cxx_atomic_contention_t const volatile* __location, __cxx_contention_t __old_value) noexcept {
- __libcpp_contention_wait(&__libcpp_contention_state(__location)->__contention_state, __location, __old_value);
+ auto __location_cast = const_cast<const void*>(static_cast<const volatile void*>(__location));
+ __contention_wait<sizeof(__cxx_atomic_contention_t)>(
+ __get_native_waiter_count(__location_cast), __location_cast, &__old_value);
+}
+
+// this function is even unused in the old ABI
+_LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t
+__libcpp_atomic_monitor(__cxx_atomic_contention_t const volatile* __location) noexcept {
+ return __cxx_atomic_load(__location, memory_order_acquire);
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/src/exception.cpp b/libcxx/src/exception.cpp
index ac6324c..9932141 100644
--- a/libcxx/src/exception.cpp
+++ b/libcxx/src/exception.cpp
@@ -9,20 +9,12 @@
#define _LIBCPP_ENABLE_CXX20_REMOVED_UNCAUGHT_EXCEPTION
#define _LIBCPP_DISABLE_DEPRECATION_WARNINGS
-#include <exception>
-#include <new>
-#include <typeinfo>
-
-#if defined(LIBCXXRT) || defined(LIBCXX_BUILDING_LIBCXXABI)
-# include <cxxabi.h>
-using namespace __cxxabiv1;
-# define HAVE_DEPENDENT_EH_ABI 1
-#endif
+#include <__config>
#if defined(_LIBCPP_ABI_MICROSOFT)
# include "support/runtime/exception_msvc.ipp"
# include "support/runtime/exception_pointer_msvc.ipp"
-#elif defined(_LIBCPPABI_VERSION)
+#elif defined(LIBCXX_BUILDING_LIBCXXABI)
# include "support/runtime/exception_libcxxabi.ipp"
# include "support/runtime/exception_pointer_cxxabi.ipp"
#elif defined(LIBCXXRT)
diff --git a/libcxx/src/filesystem/operations.cpp b/libcxx/src/filesystem/operations.cpp
index b71f94a..745db87 100644
--- a/libcxx/src/filesystem/operations.cpp
+++ b/libcxx/src/filesystem/operations.cpp
@@ -41,17 +41,10 @@
#include <time.h>
// since Linux 4.5 and FreeBSD 13, but the Linux libc wrapper is only provided by glibc >= 2.27 and musl
-#if defined(__linux__)
-# if defined(_LIBCPP_GLIBC_PREREQ)
-# if _LIBCPP_GLIBC_PREREQ(2, 27)
-# define _LIBCPP_FILESYSTEM_USE_COPY_FILE_RANGE
-# endif
-# elif _LIBCPP_HAS_MUSL_LIBC
-# define _LIBCPP_FILESYSTEM_USE_COPY_FILE_RANGE
-# endif
-#elif defined(__FreeBSD__)
+#if _LIBCPP_GLIBC_PREREQ(2, 27) || _LIBCPP_HAS_MUSL_LIBC || defined(__FreeBSD__)
# define _LIBCPP_FILESYSTEM_USE_COPY_FILE_RANGE
#endif
+
#if __has_include(<sys/sendfile.h>)
# include <sys/sendfile.h>
# define _LIBCPP_FILESYSTEM_USE_SENDFILE
diff --git a/libcxx/include/__memory/aligned_alloc.h b/libcxx/src/include/aligned_alloc.h
index fb36983..24ca26c 100644
--- a/libcxx/include/__memory/aligned_alloc.h
+++ b/libcxx/src/include/aligned_alloc.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef _LIBCPP___MEMORY_ALIGNED_ALLOC_H
-#define _LIBCPP___MEMORY_ALIGNED_ALLOC_H
+#ifndef _LIBCPP_SRC_ALIGNED_ALLOC_H
+#define _LIBCPP_SRC_ALIGNED_ALLOC_H
#include <__config>
#include <cstdlib>
@@ -29,7 +29,9 @@ _LIBCPP_BEGIN_NAMESPACE_STD
inline _LIBCPP_HIDE_FROM_ABI void* __libcpp_aligned_alloc(std::size_t __alignment, std::size_t __size) {
# if defined(_LIBCPP_MSVCRT_LIKE)
return ::_aligned_malloc(__size, __alignment);
-# elif _LIBCPP_STD_VER >= 17 && _LIBCPP_HAS_C11_ALIGNED_ALLOC
+
+// Android only provides aligned_alloc when targeting API 28 or higher.
+# elif !defined(__ANDROID__) || __ANDROID_API__ >= 28
// aligned_alloc() requires that __size is a multiple of __alignment,
// but for C++ [new.delete.general], only states "if the value of an
// alignment argument passed to any of these functions is not a valid
@@ -60,4 +62,4 @@ inline _LIBCPP_HIDE_FROM_ABI void __libcpp_aligned_free(void* __ptr) {
_LIBCPP_END_NAMESPACE_STD
-#endif // _LIBCPP___MEMORY_ALIGNED_ALLOC_H
+#endif // _LIBCPP_SRC_ALIGNED_ALLOC_H
diff --git a/libcxx/src/include/config_elast.h b/libcxx/src/include/config_elast.h
index 7edff2d..be665a9 100644
--- a/libcxx/src/include/config_elast.h
+++ b/libcxx/src/include/config_elast.h
@@ -23,7 +23,7 @@
# define _LIBCPP_ELAST ELAST
#elif defined(__LLVM_LIBC__)
// No _LIBCPP_ELAST needed for LLVM libc
-#elif defined(_NEWLIB_VERSION)
+#elif _LIBCPP_LIBC_NEWLIB
# define _LIBCPP_ELAST __ELASTERROR
#elif defined(__NuttX__)
// No _LIBCPP_ELAST needed on NuttX
diff --git a/libcxx/src/include/from_chars_floating_point.h b/libcxx/src/include/from_chars_floating_point.h
index 19eeeb2..20f23d2 100644
--- a/libcxx/src/include/from_chars_floating_point.h
+++ b/libcxx/src/include/from_chars_floating_point.h
@@ -9,11 +9,6 @@
#ifndef _LIBCPP_SRC_INCLUDE_FROM_CHARS_FLOATING_POINT_H
#define _LIBCPP_SRC_INCLUDE_FROM_CHARS_FLOATING_POINT_H
-// These headers are in the shared LLVM-libc header library.
-#include "shared/fp_bits.h"
-#include "shared/str_to_float.h"
-#include "shared/str_to_integer.h"
-
#include <__assert>
#include <__config>
#include <cctype>
@@ -21,6 +16,15 @@
#include <concepts>
#include <limits>
+// Make sure we use libc++'s assertion machinery within the shared code we use
+// from LLVM libc.
+#define LIBC_ASSERT(cond) _LIBCPP_ASSERT((cond), _LIBCPP_TOSTRING(cond))
+
+// These headers are in the shared LLVM-libc header library.
+#include "shared/fp_bits.h"
+#include "shared/str_to_float.h"
+#include "shared/str_to_integer.h"
+
// Included for the _Floating_type_traits class
#include "to_chars_floating_point.h"
diff --git a/libcxx/src/include/refstring.h b/libcxx/src/include/refstring.h
index 3e0ec7a..1c73c60 100644
--- a/libcxx/src/include/refstring.h
+++ b/libcxx/src/include/refstring.h
@@ -15,7 +15,7 @@
#include <cstring>
#include <stdexcept>
-// MacOS and iOS used to ship with libstdc++, and still support old applications
+// MacOS used to ship with libstdc++, and still support old applications
// linking against libstdc++. The libc++ and libstdc++ exceptions are supposed
// to be ABI compatible, such that they can be thrown from one library and caught
// in the other.
@@ -25,7 +25,7 @@
// string singleton before manipulating the reference count. This is done so that
// if an exception is created with a zero-length string in libstdc++, libc++abi
// won't try to delete the memory.
-#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) || defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__)
+#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__)
# define _LIBCPP_CHECK_FOR_GCC_EMPTY_STRING_STORAGE
# include <dlfcn.h>
# include <mach-o/dyld.h>
diff --git a/libcxx/src/locale.cpp b/libcxx/src/locale.cpp
index 0f695d4..aca2117 100644
--- a/libcxx/src/locale.cpp
+++ b/libcxx/src/locale.cpp
@@ -919,7 +919,7 @@ const ctype<char>::mask* ctype<char>::classic_table() noexcept {
return __pctype_func();
# elif defined(__EMSCRIPTEN__)
return *__ctype_b_loc();
-# elif defined(_NEWLIB_VERSION)
+# elif _LIBCPP_LIBC_NEWLIB
// Newlib has a 257-entry table in ctype_.c, where (char)0 starts at [1].
return _ctype_ + 1;
# elif defined(_AIX)
@@ -5557,6 +5557,54 @@ string __num_get<_CharT>::__stage2_int_prep(ios_base& __iob, _CharT* __atoms, _C
return __np.grouping();
}
+template <class _CharT>
+int __num_get<_CharT>::__stage2_int_loop(
+ _CharT __ct,
+ int __base,
+ char* __a,
+ char*& __a_end,
+ unsigned& __dc,
+ _CharT __thousands_sep,
+ const string& __grouping,
+ unsigned* __g,
+ unsigned*& __g_end,
+ _CharT* __atoms) {
+ if (__a_end == __a && (__ct == __atoms[24] || __ct == __atoms[25])) {
+ *__a_end++ = __ct == __atoms[24] ? '+' : '-';
+ __dc = 0;
+ return 0;
+ }
+ if (__grouping.size() != 0 && __ct == __thousands_sep) {
+ if (__g_end - __g < __num_get_buf_sz) {
+ *__g_end++ = __dc;
+ __dc = 0;
+ }
+ return 0;
+ }
+ ptrdiff_t __f = __atoms_offset(__atoms, __ct);
+ if (__f >= 24)
+ return -1;
+ switch (__base) {
+ case 8:
+ case 10:
+ if (__f >= __base)
+ return -1;
+ break;
+ case 16:
+ if (__f < 22)
+ break;
+ if (__a_end != __a && __a_end - __a <= 2 && __a_end[-1] == '0') {
+ __dc = 0;
+ *__a_end++ = __src[__f];
+ return 0;
+ }
+ return -1;
+ }
+ *__a_end++ = __src[__f];
+ ++__dc;
+ return 0;
+}
+
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS collate<char>;
_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS collate<wchar_t>;)
diff --git a/libcxx/src/new.cpp b/libcxx/src/new.cpp
index ce6b637..70cdab6 100644
--- a/libcxx/src/new.cpp
+++ b/libcxx/src/new.cpp
@@ -6,9 +6,9 @@
//
//===----------------------------------------------------------------------===//
+#include "include/aligned_alloc.h"
#include "include/overridable_function.h"
#include <__assert>
-#include <__memory/aligned_alloc.h>
#include <cstddef>
#include <cstdlib>
#include <new>
diff --git a/libcxx/src/print.cpp b/libcxx/src/print.cpp
index 3f2baa6..82cf2af 100644
--- a/libcxx/src/print.cpp
+++ b/libcxx/src/print.cpp
@@ -22,6 +22,14 @@
# include <windows.h>
#elif __has_include(<unistd.h>)
# include <unistd.h>
+# if defined(_NEWLIB_VERSION)
+# if defined(_POSIX_C_SOURCE) && __has_include(<stdio.h>)
+# include <stdio.h>
+# define HAS_FILENO_AND_ISATTY
+# endif
+# else
+# define HAS_FILENO_AND_ISATTY
+# endif
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -56,7 +64,7 @@ __write_to_windows_console([[maybe_unused]] FILE* __stream, [[maybe_unused]] wst
}
# endif // _LIBCPP_HAS_WIDE_CHARACTERS
-#elif __has_include(<unistd.h>) // !_LIBCPP_WIN32API
+#elif defined(HAS_FILENO_AND_ISATTY) // !_LIBCPP_WIN32API
_LIBCPP_EXPORTED_FROM_ABI bool __is_posix_terminal(FILE* __stream) { return isatty(fileno(__stream)); }
#endif
diff --git a/libcxx/src/support/runtime/exception_fallback.ipp b/libcxx/src/support/runtime/exception_fallback.ipp
index ba283ae..dca904e 100644
--- a/libcxx/src/support/runtime/exception_fallback.ipp
+++ b/libcxx/src/support/runtime/exception_fallback.ipp
@@ -8,6 +8,8 @@
//===----------------------------------------------------------------------===//
#include <__verbose_abort>
+#include <exception>
+#include "include/atomic_support.h"
namespace std {
diff --git a/libcxx/src/support/runtime/exception_glibcxx.ipp b/libcxx/src/support/runtime/exception_glibcxx.ipp
index aa67cab..5eb8d87 100644
--- a/libcxx/src/support/runtime/exception_glibcxx.ipp
+++ b/libcxx/src/support/runtime/exception_glibcxx.ipp
@@ -11,6 +11,9 @@
# error header can only be used when targeting libstdc++ or libsupc++
#endif
+#include <exception>
+#include <new>
+
namespace std {
bad_alloc::bad_alloc() noexcept {}
diff --git a/libcxx/src/support/runtime/exception_libcxxabi.ipp b/libcxx/src/support/runtime/exception_libcxxabi.ipp
index df6bd65..c42bb23 100644
--- a/libcxx/src/support/runtime/exception_libcxxabi.ipp
+++ b/libcxx/src/support/runtime/exception_libcxxabi.ipp
@@ -7,6 +7,10 @@
//
//===----------------------------------------------------------------------===//
+#include <exception>
+
+#include <cxxabi.h>
+
#ifndef _LIBCPPABI_VERSION
# error this header can only be used with libc++abi
#endif
@@ -17,9 +21,9 @@ bool uncaught_exception() noexcept { return uncaught_exceptions() > 0; }
int uncaught_exceptions() noexcept {
#if _LIBCPPABI_VERSION > 1001
- return __cxa_uncaught_exceptions();
+ return abi::__cxa_uncaught_exceptions();
#else
- return __cxa_uncaught_exception() ? 1 : 0;
+ return abi::__cxa_uncaught_exception() ? 1 : 0;
#endif
}
diff --git a/libcxx/src/support/runtime/exception_libcxxrt.ipp b/libcxx/src/support/runtime/exception_libcxxrt.ipp
index f17fecc..6afdc00 100644
--- a/libcxx/src/support/runtime/exception_libcxxrt.ipp
+++ b/libcxx/src/support/runtime/exception_libcxxrt.ipp
@@ -11,6 +11,8 @@
# error this header may only be used when targeting libcxxrt
#endif
+#include <exception>
+
namespace std {
bad_exception::~bad_exception() noexcept {}
diff --git a/libcxx/src/support/runtime/exception_msvc.ipp b/libcxx/src/support/runtime/exception_msvc.ipp
index 2ae004b..7114d90 100644
--- a/libcxx/src/support/runtime/exception_msvc.ipp
+++ b/libcxx/src/support/runtime/exception_msvc.ipp
@@ -12,6 +12,8 @@
#endif
#include <__verbose_abort>
+#include <exception>
+#include <new>
extern "C" {
typedef void(__cdecl* terminate_handler)();
diff --git a/libcxx/src/support/runtime/exception_pointer_cxxabi.ipp b/libcxx/src/support/runtime/exception_pointer_cxxabi.ipp
index 8f5c206..75cb7c9 100644
--- a/libcxx/src/support/runtime/exception_pointer_cxxabi.ipp
+++ b/libcxx/src/support/runtime/exception_pointer_cxxabi.ipp
@@ -7,22 +7,21 @@
//
//===----------------------------------------------------------------------===//
-#ifndef HAVE_DEPENDENT_EH_ABI
-# error this header may only be used with libc++abi or libcxxrt
-#endif
+#include <cxxabi.h>
+#include <exception>
namespace std {
-exception_ptr::~exception_ptr() noexcept { __cxa_decrement_exception_refcount(__ptr_); }
+exception_ptr::~exception_ptr() noexcept { abi::__cxa_decrement_exception_refcount(__ptr_); }
exception_ptr::exception_ptr(const exception_ptr& other) noexcept : __ptr_(other.__ptr_) {
- __cxa_increment_exception_refcount(__ptr_);
+ abi::__cxa_increment_exception_refcount(__ptr_);
}
exception_ptr& exception_ptr::operator=(const exception_ptr& other) noexcept {
if (__ptr_ != other.__ptr_) {
- __cxa_increment_exception_refcount(other.__ptr_);
- __cxa_decrement_exception_refcount(__ptr_);
+ abi::__cxa_increment_exception_refcount(other.__ptr_);
+ abi::__cxa_decrement_exception_refcount(__ptr_);
__ptr_ = other.__ptr_;
}
return *this;
@@ -31,7 +30,7 @@ exception_ptr& exception_ptr::operator=(const exception_ptr& other) noexcept {
exception_ptr exception_ptr::__from_native_exception_pointer(void* __e) noexcept {
exception_ptr ptr;
ptr.__ptr_ = __e;
- __cxa_increment_exception_refcount(ptr.__ptr_);
+ abi::__cxa_increment_exception_refcount(ptr.__ptr_);
return ptr;
}
@@ -51,12 +50,12 @@ exception_ptr current_exception() noexcept {
// this whole function would be just:
// return exception_ptr(__cxa_current_primary_exception());
exception_ptr ptr;
- ptr.__ptr_ = __cxa_current_primary_exception();
+ ptr.__ptr_ = abi::__cxa_current_primary_exception();
return ptr;
}
void rethrow_exception(exception_ptr p) {
- __cxa_rethrow_primary_exception(p.__ptr_);
+ abi::__cxa_rethrow_primary_exception(p.__ptr_);
// if p.__ptr_ is NULL, above returns so we terminate
terminate();
}
diff --git a/libcxx/src/support/runtime/exception_pointer_glibcxx.ipp b/libcxx/src/support/runtime/exception_pointer_glibcxx.ipp
index 174b44c..4b08db6 100644
--- a/libcxx/src/support/runtime/exception_pointer_glibcxx.ipp
+++ b/libcxx/src/support/runtime/exception_pointer_glibcxx.ipp
@@ -16,6 +16,8 @@
// stable ABI), and its rethrow_exception(std::__exception_ptr::exception_ptr)
// function.
+#include <exception>
+
namespace std {
namespace __exception_ptr {
diff --git a/libcxx/src/support/runtime/exception_pointer_msvc.ipp b/libcxx/src/support/runtime/exception_pointer_msvc.ipp
index 2be5136..4141e03 100644
--- a/libcxx/src/support/runtime/exception_pointer_msvc.ipp
+++ b/libcxx/src/support/runtime/exception_pointer_msvc.ipp
@@ -7,6 +7,7 @@
//
//===----------------------------------------------------------------------===//
+#include <exception>
#include <stdio.h>
#include <stdlib.h>
diff --git a/libcxx/src/support/runtime/exception_pointer_unimplemented.ipp b/libcxx/src/support/runtime/exception_pointer_unimplemented.ipp
index 05a71ce..5e55f0f 100644
--- a/libcxx/src/support/runtime/exception_pointer_unimplemented.ipp
+++ b/libcxx/src/support/runtime/exception_pointer_unimplemented.ipp
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
#include <__verbose_abort>
+#include <exception>
namespace std {
diff --git a/libcxx/src/thread.cpp b/libcxx/src/thread.cpp
index 028d36e..e494574 100644
--- a/libcxx/src/thread.cpp
+++ b/libcxx/src/thread.cpp
@@ -74,9 +74,7 @@ unsigned thread::hardware_concurrency() noexcept {
return 0;
return static_cast<unsigned>(result);
#elif defined(_LIBCPP_WIN32API)
- SYSTEM_INFO info;
- GetSystemInfo(&info);
- return info.dwNumberOfProcessors;
+ return static_cast<unsigned>(GetActiveProcessorCount(ALL_PROCESSOR_GROUPS));
#else // defined(CTL_HW) && defined(HW_NCPU)
// TODO: grovel through /proc or check cpuid on x86 and similar
// instructions on other architectures.
diff --git a/libcxx/test/benchmarks/algorithms/nonmodifying/find.bench.cpp b/libcxx/test/benchmarks/algorithms/nonmodifying/find.bench.cpp
index afea31f..7780b5a 100644
--- a/libcxx/test/benchmarks/algorithms/nonmodifying/find.bench.cpp
+++ b/libcxx/test/benchmarks/algorithms/nonmodifying/find.bench.cpp
@@ -12,6 +12,7 @@
#include <cstddef>
#include <deque>
#include <list>
+#include <ranges>
#include <string>
#include <vector>
@@ -83,6 +84,20 @@ int main(int argc, char** argv) {
bm.template operator()<std::list<int>>("rng::find_if_not(list<int>) (" + comment + ")", ranges_find_if_not);
};
+ auto register_nested_container_benchmarks = [&](auto bm, std::string comment) {
+ // ranges_find
+ bm.template operator()<std::vector<std::vector<char>>>(
+ "rng::find(join_view(vector<vector<char>>)) (" + comment + ")", ranges_find);
+ bm.template operator()<std::vector<std::vector<int>>>(
+ "rng::find(join_view(vector<vector<int>>)) (" + comment + ")", ranges_find);
+ bm.template operator()<std::list<std::vector<int>>>(
+ "rng::find(join_view(list<vector<int>>)) (" + comment + ")", ranges_find);
+ bm.template operator()<std::vector<std::list<int>>>(
+ "rng::find(join_view(vector<list<int>>)) (" + comment + ")", ranges_find);
+ bm.template operator()<std::deque<std::deque<int>>>(
+ "rng::find(join_view(deque<deque<int>>)) (" + comment + ")", ranges_find);
+ };
+
// Benchmark {std,ranges}::{find,find_if,find_if_not}(normal container) where we
// bail out after 25% of elements
{
@@ -142,6 +157,44 @@ int main(int argc, char** argv) {
register_benchmarks(bm, "process all");
}
+ // Benchmark {std,ranges}::{find,find_if,find_if_not}(join(normal container)) where we process the whole sequence
+ {
+ auto bm = []<class Container>(std::string name, auto find) {
+ benchmark::RegisterBenchmark(
+ name,
+ [find](auto& st) {
+ std::size_t const size = st.range(0);
+ std::size_t const seg_size = 256;
+ std::size_t const segments = (size + seg_size - 1) / seg_size;
+ using C1 = typename Container::value_type;
+ using ValueType = typename C1::value_type;
+ ValueType x = Generate<ValueType>::random();
+ ValueType y = random_different_from({x});
+ Container c(segments);
+ auto n = size;
+ for (auto it = c.begin(); it != c.end(); it++) {
+ it->resize(std::min(seg_size, n), x);
+ n -= it->size();
+ }
+
+ auto view = c | std::views::join;
+
+ for ([[maybe_unused]] auto _ : st) {
+ benchmark::DoNotOptimize(c);
+ benchmark::DoNotOptimize(y);
+ auto result = find(view.begin(), view.end(), y);
+ benchmark::DoNotOptimize(result);
+ }
+ })
+ ->Arg(8)
+ ->Arg(50) // non power-of-two
+ ->Arg(1024)
+ ->Arg(8192)
+ ->Arg(1 << 15);
+ };
+ register_nested_container_benchmarks(bm, "process all");
+ }
+
// Benchmark {std,ranges}::{find,find_if,find_if_not}(vector<bool>) where we process the whole sequence
{
auto bm = [](std::string name, auto find) {
diff --git a/libcxx/test/benchmarks/containers/associative/associative_container_benchmarks.h b/libcxx/test/benchmarks/containers/associative/associative_container_benchmarks.h
index 22a6d0d..5dd55f2 100644
--- a/libcxx/test/benchmarks/containers/associative/associative_container_benchmarks.h
+++ b/libcxx/test/benchmarks/containers/associative/associative_container_benchmarks.h
@@ -11,6 +11,7 @@
#include <algorithm>
#include <iterator>
+#include <memory_resource>
#include <random>
#include <string>
#include <ranges>
@@ -33,6 +34,9 @@ struct adapt_operations {
// using InsertionResult = ...;
// static Container::iterator get_iterator(InsertionResult const&);
+
+ // template <class Allocator>
+ // using rebind_alloc = ...;
};
template <class Container>
@@ -103,6 +107,61 @@ void associative_container_benchmarks(std::string container) {
}
});
+ bench("ctor(const&, alloc)", [=](auto& st) {
+ const std::size_t size = st.range(0);
+ std::vector<Value> in = make_value_types(generate_unique_keys(size));
+ Container src(in.begin(), in.end());
+ ScratchSpace c[BatchSize];
+
+ while (st.KeepRunningBatch(BatchSize)) {
+ for (std::size_t i = 0; i != BatchSize; ++i) {
+ new (c + i) Container(src, std::allocator<typename Container::value_type>());
+ benchmark::DoNotOptimize(c + i);
+ benchmark::ClobberMemory();
+ }
+
+ st.PauseTiming();
+ for (std::size_t i = 0; i != BatchSize; ++i) {
+ reinterpret_cast<Container*>(c + i)->~Container();
+ }
+ st.ResumeTiming();
+ }
+ });
+
+ bench("ctor(&&, different allocs)", [=](auto& st) {
+ using PMRContainer = adapt_operations<Container>::template rebind_alloc<
+ std::pmr::polymorphic_allocator<typename Container::value_type>>;
+
+ const std::size_t size = st.range(0);
+ std::vector<Value> in = make_value_types(generate_unique_keys(size));
+ std::pmr::monotonic_buffer_resource rs(size * 64 * BatchSize); // 64 bytes should be enough per node
+ std::vector<PMRContainer> srcs;
+ srcs.reserve(BatchSize);
+ for (size_t i = 0; i != BatchSize; ++i)
+ srcs.emplace_back(&rs).insert(in.begin(), in.end());
+ alignas(PMRContainer) char c[BatchSize * sizeof(PMRContainer)];
+
+ std::pmr::monotonic_buffer_resource rs2(size * 64 * BatchSize); // 64 bytes should be enough per node
+ while (st.KeepRunningBatch(BatchSize)) {
+ for (std::size_t i = 0; i != BatchSize; ++i) {
+ new (c + i * sizeof(PMRContainer)) PMRContainer(std::move(srcs[i]), &rs2);
+ benchmark::DoNotOptimize(c + i);
+ benchmark::ClobberMemory();
+ }
+
+ st.PauseTiming();
+ for (std::size_t i = 0; i != BatchSize; ++i) {
+ reinterpret_cast<PMRContainer*>(c + i * sizeof(PMRContainer))->~PMRContainer();
+ }
+ rs2.release();
+ srcs.clear();
+ for (size_t i = 0; i != BatchSize; ++i)
+ srcs.emplace_back(&rs).insert(in.begin(), in.end());
+
+ st.ResumeTiming();
+ }
+ });
+
bench("ctor(iterator, iterator) (unsorted sequence)", [=](auto& st) {
const std::size_t size = st.range(0);
std::mt19937 randomness;
diff --git a/libcxx/test/benchmarks/containers/associative/flat_map.bench.cpp b/libcxx/test/benchmarks/containers/associative/flat_map.bench.cpp
index f3b8655..407afb1 100644
--- a/libcxx/test/benchmarks/containers/associative/flat_map.bench.cpp
+++ b/libcxx/test/benchmarks/containers/associative/flat_map.bench.cpp
@@ -24,6 +24,14 @@ struct support::adapt_operations<std::flat_map<K, V>> {
using InsertionResult = std::pair<typename std::flat_map<K, V>::iterator, bool>;
static auto get_iterator(InsertionResult const& result) { return result.first; }
+
+ template <class Allocator>
+ using rebind_alloc =
+ std::flat_map<K,
+ V,
+ std::less<K>,
+ std::vector<K, typename std::allocator_traits<Allocator>::template rebind_alloc<K>>,
+ std::vector<V, typename std::allocator_traits<Allocator>::template rebind_alloc<V>>>;
};
int main(int argc, char** argv) {
diff --git a/libcxx/test/benchmarks/containers/associative/flat_multimap.bench.cpp b/libcxx/test/benchmarks/containers/associative/flat_multimap.bench.cpp
index 80eaa5490..4f70d26 100644
--- a/libcxx/test/benchmarks/containers/associative/flat_multimap.bench.cpp
+++ b/libcxx/test/benchmarks/containers/associative/flat_multimap.bench.cpp
@@ -23,6 +23,14 @@ struct support::adapt_operations<std::flat_multimap<K, V>> {
using InsertionResult = typename std::flat_multimap<K, V>::iterator;
static auto get_iterator(InsertionResult const& result) { return result; }
+
+ template <class Allocator>
+ using rebind_alloc =
+ std::flat_multimap<K,
+ V,
+ std::less<K>,
+ std::vector<K, typename std::allocator_traits<Allocator>::template rebind_alloc<K>>,
+ std::vector<V, typename std::allocator_traits<Allocator>::template rebind_alloc<V>>>;
};
int main(int argc, char** argv) {
diff --git a/libcxx/test/benchmarks/containers/associative/map.bench.cpp b/libcxx/test/benchmarks/containers/associative/map.bench.cpp
index 142229a..cc9ffd8 100644
--- a/libcxx/test/benchmarks/containers/associative/map.bench.cpp
+++ b/libcxx/test/benchmarks/containers/associative/map.bench.cpp
@@ -38,6 +38,9 @@ struct support::adapt_operations<std::map<K, V>> {
using InsertionResult = std::pair<typename std::map<K, V>::iterator, bool>;
static auto get_iterator(InsertionResult const& result) { return result.first; }
+
+ template <class Allocator>
+ using rebind_alloc = std::map<K, V, std::less<K>, Allocator>;
};
int main(int argc, char** argv) {
diff --git a/libcxx/test/benchmarks/containers/associative/multimap.bench.cpp b/libcxx/test/benchmarks/containers/associative/multimap.bench.cpp
index 15a0b57..8e3abf0 100644
--- a/libcxx/test/benchmarks/containers/associative/multimap.bench.cpp
+++ b/libcxx/test/benchmarks/containers/associative/multimap.bench.cpp
@@ -24,6 +24,9 @@ struct support::adapt_operations<std::multimap<K, V>> {
using InsertionResult = typename std::multimap<K, V>::iterator;
static auto get_iterator(InsertionResult const& result) { return result; }
+
+ template <class Allocator>
+ using rebind_alloc = std::multimap<K, V, std::less<K>, Allocator>;
};
int main(int argc, char** argv) {
diff --git a/libcxx/test/benchmarks/containers/associative/multiset.bench.cpp b/libcxx/test/benchmarks/containers/associative/multiset.bench.cpp
index c205e0a..7bafd0a 100644
--- a/libcxx/test/benchmarks/containers/associative/multiset.bench.cpp
+++ b/libcxx/test/benchmarks/containers/associative/multiset.bench.cpp
@@ -22,6 +22,9 @@ struct support::adapt_operations<std::multiset<K>> {
using InsertionResult = typename std::multiset<K>::iterator;
static auto get_iterator(InsertionResult const& result) { return result; }
+
+ template <class Allocator>
+ using rebind_alloc = std::multiset<K, std::less<K>, Allocator>;
};
int main(int argc, char** argv) {
diff --git a/libcxx/test/benchmarks/containers/associative/set.bench.cpp b/libcxx/test/benchmarks/containers/associative/set.bench.cpp
index 50ee142..e5a6cc5 100644
--- a/libcxx/test/benchmarks/containers/associative/set.bench.cpp
+++ b/libcxx/test/benchmarks/containers/associative/set.bench.cpp
@@ -23,6 +23,9 @@ struct support::adapt_operations<std::set<K>> {
using InsertionResult = std::pair<typename std::set<K>::iterator, bool>;
static auto get_iterator(InsertionResult const& result) { return result.first; }
+
+ template <class Allocator>
+ using rebind_alloc = std::set<K, std::less<K>, Allocator>;
};
int main(int argc, char** argv) {
diff --git a/libcxx/test/benchmarks/containers/associative/unordered_map.bench.cpp b/libcxx/test/benchmarks/containers/associative/unordered_map.bench.cpp
index d670c53..ddfc90c 100644
--- a/libcxx/test/benchmarks/containers/associative/unordered_map.bench.cpp
+++ b/libcxx/test/benchmarks/containers/associative/unordered_map.bench.cpp
@@ -37,6 +37,9 @@ struct support::adapt_operations<std::unordered_map<K, V>> {
using InsertionResult = std::pair<typename std::unordered_map<K, V>::iterator, bool>;
static auto get_iterator(InsertionResult const& result) { return result.first; }
+
+ template <class Allocator>
+ using rebind_alloc = std::unordered_map<K, V, std::hash<K>, std::equal_to<K>, Allocator>;
};
int main(int argc, char** argv) {
diff --git a/libcxx/test/benchmarks/containers/associative/unordered_multimap.bench.cpp b/libcxx/test/benchmarks/containers/associative/unordered_multimap.bench.cpp
index 8738ca4..5d92bd8 100644
--- a/libcxx/test/benchmarks/containers/associative/unordered_multimap.bench.cpp
+++ b/libcxx/test/benchmarks/containers/associative/unordered_multimap.bench.cpp
@@ -23,6 +23,9 @@ struct support::adapt_operations<std::unordered_multimap<K, V>> {
using InsertionResult = typename std::unordered_multimap<K, V>::iterator;
static auto get_iterator(InsertionResult const& result) { return result; }
+
+ template <class Allocator>
+ using rebind_alloc = std::unordered_multimap<K, V, std::hash<K>, std::equal_to<K>, Allocator>;
};
int main(int argc, char** argv) {
diff --git a/libcxx/test/benchmarks/containers/associative/unordered_multiset.bench.cpp b/libcxx/test/benchmarks/containers/associative/unordered_multiset.bench.cpp
index 4888b01..09412fc 100644
--- a/libcxx/test/benchmarks/containers/associative/unordered_multiset.bench.cpp
+++ b/libcxx/test/benchmarks/containers/associative/unordered_multiset.bench.cpp
@@ -22,6 +22,9 @@ struct support::adapt_operations<std::unordered_multiset<K>> {
using InsertionResult = typename std::unordered_multiset<K>::iterator;
static auto get_iterator(InsertionResult const& result) { return result; }
+
+ template <class Allocator>
+ using rebind_alloc = std::unordered_multiset<K, std::hash<K>, std::equal_to<K>, Allocator>;
};
int main(int argc, char** argv) {
diff --git a/libcxx/test/benchmarks/containers/associative/unordered_set.bench.cpp b/libcxx/test/benchmarks/containers/associative/unordered_set.bench.cpp
index 89443a5..1b66633 100644
--- a/libcxx/test/benchmarks/containers/associative/unordered_set.bench.cpp
+++ b/libcxx/test/benchmarks/containers/associative/unordered_set.bench.cpp
@@ -24,6 +24,9 @@ struct support::adapt_operations<std::unordered_set<K>> {
using InsertionResult = std::pair<typename std::unordered_set<K>::iterator, bool>;
static auto get_iterator(InsertionResult const& result) { return result.first; }
+
+ template <class Allocator>
+ using rebind_alloc = std::unordered_set<K, std::hash<K>, std::equal_to<K>, Allocator>;
};
int main(int argc, char** argv) {
diff --git a/libcxx/test/benchmarks/containers/string.bench.cpp b/libcxx/test/benchmarks/containers/string.bench.cpp
index 2484ec8..98216d2 100644
--- a/libcxx/test/benchmarks/containers/string.bench.cpp
+++ b/libcxx/test/benchmarks/containers/string.bench.cpp
@@ -541,10 +541,7 @@ struct StringRead {
static bool skip() {
// Huge does not give us anything that Large doesn't have. Skip it.
- if (Length() == ::Length::Huge) {
- return true;
- }
- return false;
+ return Length() == ::Length::Huge;
}
std::string name() const { return "BM_StringRead" + Temperature::name() + Depth::name() + Length::name(); }
@@ -585,14 +582,6 @@ void sanityCheckGeneratedStrings() {
}
}
-// Some small codegen thunks to easily see generated code.
-bool StringEqString(const std::string& a, const std::string& b) { return a == b; }
-bool StringEqCStr(const std::string& a, const char* b) { return a == b; }
-bool CStrEqString(const char* a, const std::string& b) { return a == b; }
-bool StringEqCStrLiteralEmpty(const std::string& a) { return a == ""; }
-bool StringEqCStrLiteralSmall(const std::string& a) { return a == SmallStringLiteral; }
-bool StringEqCStrLiteralLarge(const std::string& a) { return a == LargeStringLiteral; }
-
int main(int argc, char** argv) {
benchmark::Initialize(&argc, argv);
if (benchmark::ReportUnrecognizedArguments(argc, argv))
@@ -615,16 +604,4 @@ int main(int argc, char** argv) {
makeCartesianProductBenchmark<StringRelationalLiteral, AllRelations, AllLengths, AllLengths, AllDiffTypes>();
makeCartesianProductBenchmark<StringRead, AllTemperatures, AllDepths, AllLengths>();
benchmark::RunSpecifiedBenchmarks();
-
- if (argc < 0) {
- // ODR-use the functions to force them being generated in the binary.
- auto functions = std::make_tuple(
- StringEqString,
- StringEqCStr,
- CStrEqString,
- StringEqCStrLiteralEmpty,
- StringEqCStrLiteralSmall,
- StringEqCStrLiteralLarge);
- printf("%p", &functions);
- }
}
diff --git a/libcxx/test/benchmarks/streams/fstream.bench.cpp b/libcxx/test/benchmarks/streams/ofstream.bench.cpp
index 3ca1801..60606a9 100644
--- a/libcxx/test/benchmarks/streams/fstream.bench.cpp
+++ b/libcxx/test/benchmarks/streams/ofstream.bench.cpp
@@ -11,7 +11,7 @@
#include <benchmark/benchmark.h>
-static void bm_ofstream_write(benchmark::State& state) {
+static void bm_write(benchmark::State& state) {
std::vector<char> buffer;
buffer.resize(16384);
@@ -20,24 +20,6 @@ static void bm_ofstream_write(benchmark::State& state) {
for (auto _ : state)
stream.write(buffer.data(), buffer.size());
}
-BENCHMARK(bm_ofstream_write);
-
-static void bm_ifstream_read(benchmark::State& state) {
- std::vector<char> buffer;
- buffer.resize(16384);
-
- std::ofstream gen_testfile("testfile");
- gen_testfile.write(buffer.data(), buffer.size());
-
- std::ifstream stream("testfile");
- assert(stream);
-
- for (auto _ : state) {
- stream.read(buffer.data(), buffer.size());
- benchmark::DoNotOptimize(buffer);
- stream.seekg(0);
- }
-}
-BENCHMARK(bm_ifstream_read);
+BENCHMARK(bm_write);
BENCHMARK_MAIN();
diff --git a/libcxx/test/extensions/gnu/hash_map/copy.pass.cpp b/libcxx/test/extensions/gnu/hash_map/copy.pass.cpp
new file mode 100644
index 0000000..65b8deb
--- /dev/null
+++ b/libcxx/test/extensions/gnu/hash_map/copy.pass.cpp
@@ -0,0 +1,27 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// ADDITIONAL_COMPILE_FLAGS: -Wno-deprecated
+
+// hash_map::hash_map(const hash_map&)
+
+#include <cassert>
+#include <ext/hash_map>
+
+int main(int, char**) {
+ __gnu_cxx::hash_map<int, int> map;
+
+ map.insert(std::make_pair(1, 1));
+ map.insert(std::make_pair(2, 1));
+
+ auto map2 = map;
+
+ assert(map2.size() == 2);
+
+ return 0;
+}
diff --git a/libcxx/test/extensions/gnu/hash_set/copy.pass.cpp b/libcxx/test/extensions/gnu/hash_set/copy.pass.cpp
new file mode 100644
index 0000000..95a3579
--- /dev/null
+++ b/libcxx/test/extensions/gnu/hash_set/copy.pass.cpp
@@ -0,0 +1,27 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// ADDITIONAL_COMPILE_FLAGS: -Wno-deprecated
+
+// hash_set::hash_set(const hash_set&)
+
+#include <cassert>
+#include <ext/hash_set>
+
+int main(int, char**) {
+ __gnu_cxx::hash_set<int> set;
+
+ set.insert(1);
+ set.insert(2);
+
+ auto set2 = set;
+
+ assert(set2.size() == 2);
+
+ return 0;
+}
diff --git a/libcxx/test/extensions/libcxx/odr_signature.assertion_semantics.sh.cpp b/libcxx/test/extensions/libcxx/odr_signature.assertion_semantics.sh.cpp
new file mode 100644
index 0000000..8ec1ec8
--- /dev/null
+++ b/libcxx/test/extensions/libcxx/odr_signature.assertion_semantics.sh.cpp
@@ -0,0 +1,71 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// ABI tags have no effect in MSVC mode.
+// XFAIL: msvc
+
+// Assertion semantics are not supported in C++03 mode and currently are experimental.
+// UNSUPPORTED: c++03, libcpp-has-no-experimental-hardening-observe-semantic
+
+// Test that we encode the assertion semantic in an ABI tag to avoid ODR violations when linking TUs that have different
+// values for it.
+
+// RUN: %{cxx} %s %{flags} %{compile_flags} -c -DTU1 -U_LIBCPP_ASSERTION_SEMANTIC -D_LIBCPP_ASSERTION_SEMANTIC=_LIBCPP_ASSERTION_SEMANTIC_IGNORE -o %t.tu1.o
+// RUN: %{cxx} %s %{flags} %{compile_flags} -c -DTU2 -U_LIBCPP_ASSERTION_SEMANTIC -D_LIBCPP_ASSERTION_SEMANTIC=_LIBCPP_ASSERTION_SEMANTIC_OBSERVE -o %t.tu2.o
+// RUN: %{cxx} %s %{flags} %{compile_flags} -c -DTU3 -U_LIBCPP_ASSERTION_SEMANTIC -D_LIBCPP_ASSERTION_SEMANTIC=_LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE -o %t.tu3.o
+// RUN: %{cxx} %s %{flags} %{compile_flags} -c -DTU4 -U_LIBCPP_ASSERTION_SEMANTIC -D_LIBCPP_ASSERTION_SEMANTIC=_LIBCPP_ASSERTION_SEMANTIC_ENFORCE -o %t.tu4.o
+// RUN: %{cxx} %s %{flags} %{compile_flags} -c -DMAIN -o %t.main.o
+// RUN: %{cxx} %t.tu1.o %t.tu2.o %t.tu3.o %t.tu4.o %t.main.o %{flags} %{link_flags} -o %t.exe
+// RUN: %{exec} %t.exe
+
+#include "test_macros.h"
+
+// `ignore` assertion semantic.
+#ifdef TU1
+# include <__config>
+_LIBCPP_HIDE_FROM_ABI TEST_NOINLINE inline int f() { return 1; }
+int tu1() { return f(); }
+#endif // TU1
+
+// `observe` assertion semantic.
+#ifdef TU2
+# include <__config>
+_LIBCPP_HIDE_FROM_ABI TEST_NOINLINE inline int f() { return 2; }
+int tu2() { return f(); }
+#endif // TU2
+
+// `quick-enforce` assertion semantic.
+#ifdef TU3
+# include <__config>
+_LIBCPP_HIDE_FROM_ABI TEST_NOINLINE inline int f() { return 3; }
+int tu3() { return f(); }
+#endif // TU3
+
+// `enforce` assertion semantic.
+#ifdef TU4
+# include <__config>
+_LIBCPP_HIDE_FROM_ABI TEST_NOINLINE inline int f() { return 4; }
+int tu4() { return f(); }
+#endif // TU4
+
+#ifdef MAIN
+# include <cassert>
+
+int tu1();
+int tu2();
+int tu3();
+int tu4();
+
+int main(int, char**) {
+ assert(tu1() == 1);
+ assert(tu2() == 2);
+ assert(tu3() == 3);
+ assert(tu4() == 4);
+ return 0;
+}
+#endif // MAIN
diff --git a/libcxx/test/extensions/libcxx/odr_signature.exceptions.sh.cpp b/libcxx/test/extensions/libcxx/odr_signature.exceptions.sh.cpp
index c0ba48e..61aaf4f 100644
--- a/libcxx/test/extensions/libcxx/odr_signature.exceptions.sh.cpp
+++ b/libcxx/test/extensions/libcxx/odr_signature.exceptions.sh.cpp
@@ -9,8 +9,6 @@
// ABI tags have no effect in MSVC mode.
// XFAIL: msvc
-// XFAIL: FROZEN-CXX03-HEADERS-FIXME
-
// Test that we encode whether exceptions are supported in an ABI tag to avoid
// ODR violations when linking TUs that have different values for it.
@@ -24,14 +22,14 @@
// -fno-exceptions
#ifdef TU1
-# include <__config>
+# include <version>
_LIBCPP_HIDE_FROM_ABI TEST_NOINLINE inline int f() { return 1; }
int tu1() { return f(); }
#endif // TU1
// -fexceptions
#ifdef TU2
-# include <__config>
+# include <version>
_LIBCPP_HIDE_FROM_ABI TEST_NOINLINE inline int f() { return 2; }
int tu2() { return f(); }
#endif // TU2
diff --git a/libcxx/test/extensions/libcxx/odr_signature.hardening.sh.cpp b/libcxx/test/extensions/libcxx/odr_signature.hardening.sh.cpp
index 8daf3f3..28647d7 100644
--- a/libcxx/test/extensions/libcxx/odr_signature.hardening.sh.cpp
+++ b/libcxx/test/extensions/libcxx/odr_signature.hardening.sh.cpp
@@ -9,8 +9,6 @@
// ABI tags have no effect in MSVC mode.
// XFAIL: msvc
-// XFAIL: FROZEN-CXX03-HEADERS-FIXME
-
// Test that we encode the hardening mode in an ABI tag to avoid ODR violations
// when linking TUs that have different values for it.
@@ -27,28 +25,28 @@
// fast hardening mode
#ifdef TU1
-# include <__config>
+# include <version>
_LIBCPP_HIDE_FROM_ABI TEST_NOINLINE inline int f() { return 1; }
int tu1() { return f(); }
#endif // TU1
// extensive hardening mode
#ifdef TU2
-# include <__config>
+# include <version>
_LIBCPP_HIDE_FROM_ABI TEST_NOINLINE inline int f() { return 2; }
int tu2() { return f(); }
#endif // TU2
// debug hardening mode
#ifdef TU3
-# include <__config>
+# include <version>
_LIBCPP_HIDE_FROM_ABI TEST_NOINLINE inline int f() { return 3; }
int tu3() { return f(); }
#endif // TU3
// No hardening
#ifdef TU4
-# include <__config>
+# include <version>
_LIBCPP_HIDE_FROM_ABI TEST_NOINLINE inline int f() { return 4; }
int tu4() { return f(); }
#endif // TU4
diff --git a/libcxx/test/libcxx-03/algorithms/half_positive.pass.cpp b/libcxx/test/libcxx-03/algorithms/half_positive.pass.cpp
index 292fcf3..ad0cac2 100644
--- a/libcxx/test/libcxx-03/algorithms/half_positive.pass.cpp
+++ b/libcxx/test/libcxx-03/algorithms/half_positive.pass.cpp
@@ -41,17 +41,5 @@ int main(int, char**)
#endif // !defined(TEST_HAS_NO_INT128)
}
-#if TEST_STD_VER >= 11
- {
- static_assert(test<char>(), "");
- static_assert(test<int>(), "");
- static_assert(test<long>(), "");
- static_assert(test<std::size_t>(), "");
-#if !defined(TEST_HAS_NO_INT128)
- static_assert(test<__int128_t>(), "");
-#endif // !defined(TEST_HAS_NO_INT128)
- }
-#endif // TEST_STD_VER >= 11
-
return 0;
}
diff --git a/libcxx/test/libcxx-03/algorithms/robust_against_copying_comparators.pass.cpp b/libcxx/test/libcxx-03/algorithms/robust_against_copying_comparators.pass.cpp
index 2562516..2e3fc6d 100644
--- a/libcxx/test/libcxx-03/algorithms/robust_against_copying_comparators.pass.cpp
+++ b/libcxx/test/libcxx-03/algorithms/robust_against_copying_comparators.pass.cpp
@@ -82,17 +82,6 @@ struct BinaryTransform {
TEST_CONSTEXPR T operator()(T, T) const { return 0; }
};
-#if TEST_STD_VER > 17
-template <class T>
-struct ThreeWay {
- int* copies_;
- constexpr explicit ThreeWay(int* copies) : copies_(copies) {}
- constexpr ThreeWay(const ThreeWay& rhs) : copies_(rhs.copies_) { *copies_ += 1; }
- constexpr ThreeWay& operator=(const ThreeWay&) = default;
- constexpr std::strong_ordering operator()(T, T) const { return std::strong_ordering::equal; }
-};
-#endif
-
template <class T>
TEST_CONSTEXPR_CXX20 bool all_the_algorithms() {
T a[10] = {};
@@ -109,28 +98,14 @@ TEST_CONSTEXPR_CXX20 bool all_the_algorithms() {
int copies = 0;
(void)std::adjacent_find(first, last, Equal<T>(&copies));
assert(copies == 0);
-#if TEST_STD_VER >= 11
- (void)std::all_of(first, last, UnaryTrue<T>(&copies));
- assert(copies == 0);
- (void)std::any_of(first, last, UnaryTrue<T>(&copies));
- assert(copies == 0);
-#endif
(void)std::binary_search(first, last, value, Less<T>(&copies));
assert(copies == 0);
-#if TEST_STD_VER > 17
- (void)std::clamp(value, value, value, Less<T>(&copies));
- assert(copies == 0);
-#endif
(void)std::count_if(first, last, UnaryTrue<T>(&copies));
assert(copies == 0);
(void)std::copy_if(first, last, first2, UnaryTrue<T>(&copies));
assert(copies == 0);
(void)std::equal(first, last, first2, Equal<T>(&copies));
assert(copies == 0);
-#if TEST_STD_VER > 11
- (void)std::equal(first, last, first2, last2, Equal<T>(&copies));
- assert(copies == 0);
-#endif
(void)std::equal_range(first, last, value, Less<T>(&copies));
assert(copies == 0);
(void)std::find_end(first, last, first2, mid2, Equal<T>(&copies));
@@ -144,10 +119,6 @@ TEST_CONSTEXPR_CXX20 bool all_the_algorithms() {
(void)std::for_each(first, last, UnaryVoid<T>(&copies));
assert(copies == 1);
copies = 0;
-#if TEST_STD_VER > 14
- (void)std::for_each_n(first, count, UnaryVoid<T>(&copies));
- assert(copies == 0);
-#endif
(void)std::generate(first, last, NullaryValue<T>(&copies));
assert(copies == 0);
(void)std::generate_n(first, count, NullaryValue<T>(&copies));
@@ -162,10 +133,6 @@ TEST_CONSTEXPR_CXX20 bool all_the_algorithms() {
assert(copies == 0);
(void)std::is_permutation(first, last, first2, Equal<T>(&copies));
assert(copies == 0);
-#if TEST_STD_VER > 11
- (void)std::is_permutation(first, last, first2, last2, Equal<T>(&copies));
- assert(copies == 0);
-#endif
(void)std::is_sorted(first, last, Less<T>(&copies));
assert(copies == 0);
(void)std::is_sorted_until(first, last, Less<T>(&copies));
@@ -176,52 +143,28 @@ TEST_CONSTEXPR_CXX20 bool all_the_algorithms() {
}
(void)std::lexicographical_compare(first, last, first2, last2, Less<T>(&copies));
assert(copies == 0);
-#if TEST_STD_VER > 17
- (void)std::lexicographical_compare_three_way(first, last, first2, last2, ThreeWay<T>(&copies));
- assert(copies == 0);
-#endif
(void)std::lower_bound(first, last, value, Less<T>(&copies));
assert(copies == 0);
(void)std::make_heap(first, last, Less<T>(&copies));
assert(copies == 0);
(void)std::max(value, value, Less<T>(&copies));
assert(copies == 0);
-#if TEST_STD_VER >= 11
- (void)std::max({value, value}, Less<T>(&copies));
- assert(copies == 0);
-#endif
(void)std::max_element(first, last, Less<T>(&copies));
assert(copies == 0);
(void)std::merge(first, mid, mid, last, first2, Less<T>(&copies));
assert(copies == 0);
(void)std::min(value, value, Less<T>(&copies));
assert(copies == 0);
-#if TEST_STD_VER >= 11
- (void)std::min({value, value}, Less<T>(&copies));
- assert(copies == 0);
-#endif
(void)std::min_element(first, last, Less<T>(&copies));
assert(copies == 0);
(void)std::minmax(value, value, Less<T>(&copies));
assert(copies == 0);
-#if TEST_STD_VER >= 11
- (void)std::minmax({value, value}, Less<T>(&copies));
- assert(copies == 0);
-#endif
(void)std::minmax_element(first, last, Less<T>(&copies));
assert(copies == 0);
(void)std::mismatch(first, last, first2, Equal<T>(&copies));
assert(copies == 0);
-#if TEST_STD_VER > 11
- (void)std::mismatch(first, last, first2, last2, Equal<T>(&copies));
- assert(copies == 0);
-#endif
(void)std::next_permutation(first, last, Less<T>(&copies));
assert(copies == 0);
-#if TEST_STD_VER >= 11
- (void)std::none_of(first, last, UnaryTrue<T>(&copies));
- assert(copies == 0);
-#endif
(void)std::nth_element(first, mid, last, Less<T>(&copies));
assert(copies == 0);
(void)std::partial_sort(first, mid, last, Less<T>(&copies));
@@ -299,14 +242,6 @@ bool test_segmented_iterator() {
assert(copies == 1);
copies = 0;
-#if TEST_STD_VER >= 20
- std::vector<std::vector<int>> vecs(3, std::vector<int>(10));
- auto v = std::views::join(vecs);
- (void)std::for_each(v.begin(), v.end(), UnaryVoid<int>(&copies));
- assert(copies == 1);
- copies = 0;
-#endif
-
return true;
}
@@ -314,10 +249,6 @@ int main(int, char**) {
all_the_algorithms<void*>();
all_the_algorithms<int>();
assert(test_segmented_iterator());
-#if TEST_STD_VER > 17
- static_assert(all_the_algorithms<void*>());
- static_assert(all_the_algorithms<int>());
-#endif
return 0;
}
diff --git a/libcxx/test/libcxx-03/algorithms/robust_against_cpp20_hostile_iterators.compile.pass.cpp b/libcxx/test/libcxx-03/algorithms/robust_against_cpp20_hostile_iterators.compile.pass.cpp
index 03fef57..009a234 100644
--- a/libcxx/test/libcxx-03/algorithms/robust_against_cpp20_hostile_iterators.compile.pass.cpp
+++ b/libcxx/test/libcxx-03/algorithms/robust_against_cpp20_hostile_iterators.compile.pass.cpp
@@ -99,10 +99,6 @@ void test() {
(void) std::equal_range(it, it, 0, pred);
(void) std::equal(it, it, it);
(void) std::equal(it, it, it, pred);
-#if TEST_STD_VER > 11
- (void) std::equal(it, it, it, it);
- (void) std::equal(it, it, it, it, pred);
-#endif
(void) std::fill_n(it, 0, 0);
(void) std::fill(it, it, 0);
(void) std::find_end(it, it, it, it);
@@ -112,9 +108,6 @@ void test() {
(void) std::find_if_not(it, it, pred);
(void) std::find_if(it, it, pred);
(void) std::find(it, it, 0);
-#if TEST_STD_VER > 14
- (void) std::for_each_n(it, 0, pred);
-#endif
(void) std::for_each(it, it, pred);
(void) std::generate_n(it, 0, pred);
(void) std::generate(it, it, pred);
@@ -129,20 +122,12 @@ void test() {
(void) std::is_partitioned(it, it, pred);
(void) std::is_permutation(it, it, it);
(void) std::is_permutation(it, it, it, pred);
-#if TEST_STD_VER > 11
- (void) std::is_permutation(it, it, it, it);
- (void) std::is_permutation(it, it, it, it, pred);
-#endif
(void) std::is_sorted_until(it, it);
(void) std::is_sorted_until(it, it, pred);
(void) std::is_sorted(it, it);
(void) std::is_sorted(it, it, pred);
(void) std::lexicographical_compare(it, it, it, it);
(void) std::lexicographical_compare(it, it, it, it, pred);
-#if TEST_STD_VER > 17
- (void)std::lexicographical_compare_three_way(it, it, it, it);
- (void)std::lexicographical_compare_three_way(it, it, it, it, std::compare_three_way());
-#endif
(void) std::lower_bound(it, it, 0);
(void) std::lower_bound(it, it, 0, pred);
(void) std::make_heap(it, it);
@@ -189,14 +174,8 @@ void test() {
(void) std::reverse(it, it);
(void) std::rotate_copy(it, it, it, it);
(void) std::rotate(it, it, it);
-#if TEST_STD_VER > 14
- (void) std::sample(it, it, it, 0, rng);
-#endif
(void) std::search(it, it, it, it);
(void) std::search(it, it, it, it, pred);
-#if TEST_STD_VER > 14
- (void) std::search(it, it, std::default_searcher<Cpp20HostileIterator<int*>>(it, it));
-#endif
(void) std::set_difference(it, it, it, it, it);
(void) std::set_difference(it, it, it, it, it, pred);
(void) std::set_intersection(it, it, it, it, it);
@@ -205,10 +184,6 @@ void test() {
(void) std::set_symmetric_difference(it, it, it, it, it, pred);
(void) std::set_union(it, it, it, it, it);
(void) std::set_union(it, it, it, it, it, pred);
-#if TEST_STD_VER > 17
- (void) std::shift_left(it, it, 0);
- (void) std::shift_right(it, it, 0);
-#endif
(void) std::shuffle(it, it, rng);
(void) std::sort_heap(it, it);
(void) std::sort_heap(it, it, pred);
diff --git a/libcxx/test/libcxx-03/containers/sequences/vector/asan.pass.cpp b/libcxx/test/libcxx-03/containers/sequences/vector/asan.pass.cpp
index 03d2b3e6..72875a5 100644
--- a/libcxx/test/libcxx-03/containers/sequences/vector/asan.pass.cpp
+++ b/libcxx/test/libcxx-03/containers/sequences/vector/asan.pass.cpp
@@ -26,29 +26,6 @@ extern "C" void __sanitizer_set_death_callback(void (*callback)(void));
void do_exit() { exit(0); }
int main(int, char**) {
-#if TEST_STD_VER >= 11
- {
- typedef int T;
- typedef cpp17_input_iterator<T*> MyInputIter;
- std::vector<T, min_allocator<T>> v;
- v.reserve(1);
- int i[] = {42};
- v.insert(v.begin(), MyInputIter(i), MyInputIter(i + 1));
- assert(v[0] == 42);
- assert(is_contiguous_container_asan_correct(v));
- }
- {
- typedef char T;
- typedef cpp17_input_iterator<T*> MyInputIter;
- std::vector<T, unaligned_allocator<T>> v;
- v.reserve(1);
- char i[] = {'a', 'b'};
- v.insert(v.begin(), MyInputIter(i), MyInputIter(i + 2));
- assert(v[0] == 'a');
- assert(v[1] == 'b');
- assert(is_contiguous_container_asan_correct(v));
- }
-#endif // TEST_STD_VER >= 11
{
typedef cpp17_input_iterator<int*> MyInputIter;
// Sould not trigger ASan.
diff --git a/libcxx/test/libcxx-03/containers/sequences/vector/asan_throw.pass.cpp b/libcxx/test/libcxx-03/containers/sequences/vector/asan_throw.pass.cpp
index dcfa802..c18242a 100644
--- a/libcxx/test/libcxx-03/containers/sequences/vector/asan_throw.pass.cpp
+++ b/libcxx/test/libcxx-03/containers/sequences/vector/asan_throw.pass.cpp
@@ -68,23 +68,6 @@ void test_push_back() {
assert(is_contiguous_container_asan_correct(v));
}
-void test_emplace_back() {
-#if TEST_STD_VER >= 11
- std::vector<X> v;
- v.reserve(2);
- v.push_back(X(2));
- assert(v.size() == 1);
- try {
- v.emplace_back(42);
- assert(0);
- } catch (int e) {
- assert(v.size() == 1);
- }
- assert(v.size() == 1);
- assert(is_contiguous_container_asan_correct(v));
-#endif
-}
-
void test_insert_range() {
std::vector<X> v;
v.reserve(4);
@@ -119,24 +102,6 @@ void test_insert() {
assert(is_contiguous_container_asan_correct(v));
}
-void test_emplace() {
-#if TEST_STD_VER >= 11
- std::vector<X> v;
- v.reserve(3);
- v.insert(v.end(), X(1));
- v.insert(v.begin(), X(2));
- assert(v.size() == 2);
- try {
- v.emplace(v.end(), 42);
- assert(0);
- } catch (int e) {
- assert(v.size() == 2);
- }
- assert(v.size() == 2);
- assert(is_contiguous_container_asan_correct(v));
-#endif
-}
-
void test_insert_range2() {
std::vector<X> v;
v.reserve(4);
@@ -219,10 +184,8 @@ void test_resize_param() {
int main(int, char**) {
test_push_back();
- test_emplace_back();
test_insert_range();
test_insert();
- test_emplace();
test_insert_range2();
test_insert_n();
test_insert_n2();
diff --git a/libcxx/test/libcxx-03/depr/depr.default.allocator/allocator.members/construct.cxx20.pass.cpp b/libcxx/test/libcxx-03/depr/depr.default.allocator/allocator.members/construct.cxx20.pass.cpp
index 9a37cf8..4e1cda5 100644
--- a/libcxx/test/libcxx-03/depr/depr.default.allocator/allocator.members/construct.cxx20.pass.cpp
+++ b/libcxx/test/libcxx-03/depr/depr.default.allocator/allocator.members/construct.cxx20.pass.cpp
@@ -38,24 +38,6 @@ struct A {
int move_only_constructed = 0;
-#if TEST_STD_VER >= 11
-class move_only {
- move_only(const move_only&) = delete;
- move_only& operator=(const move_only&) = delete;
-
-public:
- move_only(move_only&&) { ++move_only_constructed; }
- move_only& operator=(move_only&&) { return *this; }
-
- move_only() { ++move_only_constructed; }
- ~move_only() { --move_only_constructed; }
-
-public:
- int data; // unused other than to make sizeof(move_only) == sizeof(int).
- // but public to suppress "-Wunused-private-field"
-};
-#endif // TEST_STD_VER >= 11
-
int main(int, char**) {
globalMemCounter.reset();
{
@@ -107,41 +89,6 @@ int main(int, char**) {
assert(globalMemCounter.checkOutstandingNewEq(0));
assert(A_constructed == 0);
}
-#if TEST_STD_VER >= 11
- {
- std::allocator<move_only> a;
- assert(globalMemCounter.checkOutstandingNewEq(0));
- assert(move_only_constructed == 0);
-
- globalMemCounter.last_new_size = 0;
- move_only* ap = a.allocate(3);
- DoNotOptimize(ap);
- assert(globalMemCounter.checkOutstandingNewEq(1));
- assert(globalMemCounter.checkLastNewSizeEq(3 * sizeof(int)));
- assert(move_only_constructed == 0);
-
- a.construct(ap);
- assert(globalMemCounter.checkOutstandingNewEq(1));
- assert(move_only_constructed == 1);
-
- a.destroy(ap);
- assert(globalMemCounter.checkOutstandingNewEq(1));
- assert(move_only_constructed == 0);
-
- a.construct(ap, move_only());
- assert(globalMemCounter.checkOutstandingNewEq(1));
- assert(move_only_constructed == 1);
-
- a.destroy(ap);
- assert(globalMemCounter.checkOutstandingNewEq(1));
- assert(move_only_constructed == 0);
-
- a.deallocate(ap, 3);
- DoNotOptimize(ap);
- assert(globalMemCounter.checkOutstandingNewEq(0));
- assert(move_only_constructed == 0);
- }
-#endif
return 0;
}
diff --git a/libcxx/test/libcxx-03/input.output/string.streams/stringbuf/const_sso_buffer.pass.cpp b/libcxx/test/libcxx-03/input.output/string.streams/stringbuf/const_sso_buffer.pass.cpp
index d6caa33..b6cc6e50 100644
--- a/libcxx/test/libcxx-03/input.output/string.streams/stringbuf/const_sso_buffer.pass.cpp
+++ b/libcxx/test/libcxx-03/input.output/string.streams/stringbuf/const_sso_buffer.pass.cpp
@@ -20,7 +20,6 @@
#include <cassert>
#include "test_macros.h"
-#include "min_allocator.h"
template <class CharT>
struct test_buf : public std::basic_stringbuf<CharT> {
@@ -40,29 +39,6 @@ struct test_buf : public std::basic_stringbuf<CharT> {
explicit test_buf(std::ios_base::openmode which) : std::basic_stringbuf<CharT>(which) {}
explicit test_buf(const std::basic_string<CharT>& s) : std::basic_stringbuf<CharT>(s) {}
-#if TEST_STD_VER >= 20
- explicit test_buf(const std::allocator<CharT>& a) : std::basic_stringbuf<CharT>(a) {}
- test_buf(std::ios_base::openmode which, const std::allocator<CharT>& a) : std::basic_stringbuf<CharT>(which, a) {}
- explicit test_buf(std::basic_string<CharT>&& s)
- : std::basic_stringbuf<CharT>(std::forward<std::basic_string<CharT>>(s)) {}
-
- test_buf(const std::basic_string<CharT, std::char_traits<CharT>, min_allocator<CharT>>& s,
- const std::allocator<CharT>& a)
- : std::basic_stringbuf<CharT>(s, a) {}
- test_buf(const std::basic_string<CharT, std::char_traits<CharT>, min_allocator<CharT>>& s,
- std::ios_base::openmode which,
- const std::allocator<CharT>& a)
- : std::basic_stringbuf<CharT>(s, which, a) {}
- test_buf(const std::basic_string<CharT, std::char_traits<CharT>, min_allocator<CharT>>& s)
- : std::basic_stringbuf<CharT>(s) {}
-#endif // TEST_STD_VER >= 20
-
-#if TEST_STD_VER >= 26
- test_buf(std::basic_string_view<CharT> s) : std::basic_stringbuf<CharT>(s) {}
- test_buf(std::basic_string_view<CharT> s, const std::allocator<CharT>& a) : std::basic_stringbuf<CharT>(s, a) {}
- test_buf(std::basic_string_view<CharT> s, std::ios_base::openmode which, const std::allocator<CharT>& a)
- : std::basic_stringbuf<CharT>(s, which, a) {}
-#endif // TEST_STD_VER >= 26
};
template <class CharT>
@@ -88,76 +64,6 @@ static void test() {
assert(b.pptr() == b.pbase());
assert(b.epptr() == b.pbase() + size); // copy so uses size
}
-#if TEST_STD_VER >= 20
- {
- test_buf<CharT> b = test_buf<CharT>(std::allocator<CharT>());
- assert(b.pbase() != nullptr);
- assert(b.pptr() == b.pbase());
- assert(b.epptr() == b.pbase() + size);
- }
- {
- test_buf<CharT> b = test_buf<CharT>(std::ios_base::out, std::allocator<CharT>());
- assert(b.pbase() != nullptr);
- assert(b.pptr() == b.pbase());
- assert(b.epptr() == b.pbase() + size);
- }
- {
- std::basic_string<CharT> s;
- s.reserve(1024);
- std::size_t capacity = s.capacity();
- test_buf<CharT> b = test_buf<CharT>(std::move(s));
- assert(b.pbase() != nullptr);
- assert(b.pptr() == b.pbase());
- assert(b.epptr() >= b.pbase() + capacity); // move so uses s.capacity()
- }
- {
- std::basic_string<CharT, std::char_traits<CharT>, min_allocator<CharT>> s;
- s.reserve(1024);
- test_buf<CharT> b = test_buf<CharT>(s, std::allocator<CharT>());
- assert(b.pbase() != nullptr);
- assert(b.pptr() == b.pbase());
- assert(b.epptr() == b.pbase() + size); // copy so uses size
- }
- {
- std::basic_string<CharT, std::char_traits<CharT>, min_allocator<CharT>> s;
- s.reserve(1024);
- test_buf<CharT> b = test_buf<CharT>(s, std::ios_base::out, std::allocator<CharT>());
- assert(b.pbase() != nullptr);
- assert(b.pptr() == b.pbase());
- assert(b.epptr() == b.pbase() + size); // copy so uses size
- }
- {
- std::basic_string<CharT, std::char_traits<CharT>, min_allocator<CharT>> s;
- s.reserve(1024);
- test_buf<CharT> b = test_buf<CharT>(s);
- assert(b.pbase() != nullptr);
- assert(b.pptr() == b.pbase());
- assert(b.epptr() == b.pbase() + size); // copy so uses size
- }
-#endif // TEST_STD_VER >= 20
-#if TEST_STD_VER >= 26
- {
- std::basic_string_view<CharT> s;
- test_buf<CharT> b = test_buf<CharT>(s);
- assert(b.pbase() != nullptr);
- assert(b.pptr() == b.pbase());
- assert(b.epptr() == b.pbase() + size);
- }
- {
- std::basic_string_view<CharT> s;
- test_buf<CharT> b = test_buf<CharT>(s, std::allocator<CharT>());
- assert(b.pbase() != nullptr);
- assert(b.pptr() == b.pbase());
- assert(b.epptr() == b.pbase() + size);
- }
- {
- std::basic_string_view<CharT> s;
- test_buf<CharT> b = test_buf<CharT>(s, std::ios_base::out, std::allocator<CharT>());
- assert(b.pbase() != nullptr);
- assert(b.pptr() == b.pbase());
- assert(b.epptr() == b.pbase() + size);
- }
-#endif // TEST_STD_VER >= 26
}
int main(int, char**) {
diff --git a/libcxx/test/libcxx-03/iterators/bounded_iter/arithmetic.pass.cpp b/libcxx/test/libcxx-03/iterators/bounded_iter/arithmetic.pass.cpp
index b4b6e7f..b5b6916 100644
--- a/libcxx/test/libcxx-03/iterators/bounded_iter/arithmetic.pass.cpp
+++ b/libcxx/test/libcxx-03/iterators/bounded_iter/arithmetic.pass.cpp
@@ -99,14 +99,6 @@ TEST_CONSTEXPR_CXX14 bool tests() {
int main(int, char**) {
tests<int*>();
-#if TEST_STD_VER > 11
- static_assert(tests<int*>(), "");
-#endif
-
-#if TEST_STD_VER > 17
- tests<contiguous_iterator<int*> >();
- static_assert(tests<contiguous_iterator<int*> >(), "");
-#endif
return 0;
}
diff --git a/libcxx/test/libcxx-03/iterators/bounded_iter/comparison.pass.cpp b/libcxx/test/libcxx-03/iterators/bounded_iter/comparison.pass.cpp
index 490bfed..9c6ce28 100644
--- a/libcxx/test/libcxx-03/iterators/bounded_iter/comparison.pass.cpp
+++ b/libcxx/test/libcxx-03/iterators/bounded_iter/comparison.pass.cpp
@@ -60,28 +60,11 @@ TEST_CONSTEXPR_CXX14 bool tests() {
assert(iter1 >= iter1);
}
-#if TEST_STD_VER >= 20
- // P1614
- std::same_as<std::strong_ordering> decltype(auto) r1 = iter1 <=> iter2;
- assert(r1 == std::strong_ordering::less);
-#endif
-
return true;
}
int main(int, char**) {
tests<int*>();
-#if TEST_STD_VER > 11
- static_assert(tests<int*>(), "");
-#endif
-
-#if TEST_STD_VER > 17
- tests<contiguous_iterator<int*>>();
- static_assert(tests<contiguous_iterator<int*>>());
-
- tests<three_way_contiguous_iterator<int*>>();
- static_assert(tests<three_way_contiguous_iterator<int*>>());
-#endif
return 0;
}
diff --git a/libcxx/test/libcxx-03/iterators/bounded_iter/pointer_traits.pass.cpp b/libcxx/test/libcxx-03/iterators/bounded_iter/pointer_traits.pass.cpp
index 671e716..fe21529 100644
--- a/libcxx/test/libcxx-03/iterators/bounded_iter/pointer_traits.pass.cpp
+++ b/libcxx/test/libcxx-03/iterators/bounded_iter/pointer_traits.pass.cpp
@@ -37,10 +37,6 @@ TEST_CONSTEXPR_CXX14 bool tests() {
std::__bounded_iter<Iter> const iter2 = std::__make_bounded_iter(Iter(e), Iter(b), Iter(e));
assert(std::__to_address(iter1) == b); // in-bounds iterator
assert(std::__to_address(iter2) == e); // out-of-bounds iterator
-#if TEST_STD_VER > 17
- assert(std::to_address(iter1) == b); // in-bounds iterator
- assert(std::to_address(iter2) == e); // out-of-bounds iterator
-#endif
}
return true;
@@ -48,14 +44,6 @@ TEST_CONSTEXPR_CXX14 bool tests() {
int main(int, char**) {
tests<int*>();
-#if TEST_STD_VER > 11
- static_assert(tests<int*>(), "");
-#endif
-
-#if TEST_STD_VER > 17
- tests<contiguous_iterator<int*> >();
- static_assert(tests<contiguous_iterator<int*> >(), "");
-#endif
return 0;
}
diff --git a/libcxx/test/libcxx-03/iterators/bounded_iter/types.compile.pass.cpp b/libcxx/test/libcxx-03/iterators/bounded_iter/types.compile.pass.cpp
index 0d27dff..43c53a0 100644
--- a/libcxx/test/libcxx-03/iterators/bounded_iter/types.compile.pass.cpp
+++ b/libcxx/test/libcxx-03/iterators/bounded_iter/types.compile.pass.cpp
@@ -18,32 +18,9 @@
#include "test_macros.h"
-#if TEST_STD_VER > 17
-struct Iterator {
- struct value_type {};
- using difference_type = int;
- struct pointer {};
- using reference = value_type&;
- struct iterator_category : std::random_access_iterator_tag {};
- using iterator_concept = std::contiguous_iterator_tag;
-};
-
-using BoundedIter1 = std::__bounded_iter<Iterator>;
-static_assert(std::is_same<BoundedIter1::value_type, Iterator::value_type>::value, "");
-static_assert(std::is_same<BoundedIter1::difference_type, Iterator::difference_type>::value, "");
-static_assert(std::is_same<BoundedIter1::pointer, Iterator::pointer>::value, "");
-static_assert(std::is_same<BoundedIter1::reference, Iterator::reference>::value, "");
-static_assert(std::is_same<BoundedIter1::iterator_category, Iterator::iterator_category>::value, "");
-static_assert(std::is_same<BoundedIter1::iterator_concept, Iterator::iterator_concept>::value, "");
-#endif
-
-
using BoundedIter2 = std::__bounded_iter<int*>;
static_assert(std::is_same<BoundedIter2::value_type, int>::value, "");
static_assert(std::is_same<BoundedIter2::difference_type, std::ptrdiff_t>::value, "");
static_assert(std::is_same<BoundedIter2::pointer, int*>::value, "");
static_assert(std::is_same<BoundedIter2::reference, int&>::value, "");
static_assert(std::is_same<BoundedIter2::iterator_category, std::random_access_iterator_tag>::value, "");
-#if TEST_STD_VER > 17
-static_assert(std::is_same<BoundedIter2::iterator_concept, std::contiguous_iterator_tag>::value, "");
-#endif
diff --git a/libcxx/test/libcxx-03/iterators/contiguous_iterators.conv.compile.pass.cpp b/libcxx/test/libcxx-03/iterators/contiguous_iterators.conv.compile.pass.cpp
index 4d36909..3e9707a 100644
--- a/libcxx/test/libcxx-03/iterators/contiguous_iterators.conv.compile.pass.cpp
+++ b/libcxx/test/libcxx-03/iterators/contiguous_iterators.conv.compile.pass.cpp
@@ -54,12 +54,3 @@ static_assert(!std::is_constructible<std::vector<Base>::iterator, std::vector<De
static_assert(!std::is_constructible<std::vector<Base>::const_iterator, std::vector<Derived>::iterator>::value, "");
static_assert(!std::is_constructible<std::vector<Base>::const_iterator, std::vector<Derived>::const_iterator>::value,
"");
-
-#if TEST_STD_VER >= 20
-static_assert(!std::is_convertible_v<std::span<Derived>::iterator, std::span<Base>::iterator>);
-static_assert(!std::is_convertible_v<std::span<Derived>::iterator, std::span<const Base>::iterator>);
-static_assert(!std::is_convertible_v<std::span<const Derived>::iterator, std::span<Base>::iterator>);
-static_assert(!std::is_constructible_v<std::span<Base>::iterator, std::span<Derived>::iterator>);
-static_assert(!std::is_constructible_v<std::span<Base>::iterator, std::span<const Derived>::iterator>);
-static_assert(!std::is_constructible_v<std::span<const Base>::iterator, std::span<const Derived>::iterator>);
-#endif
diff --git a/libcxx/test/libcxx-03/iterators/contiguous_iterators.pass.cpp b/libcxx/test/libcxx-03/iterators/contiguous_iterators.pass.cpp
index f00ca4e..56f12e0 100644
--- a/libcxx/test/libcxx-03/iterators/contiguous_iterators.pass.cpp
+++ b/libcxx/test/libcxx-03/iterators/contiguous_iterators.pass.cpp
@@ -27,14 +27,6 @@
#include "test_macros.h"
#include "test_iterators.h"
-#if TEST_STD_VER >= 17
-#include <string_view>
-#endif
-
-#if TEST_STD_VER >= 20
-#include <span>
-#endif
-
class T; // incomplete
class my_input_iterator
@@ -94,59 +86,12 @@ public:
friend bool operator>=(const Self&, const Self&);
};
-#if TEST_STD_VER >= 20
-class my_contiguous_iterator
-{
- struct tag : std::contiguous_iterator_tag {};
- typedef my_contiguous_iterator Self;
- int *state_;
-public:
- typedef tag iterator_category;
- typedef int value_type;
- typedef int difference_type;
- typedef int* pointer;
- typedef int& reference;
- typedef int element_type; // enable to_address via pointer_traits
-
- my_contiguous_iterator();
- reference operator*() const;
- pointer operator->() const;
- reference operator[](difference_type) const;
-
- Self& operator++();
- Self operator++(int);
- Self& operator--();
- Self operator--(int);
- friend Self& operator+=(Self&, difference_type);
- friend Self& operator-=(Self&, difference_type);
- friend Self operator+(Self, difference_type);
- friend Self operator+(difference_type, Self);
- friend Self operator-(Self, difference_type);
- friend difference_type operator-(Self, Self);
- friend bool operator==(const Self&, const Self&);
- friend bool operator!=(const Self&, const Self&);
- friend bool operator<(const Self&, const Self&);
- friend bool operator>(const Self&, const Self&);
- friend bool operator<=(const Self&, const Self&);
- friend bool operator>=(const Self&, const Self&);
-};
-#endif
-
struct fake_deque_iterator : std::deque<int>::iterator {
using element_type = int;
};
static_assert(std::__has_random_access_iterator_category<fake_deque_iterator>::value, "");
static_assert(!std::__libcpp_is_contiguous_iterator<fake_deque_iterator>::value, "");
-#if TEST_STD_VER >= 20
-struct fake2_deque_iterator : std::deque<int>::iterator {
- using iterator_concept = std::contiguous_iterator_tag;
- using element_type = int;
-};
-static_assert(std::__has_random_access_iterator_category<fake2_deque_iterator>::value, "");
-static_assert(std::__libcpp_is_contiguous_iterator<fake2_deque_iterator>::value, "");
-#endif
-
int main(int, char**)
{
// basic tests
@@ -158,9 +103,6 @@ int main(int, char**)
static_assert((!std::__libcpp_is_contiguous_iterator<my_input_iterator>::value), "");
static_assert((!std::__libcpp_is_contiguous_iterator<my_random_access_iterator>::value), "");
-#if TEST_STD_VER >= 20
- static_assert(( std::__libcpp_is_contiguous_iterator<my_contiguous_iterator>::value), "");
-#endif
// move_iterator changes value category, which makes it pretty sketchy to use in optimized codepaths
static_assert((!std::__libcpp_is_contiguous_iterator<std::move_iterator<char *> >::value), "");
@@ -168,18 +110,12 @@ int main(int, char**)
static_assert((!std::__libcpp_is_contiguous_iterator<std::move_iterator<int *> >::value), "");
static_assert((!std::__libcpp_is_contiguous_iterator<std::move_iterator<T *> >::value), "");
static_assert((!std::__libcpp_is_contiguous_iterator<std::move_iterator<my_random_access_iterator> >::value), "");
-#if TEST_STD_VER >= 20
- static_assert((!std::__libcpp_is_contiguous_iterator<std::move_iterator<my_contiguous_iterator> >::value), "");
-#endif
static_assert((!std::__libcpp_is_contiguous_iterator<std::reverse_iterator<char *> >::value), "");
static_assert((!std::__libcpp_is_contiguous_iterator<std::reverse_iterator<const char *> >::value), "");
static_assert((!std::__libcpp_is_contiguous_iterator<std::reverse_iterator<int *> >::value), "");
static_assert((!std::__libcpp_is_contiguous_iterator<std::reverse_iterator<T *> >::value), "");
static_assert((!std::__libcpp_is_contiguous_iterator<std::reverse_iterator<my_random_access_iterator> >::value), "");
-#if TEST_STD_VER >= 20
- static_assert((!std::__libcpp_is_contiguous_iterator<std::reverse_iterator<my_contiguous_iterator> >::value), "");
-#endif
static_assert(( std::__libcpp_is_contiguous_iterator<std::__wrap_iter<char *> >::value), "");
static_assert(( std::__libcpp_is_contiguous_iterator<std::__wrap_iter<const char *> >::value), "");
@@ -192,20 +128,12 @@ int main(int, char**)
static_assert(( std::__libcpp_is_contiguous_iterator<std::__wrap_iter<my_random_access_iterator> >::value), "");
static_assert(( std::__libcpp_is_contiguous_iterator<std::__wrap_iter<std::__wrap_iter<my_random_access_iterator> > >::value), "");
-#if TEST_STD_VER >= 20
- static_assert(( std::__libcpp_is_contiguous_iterator<std::__wrap_iter<my_contiguous_iterator> >::value), "");
- static_assert(( std::__libcpp_is_contiguous_iterator<std::__wrap_iter<std::__wrap_iter<my_contiguous_iterator> > >::value), "");
-#endif
-
// iterators in the libc++ test suite
static_assert((!std::__libcpp_is_contiguous_iterator<cpp17_output_iterator <char *> >::value), "");
static_assert((!std::__libcpp_is_contiguous_iterator<cpp17_input_iterator <char *> >::value), "");
static_assert((!std::__libcpp_is_contiguous_iterator<forward_iterator <char *> >::value), "");
static_assert((!std::__libcpp_is_contiguous_iterator<bidirectional_iterator<char *> >::value), "");
static_assert((!std::__libcpp_is_contiguous_iterator<random_access_iterator<char *> >::value), "");
-#if TEST_STD_VER >= 20
- static_assert(( std::__libcpp_is_contiguous_iterator<contiguous_iterator <char *> >::value), "");
-#endif
static_assert((!std::__libcpp_is_contiguous_iterator<ThrowingIterator <char *> >::value), "");
static_assert((!std::__libcpp_is_contiguous_iterator<NonThrowingIterator <char *> >::value), "");
@@ -244,22 +172,5 @@ int main(int, char**)
static_assert((!std::__libcpp_is_contiguous_iterator<std::vector<bool>::reverse_iterator> ::value), "");
static_assert((!std::__libcpp_is_contiguous_iterator<std::vector<bool>::const_reverse_iterator> ::value), "");
-#if TEST_STD_VER >= 11
- static_assert(( std::__libcpp_is_contiguous_iterator<std::initializer_list<int>::iterator> ::value), "");
- static_assert(( std::__libcpp_is_contiguous_iterator<std::initializer_list<int>::const_iterator>::value), "");
-#endif
-
-#if TEST_STD_VER >= 17
- static_assert(( std::__libcpp_is_contiguous_iterator<std::string_view::iterator> ::value), "");
- static_assert(( std::__libcpp_is_contiguous_iterator<std::string_view::const_iterator>::value), "");
-#endif
-
-#if TEST_STD_VER >= 20
- static_assert(( std::__libcpp_is_contiguous_iterator<std::span< int>::iterator> ::value), "");
- static_assert((!std::__libcpp_is_contiguous_iterator<std::span< int>::reverse_iterator>::value), "");
- static_assert(( std::__libcpp_is_contiguous_iterator<std::span<const int>::iterator> ::value), "");
- static_assert((!std::__libcpp_is_contiguous_iterator<std::span<const int>::reverse_iterator>::value), "");
-#endif
-
return 0;
}
diff --git a/libcxx/test/libcxx-03/iterators/predef.iterators/insert.iterators/back.insert.iter.ops/get_container.pass.cpp b/libcxx/test/libcxx-03/iterators/predef.iterators/insert.iterators/back.insert.iter.ops/get_container.pass.cpp
index 9f45848e..f9b242b 100644
--- a/libcxx/test/libcxx-03/iterators/predef.iterators/insert.iterators/back.insert.iter.ops/get_container.pass.cpp
+++ b/libcxx/test/libcxx-03/iterators/predef.iterators/insert.iterators/back.insert.iter.ops/get_container.pass.cpp
@@ -17,7 +17,6 @@
#include "test_macros.h"
#include "nasty_containers.h"
-#include "test_constexpr_container.h"
template <class C>
TEST_CONSTEXPR_CXX20 bool test(C c) {
@@ -29,9 +28,6 @@ TEST_CONSTEXPR_CXX20 bool test(C c) {
int main(int, char**) {
test(std::vector<int>());
test(nasty_vector<int>());
-#if TEST_STD_VER >= 20
- test(ConstexprFixedCapacityDeque<int, 10>());
- static_assert(test(ConstexprFixedCapacityDeque<int, 10>()));
-#endif
+
return 0;
}
diff --git a/libcxx/test/libcxx-03/iterators/unwrap_iter.pass.cpp b/libcxx/test/libcxx-03/iterators/unwrap_iter.pass.cpp
index 8ef2be2..d93c809 100644
--- a/libcxx/test/libcxx-03/iterators/unwrap_iter.pass.cpp
+++ b/libcxx/test/libcxx-03/iterators/unwrap_iter.pass.cpp
@@ -51,9 +51,6 @@ TEST_CONSTEXPR_CXX20 bool test() {
int main(int, char**) {
test();
-#if TEST_STD_VER > 17
- static_assert(test());
-#endif
return 0;
}
diff --git a/libcxx/test/libcxx-03/language.support/support.dynamic/libcpp_deallocate.sh.cpp b/libcxx/test/libcxx-03/language.support/support.dynamic/libcpp_deallocate.sh.cpp
index a9fe04f..e782438 100644
--- a/libcxx/test/libcxx-03/language.support/support.dynamic/libcpp_deallocate.sh.cpp
+++ b/libcxx/test/libcxx-03/language.support/support.dynamic/libcpp_deallocate.sh.cpp
@@ -200,13 +200,6 @@ void test_allocator_and_new_match() {
stats.reset();
#elif defined(NO_SIZE)
stats.reset();
-# if TEST_STD_VER >= 11
- {
- int* x = DoNotOptimize(new int(42));
- delete x;
- assert(stats.expect_plain());
- }
-# endif
stats.reset();
{
AlignedType* a = DoNotOptimize(new AlignedType());
diff --git a/libcxx/test/libcxx-03/libcpp_alignof.pass.cpp b/libcxx/test/libcxx-03/libcpp_alignof.pass.cpp
index 3ae7f74..8d319d9 100644
--- a/libcxx/test/libcxx-03/libcpp_alignof.pass.cpp
+++ b/libcxx/test/libcxx-03/libcpp_alignof.pass.cpp
@@ -19,9 +19,6 @@ template <class T>
void test() {
static_assert(_LIBCPP_ALIGNOF(T) == std::alignment_of<T>::value, "");
static_assert(_LIBCPP_ALIGNOF(T) == TEST_ALIGNOF(T), "");
-#if TEST_STD_VER >= 11
- static_assert(_LIBCPP_ALIGNOF(T) == alignof(T), "");
-#endif
#ifdef TEST_COMPILER_CLANG
static_assert(_LIBCPP_ALIGNOF(T) == _Alignof(T), "");
#endif
diff --git a/libcxx/test/libcxx-03/memory/allocation_guard.pass.cpp b/libcxx/test/libcxx-03/memory/allocation_guard.pass.cpp
index 5e71dec..ff6402e 100644
--- a/libcxx/test/libcxx-03/memory/allocation_guard.pass.cpp
+++ b/libcxx/test/libcxx-03/memory/allocation_guard.pass.cpp
@@ -85,11 +85,7 @@ struct AssignableAllocator {
TEST_CONSTEXPR_CXX20 void construct(pointer p, U&& val) {
if (stats_ != nullptr)
++stats_->construct_count;
-#if TEST_STD_VER > 17
- std::construct_at(std::to_address(p), std::forward<U>(val));
-#else
::new (static_cast<void*>(p)) T(std::forward<U>(val));
-#endif
}
TEST_CONSTEXPR_CXX14 void destroy(pointer p) {
diff --git a/libcxx/test/libcxx-03/memory/swap_allocator.pass.cpp b/libcxx/test/libcxx-03/memory/swap_allocator.pass.cpp
index 38dde7a..38fe778 100644
--- a/libcxx/test/libcxx-03/memory/swap_allocator.pass.cpp
+++ b/libcxx/test/libcxx-03/memory/swap_allocator.pass.cpp
@@ -58,24 +58,5 @@ int main(int, char**) {
assert(a2.i == 42);
}
-#if TEST_STD_VER >= 11
- {
- NoexceptSwapAlloc noexcept_alloc;
- static_assert(noexcept(std::__swap_allocator(noexcept_alloc, noexcept_alloc)), "");
- }
-
-#if TEST_STD_VER > 11
- { // From C++14, `__swap_allocator` is unconditionally noexcept.
- ThrowingSwapAlloc throwing_alloc;
- static_assert(noexcept(std::__swap_allocator(throwing_alloc, throwing_alloc)), "");
- }
-#else
- { // Until C++14, `__swap_allocator` is only noexcept if the underlying `swap` function is `noexcept`.
- ThrowingSwapAlloc throwing_alloc;
- static_assert(!noexcept(std::__swap_allocator(throwing_alloc, throwing_alloc)), "");
- }
-#endif // TEST_STD_VER > 11
-#endif // TEST_STD_VER >= 11
-
return 0;
}
diff --git a/libcxx/test/libcxx-03/numerics/bit.ops.pass.cpp b/libcxx/test/libcxx-03/numerics/bit.ops.pass.cpp
index 0b82f35..1f20811 100644
--- a/libcxx/test/libcxx-03/numerics/bit.ops.pass.cpp
+++ b/libcxx/test/libcxx-03/numerics/bit.ops.pass.cpp
@@ -29,9 +29,6 @@ TEST_CONSTEXPR_CXX14 bool test() {
int main(int, char**) {
test();
-#if TEST_STD_VER > 11
- static_assert(test(), "");
-#endif
return 0;
}
diff --git a/libcxx/test/libcxx-03/strings/basic.string/string.capacity/max_size.pass.cpp b/libcxx/test/libcxx-03/strings/basic.string/string.capacity/max_size.pass.cpp
index 6bfcb5d..73825ef 100644
--- a/libcxx/test/libcxx-03/strings/basic.string/string.capacity/max_size.pass.cpp
+++ b/libcxx/test/libcxx-03/strings/basic.string/string.capacity/max_size.pass.cpp
@@ -112,9 +112,6 @@ TEST_CONSTEXPR_CXX20 bool test() {
int main(int, char**) {
test();
-#if TEST_STD_VER > 17
- static_assert(test());
-#endif
return 0;
}
diff --git a/libcxx/test/libcxx-03/strings/basic.string/string.cons/copy_shrunk_long.pass.cpp b/libcxx/test/libcxx-03/strings/basic.string/string.cons/copy_shrunk_long.pass.cpp
index d4a0b31..309c84b 100644
--- a/libcxx/test/libcxx-03/strings/basic.string/string.cons/copy_shrunk_long.pass.cpp
+++ b/libcxx/test/libcxx-03/strings/basic.string/string.cons/copy_shrunk_long.pass.cpp
@@ -15,7 +15,6 @@
#include "test_macros.h"
#include "test_allocator.h"
-#include "min_allocator.h"
template <class S>
TEST_CONSTEXPR_CXX20 bool test() {
@@ -33,13 +32,6 @@ TEST_CONSTEXPR_CXX20 bool test() {
int main(int, char**) {
test<std::basic_string<char, std::char_traits<char>, test_allocator<char> > >();
-#if TEST_STD_VER >= 11
- test<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
-#endif
-#if TEST_STD_VER > 17
- static_assert(test<std::basic_string<char, std::char_traits<char>, test_allocator<char>>>());
- static_assert(test<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>());
-#endif
return 0;
}
diff --git a/libcxx/test/libcxx-03/strings/c.strings/constexpr_memmove.pass.cpp b/libcxx/test/libcxx-03/strings/c.strings/constexpr_memmove.pass.cpp
index d2ca5a2..6c7d194 100644
--- a/libcxx/test/libcxx-03/strings/c.strings/constexpr_memmove.pass.cpp
+++ b/libcxx/test/libcxx-03/strings/c.strings/constexpr_memmove.pass.cpp
@@ -148,8 +148,6 @@ TEST_CONSTEXPR_CXX14 bool test() {
int main(int, char**) {
test();
-#if TEST_STD_VER >= 14
- static_assert(test(), "");
-#endif
+
return 0;
}
diff --git a/libcxx/test/libcxx-03/type_traits/is_trivially_relocatable.compile.pass.cpp b/libcxx/test/libcxx-03/type_traits/is_trivially_relocatable.compile.pass.cpp
index 09049f3..b3880ed 100644
--- a/libcxx/test/libcxx-03/type_traits/is_trivially_relocatable.compile.pass.cpp
+++ b/libcxx/test/libcxx-03/type_traits/is_trivially_relocatable.compile.pass.cpp
@@ -128,31 +128,11 @@ static_assert(!std::__libcpp_is_trivially_relocatable<std::deque<int, test_alloc
static_assert(std::__libcpp_is_trivially_relocatable<std::exception_ptr>::value, "");
#endif
-// expected
-#if TEST_STD_VER >= 23
-static_assert(std::__libcpp_is_trivially_relocatable<std::expected<int, int> >::value);
-static_assert(std::__libcpp_is_trivially_relocatable<std::expected<std::unique_ptr<int>, int>>::value);
-static_assert(std::__libcpp_is_trivially_relocatable<std::expected<int, std::unique_ptr<int>>>::value);
-static_assert(std::__libcpp_is_trivially_relocatable<std::expected<std::unique_ptr<int>, std::unique_ptr<int>>>::value);
-
-static_assert(!std::__libcpp_is_trivially_relocatable<std::expected<int, NotTriviallyCopyable>>::value);
-static_assert(!std::__libcpp_is_trivially_relocatable<std::expected<NotTriviallyCopyable, int>>::value);
-static_assert(
- !std::__libcpp_is_trivially_relocatable<std::expected<NotTriviallyCopyable, NotTriviallyCopyable>>::value);
-#endif
-
// locale
#ifndef TEST_HAS_NO_LOCALIZATION
static_assert(std::__libcpp_is_trivially_relocatable<std::locale>::value, "");
#endif
-// optional
-#if TEST_STD_VER >= 17
-static_assert(std::__libcpp_is_trivially_relocatable<std::optional<int>>::value, "");
-static_assert(!std::__libcpp_is_trivially_relocatable<std::optional<NotTriviallyCopyable>>::value, "");
-static_assert(std::__libcpp_is_trivially_relocatable<std::optional<std::unique_ptr<int>>>::value, "");
-#endif // TEST_STD_VER >= 17
-
// pair
static_assert(std::__libcpp_is_trivially_relocatable<std::pair<int, int> >::value, "");
static_assert(!std::__libcpp_is_trivially_relocatable<std::pair<NotTriviallyCopyable, int> >::value, "");
@@ -165,23 +145,6 @@ static_assert(std::__libcpp_is_trivially_relocatable<std::pair<std::unique_ptr<i
// shared_ptr
static_assert(std::__libcpp_is_trivially_relocatable<std::shared_ptr<NotTriviallyCopyable> >::value, "");
-// tuple
-#if TEST_STD_VER >= 11
-static_assert(std::__libcpp_is_trivially_relocatable<std::tuple<> >::value, "");
-
-static_assert(std::__libcpp_is_trivially_relocatable<std::tuple<int> >::value, "");
-static_assert(!std::__libcpp_is_trivially_relocatable<std::tuple<NotTriviallyCopyable> >::value, "");
-static_assert(std::__libcpp_is_trivially_relocatable<std::tuple<std::unique_ptr<int> > >::value, "");
-
-static_assert(std::__libcpp_is_trivially_relocatable<std::tuple<int, int> >::value, "");
-static_assert(!std::__libcpp_is_trivially_relocatable<std::tuple<NotTriviallyCopyable, int> >::value, "");
-static_assert(!std::__libcpp_is_trivially_relocatable<std::tuple<int, NotTriviallyCopyable> >::value, "");
-static_assert(!std::__libcpp_is_trivially_relocatable<std::tuple<NotTriviallyCopyable, NotTriviallyCopyable> >::value,
- "");
-static_assert(std::__libcpp_is_trivially_relocatable<std::tuple<std::unique_ptr<int>, std::unique_ptr<int> > >::value,
- "");
-#endif // TEST_STD_VER >= 11
-
// unique_ptr
struct NotTriviallyRelocatableDeleter {
NotTriviallyRelocatableDeleter(const NotTriviallyRelocatableDeleter&);
@@ -215,21 +178,6 @@ static_assert(!std::__libcpp_is_trivially_relocatable<std::unique_ptr<int, NotTr
static_assert(!std::__libcpp_is_trivially_relocatable<std::unique_ptr<int[], NotTriviallyRelocatablePointer> >::value,
"");
-// variant
-#if TEST_STD_VER >= 17
-static_assert(std::__libcpp_is_trivially_relocatable<std::variant<int> >::value, "");
-static_assert(!std::__libcpp_is_trivially_relocatable<std::variant<NotTriviallyCopyable> >::value, "");
-static_assert(std::__libcpp_is_trivially_relocatable<std::variant<std::unique_ptr<int> > >::value, "");
-
-static_assert(std::__libcpp_is_trivially_relocatable<std::variant<int, int> >::value, "");
-static_assert(!std::__libcpp_is_trivially_relocatable<std::variant<NotTriviallyCopyable, int> >::value, "");
-static_assert(!std::__libcpp_is_trivially_relocatable<std::variant<int, NotTriviallyCopyable> >::value, "");
-static_assert(!std::__libcpp_is_trivially_relocatable<std::variant<NotTriviallyCopyable, NotTriviallyCopyable> >::value,
- "");
-static_assert(std::__libcpp_is_trivially_relocatable<std::variant<std::unique_ptr<int>, std::unique_ptr<int> > >::value,
- "");
-#endif // TEST_STD_VER >= 17
-
// vector
static_assert(std::__libcpp_is_trivially_relocatable<std::vector<int> >::value, "");
static_assert(std::__libcpp_is_trivially_relocatable<std::vector<NotTriviallyCopyable> >::value, "");
diff --git a/libcxx/test/libcxx-03/utilities/function.objects/func.require/bullet_1_2_3.pass.cpp b/libcxx/test/libcxx-03/utilities/function.objects/func.require/bullet_1_2_3.pass.cpp
index 48460d1..a883112 100644
--- a/libcxx/test/libcxx-03/utilities/function.objects/func.require/bullet_1_2_3.pass.cpp
+++ b/libcxx/test/libcxx-03/utilities/function.objects/func.require/bullet_1_2_3.pass.cpp
@@ -90,43 +90,6 @@ private:
};
-#if TEST_STD_VER >= 11
-
-//==============================================================================
-// MemFun11 - C++11 reference qualified test member functions.
-struct MemFun11 {
- typedef void*& R;
- typedef MemFun11 C;
-#define F(...) \
- R f(__VA_ARGS__) & { return MethodID<R(C::*)(__VA_ARGS__) &>::setUncheckedCall(); } \
- R f(__VA_ARGS__) const & { return MethodID<R(C::*)(__VA_ARGS__) const &>::setUncheckedCall(); } \
- R f(__VA_ARGS__) volatile & { return MethodID<R(C::*)(__VA_ARGS__) volatile &>::setUncheckedCall(); } \
- R f(__VA_ARGS__) const volatile & { return MethodID<R(C::*)(__VA_ARGS__) const volatile &>::setUncheckedCall(); } \
- R f(__VA_ARGS__) && { return MethodID<R(C::*)(__VA_ARGS__) &&>::setUncheckedCall(); } \
- R f(__VA_ARGS__) const && { return MethodID<R(C::*)(__VA_ARGS__) const &&>::setUncheckedCall(); } \
- R f(__VA_ARGS__) volatile && { return MethodID<R(C::*)(__VA_ARGS__) volatile &&>::setUncheckedCall(); } \
- R f(__VA_ARGS__) const volatile && { return MethodID<R(C::*)(__VA_ARGS__) const volatile &&>::setUncheckedCall(); }
-#
- F()
- F(...)
- F(ArgType&&)
- F(ArgType&&, ...)
- F(ArgType&&, ArgType&&)
- F(ArgType&&, ArgType&&, ...)
- F(ArgType&&, ArgType&&, ArgType&&)
- F(ArgType&&, ArgType&&, ArgType&&, ...)
-#undef F
-public:
- MemFun11() {}
-private:
- MemFun11(MemFun11 const&);
- MemFun11& operator=(MemFun11 const&);
-};
-
-#endif // TEST_STD_VER >= 11
-
-
-
//==============================================================================
// TestCase - A test case for a single member function.
// ClassType - The type of the class being tested.
@@ -167,10 +130,6 @@ private:
runTestDispatchIf(NotRValue, tag, dref);
runTestDispatchIf(NotRValue, tag, obj_ptr);
runTestDispatchIf(NotRValue, tag, der_ptr);
-#if TEST_STD_VER >= 11
- runTestDispatchIf(NotRValue, tag, rref);
- runTestDispatchIf(NotRValue, tag, drref);
-#endif
}
template <class QT, class Tp>
@@ -242,61 +201,6 @@ private:
template <class Sig, int Arity, class CV>
struct TestCase : public TestCaseImp<MemFun03, Sig, Arity, CV> {};
-#if TEST_STD_VER >= 11
-template <class Sig, int Arity, class CV, bool RValue = false>
-struct TestCase11 : public TestCaseImp<MemFun11, Sig, Arity, CV, RValue, true> {};
-
-template <class Type>
-struct ReferenceWrapper {
- using type = Type;
- Type* ptr;
-
- static void fun(Type&) noexcept;
- static void fun(Type&&) = delete;
-
- template <class Type2,
- class = typename std::enable_if<!std::__is_same_uncvref<Type2, ReferenceWrapper>::value>::type>
- constexpr ReferenceWrapper(Type2&& t) noexcept : ptr(&t) {}
-
- constexpr Type& get() const noexcept { return *ptr; }
- constexpr operator Type&() const noexcept { return *ptr; }
-
- template <class... _ArgTypes>
- constexpr std::__invoke_result_t<Type&, _ArgTypes...> operator()(_ArgTypes&&... __args) const {
- return std::__invoke(get(), std::forward<_ArgTypes>(__args)...);
- }
-};
-
-template <class Tp>
-struct DerivedFromRefWrap : public ReferenceWrapper<Tp> {
- constexpr DerivedFromRefWrap(Tp& tp) : ReferenceWrapper<Tp>(tp) {}
-};
-
-TEST_CONSTEXPR_CXX14 bool test_derived_from_ref_wrap() {
- int x = 42;
- ReferenceWrapper<int> r(x);
- DerivedFromRefWrap<int> d(x);
- auto get_fn = &ReferenceWrapper<int>::get;
- auto& ret = std::__invoke(get_fn, r);
- assert(&ret == &x);
- auto& ret2 = std::__invoke(get_fn, d);
- assert(&ret2 == &x);
-
- return true;
-}
-
-TEST_CONSTEXPR_CXX20 bool test_reference_wrapper_reference_wrapper() {
- int x = 42;
- auto get_fn = &std::reference_wrapper<int>::get;
- std::reference_wrapper<int> r(x);
- std::reference_wrapper<std::reference_wrapper<int>> r2(r);
- auto& ret3 = std::__invoke(get_fn, r2);
- assert(&ret3 == &x);
-
- return true;
-}
-#endif
-
int main(int, char**) {
typedef void*& R;
typedef ArgType A;
@@ -333,73 +237,5 @@ int main(int, char**) {
TestCase<R(A&, A&, A&, ...) volatile, 3, Q_Volatile>::run();
TestCase<R(A&, A&, A&, ...) const volatile, 3, Q_CV>::run();
-#if TEST_STD_VER >= 11
- TestCase11<R() &, 0, Q_None>::run();
- TestCase11<R() const &, 0, Q_Const>::run();
- TestCase11<R() volatile &, 0, Q_Volatile>::run();
- TestCase11<R() const volatile &, 0, Q_CV>::run();
- TestCase11<R(...) &, 0, Q_None>::run();
- TestCase11<R(...) const &, 0, Q_Const>::run();
- TestCase11<R(...) volatile &, 0, Q_Volatile>::run();
- TestCase11<R(...) const volatile &, 0, Q_CV>::run();
- TestCase11<R(A&&) &, 1, Q_None>::run();
- TestCase11<R(A&&) const &, 1, Q_Const>::run();
- TestCase11<R(A&&) volatile &, 1, Q_Volatile>::run();
- TestCase11<R(A&&) const volatile &, 1, Q_CV>::run();
- TestCase11<R(A&&, ...) &, 1, Q_None>::run();
- TestCase11<R(A&&, ...) const &, 1, Q_Const>::run();
- TestCase11<R(A&&, ...) volatile &, 1, Q_Volatile>::run();
- TestCase11<R(A&&, ...) const volatile &, 1, Q_CV>::run();
- TestCase11<R(A&&, A&&) &, 2, Q_None>::run();
- TestCase11<R(A&&, A&&) const &, 2, Q_Const>::run();
- TestCase11<R(A&&, A&&) volatile &, 2, Q_Volatile>::run();
- TestCase11<R(A&&, A&&) const volatile &, 2, Q_CV>::run();
- TestCase11<R(A&&, A&&, ...) &, 2, Q_None>::run();
- TestCase11<R(A&&, A&&, ...) const &, 2, Q_Const>::run();
- TestCase11<R(A&&, A&&, ...) volatile &, 2, Q_Volatile>::run();
- TestCase11<R(A&&, A&&, ...) const volatile &, 2, Q_CV>::run();
- TestCase11<R() &&, 0, Q_None, /* RValue */ true>::run();
- TestCase11<R() const &&, 0, Q_Const, /* RValue */ true>::run();
- TestCase11<R() volatile &&, 0, Q_Volatile, /* RValue */ true>::run();
- TestCase11<R() const volatile &&, 0, Q_CV, /* RValue */ true>::run();
- TestCase11<R(...) &&, 0, Q_None, /* RValue */ true>::run();
- TestCase11<R(...) const &&, 0, Q_Const, /* RValue */ true>::run();
- TestCase11<R(...) volatile &&, 0, Q_Volatile, /* RValue */ true>::run();
- TestCase11<R(...) const volatile &&, 0, Q_CV, /* RValue */ true>::run();
- TestCase11<R(A&&) &&, 1, Q_None, /* RValue */ true>::run();
- TestCase11<R(A&&) const &&, 1, Q_Const, /* RValue */ true>::run();
- TestCase11<R(A&&) volatile &&, 1, Q_Volatile, /* RValue */ true>::run();
- TestCase11<R(A&&) const volatile &&, 1, Q_CV, /* RValue */ true>::run();
- TestCase11<R(A&&, ...) &&, 1, Q_None, /* RValue */ true>::run();
- TestCase11<R(A&&, ...) const &&, 1, Q_Const, /* RValue */ true>::run();
- TestCase11<R(A&&, ...) volatile &&, 1, Q_Volatile, /* RValue */ true>::run();
- TestCase11<R(A&&, ...) const volatile &&, 1, Q_CV, /* RValue */ true>::run();
- TestCase11<R(A&&, A&&) &&, 2, Q_None, /* RValue */ true>::run();
- TestCase11<R(A&&, A&&) const &&, 2, Q_Const, /* RValue */ true>::run();
- TestCase11<R(A&&, A&&) volatile &&, 2, Q_Volatile, /* RValue */ true>::run();
- TestCase11<R(A&&, A&&) const volatile &&, 2, Q_CV, /* RValue */ true>::run();
- TestCase11<R(A&&, A&&, ...) &&, 2, Q_None, /* RValue */ true>::run();
- TestCase11<R(A&&, A&&, ...) const &&, 2, Q_Const, /* RValue */ true>::run();
- TestCase11<R(A&&, A&&, ...) volatile &&, 2, Q_Volatile, /* RValue */ true>::run();
- TestCase11<R(A&&, A&&, ...) const volatile &&, 2, Q_CV, /* RValue */ true>::run();
- TestCase11<R(A&&, A&&, A&&) &&, 3, Q_None, /* RValue */ true>::run();
- TestCase11<R(A&&, A&&, A&&) const &&, 3, Q_Const, /* RValue */ true>::run();
- TestCase11<R(A&&, A&&, A&&) volatile &&, 3, Q_Volatile, /* RValue */ true>::run();
- TestCase11<R(A&&, A&&, A&&) const volatile &&, 3, Q_CV, /* RValue */ true>::run();
- TestCase11<R(A&&, A&&, A&&, ...) &&, 3, Q_None, /* RValue */ true>::run();
- TestCase11<R(A&&, A&&, A&&, ...) const &&, 3, Q_Const, /* RValue */ true>::run();
- TestCase11<R(A&&, A&&, A&&, ...) volatile &&, 3, Q_Volatile, /* RValue */ true>::run();
- TestCase11<R(A&&, A&&, A&&, ...) const volatile &&, 3, Q_CV, /* RValue */ true>::run();
-
- test_derived_from_ref_wrap();
- test_reference_wrapper_reference_wrapper();
-#if TEST_STD_VER > 11
- static_assert(test_derived_from_ref_wrap(), "");
-#endif
-#if TEST_STD_VER > 17
- static_assert(test_reference_wrapper_reference_wrapper(), "");
-#endif
-#endif // TEST_STD_VER >= 11
-
return 0;
}
diff --git a/libcxx/test/libcxx-03/utilities/function.objects/func.require/bullet_4_5_6.pass.cpp b/libcxx/test/libcxx-03/utilities/function.objects/func.require/bullet_4_5_6.pass.cpp
index 0df5929..3a8d141 100644
--- a/libcxx/test/libcxx-03/utilities/function.objects/func.require/bullet_4_5_6.pass.cpp
+++ b/libcxx/test/libcxx-03/utilities/function.objects/func.require/bullet_4_5_6.pass.cpp
@@ -85,10 +85,6 @@ private:
runTestDispatch<E>(M, dref2, &dref2.object.object);
runTestPropCVDispatch<E>(M, obj_ptr, &obj_ptr->object);
runTestPropCVDispatch<E>(M, der_ptr, &der_ptr->object);
-#if TEST_STD_VER >= 11
- runTestPropCVDispatch<E>(M, rref, &(rref.get().object));
- runTestPropCVDispatch<E>(M, drref, &(drref.get().object));
-#endif
runTestNoPropDispatch<E>(M, dref, &dref.object.object);
}
{
@@ -100,10 +96,6 @@ private:
runTestDispatch<E>(M, dref2, &dref2.object.object);
runTestPropCVDispatch<E>(M, obj_ptr, &obj_ptr->object);
runTestPropCVDispatch<E>(M, der_ptr, &der_ptr->object);
-#if TEST_STD_VER >= 11
- runTestPropCVDispatch<E>(M, rref, &(rref.get().object));
- runTestPropCVDispatch<E>(M, drref, &(drref.get().object));
-#endif
runTestNoPropDispatch<E>(M, dref, &dref.object.object);
}
{
@@ -115,10 +107,6 @@ private:
runTestDispatch<E>(M, dref2, &dref2.object.object);
runTestPropCVDispatch<E>(M, obj_ptr, &obj_ptr->object);
runTestPropCVDispatch<E>(M, der_ptr, &der_ptr->object);
-#if TEST_STD_VER >= 11
- runTestPropCVDispatch<E>(M, rref, &(rref.get().object));
- runTestPropCVDispatch<E>(M, drref, &(drref.get().object));
-#endif
runTestNoPropDispatch<E>(M, dref, &dref.object.object);
}
{
@@ -130,10 +118,6 @@ private:
runTestDispatch<E>(M, dref2, &dref2.object.object);
runTestPropCVDispatch<E>(M, obj_ptr, &obj_ptr->object);
runTestPropCVDispatch<E>(M, der_ptr, &der_ptr->object);
-#if TEST_STD_VER >= 11
- runTestPropCVDispatch<E>(M, rref, &(rref.get().object));
- runTestPropCVDispatch<E>(M, drref, &(drref.get().object));
-#endif
runTestNoPropDispatch<E>(M, dref, &dref.object.object);
}
}
@@ -144,12 +128,6 @@ private:
runTest<Expect const&> (M, C_<T const&>(obj), expect);
runTest<Expect volatile&> (M, C_<T volatile&>(obj), expect);
runTest<Expect const volatile&>(M, C_<T const volatile&>(obj), expect);
-#if TEST_STD_VER >= 11
- runTest<Expect&&> (M, C_<T&&>(obj), expect);
- runTest<Expect const&&> (M, C_<T const&&>(obj), expect);
- runTest<Expect volatile&&> (M, C_<T volatile&&>(obj), expect);
- runTest<Expect const volatile&&>(M, C_<T const volatile&&>(obj), expect);
-#endif
}
template <class Expect, class Fn, class T>
@@ -166,12 +144,6 @@ private:
runTest<Expect&>(M, C_<T const&>(obj), expect);
runTest<Expect&>(M, C_<T volatile&>(obj), expect);
runTest<Expect&>(M, C_<T const volatile&>(obj), expect);
-#if TEST_STD_VER >= 11
- runTest<Expect&>(M, C_<T&&>(obj), expect);
- runTest<Expect&>(M, C_<T const&&>(obj), expect);
- runTest<Expect&>(M, C_<T volatile&&>(obj), expect);
- runTest<Expect&>(M, C_<T const volatile&&>(obj), expect);
-#endif
}
template <class Expect, class Fn, class T>
@@ -184,11 +156,7 @@ private:
}
template <class Expect, class Fn, class T>
-#if TEST_STD_VER >= 11
- void runTest(Fn M, T&& obj, ObjectType* expect) {
-#else
void runTest(Fn M, T& obj, ObjectType* expect ) {
-#endif
{
static_assert((std::is_same<
decltype(std::__invoke(M, std::forward<T>(obj))), Expect
diff --git a/libcxx/test/libcxx-03/utilities/function.objects/func.require/bullet_7.pass.cpp b/libcxx/test/libcxx-03/utilities/function.objects/func.require/bullet_7.pass.cpp
index fb789fa..ba1c655 100644
--- a/libcxx/test/libcxx-03/utilities/function.objects/func.require/bullet_7.pass.cpp
+++ b/libcxx/test/libcxx-03/utilities/function.objects/func.require/bullet_7.pass.cpp
@@ -115,49 +115,6 @@ private:
};
-#if TEST_STD_VER >= 11
-
-//==============================================================================
-// freeFunction11 - A C++11 free function.
-template <class ...Args>
-void*& freeFunction11(Args&&...) {
- return FunctionPtrID<void*&(Args&&...), freeFunction11>::setUncheckedCall();
-}
-
-template <class ...Args>
-void*& freeFunction11(Args&&...,...) {
- return FunctionPtrID<void*&(Args&&...,...), freeFunction11>::setUncheckedCall();
-}
-
-//==============================================================================
-// Functor11 - C++11 reference qualified test member functions.
-struct Functor11 {
- typedef void*& R;
- typedef Functor11 C;
-
-#define F(CV) \
- template <class ...Args> \
- R operator()(Args&&...) CV { return MethodID<R(C::*)(Args&&...) CV>::setUncheckedCall(); }
-#
- F(&)
- F(const &)
- F(volatile &)
- F(const volatile &)
- F(&&)
- F(const &&)
- F(volatile &&)
- F(const volatile &&)
-#undef F
-public:
- Functor11() {}
-private:
- Functor11(Functor11 const&);
- Functor11& operator=(Functor11 const&);
-};
-
-#endif // TEST_STD_VER >= 11
-
-
//==============================================================================
// TestCaseFunctorImp - A test case for an operator() class method.
// ClassType - The type of the call object.
@@ -207,19 +164,9 @@ public:
//==============================================================================
// runTest Helpers
//==============================================================================
-#if TEST_STD_VER >= 11
-template <class Sig, int Arity, class ArgCaster>
-void runFunctionTestCase11() {
- TestCaseFreeFunction<Sig, freeFunction11, Arity, ArgCaster>();
-}
-#endif
-
template <class Sig, int Arity, class ArgCaster>
void runFunctionTestCase() {
TestCaseFreeFunction<Sig, freeFunction03, Arity, ArgCaster>();
-#if TEST_STD_VER >= 11
- runFunctionTestCase11<Sig, Arity, ArgCaster>();
-#endif
}
template <class Sig, int Arity, class ObjCaster, class ArgCaster>
@@ -232,14 +179,6 @@ void runFunctorTestCase() {
TestCaseFunctorImp<Functor03, Sig, Arity, ObjCaster>::run();
}
-#if TEST_STD_VER >= 11
-// runTestCase - Run a test case for C++11 class functor types
-template <class Sig, int Arity, class ObjCaster, class ArgCaster = LValueCaster>
-void runFunctorTestCase11() {
- TestCaseFunctorImp<Functor11, Sig, Arity, ObjCaster, ArgCaster>::run();
-}
-#endif
-
// runTestCase - Run a test case for both function and functor types.
template <class Sig, int Arity, class ArgCaster>
void runTestCase() {
@@ -265,11 +204,6 @@ int main(int, char**) {
runFunctionTestCase<R(A&, A&, ...), 2, LValueCaster >();
runFunctionTestCase<R(A&, A&, A&, ...), 3, LValueCaster >();
-#if TEST_STD_VER >= 11
- runFunctionTestCase11<R(A&&), 1, MoveCaster >();
- runFunctionTestCase11<R(A&&, ...), 1, MoveCaster >();
-#endif
-
runFunctorTestCase<R(), 0, LValueCaster >();
runFunctorTestCase<R() const, 0, ConstCaster >();
runFunctorTestCase<R() volatile, 0, VolatileCaster >();
@@ -302,27 +236,5 @@ int main(int, char**) {
runFunctorTestCase<R(CA&, CA&, CA&) const volatile, 3, CVCaster, CC>();
}
-#if TEST_STD_VER >= 11
- runFunctorTestCase11<R() &, 0, LValueCaster >();
- runFunctorTestCase11<R() const &, 0, ConstCaster >();
- runFunctorTestCase11<R() volatile &, 0, VolatileCaster >();
- runFunctorTestCase11<R() const volatile &, 0, CVCaster >();
- runFunctorTestCase11<R() &&, 0, MoveCaster >();
- runFunctorTestCase11<R() const &&, 0, MoveConstCaster >();
- runFunctorTestCase11<R() volatile &&, 0, MoveVolatileCaster >();
- runFunctorTestCase11<R() const volatile &&, 0, MoveCVCaster >();
- {
- typedef MoveCaster MC;
- runFunctorTestCase11<R(A&&) &, 1, LValueCaster, MC>();
- runFunctorTestCase11<R(A&&) const &, 1, ConstCaster, MC>();
- runFunctorTestCase11<R(A&&) volatile &, 1, VolatileCaster, MC>();
- runFunctorTestCase11<R(A&&) const volatile &, 1, CVCaster, MC>();
- runFunctorTestCase11<R(A&&) &&, 1, MoveCaster, MC>();
- runFunctorTestCase11<R(A&&) const &&, 1, MoveConstCaster, MC>();
- runFunctorTestCase11<R(A&&) volatile &&, 1, MoveVolatileCaster, MC>();
- runFunctorTestCase11<R(A&&) const volatile &&, 1, MoveCVCaster, MC>();
- }
-#endif
-
return 0;
}
diff --git a/libcxx/test/libcxx-03/utilities/function.objects/func.require/invoke.pass.cpp b/libcxx/test/libcxx-03/utilities/function.objects/func.require/invoke.pass.cpp
index e534553..bfcea06 100644
--- a/libcxx/test/libcxx-03/utilities/function.objects/func.require/invoke.pass.cpp
+++ b/libcxx/test/libcxx-03/utilities/function.objects/func.require/invoke.pass.cpp
@@ -23,24 +23,12 @@ struct Type
{
Array<char, 1>::type& f1();
Array<char, 2>::type& f2() const;
-#if TEST_STD_VER >= 11
- Array<char, 1>::type& g1() &;
- Array<char, 2>::type& g2() const &;
- Array<char, 3>::type& g3() &&;
- Array<char, 4>::type& g4() const &&;
-#endif
};
int main(int, char**)
{
static_assert(sizeof(std::__invoke(&Type::f1, std::declval<Type >())) == 1, "");
static_assert(sizeof(std::__invoke(&Type::f2, std::declval<Type const >())) == 2, "");
-#if TEST_STD_VER >= 11
- static_assert(sizeof(std::__invoke(&Type::g1, std::declval<Type &>())) == 1, "");
- static_assert(sizeof(std::__invoke(&Type::g2, std::declval<Type const &>())) == 2, "");
- static_assert(sizeof(std::__invoke(&Type::g3, std::declval<Type &&>())) == 3, "");
- static_assert(sizeof(std::__invoke(&Type::g4, std::declval<Type const&&>())) == 4, "");
-#endif
return 0;
}
diff --git a/libcxx/test/libcxx-03/utilities/function.objects/func.require/invoke_helpers.h b/libcxx/test/libcxx-03/utilities/function.objects/func.require/invoke_helpers.h
index f6f418b..bebb9f4 100644
--- a/libcxx/test/libcxx-03/utilities/function.objects/func.require/invoke_helpers.h
+++ b/libcxx/test/libcxx-03/utilities/function.objects/func.require/invoke_helpers.h
@@ -52,13 +52,7 @@ struct Caster {
struct apply {
typedef typename std::remove_reference<T>::type RawType;
typedef typename QualTag::template apply<RawType>::type CVType;
-#if TEST_STD_VER >= 11
- typedef typename std::conditional<RValue,
- CVType&&, CVType&
- >::type type;
-#else
typedef CVType& type;
-#endif
};
template <class T>
@@ -165,21 +159,10 @@ struct DerefPropType {
template <class Up>
explicit DerefPropType(Up const& val) : object(val) {}
-#if TEST_STD_VER < 11
To& operator*() { return object; }
To const& operator*() const { return object; }
To volatile& operator*() volatile { return object; }
To const volatile& operator*() const volatile { return object; }
-#else
- To& operator*() & { return object; }
- To const& operator*() const & { return object; }
- To volatile& operator*() volatile & { return object; }
- To const volatile& operator*() const volatile & { return object; }
- To&& operator*() && { return static_cast<To &&>(object); }
- To const&& operator*() const && { return static_cast<To const&&>(object); }
- To volatile&& operator*() volatile && { return static_cast<To volatile&&>(object); }
- To const volatile&& operator*() const volatile && { return static_cast<To const volatile&&>(object); }
-#endif
};
//==============================================================================
diff --git a/libcxx/test/libcxx-03/utilities/is_pointer_in_range.pass.cpp b/libcxx/test/libcxx-03/utilities/is_pointer_in_range.pass.cpp
index 6c60147..bb33ee4 100644
--- a/libcxx/test/libcxx-03/utilities/is_pointer_in_range.pass.cpp
+++ b/libcxx/test/libcxx-03/utilities/is_pointer_in_range.pass.cpp
@@ -18,20 +18,6 @@ TEST_CONSTEXPR_CXX14 void test_cv_quals() {
assert(!std::__is_pointer_in_range(&i, &i, &i));
assert(std::__is_pointer_in_range(&i, &i + 1, &i));
assert(!std::__is_pointer_in_range(&i, &i + 1, &j));
-
-#if TEST_STD_VER >= 20
- {
- T* arr1 = new int[4]{1, 2, 3, 4};
- U* arr2 = new int[4]{5, 6, 7, 8};
-
- assert(!std::__is_pointer_in_range(arr1, arr1 + 4, arr2));
- assert(std::__is_pointer_in_range(arr1, arr1 + 4, arr1 + 3));
- assert(!std::__is_pointer_in_range(arr1, arr1, arr1 + 3));
-
- delete[] arr1;
- delete[] arr2;
- }
-#endif
}
TEST_CONSTEXPR_CXX14 bool test() {
@@ -48,9 +34,6 @@ TEST_CONSTEXPR_CXX14 bool test() {
int main(int, char**) {
test();
-#if TEST_STD_VER >= 14
- static_assert(test(), "");
-#endif
return 0;
}
diff --git a/libcxx/test/libcxx-03/utilities/is_valid_range.pass.cpp b/libcxx/test/libcxx-03/utilities/is_valid_range.pass.cpp
index 9ad1e89..ef645d4 100644
--- a/libcxx/test/libcxx-03/utilities/is_valid_range.pass.cpp
+++ b/libcxx/test/libcxx-03/utilities/is_valid_range.pass.cpp
@@ -39,14 +39,6 @@ TEST_CONSTEXPR_CXX14 void check_type() {
assert(!std::__is_valid_range(static_cast<TQualified*>(&arr[1]), static_cast<TQualified*>(&arr[0])));
assert(!std::__is_valid_range(static_cast<TQualified*>(&arr[2]), static_cast<TQualified*>(&arr[0])));
}
-
-#if TEST_STD_VER >= 20
- {
- T* arr = new int[4]{1, 2, 3, 4};
- assert(std::__is_valid_range(static_cast<TQualified*>(arr), static_cast<TQualified*>(arr + 4)));
- delete[] arr;
- }
-#endif
}
TEST_CONSTEXPR_CXX14 bool test() {
@@ -60,9 +52,6 @@ TEST_CONSTEXPR_CXX14 bool test() {
int main(int, char**) {
test();
-#if TEST_STD_VER >= 14
- static_assert(test(), "");
-#endif
return 0;
}
diff --git a/libcxx/test/libcxx-03/utilities/memory/pointer.conversion/to_address.pass.cpp b/libcxx/test/libcxx-03/utilities/memory/pointer.conversion/to_address.pass.cpp
index 60ef98a..f6df5db 100644
--- a/libcxx/test/libcxx-03/utilities/memory/pointer.conversion/to_address.pass.cpp
+++ b/libcxx/test/libcxx-03/utilities/memory/pointer.conversion/to_address.pass.cpp
@@ -152,8 +152,6 @@ TEST_CONSTEXPR_CXX14 bool test() {
int main(int, char**) {
test();
-#if TEST_STD_VER >= 14
- static_assert(test(), "");
-#endif
+
return 0;
}
diff --git a/libcxx/test/libcxx-03/utilities/memory/pointer.conversion/to_address_std_iterators.pass.cpp b/libcxx/test/libcxx-03/utilities/memory/pointer.conversion/to_address_std_iterators.pass.cpp
index 5eed12d..3b7527d 100644
--- a/libcxx/test/libcxx-03/utilities/memory/pointer.conversion/to_address_std_iterators.pass.cpp
+++ b/libcxx/test/libcxx-03/utilities/memory/pointer.conversion/to_address_std_iterators.pass.cpp
@@ -44,12 +44,6 @@ int main(int, char**) {
test_container_iterators(std::array<int, 3>());
test_container_iterators(std::vector<int>(3));
test_container_iterators(std::string("abc"));
-#if TEST_STD_VER >= 17
- test_container_iterators(std::string_view("abc"));
-#endif
-#if TEST_STD_VER >= 20
- test_container_iterators(std::span<const char>("abc"));
-#endif
test_valarray_iterators();
return 0;
diff --git a/libcxx/test/libcxx-03/utilities/meta/is_referenceable.compile.pass.cpp b/libcxx/test/libcxx-03/utilities/meta/is_referenceable.compile.pass.cpp
index f39d1a5..a079bbe 100644
--- a/libcxx/test/libcxx-03/utilities/meta/is_referenceable.compile.pass.cpp
+++ b/libcxx/test/libcxx-03/utilities/meta/is_referenceable.compile.pass.cpp
@@ -33,10 +33,6 @@ static_assert((std::__libcpp_is_referenceable<Foo>::value), "");
static_assert((std::__libcpp_is_referenceable<const Foo>::value), "");
static_assert((std::__libcpp_is_referenceable<Foo&>::value), "");
static_assert((std::__libcpp_is_referenceable<const Foo&>::value), "");
-#if TEST_STD_VER >= 11
-static_assert((std::__libcpp_is_referenceable<Foo&&>::value), "");
-static_assert((std::__libcpp_is_referenceable<const Foo&&>::value), "");
-#endif
static_assert((std::__libcpp_is_referenceable<int __attribute__((__vector_size__(8)))>::value), "");
static_assert((std::__libcpp_is_referenceable<const int __attribute__((__vector_size__(8)))>::value), "");
@@ -45,146 +41,42 @@ static_assert((std::__libcpp_is_referenceable<const float __attribute__((__vecto
// Functions without cv-qualifiers are referenceable
static_assert((std::__libcpp_is_referenceable<void()>::value), "");
-#if TEST_STD_VER >= 11
-static_assert((!std::__libcpp_is_referenceable<void() const>::value), "");
-static_assert((!std::__libcpp_is_referenceable<void() &>::value), "");
-static_assert((!std::__libcpp_is_referenceable<void() const&>::value), "");
-static_assert((!std::__libcpp_is_referenceable<void() &&>::value), "");
-static_assert((!std::__libcpp_is_referenceable<void() const&&>::value), "");
-#endif
static_assert((std::__libcpp_is_referenceable<void(int)>::value), "");
-#if TEST_STD_VER >= 11
-static_assert((!std::__libcpp_is_referenceable<void(int) const>::value), "");
-static_assert((!std::__libcpp_is_referenceable<void(int) &>::value), "");
-static_assert((!std::__libcpp_is_referenceable<void(int) const&>::value), "");
-static_assert((!std::__libcpp_is_referenceable<void(int) &&>::value), "");
-static_assert((!std::__libcpp_is_referenceable<void(int) const&&>::value), "");
-#endif
static_assert((std::__libcpp_is_referenceable<void(int, float)>::value), "");
-#if TEST_STD_VER >= 11
-static_assert((!std::__libcpp_is_referenceable<void(int, float) const>::value), "");
-static_assert((!std::__libcpp_is_referenceable<void(int, float) &>::value), "");
-static_assert((!std::__libcpp_is_referenceable<void(int, float) const&>::value), "");
-static_assert((!std::__libcpp_is_referenceable<void(int, float) &&>::value), "");
-static_assert((!std::__libcpp_is_referenceable<void(int, float) const&&>::value), "");
-#endif
static_assert((std::__libcpp_is_referenceable<void(int, float, Foo&)>::value), "");
-#if TEST_STD_VER >= 11
-static_assert((!std::__libcpp_is_referenceable<void(int, float, Foo&) const>::value), "");
-static_assert((!std::__libcpp_is_referenceable<void(int, float, Foo&) &>::value), "");
-static_assert((!std::__libcpp_is_referenceable<void(int, float, Foo&) const&>::value), "");
-static_assert((!std::__libcpp_is_referenceable<void(int, float, Foo&) &&>::value), "");
-static_assert((!std::__libcpp_is_referenceable<void(int, float, Foo&) const&&>::value), "");
-#endif
static_assert((std::__libcpp_is_referenceable<void(...)>::value), "");
-#if TEST_STD_VER >= 11
-static_assert((!std::__libcpp_is_referenceable<void(...) const>::value), "");
-static_assert((!std::__libcpp_is_referenceable<void(...) &>::value), "");
-static_assert((!std::__libcpp_is_referenceable<void(...) const&>::value), "");
-static_assert((!std::__libcpp_is_referenceable<void(...) &&>::value), "");
-static_assert((!std::__libcpp_is_referenceable<void(...) const&&>::value), "");
-#endif
static_assert((std::__libcpp_is_referenceable<void(int, ...)>::value), "");
-#if TEST_STD_VER >= 11
-static_assert((!std::__libcpp_is_referenceable<void(int, ...) const>::value), "");
-static_assert((!std::__libcpp_is_referenceable<void(int, ...) &>::value), "");
-static_assert((!std::__libcpp_is_referenceable<void(int, ...) const&>::value), "");
-static_assert((!std::__libcpp_is_referenceable<void(int, ...) &&>::value), "");
-static_assert((!std::__libcpp_is_referenceable<void(int, ...) const&&>::value), "");
-#endif
static_assert((std::__libcpp_is_referenceable<void(int, float, ...)>::value), "");
-#if TEST_STD_VER >= 11
-static_assert((!std::__libcpp_is_referenceable<void(int, float, ...) const>::value), "");
-static_assert((!std::__libcpp_is_referenceable<void(int, float, ...) &>::value), "");
-static_assert((!std::__libcpp_is_referenceable<void(int, float, ...) const&>::value), "");
-static_assert((!std::__libcpp_is_referenceable<void(int, float, ...) &&>::value), "");
-static_assert((!std::__libcpp_is_referenceable<void(int, float, ...) const&&>::value), "");
-#endif
static_assert((std::__libcpp_is_referenceable<void(int, float, Foo&, ...)>::value), "");
-#if TEST_STD_VER >= 11
-static_assert((!std::__libcpp_is_referenceable<void(int, float, Foo&, ...) const>::value), "");
-static_assert((!std::__libcpp_is_referenceable<void(int, float, Foo&, ...) &>::value), "");
-static_assert((!std::__libcpp_is_referenceable<void(int, float, Foo&, ...) const&>::value), "");
-static_assert((!std::__libcpp_is_referenceable<void(int, float, Foo&, ...) &&>::value), "");
-static_assert((!std::__libcpp_is_referenceable<void(int, float, Foo&, ...) const&&>::value), "");
-#endif
// member functions with or without cv-qualifiers are referenceable
static_assert((std::__libcpp_is_referenceable<void (Foo::*)()>::value), "");
static_assert((std::__libcpp_is_referenceable<void (Foo::*)() const>::value), "");
-#if TEST_STD_VER >= 11
-static_assert((std::__libcpp_is_referenceable<void (Foo::*)() &>::value), "");
-static_assert((std::__libcpp_is_referenceable<void (Foo::*)() const&>::value), "");
-static_assert((std::__libcpp_is_referenceable<void (Foo::*)() &&>::value), "");
-static_assert((std::__libcpp_is_referenceable<void (Foo::*)() const&&>::value), "");
-#endif
static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int)>::value), "");
static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int) const>::value), "");
-#if TEST_STD_VER >= 11
-static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int) &>::value), "");
-static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int) const&>::value), "");
-static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int) &&>::value), "");
-static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int) const&&>::value), "");
-#endif
static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float)>::value), "");
static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float) const>::value), "");
-#if TEST_STD_VER >= 11
-static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float) &>::value), "");
-static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float) const&>::value), "");
-static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float) &&>::value), "");
-static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float) const&&>::value), "");
-#endif
static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float, Foo&)>::value), "");
static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float, Foo&) const>::value), "");
-#if TEST_STD_VER >= 11
-static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float, Foo&) &>::value), "");
-static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float, Foo&) const&>::value), "");
-static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float, Foo&) &&>::value), "");
-static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float, Foo&) const&&>::value), "");
-#endif
static_assert((std::__libcpp_is_referenceable<void (Foo::*)(...)>::value), "");
static_assert((std::__libcpp_is_referenceable<void (Foo::*)(...) const>::value), "");
-#if TEST_STD_VER >= 11
-static_assert((std::__libcpp_is_referenceable<void (Foo::*)(...) &>::value), "");
-static_assert((std::__libcpp_is_referenceable<void (Foo::*)(...) const&>::value), "");
-static_assert((std::__libcpp_is_referenceable<void (Foo::*)(...) &&>::value), "");
-static_assert((std::__libcpp_is_referenceable<void (Foo::*)(...) const&&>::value), "");
-#endif
static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, ...)>::value), "");
static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, ...) const>::value), "");
-#if TEST_STD_VER >= 11
-static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, ...) &>::value), "");
-static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, ...) const&>::value), "");
-static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, ...) &&>::value), "");
-static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, ...) const&&>::value), "");
-#endif
static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float, ...)>::value), "");
static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float, ...) const>::value), "");
-#if TEST_STD_VER >= 11
-static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float, ...) &>::value), "");
-static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float, ...) const&>::value), "");
-static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float, ...) &&>::value), "");
-static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float, ...) const&&>::value), "");
-#endif
static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float, Foo&, ...)>::value), "");
static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float, Foo&, ...) const>::value), "");
-#if TEST_STD_VER >= 11
-static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float, Foo&, ...) &>::value), "");
-static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float, Foo&, ...) const&>::value), "");
-static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float, Foo&, ...) &&>::value), "");
-static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float, Foo&, ...) const&&>::value), "");
-#endif
diff --git a/libcxx/test/libcxx-03/utilities/no_destroy.pass.cpp b/libcxx/test/libcxx-03/utilities/no_destroy.pass.cpp
index 561654d..c79d208 100644
--- a/libcxx/test/libcxx-03/utilities/no_destroy.pass.cpp
+++ b/libcxx/test/libcxx-03/utilities/no_destroy.pass.cpp
@@ -11,11 +11,6 @@
#include "test_macros.h"
-#if TEST_STD_VER > 17
-// Test constexpr-constructibility.
-constinit std::__no_destroy<int> nd_int_const(std::__uninitialized_tag{});
-#endif
-
struct DestroyLast {
~DestroyLast() { assert(*ptr == 5); }
diff --git a/libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/abi.non_trivial_copy_move.pass.cpp b/libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/abi.non_trivial_copy_move.pass.cpp
index 1f5dae1..d961884 100644
--- a/libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/abi.non_trivial_copy_move.pass.cpp
+++ b/libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/abi.non_trivial_copy_move.pass.cpp
@@ -31,49 +31,8 @@ template <class T>
struct HasNonTrivialABI : std::integral_constant<bool,
!std::is_trivially_destructible<T>::value
|| (std::is_copy_constructible<T>::value && !std::is_trivially_copy_constructible<T>::value)
-#if TEST_STD_VER >= 11
- || (std::is_move_constructible<T>::value && !std::is_trivially_move_constructible<T>::value)
-#endif
> {};
-#if TEST_STD_VER >= 11
-struct NonTrivialDtor {
- NonTrivialDtor(NonTrivialDtor const&) = default;
- ~NonTrivialDtor();
-};
-NonTrivialDtor::~NonTrivialDtor() {}
-static_assert(HasNonTrivialABI<NonTrivialDtor>::value, "");
-
-struct NonTrivialCopy {
- NonTrivialCopy(NonTrivialCopy const&);
-};
-NonTrivialCopy::NonTrivialCopy(NonTrivialCopy const&) {}
-static_assert(HasNonTrivialABI<NonTrivialCopy>::value, "");
-
-struct NonTrivialMove {
- NonTrivialMove(NonTrivialMove const&) = default;
- NonTrivialMove(NonTrivialMove&&);
-};
-NonTrivialMove::NonTrivialMove(NonTrivialMove&&) {}
-static_assert(HasNonTrivialABI<NonTrivialMove>::value, "");
-
-struct DeletedCopy {
- DeletedCopy(DeletedCopy const&) = delete;
- DeletedCopy(DeletedCopy&&) = default;
-};
-static_assert(!HasNonTrivialABI<DeletedCopy>::value, "");
-
-struct TrivialMove {
- TrivialMove(TrivialMove &&) = default;
-};
-static_assert(!HasNonTrivialABI<TrivialMove>::value, "");
-
-struct Trivial {
- Trivial(Trivial const&) = default;
-};
-static_assert(!HasNonTrivialABI<Trivial>::value, "");
-#endif
-
void test_trivial()
{
@@ -82,62 +41,6 @@ void test_trivial()
static_assert(std::is_copy_constructible<P>::value, "");
static_assert(HasNonTrivialABI<P>::value, "");
}
-#if TEST_STD_VER >= 11
- {
- typedef std::pair<int, short> P;
- static_assert(std::is_move_constructible<P>::value, "");
- static_assert(HasNonTrivialABI<P>::value, "");
- }
- {
- using P = std::pair<NonTrivialDtor, int>;
- static_assert(!std::is_trivially_destructible<P>::value, "");
- static_assert(std::is_copy_constructible<P>::value, "");
- static_assert(!std::is_trivially_copy_constructible<P>::value, "");
- static_assert(std::is_move_constructible<P>::value, "");
- static_assert(!std::is_trivially_move_constructible<P>::value, "");
- static_assert(HasNonTrivialABI<P>::value, "");
- }
- {
- using P = std::pair<NonTrivialCopy, int>;
- static_assert(std::is_copy_constructible<P>::value, "");
- static_assert(!std::is_trivially_copy_constructible<P>::value, "");
- static_assert(std::is_move_constructible<P>::value, "");
- static_assert(!std::is_trivially_move_constructible<P>::value, "");
- static_assert(HasNonTrivialABI<P>::value, "");
- }
- {
- using P = std::pair<NonTrivialMove, int>;
- static_assert(std::is_copy_constructible<P>::value, "");
- static_assert(!std::is_trivially_copy_constructible<P>::value, "");
- static_assert(std::is_move_constructible<P>::value, "");
- static_assert(!std::is_trivially_move_constructible<P>::value, "");
- static_assert(HasNonTrivialABI<P>::value, "");
- }
- {
- using P = std::pair<DeletedCopy, int>;
- static_assert(!std::is_copy_constructible<P>::value, "");
- static_assert(!std::is_trivially_copy_constructible<P>::value, "");
- static_assert(std::is_move_constructible<P>::value, "");
- static_assert(!std::is_trivially_move_constructible<P>::value, "");
- static_assert(HasNonTrivialABI<P>::value, "");
- }
- {
- using P = std::pair<Trivial, int>;
- static_assert(std::is_copy_constructible<P>::value, "");
- static_assert(!std::is_trivially_copy_constructible<P>::value, "");
- static_assert(std::is_move_constructible<P>::value, "");
- static_assert(!std::is_trivially_move_constructible<P>::value, "");
- static_assert(HasNonTrivialABI<P>::value, "");
- }
- {
- using P = std::pair<TrivialMove, int>;
- static_assert(!std::is_copy_constructible<P>::value, "");
- static_assert(!std::is_trivially_copy_constructible<P>::value, "");
- static_assert(std::is_move_constructible<P>::value, "");
- static_assert(!std::is_trivially_move_constructible<P>::value, "");
- static_assert(HasNonTrivialABI<P>::value, "");
- }
-#endif
}
void test_layout() {
diff --git a/libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/abi.trivial_copy_move.pass.cpp b/libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/abi.trivial_copy_move.pass.cpp
index 3ec60c0..1dafb10 100644
--- a/libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/abi.trivial_copy_move.pass.cpp
+++ b/libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/abi.trivial_copy_move.pass.cpp
@@ -28,49 +28,8 @@ template <class T>
struct HasTrivialABI : std::integral_constant<bool,
std::is_trivially_destructible<T>::value
&& (!std::is_copy_constructible<T>::value || std::is_trivially_copy_constructible<T>::value)
-#if TEST_STD_VER >= 11
- && (!std::is_move_constructible<T>::value || std::is_trivially_move_constructible<T>::value)
-#endif
> {};
-#if TEST_STD_VER >= 11
-struct NonTrivialDtor {
- NonTrivialDtor(NonTrivialDtor const&) = default;
- ~NonTrivialDtor();
-};
-NonTrivialDtor::~NonTrivialDtor() {}
-static_assert(!HasTrivialABI<NonTrivialDtor>::value, "");
-
-struct NonTrivialCopy {
- NonTrivialCopy(NonTrivialCopy const&);
-};
-NonTrivialCopy::NonTrivialCopy(NonTrivialCopy const&) {}
-static_assert(!HasTrivialABI<NonTrivialCopy>::value, "");
-
-struct NonTrivialMove {
- NonTrivialMove(NonTrivialMove const&) = default;
- NonTrivialMove(NonTrivialMove&&);
-};
-NonTrivialMove::NonTrivialMove(NonTrivialMove&&) {}
-static_assert(!HasTrivialABI<NonTrivialMove>::value, "");
-
-struct DeletedCopy {
- DeletedCopy(DeletedCopy const&) = delete;
- DeletedCopy(DeletedCopy&&) = default;
-};
-static_assert(HasTrivialABI<DeletedCopy>::value, "");
-
-struct TrivialMove {
- TrivialMove(TrivialMove &&) = default;
-};
-static_assert(HasTrivialABI<TrivialMove>::value, "");
-
-struct Trivial {
- Trivial(Trivial const&) = default;
-};
-static_assert(HasTrivialABI<Trivial>::value, "");
-#endif
-
struct TrivialNoAssignment {
int arr[4];
TrivialNoAssignment& operator=(const TrivialNoAssignment&) = delete;
@@ -90,78 +49,14 @@ void test_trivial()
static_assert(std::is_copy_constructible<P>::value, "");
static_assert(HasTrivialABI<P>::value, "");
}
-#if TEST_STD_VER >= 11
- {
- typedef std::pair<int, short> P;
- static_assert(std::is_move_constructible<P>::value, "");
- static_assert(HasTrivialABI<P>::value, "");
- }
- {
- using P = std::pair<NonTrivialDtor, int>;
- static_assert(!std::is_trivially_destructible<P>::value, "");
- static_assert(std::is_copy_constructible<P>::value, "");
- static_assert(!std::is_trivially_copy_constructible<P>::value, "");
- static_assert(std::is_move_constructible<P>::value, "");
- static_assert(!std::is_trivially_move_constructible<P>::value, "");
- static_assert(!HasTrivialABI<P>::value, "");
- }
- {
- using P = std::pair<NonTrivialCopy, int>;
- static_assert(std::is_copy_constructible<P>::value, "");
- static_assert(!std::is_trivially_copy_constructible<P>::value, "");
- static_assert(std::is_move_constructible<P>::value, "");
- static_assert(!std::is_trivially_move_constructible<P>::value, "");
- static_assert(!HasTrivialABI<P>::value, "");
- }
- {
- using P = std::pair<NonTrivialMove, int>;
- static_assert(std::is_copy_constructible<P>::value, "");
- static_assert(std::is_trivially_copy_constructible<P>::value, "");
- static_assert(std::is_move_constructible<P>::value, "");
- static_assert(!std::is_trivially_move_constructible<P>::value, "");
- static_assert(!HasTrivialABI<P>::value, "");
- }
- {
- using P = std::pair<DeletedCopy, int>;
- static_assert(!std::is_copy_constructible<P>::value, "");
- static_assert(!std::is_trivially_copy_constructible<P>::value, "");
- static_assert(std::is_move_constructible<P>::value, "");
- static_assert(std::is_trivially_move_constructible<P>::value, "");
- static_assert(HasTrivialABI<P>::value, "");
- }
- {
- using P = std::pair<Trivial, int>;
- static_assert(std::is_copy_constructible<P>::value, "");
- static_assert(std::is_trivially_copy_constructible<P>::value, "");
- static_assert(std::is_move_constructible<P>::value, "");
- static_assert(std::is_trivially_move_constructible<P>::value, "");
- static_assert(HasTrivialABI<P>::value, "");
- }
- {
- using P = std::pair<TrivialMove, int>;
- static_assert(!std::is_copy_constructible<P>::value, "");
- static_assert(!std::is_trivially_copy_constructible<P>::value, "");
- static_assert(std::is_move_constructible<P>::value, "");
- static_assert(std::is_trivially_move_constructible<P>::value, "");
- static_assert(HasTrivialABI<P>::value, "");
- }
-#endif
{
using P = std::pair<TrivialNoAssignment, int>;
static_assert(std::is_trivially_copy_constructible<P>::value, "");
static_assert(std::is_trivially_move_constructible<P>::value, "");
-#if TEST_STD_VER >= 11 // This is https://llvm.org/PR90605
- static_assert(!std::is_trivially_copy_assignable<P>::value, "");
- static_assert(!std::is_trivially_move_assignable<P>::value, "");
-#endif // TEST_STD_VER >= 11
static_assert(std::is_trivially_destructible<P>::value, "");
}
{
using P = std::pair<TrivialNoConstruction, int>;
-#if TEST_STD_VER >= 11
- static_assert(!std::is_trivially_copy_constructible<P>::value, "");
- static_assert(!std::is_trivially_move_constructible<P>::value, "");
-#endif // TEST_STD_VER >= 11
static_assert(!std::is_trivially_copy_assignable<P>::value, "");
static_assert(!std::is_trivially_move_assignable<P>::value, "");
static_assert(std::is_trivially_destructible<P>::value, "");
diff --git a/libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/abi.trivially_copyable.compile.pass.cpp b/libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/abi.trivially_copyable.compile.pass.cpp
index 1132b3e..7bd1adc 100644
--- a/libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/abi.trivially_copyable.compile.pass.cpp
+++ b/libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/abi.trivially_copyable.compile.pass.cpp
@@ -52,13 +52,8 @@ static_assert(!std::is_trivially_copyable<std::pair<int, char> >::value, "");
static_assert(!std::is_trivially_copyable<std::pair<char, int> >::value, "");
static_assert(!std::is_trivially_copyable<std::pair<std::pair<char, char>, int> >::value, "");
static_assert(!std::is_trivially_copyable<std::pair<trivially_copyable, int> >::value, "");
-#if TEST_STD_VER == 03 // Known ABI difference
static_assert(!std::is_trivially_copyable<std::pair<trivially_copyable_no_copy_assignment, int> >::value, "");
static_assert(!std::is_trivially_copyable<std::pair<trivially_copyable_no_move_assignment, int> >::value, "");
-#else
-static_assert(std::is_trivially_copyable<std::pair<trivially_copyable_no_copy_assignment, int> >::value, "");
-static_assert(std::is_trivially_copyable<std::pair<trivially_copyable_no_move_assignment, int> >::value, "");
-#endif
static_assert(!std::is_trivially_copyable<std::pair<trivially_copyable_no_construction, int> >::value, "");
static_assert(std::is_trivially_copy_constructible<std::pair<int, int> >::value, "");
diff --git a/libcxx/test/libcxx/algorithms/alg.modifying.operations/copy_move_unwrap_reverse.pass.cpp b/libcxx/test/libcxx/algorithms/alg.modifying.operations/copy_move_unwrap_reverse.pass.cpp
index 2a85e7b..2244462 100644
--- a/libcxx/test/libcxx/algorithms/alg.modifying.operations/copy_move_unwrap_reverse.pass.cpp
+++ b/libcxx/test/libcxx/algorithms/alg.modifying.operations/copy_move_unwrap_reverse.pass.cpp
@@ -19,6 +19,7 @@
#include <cstdint>
#include <iterator>
#include <type_traits>
+#include <utility>
#include "test_iterators.h"
diff --git a/libcxx/test/libcxx/assertions/semantics/assertion_semantic_incorrect_value.sh.cpp b/libcxx/test/libcxx/assertions/semantics/assertion_semantic_incorrect_value.sh.cpp
new file mode 100644
index 0000000..d7c1e26
--- /dev/null
+++ b/libcxx/test/libcxx/assertions/semantics/assertion_semantic_incorrect_value.sh.cpp
@@ -0,0 +1,29 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// This test verifies that setting the assertion semantic to a value that's not part of the predefined constants
+// triggers a compile-time error.
+
+// Modules build produces a different error ("Could not build module 'std'").
+// UNSUPPORTED: clang-modules-build
+// UNSUPPORTED: c++03, libcpp-has-no-experimental-hardening-observe-semantic
+// REQUIRES: verify-support
+
+// RUN: %{verify} -U_LIBCPP_ASSERTION_SEMANTIC -D_LIBCPP_ASSERTION_SEMANTIC=42
+// `hardening-dependent` cannot be set as the semantic (it's only an indicator to use hardening-related logic to pick
+// the final semantic).
+// RUN: %{verify} -U_LIBCPP_ASSERTION_SEMANTIC -D_LIBCPP_ASSERTION_SEMANTIC=_LIBCPP_ASSERTION_SEMANTIC_HARDENING_DEPENDENT
+// Make sure that common cases of misuse produce readable errors. We deliberately disallow setting the assertion
+// semantic as if it were a boolean flag.
+// RUN: %{verify} -U_LIBCPP_ASSERTION_SEMANTIC -D_LIBCPP_ASSERTION_SEMANTIC=0
+// RUN: %{verify} -U_LIBCPP_ASSERTION_SEMANTIC -D_LIBCPP_ASSERTION_SEMANTIC=1
+// RUN: %{verify} -U_LIBCPP_ASSERTION_SEMANTIC -D_LIBCPP_ASSERTION_SEMANTIC
+
+#include <cassert>
+
+// expected-error@*:* {{_LIBCPP_ASSERTION_SEMANTIC must be set to one of the following values: _LIBCPP_ASSERTION_SEMANTIC_IGNORE, _LIBCPP_ASSERTION_SEMANTIC_OBSERVE, _LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE, _LIBCPP_ASSERTION_SEMANTIC_ENFORCE}}
diff --git a/libcxx/test/libcxx/assertions/semantics/override_with_enforce_semantic.pass.cpp b/libcxx/test/libcxx/assertions/semantics/override_with_enforce_semantic.pass.cpp
new file mode 100644
index 0000000..056864e
--- /dev/null
+++ b/libcxx/test/libcxx/assertions/semantics/override_with_enforce_semantic.pass.cpp
@@ -0,0 +1,29 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// This test ensures that we can override the assertion semantic used by any checked hardening mode with `enforce` on
+// a per-TU basis (this is valid for the `debug` mode as well, though a no-op).
+
+// `check_assertion.h` is only available starting from C++11 and requires Unix headers and regex support.
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, no-localization
+// UNSUPPORTED: libcpp-hardening-mode=none, libcpp-has-no-experimental-hardening-observe-semantic
+// The ability to set a custom abort message is required to compare the assertion message.
+// XFAIL: availability-verbose_abort-missing
+// ADDITIONAL_COMPILE_FLAGS: -U_LIBCPP_ASSERTION_SEMANTIC -D_LIBCPP_ASSERTION_SEMANTIC=_LIBCPP_ASSERTION_SEMANTIC_ENFORCE
+
+#include <cassert>
+#include "check_assertion.h"
+
+int main(int, char**) {
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(true, "Should not fire");
+ TEST_LIBCPP_ASSERT_FAILURE([] { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "Should fire and log a message"); }(),
+ "Should fire and log a message");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx/assertions/semantics/override_with_ignore_semantic.pass.cpp b/libcxx/test/libcxx/assertions/semantics/override_with_ignore_semantic.pass.cpp
new file mode 100644
index 0000000..b8c9028
--- /dev/null
+++ b/libcxx/test/libcxx/assertions/semantics/override_with_ignore_semantic.pass.cpp
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// This test ensures that we can override the assertion semantic used by any hardening mode with `ignore` on a per-TU
+// basis (this is valid for the `none` mode as well, though a no-op).
+
+// `check_assertion.h` is only available starting from C++11 and requires Unix headers and regex support.
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, no-localization
+// UNSUPPORTED: libcpp-has-no-experimental-hardening-observe-semantic
+// ADDITIONAL_COMPILE_FLAGS: -U_LIBCPP_ASSERTION_SEMANTIC -D_LIBCPP_ASSERTION_SEMANTIC=_LIBCPP_ASSERTION_SEMANTIC_IGNORE
+
+#include <cassert>
+#include "check_assertion.h"
+
+int main(int, char**) {
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(true, "Should not fire");
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "Also should not fire");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx/assertions/semantics/override_with_observe_semantic.pass.cpp b/libcxx/test/libcxx/assertions/semantics/override_with_observe_semantic.pass.cpp
new file mode 100644
index 0000000..a14c44f
--- /dev/null
+++ b/libcxx/test/libcxx/assertions/semantics/override_with_observe_semantic.pass.cpp
@@ -0,0 +1,27 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// This test ensures that we can override the assertion semantic used by any checked hardening mode with `observe` on
+// a per-TU basis.
+
+// `check_assertion.h` is only available starting from C++11 and requires Unix headers and regex support.
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, no-localization
+// UNSUPPORTED: libcpp-hardening-mode=none, libcpp-has-no-experimental-hardening-observe-semantic
+// ADDITIONAL_COMPILE_FLAGS: -U_LIBCPP_ASSERTION_SEMANTIC -D_LIBCPP_ASSERTION_SEMANTIC=_LIBCPP_ASSERTION_SEMANTIC_OBSERVE
+
+#include <cassert>
+#include "check_assertion.h"
+
+int main(int, char**) {
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(true, "Should not fire");
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "Also should not fire");
+ // TODO(hardening): check that a message is logged.
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx/assertions/semantics/override_with_quick_enforce_semantic.pass.cpp b/libcxx/test/libcxx/assertions/semantics/override_with_quick_enforce_semantic.pass.cpp
new file mode 100644
index 0000000..be5038c
--- /dev/null
+++ b/libcxx/test/libcxx/assertions/semantics/override_with_quick_enforce_semantic.pass.cpp
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// This test ensures that we can override the assertion semantic used by any checked hardening mode with `quick-enforce`
+// on a per-TU basis (this is valid for the `fast` and `extensive` modes as well, though a no-op).
+
+// `check_assertion.h` is only available starting from C++11 and requires Unix headers and regex support.
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, no-localization
+// UNSUPPORTED: libcpp-hardening-mode=none, libcpp-has-no-experimental-hardening-observe-semantic
+// ADDITIONAL_COMPILE_FLAGS: -U_LIBCPP_ASSERTION_SEMANTIC -D_LIBCPP_ASSERTION_SEMANTIC=_LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE
+
+#include <cassert>
+#include "check_assertion.h"
+
+int main(int, char**) {
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(true, "Should not fire");
+ TEST_LIBCPP_ASSERT_FAILURE(
+ [] { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "Should fire without logging a message"); }(),
+ "The message should not matter");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx/atomics/atomics.syn/wait.issue_85107.pass.cpp b/libcxx/test/libcxx/atomics/atomics.syn/wait.issue_85107.pass.cpp
index f606e93..ed2a8b0 100644
--- a/libcxx/test/libcxx/atomics/atomics.syn/wait.issue_85107.pass.cpp
+++ b/libcxx/test/libcxx/atomics/atomics.syn/wait.issue_85107.pass.cpp
@@ -41,7 +41,11 @@ int main(int, char**) {
// This would hang forever if the bug is present, but the test will fail in a bounded amount of
// time due to the timeout above.
+#if _LIBCPP_AVAILABILITY_HAS_NEW_SYNC
+ std::__atomic_wait_native<sizeof(std::__cxx_atomic_contention_t)>(&ct, &old_val);
+#else
std::__libcpp_atomic_wait(&ct, old_val);
+#endif
done = true;
timeout_thread.join();
diff --git a/libcxx/test/libcxx/containers/views/mdspan/extents/assert.obs.pass.cpp b/libcxx/test/libcxx/containers/views/mdspan/extents/assert.obs.pass.cpp
index c473879..e32c0a9 100644
--- a/libcxx/test/libcxx/containers/views/mdspan/extents/assert.obs.pass.cpp
+++ b/libcxx/test/libcxx/containers/views/mdspan/extents/assert.obs.pass.cpp
@@ -35,28 +35,28 @@ int main(int, char**) {
// mismatch of static extent
{
std::extents<int> e;
- TEST_LIBCPP_ASSERT_FAILURE(([=] { e.extent(0); }()), "extents access: index must be less than rank");
- TEST_LIBCPP_ASSERT_FAILURE(([=] { e.static_extent(0); }()), "extents access: index must be less than rank");
+ TEST_LIBCPP_ASSERT_FAILURE(([=] { (void)e.extent(0); }()), "extents access: index must be less than rank");
+ TEST_LIBCPP_ASSERT_FAILURE(([=] { (void)e.static_extent(0); }()), "extents access: index must be less than rank");
}
{
std::extents<int, D> e;
- TEST_LIBCPP_ASSERT_FAILURE(([=] { e.extent(2); }()), "extents access: index must be less than rank");
- TEST_LIBCPP_ASSERT_FAILURE(([=] { e.static_extent(2); }()), "extents access: index must be less than rank");
+ TEST_LIBCPP_ASSERT_FAILURE(([=] { (void)e.extent(2); }()), "extents access: index must be less than rank");
+ TEST_LIBCPP_ASSERT_FAILURE(([=] { (void)e.static_extent(2); }()), "extents access: index must be less than rank");
}
{
std::extents<int, 5> e;
- TEST_LIBCPP_ASSERT_FAILURE(([=] { e.extent(2); }()), "extents access: index must be less than rank");
- TEST_LIBCPP_ASSERT_FAILURE(([=] { e.static_extent(2); }()), "extents access: index must be less than rank");
+ TEST_LIBCPP_ASSERT_FAILURE(([=] { (void)e.extent(2); }()), "extents access: index must be less than rank");
+ TEST_LIBCPP_ASSERT_FAILURE(([=] { (void)e.static_extent(2); }()), "extents access: index must be less than rank");
}
{
std::extents<int, D, 5> e;
- TEST_LIBCPP_ASSERT_FAILURE(([=] { e.extent(2); }()), "extents access: index must be less than rank");
- TEST_LIBCPP_ASSERT_FAILURE(([=] { e.static_extent(2); }()), "extents access: index must be less than rank");
+ TEST_LIBCPP_ASSERT_FAILURE(([=] { (void)e.extent(2); }()), "extents access: index must be less than rank");
+ TEST_LIBCPP_ASSERT_FAILURE(([=] { (void)e.static_extent(2); }()), "extents access: index must be less than rank");
}
{
std::extents<int, 1, 2, 3, 4, 5, 6, 7, 8> e;
- TEST_LIBCPP_ASSERT_FAILURE(([=] { e.extent(9); }()), "extents access: index must be less than rank");
- TEST_LIBCPP_ASSERT_FAILURE(([=] { e.static_extent(9); }()), "extents access: index must be less than rank");
+ TEST_LIBCPP_ASSERT_FAILURE(([=] { (void)e.extent(9); }()), "extents access: index must be less than rank");
+ TEST_LIBCPP_ASSERT_FAILURE(([=] { (void)e.static_extent(9); }()), "extents access: index must be less than rank");
}
// check that static_extent works in constant expression with assertions enabled
diff --git a/libcxx/test/libcxx/containers/views/mdspan/nodiscard.verify.cpp b/libcxx/test/libcxx/containers/views/mdspan/nodiscard.verify.cpp
new file mode 100644
index 0000000..71f53f8
--- /dev/null
+++ b/libcxx/test/libcxx/containers/views/mdspan/nodiscard.verify.cpp
@@ -0,0 +1,62 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++23
+
+// <span>
+
+// Check that functions are marked [[nodiscard]]
+
+#include <array>
+#include <mdspan>
+#include <span>
+
+void test() {
+ // mdspan<>
+
+ std::array<int, 4> data;
+ std::mdspan<int, std::extents<std::size_t, 2, 2>> mdsp{data.data(), 2, 2};
+
+ mdsp[0, 1]; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::array arr{0, 1};
+ mdsp[arr]; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::span sp{arr};
+ mdsp[sp]; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ mdsp.rank(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ mdsp.rank_dynamic(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ mdsp.static_extent(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ mdsp.extent(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ mdsp.extents(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ mdsp.data_handle(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ mdsp.mapping(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ mdsp.accessor(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ mdsp.is_always_unique(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ mdsp.is_always_exhaustive(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ mdsp.is_always_strided(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ mdsp.is_unique(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ mdsp.is_exhaustive(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ mdsp.is_strided(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ mdsp.stride(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ // Helpers
+
+ std::extents<int, 1, 2> ex;
+ ex.rank(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ex.rank_dynamic(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ex.static_extent(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ex.extent(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ std::dextents<int, 2> dex;
+ dex.rank(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ dex.rank_dynamic(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ dex.static_extent(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ dex.extent(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+}
diff --git a/libcxx/test/libcxx/containers/views/views.span/nodiscard.verify.cpp b/libcxx/test/libcxx/containers/views/views.span/nodiscard.verify.cpp
new file mode 100644
index 0000000..6666805
--- /dev/null
+++ b/libcxx/test/libcxx/containers/views/views.span/nodiscard.verify.cpp
@@ -0,0 +1,76 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++20
+
+// <span>
+
+// Check that functions are marked [[nodiscard]]
+
+#include <span>
+
+#include "test_macros.h"
+
+void test() {
+ { // Test with a static extent
+ std::span<int, 0> sp;
+
+ sp.first<0>(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sp.last<0>(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sp.first(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sp.last(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sp.subspan<0, 0>(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sp.subspan(0, 0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sp.size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sp.size_bytes(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sp.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sp[0]; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+#if TEST_STD_VER >= 26
+ sp.at(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+#endif
+ sp.front(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sp.back(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sp.data(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sp.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sp.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sp.rbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sp.rend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ std::as_bytes(sp); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::as_writable_bytes(sp);
+ }
+ { // Test with a dynamic extent
+ std::span<int> sp;
+
+ sp.first<0>(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sp.last<0>(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sp.first(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sp.last(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sp.subspan<0, 0>(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sp.subspan(0, 0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sp.size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sp.size_bytes(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sp.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sp[0]; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+#if TEST_STD_VER >= 26
+ sp.at(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+#endif
+ sp.front(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sp.back(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sp.data(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sp.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sp.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sp.rbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sp.rend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ std::as_bytes(sp); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::as_writable_bytes(sp);
+ }
+}
diff --git a/libcxx/test/libcxx/diagnostics/array.nodiscard.verify.cpp b/libcxx/test/libcxx/diagnostics/array.nodiscard.verify.cpp
index 25a2f80..8e49807 100644
--- a/libcxx/test/libcxx/diagnostics/array.nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/diagnostics/array.nodiscard.verify.cpp
@@ -11,13 +11,70 @@
// check that <array> functions are marked [[nodiscard]]
#include <array>
+#include <utility>
-void array_test() {
- std::array<int, 1> array;
- array.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+#include <test_macros.h>
+
+template <std::size_t N>
+void test_members() {
+ std::array<int, N> a;
+ const std::array<int, N> ca{};
+
+ a.begin(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ca.begin(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ a.end(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ca.end(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ a.rbegin(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ca.rbegin(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ a.rend(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ca.rend(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ a.cbegin(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ca.cbegin(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ a.cend(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ca.cend(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ a.crbegin(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ca.crbegin(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ a.crend(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ca.crend(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ a.size(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ a.max_size(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ a.empty(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ a[0]; // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ca[0]; // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ a.at(0); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ca.at(0); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ a.front(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ca.front(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ a.back(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ca.back(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ a.data(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ca.data(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}}
+}
+
+template <typename ArrT>
+void test_get() {
+ std::array<int, 94> a{};
+
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::get<0>(a);
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::get<0>(std::move(a));
+}
+
+#if TEST_STD_VER >= 20
+void test_to_array() {
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::to_array("zmt");
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::to_array({94, 82, 49});
}
+#endif
-void empty_array_test() {
- std::array<int, 0> array;
- array.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+void test() {
+ test_members<0>();
+ test_members<82>();
}
diff --git a/libcxx/test/libcxx/diagnostics/deque.nodiscard.verify.cpp b/libcxx/test/libcxx/diagnostics/deque.nodiscard.verify.cpp
index e8dda09..a9adb175 100644
--- a/libcxx/test/libcxx/diagnostics/deque.nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/diagnostics/deque.nodiscard.verify.cpp
@@ -13,6 +13,32 @@
#include <deque>
void test() {
- std::deque<int> deque;
- deque.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::deque<int> d;
+ const std::deque<int> cd;
+
+ d.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cd.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ d.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cd.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ d.rbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cd.rbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ d.rend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cd.rend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cd.cbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cd.cend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cd.crbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cd.crend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ d.size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ d.max_size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ d.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ d[0]; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cd[0]; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ d.at(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cd.at(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ d.front(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cd.front(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ d.back(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cd.back(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
}
diff --git a/libcxx/test/libcxx/diagnostics/flat_map.nodiscard.verify.cpp b/libcxx/test/libcxx/diagnostics/flat_map.nodiscard.verify.cpp
index 79b943b7..7d75083 100644
--- a/libcxx/test/libcxx/diagnostics/flat_map.nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/diagnostics/flat_map.nodiscard.verify.cpp
@@ -6,15 +6,107 @@
//
//===----------------------------------------------------------------------===//
-// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// REQUIRES: std-at-least-c++23
// <flat_map>
-// [[nodiscard]] bool empty() const noexcept;
+// Check that functions are marked [[nodiscard]]
#include <flat_map>
+#include <utility>
-void f() {
- std::flat_map<int, int> c;
- c.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+template <typename T>
+struct TransparentKey {
+ T t;
+
+ constexpr explicit operator T() const { return t; }
+};
+
+struct TransparentCompare {
+ using is_transparent = void; // This makes the comparator transparent
+
+ template <typename T>
+ constexpr bool operator()(const T& t, const TransparentKey<T>& transparent) const {
+ return t < transparent.t;
+ }
+
+ template <typename T>
+ constexpr bool operator()(const TransparentKey<T>& transparent, const T& t) const {
+ return transparent.t < t;
+ }
+
+ template <typename T>
+ constexpr bool operator()(const T& t1, const T& t2) const {
+ return t1 < t2;
+ }
+};
+
+void test() {
+ std::flat_map<int, int, TransparentCompare> fm;
+ const std::flat_map<int, int, TransparentCompare> cfm{};
+
+ fm.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cfm.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ fm.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cfm.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ fm.rbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cfm.rbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ fm.rend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cfm.rend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cfm.cbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cfm.cend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cfm.crbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cfm.crend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ fm.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ fm.size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ fm.max_size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ int key = 0;
+ TransparentKey<int> tkey;
+
+ std::flat_map<int, int> nfm;
+ nfm[key]; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ fm[std::move(key)]; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ fm[std::move(tkey)]; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ fm.at(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cfm.at(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ fm.at(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cfm.at(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ std::move(fm).extract(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ fm.key_comp(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ fm.value_comp(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ fm.keys(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ fm.values(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ fm.find(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cfm.find(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ fm.find(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cfm.find(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ fm.count(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ fm.count(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ fm.contains(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cfm.contains(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ fm.contains(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cfm.contains(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ fm.lower_bound(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cfm.lower_bound(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ fm.lower_bound(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cfm.lower_bound(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ fm.upper_bound(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cfm.upper_bound(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ fm.upper_bound(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cfm.upper_bound(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ fm.equal_range(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cfm.equal_range(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ fm.equal_range(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cfm.equal_range(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
}
diff --git a/libcxx/test/libcxx/diagnostics/flat_set.nodiscard.verify.cpp b/libcxx/test/libcxx/diagnostics/flat_set.nodiscard.verify.cpp
index 161fe53..89d6045 100644
--- a/libcxx/test/libcxx/diagnostics/flat_set.nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/diagnostics/flat_set.nodiscard.verify.cpp
@@ -6,15 +6,93 @@
//
//===----------------------------------------------------------------------===//
-// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// REQUIRES: std-at-least-c++23
// <flat_set>
-// [[nodiscard]] bool empty() const noexcept;
+// Check that functions are marked [[nodiscard]]
#include <flat_set>
+#include <utility>
-void f() {
- std::flat_set<int> c;
- c.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+template <typename T>
+struct TransparentKey {
+ T t;
+
+ constexpr explicit operator T() const { return t; }
+};
+
+struct TransparentCompare {
+ using is_transparent = void; // This makes the comparator transparent
+
+ template <typename T>
+ constexpr bool operator()(const T& t, const TransparentKey<T>& transparent) const {
+ return t < transparent.t;
+ }
+
+ template <typename T>
+ constexpr bool operator()(const TransparentKey<T>& transparent, const T& t) const {
+ return transparent.t < t;
+ }
+
+ template <typename T>
+ constexpr bool operator()(const T& t1, const T& t2) const {
+ return t1 < t2;
+ }
+};
+
+void test() {
+ std::flat_set<int, TransparentCompare> fs;
+ const std::flat_set<int, TransparentCompare> cfs;
+
+ fs.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cfs.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ fs.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cfs.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ fs.rbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cfs.rbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ fs.rend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cfs.rend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cfs.cbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cfs.cend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cfs.crbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cfs.crend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ fs.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ fs.size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ fs.max_size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ std::move(fs).extract(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ fs.key_comp(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ fs.value_comp(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ int key = 0;
+ TransparentKey<int> tkey;
+
+ fs.find(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cfs.find(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ fs.find(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cfs.find(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ fs.count(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ fs.count(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ fs.contains(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ fs.contains(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ fs.lower_bound(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cfs.lower_bound(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ fs.lower_bound(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cfs.lower_bound(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ fs.upper_bound(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cfs.upper_bound(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ fs.upper_bound(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cfs.upper_bound(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ fs.equal_range(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cfs.equal_range(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ fs.equal_range(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cfs.equal_range(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
}
diff --git a/libcxx/test/libcxx/diagnostics/forward_list.nodiscard.verify.cpp b/libcxx/test/libcxx/diagnostics/forward_list.nodiscard.verify.cpp
index 7594a1d..671c7f7 100644
--- a/libcxx/test/libcxx/diagnostics/forward_list.nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/diagnostics/forward_list.nodiscard.verify.cpp
@@ -13,6 +13,27 @@
#include <forward_list>
void test() {
- std::forward_list<int> forward_list;
- forward_list.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::forward_list<int> fl;
+ const std::forward_list<int> cfl;
+
+ fl.get_allocator(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ fl.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cfl.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ fl.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cfl.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ fl.cbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cfl.cbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ fl.cend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cfl.cend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ fl.before_begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cfl.before_begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ fl.cbefore_begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cfl.cbefore_begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ fl.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ fl.max_size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ fl.front(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cfl.front(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
}
diff --git a/libcxx/test/libcxx/diagnostics/functional.nodiscard.verify.cpp b/libcxx/test/libcxx/diagnostics/functional.nodiscard.verify.cpp
index 4307976..521870f 100644
--- a/libcxx/test/libcxx/diagnostics/functional.nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/diagnostics/functional.nodiscard.verify.cpp
@@ -6,15 +6,63 @@
//
//===----------------------------------------------------------------------===//
-// UNSUPPORTED: c++03, c++11, c++14, c++17
+// UNSUPPORTED: c++03
// check that <functional> functions are marked [[nodiscard]]
+#include <cstddef>
#include <functional>
#include "test_macros.h"
void test() {
int i = 0;
- std::identity()(i); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ // Function wrappers
+
+#if !defined(TEST_HAS_NO_RTTI)
+ std::function<void(int)> f;
+ const std::function<void(int)> cf;
+
+ f.target_type(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ f.target<void(int)>(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cf.target<void(int)>(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+#endif
+ struct ZMT {
+ void member_function() {};
+ };
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::mem_fn(&ZMT::member_function);
+
+ // Identity
+
+#if TEST_STD_VER >= 20
+ std::identity{}(i); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+#endif
+
+ // Partial function application
+
+#if TEST_STD_VER >= 23
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::bind_back([](int a) { return a; }, 94);
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::bind_front([](int a) { return a; }, 94);
+#endif
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::bind([](int a) { return a; }, 94);
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::bind<float>([](int a) { return a; }, 94);
+
+ // Reference wrappers
+
+ std::reference_wrapper<int> rw{i};
+ rw.get(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ std::ref(i); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::cref(i); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ // Hash specializations
+
+ std::hash<std::nullptr_t> hash;
+ hash(nullptr); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
}
diff --git a/libcxx/test/libcxx/diagnostics/list.nodiscard.verify.cpp b/libcxx/test/libcxx/diagnostics/list.nodiscard.verify.cpp
index f19224a7..bfce9b8 100644
--- a/libcxx/test/libcxx/diagnostics/list.nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/diagnostics/list.nodiscard.verify.cpp
@@ -13,6 +13,33 @@
#include <list>
void test() {
- std::list<int> list;
- list.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::list<int> l;
+ const std::list<int> cl;
+
+ l.get_allocator(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ l.size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ l.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ l.max_size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ l.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cl.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ l.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cl.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ l.cbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cl.cbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ l.cend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cl.cend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ l.rbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cl.rbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ l.rend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cl.rend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ l.crbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cl.crbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ l.crend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cl.crend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ l.front(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cl.front(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ l.back(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cl.back(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
}
diff --git a/libcxx/test/libcxx/diagnostics/queue.nodiscard.verify.cpp b/libcxx/test/libcxx/diagnostics/queue.nodiscard.verify.cpp
index 77d3367..da1f9ff 100644
--- a/libcxx/test/libcxx/diagnostics/queue.nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/diagnostics/queue.nodiscard.verify.cpp
@@ -12,12 +12,24 @@
#include <queue>
-void test_queue() {
- std::queue<int> queue;
- queue.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
-}
+void test() {
+ {
+ std::queue<int> q;
+ const std::queue<int> cq{};
+
+ q.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ q.size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ q.front(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cq.front(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ q.back(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cq.back(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ }
+
+ {
+ std::priority_queue<int> pq;
-void test_priority_queue() {
- std::priority_queue<int> priority_queue;
- priority_queue.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ pq.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ pq.size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ pq.top(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ }
}
diff --git a/libcxx/test/libcxx/diagnostics/stack.nodiscard.verify.cpp b/libcxx/test/libcxx/diagnostics/stack.nodiscard.verify.cpp
index 861852a..a0a5b3c 100644
--- a/libcxx/test/libcxx/diagnostics/stack.nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/diagnostics/stack.nodiscard.verify.cpp
@@ -13,6 +13,11 @@
#include <stack>
void test() {
- std::stack<int> stack;
- stack.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::stack<int> st;
+ const std::stack<int> cst;
+
+ st.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ st.size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ st.top(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cst.top(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
}
diff --git a/libcxx/test/libcxx/diagnostics/string.nodiscard.verify.cpp b/libcxx/test/libcxx/diagnostics/string.nodiscard.verify.cpp
index d421eaf..0ff92ca 100644
--- a/libcxx/test/libcxx/diagnostics/string.nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/diagnostics/string.nodiscard.verify.cpp
@@ -11,13 +11,199 @@
// check that <string> functions are marked [[nodiscard]]
#include <string>
+#include <string_view>
#include "test_macros.h"
+std::string prval();
+
void test() {
- std::string string;
- string.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::string str;
+ const std::string cstr;
+ std::string_view sv;
+
+ str[0]; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cstr[0]; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ str.at(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cstr.at(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ str.c_str(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ str.data(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cstr.data(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ str.substr(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ prval().substr(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ str.front(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cstr.front(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ str.back(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cstr.back(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ str.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cstr.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ str.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cstr.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ str.rbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cstr.rbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ str.rend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cstr.rend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ str.cbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ str.cend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ str.crbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ str.crend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ str.capacity(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ str.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ str.length(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ str.size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ str.max_size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ str.get_allocator(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ str.find(str); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ str.find(sv); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ str.find(' '); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ str.find(""); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ str.find("", 0, 0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ str.rfind(str); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ str.rfind(sv); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ str.rfind(' '); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ str.rfind(""); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ str.rfind("", 0, 0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ // clang-format off
+ str.find_first_of(str); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ str.find_first_of(sv); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ str.find_first_of(' '); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ str.find_first_of(""); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ str.find_first_of("", 0, 0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ str.find_last_of(str); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ str.find_last_of(sv); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ str.find_last_of(' '); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ str.find_last_of(""); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ str.find_last_of("", 0, 0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ str.find_first_not_of(str); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ str.find_first_not_of(sv); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ str.find_first_not_of(' '); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ str.find_first_not_of(""); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ str.find_first_not_of("", 0, 0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ str.find_last_not_of(str); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ str.find_last_not_of(sv); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ str.find_last_not_of(' '); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ str.find_last_not_of(""); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ str.find_last_not_of("", 0, 0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ str.compare(str); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ str.compare(sv); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ str.compare(0, 0, sv); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ str.compare(0, 0, sv, 0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ str.compare(0, 0, str); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ str.compare(0, 0, str, 0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ str.compare(""); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ str.compare(0, 0, ""); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ str.compare(0, 0, "", 0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ // clang-format on
+
+#if TEST_STD_VER >= 20
+ str.starts_with(sv); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ str.starts_with(' '); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ str.starts_with(""); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ str.ends_with(sv); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ str.ends_with(' '); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ str.ends_with(""); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+#endif
+
+#if TEST_STD_VER >= 23
+ str.contains(sv); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ str.contains(' '); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ str.contains(""); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+#endif
+
#if TEST_STD_VER >= 26
- string.subview(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ str.subview(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+#endif
+}
+
+void test_nonmembers() {
+ // Numeric conversions
+
+ std::string str;
+
+ std::stoi(str); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::stol(str); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::stoll(str); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::stoull(str); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ std::stof(str); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::stod(str); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::stold(str); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ std::to_string(94); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::to_string(82U); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::to_string(94L); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::to_string(82UL); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::to_string(94LL); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::to_string(82ULL); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::to_string(94.0F); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::to_string(82.0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::to_string(94.0L); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+#if !defined(TEST_HAS_NO_WIDE_CHARACTERS)
+
+ std::wstring wstr;
+
+ std::stoi(wstr); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::stol(wstr); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::stoll(wstr); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::stoull(wstr); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ std::stof(wstr); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::stod(wstr); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::stold(wstr); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ std::to_wstring(94); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::to_wstring(82U); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::to_wstring(94L); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::to_wstring(82UL); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::to_wstring(94LL); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::to_wstring(82ULL); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::to_wstring(94.0F); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::to_wstring(82.0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::to_wstring(94.0L); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+#endif
+
+ // std::hash<>
+
+ std::hash<std::string> hash;
+
+ hash(str); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+#if TEST_STD_VER >= 14
+ // string literals
+
+ using namespace std::string_literals;
+
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ""s; // const char*
+# if !defined(TEST_HAS_NO_WIDE_CHARACTERS)
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ L""s; // const wchar_t*
+# endif
+# if !defined(TEST_HAS_NO_CHAR8_T)
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ u8""s; // const char8_t*
+# endif
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ u""s; // const char16_t*
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ U""s; // const char32_t*
#endif
}
diff --git a/libcxx/test/libcxx/diagnostics/string_view.nodiscard.verify.cpp b/libcxx/test/libcxx/diagnostics/string_view.nodiscard.verify.cpp
index e5b2258..89e4a5b 100644
--- a/libcxx/test/libcxx/diagnostics/string_view.nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/diagnostics/string_view.nodiscard.verify.cpp
@@ -12,12 +12,140 @@
#include <string_view>
+#include "type_algorithms.h"
#include "test_macros.h"
-void test() {
- std::string_view string_view;
- string_view.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+void test_members() {
+ std::string_view sv;
+
+ sv.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sv.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sv.cbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sv.cend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sv.rbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sv.rend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sv.crbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sv.crend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ sv.size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sv.length(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sv.max_size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ sv.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ sv[0]; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sv.at(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ sv.front(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sv.back(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sv.data(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ sv.substr(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
#if TEST_STD_VER >= 26
- string_view.subview(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sv.subview(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+#endif
+
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sv.compare(sv);
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sv.compare(0, 0, sv);
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sv.compare(0, 0, sv, 0, 0);
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sv.compare("");
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sv.compare(0, 0, "");
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sv.compare(0, 0, "", 0);
+
+ sv.find(sv); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sv.find(' '); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sv.find("", 0, 0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sv.find("", 0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ sv.rfind(sv); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sv.rfind(' '); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sv.rfind("", 0, 0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sv.rfind("", 0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sv.find_first_of(sv);
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sv.find_first_of(' ');
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sv.find_first_of("", 0, 0);
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sv.find_first_of("", 0);
+
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sv.find_last_of(sv);
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sv.find_last_of(' ');
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sv.find_last_of("", 0, 0);
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sv.find_last_of("", 0);
+
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sv.find_first_not_of(sv);
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sv.find_first_not_of(' ');
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sv.find_first_not_of("", 0, 0);
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sv.find_first_not_of("", 0);
+
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sv.find_last_not_of(sv);
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sv.find_last_not_of(' ');
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sv.find_last_not_of("", 0, 0);
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sv.find_last_not_of("", 0);
+
+#if TEST_STD_VER >= 20
+ sv.starts_with(sv); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sv.starts_with(' '); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sv.starts_with(""); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ sv.ends_with(sv); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sv.ends_with(' '); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sv.ends_with(""); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+#endif
+
+#if TEST_STD_VER >= 23
+ sv.contains(sv); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sv.contains(' '); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sv.contains(""); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+#endif
+}
+
+void test_nonmembers() {
+ // std::hash<>
+
+ std::hash<std::string_view> hash;
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ hash(std::string_view{});
+
+#if TEST_STD_VER >= 14
+ // string_view literals
+
+ using namespace std::string_view_literals;
+
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ""sv; // const char*
+# if !defined(TEST_HAS_NO_WIDE_CHARACTERS)
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ L""sv; // const wchar_t*
+# endif
+# if !defined(TEST_HAS_NO_CHAR8_T)
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ u8""sv; // const char8_t*
+# endif
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ u""sv; // const char16_t*
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ U""sv; // const char32_t*
#endif
}
diff --git a/libcxx/test/libcxx/diagnostics/syserr/nodiscard.verify.cpp b/libcxx/test/libcxx/diagnostics/syserr/nodiscard.verify.cpp
new file mode 100644
index 0000000..26565a1
--- /dev/null
+++ b/libcxx/test/libcxx/diagnostics/syserr/nodiscard.verify.cpp
@@ -0,0 +1,108 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// Check that functions are marked [[nodiscard]]
+
+#include <stdexcept>
+#include <system_error>
+
+void test() {
+ { // <stdexcept>
+ std::logic_error le("logic error");
+ le.what(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ std::runtime_error re("runtime error");
+ re.what(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ std::domain_error de("domain error");
+ de.what(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ std::invalid_argument ia("invalid argument");
+ ia.what(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ std::length_error lerr("length error");
+ lerr.what(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ std::out_of_range oor("out of range");
+ oor.what(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ std::range_error rerr("range error");
+ rerr.what(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ std::overflow_error oferr("overflow error");
+ oferr.what(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ std::underflow_error uferr("underflow error");
+ uferr.what(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ }
+ { // <system_error>
+ {
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::generic_category();
+
+ const std::error_category& ec = std::generic_category();
+
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ec.name();
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ec.default_error_condition(94);
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ec.equivalent(94, ec.default_error_condition(82));
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ec.equivalent(std::error_code(49, ec), 94);
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ec.message(82);
+ }
+ {
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::system_category();
+
+ const std::error_category& ec = std::system_category();
+
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ec.name();
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ec.default_error_condition(94);
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ec.equivalent(94, ec.default_error_condition(82));
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ec.equivalent(std::error_code(49, ec), 94);
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ec.message(82);
+ }
+ {
+ std::error_code ec;
+
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ec.value();
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ec.category();
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ec.default_error_condition();
+
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ec.message();
+
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::make_error_code(std::errc::invalid_argument);
+ }
+ {
+ std::error_condition ec;
+
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ec.value();
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ec.category();
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ec.message();
+
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::make_error_condition(std::errc::invalid_argument);
+ }
+ }
+}
diff --git a/libcxx/test/libcxx/diagnostics/utility.nodiscard.verify.cpp b/libcxx/test/libcxx/diagnostics/utility.nodiscard.verify.cpp
index 524be96..2f5b3ba 100644
--- a/libcxx/test/libcxx/diagnostics/utility.nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/diagnostics/utility.nodiscard.verify.cpp
@@ -10,8 +10,6 @@
// check that <utility> functions are marked [[nodiscard]]
-// clang-format off
-
#include <utility>
#include "test_macros.h"
@@ -19,15 +17,33 @@
void test() {
int i = 0;
- std::forward<int>(i); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
- std::forward<int>(1); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
- std::move(i); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
- std::move_if_noexcept(i); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::forward<int>(i); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::forward<int>(1); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::move(i); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::move_if_noexcept(i);
#if TEST_STD_VER >= 17
std::as_const(i); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
#endif
+#if TEST_STD_VER >= 20
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::cmp_equal(94, 82);
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::cmp_not_equal(94, 82);
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::cmp_less(94, 82);
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::cmp_greater(94, 82);
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::cmp_less_equal(94, 82);
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::cmp_greater_equal(94, 82);
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::in_range<long>(49);
+#endif
+
#if TEST_STD_VER >= 23
enum E { Apple, Orange } e = Apple;
std::to_underlying(e); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
diff --git a/libcxx/test/libcxx/input.output/file.streams/fstreams/filebuf/traits_mismatch.verify.cpp b/libcxx/test/libcxx/input.output/file.streams/fstreams/filebuf/traits_mismatch.verify.cpp
index 30e7b66..283adbc 100644
--- a/libcxx/test/libcxx/input.output/file.streams/fstreams/filebuf/traits_mismatch.verify.cpp
+++ b/libcxx/test/libcxx/input.output/file.streams/fstreams/filebuf/traits_mismatch.verify.cpp
@@ -19,4 +19,4 @@
std::basic_filebuf<char, std::char_traits<wchar_t> > f;
// expected-error-re@*:* {{static assertion failed{{.*}}traits_type::char_type must be the same type as CharT}}
-// expected-error@*:* 11 {{only virtual member functions can be marked 'override'}}
+// expected-error@*:* 10 {{only virtual member functions can be marked 'override'}}
diff --git a/libcxx/test/libcxx/input.output/file.streams/fstreams/traits_mismatch.verify.cpp b/libcxx/test/libcxx/input.output/file.streams/fstreams/traits_mismatch.verify.cpp
index daafb36..ba6f3c3 100644
--- a/libcxx/test/libcxx/input.output/file.streams/fstreams/traits_mismatch.verify.cpp
+++ b/libcxx/test/libcxx/input.output/file.streams/fstreams/traits_mismatch.verify.cpp
@@ -21,7 +21,7 @@ std::basic_fstream<char, std::char_traits<wchar_t> > f;
// expected-error-re@*:* {{static assertion failed{{.*}}traits_type::char_type must be the same type as CharT}}
// expected-error-re@*:* {{static assertion failed{{.*}}traits_type::char_type must be the same type as CharT}}
-// expected-error@*:* 13 {{only virtual member functions can be marked 'override'}}
+// expected-error@*:* 12 {{only virtual member functions can be marked 'override'}}
// FIXME: As of commit r324062 Clang incorrectly generates a diagnostic about mismatching
// exception specifications for types which are already invalid for one reason or another.
diff --git a/libcxx/test/libcxx/language.support/nodiscard.verify.cpp b/libcxx/test/libcxx/language.support/nodiscard.verify.cpp
new file mode 100644
index 0000000..eeadd9f
--- /dev/null
+++ b/libcxx/test/libcxx/language.support/nodiscard.verify.cpp
@@ -0,0 +1,129 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// ADDITIONAL_COMPILE_FLAGS: -Wno-deprecated
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX17_REMOVED_UNEXPECTED_FUNCTIONS
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX20_REMOVED_UNCAUGHT_EXCEPTION
+
+// Check that functions are marked [[nodiscard]]
+
+#include <compare>
+#include <coroutine>
+#include <exception>
+#include <initializer_list>
+
+#include "test_macros.h"
+
+void test() {
+#if TEST_STD_VER >= 20
+ { // <compare>
+ int x = 94;
+ int y = 82;
+ auto oRes = x <=> y;
+
+ std::is_eq(oRes); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::is_neq(oRes); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::is_lt(oRes); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::is_lteq(oRes); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::is_gt(oRes); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::is_gteq(oRes); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ }
+#endif
+
+#if TEST_STD_VER >= 20
+ { // <coroutine>
+ struct EmptyPromise {
+ } promise;
+
+ {
+ std::coroutine_handle<void> cr{};
+
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cr.address();
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::coroutine_handle<void>::from_address(&promise);
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cr.done();
+
+ std::hash<std::coroutine_handle<void>> hash;
+ hash(cr); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ }
+ {
+ std::coroutine_handle<EmptyPromise> cr;
+
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::coroutine_handle<EmptyPromise>::from_promise(promise);
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cr.address();
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::coroutine_handle<EmptyPromise>::from_address(&promise);
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cr.done();
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cr.promise();
+ }
+ {
+ std::coroutine_handle<std::noop_coroutine_promise> cr = std::noop_coroutine();
+
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cr.done();
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cr.promise();
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cr.address();
+
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::noop_coroutine();
+ }
+ }
+#endif
+
+ { // <exception>
+ {
+ std::bad_exception bex;
+
+ bex.what(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ }
+ {
+ std::exception ex;
+
+ ex.what(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ }
+ {
+ std::nested_exception nex;
+
+ nex.nested_ptr(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ }
+
+#if TEST_STD_VER <= 14
+ std::get_unexpected(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+#endif
+
+ std::get_terminate(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+#if _LIBCPP_STD_VER <= 17
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::uncaught_exception();
+#endif
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::uncaught_exceptions();
+
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::current_exception();
+ }
+
+#if TEST_STD_VER >= 11
+ { // <initializer_list>
+ std::initializer_list<int> il{94, 82, 49};
+
+ il.size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ il.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ il.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ }
+#endif
+}
diff --git a/libcxx/test/libcxx/language.support/support.dynamic/libcpp_deallocate.sh.cpp b/libcxx/test/libcxx/language.support/support.dynamic/libcpp_deallocate.sh.cpp
index 4bb42cb..282d49d 100644
--- a/libcxx/test/libcxx/language.support/support.dynamic/libcpp_deallocate.sh.cpp
+++ b/libcxx/test/libcxx/language.support/support.dynamic/libcpp_deallocate.sh.cpp
@@ -21,6 +21,8 @@
// GCC doesn't support the aligned-allocation flags.
// XFAIL: gcc
+// ADDITIONAL_COMPILE_FLAGS: -I %{libcxx-dir}/src -Wno-macro-redefined
+
// RUN: %{build} -faligned-allocation -fsized-deallocation
// RUN: %{run}
// RUN: %{build} -faligned-allocation -fno-sized-deallocation -DNO_SIZE
@@ -36,10 +38,7 @@
#include "test_macros.h"
-TEST_DIAGNOSTIC_PUSH
-TEST_CLANG_DIAGNOSTIC_IGNORED("-Wprivate-header")
-#include <__memory/aligned_alloc.h>
-TEST_DIAGNOSTIC_POP
+#include "include/aligned_alloc.h"
struct alloc_stats {
alloc_stats() { reset(); }
diff --git a/libcxx/test/libcxx/memory/allocation_guard.pass.cpp b/libcxx/test/libcxx/memory/allocation_guard.pass.cpp
index 493ebf0..a7c9397 100644
--- a/libcxx/test/libcxx/memory/allocation_guard.pass.cpp
+++ b/libcxx/test/libcxx/memory/allocation_guard.pass.cpp
@@ -17,6 +17,8 @@
#include <__memory/allocation_guard.h>
#include <cassert>
+#include <climits>
+#include <memory>
#include <type_traits>
#include <utility>
diff --git a/libcxx/test/libcxx/memory/uninitialized_allocator_copy.pass.cpp b/libcxx/test/libcxx/memory/uninitialized_allocator_copy.pass.cpp
index 679ee86..1d127f9 100644
--- a/libcxx/test/libcxx/memory/uninitialized_allocator_copy.pass.cpp
+++ b/libcxx/test/libcxx/memory/uninitialized_allocator_copy.pass.cpp
@@ -11,6 +11,7 @@
// ensure that __uninitialized_allocator_copy calls the proper construct and destruct functions
#include <algorithm>
+#include <cassert>
#include <iterator>
#include <memory>
diff --git a/libcxx/test/libcxx/numerics/clamp_to_integral.pass.cpp b/libcxx/test/libcxx/numerics/clamp_to_integral.pass.cpp
index aed78f9..937593c 100644
--- a/libcxx/test/libcxx/numerics/clamp_to_integral.pass.cpp
+++ b/libcxx/test/libcxx/numerics/clamp_to_integral.pass.cpp
@@ -16,6 +16,7 @@
#include <cassert>
#include <cmath>
#include <limits>
+#include <type_traits>
template <class IntT>
void test() {
diff --git a/libcxx/test/libcxx/strings/basic.string/nonnull.verify.cpp b/libcxx/test/libcxx/strings/basic.string/nonnull.verify.cpp
index f428c49..c9df9f0 100644
--- a/libcxx/test/libcxx/strings/basic.string/nonnull.verify.cpp
+++ b/libcxx/test/libcxx/strings/basic.string/nonnull.verify.cpp
@@ -13,6 +13,8 @@
// Clang 19 and AppleClang don't have diagnose_if with diagnostic flags
// UNSUPPORTED: clang-19, apple-clang-17
+// ADDITIONAL_COMPILE_FLAGS: -Wno-unused-result
+
#include <string>
#include "test_macros.h"
diff --git a/libcxx/test/libcxx/strings/string.view/nonnull.verify.cpp b/libcxx/test/libcxx/strings/string.view/nonnull.verify.cpp
index 316c982..ffe0487 100644
--- a/libcxx/test/libcxx/strings/string.view/nonnull.verify.cpp
+++ b/libcxx/test/libcxx/strings/string.view/nonnull.verify.cpp
@@ -10,8 +10,10 @@
// Ensure that APIs which take a CharT* are diagnosing passing a nullptr to them
-// Clang 19 and AppleClang don't have diagnose_if with diagnostic flags
-// UNSUPPORTED: clang-19, apple-clang-17
+// AppleClang doesn't have diagnose_if with diagnostic flags
+// UNSUPPORTED: apple-clang-17
+
+// ADDITIONAL_COMPILE_FLAGS: -Wno-unused-result
#include <string_view>
diff --git a/libcxx/test/libcxx/system_reserved_names.gen.py b/libcxx/test/libcxx/system_reserved_names.gen.py
index d69182d..aaede22 100644
--- a/libcxx/test/libcxx/system_reserved_names.gen.py
+++ b/libcxx/test/libcxx/system_reserved_names.gen.py
@@ -83,7 +83,7 @@ for header in public_headers:
// Test that libc++ doesn't use names that collide with FreeBSD system macros.
// newlib and picolibc also define these macros
-#if !defined(__FreeBSD__) && !defined(_NEWLIB_VERSION)
+#if !defined(__FreeBSD__) && !_LIBCPP_LIBC_NEWLIB
# define __null_sentinel SYSTEM_RESERVED_NAME
# define __generic SYSTEM_RESERVED_NAME
#endif
@@ -122,7 +122,7 @@ for header in public_headers:
#endif
// Newlib & picolibc use __input as a parameter name of a64l & l64a
-#ifndef _NEWLIB_VERSION
+#if !_LIBCPP_LIBC_NEWLIB
# define __input SYSTEM_RESERVED_NAME
#endif
#define __output SYSTEM_RESERVED_NAME
diff --git a/libcxx/test/libcxx/thread/nodiscard.verify.cpp b/libcxx/test/libcxx/thread/nodiscard.verify.cpp
new file mode 100644
index 0000000..19e43f8
--- /dev/null
+++ b/libcxx/test/libcxx/thread/nodiscard.verify.cpp
@@ -0,0 +1,144 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03
+// UNSUPPORTED: no-threads
+
+// Check that functions are marked [[nodiscard]]
+
+#include <chrono>
+#include <barrier>
+#include <latch>
+#include <mutex>
+#include <semaphore>
+#include <thread>
+
+#include "test_macros.h"
+
+const auto timePoint = std::chrono::steady_clock::now();
+
+void test() {
+ // Threads
+ {
+ std::thread th;
+
+ th.joinable(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ th.get_id(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ th.native_handle(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ th.hardware_concurrency(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ }
+#if TEST_STD_VER >= 20
+ {
+ std::jthread jt;
+
+ jt.joinable(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ jt.get_id(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ jt.native_handle(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ jt.get_stop_source(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ jt.get_stop_token(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ jt.hardware_concurrency(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ }
+#endif
+
+ // Mutual exclusion
+
+ { // <mutex>
+ std::mutex m;
+
+ m.try_lock(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ m.native_handle(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ }
+ {
+ std::recursive_mutex m;
+
+ m.try_lock(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ m.native_handle(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ }
+ {
+ std::timed_mutex m;
+
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ m.try_lock();
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ m.try_lock_for(std::chrono::nanoseconds{82});
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ m.try_lock_until(timePoint);
+ }
+ {
+ std::recursive_timed_mutex m;
+
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ m.try_lock();
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ m.try_lock_for(std::chrono::nanoseconds{82});
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ m.try_lock_until(timePoint);
+ }
+ {
+ std::mutex m1;
+ std::mutex m2;
+ std::mutex m3;
+
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::try_lock(m1, m2);
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::try_lock(m1, m2, m3);
+ }
+
+ // Condition variables
+
+ { // <condition_variable>
+ std::condition_variable cv;
+
+ cv.native_handle(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ }
+
+#if TEST_STD_VER >= 20
+
+ // Semaphores
+
+ { // <semaphore>
+ std::counting_semaphore<> cs{0};
+
+ cs.max(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cs.try_acquire_for(std::chrono::nanoseconds{82});
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cs.try_acquire();
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cs.try_acquire_until(timePoint);
+
+ std::binary_semaphore bs{0};
+
+ bs.max(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ bs.try_acquire_for(std::chrono::nanoseconds{82});
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ bs.try_acquire();
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ bs.try_acquire_until(timePoint);
+ }
+
+ // Latches and barriers
+
+ { // <barrier>
+ std::barrier<> b{94};
+
+ b.max(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ }
+ { // <latch>
+ std::latch l{94};
+
+ l.max(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ l.try_wait(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ }
+
+#endif
+}
diff --git a/libcxx/test/libcxx/transitive_includes.gen.py b/libcxx/test/libcxx/transitive_includes.gen.py
index 6ed35af..2b643e1 100644
--- a/libcxx/test/libcxx/transitive_includes.gen.py
+++ b/libcxx/test/libcxx/transitive_includes.gen.py
@@ -89,7 +89,7 @@ else:
// UNSUPPORTED: LIBCXX-FREEBSD-FIXME
// RUN: mkdir %t
-// RUN: %{{cxx}} %s %{{flags}} %{{compile_flags}} --trace-includes -fshow-skipped-includes --preprocess > /dev/null 2> %t/trace-includes.txt
+// RUN: %{{cxx}} %s %{{flags}} %{{compile_flags}} -Wno-deprecated --trace-includes -fshow-skipped-includes --preprocess > /dev/null 2> %t/trace-includes.txt
// RUN: %{{python}} %{{libcxx-dir}}/test/libcxx/transitive_includes/to_csv.py %t/trace-includes.txt > %t/actual_transitive_includes.csv
// RUN: cat %{{libcxx-dir}}/test/libcxx/transitive_includes/%{{cxx_std}}.csv | awk '/^{escaped_header} / {{ print }}' > %t/expected_transitive_includes.csv
// RUN: diff -w %t/expected_transitive_includes.csv %t/actual_transitive_includes.csv
diff --git a/libcxx/test/libcxx/type_traits/is_replaceable.compile.pass.cpp b/libcxx/test/libcxx/type_traits/is_replaceable.compile.pass.cpp
deleted file mode 100644
index c04e944..0000000
--- a/libcxx/test/libcxx/type_traits/is_replaceable.compile.pass.cpp
+++ /dev/null
@@ -1,353 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include <__type_traits/is_replaceable.h>
-#include <array>
-#include <deque>
-#include <exception>
-#include <expected>
-#include <memory>
-#include <optional>
-#include <string>
-#include <tuple>
-#include <type_traits>
-#include <variant>
-#include <vector>
-
-#include "constexpr_char_traits.h"
-#include "test_allocator.h"
-#include "test_macros.h"
-
-#ifndef TEST_HAS_NO_LOCALIZATION
-# include <locale>
-#endif
-
-template <class T>
-struct NonPropagatingStatefulMoveAssignAlloc : std::allocator<T> {
- using propagate_on_container_move_assignment = std::false_type;
- using is_always_equal = std::false_type;
- template <class U>
- struct rebind {
- using other = NonPropagatingStatefulMoveAssignAlloc<U>;
- };
-};
-
-template <class T>
-struct NonPropagatingStatefulCopyAssignAlloc : std::allocator<T> {
- using propagate_on_container_copy_assignment = std::false_type;
- using is_always_equal = std::false_type;
- template <class U>
- struct rebind {
- using other = NonPropagatingStatefulCopyAssignAlloc<U>;
- };
-};
-
-template <class T>
-struct NonPropagatingStatelessMoveAssignAlloc : std::allocator<T> {
- using propagate_on_container_move_assignment = std::false_type;
- using is_always_equal = std::true_type;
- template <class U>
- struct rebind {
- using other = NonPropagatingStatelessMoveAssignAlloc<U>;
- };
-};
-
-template <class T>
-struct NonPropagatingStatelessCopyAssignAlloc : std::allocator<T> {
- using propagate_on_container_copy_assignment = std::false_type;
- using is_always_equal = std::true_type;
- template <class U>
- struct rebind {
- using other = NonPropagatingStatelessCopyAssignAlloc<U>;
- };
-};
-
-template <class T>
-struct NonReplaceableStatelessAlloc : std::allocator<T> {
- // Ensure that we don't consider an allocator that is a member of a container to be
- // replaceable if it's not replaceable, even if it always compares equal and always propagates.
- using propagate_on_container_move_assignment = std::true_type;
- using propagate_on_container_copy_assignment = std::true_type;
- using is_always_equal = std::true_type;
- NonReplaceableStatelessAlloc() = default;
- NonReplaceableStatelessAlloc(NonReplaceableStatelessAlloc const&) {}
- NonReplaceableStatelessAlloc(NonReplaceableStatelessAlloc&&) = default;
- template <class U>
- struct rebind {
- using other = NonReplaceableStatelessAlloc<U>;
- };
-};
-static_assert(!std::__is_replaceable<NonReplaceableStatelessAlloc<int> >::value, "");
-
-static_assert(!std::__is_replaceable<test_allocator<char> >::value, ""); // we use that property below
-
-struct Empty {};
-static_assert(std::__is_replaceable<char>::value, "");
-static_assert(std::__is_replaceable<int>::value, "");
-static_assert(std::__is_replaceable<double>::value, "");
-static_assert(std::__is_replaceable<Empty>::value, "");
-
-struct TriviallyCopyable {
- char c;
- int i;
- Empty s;
-};
-static_assert(std::__is_replaceable<TriviallyCopyable>::value, "");
-
-struct NotTriviallyCopyable {
- NotTriviallyCopyable(const NotTriviallyCopyable&);
- ~NotTriviallyCopyable();
-};
-static_assert(!std::__is_replaceable<NotTriviallyCopyable>::value, "");
-
-struct MoveOnlyTriviallyCopyable {
- MoveOnlyTriviallyCopyable(const MoveOnlyTriviallyCopyable&) = delete;
- MoveOnlyTriviallyCopyable& operator=(const MoveOnlyTriviallyCopyable&) = delete;
- MoveOnlyTriviallyCopyable(MoveOnlyTriviallyCopyable&&) = default;
- MoveOnlyTriviallyCopyable& operator=(MoveOnlyTriviallyCopyable&&) = default;
-};
-static_assert(std::__is_replaceable<MoveOnlyTriviallyCopyable>::value, "");
-
-struct CustomCopyAssignment {
- CustomCopyAssignment(const CustomCopyAssignment&) = default;
- CustomCopyAssignment(CustomCopyAssignment&&) = default;
- CustomCopyAssignment& operator=(const CustomCopyAssignment&);
- CustomCopyAssignment& operator=(CustomCopyAssignment&&) = default;
-};
-static_assert(!std::__is_replaceable<CustomCopyAssignment>::value, "");
-
-struct CustomMoveAssignment {
- CustomMoveAssignment(const CustomMoveAssignment&) = default;
- CustomMoveAssignment(CustomMoveAssignment&&) = default;
- CustomMoveAssignment& operator=(const CustomMoveAssignment&) = default;
- CustomMoveAssignment& operator=(CustomMoveAssignment&&);
-};
-static_assert(!std::__is_replaceable<CustomMoveAssignment>::value, "");
-
-// library-internal types
-// ----------------------
-
-// __split_buffer
-static_assert(
- std::__is_replaceable<std::__split_buffer<int, std::allocator<int>, std::__split_buffer_pointer_layout> >::value,
- "");
-static_assert(std::__is_replaceable<std::__split_buffer<NotTriviallyCopyable,
- std::allocator<NotTriviallyCopyable>,
- std::__split_buffer_pointer_layout> >::value,
- "");
-static_assert(
- !std::__is_replaceable<
- std::__split_buffer<int, NonPropagatingStatefulCopyAssignAlloc<int>, std::__split_buffer_pointer_layout > >::
- value,
- "");
-static_assert(
- !std::__is_replaceable<
- std::__split_buffer<int, NonPropagatingStatefulMoveAssignAlloc<int>, std::__split_buffer_pointer_layout > >::
- value,
- "");
-static_assert(
- std::__is_replaceable<
- std::__split_buffer<int, NonPropagatingStatelessCopyAssignAlloc<int>, std::__split_buffer_pointer_layout > >::
- value,
- "");
-static_assert(
- std::__is_replaceable<
- std::__split_buffer<int, NonPropagatingStatelessMoveAssignAlloc<int>, std::__split_buffer_pointer_layout > >::
- value,
- "");
-
-static_assert(
- std::__is_replaceable<std::__split_buffer<int, std::allocator<int>, std::__split_buffer_size_layout> >::value, "");
-static_assert(std::__is_replaceable<std::__split_buffer<NotTriviallyCopyable,
- std::allocator<NotTriviallyCopyable>,
- std::__split_buffer_size_layout> >::value,
- "");
-static_assert(
- !std::__is_replaceable<
- std::__split_buffer<int, NonPropagatingStatefulCopyAssignAlloc<int>, std::__split_buffer_size_layout > >::value,
- "");
-static_assert(
- !std::__is_replaceable<
- std::__split_buffer<int, NonPropagatingStatefulMoveAssignAlloc<int>, std::__split_buffer_size_layout > >::value,
- "");
-static_assert(
- std::__is_replaceable<
- std::__split_buffer<int, NonPropagatingStatelessCopyAssignAlloc<int>, std::__split_buffer_size_layout > >::
- value,
- "");
-static_assert(
- std::__is_replaceable<
- std::__split_buffer<int, NonPropagatingStatelessMoveAssignAlloc<int>, std::__split_buffer_size_layout > >::
- value,
- "");
-
-// standard library types
-// ----------------------
-
-// array
-static_assert(std::__is_replaceable<std::array<int, 0> >::value, "");
-static_assert(std::__is_replaceable<std::array<NotTriviallyCopyable, 0> >::value, "");
-static_assert(std::__is_replaceable<std::array<std::unique_ptr<int>, 0> >::value, "");
-
-static_assert(std::__is_replaceable<std::array<int, 1> >::value, "");
-static_assert(!std::__is_replaceable<std::array<NotTriviallyCopyable, 1> >::value, "");
-static_assert(std::__is_replaceable<std::array<std::unique_ptr<int>, 1> >::value, "");
-
-// basic_string
-struct MyChar {
- char c;
-};
-template <class T>
-struct NotReplaceableCharTraits : constexpr_char_traits<T> {
- NotReplaceableCharTraits(const NotReplaceableCharTraits&);
- NotReplaceableCharTraits& operator=(const NotReplaceableCharTraits&);
- ~NotReplaceableCharTraits();
-};
-
-static_assert(std::__is_replaceable<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >::value,
- "");
-static_assert(
- std::__is_replaceable<std::basic_string<char, NotReplaceableCharTraits<char>, std::allocator<char> > >::value, "");
-static_assert(
- std::__is_replaceable<std::basic_string<MyChar, constexpr_char_traits<MyChar>, std::allocator<MyChar> > >::value,
- "");
-static_assert(!std::__is_replaceable<std::basic_string<char, std::char_traits<char>, test_allocator<char> > >::value,
- "");
-static_assert(!std::__is_replaceable<
- std::basic_string<char, std::char_traits<char>, NonReplaceableStatelessAlloc<char> > >::value,
- "");
-static_assert(std::__is_replaceable<
- std::basic_string<MyChar, NotReplaceableCharTraits<MyChar>, std::allocator<MyChar> > >::value,
- "");
-static_assert(
- !std::__is_replaceable<
- std::basic_string<char, std::char_traits<char>, NonPropagatingStatefulCopyAssignAlloc<char> > >::value,
- "");
-static_assert(
- !std::__is_replaceable<
- std::basic_string<char, std::char_traits<char>, NonPropagatingStatefulMoveAssignAlloc<char> > >::value,
- "");
-static_assert(
- std::__is_replaceable<
- std::basic_string<char, std::char_traits<char>, NonPropagatingStatelessCopyAssignAlloc<char> > >::value,
- "");
-static_assert(
- std::__is_replaceable<
- std::basic_string<char, std::char_traits<char>, NonPropagatingStatelessMoveAssignAlloc<char> > >::value,
- "");
-
-// deque
-static_assert(std::__is_replaceable<std::deque<int> >::value, "");
-static_assert(std::__is_replaceable<std::deque<NotTriviallyCopyable> >::value, "");
-static_assert(!std::__is_replaceable<std::deque<int, test_allocator<int> > >::value, "");
-static_assert(!std::__is_replaceable<std::deque<int, NonReplaceableStatelessAlloc<int> > >::value, "");
-static_assert(!std::__is_replaceable<std::deque<int, NonPropagatingStatefulCopyAssignAlloc<int> > >::value, "");
-static_assert(!std::__is_replaceable<std::deque<int, NonPropagatingStatefulMoveAssignAlloc<int> > >::value, "");
-static_assert(std::__is_replaceable<std::deque<int, NonPropagatingStatelessCopyAssignAlloc<int> > >::value, "");
-static_assert(std::__is_replaceable<std::deque<int, NonPropagatingStatelessMoveAssignAlloc<int> > >::value, "");
-
-// exception_ptr
-#ifndef _LIBCPP_ABI_MICROSOFT
-static_assert(std::__is_replaceable<std::exception_ptr>::value, "");
-#endif
-
-// expected
-#if TEST_STD_VER >= 23
-static_assert(std::__is_replaceable<std::expected<int, int> >::value);
-static_assert(!std::__is_replaceable<std::expected<CustomCopyAssignment, int>>::value);
-static_assert(!std::__is_replaceable<std::expected<int, CustomCopyAssignment>>::value);
-static_assert(!std::__is_replaceable<std::expected<CustomCopyAssignment, CustomCopyAssignment>>::value);
-#endif
-
-// locale
-#ifndef TEST_HAS_NO_LOCALIZATION
-static_assert(std::__is_replaceable<std::locale>::value, "");
-#endif
-
-// optional
-#if TEST_STD_VER >= 17
-static_assert(std::__is_replaceable<std::optional<int>>::value, "");
-static_assert(!std::__is_replaceable<std::optional<CustomCopyAssignment>>::value, "");
-#endif
-
-// pair
-static_assert(std::__is_replaceable<std::pair<int, int> >::value, "");
-static_assert(!std::__is_replaceable<std::pair<CustomCopyAssignment, int> >::value, "");
-static_assert(!std::__is_replaceable<std::pair<int, CustomCopyAssignment> >::value, "");
-static_assert(!std::__is_replaceable<std::pair<CustomCopyAssignment, CustomCopyAssignment> >::value, "");
-
-// shared_ptr
-static_assert(std::__is_replaceable<std::shared_ptr<int> >::value, "");
-
-// tuple
-#if TEST_STD_VER >= 11
-static_assert(std::__is_replaceable<std::tuple<> >::value, "");
-
-static_assert(std::__is_replaceable<std::tuple<int> >::value, "");
-static_assert(!std::__is_replaceable<std::tuple<CustomCopyAssignment> >::value, "");
-
-static_assert(std::__is_replaceable<std::tuple<int, int> >::value, "");
-static_assert(!std::__is_replaceable<std::tuple<CustomCopyAssignment, int> >::value, "");
-static_assert(!std::__is_replaceable<std::tuple<int, CustomCopyAssignment> >::value, "");
-static_assert(!std::__is_replaceable<std::tuple<CustomCopyAssignment, CustomCopyAssignment> >::value, "");
-#endif // TEST_STD_VER >= 11
-
-// unique_ptr
-struct NonReplaceableDeleter {
- NonReplaceableDeleter(const NonReplaceableDeleter&);
- NonReplaceableDeleter& operator=(const NonReplaceableDeleter&);
- ~NonReplaceableDeleter();
-
- template <class T>
- void operator()(T*);
-};
-
-struct NonReplaceablePointer {
- struct pointer {
- pointer(const pointer&);
- pointer& operator=(const pointer&);
- ~pointer();
- };
-
- template <class T>
- void operator()(T*);
-};
-
-static_assert(std::__is_replaceable<std::unique_ptr<int> >::value, "");
-static_assert(std::__is_replaceable<std::unique_ptr<CustomCopyAssignment> >::value, "");
-static_assert(std::__is_replaceable<std::unique_ptr<int[]> >::value, "");
-static_assert(!std::__is_replaceable<std::unique_ptr<int, NonReplaceableDeleter> >::value, "");
-static_assert(!std::__is_replaceable<std::unique_ptr<int[], NonReplaceableDeleter> >::value, "");
-static_assert(!std::__is_replaceable<std::unique_ptr<int, NonReplaceablePointer> >::value, "");
-static_assert(!std::__is_replaceable<std::unique_ptr<int[], NonReplaceablePointer> >::value, "");
-
-// variant
-#if TEST_STD_VER >= 17
-static_assert(std::__is_replaceable<std::variant<int> >::value, "");
-static_assert(!std::__is_replaceable<std::variant<CustomCopyAssignment> >::value, "");
-
-static_assert(std::__is_replaceable<std::variant<int, int> >::value, "");
-static_assert(!std::__is_replaceable<std::variant<CustomCopyAssignment, int> >::value, "");
-static_assert(!std::__is_replaceable<std::variant<int, CustomCopyAssignment> >::value, "");
-static_assert(!std::__is_replaceable<std::variant<CustomCopyAssignment, CustomCopyAssignment> >::value, "");
-#endif // TEST_STD_VER >= 17
-
-// vector
-static_assert(std::__is_replaceable<std::vector<int> >::value, "");
-static_assert(std::__is_replaceable<std::vector<CustomCopyAssignment> >::value, "");
-static_assert(!std::__is_replaceable<std::vector<int, test_allocator<int> > >::value, "");
-static_assert(!std::__is_replaceable<std::vector<int, NonReplaceableStatelessAlloc<int> > >::value, "");
-static_assert(!std::__is_replaceable<std::vector<int, NonPropagatingStatefulCopyAssignAlloc<int> > >::value, "");
-static_assert(!std::__is_replaceable<std::vector<int, NonPropagatingStatefulMoveAssignAlloc<int> > >::value, "");
-static_assert(std::__is_replaceable<std::vector<int, NonPropagatingStatelessCopyAssignAlloc<int> > >::value, "");
-static_assert(std::__is_replaceable<std::vector<int, NonPropagatingStatelessMoveAssignAlloc<int> > >::value, "");
-
-// weak_ptr
-static_assert(std::__is_replaceable<std::weak_ptr<CustomCopyAssignment> >::value, "");
-
-// TODO: Mark all the replaceable STL types as such
diff --git a/libcxx/test/libcxx/utilities/any/nodiscard.verify.cpp b/libcxx/test/libcxx/utilities/any/nodiscard.verify.cpp
new file mode 100644
index 0000000..13a67bd
--- /dev/null
+++ b/libcxx/test/libcxx/utilities/any/nodiscard.verify.cpp
@@ -0,0 +1,45 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++17
+
+// Check that functions are marked [[nodiscard]]
+
+#include <any>
+#include <utility>
+#include <vector>
+
+#include "test_macros.h"
+
+void test() {
+ std::any a{94};
+
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ a.has_value();
+#if !defined(TEST_HAS_NO_RTTI)
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ a.type();
+#endif
+
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::make_any<int>(82);
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::make_any<std::vector<int>>({94, 82, 50});
+
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::any_cast<const int&>(std::as_const(a));
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::any_cast<int&>(a);
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::any_cast<int&&>(std::move(a));
+
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::any_cast<int*>(&a);
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::any_cast<const int*>(&std::as_const(a));
+}
diff --git a/libcxx/test/libcxx/utilities/intseq/nodiscard.verify.cpp b/libcxx/test/libcxx/utilities/intseq/nodiscard.verify.cpp
new file mode 100644
index 0000000..4ca52ac
--- /dev/null
+++ b/libcxx/test/libcxx/utilities/intseq/nodiscard.verify.cpp
@@ -0,0 +1,21 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++14
+
+// <utility>
+
+// Check that functions are marked [[nodiscard]]
+
+#include <utility>
+
+void test() {
+ std::integer_sequence<int, 49, 82, 94> seq;
+
+ seq.size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+}
diff --git a/libcxx/test/libcxx/utilities/optional/optional.iterator/iterator.compile.pass.cpp b/libcxx/test/libcxx/utilities/optional/optional.iterator/iterator.compile.pass.cpp
index 3cdd755..b604579 100644
--- a/libcxx/test/libcxx/utilities/optional/optional.iterator/iterator.compile.pass.cpp
+++ b/libcxx/test/libcxx/utilities/optional/optional.iterator/iterator.compile.pass.cpp
@@ -23,8 +23,7 @@ concept has_iterator_aliases = requires {
static_assert(has_iterator_aliases<std::optional<int>>);
static_assert(has_iterator_aliases<std::optional<const int>>);
-
-// TODO: Uncomment these once P2988R12 is implemented, as they would be testing optional<T&>
-
-// static_assert(!has_iterator_aliases<std::optional<int (&)[]>>);
-// static_assert(!has_iterator_aliases<std::optional<void (&)(int, char)>>);
+static_assert(has_iterator_aliases<std::optional<int&>>);
+static_assert(has_iterator_aliases<std::optional<const int&>>);
+static_assert(!has_iterator_aliases<std::optional<int (&)[1]>>);
+static_assert(!has_iterator_aliases<std::optional<int (&)()>>);
diff --git a/libcxx/test/libcxx/utilities/optional/optional.object/optional.object.observe/value_or.compile.pass.cpp b/libcxx/test/libcxx/utilities/optional/optional.object/optional.object.observe/value_or.compile.pass.cpp
new file mode 100644
index 0000000..25df0dd
--- /dev/null
+++ b/libcxx/test/libcxx/utilities/optional/optional.object/optional.object.observe/value_or.compile.pass.cpp
@@ -0,0 +1,28 @@
+
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <optional>
+
+// template <class U> T optional<T>::value_or(U&&);
+
+#include <concepts>
+#include <optional>
+
+template <typename Opt, typename T>
+concept has_value_or = requires(Opt opt, T&& t) {
+ { opt.value_or(t) } -> std::same_as<T>;
+};
+
+static_assert(has_value_or<std::optional<int>, int>);
+static_assert(has_value_or<std::optional<int&>, int&>);
+static_assert(has_value_or<std::optional<const int&>, const int&>);
+static_assert(!has_value_or<std::optional<int (&)[1]>&&, int (&)[1]>);
+static_assert(!has_value_or<std::optional<int (&)()>&&, int (&)()>);
diff --git a/libcxx/test/libcxx/utilities/smartptr/nodiscard.verify.cpp b/libcxx/test/libcxx/utilities/smartptr/nodiscard.verify.cpp
new file mode 100644
index 0000000..6e713fe
--- /dev/null
+++ b/libcxx/test/libcxx/utilities/smartptr/nodiscard.verify.cpp
@@ -0,0 +1,165 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03
+
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX20_REMOVED_SHARED_PTR_UNIQUE -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS
+
+// <memory>
+
+// Check that functions are marked [[nodiscard]]
+
+#include <memory>
+#include <utility>
+
+#include "test_macros.h"
+
+void test() {
+ { // [unique.ptr]
+ std::unique_ptr<int> uPtr;
+
+ *uPtr; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ uPtr.get(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ uPtr.get_deleter(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ const std::unique_ptr<int> cuPtr;
+ cuPtr.get_deleter(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+#if TEST_STD_VER >= 14
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::make_unique<int>(94);
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::make_unique<int[]>(82);
+#endif
+#if TEST_STD_VER >= 20
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::make_unique_for_overwrite<int>();
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::make_unique_for_overwrite<int[]>(5);
+#endif
+
+ std::hash<std::unique_ptr<int>> hash;
+ hash(uPtr); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ }
+ { // [util.smartptr.weak.bad]
+ std::bad_weak_ptr bwp;
+
+ bwp.what(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ }
+ { // [util.sharedptr]
+ std::shared_ptr<int[]> sPtr;
+
+ sPtr.get(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ *sPtr; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sPtr.use_count(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sPtr.unique(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sPtr.owner_before(std::shared_ptr<int>());
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sPtr.owner_before(std::weak_ptr<int>());
+#if TEST_STD_VER >= 17
+ sPtr[0]; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+#endif
+
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::allocate_shared<int>(std::allocator<int>(), 5);
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::make_shared<int>();
+#if TEST_STD_VER >= 20
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::allocate_shared_for_overwrite<int>(std::allocator<int>());
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::make_shared_for_overwrite<int>();
+
+ // Bounded array variants
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::allocate_shared<int[5]>(std::allocator<int>());
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::allocate_shared<int[5]>(std::allocator<int>(), 5);
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::allocate_shared_for_overwrite<int[5]>(std::allocator<int>());
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::make_shared<int[5]>();
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::make_shared<int[5]>(94);
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::make_shared_for_overwrite<int[5]>();
+
+ // Unbounded array variants
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::allocate_shared<int[]>(std::allocator<int>(), 5);
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::allocate_shared<int[]>(std::allocator<int>(), 5, 94);
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::allocate_shared_for_overwrite<int[]>(std::allocator<int>(), 5);
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::make_shared<int[]>(5);
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::make_shared<int[]>(5, 82);
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::make_shared_for_overwrite<int[]>(5);
+#endif
+
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::static_pointer_cast<int[]>(sPtr);
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::static_pointer_cast<int[]>(std::move(sPtr));
+ class Empty {};
+ std::shared_ptr<Empty> dsPtr;
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::dynamic_pointer_cast<Empty>(dsPtr);
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::dynamic_pointer_cast<Empty>(std::move(dsPtr));
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::const_pointer_cast<int[]>(sPtr);
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::const_pointer_cast<int[]>(std::move(sPtr));
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::reinterpret_pointer_cast<int[]>(sPtr);
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::reinterpret_pointer_cast<int[]>(std::move(sPtr));
+#if !defined(TEST_HAS_NO_RTTI)
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::get_deleter<int[]>(sPtr);
+#endif
+
+ std::hash<std::shared_ptr<int[]>> hash;
+ hash(sPtr); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ }
+ { // [util.smartptr.weak]
+ std::weak_ptr<int> wPtr;
+
+ wPtr.use_count(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ wPtr.expired(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ wPtr.lock(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ wPtr.owner_before(std::weak_ptr<int>());
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ wPtr.owner_before(std::shared_ptr<int>());
+ }
+ { // [util.smartptr.enab]
+ class EnableShared : public std::enable_shared_from_this<EnableShared> {};
+ EnableShared es;
+ const EnableShared ces;
+
+ es.shared_from_this(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ces.shared_from_this(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+#if TEST_STD_VER >= 17
+ es.weak_from_this(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ces.weak_from_this(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+#endif
+ }
+#if TEST_STD_VER >= 23
+ { // [smartptr.adapt]
+ std::unique_ptr<int> uPtr;
+ // [inout.ptr]
+ std::inout_ptr(uPtr); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ // [out.ptr]
+ std::out_ptr(uPtr); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ }
+#endif
+}
diff --git a/libcxx/test/libcxx/utilities/template.bitset/nodiscard.verify.cpp b/libcxx/test/libcxx/utilities/template.bitset/nodiscard.verify.cpp
new file mode 100644
index 0000000..b13fafe
--- /dev/null
+++ b/libcxx/test/libcxx/utilities/template.bitset/nodiscard.verify.cpp
@@ -0,0 +1,61 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// <bitset>
+
+// Check that functions are marked [[nodiscard]]
+
+#include <bitset>
+
+#include "test_macros.h"
+#include "test_allocator.h"
+
+void test() {
+ std::bitset<11> bs;
+ const std::bitset<11> cbs;
+
+ // std::bitset<>::reference operator~() const noexcept;
+ ~bs[0]; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ ~bs; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ bs[0]; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cbs[0]; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ bs.to_ulong(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ bs.to_ullong(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ struct CharTraits : public std::char_traits<char> {};
+
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ bs.to_string<char, CharTraits, test_allocator<char> >();
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ bs.to_string<char, CharTraits>();
+#if !defined(TEST_HAS_NO_WIDE_CHARACTERS)
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ bs.to_string<wchar_t>();
+#endif
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ bs.to_string();
+
+ bs.count(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ bs.size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ bs.test(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ bs.all(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ bs.any(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ bs.none(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ bs << 1; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ bs >> 1; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ bs & bs; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ bs | bs; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ bs ^ bs; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ std::hash<std::bitset<11> > hash;
+
+ hash(bs); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+}
diff --git a/libcxx/test/selftest/dsl/dsl.sh.py b/libcxx/test/selftest/dsl/dsl.sh.py
index 93f351f..b8ee2ca 100644
--- a/libcxx/test/selftest/dsl/dsl.sh.py
+++ b/libcxx/test/selftest/dsl/dsl.sh.py
@@ -61,7 +61,7 @@ class SetupConfigs(unittest.TestCase):
self.litConfig = lit.LitConfig.LitConfig(
progname="lit",
path=[],
- quiet=False,
+ diagnostic_level="note",
useValgrind=False,
valgrindLeakCheck=False,
valgrindArgs=[],
diff --git a/libcxx/test/selftest/dsl/lit.local.cfg b/libcxx/test/selftest/dsl/lit.local.cfg
index dc6887a..73e1c4d 100644
--- a/libcxx/test/selftest/dsl/lit.local.cfg
+++ b/libcxx/test/selftest/dsl/lit.local.cfg
@@ -10,6 +10,6 @@
# within the test.
import base64, lit.util, pickle
-base64Encode = lambda s: lit.util.to_string(base64.b64encode(lit.util.to_bytes(s)))
+base64Encode = lambda s: base64.b64encode(s).decode("utf-8")
escapedSubstitutions = base64Encode(pickle.dumps(config.substitutions))
config.substitutions.append(("%{substitutions}", escapedSubstitutions))
diff --git a/libcxx/test/std/algorithms/alg.nonmodifying/alg.contains/ranges.contains_subrange.pass.cpp b/libcxx/test/std/algorithms/alg.nonmodifying/alg.contains/ranges.contains_subrange.pass.cpp
index 890ac23..8354894 100644
--- a/libcxx/test/std/algorithms/alg.nonmodifying/alg.contains/ranges.contains_subrange.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.nonmodifying/alg.contains/ranges.contains_subrange.pass.cpp
@@ -32,6 +32,7 @@
#include "almost_satisfies_types.h"
#include "test_iterators.h"
+#include "type_algorithms.h"
struct NotEqualityComparable {};
diff --git a/libcxx/test/std/algorithms/alg.nonmodifying/alg.count/count.pass.cpp b/libcxx/test/std/algorithms/alg.nonmodifying/alg.count/count.pass.cpp
index ffe3e0e..1561dcf 100644
--- a/libcxx/test/std/algorithms/alg.nonmodifying/alg.count/count.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.nonmodifying/alg.count/count.pass.cpp
@@ -19,6 +19,7 @@
#include <algorithm>
#include <cassert>
#include <cstddef>
+#include <cstdint>
#include <vector>
#include "sized_allocator.h"
diff --git a/libcxx/test/std/algorithms/alg.nonmodifying/alg.count/ranges.count.pass.cpp b/libcxx/test/std/algorithms/alg.nonmodifying/alg.count/ranges.count.pass.cpp
index 2c1346a..9d9d7ed 100644
--- a/libcxx/test/std/algorithms/alg.nonmodifying/alg.count/ranges.count.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.nonmodifying/alg.count/ranges.count.pass.cpp
@@ -26,6 +26,7 @@
#include <array>
#include <cassert>
#include <cstddef>
+#include <cstdint>
#include <ranges>
#include <vector>
diff --git a/libcxx/test/std/algorithms/alg.nonmodifying/alg.ends_with/ranges.ends_with.pass.cpp b/libcxx/test/std/algorithms/alg.nonmodifying/alg.ends_with/ranges.ends_with.pass.cpp
index 199e6a7..76c62ff 100644
--- a/libcxx/test/std/algorithms/alg.nonmodifying/alg.ends_with/ranges.ends_with.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.nonmodifying/alg.ends_with/ranges.ends_with.pass.cpp
@@ -25,8 +25,10 @@
#include <array>
#include <chrono>
#include <ranges>
+
#include "almost_satisfies_types.h"
#include "test_iterators.h"
+#include "type_algorithms.h"
using namespace std::chrono;
diff --git a/libcxx/test/std/algorithms/alg.nonmodifying/alg.starts_with/ranges.starts_with.pass.cpp b/libcxx/test/std/algorithms/alg.nonmodifying/alg.starts_with/ranges.starts_with.pass.cpp
index 0f2284e..172fa82 100644
--- a/libcxx/test/std/algorithms/alg.nonmodifying/alg.starts_with/ranges.starts_with.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.nonmodifying/alg.starts_with/ranges.starts_with.pass.cpp
@@ -27,6 +27,7 @@
#include "almost_satisfies_types.h"
#include "test_iterators.h"
+#include "type_algorithms.h"
template <class Iter1, class Sent1 = Iter1, class Iter2 = int*, class Sent2 = Iter2>
concept HasStartsWithIt = requires(Iter1 first1, Sent1 last1, Iter2 first2, Sent2 last2) {
diff --git a/libcxx/test/std/algorithms/alg.sorting/alg.partitions/pstl.is_partitioned.pass.cpp b/libcxx/test/std/algorithms/alg.sorting/alg.partitions/pstl.is_partitioned.pass.cpp
index a80e2f6..b64242d 100644
--- a/libcxx/test/std/algorithms/alg.sorting/alg.partitions/pstl.is_partitioned.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.sorting/alg.partitions/pstl.is_partitioned.pass.cpp
@@ -20,6 +20,7 @@
#include "test_iterators.h"
#include "test_execution_policies.h"
+#include "type_algorithms.h"
template <class Iter>
struct Test {
diff --git a/libcxx/test/std/algorithms/robust_against_nonbool.compile.pass.cpp b/libcxx/test/std/algorithms/robust_against_nonbool.compile.pass.cpp
new file mode 100644
index 0000000..e7c32d2
--- /dev/null
+++ b/libcxx/test/std/algorithms/robust_against_nonbool.compile.pass.cpp
@@ -0,0 +1,136 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// <algorithm>
+//
+// Algorithms that take predicates should support predicates that return a non-boolean value as long as the
+// returned type is implicitly convertible to bool.
+
+#include <algorithm>
+
+#include <initializer_list>
+
+#include "boolean_testable.h"
+
+using Value = StrictComparable<int>;
+using Iterator = StrictBooleanIterator<Value*>;
+auto pred1 = StrictUnaryPredicate;
+auto pred2 = StrictBinaryPredicate;
+
+void f(Iterator it, Iterator out, std::size_t n, Value const& val, std::initializer_list<Value> ilist) {
+ (void)std::any_of(it, it, pred1);
+ (void)std::all_of(it, it, pred1);
+ (void)std::none_of(it, it, pred1);
+ (void)std::find_if(it, it, pred1);
+ (void)std::find_if_not(it, it, pred1);
+ (void)std::find_first_of(it, it, it, it);
+ (void)std::find_first_of(it, it, it, it, pred2);
+ (void)std::adjacent_find(it, it);
+ (void)std::adjacent_find(it, it, pred2);
+ (void)std::mismatch(it, it, it, it);
+ (void)std::mismatch(it, it, it, it, pred2);
+ (void)std::mismatch(it, it, it);
+ (void)std::mismatch(it, it, it);
+ (void)std::mismatch(it, it, it, pred2);
+ (void)std::equal(it, it, it, it);
+ (void)std::equal(it, it, it, it, pred2);
+ (void)std::equal(it, it, it);
+ (void)std::equal(it, it, it, pred2);
+ (void)std::lexicographical_compare(it, it, it, it);
+ (void)std::lexicographical_compare(it, it, it, it, pred2);
+ (void)std::partition_point(it, it, pred1);
+ (void)std::lower_bound(it, it, val);
+ (void)std::lower_bound(it, it, val, pred2);
+ (void)std::upper_bound(it, it, val);
+ (void)std::upper_bound(it, it, val, pred2);
+ (void)std::equal_range(it, it, val);
+ (void)std::equal_range(it, it, val, pred2);
+ (void)std::binary_search(it, it, val);
+ (void)std::binary_search(it, it, val, pred2);
+ (void)std::min(val, val);
+ (void)std::min(val, val, pred2);
+ (void)std::min(ilist);
+ (void)std::min(ilist, pred2);
+ (void)std::max(val, val);
+ (void)std::max(val, val, pred2);
+ (void)std::max(ilist);
+ (void)std::max(ilist, pred2);
+ (void)std::minmax(val, val);
+ (void)std::minmax(val, val, pred2);
+ (void)std::minmax(ilist);
+ (void)std::minmax(ilist, pred2);
+ (void)std::min_element(it, it);
+ (void)std::min_element(it, it, pred2);
+ (void)std::max_element(it, it);
+ (void)std::max_element(it, it, pred2);
+ (void)std::minmax_element(it, it);
+ (void)std::minmax_element(it, it, pred2);
+ (void)std::count_if(it, it, pred1);
+ (void)std::search(it, it, it, it);
+ (void)std::search(it, it, it, it, pred2);
+ (void)std::search_n(it, it, n, val);
+ (void)std::search_n(it, it, n, val, pred2);
+ (void)std::is_partitioned(it, it, pred1);
+ (void)std::is_sorted(it, it);
+ (void)std::is_sorted(it, it, pred2);
+ (void)std::is_sorted_until(it, it);
+ (void)std::is_sorted_until(it, it, pred2);
+ (void)std::is_heap(it, it);
+ (void)std::is_heap(it, it, pred2);
+ (void)std::is_heap_until(it, it);
+ (void)std::is_heap_until(it, it, pred2);
+ (void)std::clamp(val, val, val);
+ (void)std::clamp(val, val, val, pred2);
+ (void)std::is_permutation(it, it, it, it);
+ (void)std::is_permutation(it, it, it, it, pred2);
+ (void)std::copy_if(it, it, out, pred1);
+ (void)std::remove_copy_if(it, it, out, pred1);
+ (void)std::remove_copy(it, it, out, val);
+ (void)std::replace(it, it, val, val);
+ (void)std::replace_if(it, it, pred1, val);
+ (void)std::replace_copy_if(it, it, out, pred1, val);
+ (void)std::replace_copy(it, it, out, val, val);
+ (void)std::unique_copy(it, it, out, pred2);
+ (void)std::partition_copy(it, it, out, out, pred1);
+ (void)std::partial_sort_copy(it, it, it, it, pred2);
+ (void)std::merge(it, it, it, it, out);
+ (void)std::merge(it, it, it, it, out, pred2);
+ (void)std::set_difference(it, it, it, it, out, pred2);
+ (void)std::set_intersection(it, it, it, it, out, pred2);
+ (void)std::set_symmetric_difference(it, it, it, it, out, pred2);
+ (void)std::set_union(it, it, it, it, out, pred2);
+ (void)std::remove_if(it, it, pred1);
+ (void)std::remove(it, it, val);
+ (void)std::unique(it, it, pred2);
+ (void)std::partition(it, it, pred1);
+ (void)std::stable_partition(it, it, pred1);
+ (void)std::sort(it, it);
+ (void)std::sort(it, it, pred2);
+ (void)std::stable_sort(it, it);
+ (void)std::stable_sort(it, it, pred2);
+ (void)std::partial_sort(it, it, it);
+ (void)std::partial_sort(it, it, it, pred2);
+ (void)std::nth_element(it, it, it);
+ (void)std::nth_element(it, it, it, pred2);
+ (void)std::inplace_merge(it, it, it);
+ (void)std::inplace_merge(it, it, it, pred2);
+ (void)std::make_heap(it, it);
+ (void)std::make_heap(it, it, pred2);
+ (void)std::push_heap(it, it);
+ (void)std::push_heap(it, it, pred2);
+ (void)std::pop_heap(it, it);
+ (void)std::pop_heap(it, it, pred2);
+ (void)std::sort_heap(it, it);
+ (void)std::sort_heap(it, it, pred2);
+ (void)std::prev_permutation(it, it);
+ (void)std::prev_permutation(it, it, pred2);
+ (void)std::next_permutation(it, it);
+ (void)std::next_permutation(it, it, pred2);
+}
diff --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.wait/lost_wakeup.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.wait/lost_wakeup.pass.cpp
new file mode 100644
index 0000000..17ad72d
--- /dev/null
+++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.wait/lost_wakeup.pass.cpp
@@ -0,0 +1,57 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: no-threads
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// This is a stress test for std::atomic::wait for lost wake ups.
+
+// <atomic>
+
+#include <atomic>
+#include <functional>
+#include <thread>
+#include <vector>
+
+#include "make_test_thread.h"
+
+constexpr int num_waiters = 8;
+constexpr int num_iterations = 10'000;
+
+int main(int, char**) {
+ for (int run = 0; run < 20; ++run) {
+ std::atomic<int> waiter_ready(0);
+ std::atomic<int> state(0);
+
+ auto wait = [&]() {
+ for (int i = 0; i < num_iterations; ++i) {
+ auto old_state = state.load();
+ waiter_ready.fetch_add(1);
+ state.wait(old_state);
+ }
+ };
+
+ auto notify = [&] {
+ for (int i = 0; i < num_iterations; ++i) {
+ while (waiter_ready.load() < num_waiters) {
+ }
+ waiter_ready.store(0);
+ state.fetch_add(1);
+ state.notify_all();
+ }
+ };
+
+ std::vector<std::jthread> threads;
+ for (int i = 0; i < num_waiters; ++i)
+ threads.push_back(support::make_test_jthread(wait));
+
+ threads.push_back(support::make_test_jthread(notify));
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/std/containers/associative/map/map.cons/dtor_noexcept.pass.cpp b/libcxx/test/std/containers/associative/map/map.cons/dtor_noexcept.pass.cpp
index 8497b94..c9f7f28 100644
--- a/libcxx/test/std/containers/associative/map/map.cons/dtor_noexcept.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.cons/dtor_noexcept.pass.cpp
@@ -12,8 +12,9 @@
// UNSUPPORTED: c++03
-#include <map>
#include <cassert>
+#include <map>
+#include <type_traits>
#include "test_macros.h"
#include "MoveOnly.h"
diff --git a/libcxx/test/std/containers/associative/multimap/multimap.cons/dtor_noexcept.pass.cpp b/libcxx/test/std/containers/associative/multimap/multimap.cons/dtor_noexcept.pass.cpp
index 62afae92..c757bef 100644
--- a/libcxx/test/std/containers/associative/multimap/multimap.cons/dtor_noexcept.pass.cpp
+++ b/libcxx/test/std/containers/associative/multimap/multimap.cons/dtor_noexcept.pass.cpp
@@ -12,8 +12,9 @@
// UNSUPPORTED: c++03
-#include <map>
#include <cassert>
+#include <map>
+#include <type_traits>
#include "test_macros.h"
#include "MoveOnly.h"
diff --git a/libcxx/test/std/containers/associative/multiset/multiset.cons/dtor_noexcept.pass.cpp b/libcxx/test/std/containers/associative/multiset/multiset.cons/dtor_noexcept.pass.cpp
index 987eca0..bf5d256 100644
--- a/libcxx/test/std/containers/associative/multiset/multiset.cons/dtor_noexcept.pass.cpp
+++ b/libcxx/test/std/containers/associative/multiset/multiset.cons/dtor_noexcept.pass.cpp
@@ -12,8 +12,9 @@
// UNSUPPORTED: c++03
-#include <set>
#include <cassert>
+#include <set>
+#include <type_traits>
#include "test_macros.h"
#include "MoveOnly.h"
diff --git a/libcxx/test/std/containers/associative/set/set.cons/dtor_noexcept.pass.cpp b/libcxx/test/std/containers/associative/set/set.cons/dtor_noexcept.pass.cpp
index 63c0433..a382ce6 100644
--- a/libcxx/test/std/containers/associative/set/set.cons/dtor_noexcept.pass.cpp
+++ b/libcxx/test/std/containers/associative/set/set.cons/dtor_noexcept.pass.cpp
@@ -12,8 +12,9 @@
// UNSUPPORTED: c++03
-#include <set>
#include <cassert>
+#include <set>
+#include <type_traits>
#include "test_macros.h"
#include "MoveOnly.h"
diff --git a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.access/index_transparent.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.access/index_transparent.pass.cpp
index e8ea20b..9862936 100644
--- a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.access/index_transparent.pass.cpp
+++ b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.access/index_transparent.pass.cpp
@@ -97,7 +97,7 @@ constexpr bool test() {
TransparentComparator c(transparent_used);
std::flat_map<int, int, TransparentComparator> m(std::sorted_unique, {{1, 1}, {2, 2}, {3, 3}}, c);
assert(!transparent_used);
- m[ConvertibleTransparent<int>{3}];
+ (void)m[ConvertibleTransparent<int>{3}];
assert(transparent_used);
}
{
diff --git a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/copy_assign.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/copy_assign.pass.cpp
index 8aa2e7b..56231b8 100644
--- a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/copy_assign.pass.cpp
+++ b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/copy_assign.pass.cpp
@@ -12,6 +12,7 @@
// flat_map& operator=(const flat_map& m);
+#include <cassert>
#include <deque>
#include <flat_map>
#include <functional>
@@ -28,8 +29,8 @@ constexpr void test() {
// test_allocator is not propagated
using C = test_less<int>;
KeyContainer<int, test_allocator<int>> ks({1, 3, 5}, test_allocator<int>(6));
- ValueContainer<char, test_allocator<char>> vs({2, 2, 1}, test_allocator<char>(7));
- using M = std::flat_map<int, char, C, decltype(ks), decltype(vs)>;
+ ValueContainer<long, test_allocator<long>> vs({2, 2, 1}, test_allocator<long>(7));
+ using M = std::flat_map<int, long, C, decltype(ks), decltype(vs)>;
auto mo = M(ks, vs, C(5));
auto m = M({{3, 3}, {4, 4}, {5, 5}}, C(3), test_allocator<int>(2));
m = mo;
@@ -38,23 +39,23 @@ constexpr void test() {
assert(m.keys() == ks);
assert(m.values() == vs);
assert(m.keys().get_allocator() == test_allocator<int>(2));
- assert(m.values().get_allocator() == test_allocator<char>(2));
+ assert(m.values().get_allocator() == test_allocator<long>(2));
// mo is unchanged
assert(mo.key_comp() == C(5));
assert(mo.keys() == ks);
assert(mo.values() == vs);
assert(mo.keys().get_allocator() == test_allocator<int>(6));
- assert(mo.values().get_allocator() == test_allocator<char>(7));
+ assert(mo.values().get_allocator() == test_allocator<long>(7));
}
{
// other_allocator is propagated
using C = test_less<int>;
using Ks = KeyContainer<int, other_allocator<int>>;
- using Vs = ValueContainer<char, other_allocator<char>>;
+ using Vs = ValueContainer<long, other_allocator<long>>;
auto ks = Ks({1, 3, 5}, other_allocator<int>(6));
- auto vs = Vs({2, 2, 1}, other_allocator<char>(7));
- using M = std::flat_map<int, char, C, Ks, Vs>;
+ auto vs = Vs({2, 2, 1}, other_allocator<long>(7));
+ using M = std::flat_map<int, long, C, Ks, Vs>;
auto mo = M(Ks(ks, other_allocator<int>(6)), Vs(vs, other_allocator<int>(7)), C(5));
auto m = M({{3, 3}, {4, 4}, {5, 5}}, C(3), other_allocator<int>(2));
m = mo;
@@ -63,14 +64,14 @@ constexpr void test() {
assert(m.keys() == ks);
assert(m.values() == vs);
assert(m.keys().get_allocator() == other_allocator<int>(6));
- assert(m.values().get_allocator() == other_allocator<char>(7));
+ assert(m.values().get_allocator() == other_allocator<long>(7));
// mo is unchanged
assert(mo.key_comp() == C(5));
assert(mo.keys() == ks);
assert(mo.values() == vs);
assert(mo.keys().get_allocator() == other_allocator<int>(6));
- assert(mo.values().get_allocator() == other_allocator<char>(7));
+ assert(mo.values().get_allocator() == other_allocator<long>(7));
}
if (!TEST_IS_CONSTANT_EVALUATED) {
// comparator is copied and invariant is preserved
diff --git a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/deduct.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/deduct.pass.cpp
index 21166361..7998bef 100644
--- a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/deduct.pass.cpp
+++ b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/deduct.pass.cpp
@@ -33,19 +33,19 @@ using PC = std::pair<const int, long>;
void test_copy() {
{
- std::flat_map<long, short> source = {{1, 2}, {2, 3}};
+ std::flat_map<long, int> source = {{1, 2}, {2, 3}};
std::flat_map s(source);
ASSERT_SAME_TYPE(decltype(s), decltype(source));
assert(s == source);
}
{
- std::flat_map<long, short, std::greater<long>> source = {{1, 2}, {2, 3}};
+ std::flat_map<long, int, std::greater<long>> source = {{1, 2}, {2, 3}};
std::flat_map s{source}; // braces instead of parens
ASSERT_SAME_TYPE(decltype(s), decltype(source));
assert(s == source);
}
{
- std::flat_map<long, short, std::greater<long>> source = {{1, 2}, {2, 3}};
+ std::flat_map<long, int, std::greater<long>> source = {{1, 2}, {2, 3}};
std::flat_map s(source, std::allocator<int>());
ASSERT_SAME_TYPE(decltype(s), decltype(source));
assert(s == source);
@@ -54,14 +54,14 @@ void test_copy() {
void test_containers() {
std::deque<int, test_allocator<int>> ks({1, 2, 1, INT_MAX, 3}, test_allocator<int>(0, 42));
- std::deque<short, test_allocator<short>> vs({1, 2, 1, 4, 5}, test_allocator<int>(0, 43));
+ std::deque<long, test_allocator<long>> vs({1, 2, 1, 4, 5}, test_allocator<int>(0, 43));
std::deque<int, test_allocator<int>> sorted_ks({1, 2, 3, INT_MAX}, test_allocator<int>(0, 42));
- std::deque<short, test_allocator<short>> sorted_vs({1, 2, 5, 4}, test_allocator<int>(0, 43));
- const std::pair<int, short> expected[] = {{1, 1}, {2, 2}, {3, 5}, {INT_MAX, 4}};
+ std::deque<long, test_allocator<long>> sorted_vs({1, 2, 5, 4}, test_allocator<int>(0, 43));
+ const std::pair<int, long> expected[] = {{1, 1}, {2, 2}, {3, 5}, {INT_MAX, 4}};
{
std::flat_map s(ks, vs);
- ASSERT_SAME_TYPE(decltype(s), std::flat_map<int, short, std::less<int>, decltype(ks), decltype(vs)>);
+ ASSERT_SAME_TYPE(decltype(s), std::flat_map<int, long, std::less<int>, decltype(ks), decltype(vs)>);
assert(std::ranges::equal(s, expected));
assert(s.keys().get_allocator().get_id() == 42);
assert(s.values().get_allocator().get_id() == 43);
@@ -69,7 +69,7 @@ void test_containers() {
{
std::flat_map s(std::sorted_unique, sorted_ks, sorted_vs);
- ASSERT_SAME_TYPE(decltype(s), std::flat_map<int, short, std::less<int>, decltype(ks), decltype(vs)>);
+ ASSERT_SAME_TYPE(decltype(s), std::flat_map<int, long, std::less<int>, decltype(ks), decltype(vs)>);
assert(std::ranges::equal(s, expected));
assert(s.keys().get_allocator().get_id() == 42);
assert(s.values().get_allocator().get_id() == 43);
@@ -77,7 +77,7 @@ void test_containers() {
{
std::flat_map s(ks, vs, test_allocator<long>(0, 44));
- ASSERT_SAME_TYPE(decltype(s), std::flat_map<int, short, std::less<int>, decltype(ks), decltype(vs)>);
+ ASSERT_SAME_TYPE(decltype(s), std::flat_map<int, long, std::less<int>, decltype(ks), decltype(vs)>);
assert(std::ranges::equal(s, expected));
assert(s.keys().get_allocator().get_id() == 44);
assert(s.values().get_allocator().get_id() == 44);
@@ -85,7 +85,7 @@ void test_containers() {
{
std::flat_map s(std::sorted_unique, sorted_ks, sorted_vs, test_allocator<long>(0, 44));
- ASSERT_SAME_TYPE(decltype(s), std::flat_map<int, short, std::less<int>, decltype(ks), decltype(vs)>);
+ ASSERT_SAME_TYPE(decltype(s), std::flat_map<int, long, std::less<int>, decltype(ks), decltype(vs)>);
assert(std::ranges::equal(s, expected));
assert(s.keys().get_allocator().get_id() == 44);
assert(s.values().get_allocator().get_id() == 44);
@@ -94,14 +94,14 @@ void test_containers() {
void test_containers_compare() {
std::deque<int, test_allocator<int>> ks({1, 2, 1, INT_MAX, 3}, test_allocator<int>(0, 42));
- std::deque<short, test_allocator<short>> vs({1, 2, 1, 4, 5}, test_allocator<int>(0, 43));
+ std::deque<long, test_allocator<long>> vs({1, 2, 1, 4, 5}, test_allocator<int>(0, 43));
std::deque<int, test_allocator<int>> sorted_ks({INT_MAX, 3, 2, 1}, test_allocator<int>(0, 42));
- std::deque<short, test_allocator<short>> sorted_vs({4, 5, 2, 1}, test_allocator<int>(0, 43));
- const std::pair<int, short> expected[] = {{INT_MAX, 4}, {3, 5}, {2, 2}, {1, 1}};
+ std::deque<long, test_allocator<long>> sorted_vs({4, 5, 2, 1}, test_allocator<int>(0, 43));
+ const std::pair<int, long> expected[] = {{INT_MAX, 4}, {3, 5}, {2, 2}, {1, 1}};
{
std::flat_map s(ks, vs, std::greater<int>());
- ASSERT_SAME_TYPE(decltype(s), std::flat_map<int, short, std::greater<int>, decltype(ks), decltype(vs)>);
+ ASSERT_SAME_TYPE(decltype(s), std::flat_map<int, long, std::greater<int>, decltype(ks), decltype(vs)>);
assert(std::ranges::equal(s, expected));
assert(s.keys().get_allocator().get_id() == 42);
assert(s.values().get_allocator().get_id() == 43);
@@ -109,7 +109,7 @@ void test_containers_compare() {
{
std::flat_map s(std::sorted_unique, sorted_ks, sorted_vs, std::greater<int>());
- ASSERT_SAME_TYPE(decltype(s), std::flat_map<int, short, std::greater<int>, decltype(ks), decltype(vs)>);
+ ASSERT_SAME_TYPE(decltype(s), std::flat_map<int, long, std::greater<int>, decltype(ks), decltype(vs)>);
assert(std::ranges::equal(s, expected));
assert(s.keys().get_allocator().get_id() == 42);
assert(s.values().get_allocator().get_id() == 43);
@@ -117,7 +117,7 @@ void test_containers_compare() {
{
std::flat_map s(ks, vs, std::greater<int>(), test_allocator<long>(0, 44));
- ASSERT_SAME_TYPE(decltype(s), std::flat_map<int, short, std::greater<int>, decltype(ks), decltype(vs)>);
+ ASSERT_SAME_TYPE(decltype(s), std::flat_map<int, long, std::greater<int>, decltype(ks), decltype(vs)>);
assert(std::ranges::equal(s, expected));
assert(s.keys().get_allocator().get_id() == 44);
assert(s.values().get_allocator().get_id() == 44);
@@ -125,7 +125,7 @@ void test_containers_compare() {
{
std::flat_map s(std::sorted_unique, sorted_ks, sorted_vs, std::greater<int>(), test_allocator<long>(0, 44));
- ASSERT_SAME_TYPE(decltype(s), std::flat_map<int, short, std::greater<int>, decltype(ks), decltype(vs)>);
+ ASSERT_SAME_TYPE(decltype(s), std::flat_map<int, long, std::greater<int>, decltype(ks), decltype(vs)>);
assert(std::ranges::equal(s, expected));
assert(s.keys().get_allocator().get_id() == 44);
assert(s.values().get_allocator().get_id() == 44);
@@ -280,11 +280,11 @@ void test_initializer_list_compare() {
}
void test_from_range() {
- std::list<std::pair<int, short>> r = {{1, 1}, {2, 2}, {1, 1}, {INT_MAX, 4}, {3, 5}};
- const std::pair<int, short> expected[] = {{1, 1}, {2, 2}, {3, 5}, {INT_MAX, 4}};
+ std::list<std::pair<int, long>> r = {{1, 1}, {2, 2}, {1, 1}, {INT_MAX, 4}, {3, 5}};
+ const std::pair<int, long> expected[] = {{1, 1}, {2, 2}, {3, 5}, {INT_MAX, 4}};
{
std::flat_map s(std::from_range, r);
- ASSERT_SAME_TYPE(decltype(s), std::flat_map<int, short, std::less<int>>);
+ ASSERT_SAME_TYPE(decltype(s), std::flat_map<int, long, std::less<int>>);
assert(std::ranges::equal(s, expected));
}
{
@@ -292,10 +292,10 @@ void test_from_range() {
ASSERT_SAME_TYPE(
decltype(s),
std::flat_map<int,
- short,
+ long,
std::less<int>,
std::vector<int, test_allocator<int>>,
- std::vector<short, test_allocator<short>>>);
+ std::vector<long, test_allocator<long>>>);
assert(std::ranges::equal(s, expected));
assert(s.keys().get_allocator().get_id() == 42);
assert(s.values().get_allocator().get_id() == 42);
@@ -303,11 +303,11 @@ void test_from_range() {
}
void test_from_range_compare() {
- std::list<std::pair<int, short>> r = {{1, 1}, {2, 2}, {1, 1}, {INT_MAX, 4}, {3, 5}};
- const std::pair<int, short> expected[] = {{INT_MAX, 4}, {3, 5}, {2, 2}, {1, 1}};
+ std::list<std::pair<int, long>> r = {{1, 1}, {2, 2}, {1, 1}, {INT_MAX, 4}, {3, 5}};
+ const std::pair<int, long> expected[] = {{INT_MAX, 4}, {3, 5}, {2, 2}, {1, 1}};
{
std::flat_map s(std::from_range, r, std::greater<int>());
- ASSERT_SAME_TYPE(decltype(s), std::flat_map<int, short, std::greater<int>>);
+ ASSERT_SAME_TYPE(decltype(s), std::flat_map<int, long, std::greater<int>>);
assert(std::ranges::equal(s, expected));
}
{
@@ -315,10 +315,10 @@ void test_from_range_compare() {
ASSERT_SAME_TYPE(
decltype(s),
std::flat_map<int,
- short,
+ long,
std::greater<int>,
std::vector<int, test_allocator<int>>,
- std::vector<short, test_allocator<short>>>);
+ std::vector<long, test_allocator<long>>>);
assert(std::ranges::equal(s, expected));
assert(s.keys().get_allocator().get_id() == 42);
assert(s.values().get_allocator().get_id() == 42);
diff --git a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/deduct_pmr.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/deduct_pmr.pass.cpp
index 11c18ac..97eeec4 100644
--- a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/deduct_pmr.pass.cpp
+++ b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/deduct_pmr.pass.cpp
@@ -32,19 +32,19 @@ using PC = std::pair<const int, long>;
void test_containers() {
std::deque<int, test_allocator<int>> ks({1, 2, 1, INT_MAX, 3}, test_allocator<int>(0, 42));
- std::deque<short, test_allocator<short>> vs({1, 2, 1, 4, 5}, test_allocator<int>(0, 43));
+ std::deque<long, test_allocator<long>> vs({1, 2, 1, 4, 5}, test_allocator<int>(0, 43));
std::deque<int, test_allocator<int>> sorted_ks({1, 2, 3, INT_MAX}, test_allocator<int>(0, 42));
- std::deque<short, test_allocator<short>> sorted_vs({1, 2, 5, 4}, test_allocator<int>(0, 43));
- const std::pair<int, short> expected[] = {{1, 1}, {2, 2}, {3, 5}, {INT_MAX, 4}};
+ std::deque<long, test_allocator<long>> sorted_vs({1, 2, 5, 4}, test_allocator<int>(0, 43));
+ const std::pair<int, long> expected[] = {{1, 1}, {2, 2}, {3, 5}, {INT_MAX, 4}};
{
std::pmr::monotonic_buffer_resource mr;
std::pmr::monotonic_buffer_resource mr2;
std::pmr::deque<int> pks(ks.begin(), ks.end(), &mr);
- std::pmr::deque<short> pvs(vs.begin(), vs.end(), &mr);
+ std::pmr::deque<long> pvs(vs.begin(), vs.end(), &mr);
std::flat_map s(std::move(pks), std::move(pvs), &mr2);
ASSERT_SAME_TYPE(
- decltype(s), std::flat_map<int, short, std::less<int>, std::pmr::deque<int>, std::pmr::deque<short>>);
+ decltype(s), std::flat_map<int, long, std::less<int>, std::pmr::deque<int>, std::pmr::deque<long>>);
assert(std::ranges::equal(s, expected));
assert(s.keys().get_allocator().resource() == &mr2);
assert(s.values().get_allocator().resource() == &mr2);
@@ -53,11 +53,11 @@ void test_containers() {
std::pmr::monotonic_buffer_resource mr;
std::pmr::monotonic_buffer_resource mr2;
std::pmr::deque<int> pks(sorted_ks.begin(), sorted_ks.end(), &mr);
- std::pmr::deque<short> pvs(sorted_vs.begin(), sorted_vs.end(), &mr);
+ std::pmr::deque<long> pvs(sorted_vs.begin(), sorted_vs.end(), &mr);
std::flat_map s(std::sorted_unique, std::move(pks), std::move(pvs), &mr2);
ASSERT_SAME_TYPE(
- decltype(s), std::flat_map<int, short, std::less<int>, std::pmr::deque<int>, std::pmr::deque<short>>);
+ decltype(s), std::flat_map<int, long, std::less<int>, std::pmr::deque<int>, std::pmr::deque<long>>);
assert(std::ranges::equal(s, expected));
assert(s.keys().get_allocator().resource() == &mr2);
assert(s.values().get_allocator().resource() == &mr2);
@@ -66,19 +66,19 @@ void test_containers() {
void test_containers_compare() {
std::deque<int, test_allocator<int>> ks({1, 2, 1, INT_MAX, 3}, test_allocator<int>(0, 42));
- std::deque<short, test_allocator<short>> vs({1, 2, 1, 4, 5}, test_allocator<int>(0, 43));
+ std::deque<long, test_allocator<long>> vs({1, 2, 1, 4, 5}, test_allocator<int>(0, 43));
std::deque<int, test_allocator<int>> sorted_ks({INT_MAX, 3, 2, 1}, test_allocator<int>(0, 42));
- std::deque<short, test_allocator<short>> sorted_vs({4, 5, 2, 1}, test_allocator<int>(0, 43));
- const std::pair<int, short> expected[] = {{INT_MAX, 4}, {3, 5}, {2, 2}, {1, 1}};
+ std::deque<long, test_allocator<long>> sorted_vs({4, 5, 2, 1}, test_allocator<int>(0, 43));
+ const std::pair<int, long> expected[] = {{INT_MAX, 4}, {3, 5}, {2, 2}, {1, 1}};
{
std::pmr::monotonic_buffer_resource mr;
std::pmr::monotonic_buffer_resource mr2;
std::pmr::deque<int> pks(ks.begin(), ks.end(), &mr);
- std::pmr::deque<short> pvs(vs.begin(), vs.end(), &mr);
+ std::pmr::deque<long> pvs(vs.begin(), vs.end(), &mr);
std::flat_map s(std::move(pks), std::move(pvs), std::greater<int>(), &mr2);
ASSERT_SAME_TYPE(
- decltype(s), std::flat_map<int, short, std::greater<int>, std::pmr::deque<int>, std::pmr::deque<short>>);
+ decltype(s), std::flat_map<int, long, std::greater<int>, std::pmr::deque<int>, std::pmr::deque<long>>);
assert(std::ranges::equal(s, expected));
assert(s.keys().get_allocator().resource() == &mr2);
assert(s.values().get_allocator().resource() == &mr2);
@@ -87,11 +87,11 @@ void test_containers_compare() {
std::pmr::monotonic_buffer_resource mr;
std::pmr::monotonic_buffer_resource mr2;
std::pmr::deque<int> pks(sorted_ks.begin(), sorted_ks.end(), &mr);
- std::pmr::deque<short> pvs(sorted_vs.begin(), sorted_vs.end(), &mr);
+ std::pmr::deque<long> pvs(sorted_vs.begin(), sorted_vs.end(), &mr);
std::flat_map s(std::sorted_unique, std::move(pks), std::move(pvs), std::greater<int>(), &mr2);
ASSERT_SAME_TYPE(
- decltype(s), std::flat_map<int, short, std::greater<int>, std::pmr::deque<int>, std::pmr::deque<short>>);
+ decltype(s), std::flat_map<int, long, std::greater<int>, std::pmr::deque<int>, std::pmr::deque<long>>);
assert(std::ranges::equal(s, expected));
assert(s.keys().get_allocator().resource() == &mr2);
assert(s.values().get_allocator().resource() == &mr2);
diff --git a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/dtor_noexcept.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/dtor_noexcept.pass.cpp
index 4562b01..9e81984 100644
--- a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/dtor_noexcept.pass.cpp
+++ b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/dtor_noexcept.pass.cpp
@@ -17,6 +17,7 @@
#include <flat_map>
#include <functional>
#include <vector>
+#include <type_traits>
#include "test_macros.h"
#include "MoveOnly.h"
diff --git a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/initializer_list.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/initializer_list.pass.cpp
index aea2002..ef49a6e 100644
--- a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/initializer_list.pass.cpp
+++ b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/initializer_list.pass.cpp
@@ -37,24 +37,24 @@ struct DefaultCtableComp {
template <template <class...> class KeyContainer, template <class...> class ValueContainer>
constexpr void test() {
- std::pair<int, short> expected[] = {{1, 1}, {2, 2}, {3, 3}, {5, 2}};
+ std::pair<int, long> expected[] = {{1, 1}, {2, 2}, {3, 3}, {5, 2}};
{
// flat_map(initializer_list<value_type>);
- using M = std::flat_map<int, short>;
- std::initializer_list<std::pair<int, short>> il = {{5, 2}, {2, 2}, {2, 2}, {3, 3}, {1, 1}, {3, 3}};
+ using M = std::flat_map<int, long>;
+ std::initializer_list<std::pair<int, long>> il = {{5, 2}, {2, 2}, {2, 2}, {3, 3}, {1, 1}, {3, 3}};
M m(il);
assert(std::equal(m.begin(), m.end(), expected, expected + 4));
}
{
// flat_map(initializer_list<value_type>);
// explicit(false)
- using M = std::flat_map<int, short>;
+ using M = std::flat_map<int, long>;
M m = {{5, 2}, {2, 2}, {2, 2}, {3, 3}, {1, 1}, {3, 3}};
assert(std::equal(m.begin(), m.end(), expected, expected + 4));
}
{
// flat_map(initializer_list<value_type>);
- using M = std::flat_map<int, short, std::greater<int>, KeyContainer<int, min_allocator<int>>>;
+ using M = std::flat_map<int, long, std::greater<int>, KeyContainer<int, min_allocator<int>>>;
M m = {{5, 2}, {2, 2}, {2, 2}, {3, 3}, {1, 1}, {3, 3}};
assert(std::equal(m.rbegin(), m.rend(), expected, expected + 4));
}
@@ -79,7 +79,7 @@ constexpr void test() {
{
// flat_map(initializer_list<value_type>, const key_compare&);
using C = test_less<int>;
- using M = std::flat_map<int, short, C>;
+ using M = std::flat_map<int, long, C>;
auto m = M({{5, 2}, {2, 2}, {2, 2}, {3, 3}, {1, 1}, {3, 3}}, C(10));
assert(std::equal(m.begin(), m.end(), expected, expected + 4));
assert(m.key_comp() == C(10));
@@ -92,7 +92,7 @@ constexpr void test() {
if (!TEST_IS_CONSTANT_EVALUATED) {
// flat_map(initializer_list<value_type>, const key_compare&);
// Sorting uses the comparator that was passed in
- using M = std::flat_map<int, short, std::function<bool(int, int)>, KeyContainer<int, min_allocator<int>>>;
+ using M = std::flat_map<int, long, std::function<bool(int, int)>, KeyContainer<int, min_allocator<int>>>;
auto m = M({{5, 2}, {2, 2}, {2, 2}, {3, 3}, {1, 1}, {3, 3}}, std::greater<int>());
assert(std::equal(m.rbegin(), m.rend(), expected, expected + 4));
assert(m.key_comp()(2, 1) == true);
diff --git a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/iter_iter.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/iter_iter.pass.cpp
index 0dce4f1..cb6d187 100644
--- a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/iter_iter.pass.cpp
+++ b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/iter_iter.pass.cpp
@@ -101,19 +101,19 @@ constexpr void test() {
template <template <class...> class KeyContainer, template <class...> class ValueContainer>
constexpr void test_alloc() {
- using P = std::pair<int, short>;
+ using P = std::pair<int, long>;
P ar[] = {{1, 1}, {1, 2}, {1, 3}, {2, 4}, {2, 5}, {3, 6}, {2, 7}, {3, 8}, {3, 9}};
{
// flat_map(InputIterator , InputIterator, const Allocator&)
using A1 = test_allocator<int>;
- using A2 = test_allocator<short>;
- using M = std::flat_map<int, short, std::less<int>, KeyContainer<int, A1>, ValueContainer<short, A2>>;
+ using A2 = test_allocator<long>;
+ using M = std::flat_map<int, long, std::less<int>, KeyContainer<int, A1>, ValueContainer<long, A2>>;
auto m = M(ar, ar + 9, A1(5));
assert(std::ranges::equal(m.keys(), KeyContainer<int, A1>{1, 2, 3}));
check_possible_values(
m.values(),
- std::vector<std::vector<short>>{
+ std::vector<std::vector<long>>{
{1, 2, 3},
{4, 5, 7},
{6, 8, 9},
@@ -125,13 +125,13 @@ constexpr void test_alloc() {
// flat_map(InputIterator , InputIterator, const Allocator&)
// explicit(false)
using A1 = test_allocator<int>;
- using A2 = test_allocator<short>;
- using M = std::flat_map<int, short, std::less<int>, KeyContainer<int, A1>, ValueContainer<short, A2>>;
+ using A2 = test_allocator<long>;
+ using M = std::flat_map<int, long, std::less<int>, KeyContainer<int, A1>, ValueContainer<long, A2>>;
M m = {ar, ar + 9, A1(5)}; // implicit ctor
assert(std::ranges::equal(m.keys(), KeyContainer<int, A1>{1, 2, 3}));
check_possible_values(
m.values(),
- std::vector<std::vector<short>>{
+ std::vector<std::vector<long>>{
{1, 2, 3},
{4, 5, 7},
{6, 8, 9},
@@ -143,13 +143,13 @@ constexpr void test_alloc() {
// flat_map(InputIterator , InputIterator, const key_compare&, const Allocator&)
using C = test_less<int>;
using A1 = test_allocator<int>;
- using A2 = test_allocator<short>;
- using M = std::flat_map<int, short, C, KeyContainer<int, A1>, ValueContainer<short, A2>>;
+ using A2 = test_allocator<long>;
+ using M = std::flat_map<int, long, C, KeyContainer<int, A1>, ValueContainer<long, A2>>;
auto m = M(ar, ar + 9, C(3), A1(5));
assert(std::ranges::equal(m.keys(), KeyContainer<int, A1>{1, 2, 3}));
check_possible_values(
m.values(),
- std::vector<std::vector<short>>{
+ std::vector<std::vector<long>>{
{1, 2, 3},
{4, 5, 7},
{6, 8, 9},
@@ -162,13 +162,13 @@ constexpr void test_alloc() {
// flat_map(InputIterator , InputIterator, const key_compare&, const Allocator&)
// explicit(false)
using A1 = test_allocator<int>;
- using A2 = test_allocator<short>;
- using M = std::flat_map<int, short, std::less<int>, KeyContainer<int, A1>, ValueContainer<short, A2>>;
+ using A2 = test_allocator<long>;
+ using M = std::flat_map<int, long, std::less<int>, KeyContainer<int, A1>, ValueContainer<long, A2>>;
M m = {ar, ar + 9, {}, A2(5)}; // implicit ctor
assert(std::ranges::equal(m.keys(), KeyContainer<int, A1>{1, 2, 3}));
check_possible_values(
m.values(),
- std::vector<std::vector<short>>{
+ std::vector<std::vector<long>>{
{1, 2, 3},
{4, 5, 7},
{6, 8, 9},
diff --git a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/move_assign.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/move_assign.pass.cpp
index 633c73e..dc3c2e18 100644
--- a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/move_assign.pass.cpp
+++ b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/move_assign.pass.cpp
@@ -31,8 +31,8 @@ constexpr void test() {
{
using C = test_less<int>;
using A1 = test_allocator<int>;
- using A2 = test_allocator<char>;
- using M = std::flat_map<int, char, C, KeyContainer<int, A1>, ValueContainer<char, A2>>;
+ using A2 = test_allocator<long>;
+ using M = std::flat_map<int, long, C, KeyContainer<int, A1>, ValueContainer<long, A2>>;
M mo = M({{1, 1}, {2, 3}, {3, 2}}, C(5), A1(7));
M m = M({}, C(3), A1(7));
m = std::move(mo);
@@ -46,8 +46,8 @@ constexpr void test() {
{
using C = test_less<int>;
using A1 = other_allocator<int>;
- using A2 = other_allocator<char>;
- using M = std::flat_map<int, char, C, KeyContainer<int, A1>, ValueContainer<char, A2>>;
+ using A2 = other_allocator<long>;
+ using M = std::flat_map<int, long, C, KeyContainer<int, A1>, ValueContainer<long, A2>>;
M mo = M({{4, 5}, {5, 4}}, C(5), A1(7));
M m = M({{1, 1}, {2, 2}, {3, 3}, {4, 4}}, C(3), A1(7));
m = std::move(mo);
diff --git a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/pmr.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/pmr.pass.cpp
index 154af11..f3b9d4f 100644
--- a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/pmr.pass.cpp
+++ b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/pmr.pass.cpp
@@ -166,12 +166,12 @@ int main(int, char**) {
}
{
// flat_map(InputIterator first, InputIterator last, const Allocator& a);
- using P = std::pair<int, short>;
+ using P = std::pair<int, long>;
P ar[] = {{1, 1}, {1, 2}, {1, 3}, {2, 4}, {2, 5}, {3, 6}, {2, 7}, {3, 8}, {3, 9}};
P expected[] = {{1, 1}, {2, 4}, {3, 6}};
{
// cpp17 iterator
- using M = std::flat_map<int, short, std::less<int>, std::pmr::vector<int>, std::pmr::vector<short>>;
+ using M = std::flat_map<int, long, std::less<int>, std::pmr::vector<int>, std::pmr::vector<long>>;
std::pmr::monotonic_buffer_resource mr;
std::pmr::vector<M> vm(&mr);
vm.emplace_back(cpp17_input_iterator<const P*>(ar), cpp17_input_iterator<const P*>(ar + 9));
@@ -181,7 +181,7 @@ int main(int, char**) {
assert(vm[0].values().get_allocator().resource() == &mr);
}
{
- using M = std::flat_map<int, short, std::less<int>, std::pmr::vector<int>, std::pmr::vector<short>>;
+ using M = std::flat_map<int, long, std::less<int>, std::pmr::vector<int>, std::pmr::vector<long>>;
std::pmr::monotonic_buffer_resource mr;
std::pmr::vector<M> vm(&mr);
vm.emplace_back(ar, ar);
@@ -242,12 +242,12 @@ int main(int, char**) {
}
{
// flat_map(from_range_t, R&&, const Alloc&);
- using P = std::pair<int, short>;
+ using P = std::pair<int, long>;
P ar[] = {{1, 1}, {1, 2}, {1, 3}, {2, 4}, {2, 5}, {3, 6}, {2, 7}, {3, 8}, {3, 9}};
P expected[] = {{1, 1}, {2, 4}, {3, 6}};
{
// input_range
- using M = std::flat_map<int, short, std::less<int>, std::pmr::vector<int>, std::pmr::vector<short>>;
+ using M = std::flat_map<int, long, std::less<int>, std::pmr::vector<int>, std::pmr::vector<long>>;
using Iter = cpp20_input_iterator<const P*>;
using Sent = sentinel_wrapper<Iter>;
using R = std::ranges::subrange<Iter, Sent>;
@@ -260,7 +260,7 @@ int main(int, char**) {
assert(vm[0].values().get_allocator().resource() == &mr);
}
{
- using M = std::flat_map<int, short, std::less<int>, std::pmr::vector<int>, std::pmr::vector<short>>;
+ using M = std::flat_map<int, long, std::less<int>, std::pmr::vector<int>, std::pmr::vector<long>>;
using R = std::ranges::subrange<const P*>;
std::pmr::monotonic_buffer_resource mr;
std::pmr::vector<M> vm(&mr);
diff --git a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/range.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/range.pass.cpp
index 9f74873..5ac4f09 100644
--- a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/range.pass.cpp
+++ b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/range.pass.cpp
@@ -152,19 +152,19 @@ constexpr void test() {
template <template <class...> class KeyContainer, template <class...> class ValueContainer>
constexpr void test_alloc() {
- using P = std::pair<int, short>;
+ using P = std::pair<int, long>;
P ar[] = {{1, 1}, {1, 2}, {1, 3}, {2, 4}, {2, 5}, {3, 6}, {2, 7}, {3, 8}, {3, 9}};
{
// flat_map(from_range_t, R&&, const Allocator&)
using A1 = test_allocator<int>;
- using A2 = test_allocator<short>;
- using M = std::flat_map<int, short, std::less<int>, KeyContainer<int, A1>, ValueContainer<short, A2>>;
+ using A2 = test_allocator<long>;
+ using M = std::flat_map<int, long, std::less<int>, KeyContainer<int, A1>, ValueContainer<long, A2>>;
using R = std::ranges::subrange<const P*>;
auto m = M(std::from_range, R(ar, ar + 9), A1(5));
assert(std::ranges::equal(m.keys(), KeyContainer<int, A1>{1, 2, 3}));
check_possible_values(
m.values(),
- std::vector<std::vector<short>>{
+ std::vector<std::vector<long>>{
{1, 2, 3},
{4, 5, 7},
{6, 8, 9},
@@ -176,14 +176,14 @@ constexpr void test_alloc() {
// flat_map(from_range_t, R&&, const Allocator&)
// explicit(false)
using A1 = test_allocator<int>;
- using A2 = test_allocator<short>;
- using M = std::flat_map<int, short, std::less<int>, KeyContainer<int, A1>, ValueContainer<short, A2>>;
+ using A2 = test_allocator<long>;
+ using M = std::flat_map<int, long, std::less<int>, KeyContainer<int, A1>, ValueContainer<long, A2>>;
using R = std::ranges::subrange<const P*>;
M m = {std::from_range, R(ar, ar + 9), A1(5)}; // implicit ctor
assert(std::ranges::equal(m.keys(), KeyContainer<int, A1>{1, 2, 3}));
check_possible_values(
m.values(),
- std::vector<std::vector<short>>{
+ std::vector<std::vector<long>>{
{1, 2, 3},
{4, 5, 7},
{6, 8, 9},
@@ -195,14 +195,14 @@ constexpr void test_alloc() {
// flat_map(from_range_t, R&&, const key_compare&, const Allocator&)
using C = test_less<int>;
using A1 = test_allocator<int>;
- using A2 = test_allocator<short>;
- using M = std::flat_map<int, short, C, KeyContainer<int, A1>, ValueContainer<short, A2>>;
+ using A2 = test_allocator<long>;
+ using M = std::flat_map<int, long, C, KeyContainer<int, A1>, ValueContainer<long, A2>>;
using R = std::ranges::subrange<const P*>;
auto m = M(std::from_range, R(ar, ar + 9), C(3), A1(5));
assert(std::ranges::equal(m.keys(), KeyContainer<int, A1>{1, 2, 3}));
check_possible_values(
m.values(),
- std::vector<std::vector<short>>{
+ std::vector<std::vector<long>>{
{1, 2, 3},
{4, 5, 7},
{6, 8, 9},
@@ -215,14 +215,14 @@ constexpr void test_alloc() {
// flat_map(from_range_t, R&&, const key_compare&, const Allocator&)
// explicit(false)
using A1 = test_allocator<int>;
- using A2 = test_allocator<short>;
- using M = std::flat_map<int, short, std::less<int>, KeyContainer<int, A1>, ValueContainer<short, A2>>;
+ using A2 = test_allocator<long>;
+ using M = std::flat_map<int, long, std::less<int>, KeyContainer<int, A1>, ValueContainer<long, A2>>;
using R = std::ranges::subrange<const P*>;
M m = {std::from_range, R(ar, ar + 9), {}, A2(5)}; // implicit ctor
assert(std::ranges::equal(m.keys(), KeyContainer<int, A1>{1, 2, 3}));
check_possible_values(
m.values(),
- std::vector<std::vector<short>>{
+ std::vector<std::vector<long>>{
{1, 2, 3},
{4, 5, 7},
{6, 8, 9},
diff --git a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/sorted_container.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/sorted_container.pass.cpp
index 4c58359..b0e9c3a 100644
--- a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/sorted_container.pass.cpp
+++ b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/sorted_container.pass.cpp
@@ -38,9 +38,9 @@ template <template <class...> class KeyContainer, template <class...> class Valu
constexpr void test() {
{
// flat_map(sorted_unique_t, key_container_type , mapped_container_type)
- using M = std::flat_map<int, char, std::less<int>, KeyContainer<int>, ValueContainer<char>>;
+ using M = std::flat_map<int, long, std::less<int>, KeyContainer<int>, ValueContainer<long>>;
KeyContainer<int> ks = {1, 2, 4, 10};
- ValueContainer<char> vs = {4, 3, 2, 1};
+ ValueContainer<long> vs = {4, 3, 2, 1};
auto ks2 = ks;
auto vs2 = vs;
@@ -59,8 +59,8 @@ constexpr void test() {
// flat_map(sorted_unique_t, key_container_type , mapped_container_type)
// non-default container, comparator and allocator type
using Ks = KeyContainer<int, min_allocator<int>>;
- using Vs = ValueContainer<char, min_allocator<char>>;
- using M = std::flat_map<int, char, std::greater<int>, Ks, Vs>;
+ using Vs = ValueContainer<long, min_allocator<long>>;
+ using M = std::flat_map<int, long, std::greater<int>, Ks, Vs>;
Ks ks = {10, 4, 2, 1};
Vs vs = {1, 2, 3, 4};
auto m = M(std::sorted_unique, ks, vs);
@@ -87,9 +87,9 @@ constexpr void test() {
{
// flat_map(sorted_unique_t, key_container_type , mapped_container_type, key_compare)
using C = test_less<int>;
- using M = std::flat_map<int, char, C, KeyContainer<int>, ValueContainer<char>>;
+ using M = std::flat_map<int, long, C, KeyContainer<int>, ValueContainer<long>>;
KeyContainer<int> ks = {1, 2, 4, 10};
- ValueContainer<char> vs = {4, 3, 2, 1};
+ ValueContainer<long> vs = {4, 3, 2, 1};
auto m = M(std::sorted_unique, ks, vs, C(4));
assert((m == M{{1, 4}, {2, 3}, {4, 2}, {10, 1}}));
diff --git a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/sorted_initializer_list.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/sorted_initializer_list.pass.cpp
index e8ac5d3..4c1d48c 100644
--- a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/sorted_initializer_list.pass.cpp
+++ b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/sorted_initializer_list.pass.cpp
@@ -35,8 +35,8 @@ template <class T, class U>
constexpr std::initializer_list<std::pair<T, U>> il = {{1, 1}, {2, 2}, {4, 4}, {5, 5}};
constexpr auto il1 = il<int, int>;
-constexpr auto il2 = il<int, short>;
-constexpr auto il3 = il<short, int>;
+constexpr auto il2 = il<int, long>;
+constexpr auto il3 = il<long, int>;
template <template <class...> class KeyContainer, template <class...> class ValueContainer>
constexpr void test() {
@@ -73,8 +73,8 @@ constexpr void test() {
{
// flat_map(sorted_unique_t, initializer_list<value_type>, const Allocator&)
using A1 = test_allocator<int>;
- using A2 = test_allocator<short>;
- using M = std::flat_map<int, short, std::less<int>, KeyContainer<int, A1>, ValueContainer<short, A2>>;
+ using A2 = test_allocator<long>;
+ using M = std::flat_map<int, long, std::less<int>, KeyContainer<int, A1>, ValueContainer<long, A2>>;
auto m = M(std::sorted_unique, il2, A1(5));
auto expected = M{{1, 1}, {2, 2}, {4, 4}, {5, 5}};
assert(m == expected);
@@ -91,8 +91,8 @@ constexpr void test() {
// flat_map(sorted_unique_t, initializer_list<value_type>, const key_compare&, const Allocator&);
using C = test_less<int>;
using A1 = test_allocator<int>;
- using A2 = test_allocator<short>;
- using M = std::flat_map<int, short, C, KeyContainer<int, A1>, ValueContainer<short, A2>>;
+ using A2 = test_allocator<long>;
+ using M = std::flat_map<int, long, C, KeyContainer<int, A1>, ValueContainer<long, A2>>;
auto m = M(std::sorted_unique, il2, C(3), A1(5));
assert((m == M{{1, 1}, {2, 2}, {4, 4}, {5, 5}}));
assert(m.key_comp() == C(3));
@@ -102,9 +102,9 @@ constexpr void test() {
{
// flat_map(sorted_unique_t, initializer_list<value_type>, const key_compare&, const Allocator&);
// explicit(false)
- using A1 = test_allocator<short>;
+ using A1 = test_allocator<long>;
using A2 = test_allocator<int>;
- using M = std::flat_map<short, int, std::less<int>, KeyContainer<short, A1>, ValueContainer<int, A2>>;
+ using M = std::flat_map<long, int, std::less<int>, KeyContainer<long, A1>, ValueContainer<int, A2>>;
M m = {std::sorted_unique, il3, {}, A1(5)}; // implicit ctor
assert((m == M{{1, 1}, {2, 2}, {4, 4}, {5, 5}}));
assert(m.keys().get_allocator() == A1(5));
diff --git a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/sorted_iter_iter.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/sorted_iter_iter.pass.cpp
index f853a08..4825b6c 100644
--- a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/sorted_iter_iter.pass.cpp
+++ b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/sorted_iter_iter.pass.cpp
@@ -69,7 +69,7 @@ constexpr void test() {
auto m = M(std::sorted_unique,
cpp17_input_iterator<const P*>(ar),
cpp17_input_iterator<const P*>(ar + 4),
- std::less<int>());
+ std::less<Value>());
assert(m == M({{1, 1}, {2, 2}, {4, 4}, {5, 5}}, std::less<>()));
assert(m.key_comp()(1, 2) == true);
@@ -77,19 +77,19 @@ constexpr void test() {
M m2 = {std::sorted_unique,
cpp17_input_iterator<const P*>(ar),
cpp17_input_iterator<const P*>(ar + 4),
- std::less<int>()};
+ std::less<Value>()};
assert(m2 == m);
}
{
// flat_map(sorted_unique_t, InputIterator, InputIterator, const key_compare&);
// greater
- using M = std::flat_map<Key, Value, std::greater<int>, KeyContainer, ValueContainer>;
+ using M = std::flat_map<Key, Value, std::greater<Value>, KeyContainer, ValueContainer>;
using P = std::pair<Key, Value>;
P ar[] = {{5, 5}, {4, 4}, {2, 2}, {1, 1}};
auto m = M(std::sorted_unique,
cpp17_input_iterator<const P*>(ar),
cpp17_input_iterator<const P*>(ar + 4),
- std::greater<int>());
+ std::greater<Value>());
assert((m == M{{5, 5}, {4, 4}, {2, 2}, {1, 1}}));
}
{
@@ -109,8 +109,8 @@ constexpr void test_alloc() {
{
// flat_map(sorted_unique_t, InputIterator , InputIterator, const Allocator&)
using A1 = test_allocator<int>;
- using A2 = test_allocator<short>;
- using M = std::flat_map<int, short, std::less<int>, KeyContainer<int, A1>, ValueContainer<short, A2>>;
+ using A2 = test_allocator<long>;
+ using M = std::flat_map<int, long, std::less<int>, KeyContainer<int, A1>, ValueContainer<long, A2>>;
using P = std::pair<int, int>;
P ar[] = {{1, 1}, {2, 2}, {4, 4}, {5, 5}};
auto m = M(std::sorted_unique, ar, ar + 4, A1(5));
@@ -129,8 +129,8 @@ constexpr void test_alloc() {
// flat_map(sorted_unique_t, InputIterator, InputIterator, const key_compare&, const Allocator&);
using C = test_less<int>;
using A1 = test_allocator<int>;
- using A2 = test_allocator<short>;
- using M = std::flat_map<int, short, C, KeyContainer<int, A1>, ValueContainer<short, A2>>;
+ using A2 = test_allocator<long>;
+ using M = std::flat_map<int, long, C, KeyContainer<int, A1>, ValueContainer<long, A2>>;
using P = std::pair<int, int>;
P ar[] = {{1, 1}, {2, 2}, {4, 4}, {5, 5}};
auto m = M(std::sorted_unique, ar, ar + 4, C(3), A1(5));
@@ -142,9 +142,9 @@ constexpr void test_alloc() {
{
// flat_map(sorted_unique_t, InputIterator, InputIterator, const key_compare&, const Allocator&);
// explicit(false)
- using A1 = test_allocator<short>;
+ using A1 = test_allocator<long>;
using A2 = test_allocator<int>;
- using M = std::flat_map<short, int, std::less<int>, KeyContainer<short, A1>, ValueContainer<int, A2>>;
+ using M = std::flat_map<long, int, std::less<int>, KeyContainer<long, A1>, ValueContainer<int, A2>>;
using P = std::pair<int, int>;
P ar[] = {{1, 1}, {2, 2}, {4, 4}, {5, 5}};
M m = {std::sorted_unique, ar, ar + 4, {}, A1(5)}; // implicit ctor
diff --git a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.modifiers/erase_key.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.modifiers/erase_key.pass.cpp
index e4cce76..22638f7 100644
--- a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.modifiers/erase_key.pass.cpp
+++ b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.modifiers/erase_key.pass.cpp
@@ -27,7 +27,7 @@
template <class KeyContainer, class ValueContainer, class Compare = std::less<>>
constexpr void test() {
- using M = std::flat_map<int, char, Compare, KeyContainer, ValueContainer>;
+ using M = std::flat_map<int, long, Compare, KeyContainer, ValueContainer>;
auto make = [](std::initializer_list<int> il) {
M m;
@@ -71,17 +71,17 @@ constexpr void test() {
}
constexpr bool test() {
- test<std::vector<int>, std::vector<char>>();
- test<std::vector<int>, std::vector<char>, std::greater<>>();
+ test<std::vector<int>, std::vector<long>>();
+ test<std::vector<int>, std::vector<long>, std::greater<>>();
#ifndef __cpp_lib_constexpr_deque
if (!TEST_IS_CONSTANT_EVALUATED)
#endif
{
- test<std::deque<int>, std::vector<char>>();
+ test<std::deque<int>, std::vector<long>>();
}
- test<MinSequenceContainer<int>, MinSequenceContainer<char>>();
- test<std::vector<int, min_allocator<int>>, std::vector<char, min_allocator<char>>>();
+ test<MinSequenceContainer<int>, MinSequenceContainer<long>>();
+ test<std::vector<int, min_allocator<int>>, std::vector<long, min_allocator<long>>>();
if (!TEST_IS_CONSTANT_EVALUATED) {
auto erase_function = [](auto& m, auto key_arg) {
diff --git a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.observers/comp.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.observers/comp.pass.cpp
index 5712493..626f6ad 100644
--- a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.observers/comp.pass.cpp
+++ b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.observers/comp.pass.cpp
@@ -35,7 +35,7 @@ constexpr bool test() {
assert(kc(1, 2));
assert(!kc(2, 1));
auto vc = m.value_comp();
- ASSERT_SAME_TYPE(decltype(vc(std::make_pair(1, 2), std::make_pair(1, 2))), bool);
+ ASSERT_SAME_TYPE(decltype(vc(std::make_pair(1, '2'), std::make_pair(1, '2'))), bool);
assert(vc({1, '2'}, {2, '1'}));
assert(!vc({2, '1'}, {1, '2'}));
}
diff --git a/libcxx/test/std/containers/container.adaptors/flat.map/helpers.h b/libcxx/test/std/containers/container.adaptors/flat.map/helpers.h
index 932f330..445de4f 100644
--- a/libcxx/test/std/containers/container.adaptors/flat.map/helpers.h
+++ b/libcxx/test/std/containers/container.adaptors/flat.map/helpers.h
@@ -15,6 +15,7 @@
#include <vector>
#include <flat_map>
#include <ranges>
+#include <type_traits>
#include "../flat_helpers.h"
#include "test_allocator.h"
diff --git a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/copy_assign.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/copy_assign.pass.cpp
index fd57a10..2edfca5 100644
--- a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/copy_assign.pass.cpp
+++ b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/copy_assign.pass.cpp
@@ -12,6 +12,7 @@
// flat_multimap& operator=(const flat_multimap& m);
+#include <cassert>
#include <deque>
#include <flat_map>
#include <functional>
@@ -28,8 +29,8 @@ constexpr void test() {
// test_allocator is not propagated
using C = test_less<int>;
KeyContainer<int, test_allocator<int>> ks({1, 1, 3, 5}, test_allocator<int>(6));
- ValueContainer<char, test_allocator<char>> vs({2, 2, 2, 1}, test_allocator<char>(7));
- using M = std::flat_multimap<int, char, C, decltype(ks), decltype(vs)>;
+ ValueContainer<long, test_allocator<long>> vs({2, 2, 2, 1}, test_allocator<long>(7));
+ using M = std::flat_multimap<int, long, C, decltype(ks), decltype(vs)>;
auto mo = M(ks, vs, C(5));
auto m = M({{3, 3}, {4, 4}, {5, 5}, {5, 5}}, C(3), test_allocator<int>(2));
m = mo;
@@ -38,23 +39,23 @@ constexpr void test() {
assert(m.keys() == ks);
assert(m.values() == vs);
assert(m.keys().get_allocator() == test_allocator<int>(2));
- assert(m.values().get_allocator() == test_allocator<char>(2));
+ assert(m.values().get_allocator() == test_allocator<long>(2));
// mo is unchanged
assert(mo.key_comp() == C(5));
assert(mo.keys() == ks);
assert(mo.values() == vs);
assert(mo.keys().get_allocator() == test_allocator<int>(6));
- assert(mo.values().get_allocator() == test_allocator<char>(7));
+ assert(mo.values().get_allocator() == test_allocator<long>(7));
}
{
// other_allocator is propagated
using C = test_less<int>;
using Ks = KeyContainer<int, other_allocator<int>>;
- using Vs = ValueContainer<char, other_allocator<char>>;
+ using Vs = ValueContainer<long, other_allocator<long>>;
auto ks = Ks({1, 1, 3, 5}, other_allocator<int>(6));
- auto vs = Vs({2, 2, 2, 1}, other_allocator<char>(7));
- using M = std::flat_multimap<int, char, C, Ks, Vs>;
+ auto vs = Vs({2, 2, 2, 1}, other_allocator<long>(7));
+ using M = std::flat_multimap<int, long, C, Ks, Vs>;
auto mo = M(Ks(ks, other_allocator<int>(6)), Vs(vs, other_allocator<int>(7)), C(5));
auto m = M({{3, 3}, {4, 4}, {5, 5}, {5, 5}}, C(3), other_allocator<int>(2));
m = mo;
@@ -63,14 +64,14 @@ constexpr void test() {
assert(m.keys() == ks);
assert(m.values() == vs);
assert(m.keys().get_allocator() == other_allocator<int>(6));
- assert(m.values().get_allocator() == other_allocator<char>(7));
+ assert(m.values().get_allocator() == other_allocator<long>(7));
// mo is unchanged
assert(mo.key_comp() == C(5));
assert(mo.keys() == ks);
assert(mo.values() == vs);
assert(mo.keys().get_allocator() == other_allocator<int>(6));
- assert(mo.values().get_allocator() == other_allocator<char>(7));
+ assert(mo.values().get_allocator() == other_allocator<long>(7));
}
if (!TEST_IS_CONSTANT_EVALUATED) {
// comparator is copied and invariant is preserved
diff --git a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/deduct.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/deduct.pass.cpp
index 23ef312..96f28db 100644
--- a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/deduct.pass.cpp
+++ b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/deduct.pass.cpp
@@ -32,19 +32,19 @@ using PC = std::pair<const int, long>;
void test_copy() {
{
- std::flat_multimap<long, short> source = {{1, 2}, {1, 3}};
+ std::flat_multimap<long, int> source = {{1, 2}, {1, 3}};
std::flat_multimap s(source);
ASSERT_SAME_TYPE(decltype(s), decltype(source));
assert(s == source);
}
{
- std::flat_multimap<long, short, std::greater<long>> source = {{1, 2}, {1, 3}};
+ std::flat_multimap<long, int, std::greater<long>> source = {{1, 2}, {1, 3}};
std::flat_multimap s{source}; // braces instead of parens
ASSERT_SAME_TYPE(decltype(s), decltype(source));
assert(s == source);
}
{
- std::flat_multimap<long, short, std::greater<long>> source = {{1, 2}, {1, 3}};
+ std::flat_multimap<long, int, std::greater<long>> source = {{1, 2}, {1, 3}};
std::flat_multimap s(source, std::allocator<int>());
ASSERT_SAME_TYPE(decltype(s), decltype(source));
assert(s == source);
@@ -53,14 +53,14 @@ void test_copy() {
void test_containers() {
std::deque<int, test_allocator<int>> ks({1, 2, 1, 2, 2, INT_MAX, 3}, test_allocator<int>(0, 42));
- std::deque<short, test_allocator<short>> vs({1, 2, 3, 4, 5, 3, 4}, test_allocator<int>(0, 43));
+ std::deque<long, test_allocator<long>> vs({1, 2, 3, 4, 5, 3, 4}, test_allocator<int>(0, 43));
std::deque<int, test_allocator<int>> sorted_ks({1, 1, 2, 2, 2, 3, INT_MAX}, test_allocator<int>(0, 42));
- std::deque<short, test_allocator<short>> sorted_vs({1, 3, 2, 4, 5, 4, 3}, test_allocator<int>(0, 43));
- const std::pair<int, short> expected[] = {{1, 1}, {1, 3}, {2, 2}, {2, 4}, {2, 5}, {3, 4}, {INT_MAX, 3}};
+ std::deque<long, test_allocator<long>> sorted_vs({1, 3, 2, 4, 5, 4, 3}, test_allocator<int>(0, 43));
+ const std::pair<int, long> expected[] = {{1, 1}, {1, 3}, {2, 2}, {2, 4}, {2, 5}, {3, 4}, {INT_MAX, 3}};
{
std::flat_multimap s(ks, vs);
- ASSERT_SAME_TYPE(decltype(s), std::flat_multimap<int, short, std::less<int>, decltype(ks), decltype(vs)>);
+ ASSERT_SAME_TYPE(decltype(s), std::flat_multimap<int, long, std::less<int>, decltype(ks), decltype(vs)>);
assert(std::ranges::equal(s, expected));
assert(s.keys().get_allocator().get_id() == 42);
assert(s.values().get_allocator().get_id() == 43);
@@ -68,7 +68,7 @@ void test_containers() {
{
std::flat_multimap s(std::sorted_equivalent, sorted_ks, sorted_vs);
- ASSERT_SAME_TYPE(decltype(s), std::flat_multimap<int, short, std::less<int>, decltype(ks), decltype(vs)>);
+ ASSERT_SAME_TYPE(decltype(s), std::flat_multimap<int, long, std::less<int>, decltype(ks), decltype(vs)>);
assert(std::ranges::equal(s, expected));
assert(s.keys().get_allocator().get_id() == 42);
assert(s.values().get_allocator().get_id() == 43);
@@ -76,7 +76,7 @@ void test_containers() {
{
std::flat_multimap s(ks, vs, test_allocator<long>(0, 44));
- ASSERT_SAME_TYPE(decltype(s), std::flat_multimap<int, short, std::less<int>, decltype(ks), decltype(vs)>);
+ ASSERT_SAME_TYPE(decltype(s), std::flat_multimap<int, long, std::less<int>, decltype(ks), decltype(vs)>);
assert(std::ranges::equal(s, expected));
assert(s.keys().get_allocator().get_id() == 44);
assert(s.values().get_allocator().get_id() == 44);
@@ -84,7 +84,7 @@ void test_containers() {
{
std::flat_multimap s(std::sorted_equivalent, sorted_ks, sorted_vs, test_allocator<long>(0, 44));
- ASSERT_SAME_TYPE(decltype(s), std::flat_multimap<int, short, std::less<int>, decltype(ks), decltype(vs)>);
+ ASSERT_SAME_TYPE(decltype(s), std::flat_multimap<int, long, std::less<int>, decltype(ks), decltype(vs)>);
assert(std::ranges::equal(s, expected));
assert(s.keys().get_allocator().get_id() == 44);
assert(s.values().get_allocator().get_id() == 44);
@@ -93,14 +93,14 @@ void test_containers() {
void test_containers_compare() {
std::deque<int, test_allocator<int>> ks({1, 2, 1, 2, 2, INT_MAX, 3}, test_allocator<int>(0, 42));
- std::deque<short, test_allocator<short>> vs({1, 2, 3, 4, 5, 3, 4}, test_allocator<int>(0, 43));
+ std::deque<long, test_allocator<long>> vs({1, 2, 3, 4, 5, 3, 4}, test_allocator<int>(0, 43));
std::deque<int, test_allocator<int>> sorted_ks({INT_MAX, 3, 2, 2, 2, 1, 1}, test_allocator<int>(0, 42));
- std::deque<short, test_allocator<short>> sorted_vs({3, 4, 2, 4, 5, 1, 3}, test_allocator<int>(0, 43));
- const std::pair<int, short> expected[] = {{INT_MAX, 3}, {3, 4}, {2, 2}, {2, 4}, {2, 5}, {1, 1}, {1, 3}};
+ std::deque<long, test_allocator<long>> sorted_vs({3, 4, 2, 4, 5, 1, 3}, test_allocator<int>(0, 43));
+ const std::pair<int, long> expected[] = {{INT_MAX, 3}, {3, 4}, {2, 2}, {2, 4}, {2, 5}, {1, 1}, {1, 3}};
{
std::flat_multimap s(ks, vs, std::greater<int>());
- ASSERT_SAME_TYPE(decltype(s), std::flat_multimap<int, short, std::greater<int>, decltype(ks), decltype(vs)>);
+ ASSERT_SAME_TYPE(decltype(s), std::flat_multimap<int, long, std::greater<int>, decltype(ks), decltype(vs)>);
assert(std::ranges::equal(s, expected));
assert(s.keys().get_allocator().get_id() == 42);
assert(s.values().get_allocator().get_id() == 43);
@@ -108,7 +108,7 @@ void test_containers_compare() {
{
std::flat_multimap s(std::sorted_equivalent, sorted_ks, sorted_vs, std::greater<int>());
- ASSERT_SAME_TYPE(decltype(s), std::flat_multimap<int, short, std::greater<int>, decltype(ks), decltype(vs)>);
+ ASSERT_SAME_TYPE(decltype(s), std::flat_multimap<int, long, std::greater<int>, decltype(ks), decltype(vs)>);
assert(std::ranges::equal(s, expected));
assert(s.keys().get_allocator().get_id() == 42);
assert(s.values().get_allocator().get_id() == 43);
@@ -116,7 +116,7 @@ void test_containers_compare() {
{
std::flat_multimap s(ks, vs, std::greater<int>(), test_allocator<long>(0, 44));
- ASSERT_SAME_TYPE(decltype(s), std::flat_multimap<int, short, std::greater<int>, decltype(ks), decltype(vs)>);
+ ASSERT_SAME_TYPE(decltype(s), std::flat_multimap<int, long, std::greater<int>, decltype(ks), decltype(vs)>);
assert(std::ranges::equal(s, expected));
assert(s.keys().get_allocator().get_id() == 44);
assert(s.values().get_allocator().get_id() == 44);
@@ -125,7 +125,7 @@ void test_containers_compare() {
std::flat_multimap s(
std::sorted_equivalent, sorted_ks, sorted_vs, std::greater<int>(), test_allocator<long>(0, 44));
- ASSERT_SAME_TYPE(decltype(s), std::flat_multimap<int, short, std::greater<int>, decltype(ks), decltype(vs)>);
+ ASSERT_SAME_TYPE(decltype(s), std::flat_multimap<int, long, std::greater<int>, decltype(ks), decltype(vs)>);
assert(std::ranges::equal(s, expected));
assert(s.keys().get_allocator().get_id() == 44);
assert(s.values().get_allocator().get_id() == 44);
@@ -281,11 +281,11 @@ void test_initializer_list_compare() {
}
void test_from_range() {
- std::list<std::pair<int, short>> r = {{1, 1}, {2, 2}, {1, 1}, {INT_MAX, 4}, {3, 5}};
- const std::pair<int, short> expected[] = {{1, 1}, {1, 1}, {2, 2}, {3, 5}, {INT_MAX, 4}};
+ std::list<std::pair<int, long>> r = {{1, 1}, {2, 2}, {1, 1}, {INT_MAX, 4}, {3, 5}};
+ const std::pair<int, long> expected[] = {{1, 1}, {1, 1}, {2, 2}, {3, 5}, {INT_MAX, 4}};
{
std::flat_multimap s(std::from_range, r);
- ASSERT_SAME_TYPE(decltype(s), std::flat_multimap<int, short, std::less<int>>);
+ ASSERT_SAME_TYPE(decltype(s), std::flat_multimap<int, long, std::less<int>>);
assert(std::ranges::equal(s, expected));
}
{
@@ -293,10 +293,10 @@ void test_from_range() {
ASSERT_SAME_TYPE(
decltype(s),
std::flat_multimap<int,
- short,
+ long,
std::less<int>,
std::vector<int, test_allocator<int>>,
- std::vector<short, test_allocator<short>>>);
+ std::vector<long, test_allocator<long>>>);
assert(std::ranges::equal(s, expected));
assert(s.keys().get_allocator().get_id() == 42);
assert(s.values().get_allocator().get_id() == 42);
@@ -304,11 +304,11 @@ void test_from_range() {
}
void test_from_range_compare() {
- std::list<std::pair<int, short>> r = {{1, 1}, {2, 2}, {1, 1}, {INT_MAX, 4}, {3, 5}};
- const std::pair<int, short> expected[] = {{INT_MAX, 4}, {3, 5}, {2, 2}, {1, 1}, {1, 1}};
+ std::list<std::pair<int, long>> r = {{1, 1}, {2, 2}, {1, 1}, {INT_MAX, 4}, {3, 5}};
+ const std::pair<int, long> expected[] = {{INT_MAX, 4}, {3, 5}, {2, 2}, {1, 1}, {1, 1}};
{
std::flat_multimap s(std::from_range, r, std::greater<int>());
- ASSERT_SAME_TYPE(decltype(s), std::flat_multimap<int, short, std::greater<int>>);
+ ASSERT_SAME_TYPE(decltype(s), std::flat_multimap<int, long, std::greater<int>>);
assert(std::ranges::equal(s, expected));
}
{
@@ -316,10 +316,10 @@ void test_from_range_compare() {
ASSERT_SAME_TYPE(
decltype(s),
std::flat_multimap<int,
- short,
+ long,
std::greater<int>,
std::vector<int, test_allocator<int>>,
- std::vector<short, test_allocator<short>>>);
+ std::vector<long, test_allocator<long>>>);
assert(std::ranges::equal(s, expected));
assert(s.keys().get_allocator().get_id() == 42);
assert(s.values().get_allocator().get_id() == 42);
diff --git a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/deduct_pmr.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/deduct_pmr.pass.cpp
index 1955a88..d809436 100644
--- a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/deduct_pmr.pass.cpp
+++ b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/deduct_pmr.pass.cpp
@@ -32,19 +32,19 @@ using PC = std::pair<const int, long>;
void test_containers() {
std::deque<int, test_allocator<int>> ks({1, 2, 1, 2, 2, INT_MAX, 3}, test_allocator<int>(0, 42));
- std::deque<short, test_allocator<short>> vs({1, 2, 3, 4, 5, 3, 4}, test_allocator<int>(0, 43));
+ std::deque<long, test_allocator<long>> vs({1, 2, 3, 4, 5, 3, 4}, test_allocator<int>(0, 43));
std::deque<int, test_allocator<int>> sorted_ks({1, 1, 2, 2, 2, 3, INT_MAX}, test_allocator<int>(0, 42));
- std::deque<short, test_allocator<short>> sorted_vs({1, 3, 2, 4, 5, 4, 3}, test_allocator<int>(0, 43));
- const std::pair<int, short> expected[] = {{1, 1}, {1, 3}, {2, 2}, {2, 4}, {2, 5}, {3, 4}, {INT_MAX, 3}};
+ std::deque<long, test_allocator<long>> sorted_vs({1, 3, 2, 4, 5, 4, 3}, test_allocator<int>(0, 43));
+ const std::pair<int, long> expected[] = {{1, 1}, {1, 3}, {2, 2}, {2, 4}, {2, 5}, {3, 4}, {INT_MAX, 3}};
{
std::pmr::monotonic_buffer_resource mr;
std::pmr::monotonic_buffer_resource mr2;
std::pmr::deque<int> pks(ks.begin(), ks.end(), &mr);
- std::pmr::deque<short> pvs(vs.begin(), vs.end(), &mr);
+ std::pmr::deque<long> pvs(vs.begin(), vs.end(), &mr);
std::flat_multimap s(std::move(pks), std::move(pvs), &mr2);
ASSERT_SAME_TYPE(
- decltype(s), std::flat_multimap<int, short, std::less<int>, std::pmr::deque<int>, std::pmr::deque<short>>);
+ decltype(s), std::flat_multimap<int, long, std::less<int>, std::pmr::deque<int>, std::pmr::deque<long>>);
assert(std::ranges::equal(s, expected));
assert(s.keys().get_allocator().resource() == &mr2);
assert(s.values().get_allocator().resource() == &mr2);
@@ -53,11 +53,11 @@ void test_containers() {
std::pmr::monotonic_buffer_resource mr;
std::pmr::monotonic_buffer_resource mr2;
std::pmr::deque<int> pks(sorted_ks.begin(), sorted_ks.end(), &mr);
- std::pmr::deque<short> pvs(sorted_vs.begin(), sorted_vs.end(), &mr);
+ std::pmr::deque<long> pvs(sorted_vs.begin(), sorted_vs.end(), &mr);
std::flat_multimap s(std::sorted_equivalent, std::move(pks), std::move(pvs), &mr2);
ASSERT_SAME_TYPE(
- decltype(s), std::flat_multimap<int, short, std::less<int>, std::pmr::deque<int>, std::pmr::deque<short>>);
+ decltype(s), std::flat_multimap<int, long, std::less<int>, std::pmr::deque<int>, std::pmr::deque<long>>);
assert(std::ranges::equal(s, expected));
assert(s.keys().get_allocator().resource() == &mr2);
assert(s.values().get_allocator().resource() == &mr2);
@@ -66,20 +66,20 @@ void test_containers() {
void test_containers_compare() {
std::deque<int, test_allocator<int>> ks({1, 2, 1, 2, 2, INT_MAX, 3}, test_allocator<int>(0, 42));
- std::deque<short, test_allocator<short>> vs({1, 2, 3, 4, 5, 3, 4}, test_allocator<int>(0, 43));
+ std::deque<long, test_allocator<long>> vs({1, 2, 3, 4, 5, 3, 4}, test_allocator<int>(0, 43));
std::deque<int, test_allocator<int>> sorted_ks({INT_MAX, 3, 2, 2, 2, 1, 1}, test_allocator<int>(0, 42));
- std::deque<short, test_allocator<short>> sorted_vs({3, 4, 2, 4, 5, 1, 3}, test_allocator<int>(0, 43));
- const std::pair<int, short> expected[] = {{INT_MAX, 3}, {3, 4}, {2, 2}, {2, 4}, {2, 5}, {1, 1}, {1, 3}};
+ std::deque<long, test_allocator<long>> sorted_vs({3, 4, 2, 4, 5, 1, 3}, test_allocator<int>(0, 43));
+ const std::pair<int, long> expected[] = {{INT_MAX, 3}, {3, 4}, {2, 2}, {2, 4}, {2, 5}, {1, 1}, {1, 3}};
{
std::pmr::monotonic_buffer_resource mr;
std::pmr::monotonic_buffer_resource mr2;
std::pmr::deque<int> pks(ks.begin(), ks.end(), &mr);
- std::pmr::deque<short> pvs(vs.begin(), vs.end(), &mr);
+ std::pmr::deque<long> pvs(vs.begin(), vs.end(), &mr);
std::flat_multimap s(std::move(pks), std::move(pvs), std::greater<int>(), &mr2);
ASSERT_SAME_TYPE(
- decltype(s), std::flat_multimap<int, short, std::greater<int>, std::pmr::deque<int>, std::pmr::deque<short>>);
+ decltype(s), std::flat_multimap<int, long, std::greater<int>, std::pmr::deque<int>, std::pmr::deque<long>>);
assert(std::ranges::equal(s, expected));
assert(s.keys().get_allocator().resource() == &mr2);
assert(s.values().get_allocator().resource() == &mr2);
@@ -88,11 +88,11 @@ void test_containers_compare() {
std::pmr::monotonic_buffer_resource mr;
std::pmr::monotonic_buffer_resource mr2;
std::pmr::deque<int> pks(sorted_ks.begin(), sorted_ks.end(), &mr);
- std::pmr::deque<short> pvs(sorted_vs.begin(), sorted_vs.end(), &mr);
+ std::pmr::deque<long> pvs(sorted_vs.begin(), sorted_vs.end(), &mr);
std::flat_multimap s(std::sorted_equivalent, std::move(pks), std::move(pvs), std::greater<int>(), &mr2);
ASSERT_SAME_TYPE(
- decltype(s), std::flat_multimap<int, short, std::greater<int>, std::pmr::deque<int>, std::pmr::deque<short>>);
+ decltype(s), std::flat_multimap<int, long, std::greater<int>, std::pmr::deque<int>, std::pmr::deque<long>>);
assert(std::ranges::equal(s, expected));
assert(s.keys().get_allocator().resource() == &mr2);
assert(s.values().get_allocator().resource() == &mr2);
diff --git a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/dtor_noexcept.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/dtor_noexcept.pass.cpp
index 104d567..2534a47 100644
--- a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/dtor_noexcept.pass.cpp
+++ b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/dtor_noexcept.pass.cpp
@@ -16,6 +16,7 @@
#include <deque>
#include <flat_map>
#include <functional>
+#include <type_traits>
#include <vector>
#include "test_macros.h"
diff --git a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/initializer_list.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/initializer_list.pass.cpp
index e40708a..418b46bc 100644
--- a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/initializer_list.pass.cpp
+++ b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/initializer_list.pass.cpp
@@ -38,24 +38,24 @@ struct DefaultCtableComp {
template <template <class...> class KeyContainer, template <class...> class ValueContainer>
constexpr void test() {
- std::pair<int, short> expected[] = {{1, 1}, {2, 2}, {2, 2}, {3, 3}, {3, 3}, {5, 2}};
+ std::pair<int, long> expected[] = {{1, 1}, {2, 2}, {2, 2}, {3, 3}, {3, 3}, {5, 2}};
{
// flat_multimap(initializer_list<value_type>);
- using M = std::flat_multimap<int, short>;
- std::initializer_list<std::pair<int, short>> il = {{5, 2}, {2, 2}, {2, 2}, {3, 3}, {1, 1}, {3, 3}};
+ using M = std::flat_multimap<int, long>;
+ std::initializer_list<std::pair<int, long>> il = {{5, 2}, {2, 2}, {2, 2}, {3, 3}, {1, 1}, {3, 3}};
M m(il);
assert(std::ranges::equal(m, expected));
}
{
// flat_multimap(initializer_list<value_type>);
// explicit(false)
- using M = std::flat_multimap<int, short>;
+ using M = std::flat_multimap<int, long>;
M m = {{5, 2}, {2, 2}, {2, 2}, {3, 3}, {1, 1}, {3, 3}};
assert(std::ranges::equal(m, expected));
}
{
// flat_multimap(initializer_list<value_type>);
- using M = std::flat_multimap<int, short, std::greater<int>, KeyContainer<int, min_allocator<int>>>;
+ using M = std::flat_multimap<int, long, std::greater<int>, KeyContainer<int, min_allocator<int>>>;
M m = {{5, 2}, {2, 2}, {2, 2}, {3, 3}, {1, 1}, {3, 3}};
assert(std::equal(m.rbegin(), m.rend(), expected, expected + 6));
}
@@ -80,7 +80,7 @@ constexpr void test() {
{
// flat_multimap(initializer_list<value_type>, const key_compare&);
using C = test_less<int>;
- using M = std::flat_multimap<int, short, C>;
+ using M = std::flat_multimap<int, long, C>;
auto m = M({{5, 2}, {2, 2}, {2, 2}, {3, 3}, {1, 1}, {3, 3}}, C(10));
assert(std::equal(m.begin(), m.end(), expected, expected + 6));
assert(m.key_comp() == C(10));
@@ -93,7 +93,7 @@ constexpr void test() {
if (!TEST_IS_CONSTANT_EVALUATED) {
// flat_multimap(initializer_list<value_type>, const key_compare&);
// Sorting uses the comparator that was passed in
- using M = std::flat_multimap<int, short, std::function<bool(int, int)>, KeyContainer<int, min_allocator<int>>>;
+ using M = std::flat_multimap<int, long, std::function<bool(int, int)>, KeyContainer<int, min_allocator<int>>>;
auto m = M({{5, 2}, {2, 2}, {2, 2}, {3, 3}, {1, 1}, {3, 3}}, std::greater<int>());
assert(std::equal(m.rbegin(), m.rend(), expected, expected + 6));
assert(m.key_comp()(2, 1) == true);
diff --git a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/iter_iter.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/iter_iter.pass.cpp
index c7f2d16..46c8922 100644
--- a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/iter_iter.pass.cpp
+++ b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/iter_iter.pass.cpp
@@ -119,19 +119,19 @@ constexpr void test() {
template <template <class...> class KeyContainer, template <class...> class ValueContainer>
constexpr void test_alloc() {
- using P = std::pair<int, short>;
+ using P = std::pair<int, long>;
P ar[] = {{1, 1}, {1, 2}, {1, 3}, {2, 4}, {2, 5}, {3, 6}, {2, 7}, {3, 8}, {3, 9}};
{
// flat_multimap(InputIterator , InputIterator, const Allocator&)
using A1 = test_allocator<int>;
- using A2 = test_allocator<short>;
- using M = std::flat_multimap<int, short, std::less<int>, KeyContainer<int, A1>, ValueContainer<short, A2>>;
+ using A2 = test_allocator<long>;
+ using M = std::flat_multimap<int, long, std::less<int>, KeyContainer<int, A1>, ValueContainer<long, A2>>;
auto m = M(ar, ar + 9, A1(5));
assert(std::ranges::equal(m.keys(), KeyContainer<int, A1>{1, 1, 1, 2, 2, 2, 3, 3, 3}));
check_possible_values(
m.values(),
- std::vector<std::vector<short>>{
+ std::vector<std::vector<long>>{
{1, 2, 3},
{1, 2, 3},
{1, 2, 3},
@@ -149,13 +149,13 @@ constexpr void test_alloc() {
// flat_multimap(InputIterator , InputIterator, const Allocator&)
// explicit(false)
using A1 = test_allocator<int>;
- using A2 = test_allocator<short>;
- using M = std::flat_multimap<int, short, std::less<int>, KeyContainer<int, A1>, ValueContainer<short, A2>>;
+ using A2 = test_allocator<long>;
+ using M = std::flat_multimap<int, long, std::less<int>, KeyContainer<int, A1>, ValueContainer<long, A2>>;
M m = {ar, ar + 9, A1(5)}; // implicit ctor
assert(std::ranges::equal(m.keys(), KeyContainer<int, A1>{1, 1, 1, 2, 2, 2, 3, 3, 3}));
check_possible_values(
m.values(),
- std::vector<std::vector<short>>{
+ std::vector<std::vector<long>>{
{1, 2, 3},
{1, 2, 3},
{1, 2, 3},
@@ -173,13 +173,13 @@ constexpr void test_alloc() {
// flat_multimap(InputIterator , InputIterator, const key_compare&, const Allocator&)
using C = test_less<int>;
using A1 = test_allocator<int>;
- using A2 = test_allocator<short>;
- using M = std::flat_multimap<int, short, C, KeyContainer<int, A1>, ValueContainer<short, A2>>;
+ using A2 = test_allocator<long>;
+ using M = std::flat_multimap<int, long, C, KeyContainer<int, A1>, ValueContainer<long, A2>>;
auto m = M(ar, ar + 9, C(3), A1(5));
assert(std::ranges::equal(m.keys(), KeyContainer<int, A1>{1, 1, 1, 2, 2, 2, 3, 3, 3}));
check_possible_values(
m.values(),
- std::vector<std::vector<short>>{
+ std::vector<std::vector<long>>{
{1, 2, 3},
{1, 2, 3},
{1, 2, 3},
@@ -198,13 +198,13 @@ constexpr void test_alloc() {
// flat_multimap(InputIterator , InputIterator, const key_compare&, const Allocator&)
// explicit(false)
using A1 = test_allocator<int>;
- using A2 = test_allocator<short>;
- using M = std::flat_multimap<int, short, std::less<int>, KeyContainer<int, A1>, ValueContainer<short, A2>>;
+ using A2 = test_allocator<long>;
+ using M = std::flat_multimap<int, long, std::less<int>, KeyContainer<int, A1>, ValueContainer<long, A2>>;
M m = {ar, ar + 9, {}, A2(5)}; // implicit ctor
assert(std::ranges::equal(m.keys(), KeyContainer<int, A1>{1, 1, 1, 2, 2, 2, 3, 3, 3}));
check_possible_values(
m.values(),
- std::vector<std::vector<short>>{
+ std::vector<std::vector<long>>{
{1, 2, 3},
{1, 2, 3},
{1, 2, 3},
diff --git a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/move_assign.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/move_assign.pass.cpp
index 292bb5c..bf7b34c 100644
--- a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/move_assign.pass.cpp
+++ b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/move_assign.pass.cpp
@@ -31,8 +31,8 @@ constexpr void test() {
{
using C = test_less<int>;
using A1 = test_allocator<int>;
- using A2 = test_allocator<char>;
- using M = std::flat_multimap<int, char, C, KeyContainer<int, A1>, ValueContainer<char, A2>>;
+ using A2 = test_allocator<long>;
+ using M = std::flat_multimap<int, long, C, KeyContainer<int, A1>, ValueContainer<long, A2>>;
M mo = M({{1, 1}, {1, 3}, {3, 2}}, C(5), A1(7));
M m = M({}, C(3), A1(7));
m = std::move(mo);
@@ -46,8 +46,8 @@ constexpr void test() {
{
using C = test_less<int>;
using A1 = other_allocator<int>;
- using A2 = other_allocator<char>;
- using M = std::flat_multimap<int, char, C, KeyContainer<int, A1>, ValueContainer<char, A2>>;
+ using A2 = other_allocator<long>;
+ using M = std::flat_multimap<int, long, C, KeyContainer<int, A1>, ValueContainer<long, A2>>;
M mo = M({{4, 5}, {4, 4}}, C(5), A1(7));
M m = M({{1, 1}, {2, 2}, {3, 3}, {4, 4}}, C(3), A1(7));
m = std::move(mo);
diff --git a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/pmr.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/pmr.pass.cpp
index 8b518f6..67b147f 100644
--- a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/pmr.pass.cpp
+++ b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/pmr.pass.cpp
@@ -166,12 +166,12 @@ int main(int, char**) {
}
{
// flat_multimap(InputIterator first, InputIterator last, const Allocator& a);
- using P = std::pair<int, short>;
+ using P = std::pair<int, long>;
P ar[] = {{1, 1}, {1, 2}, {1, 3}, {2, 4}, {2, 5}, {3, 6}, {2, 7}, {3, 8}, {3, 9}};
P expected[] = {{1, 1}, {1, 2}, {1, 3}, {2, 4}, {2, 5}, {2, 7}, {3, 6}, {3, 8}, {3, 9}};
{
// cpp17 iterator
- using M = std::flat_multimap<int, short, std::less<int>, std::pmr::vector<int>, std::pmr::vector<short>>;
+ using M = std::flat_multimap<int, long, std::less<int>, std::pmr::vector<int>, std::pmr::vector<long>>;
std::pmr::monotonic_buffer_resource mr;
std::pmr::vector<M> vm(&mr);
vm.emplace_back(cpp17_input_iterator<const P*>(ar), cpp17_input_iterator<const P*>(ar + 9));
@@ -181,7 +181,7 @@ int main(int, char**) {
assert(vm[0].values().get_allocator().resource() == &mr);
}
{
- using M = std::flat_multimap<int, short, std::less<int>, std::pmr::vector<int>, std::pmr::vector<short>>;
+ using M = std::flat_multimap<int, long, std::less<int>, std::pmr::vector<int>, std::pmr::vector<long>>;
std::pmr::monotonic_buffer_resource mr;
std::pmr::vector<M> vm(&mr);
vm.emplace_back(ar, ar);
@@ -242,12 +242,12 @@ int main(int, char**) {
}
{
// flat_multimap(from_range_t, R&&, const Alloc&);
- using P = std::pair<int, short>;
+ using P = std::pair<int, long>;
P ar[] = {{1, 1}, {1, 2}, {1, 3}, {2, 4}, {2, 5}, {3, 6}, {2, 7}, {3, 8}, {3, 9}};
P expected[] = {{1, 1}, {1, 2}, {1, 3}, {2, 4}, {2, 5}, {2, 7}, {3, 6}, {3, 8}, {3, 9}};
{
// input_range
- using M = std::flat_multimap<int, short, std::less<int>, std::pmr::vector<int>, std::pmr::vector<short>>;
+ using M = std::flat_multimap<int, long, std::less<int>, std::pmr::vector<int>, std::pmr::vector<long>>;
using Iter = cpp20_input_iterator<const P*>;
using Sent = sentinel_wrapper<Iter>;
using R = std::ranges::subrange<Iter, Sent>;
@@ -260,7 +260,7 @@ int main(int, char**) {
assert(vm[0].values().get_allocator().resource() == &mr);
}
{
- using M = std::flat_multimap<int, short, std::less<int>, std::pmr::vector<int>, std::pmr::vector<short>>;
+ using M = std::flat_multimap<int, long, std::less<int>, std::pmr::vector<int>, std::pmr::vector<long>>;
using R = std::ranges::subrange<const P*>;
std::pmr::monotonic_buffer_resource mr;
std::pmr::vector<M> vm(&mr);
diff --git a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/range.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/range.pass.cpp
index 0b36551..fad2cae 100644
--- a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/range.pass.cpp
+++ b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/range.pass.cpp
@@ -176,19 +176,19 @@ constexpr void test() {
template <template <class...> class KeyContainer, template <class...> class ValueContainer>
constexpr void test_alloc() {
- using P = std::pair<int, short>;
+ using P = std::pair<int, long>;
P ar[] = {{1, 1}, {1, 2}, {1, 3}, {2, 4}, {2, 5}, {3, 6}, {2, 7}, {3, 8}, {3, 9}};
{
// flat_multimap(from_range_t, R&&, const Allocator&)
using A1 = test_allocator<int>;
- using A2 = test_allocator<short>;
- using M = std::flat_multimap<int, short, std::less<int>, KeyContainer<int, A1>, ValueContainer<short, A2>>;
+ using A2 = test_allocator<long>;
+ using M = std::flat_multimap<int, long, std::less<int>, KeyContainer<int, A1>, ValueContainer<long, A2>>;
using R = std::ranges::subrange<const P*>;
auto m = M(std::from_range, R(ar, ar + 9), A1(5));
assert(std::ranges::equal(m.keys(), KeyContainer<int, A1>{1, 1, 1, 2, 2, 2, 3, 3, 3}));
check_possible_values(
m.values(),
- std::vector<std::vector<short>>{
+ std::vector<std::vector<long>>{
{1, 2, 3},
{1, 2, 3},
{1, 2, 3},
@@ -206,14 +206,14 @@ constexpr void test_alloc() {
// flat_multimap(from_range_t, R&&, const Allocator&)
// explicit(false)
using A1 = test_allocator<int>;
- using A2 = test_allocator<short>;
- using M = std::flat_multimap<int, short, std::less<int>, KeyContainer<int, A1>, ValueContainer<short, A2>>;
+ using A2 = test_allocator<long>;
+ using M = std::flat_multimap<int, long, std::less<int>, KeyContainer<int, A1>, ValueContainer<long, A2>>;
using R = std::ranges::subrange<const P*>;
M m = {std::from_range, R(ar, ar + 9), A1(5)}; // implicit ctor
assert(std::ranges::equal(m.keys(), KeyContainer<int, A1>{1, 1, 1, 2, 2, 2, 3, 3, 3}));
check_possible_values(
m.values(),
- std::vector<std::vector<short>>{
+ std::vector<std::vector<long>>{
{1, 2, 3},
{1, 2, 3},
{1, 2, 3},
@@ -231,14 +231,14 @@ constexpr void test_alloc() {
// flat_multimap(from_range_t, R&&, const key_compare&, const Allocator&)
using C = test_less<int>;
using A1 = test_allocator<int>;
- using A2 = test_allocator<short>;
- using M = std::flat_multimap<int, short, C, KeyContainer<int, A1>, ValueContainer<short, A2>>;
+ using A2 = test_allocator<long>;
+ using M = std::flat_multimap<int, long, C, KeyContainer<int, A1>, ValueContainer<long, A2>>;
using R = std::ranges::subrange<const P*>;
auto m = M(std::from_range, R(ar, ar + 9), C(3), A1(5));
assert(std::ranges::equal(m.keys(), KeyContainer<int, A1>{1, 1, 1, 2, 2, 2, 3, 3, 3}));
check_possible_values(
m.values(),
- std::vector<std::vector<short>>{
+ std::vector<std::vector<long>>{
{1, 2, 3},
{1, 2, 3},
{1, 2, 3},
@@ -257,14 +257,14 @@ constexpr void test_alloc() {
// flat_multimap(from_range_t, R&&, const key_compare&, const Allocator&)
// explicit(false)
using A1 = test_allocator<int>;
- using A2 = test_allocator<short>;
- using M = std::flat_multimap<int, short, std::less<int>, KeyContainer<int, A1>, ValueContainer<short, A2>>;
+ using A2 = test_allocator<long>;
+ using M = std::flat_multimap<int, long, std::less<int>, KeyContainer<int, A1>, ValueContainer<long, A2>>;
using R = std::ranges::subrange<const P*>;
M m = {std::from_range, R(ar, ar + 9), {}, A2(5)}; // implicit ctor
assert(std::ranges::equal(m.keys(), KeyContainer<int, A1>{1, 1, 1, 2, 2, 2, 3, 3, 3}));
check_possible_values(
m.values(),
- std::vector<std::vector<short>>{
+ std::vector<std::vector<long>>{
{1, 2, 3},
{1, 2, 3},
{1, 2, 3},
diff --git a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/sorted_container.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/sorted_container.pass.cpp
index b07f8ba..b9f491a 100644
--- a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/sorted_container.pass.cpp
+++ b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/sorted_container.pass.cpp
@@ -39,18 +39,18 @@ template <template <class...> class KeyContainer, template <class...> class Valu
constexpr void test() {
{
// flat_multimap(sorted_equivalent_t, key_container_type , mapped_container_type)
- using M = std::flat_multimap<int, char, std::less<int>, KeyContainer<int>, ValueContainer<char>>;
+ using M = std::flat_multimap<int, long, std::less<int>, KeyContainer<int>, ValueContainer<long>>;
KeyContainer<int> ks = {1, 4, 4, 10};
- ValueContainer<char> vs = {4, 3, 2, 1};
+ ValueContainer<long> vs = {4, 3, 2, 1};
auto ks2 = ks;
auto vs2 = vs;
auto m = M(std::sorted_equivalent, ks, vs);
- assert(std::ranges::equal(m, std::vector<std::pair<int, char>>{{1, 4}, {4, 3}, {4, 2}, {10, 1}}));
+ assert(std::ranges::equal(m, std::vector<std::pair<int, long>>{{1, 4}, {4, 3}, {4, 2}, {10, 1}}));
m = M(std::sorted_equivalent, std::move(ks), std::move(vs));
assert(ks.empty()); // it was moved-from
assert(vs.empty()); // it was moved-from
- assert(std::ranges::equal(m, std::vector<std::pair<int, char>>{{1, 4}, {4, 3}, {4, 2}, {10, 1}}));
+ assert(std::ranges::equal(m, std::vector<std::pair<int, long>>{{1, 4}, {4, 3}, {4, 2}, {10, 1}}));
// explicit(false)
M m2 = {std::sorted_equivalent, std::move(ks2), std::move(vs2)};
@@ -60,16 +60,16 @@ constexpr void test() {
// flat_multimap(sorted_equivalent_t, key_container_type , mapped_container_type)
// non-default container, comparator and allocator type
using Ks = KeyContainer<int, min_allocator<int>>;
- using Vs = ValueContainer<char, min_allocator<char>>;
- using M = std::flat_multimap<int, char, std::greater<int>, Ks, Vs>;
+ using Vs = ValueContainer<long, min_allocator<long>>;
+ using M = std::flat_multimap<int, long, std::greater<int>, Ks, Vs>;
Ks ks = {10, 4, 4, 1};
Vs vs = {1, 2, 3, 4};
auto m = M(std::sorted_equivalent, ks, vs);
- assert(std::ranges::equal(m, std::vector<std::pair<int, char>>{{10, 1}, {4, 2}, {4, 3}, {1, 4}}));
+ assert(std::ranges::equal(m, std::vector<std::pair<int, long>>{{10, 1}, {4, 2}, {4, 3}, {1, 4}}));
m = M(std::sorted_equivalent, std::move(ks), std::move(vs));
assert(ks.empty()); // it was moved-from
assert(vs.empty()); // it was moved-from
- assert(std::ranges::equal(m, std::vector<std::pair<int, char>>{{10, 1}, {4, 2}, {4, 3}, {1, 4}}));
+ assert(std::ranges::equal(m, std::vector<std::pair<int, long>>{{10, 1}, {4, 2}, {4, 3}, {1, 4}}));
}
{
// flat_multimap(sorted_equivalent_t, key_container_type , mapped_container_type)
@@ -81,19 +81,19 @@ constexpr void test() {
auto m = M(std::sorted_equivalent, std::move(ks), std::move(vs));
assert(ks.empty()); // it was moved-from
assert(vs.empty()); // it was moved-from
- assert(std::ranges::equal(m, std::vector<std::pair<int, char>>{{1, 4}, {4, 3}, {4, 2}, {10, 1}}));
+ assert(std::ranges::equal(m, std::vector<std::pair<int, long>>{{1, 4}, {4, 3}, {4, 2}, {10, 1}}));
assert(m.keys().get_allocator() == A(4));
assert(m.values().get_allocator() == A(5));
}
{
// flat_multimap(sorted_equivalent_t, key_container_type , mapped_container_type, key_compare)
using C = test_less<int>;
- using M = std::flat_multimap<int, char, C, KeyContainer<int>, ValueContainer<char>>;
+ using M = std::flat_multimap<int, long, C, KeyContainer<int>, ValueContainer<long>>;
KeyContainer<int> ks = {1, 4, 4, 10};
- ValueContainer<char> vs = {4, 3, 2, 1};
+ ValueContainer<long> vs = {4, 3, 2, 1};
auto m = M(std::sorted_equivalent, ks, vs, C(4));
- assert(std::ranges::equal(m, std::vector<std::pair<int, char>>{{1, 4}, {4, 3}, {4, 2}, {10, 1}}));
+ assert(std::ranges::equal(m, std::vector<std::pair<int, long>>{{1, 4}, {4, 3}, {4, 2}, {10, 1}}));
assert(m.key_comp() == C(4));
// explicit(false)
@@ -109,7 +109,7 @@ constexpr void test() {
KeyContainer<int, A> ks = {1, 4, 4, 10};
ValueContainer<int, A> vs = {4, 3, 2, 1};
auto m = M(std::sorted_equivalent, ks, vs, C(4), A(5));
- assert(std::ranges::equal(m, std::vector<std::pair<int, char>>{{1, 4}, {4, 3}, {4, 2}, {10, 1}}));
+ assert(std::ranges::equal(m, std::vector<std::pair<int, long>>{{1, 4}, {4, 3}, {4, 2}, {10, 1}}));
assert(m.key_comp() == C(4));
assert(m.keys().get_allocator() == A(5));
assert(m.values().get_allocator() == A(5));
@@ -130,7 +130,7 @@ constexpr void test() {
auto m = M(std::sorted_equivalent, ks, vs, A(6)); // replaces the allocators
assert(!ks.empty()); // it was an lvalue above
assert(!vs.empty()); // it was an lvalue above
- assert(std::ranges::equal(m, std::vector<std::pair<int, char>>{{1, 4}, {4, 3}, {4, 2}, {10, 1}}));
+ assert(std::ranges::equal(m, std::vector<std::pair<int, long>>{{1, 4}, {4, 3}, {4, 2}, {10, 1}}));
assert(m.keys().get_allocator() == A(6));
assert(m.values().get_allocator() == A(6));
diff --git a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/sorted_initializer_list.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/sorted_initializer_list.pass.cpp
index 555b8d4..4245919 100644
--- a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/sorted_initializer_list.pass.cpp
+++ b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/sorted_initializer_list.pass.cpp
@@ -36,8 +36,8 @@ template <class T, class U>
constexpr std::initializer_list<std::pair<T, U>> il = {{1, 4}, {4, 2}, {4, 4}, {5, 5}};
constexpr auto il1 = il<int, int>;
-constexpr auto il2 = il<int, short>;
-constexpr auto il3 = il<short, int>;
+constexpr auto il2 = il<int, long>;
+constexpr auto il3 = il<long, int>;
template <template <class...> class KeyContainer, template <class...> class ValueContainer>
constexpr void test() {
@@ -74,10 +74,10 @@ constexpr void test() {
{
// flat_multimap(sorted_equivalent_t, initializer_list<value_type>, const Allocator&)
using A1 = test_allocator<int>;
- using A2 = test_allocator<short>;
- using M = std::flat_multimap<int, short, std::less<int>, KeyContainer<int, A1>, ValueContainer<short, A2>>;
+ using A2 = test_allocator<long>;
+ using M = std::flat_multimap<int, long, std::less<int>, KeyContainer<int, A1>, ValueContainer<long, A2>>;
auto m = M(std::sorted_equivalent, il2, A1(5));
- assert(std::ranges::equal(m, std::vector<std::pair<int, short>>{{1, 4}, {4, 2}, {4, 4}, {5, 5}}));
+ assert(std::ranges::equal(m, std::vector<std::pair<int, long>>{{1, 4}, {4, 2}, {4, 4}, {5, 5}}));
assert(m.keys().get_allocator() == A1(5));
assert(m.values().get_allocator() == A2(5));
@@ -91,10 +91,10 @@ constexpr void test() {
// flat_multimap(sorted_equivalent_t, initializer_list<value_type>, const key_compare&, const Allocator&);
using C = test_less<int>;
using A1 = test_allocator<int>;
- using A2 = test_allocator<short>;
- using M = std::flat_multimap<int, short, C, KeyContainer<int, A1>, ValueContainer<short, A2>>;
+ using A2 = test_allocator<long>;
+ using M = std::flat_multimap<int, long, C, KeyContainer<int, A1>, ValueContainer<long, A2>>;
auto m = M(std::sorted_equivalent, il2, C(3), A1(5));
- assert(std::ranges::equal(m, std::vector<std::pair<int, short>>{{1, 4}, {4, 2}, {4, 4}, {5, 5}}));
+ assert(std::ranges::equal(m, std::vector<std::pair<int, long>>{{1, 4}, {4, 2}, {4, 4}, {5, 5}}));
assert(m.key_comp() == C(3));
assert(m.keys().get_allocator() == A1(5));
assert(m.values().get_allocator() == A2(5));
@@ -102,11 +102,11 @@ constexpr void test() {
{
// flat_multimap(sorted_equivalent_t, initializer_list<value_type>, const key_compare&, const Allocator&);
// explicit(false)
- using A1 = test_allocator<short>;
+ using A1 = test_allocator<long>;
using A2 = test_allocator<int>;
- using M = std::flat_multimap<short, int, std::less<int>, KeyContainer<short, A1>, ValueContainer<int, A2>>;
+ using M = std::flat_multimap<long, int, std::less<int>, KeyContainer<long, A1>, ValueContainer<int, A2>>;
M m = {std::sorted_equivalent, il3, {}, A1(5)}; // implicit ctor
- assert(std::ranges::equal(m, std::vector<std::pair<short, int>>{{1, 4}, {4, 2}, {4, 4}, {5, 5}}));
+ assert(std::ranges::equal(m, std::vector<std::pair<long, int>>{{1, 4}, {4, 2}, {4, 4}, {5, 5}}));
assert(m.keys().get_allocator() == A1(5));
assert(m.values().get_allocator() == A2(5));
}
diff --git a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/sorted_iter_iter.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/sorted_iter_iter.pass.cpp
index 72e9695..13e8f27 100644
--- a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/sorted_iter_iter.pass.cpp
+++ b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/sorted_iter_iter.pass.cpp
@@ -68,7 +68,7 @@ constexpr void test() {
auto m = M(std::sorted_equivalent,
cpp17_input_iterator<const P*>(ar),
cpp17_input_iterator<const P*>(ar + 4),
- std::less<int>());
+ std::less<Value>());
assert(std::ranges::equal(m, std::vector<std::pair<int, int>>{{1, 1}, {4, 2}, {4, 4}, {5, 5}}));
assert(m.key_comp()(1, 2) == true);
@@ -76,19 +76,19 @@ constexpr void test() {
M m2 = {std::sorted_equivalent,
cpp17_input_iterator<const P*>(ar),
cpp17_input_iterator<const P*>(ar + 4),
- std::less<int>()};
+ std::less<Value>()};
assert(m2 == m);
}
{
// flat_multimap(sorted_equivalent_t, InputIterator, InputIterator, const key_compare&);
// greater
- using M = std::flat_multimap<Key, Value, std::greater<int>, KeyContainer, ValueContainer>;
+ using M = std::flat_multimap<Key, Value, std::greater<Value>, KeyContainer, ValueContainer>;
using P = std::pair<Key, Value>;
P ar[] = {{5, 5}, {4, 4}, {4, 2}, {1, 1}};
auto m = M(std::sorted_equivalent,
cpp17_input_iterator<const P*>(ar),
cpp17_input_iterator<const P*>(ar + 4),
- std::greater<int>());
+ std::greater<Value>());
assert(std::ranges::equal(m, std::vector<std::pair<int, int>>{{5, 5}, {4, 4}, {4, 2}, {1, 1}}));
}
{
@@ -108,8 +108,8 @@ constexpr void test_alloc() {
{
// flat_multimap(sorted_equivalent_t, InputIterator , InputIterator, const Allocator&)
using A1 = test_allocator<int>;
- using A2 = test_allocator<short>;
- using M = std::flat_multimap<int, short, std::less<int>, KeyContainer<int, A1>, ValueContainer<short, A2>>;
+ using A2 = test_allocator<long>;
+ using M = std::flat_multimap<int, long, std::less<int>, KeyContainer<int, A1>, ValueContainer<long, A2>>;
using P = std::pair<int, int>;
P ar[] = {{1, 1}, {4, 2}, {4, 4}, {5, 5}};
auto m = M(std::sorted_equivalent, ar, ar + 4, A1(5));
@@ -127,8 +127,8 @@ constexpr void test_alloc() {
// flat_multimap(sorted_equivalent_t, InputIterator, InputIterator, const key_compare&, const Allocator&);
using C = test_less<int>;
using A1 = test_allocator<int>;
- using A2 = test_allocator<short>;
- using M = std::flat_multimap<int, short, C, KeyContainer<int, A1>, ValueContainer<short, A2>>;
+ using A2 = test_allocator<long>;
+ using M = std::flat_multimap<int, long, C, KeyContainer<int, A1>, ValueContainer<long, A2>>;
using P = std::pair<int, int>;
P ar[] = {{1, 1}, {4, 2}, {4, 4}, {5, 5}};
auto m = M(std::sorted_equivalent, ar, ar + 4, C(3), A1(5));
@@ -140,9 +140,9 @@ constexpr void test_alloc() {
{
// flat_multimap(sorted_equivalent_t, InputIterator, InputIterator, const key_compare&, const Allocator&);
// explicit(false)
- using A1 = test_allocator<short>;
+ using A1 = test_allocator<long>;
using A2 = test_allocator<int>;
- using M = std::flat_multimap<short, int, std::less<int>, KeyContainer<short, A1>, ValueContainer<int, A2>>;
+ using M = std::flat_multimap<long, int, std::less<int>, KeyContainer<long, A1>, ValueContainer<int, A2>>;
using P = std::pair<int, int>;
P ar[] = {{1, 1}, {4, 2}, {4, 4}, {5, 5}};
M m = {std::sorted_equivalent, ar, ar + 4, {}, A1(5)}; // implicit ctor
diff --git a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.modifiers/erase_key.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.modifiers/erase_key.pass.cpp
index d267c55..36fb34c 100644
--- a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.modifiers/erase_key.pass.cpp
+++ b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.modifiers/erase_key.pass.cpp
@@ -29,7 +29,7 @@
template <class KeyContainer, class ValueContainer, class Compare = std::less<>>
constexpr void test() {
- using M = std::flat_multimap<int, char, Compare, KeyContainer, ValueContainer>;
+ using M = std::flat_multimap<int, long, Compare, KeyContainer, ValueContainer>;
auto make = [](std::initializer_list<int> il) {
M m;
@@ -79,14 +79,14 @@ constexpr void test() {
}
constexpr bool test() {
- test<std::vector<int>, std::vector<char>>();
- test<std::vector<int>, std::vector<char>, std::greater<>>();
+ test<std::vector<int>, std::vector<long>>();
+ test<std::vector<int>, std::vector<long>, std::greater<>>();
#ifndef __cpp_lib_constexpr_deque
if (!TEST_IS_CONSTANT_EVALUATED)
#endif
- test<std::deque<int>, std::vector<char>>();
- test<MinSequenceContainer<int>, MinSequenceContainer<char>>();
- test<std::vector<int, min_allocator<int>>, std::vector<char, min_allocator<char>>>();
+ test<std::deque<int>, std::vector<long>>();
+ test<MinSequenceContainer<int>, MinSequenceContainer<long>>();
+ test<std::vector<int, min_allocator<int>>, std::vector<long, min_allocator<long>>>();
if (!TEST_IS_CONSTANT_EVALUATED) {
auto erase_function = [](auto& m, auto key_arg) {
diff --git a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.observers/comp.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.observers/comp.pass.cpp
index 070fbb0..2b52b47 100644
--- a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.observers/comp.pass.cpp
+++ b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.observers/comp.pass.cpp
@@ -36,7 +36,7 @@ constexpr bool test() {
assert(kc(1, 2));
assert(!kc(2, 1));
auto vc = m.value_comp();
- ASSERT_SAME_TYPE(decltype(vc(std::make_pair(1, 2), std::make_pair(1, 2))), bool);
+ ASSERT_SAME_TYPE(decltype(vc(std::make_pair(1, '2'), std::make_pair(1, '2'))), bool);
assert(vc({1, '2'}, {2, '1'}));
assert(!vc({2, '1'}, {1, '2'}));
}
diff --git a/libcxx/test/std/containers/container.adaptors/flat.multimap/helpers.h b/libcxx/test/std/containers/container.adaptors/flat.multimap/helpers.h
index f3edd3b..ccb3218 100644
--- a/libcxx/test/std/containers/container.adaptors/flat.multimap/helpers.h
+++ b/libcxx/test/std/containers/container.adaptors/flat.multimap/helpers.h
@@ -15,6 +15,7 @@
#include <vector>
#include <flat_map>
#include <ranges>
+#include <type_traits>
#include "../flat_helpers.h"
#include "test_allocator.h"
diff --git a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.cons/compare.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.cons/compare.pass.cpp
index 43ebea7..81f9bbc 100644
--- a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.cons/compare.pass.cpp
+++ b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.cons/compare.pass.cpp
@@ -14,6 +14,7 @@
// template <class Alloc>
// flat_multiset(const key_compare& comp, const Alloc& a);
+#include <cassert>
#include <deque>
#include <flat_set>
#include <functional>
diff --git a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.cons/copy_assign.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.cons/copy_assign.pass.cpp
index 2e63a00..de297f1 100644
--- a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.cons/copy_assign.pass.cpp
+++ b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.cons/copy_assign.pass.cpp
@@ -13,9 +13,11 @@
// flat_multiset& operator=(const flat_multiset& m);
#include <algorithm>
+#include <cassert>
#include <deque>
#include <flat_set>
#include <functional>
+#include <utility>
#include <vector>
#include "operator_hijacker.h"
diff --git a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.cons/dtor_noexcept.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.cons/dtor_noexcept.pass.cpp
index f7243fa..0df0667 100644
--- a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.cons/dtor_noexcept.pass.cpp
+++ b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.cons/dtor_noexcept.pass.cpp
@@ -16,6 +16,7 @@
#include <deque>
#include <flat_set>
#include <functional>
+#include <type_traits>
#include <vector>
#include "test_macros.h"
diff --git a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.cons/move.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.cons/move.pass.cpp
index 7fb0c0e..064baa9 100644
--- a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.cons/move.pass.cpp
+++ b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.cons/move.pass.cpp
@@ -145,7 +145,6 @@ void test_move_noexcept() {
C c;
C d = std::move(c);
}
-#endif // _LIBCPP_VERSION
{
// Comparator fails to be nothrow-move-constructible
using C = std::flat_multiset<int, ThrowingMoveComp>;
@@ -153,6 +152,7 @@ void test_move_noexcept() {
C c;
C d = std::move(c);
}
+#endif // _LIBCPP_VERSION
}
#if !defined(TEST_HAS_NO_EXCEPTIONS)
diff --git a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.cons/move_assign.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.cons/move_assign.pass.cpp
index 62e2181..30c06d2 100644
--- a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.cons/move_assign.pass.cpp
+++ b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.cons/move_assign.pass.cpp
@@ -156,7 +156,7 @@ void test_move_assign_no_except() {
// This tests a conforming extension
{
- using C = std::flat_multiset<int, int>;
+ using C [[maybe_unused]] = std::flat_multiset<int, int>;
LIBCPP_STATIC_ASSERT(std::is_nothrow_move_assignable_v<C>);
}
{
@@ -168,16 +168,17 @@ void test_move_assign_no_except() {
static_assert(!std::is_nothrow_move_assignable_v<C>);
}
{
- using C = std::flat_multiset<MoveOnly, std::less<MoveOnly>, std::vector<MoveOnly, other_allocator<MoveOnly>>>;
+ using C [[maybe_unused]] =
+ std::flat_multiset<MoveOnly, std::less<MoveOnly>, std::vector<MoveOnly, other_allocator<MoveOnly>>>;
LIBCPP_STATIC_ASSERT(std::is_nothrow_move_assignable_v<C>);
}
{
- using C = std::flat_multiset<int, std::less<int>, std::vector<int, other_allocator<int>>>;
+ using C [[maybe_unused]] = std::flat_multiset<int, std::less<int>, std::vector<int, other_allocator<int>>>;
LIBCPP_STATIC_ASSERT(std::is_nothrow_move_assignable_v<C>);
}
{
// Test with a comparator that throws on move-assignment.
- using C = std::flat_multiset<int, MoveThrowsComp>;
+ using C [[maybe_unused]] = std::flat_multiset<int, MoveThrowsComp>;
LIBCPP_STATIC_ASSERT(!std::is_nothrow_move_assignable_v<C>);
}
{
diff --git a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.cons/sorted_iter_iter.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.cons/sorted_iter_iter.pass.cpp
index a3c9981..af2a51a 100644
--- a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.cons/sorted_iter_iter.pass.cpp
+++ b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.cons/sorted_iter_iter.pass.cpp
@@ -147,8 +147,8 @@ constexpr void test() {
{
// flat_multiset(sorted_equivalent_t, InputIterator, InputIterator, const key_compare&, const Allocator&);
// explicit(false)
- using A1 = test_allocator<short>;
- using M = std::flat_multiset<short, std::less<int>, KeyContainer<short, A1>>;
+ using A1 = test_allocator<long>;
+ using M = std::flat_multiset<long, std::less<int>, KeyContainer<long, A1>>;
int ar[] = {1, 2, 4, 4, 5};
M m = {std::sorted_equivalent, ar, ar + 5, {}, A1(5)}; // implicit ctor
assert((m == M{1, 2, 4, 4, 5}));
diff --git a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.iterators/iterator.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.iterators/iterator.pass.cpp
index 878b2b2..ed63897 100644
--- a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.iterators/iterator.pass.cpp
+++ b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.iterators/iterator.pass.cpp
@@ -57,7 +57,7 @@ constexpr void test_one() {
i = m.begin(); // move-assignment
typename M::const_iterator k = i; // converting constructor
assert(i == k); // comparison
- for (int j = 0; j < 9; ++j, ++i) { // pre-increment
+ for (int j = 0; j < 9; ++j, (void)++i) { // pre-increment
assert(*i == expected[j]); // operator*
}
assert(i == m.end());
diff --git a/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/copy_assign.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/copy_assign.pass.cpp
index 59caa9c..33fe457 100644
--- a/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/copy_assign.pass.cpp
+++ b/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/copy_assign.pass.cpp
@@ -13,6 +13,7 @@
// flat_set& operator=(const flat_set& m);
#include <algorithm>
+#include <cassert>
#include <deque>
#include <flat_set>
#include <functional>
diff --git a/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/dtor_noexcept.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/dtor_noexcept.pass.cpp
index 810b13b..1caf58f 100644
--- a/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/dtor_noexcept.pass.cpp
+++ b/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/dtor_noexcept.pass.cpp
@@ -16,6 +16,7 @@
#include <deque>
#include <flat_set>
#include <functional>
+#include <type_traits>
#include <vector>
#include "test_macros.h"
diff --git a/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/move.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/move.pass.cpp
index fcc15ed..b737a5f 100644
--- a/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/move.pass.cpp
+++ b/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/move.pass.cpp
@@ -123,7 +123,6 @@ constexpr void test_move_noexcept() {
C c;
C d = std::move(c);
}
-#endif // _LIBCPP_VERSION
{
// Comparator fails to be nothrow-move-constructible
using C = std::flat_set<int, ThrowingMoveComp, KeyContainer<int>>;
@@ -131,6 +130,7 @@ constexpr void test_move_noexcept() {
C c;
C d = std::move(c);
}
+#endif // _LIBCPP_VERSION
}
constexpr bool test() {
diff --git a/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/move_assign.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/move_assign.pass.cpp
index 1c3affe..e596a67 100644
--- a/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/move_assign.pass.cpp
+++ b/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/move_assign.pass.cpp
@@ -159,7 +159,7 @@ void test_move_assign_no_except() {
// This tests a conforming extension
{
- using C = std::flat_set<int, int>;
+ using C [[maybe_unused]] = std::flat_set<int, int>;
LIBCPP_STATIC_ASSERT(std::is_nothrow_move_assignable_v<C>);
}
{
@@ -171,16 +171,17 @@ void test_move_assign_no_except() {
static_assert(!std::is_nothrow_move_assignable_v<C>);
}
{
- using C = std::flat_set<MoveOnly, std::less<MoveOnly>, std::vector<MoveOnly, other_allocator<MoveOnly>>>;
+ using C [[maybe_unused]] =
+ std::flat_set<MoveOnly, std::less<MoveOnly>, std::vector<MoveOnly, other_allocator<MoveOnly>>>;
LIBCPP_STATIC_ASSERT(std::is_nothrow_move_assignable_v<C>);
}
{
- using C = std::flat_set<int, std::less<int>, std::vector<int, other_allocator<int>>>;
+ using C [[maybe_unused]] = std::flat_set<int, std::less<int>, std::vector<int, other_allocator<int>>>;
LIBCPP_STATIC_ASSERT(std::is_nothrow_move_assignable_v<C>);
}
{
// Test with a comparator that throws on move-assignment.
- using C = std::flat_set<int, MoveThrowsComp>;
+ using C [[maybe_unused]] = std::flat_set<int, MoveThrowsComp>;
LIBCPP_STATIC_ASSERT(!std::is_nothrow_move_assignable_v<C>);
}
{
diff --git a/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/sorted_iter_iter.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/sorted_iter_iter.pass.cpp
index 7ffb09e..2550ed2 100644
--- a/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/sorted_iter_iter.pass.cpp
+++ b/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/sorted_iter_iter.pass.cpp
@@ -128,8 +128,8 @@ constexpr void test_alloc() {
{
// flat_set(sorted_unique_t, InputIterator, InputIterator, const key_compare&, const Allocator&);
// explicit(false)
- using A1 = test_allocator<short>;
- using M = std::flat_set<short, std::less<int>, KeyContainer<short, A1>>;
+ using A1 = test_allocator<long>;
+ using M = std::flat_set<long, std::less<int>, KeyContainer<long, A1>>;
int ar[] = {1, 2, 4, 5};
M m = {std::sorted_unique, ar, ar + 4, {}, A1(5)}; // implicit ctor
assert((m == M{1, 2, 4, 5}));
diff --git a/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.iterators/iterator.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.iterators/iterator.pass.cpp
index 8aafa97..d79a1db 100644
--- a/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.iterators/iterator.pass.cpp
+++ b/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.iterators/iterator.pass.cpp
@@ -56,7 +56,7 @@ constexpr void test_one() {
i = m.begin(); // move-assignment
typename M::const_iterator k = i; // converting constructor
assert(i == k); // comparison
- for (int j = 1; j <= 4; ++j, ++i) { // pre-increment
+ for (int j = 1; j <= 4; ++j, (void)++i) { // pre-increment
assert(*i == j); // operator*
}
assert(i == m.end());
diff --git a/libcxx/test/std/containers/container.adaptors/stack/stack.cons/ctor_iterators.pass.cpp b/libcxx/test/std/containers/container.adaptors/stack/stack.cons/ctor_iterators.pass.cpp
index 5981f91..afd5a63 100644
--- a/libcxx/test/std/containers/container.adaptors/stack/stack.cons/ctor_iterators.pass.cpp
+++ b/libcxx/test/std/containers/container.adaptors/stack/stack.cons/ctor_iterators.pass.cpp
@@ -15,6 +15,7 @@
#include <cassert>
#include <stack>
+#include <type_traits>
#include "test_allocator.h"
diff --git a/libcxx/test/std/containers/container.requirements/container.requirements.general/allocator_move.pass.cpp b/libcxx/test/std/containers/container.requirements/container.requirements.general/allocator_move.pass.cpp
index 5de5579..e927bfc 100644
--- a/libcxx/test/std/containers/container.requirements/container.requirements.general/allocator_move.pass.cpp
+++ b/libcxx/test/std/containers/container.requirements/container.requirements.general/allocator_move.pass.cpp
@@ -13,6 +13,7 @@
// belonging to the container being moved. Such move construction of the
// allocator shall not exit via an exception.
+#include <cassert>
#include <vector>
#include <deque>
#include <list>
diff --git a/libcxx/test/std/containers/sequences/array/array.creation/to_array.verify.cpp b/libcxx/test/std/containers/sequences/array/array.creation/to_array.verify.cpp
index e3efef98..ee8d8e6 100644
--- a/libcxx/test/std/containers/sequences/array/array.creation/to_array.verify.cpp
+++ b/libcxx/test/std/containers/sequences/array/array.creation/to_array.verify.cpp
@@ -22,21 +22,21 @@ int main(int, char**) {
// expected-error@array:* {{to_array does not accept multidimensional arrays}}
// expected-error@array:* {{to_array requires copy constructible elements}}
// expected-error@array:* 3 {{cannot initialize}}
- std::to_array(source); // expected-note {{requested here}}
+ (void)std::to_array(source); // expected-note {{requested here}}
}
{
MoveOnly mo[] = {MoveOnly{3}};
// expected-error@array:* {{to_array requires copy constructible elements}}
// expected-error-re@array:* 1-2{{{{(call to implicitly-deleted copy constructor of 'MoveOnly')|(call to deleted constructor of 'MoveOnly')}}}}
- std::to_array(mo); // expected-note {{requested here}}
+ (void)std::to_array(mo); // expected-note {{requested here}}
}
{
const MoveOnly cmo[] = {MoveOnly{3}};
// expected-error@array:* {{to_array requires move constructible elements}}
// expected-error-re@array:* 0-1{{{{(call to implicitly-deleted copy constructor of 'MoveOnly')|(call to deleted constructor of 'MoveOnly')}}}}
- std::to_array(std::move(cmo)); // expected-note {{requested here}}
+ (void)std::to_array(std::move(cmo)); // expected-note {{requested here}}
}
return 0;
diff --git a/libcxx/test/std/containers/sequences/deque/deque.cons/dtor_noexcept.pass.cpp b/libcxx/test/std/containers/sequences/deque/deque.cons/dtor_noexcept.pass.cpp
index f0a8394..338a0fa 100644
--- a/libcxx/test/std/containers/sequences/deque/deque.cons/dtor_noexcept.pass.cpp
+++ b/libcxx/test/std/containers/sequences/deque/deque.cons/dtor_noexcept.pass.cpp
@@ -12,8 +12,9 @@
// UNSUPPORTED: c++03
-#include <deque>
#include <cassert>
+#include <deque>
+#include <type_traits>
#include "test_macros.h"
#include "MoveOnly.h"
diff --git a/libcxx/test/std/containers/sequences/forwardlist/forwardlist.cons/dtor_noexcept.pass.cpp b/libcxx/test/std/containers/sequences/forwardlist/forwardlist.cons/dtor_noexcept.pass.cpp
index 64c60af..8d474cf 100644
--- a/libcxx/test/std/containers/sequences/forwardlist/forwardlist.cons/dtor_noexcept.pass.cpp
+++ b/libcxx/test/std/containers/sequences/forwardlist/forwardlist.cons/dtor_noexcept.pass.cpp
@@ -12,8 +12,9 @@
// UNSUPPORTED: c++03
-#include <forward_list>
#include <cassert>
+#include <forward_list>
+#include <type_traits>
#include "test_macros.h"
#include "MoveOnly.h"
diff --git a/libcxx/test/std/containers/sequences/list/list.cons/dtor_noexcept.pass.cpp b/libcxx/test/std/containers/sequences/list/list.cons/dtor_noexcept.pass.cpp
index 44e6ddd..4ebe19f 100644
--- a/libcxx/test/std/containers/sequences/list/list.cons/dtor_noexcept.pass.cpp
+++ b/libcxx/test/std/containers/sequences/list/list.cons/dtor_noexcept.pass.cpp
@@ -12,8 +12,9 @@
// UNSUPPORTED: c++03
-#include <list>
#include <cassert>
+#include <list>
+#include <type_traits>
#include "test_macros.h"
#include "MoveOnly.h"
diff --git a/libcxx/test/std/containers/sequences/vector.bool/assign_move.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/assign_move.pass.cpp
index 8791380..2200367 100644
--- a/libcxx/test/std/containers/sequences/vector.bool/assign_move.pass.cpp
+++ b/libcxx/test/std/containers/sequences/vector.bool/assign_move.pass.cpp
@@ -14,6 +14,7 @@
// vector& operator=(vector&& c);
#include <cassert>
+#include <utility>
#include <vector>
#include "min_allocator.h"
diff --git a/libcxx/test/std/containers/sequences/vector.bool/default_noexcept.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/default_noexcept.pass.cpp
index 0801709..a95d358 100644
--- a/libcxx/test/std/containers/sequences/vector.bool/default_noexcept.pass.cpp
+++ b/libcxx/test/std/containers/sequences/vector.bool/default_noexcept.pass.cpp
@@ -16,8 +16,9 @@
// For vector<>, this was added to the standard by N4258,
// but vector<bool> was not changed.
-#include <vector>
#include <cassert>
+#include <vector>
+#include <type_traits>
#include "test_macros.h"
#include "test_allocator.h"
diff --git a/libcxx/test/std/containers/sequences/vector.bool/dtor_noexcept.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/dtor_noexcept.pass.cpp
index f8f3c76..6a6ca6b 100644
--- a/libcxx/test/std/containers/sequences/vector.bool/dtor_noexcept.pass.cpp
+++ b/libcxx/test/std/containers/sequences/vector.bool/dtor_noexcept.pass.cpp
@@ -12,8 +12,9 @@
// UNSUPPORTED: c++03
-#include <vector>
#include <cassert>
+#include <vector>
+#include <type_traits>
#include "test_macros.h"
#include "test_allocator.h"
diff --git a/libcxx/test/std/containers/sequences/vector.bool/move_assign_noexcept.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/move_assign_noexcept.pass.cpp
index 5a69213..e5add73 100644
--- a/libcxx/test/std/containers/sequences/vector.bool/move_assign_noexcept.pass.cpp
+++ b/libcxx/test/std/containers/sequences/vector.bool/move_assign_noexcept.pass.cpp
@@ -17,8 +17,9 @@
// UNSUPPORTED: c++03
-#include <vector>
#include <cassert>
+#include <vector>
+#include <type_traits>
#include "test_macros.h"
#include "test_allocator.h"
diff --git a/libcxx/test/std/containers/sequences/vector.bool/move_noexcept.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/move_noexcept.pass.cpp
index d0d231f..5bdae01 100644
--- a/libcxx/test/std/containers/sequences/vector.bool/move_noexcept.pass.cpp
+++ b/libcxx/test/std/containers/sequences/vector.bool/move_noexcept.pass.cpp
@@ -15,8 +15,9 @@
// UNSUPPORTED: c++03
-#include <vector>
#include <cassert>
+#include <vector>
+#include <type_traits>
#include "test_macros.h"
#include "test_allocator.h"
diff --git a/libcxx/test/std/containers/sequences/vector/vector.cons/dtor_noexcept.pass.cpp b/libcxx/test/std/containers/sequences/vector/vector.cons/dtor_noexcept.pass.cpp
index 4a7e2cf..331b360 100644
--- a/libcxx/test/std/containers/sequences/vector/vector.cons/dtor_noexcept.pass.cpp
+++ b/libcxx/test/std/containers/sequences/vector/vector.cons/dtor_noexcept.pass.cpp
@@ -12,8 +12,9 @@
// UNSUPPORTED: c++03
-#include <vector>
#include <cassert>
+#include <vector>
+#include <type_traits>
#include "test_macros.h"
#include "MoveOnly.h"
diff --git a/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/dtor_noexcept.pass.cpp b/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/dtor_noexcept.pass.cpp
index 5797599..cf148fd 100644
--- a/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/dtor_noexcept.pass.cpp
+++ b/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/dtor_noexcept.pass.cpp
@@ -12,8 +12,9 @@
// UNSUPPORTED: c++03
-#include <unordered_map>
#include <cassert>
+#include <unordered_map>
+#include <type_traits>
#include "test_macros.h"
#include "MoveOnly.h"
diff --git a/libcxx/test/std/containers/unord/unord.map/unord.map.modifiers/erase_range.pass.cpp b/libcxx/test/std/containers/unord/unord.map/unord.map.modifiers/erase_range.pass.cpp
index 5324134..8137163 100644
--- a/libcxx/test/std/containers/unord/unord.map/unord.map.modifiers/erase_range.pass.cpp
+++ b/libcxx/test/std/containers/unord/unord.map/unord.map.modifiers/erase_range.pass.cpp
@@ -57,6 +57,28 @@ int main(int, char**) {
assert(c.size() == 0);
assert(k == c.end());
}
+ { // Make sure that we're properly updating the bucket list when we're erasing to the end
+ std::unordered_map<int, int> m;
+ m.insert(std::make_pair(1, 1));
+ m.insert(std::make_pair(2, 2));
+
+ {
+ auto pair = m.equal_range(1);
+ assert(pair.first != pair.second);
+ m.erase(pair.first, pair.second);
+ }
+
+ {
+ auto pair = m.equal_range(2);
+ assert(pair.first != pair.second);
+ m.erase(pair.first, pair.second);
+ }
+
+ m.insert(std::make_pair(3, 3));
+ assert(m.size() == 1);
+ assert(*m.begin() == std::make_pair(3, 3));
+ assert(++m.begin() == m.end());
+ }
#if TEST_STD_VER >= 11
{
typedef std::unordered_map<int,
diff --git a/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/dtor_noexcept.pass.cpp b/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/dtor_noexcept.pass.cpp
index 6fdc9e3..2771e64 100644
--- a/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/dtor_noexcept.pass.cpp
+++ b/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/dtor_noexcept.pass.cpp
@@ -12,8 +12,9 @@
// UNSUPPORTED: c++03
-#include <unordered_map>
#include <cassert>
+#include <unordered_map>
+#include <type_traits>
#include "test_macros.h"
#include "MoveOnly.h"
diff --git a/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/erase_range.pass.cpp b/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/erase_range.pass.cpp
index 38b75c0..aa6bc20 100644
--- a/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/erase_range.pass.cpp
+++ b/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/erase_range.pass.cpp
@@ -122,6 +122,28 @@ int main(int, char**) {
for (const auto& v : map)
assert(v.first == 1 || v.first == collision_val);
}
+ { // Make sure that we're properly updating the bucket list when we're erasing to the end
+ std::unordered_multimap<int, int> m;
+ m.insert(std::make_pair(1, 1));
+ m.insert(std::make_pair(2, 2));
+
+ {
+ auto pair = m.equal_range(1);
+ assert(pair.first != pair.second);
+ m.erase(pair.first, pair.second);
+ }
+
+ {
+ auto pair = m.equal_range(2);
+ assert(pair.first != pair.second);
+ m.erase(pair.first, pair.second);
+ }
+
+ m.insert(std::make_pair(3, 3));
+ assert(m.size() == 1);
+ assert(*m.begin() == std::make_pair(3, 3));
+ assert(++m.begin() == m.end());
+ }
#if TEST_STD_VER >= 11
{
typedef std::unordered_multimap<int,
diff --git a/libcxx/test/std/containers/unord/unord.multiset/erase_range.pass.cpp b/libcxx/test/std/containers/unord/unord.multiset/erase_range.pass.cpp
index 3bc686e..013e052 100644
--- a/libcxx/test/std/containers/unord/unord.multiset/erase_range.pass.cpp
+++ b/libcxx/test/std/containers/unord/unord.multiset/erase_range.pass.cpp
@@ -64,6 +64,28 @@ int main(int, char**) {
for (const auto& v : map)
assert(v == 1 || v == collision_val);
}
+ { // Make sure that we're properly updating the bucket list when we're erasing to the end
+ std::unordered_multiset<int> m;
+ m.insert(1);
+ m.insert(2);
+
+ {
+ auto pair = m.equal_range(1);
+ assert(pair.first != pair.second);
+ m.erase(pair.first, pair.second);
+ }
+
+ {
+ auto pair = m.equal_range(2);
+ assert(pair.first != pair.second);
+ m.erase(pair.first, pair.second);
+ }
+
+ m.insert(3);
+ assert(m.size() == 1);
+ assert(*m.begin() == 3);
+ assert(++m.begin() == m.end());
+ }
#if TEST_STD_VER >= 11
{
typedef std::unordered_multiset<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> C;
diff --git a/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/dtor_noexcept.pass.cpp b/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/dtor_noexcept.pass.cpp
index 32c757e1..c48c286 100644
--- a/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/dtor_noexcept.pass.cpp
+++ b/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/dtor_noexcept.pass.cpp
@@ -12,8 +12,9 @@
// UNSUPPORTED: c++03
-#include <unordered_set>
#include <cassert>
+#include <unordered_set>
+#include <type_traits>
#include "test_macros.h"
#include "MoveOnly.h"
diff --git a/libcxx/test/std/containers/unord/unord.set/erase_range.pass.cpp b/libcxx/test/std/containers/unord/unord.set/erase_range.pass.cpp
index 5fa6e41..1f049a2 100644
--- a/libcxx/test/std/containers/unord/unord.set/erase_range.pass.cpp
+++ b/libcxx/test/std/containers/unord/unord.set/erase_range.pass.cpp
@@ -47,6 +47,28 @@ int main(int, char**) {
assert(c.size() == 0);
assert(k == c.end());
}
+ { // Make sure that we're properly updating the bucket list when we're erasing to the end
+ std::unordered_set<int> m;
+ m.insert(1);
+ m.insert(2);
+
+ {
+ auto pair = m.equal_range(1);
+ assert(pair.first != pair.second);
+ m.erase(pair.first, pair.second);
+ }
+
+ {
+ auto pair = m.equal_range(2);
+ assert(pair.first != pair.second);
+ m.erase(pair.first, pair.second);
+ }
+
+ m.insert(3);
+ assert(m.size() == 1);
+ assert(*m.begin() == 3);
+ assert(++m.begin() == m.end());
+ }
#if TEST_STD_VER >= 11
{
typedef std::unordered_set<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> C;
diff --git a/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/dtor_noexcept.pass.cpp b/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/dtor_noexcept.pass.cpp
index 17cfae0..2939e36 100644
--- a/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/dtor_noexcept.pass.cpp
+++ b/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/dtor_noexcept.pass.cpp
@@ -12,8 +12,9 @@
// UNSUPPORTED: c++03
-#include <unordered_set>
#include <cassert>
+#include <unordered_set>
+#include <type_traits>
#include "test_macros.h"
#include "MoveOnly.h"
diff --git a/libcxx/test/std/depr/depr.cpp.headers/ccomplex.verify.cpp b/libcxx/test/std/depr/depr.cpp.headers/ccomplex.verify.cpp
index 0eaf82ce..900ca0e 100644
--- a/libcxx/test/std/depr/depr.cpp.headers/ccomplex.verify.cpp
+++ b/libcxx/test/std/depr/depr.cpp.headers/ccomplex.verify.cpp
@@ -14,12 +14,11 @@
// UNSUPPORTED: c++03, c++11, c++14
// UNSUPPORTED: clang-modules-build
-#include "test_macros.h"
+// FIXME: using `#warning` causes diagnostics from system headers which include deprecated headers. This can only be
+// enabled again once https://github.com/llvm/llvm-project/pull/168041 (or a similar feature) has landed, since that
+// allows suppression in system headers.
+// XFAIL: *
#include <ccomplex>
-#if TEST_STD_VER >= 20
-// expected-warning@ccomplex:* {{'__standard_header_ccomplex' is deprecated: removed in C++20. Include <complex> instead.}}
-#else
-// expected-warning@ccomplex:* {{'__standard_header_ccomplex' is deprecated: Include <complex> instead.}}
-#endif
+// expected-warning@ccomplex:* {{<ccomplex> is deprecated in C++17 and removed in C++20. Include <complex> instead.}}
diff --git a/libcxx/test/std/depr/depr.cpp.headers/ciso646.verify.cpp b/libcxx/test/std/depr/depr.cpp.headers/ciso646.verify.cpp
index 04acd10..a1ca842 100644
--- a/libcxx/test/std/depr/depr.cpp.headers/ciso646.verify.cpp
+++ b/libcxx/test/std/depr/depr.cpp.headers/ciso646.verify.cpp
@@ -14,5 +14,11 @@
// UNSUPPORTED: c++03, c++11, c++14, c++17
// UNSUPPORTED: clang-modules-build
+// FIXME: using `#warning` causes diagnostics from system headers which include deprecated headers. This can only be
+// enabled again once https://github.com/llvm/llvm-project/pull/168041 (or a similar feature) has landed, since that
+// allows suppression in system headers.
+// XFAIL: *
+
#include <ciso646>
-// expected-warning@ciso646:* {{'__standard_header_ciso646' is deprecated: removed in C++20. Include <version> instead.}}
+
+// expected-warning@ciso646:* {{<ciso646> is removed in C++20. Include <version> instead.}}
diff --git a/libcxx/test/std/depr/depr.cpp.headers/cstdalign.verify.cpp b/libcxx/test/std/depr/depr.cpp.headers/cstdalign.verify.cpp
index dc9f1af..503a876 100644
--- a/libcxx/test/std/depr/depr.cpp.headers/cstdalign.verify.cpp
+++ b/libcxx/test/std/depr/depr.cpp.headers/cstdalign.verify.cpp
@@ -14,12 +14,11 @@
// UNSUPPORTED: c++03, c++11, c++14
// UNSUPPORTED: clang-modules-build
-#include "test_macros.h"
+// FIXME: using `#warning` causes diagnostics from system headers which include deprecated headers. This can only be
+// enabled again once https://github.com/llvm/llvm-project/pull/168041 (or a similar feature) has landed, since that
+// allows suppression in system headers.
+// XFAIL: *
#include <cstdalign>
-#if TEST_STD_VER >= 20
-// expected-warning@cstdalign:* {{'__standard_header_cstdalign' is deprecated: removed in C++20.}}
-#else
-// expected-warning@cstdalign:* {{'__standard_header_cstdalign' is deprecated}}
-#endif
+// expected-warning@cstdalign:* {{<cstdalign> is deprecated in C++17 and removed in C++20.}}
diff --git a/libcxx/test/std/depr/depr.cpp.headers/cstdbool.verify.cpp b/libcxx/test/std/depr/depr.cpp.headers/cstdbool.verify.cpp
index eddefe1..80025c5 100644
--- a/libcxx/test/std/depr/depr.cpp.headers/cstdbool.verify.cpp
+++ b/libcxx/test/std/depr/depr.cpp.headers/cstdbool.verify.cpp
@@ -14,12 +14,11 @@
// UNSUPPORTED: c++03, c++11, c++14
// UNSUPPORTED: clang-modules-build
-#include "test_macros.h"
+// FIXME: using `#warning` causes diagnostics from system headers which include deprecated headers. This can only be
+// enabled again once https://github.com/llvm/llvm-project/pull/168041 (or a similar feature) has landed, since that
+// allows suppression in system headers.
+// XFAIL: *
#include <cstdbool>
-#if TEST_STD_VER >= 20
-// expected-warning@cstdbool:* {{'__standard_header_cstdbool' is deprecated: removed in C++20.}}
-#else
-// expected-warning@cstdbool:* {{'__standard_header_cstdbool' is deprecated}}
-#endif
+// expected-warning@cstdbool:* {{<cstdbool> is deprecated in C++17 and removed in C++20.}}
diff --git a/libcxx/test/std/depr/depr.cpp.headers/ctgmath.verify.cpp b/libcxx/test/std/depr/depr.cpp.headers/ctgmath.verify.cpp
index 097ab16..07bdd29 100644
--- a/libcxx/test/std/depr/depr.cpp.headers/ctgmath.verify.cpp
+++ b/libcxx/test/std/depr/depr.cpp.headers/ctgmath.verify.cpp
@@ -14,12 +14,11 @@
// UNSUPPORTED: c++03, c++11, c++14
// UNSUPPORTED: clang-modules-build
-#include "test_macros.h"
+// FIXME: using `#warning` causes diagnostics from system headers which include deprecated headers. This can only be
+// enabled again once https://github.com/llvm/llvm-project/pull/168041 (or a similar feature) has landed, since that
+// allows suppression in system headers.
+// XFAIL: *
#include <ctgmath>
-#if TEST_STD_VER >= 20
-// expected-warning@ctgmath:* {{'__standard_header_ctgmath' is deprecated: removed in C++20. Include <cmath> and <complex> instead.}}
-#else
-// expected-warning@ctgmath:* {{'__standard_header_ctgmath' is deprecated: Include <cmath> and <complex> instead.}}
-#endif
+// expected-warning@ctgmath:* {{<ctgmath> is deprecated in C++17 and removed in C++20. Include <cmath> and <complex> instead.}}
diff --git a/libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/generic_category.pass.cpp b/libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/generic_category.pass.cpp
index 5425203..513af522 100644
--- a/libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/generic_category.pass.cpp
+++ b/libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/generic_category.pass.cpp
@@ -48,7 +48,7 @@ int main(int, char**)
// responds with an empty message, which we probably want to
// treat as a failure code otherwise, but we can detect that
// with the preprocessor.
-#if defined(_NEWLIB_VERSION)
+#if _LIBCPP_LIBC_NEWLIB
const bool is_newlib = true;
#else
const bool is_newlib = false;
diff --git a/libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/system_category.pass.cpp b/libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/system_category.pass.cpp
index 255cbe7..1803c0a1 100644
--- a/libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/system_category.pass.cpp
+++ b/libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/system_category.pass.cpp
@@ -59,7 +59,7 @@ int main(int, char**) {
// responds with an empty message, which we probably want to
// treat as a failure code otherwise, but we can detect that
// with the preprocessor.
-#if defined(_NEWLIB_VERSION)
+#if _LIBCPP_LIBC_NEWLIB
const bool is_newlib = true;
#else
const bool is_newlib = false;
diff --git a/libcxx/test/std/input.output/file.streams/c.files/gets.compile.fail.cpp b/libcxx/test/std/input.output/file.streams/c.files/gets-removed.verify.cpp
index 1a92cc9..fb49375 100644
--- a/libcxx/test/std/input.output/file.streams/c.files/gets.compile.fail.cpp
+++ b/libcxx/test/std/input.output/file.streams/c.files/gets-removed.verify.cpp
@@ -7,15 +7,11 @@
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++03, c++11
-// test <cstdio>
-// gets
+// Verify that std::gets has been removed in C++14 and later
#include <cstdio>
-int main(int, char**)
-{
- (void) std::gets((char *) NULL);
-
- return 0;
+void f(char* str) {
+ (void)std::gets(str); // expected-error {{no member named 'gets' in namespace 'std'}}
}
diff --git a/libcxx/test/std/input.output/file.streams/fstreams/ifstream.members/xsgetn.pass.cpp b/libcxx/test/std/input.output/file.streams/fstreams/ifstream.members/xsgetn.pass.cpp
new file mode 100644
index 0000000..de17cd4
--- /dev/null
+++ b/libcxx/test/std/input.output/file.streams/fstreams/ifstream.members/xsgetn.pass.cpp
@@ -0,0 +1,73 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// FILE_DEPENDENCIES: xsgetn.test.dat
+
+// <fstream>
+
+// template <class charT, class traits = char_traits<charT> >
+// class basic_ifstream
+
+// streamsize xsgetn(char_type*, streamsize) override;
+
+// This isn't a required override by the standard, but most implementations
+// override it, since it allows for significantly improved performance in some
+// cases. All of this code is required to work, so this isn't a libc++ extension
+
+#include <cassert>
+#include <fstream>
+#include <vector>
+
+#include "test_macros.h"
+
+int main(int, char**) {
+ std::vector<char> stream_buffer(10);
+ std::ifstream fs("xsgetn.test.dat");
+ std::filebuf* fb = fs.rdbuf();
+ fb->pubsetbuf(stream_buffer.data(), 10);
+
+ // Ensure that the buffer is set up
+ assert(fb->sgetc() == 't');
+
+ std::vector<char> test_buffer(5);
+ test_buffer[0] = '\0';
+
+ { // Check that a read smaller than the buffer works fine
+ assert(fb->sgetn(test_buffer.data(), 5) == 5);
+ assert(std::string(test_buffer.data(), 5) == "this ");
+ }
+ { // Check that reading up to the buffer end works fine
+ assert(fb->sgetn(test_buffer.data(), 5) == 5);
+ assert(std::string(test_buffer.data(), 5) == "is so");
+ }
+ { // Check that reading from an empty buffer, but more than the buffer can
+ // hold works fine
+ test_buffer.resize(12);
+ assert(fb->sgetn(test_buffer.data(), 12) == 12);
+ assert(std::string(test_buffer.data(), 12) == "me random da");
+ }
+ { // Check that reading from a non-empty buffer, and more than the buffer can
+ // hold works fine Fill the buffer up
+ test_buffer.resize(2);
+ assert(fb->sgetn(test_buffer.data(), 2) == 2);
+ assert(std::string(test_buffer.data(), 2) == "ta");
+
+ // Do the actual check
+ test_buffer.resize(12);
+ assert(fb->sgetn(test_buffer.data(), 12) == 12);
+ assert(std::string(test_buffer.data(), 12) == " to be able ");
+ }
+ { // Check that trying to read more than the file size works fine
+ test_buffer.resize(30);
+ assert(fb->sgetn(test_buffer.data(), 30) == 24);
+ test_buffer.resize(24);
+ assert(std::string(test_buffer.data(), 24) == "to test buffer behaviour");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/std/input.output/file.streams/fstreams/ifstream.members/xsgetn.test.dat b/libcxx/test/std/input.output/file.streams/fstreams/ifstream.members/xsgetn.test.dat
new file mode 100644
index 0000000..06d663b
--- /dev/null
+++ b/libcxx/test/std/input.output/file.streams/fstreams/ifstream.members/xsgetn.test.dat
@@ -0,0 +1 @@
+this is some random data to be able to test buffer behaviour \ No newline at end of file
diff --git a/libcxx/test/std/input.output/filesystems/class.path/path.member/path.append.pass.cpp b/libcxx/test/std/input.output/filesystems/class.path/path.member/path.append.pass.cpp
index b3d87ee..65c4dab 100644
--- a/libcxx/test/std/input.output/filesystems/class.path/path.member/path.append.pass.cpp
+++ b/libcxx/test/std/input.output/filesystems/class.path/path.member/path.append.pass.cpp
@@ -32,6 +32,7 @@
#include <type_traits>
#include <string_view>
#include <cassert>
+#include <utility>
// On Windows, the append function converts all inputs (pointers, iterators)
// to an intermediate path object, causing allocations in cases where no
diff --git a/libcxx/test/std/input.output/filesystems/class.path/path.member/path.concat.pass.cpp b/libcxx/test/std/input.output/filesystems/class.path/path.member/path.concat.pass.cpp
index 96de72b..d4a3273 100644
--- a/libcxx/test/std/input.output/filesystems/class.path/path.member/path.concat.pass.cpp
+++ b/libcxx/test/std/input.output/filesystems/class.path/path.member/path.concat.pass.cpp
@@ -39,6 +39,7 @@
#include <string>
#include <string_view>
#include <cassert>
+#include <utility>
// On Windows, charset conversions cause allocations in the path class in
// cases where no allocations are done on other platforms.
diff --git a/libcxx/test/std/language.support/support.dynamic/hardware_inference_size.compile.pass.cpp b/libcxx/test/std/language.support/support.dynamic/hardware_inference_size.compile.pass.cpp
index 2656f05..aed3d42 100644
--- a/libcxx/test/std/language.support/support.dynamic/hardware_inference_size.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.dynamic/hardware_inference_size.compile.pass.cpp
@@ -7,7 +7,6 @@
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++03, c++11, c++14
-// UNSUPPORTED: (clang || apple-clang) && stdlib=libc++
#include <new>
diff --git a/libcxx/test/std/language.support/support.limits/limits/numeric.limits.members/traps.pass.cpp b/libcxx/test/std/language.support/support.limits/limits/numeric.limits.members/traps.pass.cpp
index 66e149b..c08f9db 100644
--- a/libcxx/test/std/language.support/support.limits/limits/numeric.limits.members/traps.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/limits/numeric.limits.members/traps.pass.cpp
@@ -10,6 +10,8 @@
// traps
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
+
#include <limits>
#include "test_macros.h"
@@ -33,17 +35,17 @@ test()
int main(int, char**)
{
test<bool, false>();
- test<char, integral_types_trap>();
- test<signed char, integral_types_trap>();
- test<unsigned char, integral_types_trap>();
- test<wchar_t, integral_types_trap>();
+ test<char, false>();
+ test<signed char, false>();
+ test<unsigned char, false>();
+ test<wchar_t, false>();
#if TEST_STD_VER > 17 && defined(__cpp_char8_t)
- test<char8_t, integral_types_trap>();
+ test<char8_t, false>();
#endif
- test<char16_t, integral_types_trap>();
- test<char32_t, integral_types_trap>();
- test<short, integral_types_trap>();
- test<unsigned short, integral_types_trap>();
+ test<char16_t, false>();
+ test<char32_t, false>();
+ test<short, false>();
+ test<unsigned short, false>();
test<int, integral_types_trap>();
test<unsigned int, integral_types_trap>();
test<long, integral_types_trap>();
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/optional.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/optional.version.compile.pass.cpp
index aca6290..c4e6529 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/optional.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/optional.version.compile.pass.cpp
@@ -142,8 +142,8 @@
# ifndef __cpp_lib_optional
# error "__cpp_lib_optional should be defined in c++26"
# endif
-# if __cpp_lib_optional != 202110L
-# error "__cpp_lib_optional should have the value 202110L in c++26"
+# if __cpp_lib_optional != 202506L
+# error "__cpp_lib_optional should have the value 202506L in c++26"
# endif
# ifndef __cpp_lib_optional_range_support
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
index 8189c5c..996ec29 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
@@ -7509,8 +7509,8 @@
# ifndef __cpp_lib_optional
# error "__cpp_lib_optional should be defined in c++26"
# endif
-# if __cpp_lib_optional != 202110L
-# error "__cpp_lib_optional should have the value 202110L in c++26"
+# if __cpp_lib_optional != 202506L
+# error "__cpp_lib_optional should have the value 202506L in c++26"
# endif
# ifndef __cpp_lib_optional_range_support
diff --git a/libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_long.pass.cpp b/libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_long.pass.cpp
index 0154082..45b0348 100644
--- a/libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_long.pass.cpp
+++ b/libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_long.pass.cpp
@@ -13,6 +13,8 @@
// iter_type get(iter_type in, iter_type end, ios_base&,
// ios_base::iostate& err, long& v) const;
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
+
#include <locale>
#include <ios>
#include <cassert>
@@ -99,6 +101,18 @@ int main(int, char**)
assert(v == 291);
}
{
+ const char str[] = "a123";
+ std::dec(ios);
+ std::ios_base::iostate err = ios.goodbit;
+ cpp17_input_iterator<const char*> iter =
+ f.get(cpp17_input_iterator<const char*>(str),
+ cpp17_input_iterator<const char*>(str+sizeof(str)),
+ ios, err, v);
+ assert(base(iter) == str);
+ assert(err == ios.failbit);
+ assert(v == 0);
+ }
+ {
const char str[] = "0x123";
std::hex(ios);
std::ios_base::iostate err = ios.goodbit;
@@ -519,6 +533,238 @@ int main(int, char**)
assert(err == ios.failbit);
assert(v == std::numeric_limits<long>::max());
}
+ {
+ v = -1;
+ const char str[] = "";
+ std::ios_base::iostate err = ios.goodbit;
+
+ cpp17_input_iterator<const char*> iter =
+ f.get(cpp17_input_iterator<const char*>(str), cpp17_input_iterator<const char*>(str), ios, err, v);
+ assert(base(iter) == str);
+ assert(err == (std::ios::eofbit | std::ios::failbit));
+ assert(v == 0);
+ }
+ {
+ v = -1;
+ const char str[] = "+";
+ std::ios_base::iostate err = ios.goodbit;
+
+ cpp17_input_iterator<const char*> iter =
+ f.get(cpp17_input_iterator<const char*>(str), cpp17_input_iterator<const char*>(str + 1), ios, err, v);
+ assert(base(iter) == str + 1);
+ assert(err == (std::ios::eofbit | std::ios::failbit));
+ assert(v == 0);
+ }
+ {
+ v = -1;
+ const char str[] = "+";
+ std::ios_base::iostate err = ios.goodbit;
+
+ cpp17_input_iterator<const char*> iter = f.get(
+ cpp17_input_iterator<const char*>(std::begin(str)),
+ cpp17_input_iterator<const char*>(std::end(str)),
+ ios,
+ err,
+ v);
+ assert(base(iter) == str + 1);
+ assert(err == ios.failbit);
+ assert(v == 0);
+ }
+ {
+ v = -1;
+ const char str[] = "-";
+ std::ios_base::iostate err = ios.goodbit;
+
+ cpp17_input_iterator<const char*> iter = f.get(
+ cpp17_input_iterator<const char*>(std::begin(str)),
+ cpp17_input_iterator<const char*>(std::end(str)),
+ ios,
+ err,
+ v);
+ assert(base(iter) == str + 1);
+ assert(err == ios.failbit);
+ assert(v == 0);
+ }
+ {
+ v = -1;
+ const char str[] = "0";
+ std::ios_base::iostate err = ios.goodbit;
+
+ cpp17_input_iterator<const char*> iter = f.get(
+ cpp17_input_iterator<const char*>(std::begin(str)),
+ cpp17_input_iterator<const char*>(std::end(str)),
+ ios,
+ err,
+ v);
+ assert(base(iter) == str + 1);
+ assert(err == ios.goodbit);
+ assert(v == 0);
+ }
+ {
+ v = -1;
+ const char str[] = "078";
+ std::ios_base::iostate err = ios.goodbit;
+
+ ios.flags(ios.flags() & ~ios.basefield);
+ cpp17_input_iterator<const char*> iter = f.get(
+ cpp17_input_iterator<const char*>(std::begin(str)),
+ cpp17_input_iterator<const char*>(std::end(str)),
+ ios,
+ err,
+ v);
+ assert(base(iter) == str + 2);
+ assert(err == ios.goodbit);
+ assert(v == 7);
+ ios.flags(ios.flags() | ios.dec);
+ }
+ {
+ v = -1;
+ std::string str = std::to_string(std::numeric_limits<unsigned long>::max()) + "99a";
+ std::ios_base::iostate err = ios.goodbit;
+
+ cpp17_input_iterator<const char*> iter = f.get(
+ cpp17_input_iterator<const char*>(str.data()),
+ cpp17_input_iterator<const char*>(str.data() + str.size()),
+ ios,
+ err,
+ v);
+ assert(base(iter) == str.data() + str.size() - 1);
+ assert(err == ios.failbit);
+ assert(v == std::numeric_limits<long>::max());
+ }
+ {
+ std::string str = std::to_string(std::numeric_limits<long>::max()) + 'c';
+ std::ios_base::iostate err = ios.goodbit;
+ cpp17_input_iterator<const char*> iter =
+ f.get(cpp17_input_iterator<const char*>(str.data()),
+ cpp17_input_iterator<const char*>(str.data() + str.size()),
+ ios, err, v);
+ assert(base(iter) == str.data() + str.size() - 1);
+ assert(err == ios.goodbit);
+ assert(v == std::numeric_limits<long>::max());
+ }
+ {
+ std::string str = std::to_string(static_cast<unsigned long>(std::numeric_limits<long>::max()) + 1) + 'c';
+ std::ios_base::iostate err = ios.goodbit;
+ cpp17_input_iterator<const char*> iter = f.get(
+ cpp17_input_iterator<const char*>(str.data()),
+ cpp17_input_iterator<const char*>(str.data() + str.size()),
+ ios,
+ err,
+ v);
+ assert(base(iter) == str.data() + str.size() - 1);
+ assert(err == ios.failbit);
+ assert(v == std::numeric_limits<long>::max());
+ }
+ {
+ std::string str = '-' + std::to_string(static_cast<unsigned long>(std::numeric_limits<long>::max()) + 2) + 'c';
+ std::ios_base::iostate err = ios.goodbit;
+ cpp17_input_iterator<const char*> iter = f.get(
+ cpp17_input_iterator<const char*>(str.data()),
+ cpp17_input_iterator<const char*>(str.data() + str.size()),
+ ios,
+ err,
+ v);
+ assert(base(iter) == str.data() + str.size() - 1);
+ assert(err == ios.failbit);
+ assert(v == std::numeric_limits<long>::min());
+ }
+
+ { // Check that auto-detection of the base works properly
+ ios.flags(ios.flags() & ~std::ios::basefield);
+ { // zeroes
+ {
+ v = -1;
+ const char str[] = "0";
+ std::ios_base::iostate err = ios.goodbit;
+
+ cpp17_input_iterator<const char*> iter =
+ f.get(cpp17_input_iterator<const char*>(str), cpp17_input_iterator<const char*>(str + 1), ios, err, v);
+ assert(base(iter) == str + 1);
+ assert(err == ios.eofbit);
+ assert(v == 0);
+ }
+ {
+ v = -1;
+ const char str[] = "00";
+ std::ios_base::iostate err = ios.goodbit;
+
+ cpp17_input_iterator<const char*> iter =
+ f.get(cpp17_input_iterator<const char*>(str), cpp17_input_iterator<const char*>(str + 2), ios, err, v);
+ assert(base(iter) == str + 2);
+ assert(err == ios.eofbit);
+ assert(v == 0);
+ }
+ {
+ v = -1;
+ const char str[] = "0x0";
+ std::ios_base::iostate err = ios.goodbit;
+
+ cpp17_input_iterator<const char*> iter =
+ f.get(cpp17_input_iterator<const char*>(str), cpp17_input_iterator<const char*>(str + 3), ios, err, v);
+ assert(base(iter) == str + 3);
+ assert(err == ios.eofbit);
+ assert(v == 0);
+ }
+ {
+ v = -1;
+ const char str[] = "0X0";
+ std::ios_base::iostate err = ios.goodbit;
+
+ cpp17_input_iterator<const char*> iter =
+ f.get(cpp17_input_iterator<const char*>(str), cpp17_input_iterator<const char*>(str + 3), ios, err, v);
+ assert(base(iter) == str + 3);
+ assert(err == ios.eofbit);
+ assert(v == 0);
+ }
+ }
+ { // first character after base is out of range
+ {
+ v = -1;
+ const char str[] = "08";
+ std::ios_base::iostate err = ios.goodbit;
+
+ cpp17_input_iterator<const char*> iter =
+ f.get(cpp17_input_iterator<const char*>(str), cpp17_input_iterator<const char*>(str + 2), ios, err, v);
+ assert(base(iter) == str + 1);
+ assert(err == ios.goodbit);
+ assert(v == 0);
+ }
+ {
+ v = -1;
+ const char str[] = "1a";
+ std::ios_base::iostate err = ios.goodbit;
+
+ cpp17_input_iterator<const char*> iter =
+ f.get(cpp17_input_iterator<const char*>(str), cpp17_input_iterator<const char*>(str + 2), ios, err, v);
+ assert(base(iter) == str + 1);
+ assert(err == ios.goodbit);
+ assert(v == 1);
+ }
+ {
+ v = -1;
+ const char str[] = "0xg";
+ std::ios_base::iostate err = ios.goodbit;
+
+ cpp17_input_iterator<const char*> iter =
+ f.get(cpp17_input_iterator<const char*>(str), cpp17_input_iterator<const char*>(str + 3), ios, err, v);
+ assert(base(iter) == str + 2);
+ assert(err == ios.failbit);
+ assert(v == 0);
+ }
+ {
+ v = -1;
+ const char str[] = "0Xg";
+ std::ios_base::iostate err = ios.goodbit;
+
+ cpp17_input_iterator<const char*> iter =
+ f.get(cpp17_input_iterator<const char*>(str), cpp17_input_iterator<const char*>(str + 3), ios, err, v);
+ assert(base(iter) == str + 2);
+ assert(err == ios.failbit);
+ assert(v == 0);
+ }
+ }
+ }
return 0;
}
diff --git a/libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_unsigned_int.pass.cpp b/libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_unsigned_int.pass.cpp
index bee1be0..f9cef08 100644
--- a/libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_unsigned_int.pass.cpp
+++ b/libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_unsigned_int.pass.cpp
@@ -68,6 +68,17 @@ int main(int, char**)
assert(err == ios.goodbit);
assert(v == 1);
}
+ {
+ const char str[] = "-1";
+ std::ios_base::iostate err = ios.goodbit;
+ cpp17_input_iterator<const char*> iter =
+ f.get(cpp17_input_iterator<const char*>(str),
+ cpp17_input_iterator<const char*>(str+sizeof(str)),
+ ios, err, v);
+ assert(base(iter) == str+sizeof(str)-1);
+ assert(err == ios.goodbit);
+ assert(v == std::numeric_limits<unsigned int>::max());
+ }
std::hex(ios);
{
const char str[] = "0xFFFFFFFF";
diff --git a/libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_unsigned_long.pass.cpp b/libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_unsigned_long.pass.cpp
index b087bdc..fed6fc0 100644
--- a/libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_unsigned_long.pass.cpp
+++ b/libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_unsigned_long.pass.cpp
@@ -68,6 +68,17 @@ int main(int, char**)
assert(err == ios.goodbit);
assert(v == 1);
}
+ {
+ const char str[] = "-1";
+ std::ios_base::iostate err = ios.goodbit;
+ cpp17_input_iterator<const char*> iter =
+ f.get(cpp17_input_iterator<const char*>(str),
+ cpp17_input_iterator<const char*>(str+sizeof(str)),
+ ios, err, v);
+ assert(base(iter) == str+sizeof(str)-1);
+ assert(err == ios.goodbit);
+ assert(v == std::numeric_limits<unsigned long>::max());
+ }
std::hex(ios);
{
const char str[] = "0xFFFFFFFF";
diff --git a/libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_unsigned_long_long.pass.cpp b/libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_unsigned_long_long.pass.cpp
index 6769aeb..0bdb6c1 100644
--- a/libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_unsigned_long_long.pass.cpp
+++ b/libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_unsigned_long_long.pass.cpp
@@ -68,6 +68,17 @@ int main(int, char**)
assert(err == ios.goodbit);
assert(v == 1);
}
+ {
+ const char str[] = "-1";
+ std::ios_base::iostate err = ios.goodbit;
+ cpp17_input_iterator<const char*> iter =
+ f.get(cpp17_input_iterator<const char*>(str),
+ cpp17_input_iterator<const char*>(str+sizeof(str)),
+ ios, err, v);
+ assert(base(iter) == str+sizeof(str)-1);
+ assert(err == ios.goodbit);
+ assert(v == std::numeric_limits<unsigned long long>::max());
+ }
std::hex(ios);
{
const char str[] = "0xFFFFFFFFFFFFFFFF";
diff --git a/libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_unsigned_short.pass.cpp b/libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_unsigned_short.pass.cpp
index bec9a7f..decfbe9 100644
--- a/libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_unsigned_short.pass.cpp
+++ b/libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_unsigned_short.pass.cpp
@@ -68,6 +68,17 @@ int main(int, char**)
assert(err == ios.goodbit);
assert(v == 1);
}
+ {
+ const char str[] = "-1";
+ std::ios_base::iostate err = ios.goodbit;
+ cpp17_input_iterator<const char*> iter =
+ f.get(cpp17_input_iterator<const char*>(str),
+ cpp17_input_iterator<const char*>(str+sizeof(str)),
+ ios, err, v);
+ assert(base(iter) == str+sizeof(str)-1);
+ assert(err == ios.goodbit);
+ assert(v == std::numeric_limits<unsigned short>::max());
+ }
std::hex(ios);
{
const char str[] = "0xFFFF";
diff --git a/libcxx/test/std/numerics/c.math/isnormal.pass.cpp b/libcxx/test/std/numerics/c.math/isnormal.pass.cpp
index 76c3d13..79465b3 100644
--- a/libcxx/test/std/numerics/c.math/isnormal.pass.cpp
+++ b/libcxx/test/std/numerics/c.math/isnormal.pass.cpp
@@ -14,6 +14,7 @@
#include <cassert>
#include <cmath>
#include <limits>
+#include <type_traits>
#include "test_macros.h"
#include "type_algorithms.h"
diff --git a/libcxx/test/std/numerics/c.math/signbit.pass.cpp b/libcxx/test/std/numerics/c.math/signbit.pass.cpp
index 233e8ed..5655370 100644
--- a/libcxx/test/std/numerics/c.math/signbit.pass.cpp
+++ b/libcxx/test/std/numerics/c.math/signbit.pass.cpp
@@ -20,6 +20,7 @@
#include <cassert>
#include <cmath>
#include <limits>
+#include <type_traits>
#include "test_macros.h"
#include "type_algorithms.h"
diff --git a/libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer/increment.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer/increment.pass.cpp
index 4d765d7..b557346 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer/increment.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer/increment.pass.cpp
@@ -75,6 +75,56 @@ constexpr bool test() {
}
}
+ // LWG3505
+ {
+ using namespace std::string_view_literals;
+
+ { // Motivational example
+ auto v = std::views::lazy_split("xxyx"sv, "xy"sv);
+
+ {
+ auto i = v.begin();
+ assert(std::ranges::equal(*i, "x"s));
+
+ decltype(auto) i2 = ++i;
+ static_assert(std::is_lvalue_reference_v<decltype(i2)>);
+ assert(std::ranges::equal(*i2, "x"s));
+ }
+
+ {
+ auto i = v.begin();
+ assert(std::ranges::equal(*i, "x"s));
+
+ decltype(auto) i2 = i++;
+ static_assert(!std::is_reference_v<decltype(i2)>);
+ assert(std::ranges::equal(*i2, "x"s));
+ assert(std::ranges::equal(*i, "x"s));
+ }
+ }
+ {
+ auto v = std::views::lazy_split("zzht"sv, "zh"sv);
+
+ {
+ auto i = v.begin();
+ assert(std::ranges::equal(*i, "z"s));
+
+ decltype(auto) i2 = ++i;
+ static_assert(std::is_lvalue_reference_v<decltype(i2)>);
+ assert(std::ranges::equal(*i2, "t"s));
+ }
+
+ {
+ auto i = v.begin();
+ assert(std::ranges::equal(*i, "z"s));
+
+ decltype(auto) i2 = i++;
+ static_assert(!std::is_reference_v<decltype(i2)>);
+ assert(std::ranges::equal(*i2, "z"s));
+ assert(std::ranges::equal(*i, "t"s));
+ }
+ }
+ }
+
return true;
}
diff --git a/libcxx/test/std/ranges/range.factories/range.iota.view/indices.pass.cpp b/libcxx/test/std/ranges/range.factories/range.iota.view/indices.pass.cpp
index d92b6cb..8723085 100644
--- a/libcxx/test/std/ranges/range.factories/range.iota.view/indices.pass.cpp
+++ b/libcxx/test/std/ranges/range.factories/range.iota.view/indices.pass.cpp
@@ -12,13 +12,15 @@
// inline constexpr unspecified indices = unspecified;
+// FIXME: This test shouldn't define TEST_HAS_NO_INT128
+// ADDITIONAL_COMPILE_FLAGS(clang-modules-build): -fno-modules
+
#include <cassert>
#include <cstddef>
#include <ranges>
#include <vector>
#include "test_macros.h"
-#define TEST_HAS_NO_INT128 // Size cannot be larger than 64 bits
#include "type_algorithms.h"
#include "types.h"
diff --git a/libcxx/test/std/ranges/range.factories/range.iota.view/iterator/member_typedefs.compile.pass.cpp b/libcxx/test/std/ranges/range.factories/range.iota.view/iterator/member_typedefs.compile.pass.cpp
index c2f7fd1..0d6fc9c 100644
--- a/libcxx/test/std/ranges/range.factories/range.iota.view/iterator/member_typedefs.compile.pass.cpp
+++ b/libcxx/test/std/ranges/range.factories/range.iota.view/iterator/member_typedefs.compile.pass.cpp
@@ -106,7 +106,12 @@ void test() {
// Same as below, if there is no type larger than long, we can just use that.
static_assert(sizeof(Iter::difference_type) >= sizeof(long));
static_assert(std::is_signed_v<Iter::difference_type>);
+#ifdef TEST_HAS_NO_INT128
LIBCPP_STATIC_ASSERT(std::same_as<Iter::difference_type, long long>);
+#else
+ LIBCPP_STATIC_ASSERT(std::same_as<Iter::difference_type,
+ std::conditional_t<sizeof(long) == sizeof(long long), __int128, long long>>);
+#endif
}
{
const std::ranges::iota_view<long long> io(0);
@@ -118,7 +123,11 @@ void test() {
// https://eel.is/c++draft/range.iota.view#1.3
static_assert(sizeof(Iter::difference_type) >= sizeof(long long));
static_assert(std::is_signed_v<Iter::difference_type>);
+#ifdef TEST_HAS_NO_INT128
LIBCPP_STATIC_ASSERT(std::same_as<Iter::difference_type, long long>);
+#else
+ LIBCPP_STATIC_ASSERT(std::same_as<Iter::difference_type, __int128>);
+#endif
}
{
const std::ranges::iota_view<Decrementable> io;
diff --git a/libcxx/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/array.compile.fail.cpp b/libcxx/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/array.compile.fail.cpp
deleted file mode 100644
index a03fd52..0000000
--- a/libcxx/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/array.compile.fail.cpp
+++ /dev/null
@@ -1,40 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-// <regex>
-
-// class regex_iterator<BidirectionalIterator, charT, traits>
-
-// template <size_t N>
-// regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b,
-// const regex_type&& re,
-// const int (&submatches)[N],
-// regex_constants::match_flag_type m =
-// regex_constants::match_default);
-
-#include <regex>
-#include <vector>
-#include <cassert>
-#include "test_macros.h"
-
-#if TEST_STD_VER < 14
-#error
-#endif
-
-int main(int, char**)
-{
- {
- std::regex phone_numbers("\\d{3}-(\\d{4})");
- const char phone_book[] = "start 555-1234, 555-2345, 555-3456 end";
- const int indices[] = {-1, 0, 1};
- std::cregex_token_iterator i(std::begin(phone_book), std::end(phone_book)-1,
- std::regex("\\d{3}-\\d{4}"), indices);
- }
-
- return 0;
-}
diff --git a/libcxx/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/init.compile.fail.cpp b/libcxx/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/init.compile.fail.cpp
deleted file mode 100644
index b6913e6..0000000
--- a/libcxx/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/init.compile.fail.cpp
+++ /dev/null
@@ -1,37 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-// <regex>
-
-// class regex_iterator<BidirectionalIterator, charT, traits>
-
-// regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b,
-// const regex_type&& re,
-// initializer_list<int> submatches,
-// regex_constants::match_flag_type m =
-// regex_constants::match_default);
-
-#include <regex>
-#include <cassert>
-#include "test_macros.h"
-
-#if TEST_STD_VER < 14
-#error
-#endif
-
-int main(int, char**)
-{
- {
- std::regex phone_numbers("\\d{3}-(\\d{4})");
- const char phone_book[] = "start 555-1234, 555-2345, 555-3456 end";
- std::cregex_token_iterator i(std::begin(phone_book), std::end(phone_book)-1,
- std::regex("\\d{3}-\\d{4}"), {-1, 0, 1});
- }
-
- return 0;
-}
diff --git a/libcxx/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/int.compile.fail.cpp b/libcxx/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/int.compile.fail.cpp
deleted file mode 100644
index 3c39d49..0000000
--- a/libcxx/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/int.compile.fail.cpp
+++ /dev/null
@@ -1,36 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-// <regex>
-
-// class regex_iterator<BidirectionalIterator, charT, traits>
-
-// regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b,
-// const regex_type&& re, int submatch = 0,
-// regex_constants::match_flag_type m =
-// regex_constants::match_default);
-
-#include <regex>
-#include <cassert>
-#include "test_macros.h"
-
-#if TEST_STD_VER < 14
-#error
-#endif
-
-int main(int, char**)
-{
- {
- std::regex phone_numbers("\\d{3}-\\d{4}");
- const char phone_book[] = "start 555-1234, 555-2345, 555-3456 end";
- std::cregex_token_iterator i(std::begin(phone_book), std::end(phone_book)-1,
- std::regex("\\d{3}-\\d{4}"), -1);
- }
-
- return 0;
-}
diff --git a/libcxx/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/temporary-objects.verify.cpp b/libcxx/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/temporary-objects.verify.cpp
new file mode 100644
index 0000000..b1ab0f3
--- /dev/null
+++ b/libcxx/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/temporary-objects.verify.cpp
@@ -0,0 +1,72 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11
+
+// Ensure that we don't allow iterators into temporary std::regex objects.
+
+// <regex>
+//
+// class regex_iterator<BidirectionalIterator, charT, traits>
+//
+// regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b,
+// const regex_type&& re, int submatch = 0,
+// regex_constants::match_flag_type m =
+// regex_constants::match_default);
+//
+// template <size_t N>
+// regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b,
+// const regex_type&& re,
+// const int (&submatches)[N],
+// regex_constants::match_flag_type m =
+// regex_constants::match_default);
+//
+// regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b,
+// const regex_type&& re,
+// initializer_list<int> submatches,
+// regex_constants::match_flag_type m =
+// regex_constants::match_default);
+//
+// template <std::size_t N>
+// regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b,
+// const regex_type&& re,
+// const std::vector<int>& submatches,
+// regex_constants::match_flag_type m =
+// regex_constants::match_default);
+
+#include <iterator>
+#include <regex>
+#include <vector>
+
+void f() {
+ std::regex phone_numbers("\\d{3}-\\d{4}");
+ const char phone_book[] = "start 555-1234, 555-2345, 555-3456 end";
+
+ { // int submatch
+ std::cregex_token_iterator i(std::begin(phone_book), std::end(phone_book) - 1, std::regex("\\d{3}-\\d{4}"), -1);
+ // expected-error@-1 {{call to deleted constructor of 'std::cregex_token_iterator'}}
+ }
+ { // const int (&submatches)[N]
+ const int indices[] = {-1, 0, 1};
+ std::cregex_token_iterator i(
+ std::begin(phone_book), std::end(phone_book) - 1, std::regex("\\d{3}-\\d{4}"), indices);
+ // expected-error@-2 {{call to deleted constructor of 'std::cregex_token_iterator'}}
+ }
+ { // initializer_list<int> submatches
+ std::cregex_token_iterator i(
+ std::begin(phone_book), std::end(phone_book) - 1, std::regex("\\d{3}-\\d{4}"), {-1, 0, 1});
+ // expected-error@-2 {{call to deleted constructor of 'std::cregex_token_iterator'}}
+ }
+ { // const std::vector<int>& submatches
+ std::vector<int> v;
+ v.push_back(-1);
+ v.push_back(-1);
+ std::cregex_token_iterator i(std::begin(phone_book), std::end(phone_book) - 1, std::regex("\\d{3}-\\d{4}"), v);
+ // expected-error@-1 {{call to deleted constructor of 'std::cregex_token_iterator'}}
+ }
+}
diff --git a/libcxx/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/vector.compile.fail.cpp b/libcxx/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/vector.compile.fail.cpp
deleted file mode 100644
index 9b07df9..0000000
--- a/libcxx/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/vector.compile.fail.cpp
+++ /dev/null
@@ -1,41 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-// <regex>
-
-// class regex_iterator<BidirectionalIterator, charT, traits>
-
-// template <std::size_t N>
-// regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b,
-// const regex_type&& re,
-// const std::vector<int>& submatches,
-// regex_constants::match_flag_type m =
-// regex_constants::match_default);
-
-#include <regex>
-#include <cassert>
-#include "test_macros.h"
-
-#if TEST_STD_VER < 14
-#error
-#endif
-
-int main(int, char**)
-{
- {
- std::regex phone_numbers("\\d{3}-(\\d{4})");
- const char phone_book[] = "start 555-1234, 555-2345, 555-3456 end";
- std::vector<int> v;
- v.push_back(-1);
- v.push_back(-1);
- std::cregex_token_iterator i(std::begin(phone_book), std::end(phone_book)-1,
- std::regex("\\d{3}-\\d{4}"), v);
- }
-
- return 0;
-}
diff --git a/libcxx/test/std/re/re.results/re.results.const/move.pass.cpp b/libcxx/test/std/re/re.results/re.results.const/move.pass.cpp
index 0806ede..9078d57 100644
--- a/libcxx/test/std/re/re.results/re.results.const/move.pass.cpp
+++ b/libcxx/test/std/re/re.results/re.results.const/move.pass.cpp
@@ -14,8 +14,10 @@
//
// Additionally, the stored Allocator value is move constructed from m.get_allocator().
-#include <regex>
#include <cassert>
+#include <regex>
+#include <utility>
+
#include "test_macros.h"
#include "test_allocator.h"
diff --git a/libcxx/test/std/strings/basic.string/string.cons/dtor.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/dtor.pass.cpp
index e9f1740..d5c1f4d 100644
--- a/libcxx/test/std/strings/basic.string/string.cons/dtor.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.cons/dtor.pass.cpp
@@ -12,11 +12,12 @@
// ~basic_string() // implied noexcept; // constexpr since C++20
-#include <string>
#include <cassert>
+#include <string>
+#include <type_traits>
-#include "test_macros.h"
#include "test_allocator.h"
+#include "test_macros.h"
template <class T>
struct throwing_alloc {
diff --git a/libcxx/test/std/strings/basic.string/string.cons/iter_alloc_deduction.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/iter_alloc_deduction.pass.cpp
index d9176da..d47c9df 100644
--- a/libcxx/test/std/strings/basic.string/string.cons/iter_alloc_deduction.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.cons/iter_alloc_deduction.pass.cpp
@@ -25,6 +25,7 @@
#include <iterator>
#include <string>
#include <type_traits>
+#include <utility>
#include "test_macros.h"
#include "test_allocator.h"
diff --git a/libcxx/test/std/strings/basic.string/string.cons/string_view_deduction.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/string_view_deduction.pass.cpp
index 3a6f84f..a19564b 100644
--- a/libcxx/test/std/strings/basic.string/string.cons/string_view_deduction.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.cons/string_view_deduction.pass.cpp
@@ -19,17 +19,18 @@
// The deduction guide shall not participate in overload resolution if Allocator
// is a type that does not qualify as an allocator.
-#include <string>
-#include <string_view>
+#include <cassert>
+#include <cstddef>
#include <iterator>
#include <memory>
+#include <string>
+#include <string_view>
#include <type_traits>
-#include <cassert>
-#include <cstddef>
+#include <utility>
-#include "test_macros.h"
-#include "test_allocator.h"
#include "min_allocator.h"
+#include "test_allocator.h"
+#include "test_macros.h"
template <class StringView, class Allocator, class = void>
struct CanDeduce : std::false_type {};
diff --git a/libcxx/test/std/strings/basic.string/string.cons/string_view_size_size_deduction.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/string_view_size_size_deduction.pass.cpp
index 08e696b..e36503d 100644
--- a/libcxx/test/std/strings/basic.string/string.cons/string_view_size_size_deduction.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.cons/string_view_size_size_deduction.pass.cpp
@@ -25,15 +25,16 @@
// The deduction guide shall not participate in overload resolution if Allocator
// is a type that does not qualify as an allocator.
-#include <string>
-#include <string_view>
-#include <iterator>
#include <cassert>
#include <cstddef>
+#include <iterator>
+#include <string>
+#include <string_view>
+#include <utility>
-#include "test_macros.h"
-#include "test_allocator.h"
#include "min_allocator.h"
+#include "test_allocator.h"
+#include "test_macros.h"
template <class StringView, class Size, class Allocator, class = void>
struct CanDeduce : std::false_type {};
diff --git a/libcxx/test/std/thread/thread.jthread/nodiscard.verify.cpp b/libcxx/test/std/thread/thread.jthread/nodiscard.verify.cpp
deleted file mode 100644
index 2ef5cf8..0000000
--- a/libcxx/test/std/thread/thread.jthread/nodiscard.verify.cpp
+++ /dev/null
@@ -1,29 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// UNSUPPORTED: no-threads
-// UNSUPPORTED: c++03, c++11, c++14, c++17
-
-// [[nodiscard]] bool joinable() const noexcept;
-// [[nodiscard]] id get_id() const noexcept;
-// [[nodiscard]] native_handle_type native_handle();
-// [[nodiscard]] stop_source get_stop_source() noexcept;
-// [[nodiscard]] stop_token get_stop_token() const noexcept;
-// [[nodiscard]] static unsigned int hardware_concurrency() noexcept;
-
-#include <thread>
-
-void test() {
- std::jthread jt;
- jt.joinable(); // expected-warning {{ignoring return value of function}}
- jt.get_id(); // expected-warning {{ignoring return value of function}}
- jt.native_handle(); // expected-warning {{ignoring return value of function}}
- jt.get_stop_source(); // expected-warning {{ignoring return value of function}}
- jt.get_stop_token(); // expected-warning {{ignoring return value of function}}
- jt.hardware_concurrency(); // expected-warning {{ignoring return value of function}}
-}
diff --git a/libcxx/test/std/time/time.clock/time.clock.gps/types.compile.pass.cpp b/libcxx/test/std/time/time.clock/time.clock.gps/types.compile.pass.cpp
index 006ad9a..fea70a3 100644
--- a/libcxx/test/std/time/time.clock/time.clock.gps/types.compile.pass.cpp
+++ b/libcxx/test/std/time/time.clock/time.clock.gps/types.compile.pass.cpp
@@ -32,6 +32,7 @@
#include <chrono>
#include <concepts>
#include <ratio>
+#include <type_traits>
#include "test_macros.h"
diff --git a/libcxx/test/std/time/time.clock/time.clock.tai/types.compile.pass.cpp b/libcxx/test/std/time/time.clock/time.clock.tai/types.compile.pass.cpp
index a7123bc..6499ecb 100644
--- a/libcxx/test/std/time/time.clock/time.clock.tai/types.compile.pass.cpp
+++ b/libcxx/test/std/time/time.clock/time.clock.tai/types.compile.pass.cpp
@@ -32,6 +32,7 @@
#include <chrono>
#include <concepts>
#include <ratio>
+#include <type_traits>
#include "test_macros.h"
diff --git a/libcxx/test/std/time/time.clock/time.clock.utc/types.compile.pass.cpp b/libcxx/test/std/time/time.clock/time.clock.utc/types.compile.pass.cpp
index 8cb3d78..c69671b 100644
--- a/libcxx/test/std/time/time.clock/time.clock.utc/types.compile.pass.cpp
+++ b/libcxx/test/std/time/time.clock/time.clock.utc/types.compile.pass.cpp
@@ -32,6 +32,7 @@
#include <concepts>
#include <chrono>
#include <ratio>
+#include <type_traits>
#include "test_macros.h"
diff --git a/libcxx/test/std/utilities/any/any.nonmembers/any.cast/any_cast_pointer.pass.cpp b/libcxx/test/std/utilities/any/any.nonmembers/any.cast/any_cast_pointer.pass.cpp
index 5143bef..a5f0e8b 100644
--- a/libcxx/test/std/utilities/any/any.nonmembers/any.cast/any_cast_pointer.pass.cpp
+++ b/libcxx/test/std/utilities/any/any.nonmembers/any.cast/any_cast_pointer.pass.cpp
@@ -25,156 +25,157 @@
// Test that the operators are properly noexcept.
void test_cast_is_noexcept() {
- std::any a;
- ASSERT_NOEXCEPT(std::any_cast<int>(&a));
+ std::any a;
+ ASSERT_NOEXCEPT(std::any_cast<int>(&a));
- const std::any& ca = a;
- ASSERT_NOEXCEPT(std::any_cast<int>(&ca));
+ const std::any& ca = a;
+ ASSERT_NOEXCEPT(std::any_cast<int>(&ca));
}
// Test that the return type of any_cast is correct.
void test_cast_return_type() {
- std::any a;
- ASSERT_SAME_TYPE(decltype(std::any_cast<int>(&a)), int*);
- ASSERT_SAME_TYPE(decltype(std::any_cast<int const>(&a)), int const*);
+ std::any a;
+ ASSERT_SAME_TYPE(decltype(std::any_cast<int>(&a)), int*);
+ ASSERT_SAME_TYPE(decltype(std::any_cast<int const>(&a)), int const*);
- const std::any& ca = a;
- ASSERT_SAME_TYPE(decltype(std::any_cast<int>(&ca)), int const*);
- ASSERT_SAME_TYPE(decltype(std::any_cast<int const>(&ca)), int const*);
+ const std::any& ca = a;
+ ASSERT_SAME_TYPE(decltype(std::any_cast<int>(&ca)), int const*);
+ ASSERT_SAME_TYPE(decltype(std::any_cast<int const>(&ca)), int const*);
}
// Test that any_cast handles null pointers.
void test_cast_nullptr() {
- std::any *a = nullptr;
- assert(nullptr == std::any_cast<int>(a));
- assert(nullptr == std::any_cast<int const>(a));
+ std::any* a = nullptr;
+ assert(nullptr == std::any_cast<int>(a));
+ assert(nullptr == std::any_cast<int const>(a));
- const std::any *ca = nullptr;
- assert(nullptr == std::any_cast<int>(ca));
- assert(nullptr == std::any_cast<int const>(ca));
+ const std::any* ca = nullptr;
+ assert(nullptr == std::any_cast<int>(ca));
+ assert(nullptr == std::any_cast<int const>(ca));
}
// Test casting an empty object.
void test_cast_empty() {
- {
- std::any a;
- assert(nullptr == std::any_cast<int>(&a));
- assert(nullptr == std::any_cast<int const>(&a));
-
- const std::any& ca = a;
- assert(nullptr == std::any_cast<int>(&ca));
- assert(nullptr == std::any_cast<int const>(&ca));
- }
- // Create as non-empty, then make empty and run test.
- {
- std::any a(42);
- a.reset();
- assert(nullptr == std::any_cast<int>(&a));
- assert(nullptr == std::any_cast<int const>(&a));
-
- const std::any& ca = a;
- assert(nullptr == std::any_cast<int>(&ca));
- assert(nullptr == std::any_cast<int const>(&ca));
- }
+ {
+ std::any a;
+ assert(nullptr == std::any_cast<int>(&a));
+ assert(nullptr == std::any_cast<int const>(&a));
+
+ const std::any& ca = a;
+ assert(nullptr == std::any_cast<int>(&ca));
+ assert(nullptr == std::any_cast<int const>(&ca));
+ }
+ // Create as non-empty, then make empty and run test.
+ {
+ std::any a(42);
+ a.reset();
+ assert(nullptr == std::any_cast<int>(&a));
+ assert(nullptr == std::any_cast<int const>(&a));
+
+ const std::any& ca = a;
+ assert(nullptr == std::any_cast<int>(&ca));
+ assert(nullptr == std::any_cast<int const>(&ca));
+ }
}
template <class Type>
void test_cast() {
- assert(Type::count == 0);
- Type::reset();
- {
- std::any a = Type(42);
- const std::any& ca = a;
- assert(Type::count == 1);
- assert(Type::copied == 0);
- assert(Type::moved == 1);
-
- // Try a cast to a bad type.
- // NOTE: Type cannot be an int.
- assert(std::any_cast<int>(&a) == nullptr);
- assert(std::any_cast<int const>(&a) == nullptr);
- assert(std::any_cast<int const volatile>(&a) == nullptr);
-
- // Try a cast to the right type, but as a pointer.
- assert(std::any_cast<Type*>(&a) == nullptr);
- assert(std::any_cast<Type const*>(&a) == nullptr);
-
- // Check getting a unqualified type from a non-const any.
- Type* v = std::any_cast<Type>(&a);
- assert(v != nullptr);
- assert(v->value == 42);
-
- // change the stored value and later check for the new value.
- v->value = 999;
-
- // Check getting a const qualified type from a non-const any.
- Type const* cv = std::any_cast<Type const>(&a);
- assert(cv != nullptr);
- assert(cv == v);
- assert(cv->value == 999);
-
- // Check getting a unqualified type from a const any.
- cv = std::any_cast<Type>(&ca);
- assert(cv != nullptr);
- assert(cv == v);
- assert(cv->value == 999);
-
- // Check getting a const-qualified type from a const any.
- cv = std::any_cast<Type const>(&ca);
- assert(cv != nullptr);
- assert(cv == v);
- assert(cv->value == 999);
-
- // Check that no more objects were created, copied or moved.
- assert(Type::count == 1);
- assert(Type::copied == 0);
- assert(Type::moved == 1);
- }
- assert(Type::count == 0);
+ assert(Type::count == 0);
+ Type::reset();
+ {
+ std::any a = Type(42);
+ const std::any& ca = a;
+ assert(Type::count == 1);
+ assert(Type::copied == 0);
+ assert(Type::moved == 1);
+
+ // Try a cast to a bad type.
+ // NOTE: Type cannot be an int.
+ assert(std::any_cast<int>(&a) == nullptr);
+ assert(std::any_cast<int const>(&a) == nullptr);
+ assert(std::any_cast<int const volatile>(&a) == nullptr);
+
+ // Try a cast to the right type, but as a pointer.
+ assert(std::any_cast<Type*>(&a) == nullptr);
+ assert(std::any_cast<Type const*>(&a) == nullptr);
+
+ // Check getting a unqualified type from a non-const any.
+ Type* v = std::any_cast<Type>(&a);
+ assert(v != nullptr);
+ assert(v->value == 42);
+
+ // change the stored value and later check for the new value.
+ v->value = 999;
+
+ // Check getting a const qualified type from a non-const any.
+ Type const* cv = std::any_cast<Type const>(&a);
+ assert(cv != nullptr);
+ assert(cv == v);
+ assert(cv->value == 999);
+
+ // Check getting a unqualified type from a const any.
+ cv = std::any_cast<Type>(&ca);
+ assert(cv != nullptr);
+ assert(cv == v);
+ assert(cv->value == 999);
+
+ // Check getting a const-qualified type from a const any.
+ cv = std::any_cast<Type const>(&ca);
+ assert(cv != nullptr);
+ assert(cv == v);
+ assert(cv->value == 999);
+
+ // Check that no more objects were created, copied or moved.
+ assert(Type::count == 1);
+ assert(Type::copied == 0);
+ assert(Type::moved == 1);
+ }
+ assert(Type::count == 0);
}
-void test_cast_non_copyable_type()
-{
- // Even though 'any' never stores non-copyable types
- // we still need to support any_cast<NoCopy>(ptr)
- struct NoCopy { NoCopy(NoCopy const&) = delete; };
- std::any a(42);
- std::any const& ca = a;
- assert(std::any_cast<NoCopy>(&a) == nullptr);
- assert(std::any_cast<NoCopy>(&ca) == nullptr);
+void test_cast_non_copyable_type() {
+ // Even though 'any' never stores non-copyable types
+ // we still need to support any_cast<NoCopy>(ptr)
+ struct NoCopy {
+ NoCopy(NoCopy const&) = delete;
+ };
+ std::any a(42);
+ std::any const& ca = a;
+ assert(std::any_cast<NoCopy>(&a) == nullptr);
+ assert(std::any_cast<NoCopy>(&ca) == nullptr);
}
void test_cast_array() {
- int arr[3];
- std::any a(arr);
- RTTI_ASSERT(a.type() == typeid(int*)); // contained value is decayed
- // We can't get an array out
- int (*p)[3] = std::any_cast<int[3]>(&a);
- assert(p == nullptr);
+ int arr[3];
+ std::any a(arr);
+ RTTI_ASSERT(a.type() == typeid(int*)); // contained value is decayed
+ // We can't get an array out
+ int (*p)[3] = std::any_cast<int[3]>(&a);
+ assert(p == nullptr);
}
void test_fn() {}
void test_cast_function_pointer() {
- using T = void(*)();
- std::any a(test_fn);
- // An any can never store a function type, but we should at least be able
- // to ask.
- assert(std::any_cast<void()>(&a) == nullptr);
- T fn_ptr = std::any_cast<T>(a);
- assert(fn_ptr == test_fn);
+ using T = void (*)();
+ std::any a(test_fn);
+ // An any can never store a function type, but we should at least be able
+ // to ask.
+ assert(std::any_cast<void()>(&a) == nullptr);
+ T fn_ptr = std::any_cast<T>(a);
+ assert(fn_ptr == test_fn);
}
int main(int, char**) {
- test_cast_is_noexcept();
- test_cast_return_type();
- test_cast_nullptr();
- test_cast_empty();
- test_cast<small>();
- test_cast<large>();
- test_cast_non_copyable_type();
- test_cast_array();
- test_cast_function_pointer();
+ test_cast_is_noexcept();
+ test_cast_return_type();
+ test_cast_nullptr();
+ test_cast_empty();
+ test_cast<small>();
+ test_cast<large>();
+ test_cast_non_copyable_type();
+ test_cast_array();
+ test_cast_function_pointer();
return 0;
}
diff --git a/libcxx/test/std/utilities/any/any.nonmembers/any.cast/any_cast_reference.pass.cpp b/libcxx/test/std/utilities/any/any.nonmembers/any.cast/any_cast_reference.pass.cpp
index 079be66..4ba9bf6 100644
--- a/libcxx/test/std/utilities/any/any.nonmembers/any.cast/any_cast_reference.pass.cpp
+++ b/libcxx/test/std/utilities/any/any.nonmembers/any.cast/any_cast_reference.pass.cpp
@@ -29,278 +29,275 @@
// Test that the operators are NOT marked noexcept.
void test_cast_is_not_noexcept() {
- std::any a;
- static_assert(!noexcept(std::any_cast<int>(static_cast<std::any&>(a))), "");
- static_assert(!noexcept(std::any_cast<int>(static_cast<std::any const&>(a))), "");
- static_assert(!noexcept(std::any_cast<int>(static_cast<std::any &&>(a))), "");
+ std::any a;
+ static_assert(!noexcept(std::any_cast<int>(static_cast<std::any&>(a))), "");
+ static_assert(!noexcept(std::any_cast<int>(static_cast<std::any const&>(a))), "");
+ static_assert(!noexcept(std::any_cast<int>(static_cast<std::any&&>(a))), "");
}
// Test that the return type of any_cast is correct.
void test_cast_return_type() {
- std::any a;
- static_assert(std::is_same<decltype(std::any_cast<int>(a)), int>::value, "");
- static_assert(std::is_same<decltype(std::any_cast<int const>(a)), int>::value, "");
- static_assert(std::is_same<decltype(std::any_cast<int&>(a)), int&>::value, "");
- static_assert(std::is_same<decltype(std::any_cast<int const&>(a)), int const&>::value, "");
- static_assert(std::is_same<decltype(std::any_cast<int&&>(a)), int&&>::value, "");
- static_assert(std::is_same<decltype(std::any_cast<int const&&>(a)), int const&&>::value, "");
-
- static_assert(std::is_same<decltype(std::any_cast<int>(std::move(a))), int>::value, "");
- static_assert(std::is_same<decltype(std::any_cast<int const>(std::move(a))), int>::value, "");
- static_assert(std::is_same<decltype(std::any_cast<int&>(std::move(a))), int&>::value, "");
- static_assert(std::is_same<decltype(std::any_cast<int const&>(std::move(a))), int const&>::value, "");
- static_assert(std::is_same<decltype(std::any_cast<int&&>(std::move(a))), int&&>::value, "");
- static_assert(std::is_same<decltype(std::any_cast<int const&&>(std::move(a))), int const&&>::value, "");
-
- const std::any& ca = a;
- static_assert(std::is_same<decltype(std::any_cast<int>(ca)), int>::value, "");
- static_assert(std::is_same<decltype(std::any_cast<int const>(ca)), int>::value, "");
- static_assert(std::is_same<decltype(std::any_cast<int const&>(ca)), int const&>::value, "");
- static_assert(std::is_same<decltype(std::any_cast<int const&&>(ca)), int const&&>::value, "");
+ std::any a;
+ static_assert(std::is_same<decltype(std::any_cast<int>(a)), int>::value, "");
+ static_assert(std::is_same<decltype(std::any_cast<int const>(a)), int>::value, "");
+ static_assert(std::is_same<decltype(std::any_cast<int&>(a)), int&>::value, "");
+ static_assert(std::is_same<decltype(std::any_cast<int const&>(a)), int const&>::value, "");
+ static_assert(std::is_same<decltype(std::any_cast<int&&>(a)), int&&>::value, "");
+ static_assert(std::is_same<decltype(std::any_cast<int const&&>(a)), int const&&>::value, "");
+
+ static_assert(std::is_same<decltype(std::any_cast<int>(std::move(a))), int>::value, "");
+ static_assert(std::is_same<decltype(std::any_cast<int const>(std::move(a))), int>::value, "");
+ static_assert(std::is_same<decltype(std::any_cast<int&>(std::move(a))), int&>::value, "");
+ static_assert(std::is_same<decltype(std::any_cast<int const&>(std::move(a))), int const&>::value, "");
+ static_assert(std::is_same<decltype(std::any_cast<int&&>(std::move(a))), int&&>::value, "");
+ static_assert(std::is_same<decltype(std::any_cast<int const&&>(std::move(a))), int const&&>::value, "");
+
+ const std::any& ca = a;
+ static_assert(std::is_same<decltype(std::any_cast<int>(ca)), int>::value, "");
+ static_assert(std::is_same<decltype(std::any_cast<int const>(ca)), int>::value, "");
+ static_assert(std::is_same<decltype(std::any_cast<int const&>(ca)), int const&>::value, "");
+ static_assert(std::is_same<decltype(std::any_cast<int const&&>(ca)), int const&&>::value, "");
}
template <class Type, class ConstT = Type>
-void checkThrows(std::any& a)
-{
+void checkThrows(std::any& a) {
#if !defined(TEST_HAS_NO_EXCEPTIONS)
- try {
- TEST_IGNORE_NODISCARD std::any_cast<Type>(a);
- assert(false);
- } catch (const std::bad_any_cast&) {
- // do nothing
- } catch (...) {
- assert(false);
- }
-
- try {
- TEST_IGNORE_NODISCARD std::any_cast<ConstT>(static_cast<const std::any&>(a));
- assert(false);
- } catch (const std::bad_any_cast&) {
- // do nothing
- } catch (...) {
- assert(false);
- }
-
- try {
- using RefType = typename std::conditional<
- std::is_lvalue_reference<Type>::value,
- typename std::remove_reference<Type>::type&&,
- Type
- >::type;
- TEST_IGNORE_NODISCARD std::any_cast<RefType>(static_cast<std::any&&>(a));
- assert(false);
- } catch (const std::bad_any_cast&) {
- // do nothing
- } catch (...) {
- assert(false);
- }
+ try {
+ TEST_IGNORE_NODISCARD std::any_cast<Type>(a);
+ assert(false);
+ } catch (const std::bad_any_cast&) {
+ // do nothing
+ } catch (...) {
+ assert(false);
+ }
+
+ try {
+ TEST_IGNORE_NODISCARD std::any_cast<ConstT>(static_cast<const std::any&>(a));
+ assert(false);
+ } catch (const std::bad_any_cast&) {
+ // do nothing
+ } catch (...) {
+ assert(false);
+ }
+
+ try {
+ using RefType = typename std::
+ conditional< std::is_lvalue_reference<Type>::value, typename std::remove_reference<Type>::type&&, Type >::type;
+ TEST_IGNORE_NODISCARD std::any_cast<RefType>(static_cast<std::any&&>(a));
+ assert(false);
+ } catch (const std::bad_any_cast&) {
+ // do nothing
+ } catch (...) {
+ assert(false);
+ }
#else
- (TEST_IGNORE_NODISCARD a);
+ (TEST_IGNORE_NODISCARD a);
#endif
}
void test_cast_empty() {
- // None of these operations should allocate.
- DisableAllocationGuard g; (TEST_IGNORE_NODISCARD g);
- std::any a;
- checkThrows<int>(a);
+ // None of these operations should allocate.
+ DisableAllocationGuard g;
+ (TEST_IGNORE_NODISCARD g);
+ std::any a;
+ checkThrows<int>(a);
}
template <class Type>
void test_cast_to_reference() {
- assert(Type::count == 0);
- Type::reset();
+ assert(Type::count == 0);
+ Type::reset();
+ {
+ std::any a = Type(42);
+ const std::any& ca = a;
+ assert(Type::count == 1);
+ assert(Type::copied == 0);
+ assert(Type::moved == 1);
+
+ // Try a cast to a bad type.
+ // NOTE: Type cannot be an int.
+ checkThrows<int>(a);
+ checkThrows<int&, int const&>(a);
+ checkThrows<Type*, Type const*>(a);
+ checkThrows<Type const*>(a);
+
+ // Check getting a type by reference from a non-const lvalue any.
+ {
+ Type& v = std::any_cast<Type&>(a);
+ assert(v.value == 42);
+
+ Type const& cv = std::any_cast<Type const&>(a);
+ assert(&cv == &v);
+ }
+ // Check getting a type by reference from a const lvalue any.
{
- std::any a = Type(42);
- const std::any& ca = a;
- assert(Type::count == 1);
- assert(Type::copied == 0);
- assert(Type::moved == 1);
-
- // Try a cast to a bad type.
- // NOTE: Type cannot be an int.
- checkThrows<int>(a);
- checkThrows<int&, int const&>(a);
- checkThrows<Type*, Type const*>(a);
- checkThrows<Type const*>(a);
-
- // Check getting a type by reference from a non-const lvalue any.
- {
- Type& v = std::any_cast<Type&>(a);
- assert(v.value == 42);
-
- Type const &cv = std::any_cast<Type const&>(a);
- assert(&cv == &v);
- }
- // Check getting a type by reference from a const lvalue any.
- {
- Type const& v = std::any_cast<Type const&>(ca);
- assert(v.value == 42);
-
- Type const &cv = std::any_cast<Type const&>(ca);
- assert(&cv == &v);
- }
- // Check getting a type by reference from a const rvalue any.
- {
- Type const& v = std::any_cast<Type const&>(std::move(ca));
- assert(v.value == 42);
-
- Type const &cv = std::any_cast<Type const&>(std::move(ca));
- assert(&cv == &v);
- }
- // Check getting a type by reference from a const rvalue any.
- {
- Type&& v = std::any_cast<Type&&>(std::move(a));
- assert(v.value == 42);
- assert(std::any_cast<Type&>(a).value == 42);
-
- Type&& cv = std::any_cast<Type&&>(std::move(a));
- assert(&cv == &v);
- assert(std::any_cast<Type&>(a).value == 42);
- }
- // Check getting a type by reference from a const rvalue any.
- {
- Type const&& v = std::any_cast<Type const&&>(std::move(a));
- assert(v.value == 42);
- assert(std::any_cast<Type&>(a).value == 42);
-
- Type const&& cv = std::any_cast<Type const&&>(std::move(a));
- assert(&cv == &v);
- assert(std::any_cast<Type&>(a).value == 42);
- }
- // Check that the original object hasn't been changed.
- assertContains<Type>(a, 42);
-
- // Check that no objects have been created/copied/moved.
- assert(Type::count == 1);
- assert(Type::copied == 0);
- assert(Type::moved == 1);
+ Type const& v = std::any_cast<Type const&>(ca);
+ assert(v.value == 42);
+
+ Type const& cv = std::any_cast<Type const&>(ca);
+ assert(&cv == &v);
}
- assert(Type::count == 0);
+ // Check getting a type by reference from a const rvalue any.
+ {
+ Type const& v = std::any_cast<Type const&>(std::move(ca));
+ assert(v.value == 42);
+
+ Type const& cv = std::any_cast<Type const&>(std::move(ca));
+ assert(&cv == &v);
+ }
+ // Check getting a type by reference from a const rvalue any.
+ {
+ Type&& v = std::any_cast<Type&&>(std::move(a));
+ assert(v.value == 42);
+ assert(std::any_cast<Type&>(a).value == 42);
+
+ Type&& cv = std::any_cast<Type&&>(std::move(a));
+ assert(&cv == &v);
+ assert(std::any_cast<Type&>(a).value == 42);
+ }
+ // Check getting a type by reference from a const rvalue any.
+ {
+ Type const&& v = std::any_cast<Type const&&>(std::move(a));
+ assert(v.value == 42);
+ assert(std::any_cast<Type&>(a).value == 42);
+
+ Type const&& cv = std::any_cast<Type const&&>(std::move(a));
+ assert(&cv == &v);
+ assert(std::any_cast<Type&>(a).value == 42);
+ }
+ // Check that the original object hasn't been changed.
+ assertContains<Type>(a, 42);
+
+ // Check that no objects have been created/copied/moved.
+ assert(Type::count == 1);
+ assert(Type::copied == 0);
+ assert(Type::moved == 1);
+ }
+ assert(Type::count == 0);
}
template <class Type>
void test_cast_to_value() {
- assert(Type::count == 0);
+ assert(Type::count == 0);
+ Type::reset();
+ {
+ std::any a = Type(42);
+ assert(Type::count == 1);
+ assert(Type::copied == 0);
+ assert(Type::moved == 1);
+
+ // Try a cast to a bad type.
+ // NOTE: Type cannot be an int.
+ checkThrows<int>(a);
+ checkThrows<int&, int const&>(a);
+ checkThrows<Type*, Type const*>(a);
+ checkThrows<Type const*>(a);
+
+ Type::reset(); // NOTE: reset does not modify Type::count
+ // Check getting Type by value from a non-const lvalue any.
+ // This should cause the non-const copy constructor to be called.
+ {
+ Type t = std::any_cast<Type>(a);
+
+ assert(Type::count == 2);
+ assert(Type::copied == 1);
+ assert(Type::const_copied == 0);
+ assert(Type::non_const_copied == 1);
+ assert(Type::moved == 0);
+ assert(t.value == 42);
+ }
+ assert(Type::count == 1);
+ Type::reset();
+ // Check getting const Type by value from a non-const lvalue any.
+ // This should cause the const copy constructor to be called.
+ {
+ Type t = std::any_cast<Type const>(a);
+
+ assert(Type::count == 2);
+ assert(Type::copied == 1);
+ assert(Type::const_copied == 0);
+ assert(Type::non_const_copied == 1);
+ assert(Type::moved == 0);
+ assert(t.value == 42);
+ }
+ assert(Type::count == 1);
Type::reset();
+ // Check getting Type by value from a non-const lvalue any.
+ // This should cause the const copy constructor to be called.
{
- std::any a = Type(42);
- assert(Type::count == 1);
- assert(Type::copied == 0);
- assert(Type::moved == 1);
-
- // Try a cast to a bad type.
- // NOTE: Type cannot be an int.
- checkThrows<int>(a);
- checkThrows<int&, int const&>(a);
- checkThrows<Type*, Type const*>(a);
- checkThrows<Type const*>(a);
-
- Type::reset(); // NOTE: reset does not modify Type::count
- // Check getting Type by value from a non-const lvalue any.
- // This should cause the non-const copy constructor to be called.
- {
- Type t = std::any_cast<Type>(a);
-
- assert(Type::count == 2);
- assert(Type::copied == 1);
- assert(Type::const_copied == 0);
- assert(Type::non_const_copied == 1);
- assert(Type::moved == 0);
- assert(t.value == 42);
- }
- assert(Type::count == 1);
- Type::reset();
- // Check getting const Type by value from a non-const lvalue any.
- // This should cause the const copy constructor to be called.
- {
- Type t = std::any_cast<Type const>(a);
-
- assert(Type::count == 2);
- assert(Type::copied == 1);
- assert(Type::const_copied == 0);
- assert(Type::non_const_copied == 1);
- assert(Type::moved == 0);
- assert(t.value == 42);
- }
- assert(Type::count == 1);
- Type::reset();
- // Check getting Type by value from a non-const lvalue any.
- // This should cause the const copy constructor to be called.
- {
- Type t = std::any_cast<Type>(static_cast<const std::any&>(a));
-
- assert(Type::count == 2);
- assert(Type::copied == 1);
- assert(Type::const_copied == 1);
- assert(Type::non_const_copied == 0);
- assert(Type::moved == 0);
- assert(t.value == 42);
- }
- assert(Type::count == 1);
- Type::reset();
- // Check getting Type by value from a non-const rvalue any.
- // This should cause the non-const copy constructor to be called.
- {
- Type t = std::any_cast<Type>(static_cast<std::any&&>(a));
-
- assert(Type::count == 2);
- assert(Type::moved == 1);
- assert(Type::copied == 0);
- assert(Type::const_copied == 0);
- assert(Type::non_const_copied == 0);
- assert(t.value == 42);
- assert(std::any_cast<Type&>(a).value == 0);
- std::any_cast<Type&>(a).value = 42; // reset the value
- }
- assert(Type::count == 1);
- Type::reset();
- // Check getting const Type by value from a non-const rvalue any.
- // This should cause the const copy constructor to be called.
- {
- Type t = std::any_cast<Type const>(static_cast<std::any&&>(a));
-
- assert(Type::count == 2);
- assert(Type::copied == 0);
- assert(Type::const_copied == 0);
- assert(Type::non_const_copied == 0);
- assert(Type::moved == 1);
- assert(t.value == 42);
- assert(std::any_cast<Type&>(a).value == 0);
- std::any_cast<Type&>(a).value = 42; // reset the value
- }
- assert(Type::count == 1);
- Type::reset();
- // Check getting Type by value from a const rvalue any.
- // This should cause the const copy constructor to be called.
- {
- Type t = std::any_cast<Type>(static_cast<const std::any&&>(a));
-
- assert(Type::count == 2);
- assert(Type::copied == 1);
- assert(Type::const_copied == 1);
- assert(Type::non_const_copied == 0);
- assert(Type::moved == 0);
- assert(t.value == 42);
- assert(std::any_cast<Type&>(a).value == 42);
- }
- // Ensure we still only have 1 Type object alive.
- assert(Type::count == 1);
-
- // Check that the original object hasn't been changed.
- assertContains<Type>(a, 42);
+ Type t = std::any_cast<Type>(static_cast<const std::any&>(a));
+
+ assert(Type::count == 2);
+ assert(Type::copied == 1);
+ assert(Type::const_copied == 1);
+ assert(Type::non_const_copied == 0);
+ assert(Type::moved == 0);
+ assert(t.value == 42);
}
- assert(Type::count == 0);
+ assert(Type::count == 1);
+ Type::reset();
+ // Check getting Type by value from a non-const rvalue any.
+ // This should cause the non-const copy constructor to be called.
+ {
+ Type t = std::any_cast<Type>(static_cast<std::any&&>(a));
+
+ assert(Type::count == 2);
+ assert(Type::moved == 1);
+ assert(Type::copied == 0);
+ assert(Type::const_copied == 0);
+ assert(Type::non_const_copied == 0);
+ assert(t.value == 42);
+ assert(std::any_cast<Type&>(a).value == 0);
+ std::any_cast<Type&>(a).value = 42; // reset the value
+ }
+ assert(Type::count == 1);
+ Type::reset();
+ // Check getting const Type by value from a non-const rvalue any.
+ // This should cause the const copy constructor to be called.
+ {
+ Type t = std::any_cast<Type const>(static_cast<std::any&&>(a));
+
+ assert(Type::count == 2);
+ assert(Type::copied == 0);
+ assert(Type::const_copied == 0);
+ assert(Type::non_const_copied == 0);
+ assert(Type::moved == 1);
+ assert(t.value == 42);
+ assert(std::any_cast<Type&>(a).value == 0);
+ std::any_cast<Type&>(a).value = 42; // reset the value
+ }
+ assert(Type::count == 1);
+ Type::reset();
+ // Check getting Type by value from a const rvalue any.
+ // This should cause the const copy constructor to be called.
+ {
+ Type t = std::any_cast<Type>(static_cast<const std::any&&>(a));
+
+ assert(Type::count == 2);
+ assert(Type::copied == 1);
+ assert(Type::const_copied == 1);
+ assert(Type::non_const_copied == 0);
+ assert(Type::moved == 0);
+ assert(t.value == 42);
+ assert(std::any_cast<Type&>(a).value == 42);
+ }
+ // Ensure we still only have 1 Type object alive.
+ assert(Type::count == 1);
+
+ // Check that the original object hasn't been changed.
+ assertContains<Type>(a, 42);
+ }
+ assert(Type::count == 0);
}
int main(int, char**) {
- test_cast_is_not_noexcept();
- test_cast_return_type();
- test_cast_empty();
- test_cast_to_reference<small>();
- test_cast_to_reference<large>();
- test_cast_to_value<small>();
- test_cast_to_value<large>();
+ test_cast_is_not_noexcept();
+ test_cast_return_type();
+ test_cast_empty();
+ test_cast_to_reference<small>();
+ test_cast_to_reference<large>();
+ test_cast_to_value<small>();
+ test_cast_to_value<large>();
return 0;
}
diff --git a/libcxx/test/std/utilities/any/any.nonmembers/any.cast/any_cast_request_invalid_value_category.verify.cpp b/libcxx/test/std/utilities/any/any.nonmembers/any.cast/any_cast_request_invalid_value_category.verify.cpp
index 34f785fd..55e9923 100644
--- a/libcxx/test/std/utilities/any/any.nonmembers/any.cast/any_cast_request_invalid_value_category.verify.cpp
+++ b/libcxx/test/std/utilities/any/any.nonmembers/any.cast/any_cast_request_invalid_value_category.verify.cpp
@@ -19,47 +19,35 @@
struct TestType {};
-void test_const_lvalue_cast_request_non_const_lvalue()
-{
- const std::any a;
- // expected-error-re@any:* {{static assertion failed{{.*}}ValueType is required to be a const lvalue reference or a CopyConstructible type}}
- // expected-error@any:* {{drops 'const' qualifier}}
- std::any_cast<TestType &>(a); // expected-note {{requested here}}
-
- const std::any a2(42);
- // expected-error-re@any:* {{static assertion failed{{.*}}ValueType is required to be a const lvalue reference or a CopyConstructible type}}
- // expected-error@any:* {{drops 'const' qualifier}}
- std::any_cast<int&>(a2); // expected-note {{requested here}}
-}
-
-void test_lvalue_any_cast_request_rvalue()
-{
- std::any a;
- // expected-error-re@any:* {{static assertion failed{{.*}}ValueType is required to be an lvalue reference or a CopyConstructible type}}
- std::any_cast<TestType &&>(a); // expected-note {{requested here}}
-
- std::any a2(42);
- // expected-error-re@any:* {{static assertion failed{{.*}}ValueType is required to be an lvalue reference or a CopyConstructible type}}
- std::any_cast<int&&>(a2); // expected-note {{requested here}}
+void test_const_lvalue_cast_request_non_const_lvalue() {
+ const std::any a;
+ // expected-error-re@any:* {{static assertion failed{{.*}}ValueType is required to be a const lvalue reference or a CopyConstructible type}}
+ // expected-error@any:* {{drops 'const' qualifier}}
+ (void)std::any_cast<TestType&>(a); // expected-note {{requested here}}
+
+ const std::any a2(42);
+ // expected-error-re@any:* {{static assertion failed{{.*}}ValueType is required to be a const lvalue reference or a CopyConstructible type}}
+ // expected-error@any:* {{drops 'const' qualifier}}
+ (void)std::any_cast<int&>(a2); // expected-note {{requested here}}
}
-void test_rvalue_any_cast_request_lvalue()
-{
- std::any a;
- // expected-error-re@any:* {{static assertion failed{{.*}}ValueType is required to be an rvalue reference or a CopyConstructible type}}
- // expected-error@any:* {{non-const lvalue reference to type 'TestType' cannot bind to a temporary}}
- std::any_cast<TestType &>(std::move(a)); // expected-note {{requested here}}
+void test_lvalue_any_cast_request_rvalue() {
+ std::any a;
+ // expected-error-re@any:* {{static assertion failed{{.*}}ValueType is required to be an lvalue reference or a CopyConstructible type}}
+ (void)std::any_cast<TestType&&>(a); // expected-note {{requested here}}
- // expected-error-re@any:* {{static assertion failed{{.*}}ValueType is required to be an rvalue reference or a CopyConstructible type}}
- // expected-error@any:* {{non-const lvalue reference to type 'int' cannot bind to a temporary}}
- std::any_cast<int&>(42);
+ std::any a2(42);
+ // expected-error-re@any:* {{static assertion failed{{.*}}ValueType is required to be an lvalue reference or a CopyConstructible type}}
+ (void)std::any_cast<int&&>(a2); // expected-note {{requested here}}
}
-int main(int, char**)
-{
- test_const_lvalue_cast_request_non_const_lvalue();
- test_lvalue_any_cast_request_rvalue();
- test_rvalue_any_cast_request_lvalue();
+void test_rvalue_any_cast_request_lvalue() {
+ std::any a;
+ // expected-error-re@any:* {{static assertion failed{{.*}}ValueType is required to be an rvalue reference or a CopyConstructible type}}
+ // expected-error@any:* {{non-const lvalue reference to type 'TestType' cannot bind to a temporary}}
+ (void)std::any_cast<TestType&>(std::move(a)); // expected-note {{requested here}}
- return 0;
+ // expected-error-re@any:* {{static assertion failed{{.*}}ValueType is required to be an rvalue reference or a CopyConstructible type}}
+ // expected-error@any:* {{non-const lvalue reference to type 'int' cannot bind to a temporary}}
+ (void)std::any_cast<int&>(42);
}
diff --git a/libcxx/test/std/utilities/any/any.nonmembers/any.cast/const_correctness.verify.cpp b/libcxx/test/std/utilities/any/any.nonmembers/any.cast/const_correctness.verify.cpp
index 1830626..4ed1692 100644
--- a/libcxx/test/std/utilities/any/any.nonmembers/any.cast/const_correctness.verify.cpp
+++ b/libcxx/test/std/utilities/any/any.nonmembers/any.cast/const_correctness.verify.cpp
@@ -27,18 +27,18 @@
struct TestType {};
struct TestType2 {};
-void f() {
- std::any a;
+void test() {
+ std::any a;
- // expected-error-re@any:* {{static assertion failed{{.*}}ValueType is required to be a const lvalue reference or a CopyConstructible type}}
- std::any_cast<TestType &>(static_cast<std::any const&>(a)); // expected-note {{requested here}}
+ // expected-error-re@any:* {{static assertion failed{{.*}}ValueType is required to be a const lvalue reference or a CopyConstructible type}}
+ (void)std::any_cast<TestType&>(static_cast<std::any const&>(a)); // expected-note {{requested here}}
- // expected-error-re@any:* {{static assertion failed{{.*}}ValueType is required to be a const lvalue reference or a CopyConstructible type}}
- std::any_cast<TestType &&>(static_cast<std::any const&>(a)); // expected-note {{requested here}}
+ // expected-error-re@any:* {{static assertion failed{{.*}}ValueType is required to be a const lvalue reference or a CopyConstructible type}}
+ (void)std::any_cast<TestType&&>(static_cast<std::any const&>(a)); // expected-note {{requested here}}
- // expected-error-re@any:* {{static assertion failed{{.*}}ValueType is required to be a const lvalue reference or a CopyConstructible type}}
- std::any_cast<TestType2 &>(static_cast<std::any const&&>(a)); // expected-note {{requested here}}
+ // expected-error-re@any:* {{static assertion failed{{.*}}ValueType is required to be a const lvalue reference or a CopyConstructible type}}
+ (void)std::any_cast<TestType2&>(static_cast<std::any const&&>(a)); // expected-note {{requested here}}
- // expected-error-re@any:* {{static assertion failed{{.*}}ValueType is required to be a const lvalue reference or a CopyConstructible type}}
- std::any_cast<TestType2 &&>(static_cast<std::any const&&>(a)); // expected-note {{requested here}}
+ // expected-error-re@any:* {{static assertion failed{{.*}}ValueType is required to be a const lvalue reference or a CopyConstructible type}}
+ (void)std::any_cast<TestType2&&>(static_cast<std::any const&&>(a)); // expected-note {{requested here}}
}
diff --git a/libcxx/test/std/utilities/any/any.nonmembers/any.cast/not_copy_constructible.verify.cpp b/libcxx/test/std/utilities/any/any.nonmembers/any.cast/not_copy_constructible.verify.cpp
index 3b9aac5..ad91455 100644
--- a/libcxx/test/std/utilities/any/any.nonmembers/any.cast/not_copy_constructible.verify.cpp
+++ b/libcxx/test/std/utilities/any/any.nonmembers/any.cast/not_copy_constructible.verify.cpp
@@ -31,27 +31,27 @@
#include <any>
struct no_copy {
- no_copy() {}
- no_copy(no_copy &&) {}
- no_copy(no_copy const &) = delete;
+ no_copy() {}
+ no_copy(no_copy&&) {}
+ no_copy(no_copy const&) = delete;
};
struct no_move {
- no_move() {}
- no_move(no_move&&) = delete;
- no_move(no_move const&) {}
+ no_move() {}
+ no_move(no_move&&) = delete;
+ no_move(no_move const&) {}
};
-void f() {
- std::any a;
- // expected-error-re@any:* {{static assertion failed{{.*}}ValueType is required to be an lvalue reference or a CopyConstructible type}}
- std::any_cast<no_copy>(static_cast<std::any&>(a)); // expected-note {{requested here}}
+void test() {
+ std::any a;
+ // expected-error-re@any:* {{static assertion failed{{.*}}ValueType is required to be an lvalue reference or a CopyConstructible type}}
+ (void)std::any_cast<no_copy>(static_cast<std::any&>(a)); // expected-note {{requested here}}
- // expected-error-re@any:* {{static assertion failed{{.*}}ValueType is required to be a const lvalue reference or a CopyConstructible type}}
- std::any_cast<no_copy>(static_cast<std::any const&>(a)); // expected-note {{requested here}}
+ // expected-error-re@any:* {{static assertion failed{{.*}}ValueType is required to be a const lvalue reference or a CopyConstructible type}}
+ (void)std::any_cast<no_copy>(static_cast<std::any const&>(a)); // expected-note {{requested here}}
- std::any_cast<no_copy>(static_cast<std::any &&>(a)); // OK
+ (void)std::any_cast<no_copy>(static_cast<std::any&&>(a)); // OK
- // expected-error-re@any:* {{static assertion failed{{.*}}ValueType is required to be an rvalue reference or a CopyConstructible type}}
- std::any_cast<no_move>(static_cast<std::any &&>(a));
+ // expected-error-re@any:* {{static assertion failed{{.*}}ValueType is required to be an rvalue reference or a CopyConstructible type}}
+ (void)std::any_cast<no_move>(static_cast<std::any&&>(a));
}
diff --git a/libcxx/test/std/utilities/any/any.nonmembers/any.cast/reference_types.verify.cpp b/libcxx/test/std/utilities/any/any.nonmembers/any.cast/reference_types.verify.cpp
index 0a13fdf..d634f73 100644
--- a/libcxx/test/std/utilities/any/any.nonmembers/any.cast/reference_types.verify.cpp
+++ b/libcxx/test/std/utilities/any/any.nonmembers/any.cast/reference_types.verify.cpp
@@ -18,35 +18,32 @@
#include <any>
-int main(int, char**)
-{
- std::any a = 1;
+void test() {
+ std::any a = 1;
- // expected-error-re@any:* 1 {{static assertion failed{{.*}}_ValueType may not be a reference.}}
- std::any_cast<int &>(&a); // expected-note {{requested here}}
+ // expected-error-re@any:* 1 {{static assertion failed{{.*}}_ValueType may not be a reference.}}
+ (void)std::any_cast<int&>(&a); // expected-note {{requested here}}
- // expected-error-re@any:* 1 {{static assertion failed{{.*}}_ValueType may not be a reference.}}
- std::any_cast<int &&>(&a); // expected-note {{requested here}}
+ // expected-error-re@any:* 1 {{static assertion failed{{.*}}_ValueType may not be a reference.}}
+ (void)std::any_cast<int&&>(&a); // expected-note {{requested here}}
- // expected-error-re@any:* 1 {{static assertion failed{{.*}}_ValueType may not be a reference.}}
- std::any_cast<int const &>(&a); // expected-note {{requested here}}
+ // expected-error-re@any:* 1 {{static assertion failed{{.*}}_ValueType may not be a reference.}}
+ (void)std::any_cast<int const&>(&a); // expected-note {{requested here}}
- // expected-error-re@any:* 1 {{static assertion failed{{.*}}_ValueType may not be a reference.}}
- std::any_cast<int const&&>(&a); // expected-note {{requested here}}
+ // expected-error-re@any:* 1 {{static assertion failed{{.*}}_ValueType may not be a reference.}}
+ (void)std::any_cast<int const&&>(&a); // expected-note {{requested here}}
- const std::any& a2 = a;
+ const std::any& a2 = a;
- // expected-error-re@any:* 1 {{static assertion failed{{.*}}_ValueType may not be a reference.}}
- std::any_cast<int &>(&a2); // expected-note {{requested here}}
+ // expected-error-re@any:* 1 {{static assertion failed{{.*}}_ValueType may not be a reference.}}
+ (void)std::any_cast<int&>(&a2); // expected-note {{requested here}}
- // expected-error-re@any:* 1 {{static assertion failed{{.*}}_ValueType may not be a reference.}}
- std::any_cast<int &&>(&a2); // expected-note {{requested here}}
+ // expected-error-re@any:* 1 {{static assertion failed{{.*}}_ValueType may not be a reference.}}
+ (void)std::any_cast<int&&>(&a2); // expected-note {{requested here}}
- // expected-error-re@any:* 1 {{static assertion failed{{.*}}_ValueType may not be a reference.}}
- std::any_cast<int const &>(&a2); // expected-note {{requested here}}
+ // expected-error-re@any:* 1 {{static assertion failed{{.*}}_ValueType may not be a reference.}}
+ (void)std::any_cast<int const&>(&a2); // expected-note {{requested here}}
- // expected-error-re@any:* 1 {{static assertion failed{{.*}}_ValueType may not be a reference.}}
- std::any_cast<int const &&>(&a2); // expected-note {{requested here}}
-
- return 0;
+ // expected-error-re@any:* 1 {{static assertion failed{{.*}}_ValueType may not be a reference.}}
+ (void)std::any_cast<int const&&>(&a2); // expected-note {{requested here}}
}
diff --git a/libcxx/test/std/utilities/any/any.nonmembers/any.cast/void.verify.cpp b/libcxx/test/std/utilities/any/any.nonmembers/any.cast/void.verify.cpp
index 9530d63..d1ec42ea 100644
--- a/libcxx/test/std/utilities/any/any.nonmembers/any.cast/void.verify.cpp
+++ b/libcxx/test/std/utilities/any/any.nonmembers/any.cast/void.verify.cpp
@@ -23,12 +23,12 @@ void test() {
const std::any ca = 1;
// expected-error-re@any:* {{static assertion failed{{.*}}_ValueType may not be void.}}
- std::any_cast<void>(&ca); // expected-note {{requested here}}
+ (void)std::any_cast<void>(&ca); // expected-note {{requested here}}
}
{
std::any a = 1;
// expected-error-re@any:* {{static assertion failed{{.*}}_ValueType may not be void.}}
- std::any_cast<void>(&a); // expected-note {{requested here}}
+ (void)std::any_cast<void>(&a); // expected-note {{requested here}}
}
}
diff --git a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.invoke/robust_against_adl.pass.cpp b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.invoke/robust_against_adl.pass.cpp
index 2774401..f666e8b 100644
--- a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.invoke/robust_against_adl.pass.cpp
+++ b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.invoke/robust_against_adl.pass.cpp
@@ -27,23 +27,23 @@ int main(int, char**)
{
Ptr x = nullptr;
const Ptr cx = nullptr;
- std::ref(no_args)();
- std::ref(one_arg)(x);
- std::ref(one_arg)(cx);
- std::ref(two_args)(x, x);
- std::ref(two_args)(x, cx);
- std::ref(two_args)(cx, x);
- std::ref(two_args)(cx, cx);
- std::ref(three_args)(x, x, x);
- std::ref(three_args)(x, x, cx);
- std::ref(three_args)(x, cx, x);
- std::ref(three_args)(cx, x, x);
- std::ref(three_args)(x, cx, cx);
- std::ref(three_args)(cx, x, cx);
- std::ref(three_args)(cx, cx, x);
- std::ref(three_args)(cx, cx, cx);
- std::ref(one_arg_void)(x);
- std::ref(one_arg_void)(cx);
+ (void)std::ref(no_args)();
+ (void)std::ref(one_arg)(x);
+ (void)std::ref(one_arg)(cx);
+ (void)std::ref(two_args)(x, x);
+ (void)std::ref(two_args)(x, cx);
+ (void)std::ref(two_args)(cx, x);
+ (void)std::ref(two_args)(cx, cx);
+ (void)std::ref(three_args)(x, x, x);
+ (void)std::ref(three_args)(x, x, cx);
+ (void)std::ref(three_args)(x, cx, x);
+ (void)std::ref(three_args)(cx, x, x);
+ (void)std::ref(three_args)(x, cx, cx);
+ (void)std::ref(three_args)(cx, x, cx);
+ (void)std::ref(three_args)(cx, cx, x);
+ (void)std::ref(three_args)(cx, cx, cx);
+ (void)std::ref(one_arg_void)(x);
+ (void)std::ref(one_arg_void)(cx);
return 0;
}
diff --git a/libcxx/test/std/utilities/memory/allocator.uses/allocator.uses.construction/make_obj_using_allocator.pass.cpp b/libcxx/test/std/utilities/memory/allocator.uses/allocator.uses.construction/make_obj_using_allocator.pass.cpp
index 1f60514..744e530 100644
--- a/libcxx/test/std/utilities/memory/allocator.uses/allocator.uses.construction/make_obj_using_allocator.pass.cpp
+++ b/libcxx/test/std/utilities/memory/allocator.uses/allocator.uses.construction/make_obj_using_allocator.pass.cpp
@@ -14,6 +14,7 @@
// test_memory_resource requires RTTI for dynamic_cast
// UNSUPPORTED: no-rtti
+#include <cassert>
#include <concepts>
#include <memory>
#include <tuple>
diff --git a/libcxx/test/std/utilities/memory/allocator.uses/allocator.uses.construction/uninitialized_construct_using_allocator.pass.cpp b/libcxx/test/std/utilities/memory/allocator.uses/allocator.uses.construction/uninitialized_construct_using_allocator.pass.cpp
index 07260e5..329698c 100644
--- a/libcxx/test/std/utilities/memory/allocator.uses/allocator.uses.construction/uninitialized_construct_using_allocator.pass.cpp
+++ b/libcxx/test/std/utilities/memory/allocator.uses/allocator.uses.construction/uninitialized_construct_using_allocator.pass.cpp
@@ -14,6 +14,7 @@
// test_memory_resource requires RTTI for dynamic_cast
// UNSUPPORTED: no-rtti
+#include <cassert>
#include <concepts>
#include <memory>
#include <tuple>
diff --git a/libcxx/test/std/utilities/memory/allocator.uses/allocator.uses.construction/uses_allocator_construction_args.pass.cpp b/libcxx/test/std/utilities/memory/allocator.uses/allocator.uses.construction/uses_allocator_construction_args.pass.cpp
index 93a445d7..aa3a5e8 100644
--- a/libcxx/test/std/utilities/memory/allocator.uses/allocator.uses.construction/uses_allocator_construction_args.pass.cpp
+++ b/libcxx/test/std/utilities/memory/allocator.uses/allocator.uses.construction/uses_allocator_construction_args.pass.cpp
@@ -14,10 +14,12 @@
// test_memory_resource requires RTTI for dynamic_cast
// UNSUPPORTED: no-rtti
+#include <cassert>
#include <concepts>
#include <memory>
#include <ranges>
#include <tuple>
+#include <type_traits>
#include <utility>
#include "common.h"
diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/unique_ptr.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/unique_ptr.pass.cpp
index 9308bb3..f956262 100644
--- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/unique_ptr.pass.cpp
+++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/unique_ptr.pass.cpp
@@ -12,6 +12,8 @@
// template <class Y, class D> shared_ptr(unique_ptr<Y, D>&&r);
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
+
#include <memory>
#include <new>
#include <cstdlib>
@@ -165,12 +167,10 @@ int main(int, char**)
{ // LWG 2399
fn(std::unique_ptr<int>(new int));
}
-#if TEST_STD_VER >= 14
{ // LWG 2415
std::unique_ptr<int, void (*)(int*)> p(nullptr, assert_deleter<int>);
std::shared_ptr<int> p2(std::move(p)); // should not call deleter when going out of scope
}
-#endif
{
adl::D d;
diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.obs/unique.deprecated_in_cxx17.verify.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.obs/unique.deprecated_in_cxx17.verify.cpp
index eae0f6e..bc6f2a3 100644
--- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.obs/unique.deprecated_in_cxx17.verify.cpp
+++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.obs/unique.deprecated_in_cxx17.verify.cpp
@@ -20,5 +20,5 @@
void f() {
const std::shared_ptr<int> p;
- p.unique(); // expected-warning {{'unique' is deprecated}}
+ (void)p.unique(); // expected-warning {{'unique' is deprecated}}
}
diff --git a/libcxx/test/std/utilities/optional/optional.iterator/begin.pass.cpp b/libcxx/test/std/utilities/optional/optional.iterator/begin.pass.cpp
index df95a8d..8123452 100644
--- a/libcxx/test/std/utilities/optional/optional.iterator/begin.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.iterator/begin.pass.cpp
@@ -21,7 +21,8 @@
template <typename T>
constexpr bool test() {
- std::optional<T> opt{T{}};
+ std::remove_reference_t<T> t = std::remove_reference_t<T>{};
+ std::optional<T> opt{t};
{ // begin() is marked noexcept
static_assert(noexcept(opt.begin()));
@@ -53,6 +54,10 @@ constexpr bool tests() {
assert(test<char>());
assert(test<const int>());
assert(test<const char>());
+ assert(test<int&>());
+ assert(test<char&>());
+ assert(test<const int&>());
+ assert(test<const char&>());
return true;
}
diff --git a/libcxx/test/std/utilities/optional/optional.iterator/borrowed_range.compile.pass.cpp b/libcxx/test/std/utilities/optional/optional.iterator/borrowed_range.compile.pass.cpp
new file mode 100644
index 0000000..a79d1d5
--- /dev/null
+++ b/libcxx/test/std/utilities/optional/optional.iterator/borrowed_range.compile.pass.cpp
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <optional>
+
+// template <class T> class optional<T&>::iterator;
+// template <class T> class optional<T&>::const_iterator;
+// template <class T>
+// constexpr bool ranges::enable_borrowed_range<optional<T&>> = true;
+
+#include <cassert>
+#include <optional>
+#include <ranges>
+
+template <typename T>
+void borrowed_range() {
+ static_assert(std::ranges::enable_borrowed_range<std::optional<T&>>);
+ static_assert(std::ranges::range<std::optional<T&>> == std::ranges::borrowed_range<std::optional<T&>>);
+}
+
+void test_borrowed_range() {
+ borrowed_range<int>();
+ borrowed_range<const int>();
+ borrowed_range<int[]>();
+ borrowed_range<int[10]>();
+ borrowed_range<int()>();
+}
diff --git a/libcxx/test/std/utilities/optional/optional.iterator/end.pass.cpp b/libcxx/test/std/utilities/optional/optional.iterator/end.pass.cpp
index 966c3e7..c62c9fc 100644
--- a/libcxx/test/std/utilities/optional/optional.iterator/end.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.iterator/end.pass.cpp
@@ -17,6 +17,7 @@
#include <iterator>
#include <optional>
#include <ranges>
+#include <type_traits>
#include <utility>
template <typename T>
@@ -41,7 +42,8 @@ constexpr bool test() {
assert(it2 == std::as_const(disengaged).end());
}
- std::optional<T> engaged{T{}};
+ std::remove_reference_t<T> t = std::remove_reference_t<T>{};
+ std::optional<T> engaged{t};
{ // end() != begin() if the optional is engaged
auto it = engaged.end();
@@ -62,6 +64,10 @@ constexpr bool tests() {
assert(test<char>());
assert(test<const int>());
assert(test<const char>());
+ assert(test<int&>());
+ assert(test<char&>());
+ assert(test<const int&>());
+ assert(test<const char&>());
return true;
}
diff --git a/libcxx/test/std/utilities/optional/optional.iterator/iterator.pass.cpp b/libcxx/test/std/utilities/optional/optional.iterator/iterator.pass.cpp
index 1203290..671fac3 100644
--- a/libcxx/test/std/utilities/optional/optional.iterator/iterator.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.iterator/iterator.pass.cpp
@@ -14,15 +14,23 @@
// template <class T> class optional::const_iterator;
#include <cassert>
-#include <iterator>
#include <optional>
#include <ranges>
#include <type_traits>
#include <utility>
-template <typename T, T __val>
+template <typename T>
+constexpr bool test_range_concept() {
+ return std::ranges::range<std::optional<T>>;
+}
+
+template <typename T, std::remove_reference_t<T> __val>
constexpr bool test() {
- std::optional<T> opt{__val};
+ std::remove_reference_t<T> v{__val};
+ std::optional<T> opt{v};
+ {
+ assert(test_range_concept<T>());
+ }
{ // Dereferencing an iterator of an engaged optional will return the same value that the optional holds.
auto it = opt.begin();
@@ -41,13 +49,14 @@ constexpr bool test() {
assert(std::random_access_iterator<decltype(it2)>);
}
- { // const_iterator::value_type == std::remove_cv_t<T>, const_iterator::reference == const T&, iterator::value_type = std::remove_cv_t<T>, iterator::reference == T&
+ { // const_iterator::value_type == std::remove_cvref_t<T>, const_iterator::reference == const T&, iterator::value_type = std::remove_cvref_t<T>, iterator::reference == T&
+ // std::remove_cv_t is impossible for optional<T&>
auto it = opt.begin();
auto it2 = std::as_const(opt).begin();
- assert((std::is_same_v<typename decltype(it)::value_type, std::remove_cv_t<T>>));
- assert((std::is_same_v<typename decltype(it)::reference, T&>));
- assert((std::is_same_v<typename decltype(it2)::value_type, std::remove_cv_t<T>>));
- assert((std::is_same_v<typename decltype(it2)::reference, const T&>));
+ assert((std::is_same_v<typename decltype(it)::value_type, std::remove_cvref_t<T>>));
+ assert((std::is_same_v<typename decltype(it)::reference, std::remove_reference_t<T>&>));
+ assert((std::is_same_v<typename decltype(it2)::value_type, std::remove_cvref_t<T>>));
+ assert((std::is_same_v<typename decltype(it2)::reference, const std::remove_reference_t<T>&>));
}
{ // std::ranges::size for an engaged optional<T> == 1, disengaged optional<T> == 0
@@ -68,13 +77,13 @@ constexpr bool test() {
// An optional with value that is reset will have a begin() == end(), then when it is reassigned a value,
// begin() != end(), and *begin() will contain the new value.
{
- std::optional<T> val{__val};
+ std::optional<T> val{v};
assert(val.begin() != val.end());
val.reset();
assert(val.begin() == val.end());
- val.emplace(__val);
+ val.emplace(v);
assert(val.begin() != val.end());
- assert(*(val.begin()) == __val);
+ assert(*(val.begin()) == v);
}
return true;
@@ -86,6 +95,15 @@ constexpr bool tests() {
assert((test<bool, true>()));
assert((test<const int, 2>()));
assert((test<const char, 'b'>()));
+ assert((test<int&, 1>()));
+ assert((test<char&, 'a'>()));
+ assert((test<bool&, true>()));
+ assert((test<const int&, 2>()));
+ assert((test<const char&, 'b'>()));
+
+ assert(!test_range_concept<int (&)()>());
+ assert(!test_range_concept<int (&)[]>());
+ assert(!test_range_concept<int (&)[42]>());
return true;
}
diff --git a/libcxx/test/std/utilities/optional/optional.monadic/and_then.pass.cpp b/libcxx/test/std/utilities/optional/optional.monadic/and_then.pass.cpp
index 97305d9..133eed4 100644
--- a/libcxx/test/std/utilities/optional/optional.monadic/and_then.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.monadic/and_then.pass.cpp
@@ -16,6 +16,7 @@
// template<class F> constexpr auto and_then(F&&) const&&;
#include <cassert>
+#include <concepts>
#include <optional>
#include "test_macros.h"
@@ -257,8 +258,94 @@ constexpr bool test() {
return true;
}
+#if TEST_STD_VER >= 26
+constexpr bool test_ref() {
+ // Test & overload
+ {
+ // Without & qualifier on F's operator()
+ {
+ int j = 42;
+ std::optional<int&> i{j};
+ std::same_as<std::optional<int>> decltype(auto) r = i.and_then(LVal{});
+
+ assert(r == 1);
+ assert(i.and_then(NOLVal{}) == std::nullopt);
+ }
+
+ //With & qualifier on F's operator()
+ {
+ int j = 42;
+ std::optional<int&> i{j};
+ RefQual l{};
+ NORefQual nl{};
+ std::same_as<std::optional<int>> decltype(auto) r = i.and_then(l);
+
+ assert(r == 1);
+ assert(i.and_then(nl) == std::nullopt);
+ }
+ }
+
+ // Test const& overload
+ {
+ // Without & qualifier on F's operator()
+ {
+ int j = 42;
+ std::optional<const int&> i{j};
+ std::same_as<std::optional<int>> decltype(auto) r = i.and_then(CLVal{});
+
+ assert(r == 1);
+ assert(i.and_then(NOCLVal{}) == std::nullopt);
+ }
+
+ //With & qualifier on F's operator()
+ {
+ int j = 42;
+ const std::optional<int&> i{j};
+ const CRefQual l{};
+ const NOCRefQual nl{};
+ std::same_as<std::optional<int>> decltype(auto) r = i.and_then(l);
+
+ assert(r == 1);
+ assert(i.and_then(nl) == std::nullopt);
+ }
+ }
+ // Test && overload
+ {
+ //With & qualifier on F's operator()
+ {
+ int j = 42;
+ std::optional<int&> i{j};
+ std::same_as<std::optional<int>> decltype(auto) r = i.and_then(RVRefQual{});
+
+ assert(r == 1);
+ assert(i.and_then(NORVRefQual{}) == std::nullopt);
+ }
+ }
+
+ // Test const&& overload
+ {
+ //With & qualifier on F's operator()
+ {
+ int j = 42;
+ const std::optional<int&> i{j};
+ const RVCRefQual l{};
+ const NORVCRefQual nl{};
+ std::same_as<std::optional<int>> decltype(auto) r = i.and_then(std::move(l));
+
+ assert(r == 1);
+ assert(i.and_then(std::move(nl)) == std::nullopt);
+ }
+ }
+ return true;
+}
+#endif
+
int main(int, char**) {
test();
static_assert(test());
+#if TEST_STD_VER >= 26
+ test_ref();
+ static_assert(test_ref());
+#endif
return 0;
}
diff --git a/libcxx/test/std/utilities/optional/optional.monadic/or_else.pass.cpp b/libcxx/test/std/utilities/optional/optional.monadic/or_else.pass.cpp
index ccc94ab..de0a67c 100644
--- a/libcxx/test/std/utilities/optional/optional.monadic/or_else.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.monadic/or_else.pass.cpp
@@ -62,6 +62,32 @@ constexpr bool test() {
return std::optional<MoveOnly>{};
});
}
+#if TEST_STD_VER >= 26
+ {
+ int i = 2;
+ std::optional<int&> opt;
+ assert(opt.or_else([&] { return std::optional<int&>{i}; }) == i);
+ int j = 3;
+ opt = j;
+ opt.or_else([] {
+ assert(false);
+ return std::optional<int&>{};
+ });
+ assert(opt == j);
+ }
+ {
+ int i = 2;
+ std::optional<int&> opt;
+ assert(std::move(opt).or_else([&] { return std::optional<int&>{i}; }) == i);
+ int j = 3;
+ opt = j;
+ std::move(opt).or_else([] {
+ assert(false);
+ return std::optional<int&>{};
+ });
+ assert(opt == j);
+ }
+#endif
return true;
}
diff --git a/libcxx/test/std/utilities/optional/optional.monadic/transform.pass.cpp b/libcxx/test/std/utilities/optional/optional.monadic/transform.pass.cpp
index 0a15151..ad2713f 100644
--- a/libcxx/test/std/utilities/optional/optional.monadic/transform.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.monadic/transform.pass.cpp
@@ -17,62 +17,64 @@
#include "test_macros.h"
#include <cassert>
+#include <concepts>
#include <optional>
#include <type_traits>
+#include <utility>
struct LVal {
constexpr int operator()(int&) { return 1; }
- int operator()(const int&) = delete;
- int operator()(int&&) = delete;
+ int operator()(const int&) = delete;
+ int operator()(int&&) = delete;
int operator()(const int&&) = delete;
};
struct CLVal {
int operator()(int&) = delete;
constexpr int operator()(const int&) { return 1; }
- int operator()(int&&) = delete;
+ int operator()(int&&) = delete;
int operator()(const int&&) = delete;
};
struct RVal {
- int operator()(int&) = delete;
+ int operator()(int&) = delete;
int operator()(const int&) = delete;
constexpr int operator()(int&&) { return 1; }
int operator()(const int&&) = delete;
};
struct CRVal {
- int operator()(int&) = delete;
+ int operator()(int&) = delete;
int operator()(const int&) = delete;
- int operator()(int&&) = delete;
+ int operator()(int&&) = delete;
constexpr int operator()(const int&&) { return 1; }
};
struct RefQual {
constexpr int operator()(int) & { return 1; }
- int operator()(int) const& = delete;
- int operator()(int) && = delete;
+ int operator()(int) const& = delete;
+ int operator()(int) && = delete;
int operator()(int) const&& = delete;
};
struct CRefQual {
int operator()(int) & = delete;
constexpr int operator()(int) const& { return 1; }
- int operator()(int) && = delete;
+ int operator()(int) && = delete;
int operator()(int) const&& = delete;
};
struct RVRefQual {
- int operator()(int) & = delete;
+ int operator()(int) & = delete;
int operator()(int) const& = delete;
constexpr int operator()(int) && { return 1; }
int operator()(int) const&& = delete;
};
struct RVCRefQual {
- int operator()(int) & = delete;
+ int operator()(int) & = delete;
int operator()(int) const& = delete;
- int operator()(int) && = delete;
+ int operator()(int) && = delete;
constexpr int operator()(int) const&& { return 1; }
};
@@ -83,7 +85,7 @@ struct NoCopy {
};
struct NoMove {
- NoMove() = default;
+ NoMove() = default;
NoMove(NoMove&&) = delete;
NoMove operator()(const NoCopy&&) { return NoMove{}; }
};
@@ -200,8 +202,111 @@ constexpr bool test() {
return true;
}
+#if TEST_STD_VER >= 26
+constexpr bool test_ref() {
+ {
+ std::optional<int&> opt1;
+ std::same_as<std::optional<int>> decltype(auto) opt1r = opt1.transform([](int i) { return i + 2; });
+ assert(!opt1);
+ assert(!opt1r);
+ }
+
+ {
+ int i = 42;
+ std::optional<int&> opt{i};
+ std::same_as<std::optional<int>> decltype(auto) o2 = opt.transform([](int j) { return j + 2; });
+
+ assert(*o2 == 44);
+ }
+ // Test & overload
+ {
+ // Without & qualifier on F's operator()
+ {
+ int i = 42;
+ std::optional<int&> opt{i};
+ std::same_as<std::optional<int>> decltype(auto) o3 = opt.transform(LVal{});
+
+ assert(*o3 == 1);
+ }
+
+ //With & qualifier on F's operator()
+ {
+ int i = 42;
+ std::optional<int&> opt{i};
+ RefQual l{};
+ std::same_as<std::optional<int>> decltype(auto) o3 = opt.transform(l);
+
+ assert(*o3 == 1);
+ }
+ }
+ // const& overload
+ {
+ // Without & qualifier on F's operator()
+ {
+ int i = 42;
+ std::optional<const int&> opt{i};
+ std::same_as<std::optional<int>> decltype(auto) o3 = std::as_const(opt).transform(CLVal{});
+
+ assert(*o3 == 1);
+ }
+
+ //With & qualifier on F's operator()
+ {
+ int i = 42;
+ const std::optional<int&> opt{i};
+ const CRefQual l{};
+ std::same_as<std::optional<int>> decltype(auto) o3 = opt.transform(l);
+
+ assert(*o3 == 1);
+ }
+ }
+
+ // Test && overload
+ {
+ // Without & qualifier on F's operator()
+ {
+ int i = 42;
+ std::optional<int> opt{i};
+ std::same_as<std::optional<int>> decltype(auto) o3 = std::move(opt).transform(RVal{});
+
+ assert(*o3 == 1);
+ }
+
+ //With & qualifier on F's operator()
+ {
+ int i = 42;
+ std::optional<int&> opt{i};
+ std::same_as<std::optional<int>> decltype(auto) o3 = std::move(opt).transform(RVRefQual{});
+ assert(*o3 == 1);
+ }
+ }
+
+ // const&& overload
+ {
+ //With & qualifier on F's operator()
+ {
+ int i = 42;
+ std::optional<int&> opt{i};
+ const RVCRefQual rvc{};
+ std::same_as<std::optional<int>> decltype(auto) o3 = opt.transform(std::move(rvc));
+ assert(*o3 == 1);
+ }
+ }
+ {
+ std::optional<int&> o6 = std::nullopt;
+ auto o6r = o6.transform([](int) { return 42; });
+ assert(!o6r);
+ }
+ return true;
+}
+#endif
+
int main(int, char**) {
test();
static_assert(test());
+#if TEST_STD_VER >= 26
+ test_ref();
+ static_assert(test_ref());
+#endif
return 0;
}
diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.assign/assign_value.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.assign/assign_value.pass.cpp
index eaca111b..ddb9ffc 100644
--- a/libcxx/test/std/utilities/optional/optional.object/optional.object.assign/assign_value.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.assign/assign_value.pass.cpp
@@ -250,6 +250,57 @@ constexpr T pr38638(T v)
return *o + 2;
}
+#if TEST_STD_VER >= 26
+
+template <typename T, std::remove_reference_t<T> _Val>
+constexpr void test_with_ref() {
+ T t{_Val};
+ { // to empty
+ optional<T&> opt;
+ opt = t;
+ assert(static_cast<bool>(opt) == true);
+ assert(*opt == t);
+ }
+ { // to existing
+ optional<T&> opt{t};
+ opt = t;
+ assert(static_cast<bool>(opt) == true);
+ assert(*opt == t);
+ }
+ { // test default argument
+ optional<T&> opt;
+ opt = {t};
+ assert(static_cast<bool>(opt) == true);
+ assert(*opt == t);
+ }
+ { // test default argument
+ optional<T&> opt{t};
+ opt = {};
+ assert(static_cast<bool>(opt) == false);
+ }
+ // test two objects, make sure that the optional only changes what it holds a reference to
+ {
+ T t2{_Val};
+ optional<T&> opt{t};
+ opt = t2;
+
+ assert(std::addressof(*opt) != std::addressof(t));
+ assert(std::addressof(*opt) == std::addressof(t2));
+ }
+ // test that reassigning the reference for an optional<T&> doesn't affect the objet it's holding a reference to
+ {
+ int i = -1;
+ int j = 2;
+ optional<int&> opt{i};
+ opt = j;
+
+ assert(i == -1);
+ assert(std::addressof(*opt) != std::addressof(i));
+ assert(std::addressof(*opt) == std::addressof(j));
+ assert(*opt == 2);
+ }
+}
+#endif
int main(int, char**)
{
@@ -281,5 +332,8 @@ int main(int, char**)
static_assert(pr38638(3) == 5, "");
- return 0;
+#if TEST_STD_VER >= 26
+ test_with_ref<int, 3>();
+#endif
+ return 0;
}
diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.assign/emplace.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.assign/emplace.pass.cpp
index 245d8ff..629e315 100644
--- a/libcxx/test/std/utilities/optional/optional.object/optional.object.assign/emplace.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.assign/emplace.pass.cpp
@@ -221,6 +221,24 @@ TEST_CONSTEXPR_CXX20 bool test_empty_emplace() {
return true;
}
+#if TEST_STD_VER >= 26
+template <class T, std::remove_reference_t<T> _Val>
+constexpr bool test_ref() {
+ using Opt = std::optional<T&>;
+ T t{_Val};
+ {
+ Opt opt;
+ auto& v = opt.emplace(t);
+ static_assert(std::is_same_v<T&, decltype(v)>);
+ assert(static_cast<bool>(opt) == true);
+ assert(*opt == t);
+ assert(&v == &*opt);
+ assert(&t == &*opt);
+ }
+ return true;
+}
+#endif
+
int main(int, char**)
{
{
@@ -291,6 +309,11 @@ int main(int, char**)
}
}
#endif
-
- return 0;
+#if TEST_STD_VER >= 26
+ static_assert(test_ref<int, 1>());
+ static_assert(test_ref<double, 15.0>());
+ assert((test_ref<int, 1>()));
+ assert((test_ref<double, 15.0>()));
+#endif
+ return 0;
}
diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/U.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/U.pass.cpp
index a90fecfd..1e951eb 100644
--- a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/U.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/U.pass.cpp
@@ -13,25 +13,28 @@
// template <class U>
// constexpr EXPLICIT optional(U&& u);
+#include <cassert>
#include <optional>
#include <type_traits>
-#include <cassert>
#include "test_macros.h"
#include "archetypes.h"
#include "test_convertible.h"
-
using std::optional;
-struct ImplicitThrow
-{
- constexpr ImplicitThrow(int x) { if (x != -1) TEST_THROW(6);}
+struct ImplicitThrow {
+ constexpr ImplicitThrow(int x) {
+ if (x != -1)
+ TEST_THROW(6);
+ }
};
-struct ExplicitThrow
-{
- constexpr explicit ExplicitThrow(int x) { if (x != -1) TEST_THROW(6);}
+struct ExplicitThrow {
+ constexpr explicit ExplicitThrow(int x) {
+ if (x != -1)
+ TEST_THROW(6);
+ }
};
struct ImplicitAny {
@@ -39,56 +42,52 @@ struct ImplicitAny {
constexpr ImplicitAny(U&&) {}
};
-
template <class To, class From>
-constexpr bool implicit_conversion(optional<To>&& opt, const From& v)
-{
- using O = optional<To>;
- static_assert(test_convertible<O, From>(), "");
- static_assert(!test_convertible<O, void*>(), "");
- static_assert(!test_convertible<O, From, int>(), "");
- return opt && *opt == static_cast<To>(v);
+constexpr bool implicit_conversion(optional<To>&& opt, const From& v) {
+ using O = optional<To>;
+ static_assert(test_convertible<O, From>(), "");
+ static_assert(!test_convertible<O, void*>(), "");
+ static_assert(!test_convertible<O, From, int>(), "");
+ return opt && *opt == static_cast<To>(v);
}
template <class To, class Input, class Expect>
-constexpr bool explicit_conversion(Input&& in, const Expect& v)
-{
- using O = optional<To>;
- static_assert(std::is_constructible<O, Input>::value, "");
- static_assert(!std::is_convertible<Input, O>::value, "");
- static_assert(!std::is_constructible<O, void*>::value, "");
- static_assert(!std::is_constructible<O, Input, int>::value, "");
- optional<To> opt(std::forward<Input>(in));
- optional<To> opt2{std::forward<Input>(in)};
- return opt && *opt == static_cast<To>(v) && (opt2 && *opt2 == static_cast<To>(v));
+constexpr bool explicit_conversion(Input&& in, const Expect& v) {
+ using O = optional<To>;
+ static_assert(std::is_constructible<O, Input>::value, "");
+ static_assert(!std::is_convertible<Input, O>::value, "");
+ static_assert(!std::is_constructible<O, void*>::value, "");
+ static_assert(!std::is_constructible<O, Input, int>::value, "");
+ optional<To> opt(std::forward<Input>(in));
+ optional<To> opt2{std::forward<Input>(in)};
+ return opt && *opt == static_cast<To>(v) && (opt2 && *opt2 == static_cast<To>(v));
}
-void test_implicit()
-{
- {
- static_assert(implicit_conversion<long long>(42, 42), "");
- }
- {
- static_assert(implicit_conversion<long double>(3.14, 3.14), "");
- }
- {
- int x = 42;
- optional<void* const> o(&x);
- assert(*o == &x);
- }
- {
- using T = TrivialTestTypes::TestType;
- static_assert(implicit_conversion<T>(42, 42), "");
- }
- {
- using T = TestTypes::TestType;
- assert(implicit_conversion<T>(3, T(3)));
- }
- {
- using T = TestTypes::TestType;
- optional<T> opt({3});
- assert(opt && *opt == static_cast<T>(3));
- }
+void test_implicit() {
+ {
+ static_assert(implicit_conversion<long long>(42, 42), "");
+ }
+ {
+ static_assert(implicit_conversion<long double>(3.14, 3.14), "");
+ }
+ {
+ int x = 42;
+ optional<void* const> o(&x);
+ assert(*o == &x);
+ }
+ {
+ using T = TrivialTestTypes::TestType;
+ static_assert(implicit_conversion<T>(42, 42), "");
+ }
+ {
+ using T = TestTypes::TestType;
+ assert(implicit_conversion<T>(3, T(3)));
+ }
+ {
+ using T = TestTypes::TestType;
+ optional<T> opt({3});
+ assert(opt && *opt == static_cast<T>(3));
+ }
{
using O = optional<ImplicitAny>;
static_assert(!test_convertible<O, std::in_place_t>(), "");
@@ -96,64 +95,63 @@ void test_implicit()
static_assert(!test_convertible<O, const std::in_place_t&>(), "");
static_assert(!test_convertible<O, std::in_place_t&&>(), "");
static_assert(!test_convertible<O, const std::in_place_t&&>(), "");
-
}
#ifndef TEST_HAS_NO_EXCEPTIONS
- {
- try {
- using T = ImplicitThrow;
- optional<T> t = 42;
- assert(false);
- ((void)t);
- } catch (int) {
- }
+ {
+ try {
+ using T = ImplicitThrow;
+ optional<T> t = 42;
+ assert(false);
+ ((void)t);
+ } catch (int) {
}
+ }
#endif
}
void test_explicit() {
+ {
+ using T = ExplicitTrivialTestTypes::TestType;
+ static_assert(explicit_conversion<T>(42, 42), "");
+ }
+ {
+ using T = ExplicitConstexprTestTypes::TestType;
+ static_assert(explicit_conversion<T>(42, 42), "");
+ static_assert(!std::is_convertible<int, T>::value, "");
+ }
+ {
+ using T = ExplicitTestTypes::TestType;
+ T::reset();
{
- using T = ExplicitTrivialTestTypes::TestType;
- static_assert(explicit_conversion<T>(42, 42), "");
- }
- {
- using T = ExplicitConstexprTestTypes::TestType;
- static_assert(explicit_conversion<T>(42, 42), "");
- static_assert(!std::is_convertible<int, T>::value, "");
+ assert(explicit_conversion<T>(42, 42));
+ assert(T::alive == 0);
}
+ T::reset();
{
- using T = ExplicitTestTypes::TestType;
- T::reset();
- {
- assert(explicit_conversion<T>(42, 42));
- assert(T::alive == 0);
- }
- T::reset();
- {
- optional<T> t(42);
- assert(T::alive == 1);
- assert(T::value_constructed == 1);
- assert(T::move_constructed == 0);
- assert(T::copy_constructed == 0);
- assert(t.value().value == 42);
- }
- assert(T::alive == 0);
+ optional<T> t(42);
+ assert(T::alive == 1);
+ assert(T::value_constructed == 1);
+ assert(T::move_constructed == 0);
+ assert(T::copy_constructed == 0);
+ assert(t.value().value == 42);
}
+ assert(T::alive == 0);
+ }
#ifndef TEST_HAS_NO_EXCEPTIONS
- {
- try {
- using T = ExplicitThrow;
- optional<T> t(42);
- assert(false);
- } catch (int) {
- }
+ {
+ try {
+ using T = ExplicitThrow;
+ optional<T> t(42);
+ assert(false);
+ } catch (int) {
}
+ }
#endif
}
int main(int, char**) {
- test_implicit();
- test_explicit();
+ test_implicit();
+ test_explicit();
return 0;
}
diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/const_T.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/const_T.pass.cpp
index 91a2323..67d0fcf 100644
--- a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/const_T.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/const_T.pass.cpp
@@ -12,117 +12,102 @@
// constexpr optional(const T& v);
+#include <cassert>
#include <optional>
#include <type_traits>
-#include <cassert>
#include "test_macros.h"
#include "archetypes.h"
using std::optional;
-int main(int, char**)
-{
- {
- typedef int T;
- constexpr T t(5);
- constexpr optional<T> opt(t);
- static_assert(static_cast<bool>(opt) == true, "");
- static_assert(*opt == 5, "");
-
- struct test_constexpr_ctor
- : public optional<T>
- {
- constexpr test_constexpr_ctor(const T&) {}
- };
-
- }
- {
- typedef double T;
- constexpr T t(3);
- constexpr optional<T> opt(t);
- static_assert(static_cast<bool>(opt) == true, "");
- static_assert(*opt == 3, "");
-
- struct test_constexpr_ctor
- : public optional<T>
- {
- constexpr test_constexpr_ctor(const T&) {}
- };
+int main(int, char**) {
+ {
+ typedef int T;
+ constexpr T t(5);
+ constexpr optional<T> opt(t);
+ static_assert(static_cast<bool>(opt) == true, "");
+ static_assert(*opt == 5, "");
- }
- {
- const int x = 42;
- optional<const int> o(x);
- assert(*o == x);
- }
- {
- typedef TestTypes::TestType T;
- T::reset();
- const T t(3);
- optional<T> opt = t;
- assert(T::alive == 2);
- assert(T::copy_constructed == 1);
- assert(static_cast<bool>(opt) == true);
- assert(opt.value().value == 3);
- }
- {
- typedef ExplicitTestTypes::TestType T;
- static_assert(!std::is_convertible<T const&, optional<T>>::value, "");
- T::reset();
- const T t(3);
- optional<T> opt(t);
- assert(T::alive == 2);
- assert(T::copy_constructed == 1);
- assert(static_cast<bool>(opt) == true);
- assert(opt.value().value == 3);
- }
- {
- typedef ConstexprTestTypes::TestType T;
- constexpr T t(3);
- constexpr optional<T> opt = {t};
- static_assert(static_cast<bool>(opt) == true, "");
- static_assert(opt.value().value == 3, "");
+ struct test_constexpr_ctor : public optional<T> {
+ constexpr test_constexpr_ctor(const T&) {}
+ };
+ }
+ {
+ typedef double T;
+ constexpr T t(3);
+ constexpr optional<T> opt(t);
+ static_assert(static_cast<bool>(opt) == true, "");
+ static_assert(*opt == 3, "");
- struct test_constexpr_ctor
- : public optional<T>
- {
- constexpr test_constexpr_ctor(const T&) {}
- };
- }
- {
- typedef ExplicitConstexprTestTypes::TestType T;
- static_assert(!std::is_convertible<const T&, optional<T>>::value, "");
- constexpr T t(3);
- constexpr optional<T> opt(t);
- static_assert(static_cast<bool>(opt) == true, "");
- static_assert(opt.value().value == 3, "");
+ struct test_constexpr_ctor : public optional<T> {
+ constexpr test_constexpr_ctor(const T&) {}
+ };
+ }
+ {
+ const int x = 42;
+ optional<const int> o(x);
+ assert(*o == x);
+ }
+ {
+ typedef TestTypes::TestType T;
+ T::reset();
+ const T t(3);
+ optional<T> opt = t;
+ assert(T::alive == 2);
+ assert(T::copy_constructed == 1);
+ assert(static_cast<bool>(opt) == true);
+ assert(opt.value().value == 3);
+ }
+ {
+ typedef ExplicitTestTypes::TestType T;
+ static_assert(!std::is_convertible<T const&, optional<T>>::value, "");
+ T::reset();
+ const T t(3);
+ optional<T> opt(t);
+ assert(T::alive == 2);
+ assert(T::copy_constructed == 1);
+ assert(static_cast<bool>(opt) == true);
+ assert(opt.value().value == 3);
+ }
+ {
+ typedef ConstexprTestTypes::TestType T;
+ constexpr T t(3);
+ constexpr optional<T> opt = {t};
+ static_assert(static_cast<bool>(opt) == true, "");
+ static_assert(opt.value().value == 3, "");
- struct test_constexpr_ctor
- : public optional<T>
- {
- constexpr test_constexpr_ctor(const T&) {}
- };
+ struct test_constexpr_ctor : public optional<T> {
+ constexpr test_constexpr_ctor(const T&) {}
+ };
+ }
+ {
+ typedef ExplicitConstexprTestTypes::TestType T;
+ static_assert(!std::is_convertible<const T&, optional<T>>::value, "");
+ constexpr T t(3);
+ constexpr optional<T> opt(t);
+ static_assert(static_cast<bool>(opt) == true, "");
+ static_assert(opt.value().value == 3, "");
- }
+ struct test_constexpr_ctor : public optional<T> {
+ constexpr test_constexpr_ctor(const T&) {}
+ };
+ }
#ifndef TEST_HAS_NO_EXCEPTIONS
- {
- struct Z {
- Z(int) {}
- Z(const Z&) {throw 6;}
- };
- typedef Z T;
- try
- {
- const T t(3);
- optional<T> opt(t);
- assert(false);
- }
- catch (int i)
- {
- assert(i == 6);
- }
+ {
+ struct Z {
+ Z(int) {}
+ Z(const Z&) { throw 6; }
+ };
+ typedef Z T;
+ try {
+ const T t(3);
+ optional<T> opt(t);
+ assert(false);
+ } catch (int i) {
+ assert(i == 6);
}
+ }
#endif
return 0;
diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/const_optional_U.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/const_optional_U.pass.cpp
index 9505238..70fd76e 100644
--- a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/const_optional_U.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/const_optional_U.pass.cpp
@@ -12,74 +12,69 @@
// template <class U>
// optional(const optional<U>& rhs);
+#include <cassert>
#include <optional>
#include <type_traits>
-#include <cassert>
#include "test_macros.h"
using std::optional;
template <class T, class U>
-TEST_CONSTEXPR_CXX20 void
-test(const optional<U>& rhs, bool is_going_to_throw = false)
-{
- bool rhs_engaged = static_cast<bool>(rhs);
+TEST_CONSTEXPR_CXX20 void test(const optional<U>& rhs, bool is_going_to_throw = false) {
+ bool rhs_engaged = static_cast<bool>(rhs);
#ifndef TEST_HAS_NO_EXCEPTIONS
- try
- {
- optional<T> lhs = rhs;
- assert(is_going_to_throw == false);
- assert(static_cast<bool>(lhs) == rhs_engaged);
- if (rhs_engaged)
- assert(*lhs == *rhs);
- }
- catch (int i)
- {
- assert(i == 6);
- }
-#else
- if (is_going_to_throw) return;
+ try {
optional<T> lhs = rhs;
+ assert(is_going_to_throw == false);
assert(static_cast<bool>(lhs) == rhs_engaged);
if (rhs_engaged)
- assert(*lhs == *rhs);
+ assert(*lhs == *rhs);
+ } catch (int i) {
+ assert(i == 6);
+ }
+#else
+ if (is_going_to_throw)
+ return;
+ optional<T> lhs = rhs;
+ assert(static_cast<bool>(lhs) == rhs_engaged);
+ if (rhs_engaged)
+ assert(*lhs == *rhs);
#endif
}
-class X
-{
- int i_;
+class X {
+ int i_;
+
public:
- constexpr X(int i) : i_(i) {}
- constexpr X(const X& x) : i_(x.i_) {}
- TEST_CONSTEXPR_CXX20 ~X() {i_ = 0;}
- friend constexpr bool operator==(const X& x, const X& y) {return x.i_ == y.i_;}
+ constexpr X(int i) : i_(i) {}
+ constexpr X(const X& x) : i_(x.i_) {}
+ TEST_CONSTEXPR_CXX20 ~X() { i_ = 0; }
+ friend constexpr bool operator==(const X& x, const X& y) { return x.i_ == y.i_; }
};
-class Y
-{
- int i_;
+class Y {
+ int i_;
+
public:
- constexpr Y(int i) : i_(i) {}
+ constexpr Y(int i) : i_(i) {}
- friend constexpr bool operator==(const Y& x, const Y& y) {return x.i_ == y.i_;}
+ friend constexpr bool operator==(const Y& x, const Y& y) { return x.i_ == y.i_; }
};
int count = 0;
-class Z
-{
- int i_;
+class Z {
+ int i_;
+
public:
- Z(int i) : i_(i) {TEST_THROW(6);}
+ Z(int i) : i_(i) { TEST_THROW(6); }
- friend bool operator==(const Z& x, const Z& y) {return x.i_ == y.i_;}
+ friend bool operator==(const Z& x, const Z& y) { return x.i_ == y.i_; }
};
-template<class T, class U>
-constexpr bool test_all()
-{
+template <class T, class U>
+constexpr bool test_all() {
{
optional<U> rhs;
test<T>(rhs);
@@ -91,30 +86,29 @@ constexpr bool test_all()
return true;
}
-int main(int, char**)
-{
- test_all<int, short>();
- test_all<X, int>();
- test_all<Y, int>();
+int main(int, char**) {
+ test_all<int, short>();
+ test_all<X, int>();
+ test_all<Y, int>();
#if TEST_STD_VER > 17
- static_assert(test_all<int, short>());
- static_assert(test_all<X, int>());
- static_assert(test_all<Y, int>());
+ static_assert(test_all<int, short>());
+ static_assert(test_all<X, int>());
+ static_assert(test_all<Y, int>());
#endif
- {
- typedef Z T;
- typedef int U;
- optional<U> rhs;
- test<T>(rhs);
- }
- {
- typedef Z T;
- typedef int U;
- optional<U> rhs(U{3});
- test<T>(rhs, true);
- }
-
- static_assert(!(std::is_constructible<optional<X>, const optional<Y>&>::value), "");
+ {
+ typedef Z T;
+ typedef int U;
+ optional<U> rhs;
+ test<T>(rhs);
+ }
+ {
+ typedef Z T;
+ typedef int U;
+ optional<U> rhs(U{3});
+ test<T>(rhs, true);
+ }
+
+ static_assert(!(std::is_constructible<optional<X>, const optional<Y>&>::value), "");
return 0;
}
diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/copy.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/copy.pass.cpp
index 54a424c..f61a22c 100644
--- a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/copy.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/copy.pass.cpp
@@ -11,173 +11,165 @@
// constexpr optional(const optional<T>& rhs);
+#include <cassert>
#include <optional>
#include <type_traits>
-#include <cassert>
#include "test_macros.h"
#include "archetypes.h"
using std::optional;
-template <class T, class ...InitArgs>
-void test(InitArgs&&... args)
-{
- const optional<T> rhs(std::forward<InitArgs>(args)...);
- bool rhs_engaged = static_cast<bool>(rhs);
- optional<T> lhs = rhs;
- assert(static_cast<bool>(lhs) == rhs_engaged);
- if (rhs_engaged)
- assert(*lhs == *rhs);
+template <class T, class... InitArgs>
+void test(InitArgs&&... args) {
+ const optional<T> rhs(std::forward<InitArgs>(args)...);
+ bool rhs_engaged = static_cast<bool>(rhs);
+ optional<T> lhs = rhs;
+ assert(static_cast<bool>(lhs) == rhs_engaged);
+ if (rhs_engaged)
+ assert(*lhs == *rhs);
}
-template <class T, class ...InitArgs>
-constexpr bool constexpr_test(InitArgs&&... args)
-{
- static_assert( std::is_trivially_copy_constructible_v<T>, ""); // requirement
- const optional<T> rhs(std::forward<InitArgs>(args)...);
- optional<T> lhs = rhs;
- return (lhs.has_value() == rhs.has_value()) &&
- (lhs.has_value() ? *lhs == *rhs : true);
+template <class T, class... InitArgs>
+constexpr bool constexpr_test(InitArgs&&... args) {
+ static_assert(std::is_trivially_copy_constructible_v<T>, ""); // requirement
+ const optional<T> rhs(std::forward<InitArgs>(args)...);
+ optional<T> lhs = rhs;
+ return (lhs.has_value() == rhs.has_value()) && (lhs.has_value() ? *lhs == *rhs : true);
}
void test_throwing_ctor() {
#ifndef TEST_HAS_NO_EXCEPTIONS
- struct Z {
- Z() : count(0) {}
- Z(Z const& o) : count(o.count + 1)
- { if (count == 2) throw 6; }
- int count;
- };
- const Z z;
- const optional<Z> rhs(z);
- try
- {
- optional<Z> lhs(rhs);
- assert(false);
- }
- catch (int i)
- {
- assert(i == 6);
+ struct Z {
+ Z() : count(0) {}
+ Z(Z const& o) : count(o.count + 1) {
+ if (count == 2)
+ throw 6;
}
+ int count;
+ };
+ const Z z;
+ const optional<Z> rhs(z);
+ try {
+ optional<Z> lhs(rhs);
+ assert(false);
+ } catch (int i) {
+ assert(i == 6);
+ }
#endif
}
-template <class T, class ...InitArgs>
-void test_ref(InitArgs&&... args)
-{
- const optional<T> rhs(std::forward<InitArgs>(args)...);
- bool rhs_engaged = static_cast<bool>(rhs);
- optional<T> lhs = rhs;
- assert(static_cast<bool>(lhs) == rhs_engaged);
- if (rhs_engaged)
- assert(&(*lhs) == &(*rhs));
+template <class T, class... InitArgs>
+void test_ref(InitArgs&&... args) {
+ const optional<T> rhs(std::forward<InitArgs>(args)...);
+ bool rhs_engaged = static_cast<bool>(rhs);
+ optional<T> lhs = rhs;
+ assert(static_cast<bool>(lhs) == rhs_engaged);
+ if (rhs_engaged)
+ assert(&(*lhs) == &(*rhs));
}
-
-void test_reference_extension()
-{
+void test_reference_extension() {
#if defined(_LIBCPP_VERSION) && 0 // FIXME these extensions are currently disabled.
- using T = TestTypes::TestType;
- T::reset();
- {
- T t;
- T::reset_constructors();
- test_ref<T&>();
- test_ref<T&>(t);
- assert(T::alive == 1);
- assert(T::constructed == 0);
- assert(T::assigned == 0);
- assert(T::destroyed == 0);
- }
- assert(T::destroyed == 1);
- assert(T::alive == 0);
- {
- T t;
- const T& ct = t;
- T::reset_constructors();
- test_ref<T const&>();
- test_ref<T const&>(t);
- test_ref<T const&>(ct);
- assert(T::alive == 1);
- assert(T::constructed == 0);
- assert(T::assigned == 0);
- assert(T::destroyed == 0);
- }
- assert(T::alive == 0);
- assert(T::destroyed == 1);
- {
- static_assert(!std::is_copy_constructible<std::optional<T&&>>::value, "");
- static_assert(!std::is_copy_constructible<std::optional<T const&&>>::value, "");
- }
+ using T = TestTypes::TestType;
+ T::reset();
+ {
+ T t;
+ T::reset_constructors();
+ test_ref<T&>();
+ test_ref<T&>(t);
+ assert(T::alive == 1);
+ assert(T::constructed == 0);
+ assert(T::assigned == 0);
+ assert(T::destroyed == 0);
+ }
+ assert(T::destroyed == 1);
+ assert(T::alive == 0);
+ {
+ T t;
+ const T& ct = t;
+ T::reset_constructors();
+ test_ref<T const&>();
+ test_ref<T const&>(t);
+ test_ref<T const&>(ct);
+ assert(T::alive == 1);
+ assert(T::constructed == 0);
+ assert(T::assigned == 0);
+ assert(T::destroyed == 0);
+ }
+ assert(T::alive == 0);
+ assert(T::destroyed == 1);
+ {
+ static_assert(!std::is_copy_constructible<std::optional<T&&>>::value, "");
+ static_assert(!std::is_copy_constructible<std::optional<T const&&>>::value, "");
+ }
#endif
}
-int main(int, char**)
-{
- test<int>();
- test<int>(3);
- static_assert(constexpr_test<int>(), "" );
- static_assert(constexpr_test<int>(3), "" );
+int main(int, char**) {
+ test<int>();
+ test<int>(3);
+ static_assert(constexpr_test<int>(), "");
+ static_assert(constexpr_test<int>(3), "");
- {
- const optional<const int> o(42);
- optional<const int> o2(o);
- assert(*o2 == 42);
- }
- {
- using T = TestTypes::TestType;
- T::reset();
- const optional<T> rhs;
- assert(T::alive == 0);
- const optional<T> lhs(rhs);
- assert(lhs.has_value() == false);
- assert(T::alive == 0);
- }
- TestTypes::TestType::reset();
- {
- using T = TestTypes::TestType;
- T::reset();
- const optional<T> rhs(42);
- assert(T::alive == 1);
- assert(T::value_constructed == 1);
- assert(T::copy_constructed == 0);
- const optional<T> lhs(rhs);
- assert(lhs.has_value());
- assert(T::copy_constructed == 1);
- assert(T::alive == 2);
- }
- TestTypes::TestType::reset();
- {
- using namespace ConstexprTestTypes;
- test<TestType>();
- test<TestType>(42);
- }
- {
- using namespace TrivialTestTypes;
- test<TestType>();
- test<TestType>(42);
- }
- {
- test_throwing_ctor();
- }
- {
- test_reference_extension();
- }
- {
- constexpr std::optional<int> o1{4};
- constexpr std::optional<int> o2 = o1;
- static_assert( *o2 == 4, "" );
- }
+ {
+ const optional<const int> o(42);
+ optional<const int> o2(o);
+ assert(*o2 == 42);
+ }
+ {
+ using T = TestTypes::TestType;
+ T::reset();
+ const optional<T> rhs;
+ assert(T::alive == 0);
+ const optional<T> lhs(rhs);
+ assert(lhs.has_value() == false);
+ assert(T::alive == 0);
+ }
+ TestTypes::TestType::reset();
+ {
+ using T = TestTypes::TestType;
+ T::reset();
+ const optional<T> rhs(42);
+ assert(T::alive == 1);
+ assert(T::value_constructed == 1);
+ assert(T::copy_constructed == 0);
+ const optional<T> lhs(rhs);
+ assert(lhs.has_value());
+ assert(T::copy_constructed == 1);
+ assert(T::alive == 2);
+ }
+ TestTypes::TestType::reset();
+ {
+ using namespace ConstexprTestTypes;
+ test<TestType>();
+ test<TestType>(42);
+ }
+ {
+ using namespace TrivialTestTypes;
+ test<TestType>();
+ test<TestType>(42);
+ }
+ {
+ test_throwing_ctor();
+ }
+ {
+ test_reference_extension();
+ }
+ {
+ constexpr std::optional<int> o1{4};
+ constexpr std::optional<int> o2 = o1;
+ static_assert(*o2 == 4, "");
+ }
- // LWG3836 https://wg21.link/LWG3836
- // std::optional<bool> conversion constructor optional(const optional<U>&)
- // should take precedence over optional(U&&) with operator bool
- {
- std::optional<bool> o1(false);
- std::optional<bool> o2(o1);
- assert(!o2.value());
- }
+ // LWG3836 https://wg21.link/LWG3836
+ // std::optional<bool> conversion constructor optional(const optional<U>&)
+ // should take precedence over optional(U&&) with operator bool
+ {
+ std::optional<bool> o1(false);
+ std::optional<bool> o2(o1);
+ assert(!o2.value());
+ }
return 0;
}
diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/ctor.verify.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/ctor.verify.cpp
index 775d2bd..00ca941 100644
--- a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/ctor.verify.cpp
+++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/ctor.verify.cpp
@@ -13,35 +13,40 @@
// and shall satisfy the Cpp17Destructible requirements.
// Note: array types do not satisfy the Cpp17Destructible requirements.
-#include <optional>
-#include <type_traits>
#include <cassert>
+#include <optional>
#include "test_macros.h"
-struct NonDestructible { ~NonDestructible() = delete; };
-
-int main(int, char**)
-{
- {
- std::optional<char &> o1; // expected-error-re@optional:* {{static assertion failed{{.*}}instantiation of optional with a reference type is ill-formed}}
+struct NonDestructible {
+ ~NonDestructible() = delete;
+};
+
+int main(int, char**) {
+ // clang-format off
+ {
+#if TEST_STD_VER >= 26
+ std::optional<int&&> opt2; // expected-error-re@optional:* {{static assertion failed{{.*}}instantiation of optional with an rvalue reference type is ill-formed}}
+#else
+ std::optional<char&> o1; // expected-error-re@optional:* {{static assertion failed{{.*}}instantiation of optional with a reference type is ill-formed}}
+#endif
std::optional<NonDestructible> o2; // expected-error-re@optional:* {{static assertion failed{{.*}}instantiation of optional with a non-destructible type is ill-formed}}
- std::optional<char[20]> o3; // expected-error-re@optional:* {{static assertion failed{{.*}}instantiation of optional with an array type is ill-formed}}
- }
+ std::optional<char[20]> o3; // expected-error-re@optional:* {{static assertion failed{{.*}}instantiation of optional with an array type is ill-formed}}
+ }
- {
+ {
std::optional< std::in_place_t> o1; // expected-error-re@optional:* {{static assertion failed{{.*}}instantiation of optional with in_place_t is ill-formed}}
std::optional<const std::in_place_t> o2; // expected-error-re@optional:* {{static assertion failed{{.*}}instantiation of optional with in_place_t is ill-formed}}
std::optional< volatile std::in_place_t> o3; // expected-error-re@optional:* {{static assertion failed{{.*}}instantiation of optional with in_place_t is ill-formed}}
std::optional<const volatile std::in_place_t> o4; // expected-error-re@optional:* {{static assertion failed{{.*}}instantiation of optional with in_place_t is ill-formed}}
- }
+ }
- {
+ {
std::optional< std::nullopt_t> o1; // expected-error-re@optional:* {{static assertion failed{{.*}}instantiation of optional with nullopt_t is ill-formed}}
std::optional<const std::nullopt_t> o2; // expected-error-re@optional:* {{static assertion failed{{.*}}instantiation of optional with nullopt_t is ill-formed}}
std::optional< volatile std::nullopt_t> o3; // expected-error-re@optional:* {{static assertion failed{{.*}}instantiation of optional with nullopt_t is ill-formed}}
std::optional<const volatile std::nullopt_t> o4; // expected-error-re@optional:* {{static assertion failed{{.*}}instantiation of optional with nullopt_t is ill-formed}}
- }
-
- return 0;
+ }
+ // clang-format on
+ return 0;
}
diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/deduct.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/deduct.pass.cpp
index 9bfde5a..bc1d26a 100644
--- a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/deduct.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/deduct.pass.cpp
@@ -12,67 +12,66 @@
// template<class T>
// optional(T) -> optional<T>;
-#include <optional>
#include <cassert>
+#include <optional>
#include "test_macros.h"
struct A {};
-int main(int, char**)
-{
-// Test the explicit deduction guides
- {
-// optional(T)
+int main(int, char**) {
+ // Test the explicit deduction guides
+ {
+ // optional(T)
std::optional opt(5);
ASSERT_SAME_TYPE(decltype(opt), std::optional<int>);
assert(static_cast<bool>(opt));
assert(*opt == 5);
- }
+ }
- {
-// optional(T)
+ {
+ // optional(T)
std::optional opt(A{});
ASSERT_SAME_TYPE(decltype(opt), std::optional<A>);
assert(static_cast<bool>(opt));
- }
+ }
- {
-// optional(const T&);
+ {
+ // optional(const T&);
const int& source = 5;
std::optional opt(source);
ASSERT_SAME_TYPE(decltype(opt), std::optional<int>);
assert(static_cast<bool>(opt));
assert(*opt == 5);
- }
+ }
- {
-// optional(T*);
+ {
+ // optional(T*);
const int* source = nullptr;
std::optional opt(source);
ASSERT_SAME_TYPE(decltype(opt), std::optional<const int*>);
assert(static_cast<bool>(opt));
assert(*opt == nullptr);
- }
+ }
- {
-// optional(T[]);
+ {
+ // optional(T[]);
int source[] = {1, 2, 3};
std::optional opt(source);
ASSERT_SAME_TYPE(decltype(opt), std::optional<int*>);
assert(static_cast<bool>(opt));
assert((*opt)[0] == 1);
- }
+ }
-// Test the implicit deduction guides
- {
-// optional(optional);
+ // Test the implicit deduction guides
+ {
+ // optional(optional);
std::optional<char> source('A');
std::optional opt(source);
ASSERT_SAME_TYPE(decltype(opt), std::optional<char>);
assert(static_cast<bool>(opt) == static_cast<bool>(source));
assert(*opt == *source);
- }
+ }
return 0;
}
diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/deduct.verify.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/deduct.verify.cpp
index 364f9b2..7ab842b 100644
--- a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/deduct.verify.cpp
+++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/deduct.verify.cpp
@@ -13,25 +13,26 @@
// template<class T>
// optional(T) -> optional<T>;
-#include <optional>
#include <cassert>
+#include <optional>
struct A {};
-int main(int, char**)
-{
-// Test the explicit deduction guides
+int main(int, char**) {
+ // Test the explicit deduction guides
-// Test the implicit deduction guides
- {
-// optional()
- std::optional opt; // expected-error-re {{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}optional'}}
- }
+ // Test the implicit deduction guides
- {
-// optional(nullopt_t)
- std::optional opt(std::nullopt); // expected-error-re@optional:* {{static assertion failed{{.*}}instantiation of optional with nullopt_t is ill-formed}}
- }
+ // clang-format off
+ {
+ // optional()
+ std::optional opt; // expected-error-re {{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}optional'}}
+ }
+ {
+ // optional(nullopt_t)
+ std::optional opt(std::nullopt); // expected-error-re@optional:* {{static assertion failed{{.*}}instantiation of optional with nullopt_t is ill-formed}}
+ }
+ // clang-format on
return 0;
}
diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/default.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/default.pass.cpp
index 61a365e..71d4d05 100644
--- a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/default.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/default.pass.cpp
@@ -11,9 +11,9 @@
// constexpr optional() noexcept;
+#include <cassert>
#include <optional>
#include <type_traits>
-#include <cassert>
#include "test_macros.h"
#include "archetypes.h"
@@ -21,61 +21,52 @@
using std::optional;
template <class Opt>
-void
-test_constexpr()
-{
- static_assert(std::is_nothrow_default_constructible<Opt>::value, "");
- static_assert(std::is_trivially_destructible<Opt>::value, "");
- static_assert(std::is_trivially_destructible<typename Opt::value_type>::value, "");
+void test_constexpr() {
+ static_assert(std::is_nothrow_default_constructible<Opt>::value, "");
+ static_assert(std::is_trivially_destructible<Opt>::value, "");
+ static_assert(std::is_trivially_destructible<typename Opt::value_type>::value, "");
- constexpr Opt opt;
- static_assert(static_cast<bool>(opt) == false, "");
+ constexpr Opt opt;
+ static_assert(static_cast<bool>(opt) == false, "");
- struct test_constexpr_ctor
- : public Opt
- {
- constexpr test_constexpr_ctor() {}
- };
+ struct test_constexpr_ctor : public Opt {
+ constexpr test_constexpr_ctor() {}
+ };
}
template <class Opt>
-void
-test()
-{
- static_assert(std::is_nothrow_default_constructible<Opt>::value, "");
- static_assert(!std::is_trivially_destructible<Opt>::value, "");
- static_assert(!std::is_trivially_destructible<typename Opt::value_type>::value, "");
- {
- Opt opt;
- assert(static_cast<bool>(opt) == false);
- }
- {
- const Opt opt;
- assert(static_cast<bool>(opt) == false);
- }
+void test() {
+ static_assert(std::is_nothrow_default_constructible<Opt>::value, "");
+ static_assert(!std::is_trivially_destructible<Opt>::value, "");
+ static_assert(!std::is_trivially_destructible<typename Opt::value_type>::value, "");
+ {
+ Opt opt;
+ assert(static_cast<bool>(opt) == false);
+ }
+ {
+ const Opt opt;
+ assert(static_cast<bool>(opt) == false);
+ }
- struct test_constexpr_ctor
- : public Opt
- {
- constexpr test_constexpr_ctor() {}
- };
+ struct test_constexpr_ctor : public Opt {
+ constexpr test_constexpr_ctor() {}
+ };
}
-int main(int, char**)
-{
- test_constexpr<optional<int>>();
- test_constexpr<optional<int*>>();
- test_constexpr<optional<ImplicitTypes::NoCtors>>();
- test_constexpr<optional<NonTrivialTypes::NoCtors>>();
- test_constexpr<optional<NonConstexprTypes::NoCtors>>();
- test<optional<NonLiteralTypes::NoCtors>>();
- // EXTENSIONS
+int main(int, char**) {
+ test_constexpr<optional<int>>();
+ test_constexpr<optional<int*>>();
+ test_constexpr<optional<ImplicitTypes::NoCtors>>();
+ test_constexpr<optional<NonTrivialTypes::NoCtors>>();
+ test_constexpr<optional<NonConstexprTypes::NoCtors>>();
+ test<optional<NonLiteralTypes::NoCtors>>();
+ // EXTENSIONS
#if defined(_LIBCPP_VERSION) && 0 // FIXME these extensions are currently disabled.
- test_constexpr<optional<int&>>();
- test_constexpr<optional<const int&>>();
- test_constexpr<optional<int&>>();
- test_constexpr<optional<NonLiteralTypes::NoCtors&>>();
- test_constexpr<optional<NonLiteralTypes::NoCtors&&>>();
+ test_constexpr<optional<int&>>();
+ test_constexpr<optional<const int&>>();
+ test_constexpr<optional<int&>>();
+ test_constexpr<optional<NonLiteralTypes::NoCtors&>>();
+ test_constexpr<optional<NonLiteralTypes::NoCtors&&>>();
#endif
return 0;
diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/empty_in_place_t_does_not_clobber.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/empty_in_place_t_does_not_clobber.pass.cpp
index 594aac7..f191748 100644
--- a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/empty_in_place_t_does_not_clobber.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/empty_in_place_t_does_not_clobber.pass.cpp
@@ -15,9 +15,9 @@
// in_place_t constructor with no arguments when the Clang is trying to check
// copy constructor.
+#include <cassert>
#include <optional>
#include <type_traits>
-#include <cassert>
#include "test_macros.h"
#include "archetypes.h"
diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/explicit_const_optional_U.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/explicit_const_optional_U.pass.cpp
index d8594bc..1b9882f 100644
--- a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/explicit_const_optional_U.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/explicit_const_optional_U.pass.cpp
@@ -12,75 +12,70 @@
// template <class U>
// explicit optional(const optional<U>& rhs);
+#include <cassert>
#include <optional>
#include <type_traits>
-#include <cassert>
#include "test_macros.h"
using std::optional;
template <class T, class U>
-TEST_CONSTEXPR_CXX20 void
-test(const optional<U>& rhs, bool is_going_to_throw = false)
-{
- static_assert(!(std::is_convertible<const optional<U>&, optional<T>>::value), "");
- bool rhs_engaged = static_cast<bool>(rhs);
+TEST_CONSTEXPR_CXX20 void test(const optional<U>& rhs, bool is_going_to_throw = false) {
+ static_assert(!(std::is_convertible<const optional<U>&, optional<T>>::value), "");
+ bool rhs_engaged = static_cast<bool>(rhs);
#ifndef TEST_HAS_NO_EXCEPTIONS
- try
- {
- optional<T> lhs(rhs);
- assert(is_going_to_throw == false);
- assert(static_cast<bool>(lhs) == rhs_engaged);
- if (rhs_engaged)
- assert(*lhs == T(*rhs));
- }
- catch (int i)
- {
- assert(i == 6);
- }
-#else
- if (is_going_to_throw) return;
+ try {
optional<T> lhs(rhs);
+ assert(is_going_to_throw == false);
assert(static_cast<bool>(lhs) == rhs_engaged);
if (rhs_engaged)
- assert(*lhs == T(*rhs));
+ assert(*lhs == T(*rhs));
+ } catch (int i) {
+ assert(i == 6);
+ }
+#else
+ if (is_going_to_throw)
+ return;
+ optional<T> lhs(rhs);
+ assert(static_cast<bool>(lhs) == rhs_engaged);
+ if (rhs_engaged)
+ assert(*lhs == T(*rhs));
#endif
}
-class X
-{
- int i_;
+class X {
+ int i_;
+
public:
- constexpr explicit X(int i) : i_(i) {}
- constexpr X(const X& x) : i_(x.i_) {}
- TEST_CONSTEXPR_CXX20 ~X() {i_ = 0;}
- friend constexpr bool operator==(const X& x, const X& y) {return x.i_ == y.i_;}
+ constexpr explicit X(int i) : i_(i) {}
+ constexpr X(const X& x) : i_(x.i_) {}
+ TEST_CONSTEXPR_CXX20 ~X() { i_ = 0; }
+ friend constexpr bool operator==(const X& x, const X& y) { return x.i_ == y.i_; }
};
-class Y
-{
- int i_;
+class Y {
+ int i_;
+
public:
- constexpr explicit Y(int i) : i_(i) {}
+ constexpr explicit Y(int i) : i_(i) {}
- friend constexpr bool operator==(const Y& x, const Y& y) {return x.i_ == y.i_;}
+ friend constexpr bool operator==(const Y& x, const Y& y) { return x.i_ == y.i_; }
};
int count = 0;
-class Z
-{
- int i_;
+class Z {
+ int i_;
+
public:
- explicit Z(int i) : i_(i) {TEST_THROW(6);}
+ explicit Z(int i) : i_(i) { TEST_THROW(6); }
- friend bool operator==(const Z& x, const Z& y) {return x.i_ == y.i_;}
+ friend bool operator==(const Z& x, const Z& y) { return x.i_ == y.i_; }
};
-template<class T, class U>
-constexpr bool test_all()
-{
+template <class T, class U>
+constexpr bool test_all() {
{
optional<U> rhs;
test<T>(rhs);
@@ -92,27 +87,25 @@ constexpr bool test_all()
return true;
}
-
-int main(int, char**)
-{
- test_all<X, int>();
- test_all<Y, int>();
+int main(int, char**) {
+ test_all<X, int>();
+ test_all<Y, int>();
#if TEST_STD_VER > 17
- static_assert(test_all<X, int>());
- static_assert(test_all<Y, int>());
+ static_assert(test_all<X, int>());
+ static_assert(test_all<Y, int>());
#endif
- {
- typedef Z T;
- typedef int U;
- optional<U> rhs;
- test<T>(rhs);
- }
- {
- typedef Z T;
- typedef int U;
- optional<U> rhs(3);
- test<T>(rhs, true);
- }
+ {
+ typedef Z T;
+ typedef int U;
+ optional<U> rhs;
+ test<T>(rhs);
+ }
+ {
+ typedef Z T;
+ typedef int U;
+ optional<U> rhs(3);
+ test<T>(rhs, true);
+ }
return 0;
}
diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/explicit_optional_U.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/explicit_optional_U.pass.cpp
index 708370a..bddbd4b 100644
--- a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/explicit_optional_U.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/explicit_optional_U.pass.cpp
@@ -12,83 +12,77 @@
// template <class U>
// explicit optional(optional<U>&& rhs);
+#include <cassert>
#include <optional>
#include <type_traits>
-#include <cassert>
#include "test_macros.h"
using std::optional;
template <class T, class U>
-TEST_CONSTEXPR_CXX20 void test(optional<U>&& rhs, bool is_going_to_throw = false)
-{
- static_assert(!(std::is_convertible<optional<U>&&, optional<T>>::value), "");
- bool rhs_engaged = static_cast<bool>(rhs);
+TEST_CONSTEXPR_CXX20 void test(optional<U>&& rhs, bool is_going_to_throw = false) {
+ static_assert(!(std::is_convertible<optional<U>&&, optional<T>>::value), "");
+ bool rhs_engaged = static_cast<bool>(rhs);
#ifndef TEST_HAS_NO_EXCEPTIONS
- try
- {
- optional<T> lhs(std::move(rhs));
- assert(is_going_to_throw == false);
- assert(static_cast<bool>(lhs) == rhs_engaged);
- }
- catch (int i)
- {
- assert(i == 6);
- }
-#else
- if (is_going_to_throw) return;
+ try {
optional<T> lhs(std::move(rhs));
+ assert(is_going_to_throw == false);
assert(static_cast<bool>(lhs) == rhs_engaged);
+ } catch (int i) {
+ assert(i == 6);
+ }
+#else
+ if (is_going_to_throw)
+ return;
+ optional<T> lhs(std::move(rhs));
+ assert(static_cast<bool>(lhs) == rhs_engaged);
#endif
}
-class X
-{
- int i_;
+class X {
+ int i_;
+
public:
- constexpr explicit X(int i) : i_(i) {}
- constexpr X(X&& x) : i_(x.i_) { x.i_ = 0; }
- TEST_CONSTEXPR_CXX20 ~X() {i_ = 0;}
- friend constexpr bool operator==(const X& x, const X& y) {return x.i_ == y.i_;}
+ constexpr explicit X(int i) : i_(i) {}
+ constexpr X(X&& x) : i_(x.i_) { x.i_ = 0; }
+ TEST_CONSTEXPR_CXX20 ~X() { i_ = 0; }
+ friend constexpr bool operator==(const X& x, const X& y) { return x.i_ == y.i_; }
};
int count = 0;
-class Z
-{
+class Z {
public:
- explicit Z(int) { TEST_THROW(6); }
+ explicit Z(int) { TEST_THROW(6); }
};
-TEST_CONSTEXPR_CXX20 bool test()
-{
- {
- optional<int> rhs;
- test<X>(std::move(rhs));
- }
- {
- optional<int> rhs(3);
- test<X>(std::move(rhs));
- }
+TEST_CONSTEXPR_CXX20 bool test() {
+ {
+ optional<int> rhs;
+ test<X>(std::move(rhs));
+ }
+ {
+ optional<int> rhs(3);
+ test<X>(std::move(rhs));
+ }
- return true;
+ return true;
}
-int main(int, char**)
-{
+int main(int, char**) {
#if TEST_STD_VER > 17
- static_assert(test());
+ static_assert(test());
#endif
- test();
- {
- optional<int> rhs;
- test<Z>(std::move(rhs));
- }
- {
- optional<int> rhs(3);
- test<Z>(std::move(rhs), true);
- }
+ test();
+ {
+ optional<int> rhs;
+ test<Z>(std::move(rhs));
+ }
+ {
+ optional<int> rhs(3);
+ test<Z>(std::move(rhs), true);
+ }
return 0;
}
diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/in_place_t.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/in_place_t.pass.cpp
index 65276c5..9027544 100644
--- a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/in_place_t.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/in_place_t.pass.cpp
@@ -13,136 +13,112 @@
// template <class... Args>
// constexpr explicit optional(in_place_t, Args&&... args);
+#include <cassert>
#include <optional>
#include <type_traits>
-#include <cassert>
#include "test_macros.h"
-using std::optional;
-using std::in_place_t;
using std::in_place;
+using std::in_place_t;
+using std::optional;
+
+class X {
+ int i_;
+ int j_ = 0;
-class X
-{
- int i_;
- int j_ = 0;
public:
- X() : i_(0) {}
- X(int i) : i_(i) {}
- X(int i, int j) : i_(i), j_(j) {}
+ X() : i_(0) {}
+ X(int i) : i_(i) {}
+ X(int i, int j) : i_(i), j_(j) {}
- ~X() {}
+ ~X() {}
- friend bool operator==(const X& x, const X& y)
- {return x.i_ == y.i_ && x.j_ == y.j_;}
+ friend bool operator==(const X& x, const X& y) { return x.i_ == y.i_ && x.j_ == y.j_; }
};
-class Y
-{
- int i_;
- int j_ = 0;
+class Y {
+ int i_;
+ int j_ = 0;
+
public:
- constexpr Y() : i_(0) {}
- constexpr Y(int i) : i_(i) {}
- constexpr Y(int i, int j) : i_(i), j_(j) {}
+ constexpr Y() : i_(0) {}
+ constexpr Y(int i) : i_(i) {}
+ constexpr Y(int i, int j) : i_(i), j_(j) {}
- friend constexpr bool operator==(const Y& x, const Y& y)
- {return x.i_ == y.i_ && x.j_ == y.j_;}
+ friend constexpr bool operator==(const Y& x, const Y& y) { return x.i_ == y.i_ && x.j_ == y.j_; }
};
-class Z
-{
+class Z {
public:
- Z(int) {TEST_THROW(6);}
+ Z(int) { TEST_THROW(6); }
};
-
-int main(int, char**)
-{
- {
- constexpr optional<int> opt(in_place, 5);
- static_assert(static_cast<bool>(opt) == true, "");
- static_assert(*opt == 5, "");
-
- struct test_constexpr_ctor
- : public optional<int>
- {
- constexpr test_constexpr_ctor(in_place_t, int i)
- : optional<int>(in_place, i) {}
- };
-
- }
- {
- optional<const int> opt(in_place, 5);
- assert(*opt == 5);
- }
- {
- const optional<X> opt(in_place);
- assert(static_cast<bool>(opt) == true);
- assert(*opt == X());
- }
- {
- const optional<X> opt(in_place, 5);
- assert(static_cast<bool>(opt) == true);
- assert(*opt == X(5));
- }
- {
- const optional<X> opt(in_place, 5, 4);
- assert(static_cast<bool>(opt) == true);
- assert(*opt == X(5, 4));
- }
- {
- constexpr optional<Y> opt(in_place);
- static_assert(static_cast<bool>(opt) == true, "");
- static_assert(*opt == Y(), "");
-
- struct test_constexpr_ctor
- : public optional<Y>
- {
- constexpr test_constexpr_ctor(in_place_t)
- : optional<Y>(in_place) {}
- };
-
- }
- {
- constexpr optional<Y> opt(in_place, 5);
- static_assert(static_cast<bool>(opt) == true, "");
- static_assert(*opt == Y(5), "");
-
- struct test_constexpr_ctor
- : public optional<Y>
- {
- constexpr test_constexpr_ctor(in_place_t, int i)
- : optional<Y>(in_place, i) {}
- };
-
- }
- {
- constexpr optional<Y> opt(in_place, 5, 4);
- static_assert(static_cast<bool>(opt) == true, "");
- static_assert(*opt == Y(5, 4), "");
-
- struct test_constexpr_ctor
- : public optional<Y>
- {
- constexpr test_constexpr_ctor(in_place_t, int i, int j)
- : optional<Y>(in_place, i, j) {}
- };
-
- }
+int main(int, char**) {
+ {
+ constexpr optional<int> opt(in_place, 5);
+ static_assert(static_cast<bool>(opt) == true, "");
+ static_assert(*opt == 5, "");
+
+ struct test_constexpr_ctor : public optional<int> {
+ constexpr test_constexpr_ctor(in_place_t, int i) : optional<int>(in_place, i) {}
+ };
+ }
+ {
+ optional<const int> opt(in_place, 5);
+ assert(*opt == 5);
+ }
+ {
+ const optional<X> opt(in_place);
+ assert(static_cast<bool>(opt) == true);
+ assert(*opt == X());
+ }
+ {
+ const optional<X> opt(in_place, 5);
+ assert(static_cast<bool>(opt) == true);
+ assert(*opt == X(5));
+ }
+ {
+ const optional<X> opt(in_place, 5, 4);
+ assert(static_cast<bool>(opt) == true);
+ assert(*opt == X(5, 4));
+ }
+ {
+ constexpr optional<Y> opt(in_place);
+ static_assert(static_cast<bool>(opt) == true, "");
+ static_assert(*opt == Y(), "");
+
+ struct test_constexpr_ctor : public optional<Y> {
+ constexpr test_constexpr_ctor(in_place_t) : optional<Y>(in_place) {}
+ };
+ }
+ {
+ constexpr optional<Y> opt(in_place, 5);
+ static_assert(static_cast<bool>(opt) == true, "");
+ static_assert(*opt == Y(5), "");
+
+ struct test_constexpr_ctor : public optional<Y> {
+ constexpr test_constexpr_ctor(in_place_t, int i) : optional<Y>(in_place, i) {}
+ };
+ }
+ {
+ constexpr optional<Y> opt(in_place, 5, 4);
+ static_assert(static_cast<bool>(opt) == true, "");
+ static_assert(*opt == Y(5, 4), "");
+
+ struct test_constexpr_ctor : public optional<Y> {
+ constexpr test_constexpr_ctor(in_place_t, int i, int j) : optional<Y>(in_place, i, j) {}
+ };
+ }
#ifndef TEST_HAS_NO_EXCEPTIONS
- {
- try
- {
- const optional<Z> opt(in_place, 1);
- assert(false);
- }
- catch (int i)
- {
- assert(i == 6);
- }
+ {
+ try {
+ const optional<Z> opt(in_place, 1);
+ assert(false);
+ } catch (int i) {
+ assert(i == 6);
}
+ }
#endif
return 0;
diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/initializer_list.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/initializer_list.pass.cpp
index 6c42df9..1993476 100644
--- a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/initializer_list.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/initializer_list.pass.cpp
@@ -13,105 +13,93 @@
// constexpr
// explicit optional(in_place_t, initializer_list<U> il, Args&&... args);
+#include <cassert>
+#include <memory>
#include <optional>
#include <type_traits>
-#include <memory>
#include <vector>
-#include <cassert>
#include "test_macros.h"
-using std::optional;
-using std::in_place_t;
using std::in_place;
+using std::in_place_t;
+using std::optional;
+
+class X {
+ int i_;
+ int j_ = 0;
-class X
-{
- int i_;
- int j_ = 0;
public:
- X() : i_(0) {}
- X(int i) : i_(i) {}
- X(int i, int j) : i_(i), j_(j) {}
+ X() : i_(0) {}
+ X(int i) : i_(i) {}
+ X(int i, int j) : i_(i), j_(j) {}
- ~X() {}
+ ~X() {}
- friend bool operator==(const X& x, const X& y)
- {return x.i_ == y.i_ && x.j_ == y.j_;}
+ friend bool operator==(const X& x, const X& y) { return x.i_ == y.i_ && x.j_ == y.j_; }
};
-class Y
-{
- int i_;
- int j_ = 0;
+class Y {
+ int i_;
+ int j_ = 0;
+
public:
- constexpr Y() : i_(0) {}
- constexpr Y(int i) : i_(i) {}
- constexpr Y(std::initializer_list<int> il) : i_(il.begin()[0]), j_(il.begin()[1]) {}
+ constexpr Y() : i_(0) {}
+ constexpr Y(int i) : i_(i) {}
+ constexpr Y(std::initializer_list<int> il) : i_(il.begin()[0]), j_(il.begin()[1]) {}
- friend constexpr bool operator==(const Y& x, const Y& y)
- {return x.i_ == y.i_ && x.j_ == y.j_;}
+ friend constexpr bool operator==(const Y& x, const Y& y) { return x.i_ == y.i_ && x.j_ == y.j_; }
};
-class Z
-{
- int i_;
- int j_ = 0;
+class Z {
+ int i_;
+ int j_ = 0;
+
public:
- Z() : i_(0) {}
- Z(int i) : i_(i) {}
- Z(std::initializer_list<int> il) : i_(il.begin()[0]), j_(il.begin()[1])
- {TEST_THROW(6);}
+ Z() : i_(0) {}
+ Z(int i) : i_(i) {}
+ Z(std::initializer_list<int> il) : i_(il.begin()[0]), j_(il.begin()[1]) { TEST_THROW(6); }
- friend bool operator==(const Z& x, const Z& y)
- {return x.i_ == y.i_ && x.j_ == y.j_;}
+ friend bool operator==(const Z& x, const Z& y) { return x.i_ == y.i_ && x.j_ == y.j_; }
};
-int main(int, char**)
-{
- {
- static_assert(!std::is_constructible<X, std::initializer_list<int>&>::value, "");
- static_assert(!std::is_constructible<optional<X>, std::initializer_list<int>&>::value, "");
- }
- {
- optional<std::vector<int>> opt(in_place, {3, 1});
- assert(static_cast<bool>(opt) == true);
- assert((*opt == std::vector<int>{3, 1}));
- assert(opt->size() == 2);
- }
- {
- optional<std::vector<int>> opt(in_place, {3, 1}, std::allocator<int>());
- assert(static_cast<bool>(opt) == true);
- assert((*opt == std::vector<int>{3, 1}));
- assert(opt->size() == 2);
- }
- {
- static_assert(std::is_constructible<optional<Y>, std::initializer_list<int>&>::value, "");
- constexpr optional<Y> opt(in_place, {3, 1});
- static_assert(static_cast<bool>(opt) == true, "");
- static_assert(*opt == Y{3, 1}, "");
-
- struct test_constexpr_ctor
- : public optional<Y>
- {
- constexpr test_constexpr_ctor(in_place_t, std::initializer_list<int> i)
- : optional<Y>(in_place, i) {}
- };
-
- }
+int main(int, char**) {
+ {
+ static_assert(!std::is_constructible<X, std::initializer_list<int>&>::value, "");
+ static_assert(!std::is_constructible<optional<X>, std::initializer_list<int>&>::value, "");
+ }
+ {
+ optional<std::vector<int>> opt(in_place, {3, 1});
+ assert(static_cast<bool>(opt) == true);
+ assert((*opt == std::vector<int>{3, 1}));
+ assert(opt->size() == 2);
+ }
+ {
+ optional<std::vector<int>> opt(in_place, {3, 1}, std::allocator<int>());
+ assert(static_cast<bool>(opt) == true);
+ assert((*opt == std::vector<int>{3, 1}));
+ assert(opt->size() == 2);
+ }
+ {
+ static_assert(std::is_constructible<optional<Y>, std::initializer_list<int>&>::value, "");
+ constexpr optional<Y> opt(in_place, {3, 1});
+ static_assert(static_cast<bool>(opt) == true, "");
+ static_assert(*opt == Y{3, 1}, "");
+
+ struct test_constexpr_ctor : public optional<Y> {
+ constexpr test_constexpr_ctor(in_place_t, std::initializer_list<int> i) : optional<Y>(in_place, i) {}
+ };
+ }
#ifndef TEST_HAS_NO_EXCEPTIONS
- {
- static_assert(std::is_constructible<optional<Z>, std::initializer_list<int>&>::value, "");
- try
- {
- optional<Z> opt(in_place, {3, 1});
- assert(false);
- }
- catch (int i)
- {
- assert(i == 6);
- }
+ {
+ static_assert(std::is_constructible<optional<Z>, std::initializer_list<int>&>::value, "");
+ try {
+ optional<Z> opt(in_place, {3, 1});
+ assert(false);
+ } catch (int i) {
+ assert(i == 6);
}
+ }
#endif
return 0;
diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/move.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/move.pass.cpp
index f856c1d..583debc 100644
--- a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/move.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/move.pass.cpp
@@ -12,211 +12,204 @@
// constexpr optional(optional<T>&& rhs);
+#include <cassert>
#include <optional>
#include <type_traits>
-#include <cassert>
#include "test_macros.h"
#include "archetypes.h"
using std::optional;
-template <class T, class ...InitArgs>
-void test(InitArgs&&... args)
-{
- const optional<T> orig(std::forward<InitArgs>(args)...);
- optional<T> rhs(orig);
- bool rhs_engaged = static_cast<bool>(rhs);
- optional<T> lhs = std::move(rhs);
- assert(static_cast<bool>(lhs) == rhs_engaged);
- if (rhs_engaged)
- assert(*lhs == *orig);
+template <class T, class... InitArgs>
+void test(InitArgs&&... args) {
+ const optional<T> orig(std::forward<InitArgs>(args)...);
+ optional<T> rhs(orig);
+ bool rhs_engaged = static_cast<bool>(rhs);
+ optional<T> lhs = std::move(rhs);
+ assert(static_cast<bool>(lhs) == rhs_engaged);
+ if (rhs_engaged)
+ assert(*lhs == *orig);
}
-template <class T, class ...InitArgs>
-constexpr bool constexpr_test(InitArgs&&... args)
-{
- static_assert( std::is_trivially_copy_constructible_v<T>, ""); // requirement
- const optional<T> orig(std::forward<InitArgs>(args)...);
- optional<T> rhs(orig);
- optional<T> lhs = std::move(rhs);
- return (lhs.has_value() == orig.has_value()) &&
- (lhs.has_value() ? *lhs == *orig : true);
+template <class T, class... InitArgs>
+constexpr bool constexpr_test(InitArgs&&... args) {
+ static_assert(std::is_trivially_copy_constructible_v<T>, ""); // requirement
+ const optional<T> orig(std::forward<InitArgs>(args)...);
+ optional<T> rhs(orig);
+ optional<T> lhs = std::move(rhs);
+ return (lhs.has_value() == orig.has_value()) && (lhs.has_value() ? *lhs == *orig : true);
}
void test_throwing_ctor() {
#ifndef TEST_HAS_NO_EXCEPTIONS
- struct Z {
- Z() : count(0) {}
- Z(Z&& o) : count(o.count + 1)
- { if (count == 2) throw 6; }
- int count;
- };
- Z z;
- optional<Z> rhs(std::move(z));
- try
- {
- optional<Z> lhs(std::move(rhs));
- assert(false);
- }
- catch (int i)
- {
- assert(i == 6);
- }
+ struct Z {
+ Z() : count(0) {}
+ Z(Z&& o) : count(o.count + 1) {
+ if (count == 2)
+ throw 6;
+ }
+ int count;
+ };
+ Z z;
+ optional<Z> rhs(std::move(z));
+ try {
+ optional<Z> lhs(std::move(rhs));
+ assert(false);
+ } catch (int i) {
+ assert(i == 6);
+ }
#endif
}
+template <class T, class... InitArgs>
+void test_ref(InitArgs&&... args) {
+ optional<T> rhs(std::forward<InitArgs>(args)...);
+ bool rhs_engaged = static_cast<bool>(rhs);
+ optional<T> lhs = std::move(rhs);
+ assert(static_cast<bool>(lhs) == rhs_engaged);
+ if (rhs_engaged)
+ assert(&(*lhs) == &(*rhs));
+}
-template <class T, class ...InitArgs>
-void test_ref(InitArgs&&... args)
-{
- optional<T> rhs(std::forward<InitArgs>(args)...);
- bool rhs_engaged = static_cast<bool>(rhs);
- optional<T> lhs = std::move(rhs);
- assert(static_cast<bool>(lhs) == rhs_engaged);
- if (rhs_engaged)
- assert(&(*lhs) == &(*rhs));
+void test_reference_extension() {
+#if TEST_STD_VER >= 26
+ using T = TestTypes::TestType;
+ T::reset();
+ {
+ T t;
+ T::reset_constructors();
+ test_ref<T&>();
+ test_ref<T&>(t);
+ assert(T::alive == 1);
+ assert(T::constructed == 0);
+ assert(T::assigned == 0);
+ assert(T::destroyed == 0);
+ }
+ assert(T::destroyed == 1);
+ assert(T::alive == 0);
+ {
+ T t;
+ const T& ct = t;
+ T::reset_constructors();
+ test_ref<T const&>();
+ test_ref<T const&>(t);
+ test_ref<T const&>(ct);
+ assert(T::alive == 1);
+ assert(T::constructed == 0);
+ assert(T::assigned == 0);
+ assert(T::destroyed == 0);
+ }
+ assert(T::alive == 0);
+ assert(T::destroyed == 1);
+# if 0 // FIXME: optional<T&&> is not allowed.
+ {
+ T t;
+ T::reset_constructors();
+ test_ref<T&&>();
+ test_ref<T&&>(std::move(t));
+ assert(T::alive == 1);
+ assert(T::constructed == 0);
+ assert(T::assigned == 0);
+ assert(T::destroyed == 0);
+ }
+ assert(T::alive == 0);
+ assert(T::destroyed == 1);
+ {
+ T t;
+ const T& ct = t;
+ T::reset_constructors();
+ test_ref<T const&&>();
+ test_ref<T const&&>(std::move(t));
+ test_ref<T const&&>(std::move(ct));
+ assert(T::alive == 1);
+ assert(T::constructed == 0);
+ assert(T::assigned == 0);
+ assert(T::destroyed == 0);
+ }
+ assert(T::alive == 0);
+ assert(T::destroyed == 1);
+ {
+ static_assert(!std::is_copy_constructible_v<std::optional<T&&>>);
+ static_assert(!std::is_copy_constructible_v<std::optional<T const&&>>);
+ }
+# endif
+#endif
}
-void test_reference_extension()
-{
-#if defined(_LIBCPP_VERSION) && 0 // FIXME these extensions are currently disabled.
+int main(int, char**) {
+ test<int>();
+ test<int>(3);
+ static_assert(constexpr_test<int>(), "");
+ static_assert(constexpr_test<int>(3), "");
+
+ {
+ optional<const int> o(42);
+ optional<const int> o2(std::move(o));
+ assert(*o2 == 42);
+ }
+ {
using T = TestTypes::TestType;
T::reset();
- {
- T t;
- T::reset_constructors();
- test_ref<T&>();
- test_ref<T&>(t);
- assert(T::alive == 1);
- assert(T::constructed == 0);
- assert(T::assigned == 0);
- assert(T::destroyed == 0);
- }
- assert(T::destroyed == 1);
+ optional<T> rhs;
assert(T::alive == 0);
- {
- T t;
- const T& ct = t;
- T::reset_constructors();
- test_ref<T const&>();
- test_ref<T const&>(t);
- test_ref<T const&>(ct);
- assert(T::alive == 1);
- assert(T::constructed == 0);
- assert(T::assigned == 0);
- assert(T::destroyed == 0);
- }
- assert(T::alive == 0);
- assert(T::destroyed == 1);
- {
- T t;
- T::reset_constructors();
- test_ref<T&&>();
- test_ref<T&&>(std::move(t));
- assert(T::alive == 1);
- assert(T::constructed == 0);
- assert(T::assigned == 0);
- assert(T::destroyed == 0);
- }
- assert(T::alive == 0);
- assert(T::destroyed == 1);
- {
- T t;
- const T& ct = t;
- T::reset_constructors();
- test_ref<T const&&>();
- test_ref<T const&&>(std::move(t));
- test_ref<T const&&>(std::move(ct));
- assert(T::alive == 1);
- assert(T::constructed == 0);
- assert(T::assigned == 0);
- assert(T::destroyed == 0);
- }
+ const optional<T> lhs(std::move(rhs));
+ assert(lhs.has_value() == false);
+ assert(rhs.has_value() == false);
assert(T::alive == 0);
- assert(T::destroyed == 1);
- {
- static_assert(!std::is_copy_constructible<std::optional<T&&>>::value, "");
- static_assert(!std::is_copy_constructible<std::optional<T const&&>>::value, "");
- }
-#endif
-}
-
-
-int main(int, char**)
-{
- test<int>();
- test<int>(3);
- static_assert(constexpr_test<int>(), "" );
- static_assert(constexpr_test<int>(3), "" );
-
- {
- optional<const int> o(42);
- optional<const int> o2(std::move(o));
- assert(*o2 == 42);
- }
- {
- using T = TestTypes::TestType;
- T::reset();
- optional<T> rhs;
- assert(T::alive == 0);
- const optional<T> lhs(std::move(rhs));
- assert(lhs.has_value() == false);
- assert(rhs.has_value() == false);
- assert(T::alive == 0);
- }
- TestTypes::TestType::reset();
- {
- using T = TestTypes::TestType;
- T::reset();
- optional<T> rhs(42);
- assert(T::alive == 1);
- assert(T::value_constructed == 1);
- assert(T::move_constructed == 0);
- const optional<T> lhs(std::move(rhs));
- assert(lhs.has_value());
- assert(rhs.has_value());
- assert(lhs.value().value == 42);
- assert(rhs.value().value == -1);
- assert(T::move_constructed == 1);
- assert(T::alive == 2);
- }
- TestTypes::TestType::reset();
- {
- using namespace ConstexprTestTypes;
- test<TestType>();
- test<TestType>(42);
- }
- {
- using namespace TrivialTestTypes;
- test<TestType>();
- test<TestType>(42);
- }
- {
- test_throwing_ctor();
- }
- {
- struct ThrowsMove {
- ThrowsMove() noexcept(false) {}
- ThrowsMove(ThrowsMove const&) noexcept(false) {}
- ThrowsMove(ThrowsMove &&) noexcept(false) {}
- };
- static_assert(!std::is_nothrow_move_constructible<optional<ThrowsMove>>::value, "");
- struct NoThrowMove {
- NoThrowMove() noexcept(false) {}
- NoThrowMove(NoThrowMove const&) noexcept(false) {}
- NoThrowMove(NoThrowMove &&) noexcept(true) {}
- };
- static_assert(std::is_nothrow_move_constructible<optional<NoThrowMove>>::value, "");
- }
- {
- test_reference_extension();
- }
- {
+ }
+ TestTypes::TestType::reset();
+ {
+ using T = TestTypes::TestType;
+ T::reset();
+ optional<T> rhs(42);
+ assert(T::alive == 1);
+ assert(T::value_constructed == 1);
+ assert(T::move_constructed == 0);
+ const optional<T> lhs(std::move(rhs));
+ assert(lhs.has_value());
+ assert(rhs.has_value());
+ assert(lhs.value().value == 42);
+ assert(rhs.value().value == -1);
+ assert(T::move_constructed == 1);
+ assert(T::alive == 2);
+ }
+ TestTypes::TestType::reset();
+ {
+ using namespace ConstexprTestTypes;
+ test<TestType>();
+ test<TestType>(42);
+ }
+ {
+ using namespace TrivialTestTypes;
+ test<TestType>();
+ test<TestType>(42);
+ }
+ {
+ test_throwing_ctor();
+ }
+ {
+ struct ThrowsMove {
+ ThrowsMove() noexcept(false) {}
+ ThrowsMove(ThrowsMove const&) noexcept(false) {}
+ ThrowsMove(ThrowsMove&&) noexcept(false) {}
+ };
+ static_assert(!std::is_nothrow_move_constructible<optional<ThrowsMove>>::value, "");
+ struct NoThrowMove {
+ NoThrowMove() noexcept(false) {}
+ NoThrowMove(NoThrowMove const&) noexcept(false) {}
+ NoThrowMove(NoThrowMove&&) noexcept(true) {}
+ };
+ static_assert(std::is_nothrow_move_constructible<optional<NoThrowMove>>::value, "");
+ }
+ {
+ test_reference_extension();
+ }
+ {
constexpr std::optional<int> o1{4};
constexpr std::optional<int> o2 = std::move(o1);
- static_assert( *o2 == 4, "" );
- }
+ static_assert(*o2 == 4, "");
+ }
return 0;
}
diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/nullopt_t.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/nullopt_t.pass.cpp
index 36a60f2..c1bdd81 100644
--- a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/nullopt_t.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/nullopt_t.pass.cpp
@@ -11,66 +11,57 @@
// constexpr optional(nullopt_t) noexcept;
+#include <cassert>
#include <optional>
#include <type_traits>
-#include <cassert>
#include "archetypes.h"
#include "test_macros.h"
-using std::optional;
-using std::nullopt_t;
using std::nullopt;
+using std::nullopt_t;
+using std::optional;
template <class Opt>
-void
-test_constexpr()
-{
- static_assert(std::is_nothrow_constructible<Opt, nullopt_t&>::value, "");
- static_assert(std::is_trivially_destructible<Opt>::value, "");
- static_assert(std::is_trivially_destructible<typename Opt::value_type>::value, "");
+void test_constexpr() {
+ static_assert(std::is_nothrow_constructible<Opt, nullopt_t&>::value, "");
+ static_assert(std::is_trivially_destructible<Opt>::value, "");
+ static_assert(std::is_trivially_destructible<typename Opt::value_type>::value, "");
- constexpr Opt opt(nullopt);
- static_assert(static_cast<bool>(opt) == false, "");
+ constexpr Opt opt(nullopt);
+ static_assert(static_cast<bool>(opt) == false, "");
- struct test_constexpr_ctor
- : public Opt
- {
- constexpr test_constexpr_ctor() {}
- };
+ struct test_constexpr_ctor : public Opt {
+ constexpr test_constexpr_ctor() {}
+ };
}
template <class Opt>
-void
-test()
-{
- static_assert(std::is_nothrow_constructible<Opt, nullopt_t&>::value, "");
- static_assert(!std::is_trivially_destructible<Opt>::value, "");
- static_assert(!std::is_trivially_destructible<typename Opt::value_type>::value, "");
- {
+void test() {
+ static_assert(std::is_nothrow_constructible<Opt, nullopt_t&>::value, "");
+ static_assert(!std::is_trivially_destructible<Opt>::value, "");
+ static_assert(!std::is_trivially_destructible<typename Opt::value_type>::value, "");
+ {
Opt opt(nullopt);
assert(static_cast<bool>(opt) == false);
- }
- {
+ }
+ {
const Opt opt(nullopt);
assert(static_cast<bool>(opt) == false);
- }
- struct test_constexpr_ctor
- : public Opt
- {
- constexpr test_constexpr_ctor() {}
- };
+ }
+ struct test_constexpr_ctor : public Opt {
+ constexpr test_constexpr_ctor() {}
+ };
}
-int main(int, char**)
-{
- test_constexpr<optional<int>>();
- test_constexpr<optional<int*>>();
- test_constexpr<optional<ImplicitTypes::NoCtors>>();
- test_constexpr<optional<NonTrivialTypes::NoCtors>>();
- test_constexpr<optional<NonConstexprTypes::NoCtors>>();
- test<optional<NonLiteralTypes::NoCtors>>();
+int main(int, char**) {
+ test_constexpr<optional<int>>();
+ test_constexpr<optional<int*>>();
+ test_constexpr<optional<ImplicitTypes::NoCtors>>();
+ test_constexpr<optional<NonTrivialTypes::NoCtors>>();
+ test_constexpr<optional<NonConstexprTypes::NoCtors>>();
+ test<optional<NonLiteralTypes::NoCtors>>();
return 0;
}
diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/optional_U.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/optional_U.pass.cpp
index 14c400c..709b106 100644
--- a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/optional_U.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/optional_U.pass.cpp
@@ -23,75 +23,68 @@
using std::optional;
template <class T, class U>
-TEST_CONSTEXPR_CXX20 void
-test(optional<U>&& rhs, bool is_going_to_throw = false)
-{
- bool rhs_engaged = static_cast<bool>(rhs);
+TEST_CONSTEXPR_CXX20 void test(optional<U>&& rhs, bool is_going_to_throw = false) {
+ bool rhs_engaged = static_cast<bool>(rhs);
#ifndef TEST_HAS_NO_EXCEPTIONS
- try
- {
- optional<T> lhs = std::move(rhs);
- assert(is_going_to_throw == false);
- assert(static_cast<bool>(lhs) == rhs_engaged);
- }
- catch (int i)
- {
- assert(i == 6);
- }
-#else
- if (is_going_to_throw) return;
+ try {
optional<T> lhs = std::move(rhs);
+ assert(is_going_to_throw == false);
assert(static_cast<bool>(lhs) == rhs_engaged);
+ } catch (int i) {
+ assert(i == 6);
+ }
+#else
+ if (is_going_to_throw)
+ return;
+ optional<T> lhs = std::move(rhs);
+ assert(static_cast<bool>(lhs) == rhs_engaged);
#endif
}
-class X
-{
- int i_;
+class X {
+ int i_;
+
public:
- TEST_CONSTEXPR_CXX20 X(int i) : i_(i) {}
- TEST_CONSTEXPR_CXX20 X(X&& x) : i_(std::exchange(x.i_, 0)) {}
- TEST_CONSTEXPR_CXX20 ~X() {i_ = 0;}
- friend constexpr bool operator==(const X& x, const X& y) {return x.i_ == y.i_;}
+ TEST_CONSTEXPR_CXX20 X(int i) : i_(i) {}
+ TEST_CONSTEXPR_CXX20 X(X&& x) : i_(std::exchange(x.i_, 0)) {}
+ TEST_CONSTEXPR_CXX20 ~X() { i_ = 0; }
+ friend constexpr bool operator==(const X& x, const X& y) { return x.i_ == y.i_; }
};
-struct Z
-{
- Z(int) { TEST_THROW(6); }
+struct Z {
+ Z(int) { TEST_THROW(6); }
};
-template<class T, class U>
-TEST_CONSTEXPR_CXX20 bool test_all()
-{
- {
- optional<T> rhs;
- test<U>(std::move(rhs));
- }
- {
- optional<T> rhs(short{3});
- test<U>(std::move(rhs));
- }
- return true;
+template <class T, class U>
+TEST_CONSTEXPR_CXX20 bool test_all() {
+ {
+ optional<T> rhs;
+ test<U>(std::move(rhs));
+ }
+ {
+ optional<T> rhs(short{3});
+ test<U>(std::move(rhs));
+ }
+ return true;
}
-int main(int, char**)
-{
- test_all<short, int>();
- test_all<int, X>();
+int main(int, char**) {
+ test_all<short, int>();
+ test_all<int, X>();
#if TEST_STD_VER > 17
- static_assert(test_all<short, int>());
- static_assert(test_all<int, X>());
+ static_assert(test_all<short, int>());
+ static_assert(test_all<int, X>());
#endif
- {
- optional<int> rhs;
- test<Z>(std::move(rhs));
- }
- {
- optional<int> rhs(3);
- test<Z>(std::move(rhs), true);
- }
+ {
+ optional<int> rhs;
+ test<Z>(std::move(rhs));
+ }
+ {
+ optional<int> rhs(3);
+ test<Z>(std::move(rhs), true);
+ }
- static_assert(!(std::is_constructible<optional<X>, optional<Z>>::value), "");
+ static_assert(!(std::is_constructible<optional<X>, optional<Z>>::value), "");
return 0;
}
diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/ref_constructs_from_temporary.verify.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/ref_constructs_from_temporary.verify.cpp
new file mode 100644
index 0000000..01b241f
--- /dev/null
+++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/ref_constructs_from_temporary.verify.cpp
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// optional
+
+#include <optional>
+#include <utility>
+
+struct X {
+ int i;
+
+ X(int j) : i(j) {}
+};
+
+int main(int, char**) {
+ const std::optional<int> _co(1);
+ std::optional<int> _o(1);
+
+ // expected-error-re@*:* 8 {{call to deleted constructor of 'std::optional<{{.*}}>'}}
+ std::optional<const int&> o1{1}; // optional(U&&)
+ std::optional<const int&> o2{std::optional<int>(1)}; // optional(optional<U>&&)
+ std::optional<const int&> o3{_co}; // optional(const optional<U>&)
+ std::optional<const int&> o4{_o}; // optional(optional<U>&)
+ std::optional<const X&> o5{1}; // optional(U&&)
+ std::optional<const X&> o6{std::optional<int>(1)}; // optional(optional<U>&&)
+ std::optional<const X&> o7{_co}; // optional(const optional<U>&)
+ std::optional<const X&> o8{_o}; // optional(optional<U>&)
+}
diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/ref_t.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/ref_t.pass.cpp
new file mode 100644
index 0000000..5755274
--- /dev/null
+++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/ref_t.pass.cpp
@@ -0,0 +1,75 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <optional>
+
+#include <cassert>
+#include <optional>
+#include <type_traits>
+#include <utility>
+
+template <typename RefType, std::remove_reference_t<RefType> _Val>
+constexpr bool test() {
+ std::remove_reference_t<RefType> item{_Val};
+ std::optional<RefType> opt{item};
+
+ {
+ assert(*opt == item);
+ assert(&(*opt) == &item);
+ }
+ {
+ assert(*std::as_const(opt) == item);
+ assert(&(*std::as_const(opt)) == &item);
+ }
+
+ return true;
+}
+
+template <typename T>
+constexpr T foo(T val) {
+ return val;
+}
+
+template <typename T, T _Val>
+constexpr bool fn_ref_test() {
+ std::optional<T (&)(T)> opt{foo<T>};
+ assert(opt.has_value());
+ assert((*opt)(_Val) == _Val);
+
+ return true;
+}
+
+template <typename T, T _Val>
+constexpr bool array_ref_test() {
+ T arr[5]{};
+ std::optional<T(&)[5]> opt{arr};
+
+ assert(opt.has_value());
+ (*opt)[0] = _Val;
+ assert((*opt)[0] == _Val);
+ assert(arr[0] == _Val);
+
+ return true;
+}
+
+constexpr bool tests() {
+ assert((test<int&, 1>()));
+ assert((test<double&, 1.0>()));
+ assert((fn_ref_test<int, 1>()));
+ assert((array_ref_test<int, 1>()));
+ assert((fn_ref_test<double, 1.0>()));
+ assert((array_ref_test<double, 1.0>()));
+ return true;
+}
+
+int main(int, char**) {
+ static_assert(tests());
+ tests();
+}
diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/rvalue_T.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/rvalue_T.pass.cpp
index 1242595..e73eef4 100644
--- a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/rvalue_T.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/rvalue_T.pass.cpp
@@ -12,137 +12,118 @@
// constexpr optional(T&& v);
+#include <cassert>
#include <optional>
#include <type_traits>
-#include <cassert>
#include "test_macros.h"
#include "archetypes.h"
-
using std::optional;
-
-class Z
-{
+class Z {
public:
- Z(int) {}
- Z(Z&&) {TEST_THROW(6);}
+ Z(int) {}
+ Z(Z&&) { TEST_THROW(6); }
};
-
-int main(int, char**)
-{
- {
- typedef int T;
- constexpr optional<T> opt(T(5));
- static_assert(static_cast<bool>(opt) == true, "");
- static_assert(*opt == 5, "");
-
- struct test_constexpr_ctor
- : public optional<T>
- {
- constexpr test_constexpr_ctor(T&&) {}
- };
- }
- {
- typedef double T;
- constexpr optional<T> opt(T(3));
- static_assert(static_cast<bool>(opt) == true, "");
- static_assert(*opt == 3, "");
-
- struct test_constexpr_ctor
- : public optional<T>
- {
- constexpr test_constexpr_ctor(T&&) {}
- };
- }
- {
- const int x = 42;
- optional<const int> o(std::move(x));
- assert(*o == 42);
- }
- {
- typedef TestTypes::TestType T;
- T::reset();
- optional<T> opt = T{3};
- assert(T::alive == 1);
- assert(T::move_constructed == 1);
- assert(static_cast<bool>(opt) == true);
- assert(opt.value().value == 3);
- }
- {
- typedef ExplicitTestTypes::TestType T;
- static_assert(!std::is_convertible<T&&, optional<T>>::value, "");
- T::reset();
- optional<T> opt(T{3});
- assert(T::alive == 1);
- assert(T::move_constructed == 1);
- assert(static_cast<bool>(opt) == true);
- assert(opt.value().value == 3);
- }
- {
- typedef TestTypes::TestType T;
- T::reset();
- optional<T> opt = {3};
- assert(T::alive == 1);
- assert(T::value_constructed == 1);
- assert(T::copy_constructed == 0);
- assert(T::move_constructed == 0);
- assert(static_cast<bool>(opt) == true);
- assert(opt.value().value == 3);
- }
- {
- typedef ConstexprTestTypes::TestType T;
- constexpr optional<T> opt = {T(3)};
- static_assert(static_cast<bool>(opt) == true, "");
- static_assert(opt.value().value == 3, "");
-
- struct test_constexpr_ctor
- : public optional<T>
- {
- constexpr test_constexpr_ctor(const T&) {}
- };
- }
- {
- typedef ConstexprTestTypes::TestType T;
- constexpr optional<T> opt = {3};
- static_assert(static_cast<bool>(opt) == true, "");
- static_assert(opt.value().value == 3, "");
-
- struct test_constexpr_ctor
- : public optional<T>
- {
- constexpr test_constexpr_ctor(const T&) {}
- };
- }
- {
- typedef ExplicitConstexprTestTypes::TestType T;
- static_assert(!std::is_convertible<T&&, optional<T>>::value, "");
- constexpr optional<T> opt(T{3});
- static_assert(static_cast<bool>(opt) == true, "");
- static_assert(opt.value().value == 3, "");
-
- struct test_constexpr_ctor
- : public optional<T>
- {
- constexpr test_constexpr_ctor(T&&) {}
- };
-
- }
+int main(int, char**) {
+ {
+ typedef int T;
+ constexpr optional<T> opt(T(5));
+ static_assert(static_cast<bool>(opt) == true, "");
+ static_assert(*opt == 5, "");
+
+ struct test_constexpr_ctor : public optional<T> {
+ constexpr test_constexpr_ctor(T&&) {}
+ };
+ }
+ {
+ typedef double T;
+ constexpr optional<T> opt(T(3));
+ static_assert(static_cast<bool>(opt) == true, "");
+ static_assert(*opt == 3, "");
+
+ struct test_constexpr_ctor : public optional<T> {
+ constexpr test_constexpr_ctor(T&&) {}
+ };
+ }
+ {
+ const int x = 42;
+ optional<const int> o(std::move(x));
+ assert(*o == 42);
+ }
+ {
+ typedef TestTypes::TestType T;
+ T::reset();
+ optional<T> opt = T{3};
+ assert(T::alive == 1);
+ assert(T::move_constructed == 1);
+ assert(static_cast<bool>(opt) == true);
+ assert(opt.value().value == 3);
+ }
+ {
+ typedef ExplicitTestTypes::TestType T;
+ static_assert(!std::is_convertible<T&&, optional<T>>::value, "");
+ T::reset();
+ optional<T> opt(T{3});
+ assert(T::alive == 1);
+ assert(T::move_constructed == 1);
+ assert(static_cast<bool>(opt) == true);
+ assert(opt.value().value == 3);
+ }
+ {
+ typedef TestTypes::TestType T;
+ T::reset();
+ optional<T> opt = {3};
+ assert(T::alive == 1);
+ assert(T::value_constructed == 1);
+ assert(T::copy_constructed == 0);
+ assert(T::move_constructed == 0);
+ assert(static_cast<bool>(opt) == true);
+ assert(opt.value().value == 3);
+ }
+ {
+ typedef ConstexprTestTypes::TestType T;
+ constexpr optional<T> opt = {T(3)};
+ static_assert(static_cast<bool>(opt) == true, "");
+ static_assert(opt.value().value == 3, "");
+
+ struct test_constexpr_ctor : public optional<T> {
+ constexpr test_constexpr_ctor(const T&) {}
+ };
+ }
+ {
+ typedef ConstexprTestTypes::TestType T;
+ constexpr optional<T> opt = {3};
+ static_assert(static_cast<bool>(opt) == true, "");
+ static_assert(opt.value().value == 3, "");
+
+ struct test_constexpr_ctor : public optional<T> {
+ constexpr test_constexpr_ctor(const T&) {}
+ };
+ }
+ {
+ typedef ExplicitConstexprTestTypes::TestType T;
+ static_assert(!std::is_convertible<T&&, optional<T>>::value, "");
+ constexpr optional<T> opt(T{3});
+ static_assert(static_cast<bool>(opt) == true, "");
+ static_assert(opt.value().value == 3, "");
+
+ struct test_constexpr_ctor : public optional<T> {
+ constexpr test_constexpr_ctor(T&&) {}
+ };
+ }
#ifndef TEST_HAS_NO_EXCEPTIONS
- {
- try
- {
- Z z(3);
- optional<Z> opt(std::move(z));
- assert(false);
- }
- catch (int i)
- {
- assert(i == 6);
- }
+ {
+ try {
+ Z z(3);
+ optional<Z> opt(std::move(z));
+ assert(false);
+ } catch (int i) {
+ assert(i == 6);
}
+ }
#endif
return 0;
diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.dtor/dtor.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.dtor/dtor.pass.cpp
index c004427..1202879 100644
--- a/libcxx/test/std/utilities/optional/optional.object/optional.object.dtor/dtor.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.dtor/dtor.pass.cpp
@@ -11,9 +11,9 @@
// ~optional();
+#include <cassert>
#include <optional>
#include <type_traits>
-#include <cassert>
#include "test_macros.h"
@@ -64,6 +64,24 @@ int main(int, char**)
}
assert(X::dtor_called == true);
}
+#if TEST_STD_VER >= 26
+ {
+ typedef X& T;
+ static_assert(std::is_trivially_destructible_v<T>);
+ static_assert(std::is_trivially_destructible_v<optional<T>>);
+ }
+ X::dtor_called = false;
+ X x;
+ {
+ optional<X&> opt{x};
+ assert(X::dtor_called == false);
+ }
+ assert(X::dtor_called == false);
- return 0;
+ {
+ static_assert(std::is_trivially_destructible_v<X (&)()>);
+ static_assert(std::is_trivially_destructible_v<optional<X (&)()>>);
+ }
+#endif
+ return 0;
}
diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.mod/reset.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.mod/reset.pass.cpp
index 7029b37..e23e481 100644
--- a/libcxx/test/std/utilities/optional/optional.object/optional.object.mod/reset.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.mod/reset.pass.cpp
@@ -69,5 +69,16 @@ int main(int, char**)
X::dtor_called = false;
}
- return 0;
+#if TEST_STD_VER >= 26
+ {
+ X x{};
+ optional<X&> opt(x);
+ X::dtor_called = false;
+ opt.reset();
+ assert(X::dtor_called == false);
+ assert(static_cast<bool>(opt) == false);
+ }
+#endif
+
+ return 0;
}
diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/dereference.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/dereference.pass.cpp
index 49b4d21..6c1bf8a 100644
--- a/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/dereference.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/dereference.pass.cpp
@@ -50,7 +50,19 @@ int main(int, char**)
optional<X> opt(X{});
assert((*opt).test() == 4);
}
+#if TEST_STD_VER >= 26
+ {
+ X x{};
+ optional<X&> opt(x);
+ ASSERT_SAME_TYPE(decltype(*opt), X&);
+ ASSERT_NOEXCEPT(*opt);
+ }
+ {
+ X x{};
+ optional<X&> opt(x);
+ assert((*opt).test() == 4);
+ }
+#endif
static_assert(test() == 7, "");
-
return 0;
}
diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/dereference_const.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/dereference_const.pass.cpp
index ff86d95..c15d4e4 100644
--- a/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/dereference_const.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/dereference_const.pass.cpp
@@ -43,6 +43,25 @@ int main(int, char**)
constexpr optional<X> opt(X{});
static_assert((*opt).test() == 3, "");
}
+#if TEST_STD_VER >= 26
+ {
+ X x{};
+ const optional<X&> opt{x};
+ ASSERT_SAME_TYPE(decltype(*opt), X&);
+ ASSERT_NOEXCEPT(*opt);
+ }
+ {
+ X x{};
+ const optional<const X&> opt{x};
+ ASSERT_SAME_TYPE(decltype(*opt), const X&);
+ ASSERT_NOEXCEPT(*opt);
+ }
+ {
+ static constexpr X x{};
+ constexpr optional<const X&> opt(x);
+ static_assert((*opt).test() == 3);
+ }
+#endif
{
constexpr optional<Y> opt(Y{});
assert((*opt).test() == 2);
diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/has_value.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/has_value.pass.cpp
index 6998e02..9873a76 100644
--- a/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/has_value.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/has_value.pass.cpp
@@ -33,6 +33,13 @@ int main(int, char**)
constexpr optional<int> opt(0);
static_assert(opt.has_value(), "");
}
+#if TEST_STD_VER >= 26
+ {
+ static constexpr int i = 0;
+ constexpr optional<const int&> opt{i};
+ static_assert(opt.has_value());
+ }
+#endif
- return 0;
+ return 0;
}
diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/op_arrow.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/op_arrow.pass.cpp
index 2b5fba5..96d2274 100644
--- a/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/op_arrow.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/op_arrow.pass.cpp
@@ -19,9 +19,9 @@
using std::optional;
-struct X
-{
- int test() noexcept {return 3;}
+struct X {
+ int test() noexcept { return 3; }
+ int test() const noexcept { return 3; }
};
struct Y
@@ -47,6 +47,30 @@ int main(int, char**)
optional<X> opt(X{});
assert(opt->test() == 3);
}
+#if TEST_STD_VER >= 26
+ {
+ X x{};
+ std::optional<X&> opt(x);
+ ASSERT_SAME_TYPE(decltype(opt.operator->()), X*);
+ ASSERT_NOEXCEPT(opt.operator->());
+ }
+ {
+ X x{};
+ std::optional<const X&> opt(x);
+ ASSERT_SAME_TYPE(decltype(opt.operator->()), const X*);
+ ASSERT_NOEXCEPT(opt.operator->());
+ }
+ {
+ X x{};
+ optional<X&> opt{x};
+ assert(opt->test() == 3);
+ }
+ {
+ X x{};
+ optional<const X&> opt{x};
+ assert(opt->test() == 3);
+ }
+#endif
{
static_assert(test() == 3, "");
}
diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/op_arrow_const.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/op_arrow_const.pass.cpp
index d8ce932..e9694fd6 100644
--- a/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/op_arrow_const.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/op_arrow_const.pass.cpp
@@ -54,6 +54,25 @@ int main(int, char**)
constexpr optional<Z> opt(Z{});
static_assert(opt->test() == 1, "");
}
+#if TEST_STD_VER >= 26
+ {
+ X x{};
+ const std::optional<X&> opt(x);
+ ASSERT_SAME_TYPE(decltype(opt.operator->()), X*);
+ ASSERT_NOEXCEPT(opt.operator->());
+ }
+ {
+ X x{};
+ const std::optional<const X&> opt(x);
+ ASSERT_SAME_TYPE(decltype(opt.operator->()), const X*);
+ ASSERT_NOEXCEPT(opt.operator->());
+ }
+ {
+ static constexpr Z z{};
+ constexpr optional<const Z&> opt(z);
+ static_assert(opt->test() == 1);
+ }
+#endif
return 0;
}
diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/value.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/value.pass.cpp
index 781784c6..22b74f5 100644
--- a/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/value.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/value.pass.cpp
@@ -56,6 +56,14 @@ int main(int, char**)
opt.emplace();
assert(opt.value().test() == 4);
}
+#if TEST_STD_VER >= 26
+ {
+ X x;
+ optional<X&> opt{x};
+ ASSERT_NOT_NOEXCEPT(opt.value());
+ ASSERT_SAME_TYPE(decltype(opt.value()), X&);
+ }
+#endif
#ifndef TEST_HAS_NO_EXCEPTIONS
{
optional<X> opt;
diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/value_or.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/value_or.pass.cpp
index 8c063ae..66890ff 100644
--- a/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/value_or.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/value_or.pass.cpp
@@ -80,6 +80,14 @@ constexpr int test()
assert((std::move(opt).value_or({2, 3}) == Z{2, 3}));
assert(!opt);
}
+#if TEST_STD_VER >= 26
+ {
+ int y = 2;
+ optional<int&> opt;
+ assert(std::move(opt).value_or(y) == 2);
+ assert(!opt);
+ }
+#endif
return 0;
}
diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/value_or_const.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/value_or_const.pass.cpp
index ec42890..6bd308b 100644
--- a/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/value_or_const.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/value_or_const.pass.cpp
@@ -79,6 +79,12 @@ int main(int, char**)
const optional<X> opt;
assert(opt.value_or({Y(3)}) == 4);
}
-
- return 0;
+#if TEST_STD_VER >= 26
+ {
+ X y{3};
+ const optional<X&> opt;
+ assert(opt.value_or(y) == 3);
+ }
+#endif
+ return 0;
}
diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.swap/swap.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.swap/swap.pass.cpp
index e3a2fdb..a82ca61 100644
--- a/libcxx/test/std/utilities/optional/optional.object/optional.object.swap/swap.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.swap/swap.pass.cpp
@@ -13,9 +13,10 @@
// noexcept(is_nothrow_move_constructible<T>::value &&
// is_nothrow_swappable<T>::value)
+#include <cassert>
+#include <memory>
#include <optional>
#include <type_traits>
-#include <cassert>
#include "test_macros.h"
#include "archetypes.h"
@@ -127,6 +128,74 @@ TEST_CONSTEXPR_CXX20 bool check_swap()
return true;
}
+#if TEST_STD_VER >= 26
+template <typename T>
+constexpr bool check_swap_ref() {
+ {
+ optional<T&> opt1;
+ optional<T&> opt2;
+ static_assert(noexcept(opt1.swap(opt2)) == true);
+ assert(static_cast<bool>(opt1) == false);
+ assert(static_cast<bool>(opt2) == false);
+ opt1.swap(opt2);
+ assert(static_cast<bool>(opt1) == false);
+ assert(static_cast<bool>(opt2) == false);
+ }
+
+ {
+ T one{1};
+ optional<T&> opt1(one);
+ optional<T&> opt2;
+ static_assert(noexcept(opt1.swap(opt2)) == true);
+ assert(static_cast<bool>(opt1) == true);
+ assert(std::addressof(*opt1) == std::addressof(one));
+ assert(static_cast<bool>(opt2) == false);
+ opt1.swap(opt2);
+ assert(static_cast<bool>(opt1) == false);
+ assert(static_cast<bool>(opt2) == true);
+ assert(std::addressof(*opt2) == std::addressof(one));
+ }
+
+ {
+ T two{2};
+ optional<T&> opt1;
+ optional<T&> opt2(two);
+ static_assert(noexcept(opt1.swap(opt2)) == true);
+ assert(static_cast<bool>(opt1) == false);
+ assert(static_cast<bool>(opt2) == true);
+ assert(std::addressof(*opt2) == std::addressof(two));
+ opt1.swap(opt2);
+ assert(static_cast<bool>(opt1) == true);
+ assert(std::addressof(*opt1) == std::addressof(two));
+ assert(static_cast<bool>(opt2) == false);
+ }
+
+ {
+ T one{1};
+ T two{2};
+
+ optional<T&> opt1(one);
+ optional<T&> opt2(two);
+ static_assert(noexcept(opt1.swap(opt2)) == true);
+ assert(static_cast<bool>(opt1) == true);
+ assert(*opt1 == 1);
+ assert(std::addressof(*opt1) == std::addressof(one));
+ assert(static_cast<bool>(opt2) == true);
+ assert(*opt2 == 2);
+ assert(std::addressof(*opt2) == std::addressof(two));
+ opt1.swap(opt2);
+ assert(static_cast<bool>(opt1) == true);
+ assert(*opt1 == 2);
+ assert(std::addressof(*opt1) == std::addressof(two));
+ assert(static_cast<bool>(opt2) == true);
+ assert(*opt2 == 1);
+ assert(std::addressof(*opt2) == std::addressof(one));
+ }
+
+ return true;
+}
+#endif
+
int main(int, char**)
{
check_swap<int>();
@@ -135,6 +204,12 @@ int main(int, char**)
static_assert(check_swap<int>());
static_assert(check_swap<W>());
#endif
+#if TEST_STD_VER >= 26
+ static_assert(check_swap_ref<int>());
+ static_assert(check_swap_ref<W>());
+ check_swap_ref<int>();
+ check_swap_ref<W>();
+#endif
{
optional<X> opt1;
optional<X> opt2;
diff --git a/libcxx/test/std/utilities/optional/optional.object/optional_requires_destructible_object.verify.cpp b/libcxx/test/std/utilities/optional/optional.object/optional_requires_destructible_object.verify.cpp
index a96c3c6..a956ab3 100644
--- a/libcxx/test/std/utilities/optional/optional.object/optional_requires_destructible_object.verify.cpp
+++ b/libcxx/test/std/utilities/optional/optional.object/optional_requires_destructible_object.verify.cpp
@@ -13,6 +13,8 @@
#include <optional>
+#include "test_macros.h"
+
using std::optional;
struct X
@@ -25,9 +27,13 @@ int main(int, char**)
{
using std::optional;
{
- // expected-error-re@optional:* 2 {{static assertion failed{{.*}}instantiation of optional with a reference type is ill-formed}}
- optional<int&> opt1;
- optional<int&&> opt2;
+#if TEST_STD_VER >= 26
+ // expected-error-re@optional:* {{static assertion failed{{.*}}instantiation of optional with an rvalue reference type is ill-formed}}
+#else
+ // expected-error-re@optional:* 2 {{static assertion failed{{.*}}instantiation of optional with a reference type is ill-formed}}
+#endif
+ optional<int&> opt1;
+ optional<int&&> opt2;
}
{
// expected-error-re@optional:* {{static assertion failed{{.*}}instantiation of optional with a non-destructible type is ill-formed}}
diff --git a/libcxx/test/std/utilities/optional/optional.object/types.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/types.pass.cpp
index d097559..ecbc6b4 100644
--- a/libcxx/test/std/utilities/optional/optional.object/types.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.object/types.pass.cpp
@@ -36,6 +36,11 @@ int main(int, char**)
test<optional<const int>, const int>();
test<optional<double>, double>();
test<optional<const double>, const double>();
-
- return 0;
+#if TEST_STD_VER >= 26
+ test<optional<int&>, int>();
+ test<optional<const int&>, const int>();
+ test<optional<double&>, double>();
+ test<optional<const double&>, const double>();
+#endif
+ return 0;
}
diff --git a/libcxx/test/std/utilities/optional/optional.specalg/make_optional.pass.cpp b/libcxx/test/std/utilities/optional/optional.specalg/make_optional.pass.cpp
index e325a7a..c276451 100644
--- a/libcxx/test/std/utilities/optional/optional.specalg/make_optional.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.specalg/make_optional.pass.cpp
@@ -13,10 +13,10 @@
// template <class T>
// constexpr optional<decay_t<T>> make_optional(T&& v);
+#include <cassert>
+#include <memory>
#include <optional>
#include <string>
-#include <memory>
-#include <cassert>
#include "test_macros.h"
diff --git a/libcxx/test/std/utilities/optional/optional.specalg/make_optional_explicit.pass.cpp b/libcxx/test/std/utilities/optional/optional.specalg/make_optional_explicit.pass.cpp
index 23f131d..5dd1d6f 100644
--- a/libcxx/test/std/utilities/optional/optional.specalg/make_optional_explicit.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.specalg/make_optional_explicit.pass.cpp
@@ -15,13 +15,30 @@
// GCC crashes on this file, see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120577
// XFAIL: gcc-15
+#include <cassert>
+#include <memory>
#include <optional>
#include <string>
-#include <memory>
-#include <cassert>
+#include <string_view>
#include "test_macros.h"
+template <typename T>
+constexpr bool test_ref() {
+ T i{0};
+ auto opt = std::make_optional<T&>(i);
+
+#if TEST_STD_VER < 26
+ assert((std::is_same_v<decltype(opt), std::optional<T>>));
+#else
+ assert((std::is_same_v<decltype(opt), std::optional<T&>>));
+#endif
+
+ assert(*opt == 0);
+
+ return true;
+}
+
int main(int, char**)
{
{
@@ -43,6 +60,12 @@ int main(int, char**)
auto opt = std::make_optional<std::string>(4u, 'X');
assert(*opt == "XXXX");
}
+ using namespace std::string_view_literals;
+
+ static_assert(test_ref<int>());
+ assert((test_ref<int>()));
+ static_assert(test_ref<double>());
+ assert((test_ref<double>()));
- return 0;
+ return 0;
}
diff --git a/libcxx/test/std/utilities/optional/optional.specalg/swap.pass.cpp b/libcxx/test/std/utilities/optional/optional.specalg/swap.pass.cpp
index 0da3a82..c757120 100644
--- a/libcxx/test/std/utilities/optional/optional.specalg/swap.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.specalg/swap.pass.cpp
@@ -12,9 +12,10 @@
// template <class T> void swap(optional<T>& x, optional<T>& y)
// noexcept(noexcept(x.swap(y)));
+#include <cassert>
+#include <memory>
#include <optional>
#include <type_traits>
-#include <cassert>
#include "test_macros.h"
#include "archetypes.h"
@@ -109,9 +110,82 @@ void test_swap_sfinae() {
}
}
+#if TEST_STD_VER >= 26
+template <typename T>
+constexpr bool test_swap_ref() {
+ {
+ optional<T&> opt1;
+ optional<T&> opt2;
+ static_assert(noexcept(swap(opt1, opt2)) == true);
+ assert(static_cast<bool>(opt1) == false);
+ assert(static_cast<bool>(opt2) == false);
+ swap(opt1, opt2);
+ assert(static_cast<bool>(opt1) == false);
+ assert(static_cast<bool>(opt2) == false);
+ }
+ {
+ T one{1};
+ optional<T&> opt1(one);
+ optional<T&> opt2;
+ static_assert(noexcept(swap(opt1, opt2)) == true);
+ assert(static_cast<bool>(opt1) == true);
+ assert(*opt1 == 1);
+ assert(std::addressof(*opt1) == std::addressof(one));
+ assert(static_cast<bool>(opt2) == false);
+ swap(opt1, opt2);
+ assert(static_cast<bool>(opt1) == false);
+ assert(static_cast<bool>(opt2) == true);
+ assert(*opt2 == 1);
+ assert(std::addressof(*opt2) == std::addressof(one));
+ }
+ {
+ T two{2};
+ optional<T&> opt1;
+ optional<T&> opt2(two);
+ static_assert(noexcept(swap(opt1, opt2)) == true);
+ assert(static_cast<bool>(opt1) == false);
+ assert(static_cast<bool>(opt2) == true);
+ assert(*opt2 == 2);
+ assert(std::addressof(*opt2) == std::addressof(two));
+ swap(opt1, opt2);
+ assert(static_cast<bool>(opt1) == true);
+ assert(*opt1 == 2);
+ assert(std::addressof(*opt1) == std::addressof(two));
+ assert(static_cast<bool>(opt2) == false);
+ }
+ {
+ T one{1};
+ T two{2};
+ optional<T&> opt1(one);
+ optional<T&> opt2(two);
+ static_assert(noexcept(swap(opt1, opt2)) == true);
+ assert(static_cast<bool>(opt1) == true);
+ assert(*opt1 == 1);
+ assert(std::addressof(*opt1) == std::addressof(one));
+ assert(static_cast<bool>(opt2) == true);
+ assert(*opt2 == 2);
+ assert(std::addressof(*opt2) == std::addressof(two));
+ swap(opt1, opt2);
+ assert(static_cast<bool>(opt1) == true);
+ assert(*opt1 == 2);
+ assert(std::addressof(*opt1) == std::addressof(two));
+ assert(static_cast<bool>(opt2) == true);
+ assert(*opt2 == 1);
+ assert(std::addressof(*opt2) == std::addressof(one));
+ }
+ return true;
+}
+#endif
+
int main(int, char**)
{
test_swap_sfinae();
+#if TEST_STD_VER >= 26
+ static_assert(test_swap_ref<int>());
+ static_assert(test_swap_ref<double>());
+ test_swap_ref<int>();
+ test_swap_ref<double>();
+#endif
{
optional<int> opt1;
optional<int> opt2;
diff --git a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.apply/make_from_tuple.verify.cpp b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.apply/make_from_tuple.verify.cpp
index 12d7784..e58e760 100644
--- a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.apply/make_from_tuple.verify.cpp
+++ b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.apply/make_from_tuple.verify.cpp
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
-// REQUIRES: std-at-least-c++23
+// REQUIRES: std-at-least-c++26
// <tuple>
@@ -21,11 +21,6 @@
void test() {
// expected-error@*:* {{static assertion failed}}
- // Turns to an error since C++26 (Disallow Binding a Returned Glvalue to a Temporary https://wg21.link/P2748R5).
-#if TEST_STD_VER >= 26
// expected-error@tuple:* {{returning reference to local temporary object}}
-#else
- // expected-warning@tuple:* {{returning reference to local temporary object}}
-#endif
std::ignore = std::make_from_tuple<const int&>(std::tuple<char>{});
}
diff --git a/libcxx/test/std/utilities/utility/utility.intcmp/intcmp.cmp_greater/cmp_greater.pass.cpp b/libcxx/test/std/utilities/utility/utility.intcmp/intcmp.cmp_greater/cmp_greater.pass.cpp
index 8b69ec6..f261166 100644
--- a/libcxx/test/std/utilities/utility/utility.intcmp/intcmp.cmp_greater/cmp_greater.pass.cpp
+++ b/libcxx/test/std/utilities/utility/utility.intcmp/intcmp.cmp_greater/cmp_greater.pass.cpp
@@ -17,6 +17,7 @@
#include <numeric>
#include <tuple>
#include <cassert>
+#include <type_traits>
#include "test_macros.h"
diff --git a/libcxx/test/std/utilities/utility/utility.intcmp/intcmp.cmp_less/cmp_less.pass.cpp b/libcxx/test/std/utilities/utility/utility.intcmp/intcmp.cmp_less/cmp_less.pass.cpp
index 2cc66eb..5a07835 100644
--- a/libcxx/test/std/utilities/utility/utility.intcmp/intcmp.cmp_less/cmp_less.pass.cpp
+++ b/libcxx/test/std/utilities/utility/utility.intcmp/intcmp.cmp_less/cmp_less.pass.cpp
@@ -18,6 +18,7 @@
#include <numeric>
#include <tuple>
#include <cassert>
+#include <type_traits>
#include "test_macros.h"
diff --git a/libcxx/test/std/utilities/utility/utility.intcmp/intcmp.cmp_less_equal/cmp_less_equal.pass.cpp b/libcxx/test/std/utilities/utility/utility.intcmp/intcmp.cmp_less_equal/cmp_less_equal.pass.cpp
index fb46980..079a2f7 100644
--- a/libcxx/test/std/utilities/utility/utility.intcmp/intcmp.cmp_less_equal/cmp_less_equal.pass.cpp
+++ b/libcxx/test/std/utilities/utility/utility.intcmp/intcmp.cmp_less_equal/cmp_less_equal.pass.cpp
@@ -17,6 +17,7 @@
#include <numeric>
#include <tuple>
#include <cassert>
+#include <type_traits>
#include "test_macros.h"
diff --git a/libcxx/test/support/module.modulemap b/libcxx/test/support/module.modulemap
new file mode 100644
index 0000000..75ae8c4
--- /dev/null
+++ b/libcxx/test/support/module.modulemap
@@ -0,0 +1,10 @@
+
+module test_config {
+ module test_macros { textual header "test_macros.h" }
+}
+
+module test {
+ module double_move_tracker { header "double_move_tracker.h" }
+ module test_allocator { header "test_allocator.h" }
+ module type_algorithms { header "type_algorithms.h" }
+}
diff --git a/libcxx/test/support/platform_support.h b/libcxx/test/support/platform_support.h
index 99e60f6..b66fdff 100644
--- a/libcxx/test/support/platform_support.h
+++ b/libcxx/test/support/platform_support.h
@@ -48,7 +48,7 @@
# include <string.h> // strverscmp
#endif
-#if defined(_NEWLIB_VERSION) && defined(__STRICT_ANSI__)
+#if _LIBCPP_LIBC_NEWLIB && defined(__STRICT_ANSI__)
// Newlib provides this, but in the header it's under __STRICT_ANSI__
extern "C" {
int mkstemp(char*);
diff --git a/libcxx/test/support/test.support/test_check_assertion.pass.cpp b/libcxx/test/support/test.support/test_check_assertion.pass.cpp
index 78e47b3..9d356ef 100644
--- a/libcxx/test/support/test.support/test_check_assertion.pass.cpp
+++ b/libcxx/test/support/test.support/test_check_assertion.pass.cpp
@@ -21,11 +21,11 @@ template <class Func>
bool TestDeathTest(
Outcome expected_outcome, DeathCause expected_cause, const char* stmt, Func&& func, const Matcher& matcher) {
auto get_matcher = [&] {
-#if _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG
- return matcher;
-#else
+#if _LIBCPP_ASSERTION_SEMANTIC == _LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE
(void)matcher;
return MakeAnyMatcher();
+#else
+ return matcher;
#endif
};
@@ -69,7 +69,7 @@ bool TestDeathTest(
// clang-format on
-#if _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG
+#if _LIBCPP_ASSERTION_SEMANTIC == _LIBCPP_ASSERTION_SEMANTIC_ENFORCE
DeathCause assertion_death_cause = DeathCause::VerboseAbort;
#else
DeathCause assertion_death_cause = DeathCause::Trap;
@@ -99,7 +99,7 @@ int main(int, char**) {
// Success -- assertion failure with a specific matcher.
TEST_DEATH_TEST_MATCHES(Outcome::Success, assertion_death_cause, good_matcher, fail_assert());
-# if _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG
+# if _LIBCPP_ASSERTION_SEMANTIC == _LIBCPP_ASSERTION_SEMANTIC_ENFORCE
// Failure -- error message doesn't match.
TEST_DEATH_TEST_MATCHES(Outcome::UnexpectedErrorMessage, assertion_death_cause, bad_matcher, fail_assert());
# endif
diff --git a/libcxx/utils/ci/Dockerfile b/libcxx/utils/ci/Dockerfile
deleted file mode 100644
index d22deec..0000000
--- a/libcxx/utils/ci/Dockerfile
+++ /dev/null
@@ -1,329 +0,0 @@
-# ===----------------------------------------------------------------------===##
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-#
-# ===----------------------------------------------------------------------===##
-#
-# This file defines the buildkite and github actions builder images.
-# This images are tagged with <tag>. You can build both images using:
-#
-# TAG=<tag> docker compose build
-#
-# Or you can select a single image to build
-#
-# TAG=test docker compose build actions-builder
-#
-# The final images can be found at
-#
-# ghcr.io/libcxx/libcxx-linux-builder
-# ghcr.io/libcxx/android-buildkite-builder
-#
-# Members of the github.com/libcxx/ organizations can push new images to the CI.
-# This is done by GitHub actions in the https://github.com/libcxx/builders repo.
-#
-# ===----------------------------------------------------------------------===##
-# Running the buildkite image
-# ===----------------------------------------------------------------------===##
-#
-# To start a Buildkite Agent, run it as:
-# $ docker run --env-file <secrets> -it $(docker build -q libcxx/utils/ci)
-#
-# The environment variables in `<secrets>` should be the ones necessary
-# to run a BuildKite agent:
-#
-# BUILDKITE_AGENT_TOKEN=<token>
-#
-# If you're only looking to run the Docker image locally for debugging a
-# build bot, see the `run-buildbot-container` script located in this directory.
-
-ARG ACTIONS_BASE_IMAGE
-
-# HACK: We set the base image in the docker-compose file depending on the final target (buildkite vs github actions).
-# This means we have a much slower container build, but we can use the same Dockerfile for both targets.
-ARG BASE_IMAGE
-FROM $BASE_IMAGE AS builder-base
-
-# Changing this file causes a rebuild of the image in a GitHub action.
-# However, it does not cause the CI runners to switch to that image
-# automatically, that must be done by updating the SHA in the Github workflow
-# file. The date uses the ISO format YYYY-MM-DD.
-RUN echo "Last forced update executed on 2025-04-28."
-
-# Make sure apt-get doesn't try to prompt for stuff like our time zone, etc.
-ENV DEBIAN_FRONTEND=noninteractive
-
-# populated in the docker-compose file
-ARG GCC_HEAD_VERSION
-ENV GCC_HEAD_VERSION=${GCC_HEAD_VERSION}
-
-# populated in the docker-compose file
-ARG LLVM_HEAD_VERSION
-ENV LLVM_HEAD_VERSION=${LLVM_HEAD_VERSION}
-
-# HACK: The github actions runner image already has sudo and requires its use. The buildkite base image does not.
-# Reconcile this.
-RUN <<EOF
- apt-get update || true
- apt-get install -y sudo || true
- echo "ALL ALL = (ALL) NOPASSWD: ALL" | tee /etc/sudoers || true
-EOF
-
-# Installing tzdata before other packages avoids the time zone prompts.
-# These prompts seem to ignore DEBIAN_FRONTEND=noninteractive.
-RUN sudo apt-get update \
- && sudo apt-get install -y \
- tzdata
-
-# Install various tools used by the build or the test suite
-# TODO add ninja-build once 1.11 is available in Ubuntu, also remove the manual
-# installation below.
-RUN sudo apt-get update \
- && sudo apt-get install -y \
- bash \
- ccache \
- curl \
- gdb \
- git \
- gpg \
- language-pack-en \
- language-pack-fr \
- language-pack-ja \
- language-pack-ru \
- language-pack-zh-hans \
- libedit-dev \
- libncurses5-dev \
- libpython3-dev \
- libxml2-dev \
- lsb-release \
- make \
- python3 \
- python3-dev \
- python3-packaging \
- python3-setuptools \
- python3-psutil \
- software-properties-common \
- swig \
- unzip \
- uuid-dev \
- wget \
- xz-utils \
- && sudo rm -rf /var/lib/apt/lists/*
-
-RUN <<EOF
- set -e
- wget -qO /tmp/ninja.gz https://github.com/ninja-build/ninja/releases/latest/download/ninja-linux.zip
- gunzip /tmp/ninja.gz
- chmod a+x /tmp/ninja
- sudo mv /tmp/ninja /usr/local/bin/ninja
-EOF
-
-
-# These two locales are not enabled by default so generate them
-RUN <<EOF
- set -e
- printf "fr_CA ISO-8859-1\ncs_CZ ISO-8859-2" | sudo tee -a /etc/locale.gen
- sudo mkdir /usr/local/share/i1en/
- printf "fr_CA ISO-8859-1\ncs_CZ ISO-8859-2" | sudo tee -a /usr/local/share/i1en/SUPPORTED
- sudo locale-gen
-EOF
-
-# Install Clang <latest>, <latest-1> and ToT, which are the ones we support.
-# We also install <latest-2> because we need to support the "latest-1" of the
-# current LLVM release branch, which is effectively the <latest-2> of the
-# tip-of-trunk LLVM. For example, after branching LLVM 14 but before branching
-# LLVM 15, we still need to have Clang 12 in this Docker image because the LLVM
-# 14 release branch CI uses it. The tip-of-trunk CI will never use Clang 12,
-# though.
-RUN <<EOF
- set -e
- sudo apt-get update
- wget https://apt.llvm.org/llvm.sh -O /tmp/llvm.sh
- chmod +x /tmp/llvm.sh
- sudo /tmp/llvm.sh $(($LLVM_HEAD_VERSION - 3)) all # for CI transitions
- sudo /tmp/llvm.sh $(($LLVM_HEAD_VERSION - 2)) all # previous release
- sudo /tmp/llvm.sh $(($LLVM_HEAD_VERSION - 1)) all # latest release
- sudo /tmp/llvm.sh $LLVM_HEAD_VERSION all # current ToT
- sudo apt-get install -y libomp5-$LLVM_HEAD_VERSION
- sudo rm -rf /var/lib/apt/lists/*
-EOF
-
-# Install the most recent GCC, like clang install the previous version as a transition.
-RUN <<EOF
- set -e
- sudo git clone https://github.com/compiler-explorer/infra.git /tmp/ce-infra
- (cd /tmp/ce-infra && sudo make ce)
- # Current ToT, we do not guarantee any support in our support matrix.
- sudo /tmp/ce-infra/bin/ce_install --enable nightly install compilers/c++/nightly/gcc trunk
- sudo ln -s /opt/compiler-explorer/gcc-snapshot/bin/gcc /usr/bin/gcc-$GCC_HEAD_VERSION
- sudo ln -s /opt/compiler-explorer/gcc-snapshot/bin/g++ /usr/bin/g++-$GCC_HEAD_VERSION
- # The latest release.
- sudo /tmp/ce-infra/bin/ce_install install compilers/c++/x86/gcc $((GCC_HEAD_VERSION - 1)).1.0
- sudo ln -s /opt/compiler-explorer/gcc-$((GCC_HEAD_VERSION - 1)).1.0/bin/gcc /usr/bin/gcc-$((GCC_HEAD_VERSION - 1))
- sudo ln -s /opt/compiler-explorer/gcc-$((GCC_HEAD_VERSION - 1)).1.0/bin/g++ /usr/bin/g++-$((GCC_HEAD_VERSION - 1))
- # For CI transitions.
- sudo /tmp/ce-infra/bin/ce_install install compilers/c++/x86/gcc $((GCC_HEAD_VERSION - 2)).1.0
- sudo ln -s /opt/compiler-explorer/gcc-$((GCC_HEAD_VERSION - 2)).1.0/bin/gcc /usr/bin/gcc-$((GCC_HEAD_VERSION - 2))
- sudo ln -s /opt/compiler-explorer/gcc-$((GCC_HEAD_VERSION - 2)).1.0/bin/g++ /usr/bin/g++-$((GCC_HEAD_VERSION - 2))
- sudo rm -rf /tmp/ce-infra
-EOF
-
-RUN <<EOF
- # Install a recent CMake
- set -e
- wget https://github.com/Kitware/CMake/releases/download/v3.24.4/cmake-3.24.4-linux-x86_64.sh -O /tmp/install-cmake.sh
- sudo bash /tmp/install-cmake.sh --prefix=/usr --exclude-subdir --skip-license
- rm /tmp/install-cmake.sh
-EOF
-
-# ===----------------------------------------------------------------------===##
-# Android Builder Base Image
-# ===----------------------------------------------------------------------===##
-
-FROM docker.io/library/ubuntu:jammy AS android-builder-base
-
-ARG ANDROID_CLANG_VERSION
-ARG ANDROID_CLANG_PREBUILTS_COMMIT
-ARG ANDROID_SYSROOT_COMMIT
-
-RUN apt-get update && apt-get install -y curl bzip2 git unzip
-
-# Install the Android platform tools (e.g. adb) into /opt/android/sdk.
-RUN <<EOF
- set -e
- mkdir -p /opt/android/sdk
- cd /opt/android/sdk
- curl -LO https://dl.google.com/android/repository/platform-tools-latest-linux.zip
- unzip platform-tools-latest-linux.zip
- rm platform-tools-latest-linux.zip
-EOF
-
-# Install the current Android compiler. Specify the prebuilts commit to retrieve
-# this compiler version even after it's removed from HEAD.
-
-ENV ANDROID_CLANG_VERSION=$ANDROID_CLANG_VERSION
-ENV ANDROID_CLANG_PREBUILTS_COMMIT=$ANDROID_CLANG_PREBUILTS_COMMIT
-RUN <<EOF
- set -e
- git clone --filter=blob:none --sparse \
- https://android.googlesource.com/platform/prebuilts/clang/host/linux-x86 \
- /opt/android/clang
- git -C /opt/android/clang checkout ${ANDROID_CLANG_PREBUILTS_COMMIT}
- git -C /opt/android/clang sparse-checkout add clang-${ANDROID_CLANG_VERSION}
- rm -fr /opt/android/clang/.git
- ln -sf /opt/android/clang/clang-${ANDROID_CLANG_VERSION} /opt/android/clang/clang-current
- # The "git sparse-checkout" and "ln" commands succeed even if nothing was
- # checked out, so use this "ls" command to fix that.
- ls /opt/android/clang/clang-current/bin/clang
-EOF
-
-# Install an Android sysroot. New Android sysroots are available at
-# https://android.googlesource.com/platform/prebuilts/ndk/+/refs/heads/mirror-goog-main-ndk/platform/sysroot.
-
-ENV ANDROID_SYSROOT_COMMIT=$ANDROID_SYSROOT_COMMIT
-RUN <<EOF
- set -e
- mkdir -p /opt/android/ndk
- cd /opt/android/ndk
- git clone --filter=blob:none https://android.googlesource.com/platform/prebuilts/ndk tmp
- git -C tmp checkout ${ANDROID_SYSROOT_COMMIT}
- mv tmp/platform/sysroot .
- rm -rf tmp
-EOF
-
-# ===----------------------------------------------------------------------===##
-# Buildkite Builder Image
-# ===----------------------------------------------------------------------===##
-#
-# IMAGE: ghcr.io/libcxx/buildkite-builder.
-#
-FROM builder-base AS buildkite-builder
-
-# Create the libcxx-builder user, regardless of if we use it or not
-RUN sudo useradd --create-home libcxx-builder
-
-USER libcxx-builder
-WORKDIR /home/libcxx-builder
-
-# Install the Buildkite agent and dependencies. This must be done as non-root
-# for the Buildkite agent to be installed in a path where we can find it.
-RUN <<EOF
- set -e
- cd /home/libcxx-builder
- curl -sL https://raw.githubusercontent.com/buildkite/agent/main/install.sh -o /tmp/install-agent.sh
- bash /tmp/install-agent.sh
- rm /tmp/install-agent.sh
- echo "tags=\"queue=libcxx-builders,arch=$(uname -m),os=linux\"" \
- >> /home/libcxx-builder/.buildkite-agent/buildkite-agent.cfg
-EOF
-
-USER libcxx-builder
-WORKDIR /home/libcxx-builder
-
-ENV PATH="${PATH}:/home/libcxx-builder/.buildkite-agent/bin"
-
-CMD ["buildkite-agent", "start"]
-
-# ===----------------------------------------------------------------------===##
-# Android Buildkite Builder Image
-# ===----------------------------------------------------------------------===##
-#
-# IMAGE: ghcr.io/libcxx/android-buildkite-builder.
-#
-FROM buildkite-builder AS android-buildkite-builder
-
-COPY --from=android-builder-base /opt/android /opt/android
-COPY ./vendor/android/container-setup.sh /opt/android/container-setup.sh
-
-ENV PATH="/opt/android/sdk/platform-tools:${PATH}"
-
-USER root
-
-# Install Docker
-RUN <<EOF
- set -e
- curl -fsSL https://get.docker.com -o /tmp/get-docker.sh
- sh /tmp/get-docker.sh
- rm /tmp/get-docker.sh
-
- # Install Docker. Mark the binary setuid so it can be run without prefixing it
- # with sudo. Adding the container user to the docker group doesn't work because
- # /var/run/docker.sock is owned by the host's docker GID, not the container's
- # docker GID.
- chmod u+s /usr/bin/docker
-EOF
-
-USER libcxx-builder
-WORKDIR /home/libcxx-builder
-
-# Reset the configuration, we pass the configuration via the environment.
-RUN cp /home/libcxx-builder/.buildkite-agent/buildkite-agent.dist.cfg \
- /home/libcxx-builder/.buildkite-agent/buildkite-agent.cfg
-
-# Modify the Buildkite agent cmdline to do Android setup stuff first.
-CMD /opt/android/container-setup.sh && buildkite-agent start
-
-# ===----------------------------------------------------------------------===##
-# Github Actions Builder Image
-# ===----------------------------------------------------------------------===##
-#
-# IMAGE: ghcr.io/libcxx/actions-builder.
-#
-FROM $ACTIONS_BASE_IMAGE AS actions-builder
-
-ARG GITHUB_RUNNER_VERSION
-
-RUN useradd gha -u 1001 -m -s /bin/bash
-RUN adduser gha sudo
-RUN echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
-WORKDIR /home/gha
-USER gha
-
-ENV RUNNER_MANUALLY_TRAP_SIG=1
-ENV ACTIONS_RUNNER_PRINT_LOG_TO_STDOUT=1
-RUN mkdir actions-runner && \
- cd actions-runner && \
- curl -O -L https://github.com/actions/runner/releases/download/v$GITHUB_RUNNER_VERSION/actions-runner-linux-x64-$GITHUB_RUNNER_VERSION.tar.gz && \
- tar xzf ./actions-runner-linux-x64-$GITHUB_RUNNER_VERSION.tar.gz && \
- rm ./actions-runner-linux-x64-$GITHUB_RUNNER_VERSION.tar.gz
diff --git a/libcxx/utils/ci/buildkite-pipeline.yml b/libcxx/utils/ci/buildkite-pipeline.yml
index 2ac69c3..1938d9a 100644
--- a/libcxx/utils/ci/buildkite-pipeline.yml
+++ b/libcxx/utils/ci/buildkite-pipeline.yml
@@ -37,6 +37,9 @@ steps:
steps:
- label: AArch64
command: libcxx/utils/ci/run-buildbot aarch64
+ env:
+ CC: cc
+ CXX: c++
agents:
queue: libcxx-builders-linaro-arm
arch: aarch64
@@ -44,6 +47,9 @@ steps:
- label: AArch64 -fno-exceptions
command: libcxx/utils/ci/run-buildbot aarch64-no-exceptions
+ env:
+ CC: cc
+ CXX: c++
agents:
queue: libcxx-builders-linaro-arm
arch: aarch64
@@ -51,6 +57,9 @@ steps:
- label: Armv8
command: libcxx/utils/ci/run-buildbot armv8
+ env:
+ CC: cc
+ CXX: c++
agents:
queue: libcxx-builders-linaro-arm
arch: armv8l
@@ -58,6 +67,9 @@ steps:
- label: Armv8 -fno-exceptions
command: libcxx/utils/ci/run-buildbot armv8-no-exceptions
+ env:
+ CC: cc
+ CXX: c++
agents:
queue: libcxx-builders-linaro-arm
arch: armv8l
@@ -65,6 +77,9 @@ steps:
- label: Armv7
command: libcxx/utils/ci/run-buildbot armv7
+ env:
+ CC: cc
+ CXX: c++
agents:
queue: libcxx-builders-linaro-arm
arch: armv8l
@@ -72,6 +87,9 @@ steps:
- label: Armv7 -fno-exceptions
command: libcxx/utils/ci/run-buildbot armv7-no-exceptions
+ env:
+ CC: cc
+ CXX: c++
agents:
queue: libcxx-builders-linaro-arm
arch: armv8l
@@ -79,6 +97,9 @@ steps:
- label: Armv7-M picolibc
command: libcxx/utils/ci/run-buildbot armv7m-picolibc
+ env:
+ CC: cc
+ CXX: c++
agents:
queue: libcxx-builders-linaro-arm
arch: aarch64
@@ -86,6 +107,9 @@ steps:
- label: Armv7-M picolibc -fno-exceptions
command: libcxx/utils/ci/run-buildbot armv7m-picolibc-no-exceptions
+ env:
+ CC: cc
+ CXX: c++
agents:
queue: libcxx-builders-linaro-arm
arch: aarch64
@@ -131,6 +155,9 @@ steps:
steps:
- label: Android 5.0, x86 NDK
command: libcxx/utils/ci/run-buildbot android-ndk-21-def-x86
+ env:
+ CC: /opt/android/clang/clang-current/bin/clang
+ CXX: /opt/android/clang/clang-current/bin/clang++
agents:
queue: libcxx-builders
os: android
@@ -138,6 +165,9 @@ steps:
- label: Android 13, x86_64 NDK
command: libcxx/utils/ci/run-buildbot android-ndk-33-goog-x86_64
+ env:
+ CC: /opt/android/clang/clang-current/bin/clang
+ CXX: /opt/android/clang/clang-current/bin/clang++
agents:
queue: libcxx-builders
os: android
diff --git a/libcxx/utils/ci/docker-compose.yml b/libcxx/utils/ci/docker-compose.yml
deleted file mode 100644
index 9367a8f..0000000
--- a/libcxx/utils/ci/docker-compose.yml
+++ /dev/null
@@ -1,40 +0,0 @@
-x-versions: &compiler_versions
- GCC_HEAD_VERSION: 16
- LLVM_HEAD_VERSION: 22
-
-x-image-versions: &image_versions
- BASE_IMAGE: docker.io/library/ubuntu:jammy
- ACTIONS_BASE_IMAGE: ghcr.io/llvm/libcxx-linux-builder-base:77cb0980bcc2675b27d08141526939423fa0be76
-
-services:
- builder-base:
- image: ghcr.io/llvm/libcxx-linux-builder-base:${TAG}
- build:
- context: .
- dockerfile: Dockerfile
- target: builder-base
- args:
- <<: [*image_versions, *compiler_versions]
-
- actions-builder:
- image: ghcr.io/llvm/libcxx-linux-builder:${TAG}
- build:
- context: .
- dockerfile: Dockerfile
- target: actions-builder
- args:
- GITHUB_RUNNER_VERSION: "2.329.0"
- <<: [*image_versions, *compiler_versions]
-
- android-buildkite-builder:
- image: ghcr.io/llvm/libcxx-android-builder:${TAG}
- build:
- context: .
- dockerfile: Dockerfile
- target: android-buildkite-builder
- args:
- BASE_IMAGE: docker.io/library/ubuntu:noble
- ANDROID_CLANG_VERSION: r563880
- ANDROID_CLANG_PREBUILTS_COMMIT: 6ae4184bb8706f9731569b9a0a82be3fcdcb951c
- ANDROID_SYSROOT_COMMIT: f8b85cc5262c6e5cbc9a92c1bab2b18b32a4c63f
- <<: [*image_versions, *compiler_versions]
diff --git a/libcxx/utils/ci/docker/android-builder.dockerfile b/libcxx/utils/ci/docker/android-builder.dockerfile
new file mode 100644
index 0000000..9c5d504
--- /dev/null
+++ b/libcxx/utils/ci/docker/android-builder.dockerfile
@@ -0,0 +1,114 @@
+# ===----------------------------------------------------------------------===##
+#
+# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+# See https://llvm.org/LICENSE.txt for license information.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+#
+# ===----------------------------------------------------------------------===##
+#
+# This file defines the image we use to run Android testing on Buildkite.
+# From the root of the monorepo, this image can be built with:
+#
+# $ docker build --file libcxx/utils/ci/docker/android-builder.dockerfile \
+# --build-arg BASE_IMAGE_VERSION=<sha> \
+# --build-arg ANDROID_CLANG_VERSION=<version> \
+# --build-arg ANDROID_CLANG_PREBUILTS_COMMIT=<sha> \
+# --build-arg ANDROID_SYSROOT_COMMIT=<sha> .
+#
+# This image also gets built on every push to `main` that modifies these Docker
+# files, and can be found at ghcr.io/llvm/libcxx-android-builder.
+#
+# To run the image and start a Buildkite Agent, run it as:
+#
+# $ docker run --env-file <secrets> -it ghcr.io/llvm/libcxx-android-builder:latest
+#
+# The environment variables in `<secrets>` should be the ones necessary
+# to run a BuildKite agent:
+#
+# BUILDKITE_AGENT_TOKEN=<token>
+
+ARG BASE_IMAGE_VERSION
+FROM ghcr.io/llvm/libcxx-linux-builder-base:${BASE_IMAGE_VERSION}
+
+ARG ANDROID_CLANG_VERSION
+ARG ANDROID_CLANG_PREBUILTS_COMMIT
+ARG ANDROID_SYSROOT_COMMIT
+
+# Install the Android platform tools (e.g. adb) into /opt/android/sdk.
+RUN <<EOF
+ set -e
+ mkdir -p /opt/android/sdk
+ cd /opt/android/sdk
+ curl -LO https://dl.google.com/android/repository/platform-tools-latest-linux.zip
+ unzip platform-tools-latest-linux.zip
+ rm platform-tools-latest-linux.zip
+EOF
+
+# Install the current Android compiler. Specify the prebuilts commit to retrieve
+# this compiler version even after it's removed from HEAD.
+ENV ANDROID_CLANG_VERSION=$ANDROID_CLANG_VERSION
+ENV ANDROID_CLANG_PREBUILTS_COMMIT=$ANDROID_CLANG_PREBUILTS_COMMIT
+RUN <<EOF
+ set -e
+ git clone --filter=blob:none --sparse \
+ https://android.googlesource.com/platform/prebuilts/clang/host/linux-x86 \
+ /opt/android/clang
+ git -C /opt/android/clang checkout ${ANDROID_CLANG_PREBUILTS_COMMIT}
+ git -C /opt/android/clang sparse-checkout add clang-${ANDROID_CLANG_VERSION}
+ rm -fr /opt/android/clang/.git
+ ln -sf /opt/android/clang/clang-${ANDROID_CLANG_VERSION} /opt/android/clang/clang-current
+ # The "git sparse-checkout" and "ln" commands succeed even if nothing was
+ # checked out, so use this "ls" command to fix that.
+ ls /opt/android/clang/clang-current/bin/clang
+EOF
+
+# Install an Android sysroot. New Android sysroots are available at
+# https://android.googlesource.com/platform/prebuilts/ndk/+/refs/heads/mirror-goog-main-ndk/platform/sysroot.
+ENV ANDROID_SYSROOT_COMMIT=$ANDROID_SYSROOT_COMMIT
+RUN <<EOF
+ set -e
+ mkdir -p /opt/android/ndk
+ cd /opt/android/ndk
+ git clone --filter=blob:none https://android.googlesource.com/platform/prebuilts/ndk tmp
+ git -C tmp checkout ${ANDROID_SYSROOT_COMMIT}
+ mv tmp/platform/sysroot .
+ rm -rf tmp
+EOF
+
+# Create the libcxx-builder user
+RUN sudo useradd --create-home libcxx-builder
+WORKDIR /home/libcxx-builder
+
+# Install the Buildkite agent and dependencies. This must be done as non-root
+# for the Buildkite agent to be installed in a path where we can find it.
+#
+# Note that we don't set up the configuration file here, since the configuration
+# is passed via the environment.
+RUN <<EOF
+ set -e
+ cd /home/libcxx-builder
+ curl -sL https://raw.githubusercontent.com/buildkite/agent/main/install.sh -o /tmp/install-agent.sh
+ bash /tmp/install-agent.sh
+ rm /tmp/install-agent.sh
+EOF
+ENV PATH="${PATH}:/home/libcxx-builder/.buildkite-agent/bin"
+
+# Install Docker
+RUN <<EOF
+ set -e
+ curl -fsSL https://get.docker.com -o /tmp/get-docker.sh
+ sh /tmp/get-docker.sh
+ rm /tmp/get-docker.sh
+
+ # Install Docker. Mark the binary setuid so it can be run without prefixing it
+ # with sudo. Adding the container user to the docker group doesn't work because
+ # /var/run/docker.sock is owned by the host's docker GID, not the container's
+ # docker GID.
+ chmod u+s /usr/bin/docker
+EOF
+
+# Setup the Buildkite agent command line to do Android setup stuff first.
+USER libcxx-builder
+COPY libcxx/utils/ci/vendor/android/container-setup.sh /opt/android/container-setup.sh
+ENV PATH="/opt/android/sdk/platform-tools:${PATH}"
+CMD /opt/android/container-setup.sh && buildkite-agent start
diff --git a/libcxx/utils/ci/docker/docker-compose.yml b/libcxx/utils/ci/docker/docker-compose.yml
new file mode 100644
index 0000000..74df3e49
--- /dev/null
+++ b/libcxx/utils/ci/docker/docker-compose.yml
@@ -0,0 +1,38 @@
+#
+# This docker compose file allows building the various Docker images we use for
+# libc++'s CI. It encodes the versions of various tools included in these images.
+#
+# Images can be built with:
+#
+# $ docker compose --file libcxx/utils/ci/docker/docker-compose.yml build <image-name>
+#
+
+services:
+ libcxx-linux-builder-base:
+ image: ghcr.io/llvm/libcxx-linux-builder-base:${TAG:-latest}
+ build:
+ context: ../../../.. # monorepo root
+ dockerfile: libcxx/utils/ci/docker/linux-builder-base.dockerfile
+ args:
+ GCC_HEAD_VERSION: 16
+ LLVM_HEAD_VERSION: 22
+
+ libcxx-linux-builder:
+ image: ghcr.io/llvm/libcxx-linux-builder:${TAG:-latest}
+ build:
+ context: ../../../.. # monorepo root
+ dockerfile: libcxx/utils/ci/docker/linux-builder.dockerfile
+ args:
+ BASE_IMAGE_VERSION: 825943e06f840710177e5514c4f61c9e73660c44
+ GITHUB_RUNNER_VERSION: 2.329.0
+
+ libcxx-android-builder:
+ image: ghcr.io/llvm/libcxx-android-builder:${TAG:-latest}
+ build:
+ context: ../../../.. # monorepo root
+ dockerfile: libcxx/utils/ci/docker/android-builder.dockerfile
+ args:
+ BASE_IMAGE_VERSION: 825943e06f840710177e5514c4f61c9e73660c44
+ ANDROID_CLANG_VERSION: r563880
+ ANDROID_CLANG_PREBUILTS_COMMIT: 6ae4184bb8706f9731569b9a0a82be3fcdcb951c
+ ANDROID_SYSROOT_COMMIT: f8b85cc5262c6e5cbc9a92c1bab2b18b32a4c63f
diff --git a/libcxx/utils/ci/docker/linux-builder-base.dockerfile b/libcxx/utils/ci/docker/linux-builder-base.dockerfile
new file mode 100644
index 0000000..8a8a6e3
--- /dev/null
+++ b/libcxx/utils/ci/docker/linux-builder-base.dockerfile
@@ -0,0 +1,141 @@
+# ===----------------------------------------------------------------------===##
+#
+# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+# See https://llvm.org/LICENSE.txt for license information.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+#
+# ===----------------------------------------------------------------------===##
+#
+# This file defines the base image we use for Linux testing using Github Actions.
+# From the root of the monorepo, this image can be built with:
+#
+# $ docker build --file libcxx/utils/ci/docker/linux-builder-base.dockerfile \
+# --build-arg GCC_HEAD_VERSION=<version> \
+# --build-arg LLVM_HEAD_VERSION=<version> .
+#
+# This image also gets built on every push to `main` that modifies these Docker
+# files, and can be found at ghcr.io/libcxx/libcxx-linux-builder-base .
+
+FROM docker.io/library/ubuntu:noble
+
+# Changing this file causes a rebuild of the image in a GitHub action. However, it does not cause
+# the CI runners to switch to that image automatically, that must be done by updating the image used
+# by the libc++ self-hosted runners in llvm-zorg. The date uses the ISO format YYYY-MM-DD.
+RUN echo "Last forced update executed on 2025-11-11."
+
+# Make sure apt-get doesn't try to prompt for stuff like our time zone, etc.
+ENV DEBIAN_FRONTEND=noninteractive
+
+# populated in the docker-compose file
+ARG GCC_HEAD_VERSION
+ENV GCC_HEAD_VERSION=${GCC_HEAD_VERSION}
+
+# populated in the docker-compose file
+ARG LLVM_HEAD_VERSION
+ENV LLVM_HEAD_VERSION=${LLVM_HEAD_VERSION}
+
+# Install sudo and setup passwordless sudo.
+RUN <<EOF
+ apt-get update || true
+ apt-get install -y sudo || true
+ echo "ALL ALL = (ALL) NOPASSWD: ALL" | tee /etc/sudoers || true
+EOF
+
+# Installing tzdata before other packages avoids the time zone prompts.
+# These prompts seem to ignore DEBIAN_FRONTEND=noninteractive.
+RUN sudo apt-get update \
+ && sudo apt-get install -y \
+ tzdata
+
+# Install various tools used by the build or the test suite
+# TODO add ninja-build once 1.11 is available in Ubuntu, also remove the manual
+# installation below.
+RUN sudo apt-get update \
+ && sudo apt-get install -y \
+ bash \
+ bzip2 \
+ ccache \
+ curl \
+ gdb \
+ git \
+ gpg \
+ language-pack-en \
+ language-pack-fr \
+ language-pack-ja \
+ language-pack-ru \
+ language-pack-zh-hans \
+ libedit-dev \
+ libncurses5-dev \
+ libpython3-dev \
+ libxml2-dev \
+ lsb-release \
+ make \
+ ninja-build \
+ python3 \
+ python3-dev \
+ python3-packaging \
+ python3-setuptools \
+ python3-psutil \
+ software-properties-common \
+ swig \
+ unzip \
+ uuid-dev \
+ wget \
+ xz-utils \
+ && sudo rm -rf /var/lib/apt/lists/*
+
+# These two locales are not enabled by default so generate them
+RUN <<EOF
+ set -e
+ printf "fr_CA ISO-8859-1\ncs_CZ ISO-8859-2" | sudo tee -a /etc/locale.gen
+ sudo mkdir /usr/local/share/i1en/
+ printf "fr_CA ISO-8859-1\ncs_CZ ISO-8859-2" | sudo tee -a /usr/local/share/i1en/SUPPORTED
+ sudo locale-gen
+EOF
+
+# Install Clang <latest>, <latest-1> and ToT, which are the ones we support.
+# We also install <latest-2> because we need to support the "latest-1" of the
+# current LLVM release branch, which is effectively the <latest-2> of the
+# tip-of-trunk LLVM. For example, after branching LLVM 14 but before branching
+# LLVM 15, we still need to have Clang 12 in this Docker image because the LLVM
+# 14 release branch CI uses it. The tip-of-trunk CI will never use Clang 12,
+# though.
+RUN <<EOF
+ set -e
+ sudo apt-get update
+ wget https://apt.llvm.org/llvm.sh -O /tmp/llvm.sh
+ chmod +x /tmp/llvm.sh
+ sudo /tmp/llvm.sh $(($LLVM_HEAD_VERSION - 3)) all # for CI transitions
+ sudo /tmp/llvm.sh $(($LLVM_HEAD_VERSION - 2)) all # previous release
+ sudo /tmp/llvm.sh $(($LLVM_HEAD_VERSION - 1)) all # latest release
+ sudo /tmp/llvm.sh $LLVM_HEAD_VERSION all # current ToT
+ sudo rm -rf /var/lib/apt/lists/*
+EOF
+
+# Install the most recent GCC, like clang install the previous version as a transition.
+RUN <<EOF
+ set -e
+ sudo git clone https://github.com/compiler-explorer/infra.git /tmp/ce-infra
+ (cd /tmp/ce-infra && sudo make ce)
+ # Current ToT, we do not guarantee any support in our support matrix.
+ sudo /tmp/ce-infra/bin/ce_install --enable nightly install compilers/c++/nightly/gcc trunk
+ sudo ln -s /opt/compiler-explorer/gcc-snapshot/bin/gcc /usr/bin/gcc-$GCC_HEAD_VERSION
+ sudo ln -s /opt/compiler-explorer/gcc-snapshot/bin/g++ /usr/bin/g++-$GCC_HEAD_VERSION
+ # The latest release.
+ sudo /tmp/ce-infra/bin/ce_install install compilers/c++/x86/gcc $((GCC_HEAD_VERSION - 1)).1.0
+ sudo ln -s /opt/compiler-explorer/gcc-$((GCC_HEAD_VERSION - 1)).1.0/bin/gcc /usr/bin/gcc-$((GCC_HEAD_VERSION - 1))
+ sudo ln -s /opt/compiler-explorer/gcc-$((GCC_HEAD_VERSION - 1)).1.0/bin/g++ /usr/bin/g++-$((GCC_HEAD_VERSION - 1))
+ # For CI transitions.
+ sudo /tmp/ce-infra/bin/ce_install install compilers/c++/x86/gcc $((GCC_HEAD_VERSION - 2)).1.0
+ sudo ln -s /opt/compiler-explorer/gcc-$((GCC_HEAD_VERSION - 2)).1.0/bin/gcc /usr/bin/gcc-$((GCC_HEAD_VERSION - 2))
+ sudo ln -s /opt/compiler-explorer/gcc-$((GCC_HEAD_VERSION - 2)).1.0/bin/g++ /usr/bin/g++-$((GCC_HEAD_VERSION - 2))
+ sudo rm -rf /tmp/ce-infra
+EOF
+
+RUN <<EOF
+ # Install a recent CMake
+ set -e
+ wget https://github.com/Kitware/CMake/releases/download/v3.24.4/cmake-3.24.4-linux-x86_64.sh -O /tmp/install-cmake.sh
+ sudo bash /tmp/install-cmake.sh --prefix=/usr --exclude-subdir --skip-license
+ rm /tmp/install-cmake.sh
+EOF
diff --git a/libcxx/utils/ci/docker/linux-builder.dockerfile b/libcxx/utils/ci/docker/linux-builder.dockerfile
new file mode 100644
index 0000000..d6a878b
--- /dev/null
+++ b/libcxx/utils/ci/docker/linux-builder.dockerfile
@@ -0,0 +1,38 @@
+# ===----------------------------------------------------------------------===##
+#
+# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+# See https://llvm.org/LICENSE.txt for license information.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+#
+# ===----------------------------------------------------------------------===##
+#
+# This file defines the image we use for Linux testing using Github Actions.
+# From the root of the monorepo, this image can be built with:
+#
+# $ docker build --file libcxx/utils/ci/docker/linux-builder.dockerfile \
+# --build-arg BASE_IMAGE_VERSION=<sha> \
+# --build-arg GITHUB_RUNNER_VERSION=<version> .
+#
+# This image also gets built on every push to `main` that modifies these Docker
+# files, and can be found at ghcr.io/llvm/libcxx-linux-builder.
+
+ARG BASE_IMAGE_VERSION
+FROM ghcr.io/llvm/libcxx-linux-builder-base:${BASE_IMAGE_VERSION}
+
+ARG GITHUB_RUNNER_VERSION
+
+# Setup the user
+RUN useradd gha -u 1001 -m -s /bin/bash
+RUN adduser gha sudo
+RUN echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
+WORKDIR /home/gha
+USER gha
+
+# Install the Github Actions runner
+ENV RUNNER_MANUALLY_TRAP_SIG=1
+ENV ACTIONS_RUNNER_PRINT_LOG_TO_STDOUT=1
+RUN mkdir actions-runner && \
+ cd actions-runner && \
+ curl -O -L https://github.com/actions/runner/releases/download/v$GITHUB_RUNNER_VERSION/actions-runner-linux-x64-$GITHUB_RUNNER_VERSION.tar.gz && \
+ tar xzf ./actions-runner-linux-x64-$GITHUB_RUNNER_VERSION.tar.gz && \
+ rm ./actions-runner-linux-x64-$GITHUB_RUNNER_VERSION.tar.gz
diff --git a/libcxx/utils/ci/run-buildbot b/libcxx/utils/ci/run-buildbot
index d265ddd..b8ff947 100755
--- a/libcxx/utils/ci/run-buildbot
+++ b/libcxx/utils/ci/run-buildbot
@@ -30,17 +30,41 @@ ${PROGNAME} [options] <BUILDER>
Environment variables
CC The C compiler to use, this value is used by CMake. This
- variable is optional.
+ variable is mandatory.
CXX The C++ compiler to use, this value is used by CMake. This
- variable is optional.
-
-CLANG_FORMAT The clang-format binary to use when generating the format
- ignore list.
+ variable is mandatory.
+CCACHE The ccache binary to use. This variable is optional and is only
+ used by the bootstrapping build.
EOF
}
+function step() {
+ endstep
+ set +x
+ if [[ ! -z ${GITHUB_ACTIONS+x} ]]; then
+ echo "::group::$1"
+ export IN_GROUP=1
+ else
+ echo "--- $1"
+ fi
+ set -x
+}
+
+function endstep() {
+ set +x
+ if [[ ! -z ${GITHUB_ACTIONS+x} ]] && [[ ! -z ${IN_GROUP+x} ]]; then
+ echo "::endgroup::"
+ unset IN_GROUP
+ fi
+ set -x
+}
+
+function error() {
+ echo "::error::$1"
+}
+
if [[ $# == 0 ]]; then
usage
exit 0
@@ -71,30 +95,22 @@ MONOREPO_ROOT="${MONOREPO_ROOT:="$(git rev-parse --show-toplevel)"}"
BUILD_DIR="${BUILD_DIR:=${MONOREPO_ROOT}/build/${BUILDER}}"
INSTALL_DIR="${BUILD_DIR}/install"
-function step() {
- endstep
- set +x
- if [[ ! -z ${GITHUB_ACTIONS+x} ]]; then
- echo "::group::$1"
- export IN_GROUP=1
- else
- echo "--- $1"
- fi
- set -x
-}
+if [ -z ${CC+x} ]; then
+ error "Environment variable CC must be defined"
+ exit 1
+fi
-function endstep() {
- set +x
- if [[ ! -z ${GITHUB_ACTIONS+x} ]] && [[ ! -z ${IN_GROUP+x} ]]; then
- echo "::endgroup::"
- unset IN_GROUP
- fi
- set -x
-}
+if [ -z ${CXX+x} ]; then
+ error "Environment variable CXX must be defined"
+ exit 1
+fi
-function error() {
- echo "::error::$1"
-}
+# Print the version of a few tools to aid diagnostics in some cases
+step "Diagnose tools in use"
+cmake --version
+ninja --version
+${CC} --version
+${CXX} --version
function clean() {
rm -rf "${BUILD_DIR}"
@@ -127,11 +143,7 @@ function generate-cmake() {
}
function generate-cmake-libcxx-win() {
- generate-cmake-base \
- -DLLVM_ENABLE_RUNTIMES="libcxx" \
- -DCMAKE_C_COMPILER=clang-cl \
- -DCMAKE_CXX_COMPILER=clang-cl \
- "${@}"
+ generate-cmake-base -DLLVM_ENABLE_RUNTIMES="libcxx" "${@}"
}
function generate-cmake-android() {
@@ -205,6 +217,7 @@ function test-armv7m-picolibc() {
-DLIBUNWIND_TEST_CONFIG="armv7m-picolibc-libunwind.cfg.in" \
-DCMAKE_C_FLAGS="${flags}" \
-DCMAKE_CXX_FLAGS="${flags}" \
+ -DRUNTIMES_USE_LIBC=picolibc \
"${@}"
step "Installing compiler-rt"
@@ -215,12 +228,6 @@ function test-armv7m-picolibc() {
check-runtimes
}
-# Print the version of a few tools to aid diagnostics in some cases
-step "Diagnose tools in use"
-cmake --version
-ninja --version
-if [ ! -z "${CXX}" ]; then ${CXX} --version; fi
-
case "${BUILDER}" in
check-generated-output)
# `! foo` doesn't work properly with `set -e`, use `! foo || false` instead.
@@ -357,20 +364,25 @@ generic-ubsan)
bootstrapping-build)
clean
+ if [ ! -z ${CCACHE+x} ]; then
+ COMPILER_LAUNCHER="-DCMAKE_CXX_COMPILER_LAUNCHER=${CCACHE}"
+ fi
+
step "Generating CMake"
cmake \
-S "${MONOREPO_ROOT}/llvm" \
-B "${BUILD_DIR}" \
-GNinja \
- -DCMAKE_CXX_COMPILER_LAUNCHER="ccache" \
+ ${COMPILER_LAUNCHER} \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX="${INSTALL_DIR}" \
-DLLVM_ENABLE_PROJECTS="clang;lldb" \
- -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi;libunwind" \
+ -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi;libunwind;compiler-rt" \
-DLLVM_RUNTIME_TARGETS="$(${CXX} --print-target-triple)" \
-DLLVM_HOST_TRIPLE="$(${CXX} --print-target-triple)" \
-DLLVM_TARGETS_TO_BUILD="host" \
-DRUNTIMES_BUILD_ALLOW_DARWIN=ON \
+ -DCOMPILER_RT_INCLUDE_TESTS=OFF \
-DLLVM_ENABLE_ASSERTIONS=ON \
-DLLVM_LIT_ARGS="-sv --xunit-xml-output test-results.xml --timeout=1500 --time-tests"
@@ -689,14 +701,6 @@ mingw-static)
-DLIBUNWIND_ENABLE_SHARED=OFF
check-runtimes
;;
-mingw-dll-i686)
- clean
- generate-cmake \
- -DCMAKE_C_COMPILER=i686-w64-mingw32-clang \
- -DCMAKE_CXX_COMPILER=i686-w64-mingw32-clang++ \
- -C "${MONOREPO_ROOT}/libcxx/cmake/caches/MinGW.cmake"
- check-runtimes
-;;
mingw-incomplete-sysroot)
# When bringing up a new cross compiler from scratch, we build
# libunwind/libcxx in a setup where the toolchain is incomplete and
@@ -741,10 +745,6 @@ android-ndk-*)
fi
ARCH=$(arch_of_emu_img ${ANDROID_EMU_IMG})
- # Use the Android compiler by default.
- export CC=${CC:-/opt/android/clang/clang-current/bin/clang}
- export CXX=${CXX:-/opt/android/clang/clang-current/bin/clang++}
-
# The NDK libc++_shared.so is always built against the oldest supported API
# level. When tests are run against a device with a newer API level, test
# programs can be built for any supported API level, but building for the
diff --git a/libcxx/utils/ci/run-buildbot-container b/libcxx/utils/ci/run-buildbot-container
index 33a00a9c..fa83d1d 100755
--- a/libcxx/utils/ci/run-buildbot-container
+++ b/libcxx/utils/ci/run-buildbot-container
@@ -26,6 +26,6 @@ if [[ ! -d "${MONOREPO_ROOT}/libcxx/utils/ci" ]]; then
echo "Was unable to find the root of the LLVM monorepo; are you running from within the monorepo?"
exit 1
fi
-docker pull ghcr.io/llvm/libcxx-linux-builder:b060022103f551d8ca1dad84122ef73927c86512
-docker run -it --volume "${MONOREPO_ROOT}:/llvm" --workdir "/llvm" --cap-add=SYS_PTRACE ghcr.io/llvm/libcxx-linux-builder:b060022103f551d8ca1dad84122ef73927c86512 \
+docker pull ghcr.io/llvm/libcxx-linux-builder:d6b22a347f813cf4a9832627323a43074f57bbcf
+docker run -it --volume "${MONOREPO_ROOT}:/llvm" --workdir "/llvm" --cap-add=SYS_PTRACE ghcr.io/llvm/libcxx-linux-builder:d6b22a347f813cf4a9832627323a43074f57bbcf \
bash -c 'git config --global --add safe.directory /llvm ; exec bash'
diff --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py
index 22209f5..0802f86 100644
--- a/libcxx/utils/generate_feature_test_macro_components.py
+++ b/libcxx/utils/generate_feature_test_macro_components.py
@@ -14,7 +14,7 @@ from typing import (
)
import functools
import json
-from libcxx.header_information import module_c_headers, module_headers, header_restrictions, headers_not_available, libcxx_root
+from libcxx.header_information import headers_not_available
def get_libcxx_paths():
@@ -1017,6 +1017,7 @@ feature_test_macros = [
"c++17": 201606,
"c++20": 202106, # P2231R1 Missing constexpr in std::optional and std::variant
"c++23": 202110, # P0798R8 Monadic operations for std::optional + LWG3621 Remove feature-test macro __cpp_lib_monadic_optional
+ "c++26": 202506, # P2988R12: std::optional<T&>
},
"headers": ["optional"],
},
diff --git a/libcxx/utils/libcxx/test/config.py b/libcxx/utils/libcxx/test/config.py
index 0840c46..00fab6a 100644
--- a/libcxx/utils/libcxx/test/config.py
+++ b/libcxx/utils/libcxx/test/config.py
@@ -22,6 +22,7 @@ def _appendToSubstitution(substitutions, key, value):
def configure(parameters, features, config, lit_config):
note = lambda s: lit_config.note("({}) {}".format(config.name, s))
+ debug = lambda s: lit_config.dbg("({}) {}".format(config.name, s))
config.environment = dict(os.environ)
# Apply the actions supplied by parameters to the configuration first, since
@@ -31,25 +32,23 @@ def configure(parameters, features, config, lit_config):
actions = param.getActions(config, lit_config.params)
for action in actions:
action.applyTo(config)
- if lit_config.debug:
- note(
- "Applied '{}' as a result of parameter '{}'".format(
- action.pretty(config, lit_config.params),
- param.pretty(config, lit_config.params),
- )
+ debug(
+ "Applied '{}' as a result of parameter '{}'".format(
+ action.pretty(config, lit_config.params),
+ param.pretty(config, lit_config.params),
)
+ )
# Then, apply the automatically-detected features.
for feature in features:
actions = feature.getActions(config)
for action in actions:
action.applyTo(config)
- if lit_config.debug:
- note(
- "Applied '{}' as a result of implicitly detected feature '{}'".format(
- action.pretty(config, lit_config.params), feature.pretty(config)
- )
+ debug(
+ "Applied '{}' as a result of implicitly detected feature '{}'".format(
+ action.pretty(config, lit_config.params), feature.pretty(config)
)
+ )
# Print the basic substitutions
for sub in ("%{cxx}", "%{flags}", "%{compile_flags}", "%{link_flags}", "%{benchmark_flags}", "%{exec}"):
diff --git a/libcxx/utils/libcxx/test/dsl.py b/libcxx/utils/libcxx/test/dsl.py
index 3fb30d8..88fc491 100644
--- a/libcxx/utils/libcxx/test/dsl.py
+++ b/libcxx/utils/libcxx/test/dsl.py
@@ -88,7 +88,7 @@ def _executeWithFakeConfig(test, commands):
litConfig = lit.LitConfig.LitConfig(
progname="lit",
path=[],
- quiet=False,
+ diagnostic_level="note",
useValgrind=False,
valgrindLeakCheck=False,
valgrindArgs=[],
diff --git a/libcxx/utils/libcxx/test/features.py b/libcxx/utils/libcxx/test/features.py
deleted file mode 100644
index 5da1d9a..0000000
--- a/libcxx/utils/libcxx/test/features.py
+++ /dev/null
@@ -1,920 +0,0 @@
-# ===----------------------------------------------------------------------===##
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-#
-# ===----------------------------------------------------------------------===##
-
-from libcxx.test.dsl import *
-from lit.BooleanExpression import BooleanExpression
-import re
-import shutil
-import subprocess
-import sys
-
-_isAnyClang = lambda cfg: "__clang__" in compilerMacros(cfg)
-_isAppleClang = lambda cfg: "__apple_build_version__" in compilerMacros(cfg)
-_isAnyGCC = lambda cfg: "__GNUC__" in compilerMacros(cfg)
-_isClang = lambda cfg: _isAnyClang(cfg) and not _isAppleClang(cfg)
-_isGCC = lambda cfg: _isAnyGCC(cfg) and not _isAnyClang(cfg)
-_isAnyClangOrGCC = lambda cfg: _isAnyClang(cfg) or _isAnyGCC(cfg)
-_isClExe = lambda cfg: not _isAnyClangOrGCC(cfg)
-_isMSVC = lambda cfg: "_MSC_VER" in compilerMacros(cfg)
-_msvcVersion = lambda cfg: (int(compilerMacros(cfg)["_MSC_VER"]) // 100, int(compilerMacros(cfg)["_MSC_VER"]) % 100)
-
-def _getAndroidDeviceApi(cfg):
- return int(
- programOutput(
- cfg,
- r"""
- #include <android/api-level.h>
- #include <stdio.h>
- int main(int, char**) {
- printf("%d\n", android_get_device_api_level());
- return 0;
- }
- """,
- )
- )
-
-
-def _mingwSupportsModules(cfg):
- # Only mingw headers are known to work with libc++ built as a module,
- # at the moment.
- if not "__MINGW32__" in compilerMacros(cfg):
- return False
- # For mingw headers, check for a version known to support being built
- # as a module.
- return sourceBuilds(
- cfg,
- """
- #include <_mingw_mac.h>
- #if __MINGW64_VERSION_MAJOR < 12
- #error Headers known to be incompatible
- #elif __MINGW64_VERSION_MAJOR == 12
- // The headers were fixed to work with libc++ modules during
- // __MINGW64_VERSION_MAJOR == 12. The headers became compatible
- // with libc++ built as a module in
- // 1652e9241b5d8a5a779c6582b1c3c4f4a7cc66e5 (Apr 2024), but the
- // following commit 8c13b28ace68f2c0094d45121d59a4b951b533ed
- // removed the now unused __mingw_static_ovr define. Use this
- // as indicator for whether we've got new enough headers.
- #ifdef __mingw_static_ovr
- #error Headers too old
- #endif
- #else
- // __MINGW64_VERSION_MAJOR > 12 should be ok.
- #endif
- int main(int, char**) { return 0; }
- """,
- )
-
-
-# Lit features are evaluated in order. Some checks may require the compiler detection to have
-# run first in order to work properly.
-DEFAULT_FEATURES = [
- # gcc-style-warnings detects compilers that understand -Wno-meow flags, unlike MSVC's compiler driver cl.exe.
- Feature(name="gcc-style-warnings", when=_isAnyClangOrGCC),
- Feature(name="cl-style-warnings", when=_isClExe),
- Feature(name="apple-clang", when=_isAppleClang),
- Feature(
- name=lambda cfg: "apple-clang-{__clang_major__}".format(**compilerMacros(cfg)),
- when=_isAppleClang,
- ),
- Feature(
- name=lambda cfg: "apple-clang-{__clang_major__}.{__clang_minor__}".format(**compilerMacros(cfg)),
- when=_isAppleClang,
- ),
- Feature(
- name=lambda cfg: "apple-clang-{__clang_major__}.{__clang_minor__}.{__clang_patchlevel__}".format(**compilerMacros(cfg)),
- when=_isAppleClang,
- ),
- Feature(name="clang", when=_isClang),
- Feature(
- name=lambda cfg: "clang-{__clang_major__}".format(**compilerMacros(cfg)),
- when=_isClang,
- ),
- Feature(
- name=lambda cfg: "clang-{__clang_major__}.{__clang_minor__}".format(**compilerMacros(cfg)),
- when=_isClang,
- ),
- Feature(
- name=lambda cfg: "clang-{__clang_major__}.{__clang_minor__}.{__clang_patchlevel__}".format(**compilerMacros(cfg)),
- when=_isClang,
- ),
- # Note: Due to a GCC bug (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104760), we must disable deprecation warnings
- # on GCC or spurious diagnostics are issued.
- #
- # TODO:
- # - Enable -Wplacement-new with GCC.
- # - Enable -Wclass-memaccess with GCC.
- Feature(
- name="gcc",
- when=_isGCC,
- actions=[
- AddCompileFlag("-D_LIBCPP_DISABLE_DEPRECATION_WARNINGS"),
- AddCompileFlag("-Wno-placement-new"),
- AddCompileFlag("-Wno-class-memaccess"),
- AddFeature("GCC-ALWAYS_INLINE-FIXME"),
- ],
- ),
- Feature(
- name=lambda cfg: "gcc-{__GNUC__}".format(**compilerMacros(cfg)), when=_isGCC
- ),
- Feature(
- name=lambda cfg: "gcc-{__GNUC__}.{__GNUC_MINOR__}".format(**compilerMacros(cfg)),
- when=_isGCC,
- ),
- Feature(
- name=lambda cfg: "gcc-{__GNUC__}.{__GNUC_MINOR__}.{__GNUC_PATCHLEVEL__}".format(**compilerMacros(cfg)),
- when=_isGCC,
- ),
- Feature(name="msvc", when=_isMSVC),
- Feature(name=lambda cfg: "msvc-{}".format(*_msvcVersion(cfg)), when=_isMSVC),
- Feature(name=lambda cfg: "msvc-{}.{}".format(*_msvcVersion(cfg)), when=_isMSVC),
-
- Feature(
- name="diagnose-if-support",
- when=lambda cfg: hasCompileFlag(cfg, "-Wuser-defined-warnings"),
- actions=[AddCompileFlag("-Wuser-defined-warnings")],
- ),
- Feature(
- name="character-conversion-warnings",
- when=lambda cfg: hasCompileFlag(cfg, "-Wcharacter-conversion"),
- ),
- # Tests to validate whether the compiler has a way to set the maximum number
- # of steps during constant evaluation. Since the flag differs per compiler
- # store the "valid" flag as a feature. This allows passing the proper compile
- # flag to the compiler:
- # // ADDITIONAL_COMPILE_FLAGS(has-fconstexpr-steps): -fconstexpr-steps=12345678
- # // ADDITIONAL_COMPILE_FLAGS(has-fconstexpr-ops-limit): -fconstexpr-ops-limit=12345678
- Feature(
- name="has-fconstexpr-steps",
- when=lambda cfg: hasCompileFlag(cfg, "-fconstexpr-steps=1"),
- ),
- Feature(
- name="has-fconstexpr-ops-limit",
- when=lambda cfg: hasCompileFlag(cfg, "-fconstexpr-ops-limit=1"),
- ),
- Feature(name="has-fblocks", when=lambda cfg: hasCompileFlag(cfg, "-fblocks")),
- Feature(
- name="fdelayed-template-parsing",
- when=lambda cfg: hasCompileFlag(cfg, "-fdelayed-template-parsing"),
- ),
- Feature(
- name="has-fobjc-arc",
- when=lambda cfg: hasCompileFlag(cfg, "-xobjective-c++ -fobjc-arc")
- and sys.platform.lower().strip() == "darwin",
- ), # TODO: this doesn't handle cross-compiling to Apple platforms.
- Feature(
- name="objective-c++",
- when=lambda cfg: hasCompileFlag(cfg, "-xobjective-c++ -fobjc-arc"),
- ),
- Feature(
- name="verify-support",
- when=lambda cfg: hasCompileFlag(cfg, "-Xclang -verify-ignore-unexpected"),
- ),
- Feature(
- name="add-latomic-workaround", # https://llvm.org/PR73361
- when=lambda cfg: sourceBuilds(
- cfg, "int main(int, char**) { return 0; }", ["-latomic"]
- ),
- actions=[AddLinkFlag("-latomic")],
- ),
- Feature(
- name="has-64-bit-atomics",
- when=lambda cfg: sourceBuilds(
- cfg,
- """
- #include <atomic>
- struct Large { char storage[64/8]; };
- std::atomic<Large> x;
- int main(int, char**) { (void)x.load(); (void)x.is_lock_free(); return 0; }
- """,
- ),
- ),
- Feature(
- name="has-1024-bit-atomics",
- when=lambda cfg: sourceBuilds(
- cfg,
- """
- #include <atomic>
- struct Large { char storage[1024/8]; };
- std::atomic<Large> x;
- int main(int, char**) { (void)x.load(); (void)x.is_lock_free(); return 0; }
- """,
- ),
- ),
- # Tests that require 64-bit architecture
- Feature(
- name="32-bit-pointer",
- when=lambda cfg: sourceBuilds(
- cfg,
- """
- int main(int, char**) {
- static_assert(sizeof(void *) == 4);
- }
- """,
- ),
- ),
- # Check for a Windows UCRT bug (fixed in UCRT/Windows 10.0.20348.0):
- # https://developercommunity.visualstudio.com/t/utf-8-locales-break-ctype-functions-for-wchar-type/1653678
- Feature(
- name="win32-broken-utf8-wchar-ctype",
- when=lambda cfg: not "_LIBCPP_HAS_LOCALIZATION" in compilerMacros(cfg)
- or compilerMacros(cfg)["_LIBCPP_HAS_LOCALIZATION"] == "1"
- and "_WIN32" in compilerMacros(cfg)
- and not programSucceeds(
- cfg,
- """
- #include <locale.h>
- #include <wctype.h>
- int main(int, char**) {
- setlocale(LC_ALL, "en_US.UTF-8");
- return towlower(L'\\xDA') != L'\\xFA';
- }
- """,
- ),
- ),
- # Check for a Windows UCRT bug (fixed in UCRT/Windows 10.0.19041.0).
- # https://developercommunity.visualstudio.com/t/printf-formatting-with-g-outputs-too/1660837
- Feature(
- name="win32-broken-printf-g-precision",
- when=lambda cfg: "_WIN32" in compilerMacros(cfg)
- and not programSucceeds(
- cfg,
- """
- #include <stdio.h>
- #include <string.h>
- int main(int, char**) {
- char buf[100];
- snprintf(buf, sizeof(buf), "%#.*g", 0, 0.0);
- return strcmp(buf, "0.");
- }
- """,
- ),
- ),
- # Check for a Windows UCRT bug (not fixed upstream yet).
- # With UCRT, printf("%a", 0.0) produces "0x0.0000000000000p+0",
- # while other C runtimes produce just "0x0p+0".
- # https://developercommunity.visualstudio.com/t/Printf-formatting-of-float-as-hex-prints/1660844
- Feature(
- name="win32-broken-printf-a-precision",
- when=lambda cfg: "_WIN32" in compilerMacros(cfg)
- and not programSucceeds(
- cfg,
- """
- #include <stdio.h>
- #include <string.h>
- int main(int, char**) {
- char buf[100];
- snprintf(buf, sizeof(buf), "%a", 0.0);
- return strcmp(buf, "0x0p+0");
- }
- """,
- ),
- ),
- # Check for Glibc < 2.27, where the ru_RU.UTF-8 locale had
- # mon_decimal_point == ".", which our tests don't handle.
- Feature(
- name="glibc-old-ru_RU-decimal-point",
- when=lambda cfg: not "_LIBCPP_HAS_LOCALIZATION" in compilerMacros(cfg)
- or compilerMacros(cfg)["_LIBCPP_HAS_LOCALIZATION"] == "1"
- and not programSucceeds(
- cfg,
- """
- #include <locale.h>
- #include <string.h>
- int main(int, char**) {
- setlocale(LC_ALL, "ru_RU.UTF-8");
- return strcmp(localeconv()->mon_decimal_point, ",");
- }
- """,
- ),
- ),
- Feature(
- name="has-unix-headers",
- when=lambda cfg: sourceBuilds(
- cfg,
- """
- #include <unistd.h>
- #include <sys/wait.h>
- int main(int, char**) {
- int fd[2];
- return pipe(fd);
- }
- """,
- ),
- ),
- # Whether Bash can run on the executor.
- # This is not always the case, for example when running on embedded systems.
- #
- # For the corner case of bash existing, but it being missing in the path
- # set in %{exec} as "--env PATH=one-single-dir", the executor does find
- # and executes bash, but bash then can't find any other common shell
- # utilities. Test executing "bash -c 'bash --version'" to see if bash
- # manages to find binaries to execute.
- Feature(
- name="executor-has-no-bash",
- when=lambda cfg: runScriptExitCode(cfg, ["%{exec} bash -c 'bash --version'"]) != 0,
- ),
- # Whether module support for the platform is available.
- Feature(
- name="has-no-cxx-module-support",
- # The libc of these platforms have functions with internal linkage.
- # This is not allowed per C11 7.1.2 Standard headers/6
- # Any declaration of a library function shall have external linkage.
- when=lambda cfg: "__ANDROID__" in compilerMacros(cfg)
- or "__FreeBSD__" in compilerMacros(cfg)
- or ("_WIN32" in compilerMacros(cfg) and not _mingwSupportsModules(cfg))
- or platform.system().lower().startswith("aix")
- # Avoid building on platforms that don't support modules properly.
- or not hasCompileFlag(cfg, "-Wno-reserved-module-identifier")
- # older versions don't support extern "C++", newer versions don't support main in named module.
- or not (
- sourceBuilds(
- cfg,
- """
- export module test;
- extern "C++" int main(int, char**) { return 0; }
- """,
- )
- or sourceBuilds(
- cfg,
- """
- export module test;
- int main(int, char**) { return 0; }
- """,
- )
- ),
- ),
- # The time zone validation tests compare the output of zdump against the
- # output generated by <chrono>'s time zone support.
- Feature(
- name="has-no-zdump",
- when=lambda cfg: runScriptExitCode(cfg, ["zdump --version"]) != 0,
- ),
-]
-
-# Deduce and add the test features that that are implied by the #defines in
-# the <__config> header.
-#
-# For each macro of the form `_LIBCPP_XXX_YYY_ZZZ` defined below that
-# is defined after including <__config>, add a Lit feature called
-# `libcpp-xxx-yyy-zzz`. When a macro is defined to a specific value
-# (e.g. `_LIBCPP_ABI_VERSION=2`), the feature is `libcpp-xxx-yyy-zzz=<value>`.
-#
-# Note that features that are more strongly tied to libc++ are named libcpp-foo,
-# while features that are more general in nature are not prefixed with 'libcpp-'.
-macros = {
- "_LIBCPP_NO_VCRUNTIME": "libcpp-no-vcruntime",
- "_LIBCPP_ABI_VERSION": "libcpp-abi-version",
- "_LIBCPP_ABI_BOUNDED_ITERATORS": "libcpp-has-abi-bounded-iterators",
- "_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STRING": "libcpp-has-abi-bounded-iterators-in-string",
- "_LIBCPP_ABI_BOUNDED_ITERATORS_IN_VECTOR": "libcpp-has-abi-bounded-iterators-in-vector",
- "_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STD_ARRAY": "libcpp-has-abi-bounded-iterators-in-std-array",
- "_LIBCPP_ABI_BOUNDED_UNIQUE_PTR": "libcpp-has-abi-bounded-unique_ptr",
- "_LIBCPP_ABI_FIX_UNORDERED_CONTAINER_SIZE_TYPE": "libcpp-has-abi-fix-unordered-container-size-type",
- "_LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR": "libcpp-deprecated-abi-disable-pair-trivial-copy-ctor",
- "_LIBCPP_ABI_NO_COMPRESSED_PAIR_PADDING": "libcpp-abi-no-compressed-pair-padding",
- "_LIBCPP_PSTL_BACKEND_LIBDISPATCH": "libcpp-pstl-backend-libdispatch",
-}
-for macro, feature in macros.items():
- DEFAULT_FEATURES.append(
- Feature(
- name=lambda cfg, m=macro, f=feature: f + ("={}".format(compilerMacros(cfg)[m]) if compilerMacros(cfg)[m] else ""),
- when=lambda cfg, m=macro: m in compilerMacros(cfg),
- )
- )
-
-true_false_macros = {
- "_LIBCPP_HAS_THREAD_API_EXTERNAL": "libcpp-has-thread-api-external",
- "_LIBCPP_HAS_THREAD_API_PTHREAD": "libcpp-has-thread-api-pthread",
-}
-for macro, feature in true_false_macros.items():
- DEFAULT_FEATURES.append(
- Feature(
- name=feature,
- when=lambda cfg, m=macro: m in compilerMacros(cfg)
- and compilerMacros(cfg)[m] == "1",
- )
- )
-
-inverted_macros = {
- "_LIBCPP_HAS_TIME_ZONE_DATABASE": "no-tzdb",
- "_LIBCPP_HAS_FILESYSTEM": "no-filesystem",
- "_LIBCPP_HAS_LOCALIZATION": "no-localization",
- "_LIBCPP_HAS_THREADS": "no-threads",
- "_LIBCPP_HAS_MONOTONIC_CLOCK": "no-monotonic-clock",
- "_LIBCPP_HAS_WIDE_CHARACTERS": "no-wide-characters",
- "_LIBCPP_HAS_VENDOR_AVAILABILITY_ANNOTATIONS": "libcpp-has-no-availability-markup",
- "_LIBCPP_HAS_RANDOM_DEVICE": "no-random-device",
- "_LIBCPP_HAS_UNICODE": "libcpp-has-no-unicode",
- "_LIBCPP_HAS_TERMINAL": "no-terminal",
-}
-for macro, feature in inverted_macros.items():
- DEFAULT_FEATURES.append(
- Feature(
- name=feature,
- when=lambda cfg, m=macro: m in compilerMacros(cfg)
- and compilerMacros(cfg)[m] == "0",
- )
- )
-
-# Mapping from canonical locale names (used in the tests) to possible locale
-# names on various systems. Each locale is considered supported if any of the
-# alternative names is supported.
-locales = {
- "en_US.UTF-8": ["en_US.UTF-8", "en_US.utf8", "English_United States.1252"],
- "fr_FR.UTF-8": ["fr_FR.UTF-8", "fr_FR.utf8", "French_France.1252"],
- "ja_JP.UTF-8": ["ja_JP.UTF-8", "ja_JP.utf8", "Japanese_Japan.923"],
- "ru_RU.UTF-8": ["ru_RU.UTF-8", "ru_RU.utf8", "Russian_Russia.1251"],
- "zh_CN.UTF-8": ["zh_CN.UTF-8", "zh_CN.utf8", "Chinese_China.936"],
- "fr_CA.ISO8859-1": ["fr_CA.ISO8859-1", "French_Canada.1252"],
- "cs_CZ.ISO8859-2": ["cs_CZ.ISO8859-2", "Czech_Czech Republic.1250"],
-}
-provide_locale_conversions = {
- "fr_FR.UTF-8": ["decimal_point", "mon_thousands_sep", "thousands_sep"],
- "ru_RU.UTF-8": ["mon_thousands_sep"],
-}
-for locale, alts in locales.items():
- # Note: Using alts directly in the lambda body here will bind it to the value at the
- # end of the loop. Assigning it to a default argument works around this issue.
- DEFAULT_FEATURES.append(
- Feature(
- name="locale.{}".format(locale),
- when=lambda cfg, alts=alts: hasAnyLocale(cfg, alts),
- actions=lambda cfg, locale=locale, alts=alts: _getLocaleFlagsAction(
- cfg, locale, alts, provide_locale_conversions[locale]
- )
- if locale in provide_locale_conversions
- and ("_LIBCPP_HAS_WIDE_CHARACTERS" not in compilerMacros(cfg) or
- compilerMacros(cfg)["_LIBCPP_HAS_WIDE_CHARACTERS"] == "1")
- else [],
- ),
- )
-
-
-# Provide environment locale conversions through substitutions to avoid platform specific
-# maintenance.
-def _getLocaleFlagsAction(cfg, locale, alts, members):
- alts_list = ",".join([f'"{l}"' for l in alts])
- get_member_list = ",".join([f"lc->{m}" for m in members])
-
- localeconv_info = programOutput(
- cfg,
- r"""
- #if defined(_WIN32) && !defined(_CRT_SECURE_NO_WARNINGS)
- #define _CRT_SECURE_NO_WARNINGS
- #endif
- #include <stdio.h>
- #include <locale.h>
- #include <stdlib.h>
- #include <wchar.h>
-
- // Print each requested locale conversion member on separate lines.
- int main(int, char**) {
- const char* locales[] = { %s };
- for (int loc_i = 0; loc_i < %d; ++loc_i) {
- if (!setlocale(LC_ALL, locales[loc_i])) {
- continue; // Choose first locale name that is recognized.
- }
-
- lconv* lc = localeconv();
- const char* members[] = { %s };
- for (size_t m_i = 0; m_i < %d; ++m_i) {
- if (!members[m_i]) {
- printf("\n"); // member value is an empty string
- continue;
- }
-
- size_t len = mbstowcs(nullptr, members[m_i], 0);
- if (len == static_cast<size_t>(-1)) {
- fprintf(stderr, "mbstowcs failed unexpectedly\n");
- return 1;
- }
- // Include room for null terminator. Use malloc as these features
- // are also used by lit configs that don't use -lc++ (libunwind tests).
- wchar_t* dst = (wchar_t*)malloc((len + 1) * sizeof(wchar_t));
- size_t ret = mbstowcs(dst, members[m_i], len + 1);
- if (ret == static_cast<size_t>(-1)) {
- fprintf(stderr, "mbstowcs failed unexpectedly\n");
- free(dst);
- return 1;
- }
-
- for (size_t i = 0; i < len; ++i) {
- if (dst[i] > 0x7F) {
- printf("\\u%%04x", dst[i]);
- } else {
- // c++03 does not allow basic ascii-range characters in UCNs
- printf("%%c", (char)dst[i]);
- }
- }
- printf("\n");
- free(dst);
- }
- return 0;
- }
-
- return 1;
- }
- """
- % (alts_list, len(alts), get_member_list, len(members)),
- )
- valid_define_name = re.sub(r"[.-]", "_", locale).upper()
- return [
- # Provide locale conversion through a substitution.
- # Example: %{LOCALE_CONV_FR_FR_UTF_8_THOUSANDS_SEP} = L"\u202f"
- AddSubstitution(
- f"%{{LOCALE_CONV_{valid_define_name}_{member.upper()}}}",
- lambda cfg, value=value: f"'L\"{value}\"'",
- )
- for member, value in zip(members, localeconv_info.split("\n"))
- ]
-
-
-# Add features representing the target platform name: darwin, linux, windows, etc...
-DEFAULT_FEATURES += [
- Feature(name="darwin", when=lambda cfg: "__APPLE__" in compilerMacros(cfg)),
- Feature(name="windows", when=lambda cfg: "_WIN32" in compilerMacros(cfg)),
- Feature(
- name="windows-dll",
- when=lambda cfg: "_WIN32" in compilerMacros(cfg)
- and sourceBuilds(
- cfg,
- """
- #include <iostream>
- int main(int, char**) { return 0; }
- """,
- )
- and programSucceeds(
- cfg,
- """
- #include <iostream>
- #include <windows.h>
- #include <winnt.h>
- int main(int, char**) {
- // Get a pointer to a data member that gets linked from the C++
- // library. This must be a data member (functions can get
- // thunk inside the calling executable), and must not be
- // something that is defined inline in headers.
- void *ptr = &std::cout;
- // Get a handle to the current main executable.
- void *exe = GetModuleHandle(NULL);
- // The handle points at the PE image header. Navigate through
- // the header structure to find the size of the PE image (the
- // executable).
- PIMAGE_DOS_HEADER dosheader = (PIMAGE_DOS_HEADER)exe;
- PIMAGE_NT_HEADERS ntheader = (PIMAGE_NT_HEADERS)((BYTE *)dosheader + dosheader->e_lfanew);
- PIMAGE_OPTIONAL_HEADER peheader = &ntheader->OptionalHeader;
- void *exeend = (BYTE*)exe + peheader->SizeOfImage;
- // Check if the tested pointer - the data symbol from the
- // C++ library - is located within the exe.
- if (ptr >= exe && ptr <= exeend)
- return 1;
- // Return success if it was outside of the executable, i.e.
- // loaded from a DLL.
- return 0;
- }
- """,
- ),
- actions=[AddCompileFlag("-DTEST_WINDOWS_DLL")],
- ),
- Feature(name="linux", when=lambda cfg: "__linux__" in compilerMacros(cfg)),
- Feature(name="android", when=lambda cfg: "__ANDROID__" in compilerMacros(cfg)),
- Feature(
- name=lambda cfg: "android-device-api={}".format(_getAndroidDeviceApi(cfg)),
- when=lambda cfg: "__ANDROID__" in compilerMacros(cfg),
- ),
- Feature(
- name="LIBCXX-ANDROID-FIXME",
- when=lambda cfg: "__ANDROID__" in compilerMacros(cfg),
- ),
- Feature(name="netbsd", when=lambda cfg: "__NetBSD__" in compilerMacros(cfg)),
- Feature(name="freebsd", when=lambda cfg: "__FreeBSD__" in compilerMacros(cfg)),
- Feature(
- name="LIBCXX-FREEBSD-FIXME",
- when=lambda cfg: "__FreeBSD__" in compilerMacros(cfg),
- ),
- Feature(
- name="LIBCXX-PICOLIBC-FIXME",
- when=lambda cfg: sourceBuilds(
- cfg,
- """
- #include <string.h>
- #ifndef __PICOLIBC__
- #error not picolibc
- #endif
- int main(int, char**) { return 0; }
- """,
- ),
- ),
- Feature(
- name="LIBCXX-AMDGPU-FIXME",
- when=lambda cfg: "__AMDGPU__" in compilerMacros(cfg),
- ),
- Feature(
- name="LIBCXX-NVPTX-FIXME",
- when=lambda cfg: "__NVPTX__" in compilerMacros(cfg),
- ),
- Feature(
- name="can-create-symlinks",
- when=lambda cfg: "_WIN32" not in compilerMacros(cfg)
- or programSucceeds(
- cfg,
- # Creation of symlinks require elevated privileges on Windows unless
- # Windows developer mode is enabled.
- """
- #include <stdio.h>
- #include <windows.h>
- int main(int, char**) {
- CHAR tempDirPath[MAX_PATH];
- DWORD tempPathRet = GetTempPathA(MAX_PATH, tempDirPath);
- if (tempPathRet == 0 || tempPathRet > MAX_PATH) {
- return 1;
- }
-
- CHAR tempFilePath[MAX_PATH];
- UINT uRetVal = GetTempFileNameA(
- tempDirPath,
- "cxx", // Prefix
- 0, // Unique=0 also implies file creation.
- tempFilePath);
- if (uRetVal == 0) {
- return 1;
- }
-
- CHAR symlinkFilePath[MAX_PATH];
- int ret = sprintf_s(symlinkFilePath, MAX_PATH, "%s_symlink", tempFilePath);
- if (ret == -1) {
- DeleteFileA(tempFilePath);
- return 1;
- }
-
- // Requires either administrator, or developer mode enabled.
- BOOL bCreatedSymlink = CreateSymbolicLinkA(symlinkFilePath,
- tempFilePath,
- SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE);
- if (!bCreatedSymlink) {
- DeleteFileA(tempFilePath);
- return 1;
- }
-
- DeleteFileA(tempFilePath);
- DeleteFileA(symlinkFilePath);
- return 0;
- }
- """,
- ),
- ),
-]
-
-# Add features representing the build host platform name.
-# The build host could differ from the target platform for cross-compilation.
-DEFAULT_FEATURES += [
- Feature(name="buildhost={}".format(sys.platform.lower().strip())),
- # sys.platform can often be represented by a "sub-system", such as 'win32', 'cygwin', 'mingw', freebsd13 & etc.
- # We define a consolidated feature on a few platforms.
- Feature(
- name="buildhost=windows",
- when=lambda cfg: platform.system().lower().startswith("windows"),
- ),
- Feature(
- name="buildhost=freebsd",
- when=lambda cfg: platform.system().lower().startswith("freebsd"),
- ),
- Feature(
- name="buildhost=aix",
- when=lambda cfg: platform.system().lower().startswith("aix"),
- ),
-]
-
-# Detect whether GDB is on the system, has Python scripting and supports
-# adding breakpoint commands. If so add a substitution to access it.
-def check_gdb(cfg):
- gdb_path = shutil.which("gdb")
- if gdb_path is None:
- return False
-
- # Check that we can set breakpoint commands, which was added in 8.3.
- # Using the quit command here means that gdb itself exits, not just
- # the "python <...>" command.
- test_src = """\
-try:
- gdb.Breakpoint(\"main\").commands=\"foo\"
-except AttributeError:
- gdb.execute(\"quit 1\")
-gdb.execute(\"quit\")"""
-
- try:
- stdout = subprocess.check_output(
- [gdb_path, "-ex", "python " + test_src, "--batch"],
- stderr=subprocess.DEVNULL,
- universal_newlines=True,
- )
- except subprocess.CalledProcessError:
- # We can't set breakpoint commands
- return False
-
- # Check we actually ran the Python
- return not "Python scripting is not supported" in stdout
-
-
-DEFAULT_FEATURES += [
- Feature(
- name="host-has-gdb-with-python",
- when=check_gdb,
- actions=[AddSubstitution("%{gdb}", lambda cfg: shutil.which("gdb"))],
- )
-]
-
-# Helpers to define correspondances between LLVM versions and vendor system versions.
-# Those are used for backdeployment features below, do not use directly in tests.
-DEFAULT_FEATURES += [
- Feature(
- name="_target-has-llvm-22",
- when=lambda cfg: BooleanExpression.evaluate(
- "TBD",
- cfg.available_features,
- ),
- ),
- Feature(
- name="_target-has-llvm-21",
- when=lambda cfg: BooleanExpression.evaluate(
- "TBD",
- cfg.available_features,
- ),
- ),
- Feature(
- name="_target-has-llvm-20",
- when=lambda cfg: BooleanExpression.evaluate(
- "_target-has-llvm-21 || target={{.+}}-apple-macosx{{26.[0-9](.\d+)?}}",
- cfg.available_features,
- ),
- ),
- Feature(
- name="_target-has-llvm-19",
- when=lambda cfg: BooleanExpression.evaluate(
- "_target-has-llvm-20 || target={{.+}}-apple-macosx{{15.[4-9](.\d+)?}}",
- cfg.available_features,
- ),
- ),
- Feature(
- name="_target-has-llvm-18",
- when=lambda cfg: BooleanExpression.evaluate(
- "_target-has-llvm-19 || target={{.+}}-apple-macosx{{15.[0-3](.\d+)?}}",
- cfg.available_features,
- ),
- ),
- Feature(
- name="_target-has-llvm-17",
- when=lambda cfg: BooleanExpression.evaluate(
- "_target-has-llvm-18 || target={{.+}}-apple-macosx{{14.[4-9](.\d+)?}}",
- cfg.available_features,
- ),
- ),
- Feature(
- name="_target-has-llvm-16",
- when=lambda cfg: BooleanExpression.evaluate(
- "_target-has-llvm-17 || target={{.+}}-apple-macosx{{14.[0-3](.[0-9]+)?}}",
- cfg.available_features,
- ),
- ),
- Feature(
- name="_target-has-llvm-15",
- when=lambda cfg: BooleanExpression.evaluate(
- "_target-has-llvm-16 || target={{.+}}-apple-macosx{{13.[4-9](.[0-9]+)?}}",
- cfg.available_features,
- ),
- ),
- Feature(
- name="_target-has-llvm-14",
- when=lambda cfg: BooleanExpression.evaluate(
- "_target-has-llvm-15",
- cfg.available_features,
- ),
- ),
- Feature(
- name="_target-has-llvm-13",
- when=lambda cfg: BooleanExpression.evaluate(
- "_target-has-llvm-14 || target={{.+}}-apple-macosx{{13.[0-3](.[0-9]+)?}}",
- cfg.available_features,
- ),
- ),
- Feature(
- name="_target-has-llvm-12",
- when=lambda cfg: BooleanExpression.evaluate(
- "_target-has-llvm-13 || target={{.+}}-apple-macosx{{12.[3-9](.[0-9]+)?}}",
- cfg.available_features,
- ),
- ),
-]
-
-# Define features for back-deployment testing.
-#
-# These features can be used to XFAIL tests that fail when deployed on (or compiled
-# for) an older system. For example, if a test exhibits a bug in the libc++ on a
-# particular system version, or if it uses a symbol that is not available on an
-# older version of the dylib, it can be marked as XFAIL with these features.
-#
-# We have two families of Lit features:
-#
-# The first one is `using-built-library-before-llvm-XYZ`. These features encode the
-# fact that the test suite is being *run* against a version of the shared/static library
-# that predates LLVM version XYZ. This is useful to represent the use case of compiling
-# a program against the latest libc++ but then deploying it and running it on an older
-# system with an older version of the (usually shared) library.
-#
-# This feature is built up using the target triple passed to the compiler and the
-# `stdlib=system` Lit feature, which encodes that we're running against the same library
-# as described by the target triple.
-#
-# The second set of features is `availability-<FEATURE>-missing`. This family of Lit
-# features encodes the presence of availability markup in the libc++ headers. This is
-# useful to check that a test fails specifically when compiled for a given deployment
-# target, such as when testing availability markup where we want to make sure that
-# using the annotated facility on a deployment target that doesn't support it will fail
-# at compile time. This can be achieved by creating a `.verify.cpp` test that checks for
-# the right errors and marking the test as `REQUIRES: availability-<FEATURE>-missing`.
-#
-# This feature is built up using the presence of availability markup detected inside
-# __config, the flavor of the library being tested and the target triple passed to the
-# compiler.
-#
-# Note that both families of Lit features are similar but different in important ways.
-# For example, tests for availability markup should be expected to produce diagnostics
-# regardless of whether we're running against a system library, as long as we're using
-# a libc++ flavor that enables availability markup. Similarly, a test could fail when
-# run against the system library of an older version of FreeBSD, even though FreeBSD
-# doesn't provide availability markup at the time of writing this.
-for version in ("12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22"):
- DEFAULT_FEATURES.append(
- Feature(
- name="using-built-library-before-llvm-{}".format(version),
- when=lambda cfg, v=version: BooleanExpression.evaluate(
- "stdlib=system && !_target-has-llvm-{}".format(v),
- cfg.available_features,
- ),
- )
- )
-
-DEFAULT_FEATURES += [
- # Tests that require https://wg21.link/P0482 support in the built library
- Feature(
- name="availability-char8_t_support-missing",
- when=lambda cfg: BooleanExpression.evaluate(
- "!libcpp-has-no-availability-markup && (stdlib=apple-libc++ && !_target-has-llvm-12)",
- cfg.available_features,
- ),
- ),
- # Tests that require std::to_chars(floating-point) in the built library
- Feature(
- name="availability-fp_to_chars-missing",
- when=lambda cfg: BooleanExpression.evaluate(
- "!libcpp-has-no-availability-markup && (stdlib=apple-libc++ && !_target-has-llvm-14)",
- cfg.available_features,
- ),
- ),
- # Tests that require __libcpp_verbose_abort support in the built library
- Feature(
- name="availability-verbose_abort-missing",
- when=lambda cfg: BooleanExpression.evaluate(
- "!libcpp-has-no-availability-markup && (stdlib=apple-libc++ && !_target-has-llvm-15)",
- cfg.available_features,
- ),
- ),
- # Tests that require std::pmr support in the built library
- Feature(
- name="availability-pmr-missing",
- when=lambda cfg: BooleanExpression.evaluate(
- "!libcpp-has-no-availability-markup && (stdlib=apple-libc++ && !_target-has-llvm-16)",
- cfg.available_features,
- ),
- ),
- # Tests that require support for <print> and std::print in <ostream> in the built library.
- Feature(
- name="availability-print-missing",
- when=lambda cfg: BooleanExpression.evaluate(
- "!libcpp-has-no-availability-markup && (stdlib=apple-libc++ && !_target-has-llvm-18)",
- cfg.available_features,
- ),
- ),
- # Tests that require time zone database support in the built library
- Feature(
- name="availability-tzdb-missing",
- when=lambda cfg: BooleanExpression.evaluate(
- "!libcpp-has-no-availability-markup && (stdlib=apple-libc++ && !_target-has-llvm-19)",
- cfg.available_features,
- ),
- ),
- # Tests that require std::from_chars(floating-point) in the built library
- Feature(
- name="availability-fp_from_chars-missing",
- when=lambda cfg: BooleanExpression.evaluate(
- "!libcpp-has-no-availability-markup && (stdlib=apple-libc++ && !_target-has-llvm-20)",
- cfg.available_features,
- ),
- ),
-]
diff --git a/libcxx/utils/libcxx/test/features/__init__.py b/libcxx/utils/libcxx/test/features/__init__.py
new file mode 100644
index 0000000..5c0d1f3
--- /dev/null
+++ b/libcxx/utils/libcxx/test/features/__init__.py
@@ -0,0 +1,21 @@
+# ===----------------------------------------------------------------------===##
+#
+# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+# See https://llvm.org/LICENSE.txt for license information.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+#
+# ===----------------------------------------------------------------------===##
+
+from . import availability, compiler, gdb, libcxx_macros, localization, misc, platform
+
+# Lit features are evaluated in order. Some features depend on other features, so
+# we are careful to define them in the correct order. For example, several features
+# require the compiler detection to have been performed.
+DEFAULT_FEATURES = []
+DEFAULT_FEATURES += compiler.features
+DEFAULT_FEATURES += libcxx_macros.features
+DEFAULT_FEATURES += platform.features
+DEFAULT_FEATURES += localization.features
+DEFAULT_FEATURES += gdb.features
+DEFAULT_FEATURES += misc.features
+DEFAULT_FEATURES += availability.features
diff --git a/libcxx/utils/libcxx/test/features/availability.py b/libcxx/utils/libcxx/test/features/availability.py
new file mode 100644
index 0000000..39c6cf4
--- /dev/null
+++ b/libcxx/utils/libcxx/test/features/availability.py
@@ -0,0 +1,199 @@
+# ===----------------------------------------------------------------------===##
+#
+# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+# See https://llvm.org/LICENSE.txt for license information.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+#
+# ===----------------------------------------------------------------------===##
+
+from libcxx.test.dsl import Feature
+from lit.BooleanExpression import BooleanExpression
+
+# Helpers to define correspondances between LLVM versions and vendor system versions.
+# Those are used for backdeployment features below, do not use directly in tests.
+features = [
+ Feature(
+ name="_target-has-llvm-22",
+ when=lambda cfg: BooleanExpression.evaluate(
+ "TBD",
+ cfg.available_features,
+ ),
+ ),
+ Feature(
+ name="_target-has-llvm-21",
+ when=lambda cfg: BooleanExpression.evaluate(
+ "TBD",
+ cfg.available_features,
+ ),
+ ),
+ Feature(
+ name="_target-has-llvm-20",
+ when=lambda cfg: BooleanExpression.evaluate(
+ r"_target-has-llvm-21 || target={{.+}}-apple-macosx{{26.[0-9](.\d+)?}}",
+ cfg.available_features,
+ ),
+ ),
+ Feature(
+ name="_target-has-llvm-19",
+ when=lambda cfg: BooleanExpression.evaluate(
+ r"_target-has-llvm-20 || target={{.+}}-apple-macosx{{15.[4-9](.\d+)?}}",
+ cfg.available_features,
+ ),
+ ),
+ Feature(
+ name="_target-has-llvm-18",
+ when=lambda cfg: BooleanExpression.evaluate(
+ r"_target-has-llvm-19 || target={{.+}}-apple-macosx{{15.[0-3](.\d+)?}}",
+ cfg.available_features,
+ ),
+ ),
+ Feature(
+ name="_target-has-llvm-17",
+ when=lambda cfg: BooleanExpression.evaluate(
+ r"_target-has-llvm-18 || target={{.+}}-apple-macosx{{14.[4-9](.\d+)?}}",
+ cfg.available_features,
+ ),
+ ),
+ Feature(
+ name="_target-has-llvm-16",
+ when=lambda cfg: BooleanExpression.evaluate(
+ "_target-has-llvm-17 || target={{.+}}-apple-macosx{{14.[0-3](.[0-9]+)?}}",
+ cfg.available_features,
+ ),
+ ),
+ Feature(
+ name="_target-has-llvm-15",
+ when=lambda cfg: BooleanExpression.evaluate(
+ "_target-has-llvm-16 || target={{.+}}-apple-macosx{{13.[4-9](.[0-9]+)?}}",
+ cfg.available_features,
+ ),
+ ),
+ Feature(
+ name="_target-has-llvm-14",
+ when=lambda cfg: BooleanExpression.evaluate(
+ "_target-has-llvm-15",
+ cfg.available_features,
+ ),
+ ),
+ Feature(
+ name="_target-has-llvm-13",
+ when=lambda cfg: BooleanExpression.evaluate(
+ "_target-has-llvm-14 || target={{.+}}-apple-macosx{{13.[0-3](.[0-9]+)?}}",
+ cfg.available_features,
+ ),
+ ),
+ Feature(
+ name="_target-has-llvm-12",
+ when=lambda cfg: BooleanExpression.evaluate(
+ "_target-has-llvm-13 || target={{.+}}-apple-macosx{{12.[3-9](.[0-9]+)?}}",
+ cfg.available_features,
+ ),
+ ),
+]
+
+# Define features for back-deployment testing.
+#
+# These features can be used to XFAIL tests that fail when deployed on (or compiled
+# for) an older system. For example, if a test exhibits a bug in the libc++ on a
+# particular system version, or if it uses a symbol that is not available on an
+# older version of the dylib, it can be marked as XFAIL with these features.
+#
+# We have two families of Lit features:
+#
+# The first one is `using-built-library-before-llvm-XYZ`. These features encode the
+# fact that the test suite is being *run* against a version of the shared/static library
+# that predates LLVM version XYZ. This is useful to represent the use case of compiling
+# a program against the latest libc++ but then deploying it and running it on an older
+# system with an older version of the (usually shared) library.
+#
+# This feature is built up using the target triple passed to the compiler and the
+# `stdlib=system` Lit feature, which encodes that we're running against the same library
+# as described by the target triple.
+#
+# The second set of features is `availability-<FEATURE>-missing`. This family of Lit
+# features encodes the presence of availability markup in the libc++ headers. This is
+# useful to check that a test fails specifically when compiled for a given deployment
+# target, such as when testing availability markup where we want to make sure that
+# using the annotated facility on a deployment target that doesn't support it will fail
+# at compile time. This can be achieved by creating a `.verify.cpp` test that checks for
+# the right errors and marking the test as `REQUIRES: availability-<FEATURE>-missing`.
+#
+# This feature is built up using the presence of availability markup detected inside
+# __config, the flavor of the library being tested and the target triple passed to the
+# compiler.
+#
+# Note that both families of Lit features are similar but different in important ways.
+# For example, tests for availability markup should be expected to produce diagnostics
+# regardless of whether we're running against a system library, as long as we're using
+# a libc++ flavor that enables availability markup. Similarly, a test could fail when
+# run against the system library of an older version of FreeBSD, even though FreeBSD
+# doesn't provide availability markup at the time of writing this.
+for version in ("12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22"):
+ features.append(
+ Feature(
+ name="using-built-library-before-llvm-{}".format(version),
+ when=lambda cfg, v=version: BooleanExpression.evaluate(
+ "stdlib=system && !_target-has-llvm-{}".format(v),
+ cfg.available_features,
+ ),
+ )
+ )
+
+features += [
+ # Tests that require https://wg21.link/P0482 support in the built library
+ Feature(
+ name="availability-char8_t_support-missing",
+ when=lambda cfg: BooleanExpression.evaluate(
+ "!libcpp-has-no-availability-markup && (stdlib=apple-libc++ && !_target-has-llvm-12)",
+ cfg.available_features,
+ ),
+ ),
+ # Tests that require std::to_chars(floating-point) in the built library
+ Feature(
+ name="availability-fp_to_chars-missing",
+ when=lambda cfg: BooleanExpression.evaluate(
+ "!libcpp-has-no-availability-markup && (stdlib=apple-libc++ && !_target-has-llvm-14)",
+ cfg.available_features,
+ ),
+ ),
+ # Tests that require __libcpp_verbose_abort support in the built library
+ Feature(
+ name="availability-verbose_abort-missing",
+ when=lambda cfg: BooleanExpression.evaluate(
+ "!libcpp-has-no-availability-markup && (stdlib=apple-libc++ && !_target-has-llvm-15)",
+ cfg.available_features,
+ ),
+ ),
+ # Tests that require std::pmr support in the built library
+ Feature(
+ name="availability-pmr-missing",
+ when=lambda cfg: BooleanExpression.evaluate(
+ "!libcpp-has-no-availability-markup && (stdlib=apple-libc++ && !_target-has-llvm-16)",
+ cfg.available_features,
+ ),
+ ),
+ # Tests that require support for <print> and std::print in <ostream> in the built library.
+ Feature(
+ name="availability-print-missing",
+ when=lambda cfg: BooleanExpression.evaluate(
+ "!libcpp-has-no-availability-markup && (stdlib=apple-libc++ && !_target-has-llvm-18)",
+ cfg.available_features,
+ ),
+ ),
+ # Tests that require time zone database support in the built library
+ Feature(
+ name="availability-tzdb-missing",
+ when=lambda cfg: BooleanExpression.evaluate(
+ "!libcpp-has-no-availability-markup && (stdlib=apple-libc++ && !_target-has-llvm-19)",
+ cfg.available_features,
+ ),
+ ),
+ # Tests that require std::from_chars(floating-point) in the built library
+ Feature(
+ name="availability-fp_from_chars-missing",
+ when=lambda cfg: BooleanExpression.evaluate(
+ "!libcpp-has-no-availability-markup && (stdlib=apple-libc++ && !_target-has-llvm-20)",
+ cfg.available_features,
+ ),
+ ),
+]
diff --git a/libcxx/utils/libcxx/test/features/compiler.py b/libcxx/utils/libcxx/test/features/compiler.py
new file mode 100644
index 0000000..2fb2d4b
--- /dev/null
+++ b/libcxx/utils/libcxx/test/features/compiler.py
@@ -0,0 +1,82 @@
+# ===----------------------------------------------------------------------===##
+#
+# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+# See https://llvm.org/LICENSE.txt for license information.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+#
+# ===----------------------------------------------------------------------===##
+
+from libcxx.test.dsl import compilerMacros, Feature, AddCompileFlag, AddFeature
+
+_isAnyClang = lambda cfg: "__clang__" in compilerMacros(cfg)
+_isAppleClang = lambda cfg: "__apple_build_version__" in compilerMacros(cfg)
+_isAnyGCC = lambda cfg: "__GNUC__" in compilerMacros(cfg)
+_isClang = lambda cfg: _isAnyClang(cfg) and not _isAppleClang(cfg)
+_isGCC = lambda cfg: _isAnyGCC(cfg) and not _isAnyClang(cfg)
+_isAnyClangOrGCC = lambda cfg: _isAnyClang(cfg) or _isAnyGCC(cfg)
+_isClExe = lambda cfg: not _isAnyClangOrGCC(cfg)
+_isMSVC = lambda cfg: "_MSC_VER" in compilerMacros(cfg)
+_msvcVersion = lambda cfg: (int(compilerMacros(cfg)["_MSC_VER"]) // 100, int(compilerMacros(cfg)["_MSC_VER"]) % 100)
+
+features = [
+ # gcc-style-warnings detects compilers that understand -Wno-meow flags, unlike MSVC's compiler driver cl.exe.
+ Feature(name="gcc-style-warnings", when=_isAnyClangOrGCC),
+ Feature(name="cl-style-warnings", when=_isClExe),
+
+ Feature(name="apple-clang", when=_isAppleClang),
+ Feature(
+ name=lambda cfg: "apple-clang-{__clang_major__}".format(**compilerMacros(cfg)),
+ when=_isAppleClang,
+ ),
+ Feature(
+ name=lambda cfg: "apple-clang-{__clang_major__}.{__clang_minor__}".format(**compilerMacros(cfg)),
+ when=_isAppleClang,
+ ),
+ Feature(
+ name=lambda cfg: "apple-clang-{__clang_major__}.{__clang_minor__}.{__clang_patchlevel__}".format(**compilerMacros(cfg)),
+ when=_isAppleClang,
+ ),
+ Feature(name="clang", when=_isClang),
+ Feature(
+ name=lambda cfg: "clang-{__clang_major__}".format(**compilerMacros(cfg)),
+ when=_isClang,
+ ),
+ Feature(
+ name=lambda cfg: "clang-{__clang_major__}.{__clang_minor__}".format(**compilerMacros(cfg)),
+ when=_isClang,
+ ),
+ Feature(
+ name=lambda cfg: "clang-{__clang_major__}.{__clang_minor__}.{__clang_patchlevel__}".format(**compilerMacros(cfg)),
+ when=_isClang,
+ ),
+ # Note: Due to a GCC bug (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104760), we must disable deprecation warnings
+ # on GCC or spurious diagnostics are issued.
+ #
+ # TODO:
+ # - Enable -Wplacement-new with GCC.
+ # - Enable -Wclass-memaccess with GCC.
+ Feature(
+ name="gcc",
+ when=_isGCC,
+ actions=[
+ AddCompileFlag("-D_LIBCPP_DISABLE_DEPRECATION_WARNINGS"),
+ AddCompileFlag("-Wno-placement-new"),
+ AddCompileFlag("-Wno-class-memaccess"),
+ AddFeature("GCC-ALWAYS_INLINE-FIXME"),
+ ],
+ ),
+ Feature(
+ name=lambda cfg: "gcc-{__GNUC__}".format(**compilerMacros(cfg)), when=_isGCC
+ ),
+ Feature(
+ name=lambda cfg: "gcc-{__GNUC__}.{__GNUC_MINOR__}".format(**compilerMacros(cfg)),
+ when=_isGCC,
+ ),
+ Feature(
+ name=lambda cfg: "gcc-{__GNUC__}.{__GNUC_MINOR__}.{__GNUC_PATCHLEVEL__}".format(**compilerMacros(cfg)),
+ when=_isGCC,
+ ),
+ Feature(name="msvc", when=_isMSVC),
+ Feature(name=lambda cfg: "msvc-{}".format(*_msvcVersion(cfg)), when=_isMSVC),
+ Feature(name=lambda cfg: "msvc-{}.{}".format(*_msvcVersion(cfg)), when=_isMSVC),
+]
diff --git a/libcxx/utils/libcxx/test/features/gdb.py b/libcxx/utils/libcxx/test/features/gdb.py
new file mode 100644
index 0000000..459a59a
--- /dev/null
+++ b/libcxx/utils/libcxx/test/features/gdb.py
@@ -0,0 +1,50 @@
+# ===----------------------------------------------------------------------===##
+#
+# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+# See https://llvm.org/LICENSE.txt for license information.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+#
+# ===----------------------------------------------------------------------===##
+
+from libcxx.test.dsl import Feature, AddSubstitution
+import shutil
+import subprocess
+
+# Detect whether GDB is on the system, has Python scripting and supports
+# adding breakpoint commands. If so add a substitution to access it.
+def check_gdb(cfg):
+ gdb_path = shutil.which("gdb")
+ if gdb_path is None:
+ return False
+
+ # Check that we can set breakpoint commands, which was added in 8.3.
+ # Using the quit command here means that gdb itself exits, not just
+ # the "python <...>" command.
+ test_src = """\
+try:
+ gdb.Breakpoint(\"main\").commands=\"foo\"
+except AttributeError:
+ gdb.execute(\"quit 1\")
+gdb.execute(\"quit\")"""
+
+ try:
+ stdout = subprocess.check_output(
+ [gdb_path, "-ex", "python " + test_src, "--batch"],
+ stderr=subprocess.DEVNULL,
+ universal_newlines=True,
+ )
+ except subprocess.CalledProcessError:
+ # We can't set breakpoint commands
+ return False
+
+ # Check we actually ran the Python
+ return not "Python scripting is not supported" in stdout
+
+
+features = [
+ Feature(
+ name="host-has-gdb-with-python",
+ when=check_gdb,
+ actions=[AddSubstitution("%{gdb}", lambda cfg: shutil.which("gdb"))],
+ )
+]
diff --git a/libcxx/utils/libcxx/test/features/libcxx_macros.py b/libcxx/utils/libcxx/test/features/libcxx_macros.py
new file mode 100644
index 0000000..7a465f2
--- /dev/null
+++ b/libcxx/utils/libcxx/test/features/libcxx_macros.py
@@ -0,0 +1,76 @@
+# ===----------------------------------------------------------------------===##
+#
+# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+# See https://llvm.org/LICENSE.txt for license information.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+#
+# ===----------------------------------------------------------------------===##
+
+from libcxx.test.dsl import Feature, compilerMacros
+
+features = []
+
+# Deduce and add the test features that that are implied by the #defines in
+# the <__config> header.
+#
+# For each macro of the form `_LIBCPP_XXX_YYY_ZZZ` defined below that
+# is defined after including <__config>, add a Lit feature called
+# `libcpp-xxx-yyy-zzz`. When a macro is defined to a specific value
+# (e.g. `_LIBCPP_ABI_VERSION=2`), the feature is `libcpp-xxx-yyy-zzz=<value>`.
+#
+# Note that features that are more strongly tied to libc++ are named libcpp-foo,
+# while features that are more general in nature are not prefixed with 'libcpp-'.
+macros = {
+ "_LIBCPP_NO_VCRUNTIME": "libcpp-no-vcruntime",
+ "_LIBCPP_ABI_VERSION": "libcpp-abi-version",
+ "_LIBCPP_ABI_BOUNDED_ITERATORS": "libcpp-has-abi-bounded-iterators",
+ "_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STRING": "libcpp-has-abi-bounded-iterators-in-string",
+ "_LIBCPP_ABI_BOUNDED_ITERATORS_IN_VECTOR": "libcpp-has-abi-bounded-iterators-in-vector",
+ "_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STD_ARRAY": "libcpp-has-abi-bounded-iterators-in-std-array",
+ "_LIBCPP_ABI_BOUNDED_UNIQUE_PTR": "libcpp-has-abi-bounded-unique_ptr",
+ "_LIBCPP_ABI_FIX_UNORDERED_CONTAINER_SIZE_TYPE": "libcpp-has-abi-fix-unordered-container-size-type",
+ "_LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR": "libcpp-deprecated-abi-disable-pair-trivial-copy-ctor",
+ "_LIBCPP_ABI_NO_COMPRESSED_PAIR_PADDING": "libcpp-abi-no-compressed-pair-padding",
+ "_LIBCPP_PSTL_BACKEND_LIBDISPATCH": "libcpp-pstl-backend-libdispatch",
+}
+for macro, feature in macros.items():
+ features.append(
+ Feature(
+ name=lambda cfg, m=macro, f=feature: f + ("={}".format(compilerMacros(cfg)[m]) if compilerMacros(cfg)[m] else ""),
+ when=lambda cfg, m=macro: m in compilerMacros(cfg),
+ )
+ )
+
+true_false_macros = {
+ "_LIBCPP_HAS_THREAD_API_EXTERNAL": "libcpp-has-thread-api-external",
+ "_LIBCPP_HAS_THREAD_API_PTHREAD": "libcpp-has-thread-api-pthread",
+}
+for macro, feature in true_false_macros.items():
+ features.append(
+ Feature(
+ name=feature,
+ when=lambda cfg, m=macro: m in compilerMacros(cfg)
+ and compilerMacros(cfg)[m] == "1",
+ )
+ )
+
+inverted_macros = {
+ "_LIBCPP_HAS_TIME_ZONE_DATABASE": "no-tzdb",
+ "_LIBCPP_HAS_FILESYSTEM": "no-filesystem",
+ "_LIBCPP_HAS_LOCALIZATION": "no-localization",
+ "_LIBCPP_HAS_THREADS": "no-threads",
+ "_LIBCPP_HAS_MONOTONIC_CLOCK": "no-monotonic-clock",
+ "_LIBCPP_HAS_WIDE_CHARACTERS": "no-wide-characters",
+ "_LIBCPP_HAS_VENDOR_AVAILABILITY_ANNOTATIONS": "libcpp-has-no-availability-markup",
+ "_LIBCPP_HAS_RANDOM_DEVICE": "no-random-device",
+ "_LIBCPP_HAS_UNICODE": "libcpp-has-no-unicode",
+ "_LIBCPP_HAS_TERMINAL": "no-terminal",
+}
+for macro, feature in inverted_macros.items():
+ features.append(
+ Feature(
+ name=feature,
+ when=lambda cfg, m=macro: m in compilerMacros(cfg)
+ and compilerMacros(cfg)[m] == "0",
+ )
+ )
diff --git a/libcxx/utils/libcxx/test/features/localization.py b/libcxx/utils/libcxx/test/features/localization.py
new file mode 100644
index 0000000..157c250
--- /dev/null
+++ b/libcxx/utils/libcxx/test/features/localization.py
@@ -0,0 +1,142 @@
+# ===----------------------------------------------------------------------===##
+#
+# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+# See https://llvm.org/LICENSE.txt for license information.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+#
+# ===----------------------------------------------------------------------===##
+
+from libcxx.test.dsl import compilerMacros, Feature, programSucceeds, hasAnyLocale, programOutput, AddSubstitution
+import re
+
+features = [
+ # Check for Glibc < 2.27, where the ru_RU.UTF-8 locale had
+ # mon_decimal_point == ".", which our tests don't handle.
+ Feature(
+ name="glibc-old-ru_RU-decimal-point",
+ when=lambda cfg: not "_LIBCPP_HAS_LOCALIZATION" in compilerMacros(cfg)
+ or compilerMacros(cfg)["_LIBCPP_HAS_LOCALIZATION"] == "1"
+ and not programSucceeds(
+ cfg,
+ """
+ #include <locale.h>
+ #include <string.h>
+ int main(int, char**) {
+ setlocale(LC_ALL, "ru_RU.UTF-8");
+ return strcmp(localeconv()->mon_decimal_point, ",");
+ }
+ """,
+ ),
+ ),
+]
+
+# Mapping from canonical locale names (used in the tests) to possible locale
+# names on various systems. Each locale is considered supported if any of the
+# alternative names is supported.
+_locales = {
+ "en_US.UTF-8": ["en_US.UTF-8", "en_US.utf8", "English_United States.1252"],
+ "fr_FR.UTF-8": ["fr_FR.UTF-8", "fr_FR.utf8", "French_France.1252"],
+ "ja_JP.UTF-8": ["ja_JP.UTF-8", "ja_JP.utf8", "Japanese_Japan.923"],
+ "ru_RU.UTF-8": ["ru_RU.UTF-8", "ru_RU.utf8", "Russian_Russia.1251"],
+ "zh_CN.UTF-8": ["zh_CN.UTF-8", "zh_CN.utf8", "Chinese_China.936"],
+ "fr_CA.ISO8859-1": ["fr_CA.ISO8859-1", "French_Canada.1252"],
+ "cs_CZ.ISO8859-2": ["cs_CZ.ISO8859-2", "Czech_Czech Republic.1250"],
+}
+_provide_locale_conversions = {
+ "fr_FR.UTF-8": ["decimal_point", "mon_thousands_sep", "thousands_sep"],
+ "ru_RU.UTF-8": ["mon_thousands_sep"],
+}
+for locale, alts in _locales.items():
+ # Note: Using alts directly in the lambda body here will bind it to the value at the
+ # end of the loop. Assigning it to a default argument works around this issue.
+ features.append(
+ Feature(
+ name="locale.{}".format(locale),
+ when=lambda cfg, alts=alts: hasAnyLocale(cfg, alts),
+ actions=lambda cfg, locale=locale, alts=alts: _getLocaleFlagsAction(
+ cfg, locale, alts, _provide_locale_conversions[locale]
+ )
+ if locale in _provide_locale_conversions
+ and ("_LIBCPP_HAS_WIDE_CHARACTERS" not in compilerMacros(cfg) or
+ compilerMacros(cfg)["_LIBCPP_HAS_WIDE_CHARACTERS"] == "1")
+ else [],
+ ),
+ )
+
+# Provide environment locale conversions through substitutions to avoid platform specific
+# maintenance.
+def _getLocaleFlagsAction(cfg, locale, alts, members):
+ alts_list = ",".join([f'"{l}"' for l in alts])
+ get_member_list = ",".join([f"lc->{m}" for m in members])
+
+ localeconv_info = programOutput(
+ cfg,
+ r"""
+ #if defined(_WIN32) && !defined(_CRT_SECURE_NO_WARNINGS)
+ #define _CRT_SECURE_NO_WARNINGS
+ #endif
+ #include <stdio.h>
+ #include <locale.h>
+ #include <stdlib.h>
+ #include <wchar.h>
+
+ // Print each requested locale conversion member on separate lines.
+ int main(int, char**) {
+ const char* locales[] = { %s };
+ for (int loc_i = 0; loc_i < %d; ++loc_i) {
+ if (!setlocale(LC_ALL, locales[loc_i])) {
+ continue; // Choose first locale name that is recognized.
+ }
+
+ lconv* lc = localeconv();
+ const char* members[] = { %s };
+ for (size_t m_i = 0; m_i < %d; ++m_i) {
+ if (!members[m_i]) {
+ printf("\n"); // member value is an empty string
+ continue;
+ }
+
+ size_t len = mbstowcs(nullptr, members[m_i], 0);
+ if (len == static_cast<size_t>(-1)) {
+ fprintf(stderr, "mbstowcs failed unexpectedly\n");
+ return 1;
+ }
+ // Include room for null terminator. Use malloc as these features
+ // are also used by lit configs that don't use -lc++ (libunwind tests).
+ wchar_t* dst = (wchar_t*)malloc((len + 1) * sizeof(wchar_t));
+ size_t ret = mbstowcs(dst, members[m_i], len + 1);
+ if (ret == static_cast<size_t>(-1)) {
+ fprintf(stderr, "mbstowcs failed unexpectedly\n");
+ free(dst);
+ return 1;
+ }
+
+ for (size_t i = 0; i < len; ++i) {
+ if (dst[i] > 0x7F) {
+ printf("\\u%%04x", dst[i]);
+ } else {
+ // c++03 does not allow basic ascii-range characters in UCNs
+ printf("%%c", (char)dst[i]);
+ }
+ }
+ printf("\n");
+ free(dst);
+ }
+ return 0;
+ }
+
+ return 1;
+ }
+ """
+ % (alts_list, len(alts), get_member_list, len(members)),
+ )
+ valid_define_name = re.sub(r"[.-]", "_", locale).upper()
+ return [
+ # Provide locale conversion through a substitution.
+ # Example: %{LOCALE_CONV_FR_FR_UTF_8_THOUSANDS_SEP} = L"\u202f"
+ AddSubstitution(
+ f"%{{LOCALE_CONV_{valid_define_name}_{member.upper()}}}",
+ lambda cfg, value=value: f"'L\"{value}\"'",
+ )
+ for member, value in zip(members, localeconv_info.split("\n"))
+ ]
diff --git a/libcxx/utils/libcxx/test/features/misc.py b/libcxx/utils/libcxx/test/features/misc.py
new file mode 100644
index 0000000..738e3d8
--- /dev/null
+++ b/libcxx/utils/libcxx/test/features/misc.py
@@ -0,0 +1,299 @@
+# ===----------------------------------------------------------------------===##
+#
+# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+# See https://llvm.org/LICENSE.txt for license information.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+#
+# ===----------------------------------------------------------------------===##
+
+from libcxx.test.dsl import compilerMacros, sourceBuilds, hasCompileFlag, programSucceeds, runScriptExitCode
+from libcxx.test.dsl import Feature, AddCompileFlag, AddLinkFlag
+import platform
+import sys
+
+def _mingwSupportsModules(cfg):
+ # Only mingw headers are known to work with libc++ built as a module,
+ # at the moment.
+ if not "__MINGW32__" in compilerMacros(cfg):
+ return False
+ # For mingw headers, check for a version known to support being built
+ # as a module.
+ return sourceBuilds(
+ cfg,
+ """
+ #include <_mingw_mac.h>
+ #if __MINGW64_VERSION_MAJOR < 12
+ #error Headers known to be incompatible
+ #elif __MINGW64_VERSION_MAJOR == 12
+ // The headers were fixed to work with libc++ modules during
+ // __MINGW64_VERSION_MAJOR == 12. The headers became compatible
+ // with libc++ built as a module in
+ // 1652e9241b5d8a5a779c6582b1c3c4f4a7cc66e5 (Apr 2024), but the
+ // following commit 8c13b28ace68f2c0094d45121d59a4b951b533ed
+ // removed the now unused __mingw_static_ovr define. Use this
+ // as indicator for whether we've got new enough headers.
+ #ifdef __mingw_static_ovr
+ #error Headers too old
+ #endif
+ #else
+ // __MINGW64_VERSION_MAJOR > 12 should be ok.
+ #endif
+ int main(int, char**) { return 0; }
+ """,
+ )
+
+features = [
+ Feature(
+ name="diagnose-if-support",
+ when=lambda cfg: hasCompileFlag(cfg, "-Wuser-defined-warnings"),
+ actions=[AddCompileFlag("-Wuser-defined-warnings")],
+ ),
+ Feature(
+ name="character-conversion-warnings",
+ when=lambda cfg: hasCompileFlag(cfg, "-Wcharacter-conversion"),
+ ),
+ # Tests to validate whether the compiler has a way to set the maximum number
+ # of steps during constant evaluation. Since the flag differs per compiler
+ # store the "valid" flag as a feature. This allows passing the proper compile
+ # flag to the compiler:
+ # // ADDITIONAL_COMPILE_FLAGS(has-fconstexpr-steps): -fconstexpr-steps=12345678
+ # // ADDITIONAL_COMPILE_FLAGS(has-fconstexpr-ops-limit): -fconstexpr-ops-limit=12345678
+ Feature(
+ name="has-fconstexpr-steps",
+ when=lambda cfg: hasCompileFlag(cfg, "-fconstexpr-steps=1"),
+ ),
+ Feature(
+ name="has-fconstexpr-ops-limit",
+ when=lambda cfg: hasCompileFlag(cfg, "-fconstexpr-ops-limit=1"),
+ ),
+ Feature(name="has-fblocks", when=lambda cfg: hasCompileFlag(cfg, "-fblocks")),
+ Feature(
+ name="fdelayed-template-parsing",
+ when=lambda cfg: hasCompileFlag(cfg, "-fdelayed-template-parsing"),
+ ),
+ Feature(
+ name="has-fobjc-arc",
+ when=lambda cfg: hasCompileFlag(cfg, "-xobjective-c++ -fobjc-arc")
+ and sys.platform.lower().strip() == "darwin",
+ ), # TODO: this doesn't handle cross-compiling to Apple platforms.
+ Feature(
+ name="objective-c++",
+ when=lambda cfg: hasCompileFlag(cfg, "-xobjective-c++ -fobjc-arc"),
+ ),
+ Feature(
+ name="verify-support",
+ when=lambda cfg: hasCompileFlag(cfg, "-Xclang -verify-ignore-unexpected"),
+ ),
+ Feature(
+ name="add-latomic-workaround", # https://llvm.org/PR73361
+ when=lambda cfg: sourceBuilds(
+ cfg, "int main(int, char**) { return 0; }", ["-latomic"]
+ ),
+ actions=[AddLinkFlag("-latomic")],
+ ),
+ Feature(
+ name="has-64-bit-atomics",
+ when=lambda cfg: sourceBuilds(
+ cfg,
+ """
+ #include <atomic>
+ struct Large { char storage[64/8]; };
+ std::atomic<Large> x;
+ int main(int, char**) { (void)x.load(); (void)x.is_lock_free(); return 0; }
+ """,
+ ),
+ ),
+ Feature(
+ name="has-1024-bit-atomics",
+ when=lambda cfg: sourceBuilds(
+ cfg,
+ """
+ #include <atomic>
+ struct Large { char storage[1024/8]; };
+ std::atomic<Large> x;
+ int main(int, char**) { (void)x.load(); (void)x.is_lock_free(); return 0; }
+ """,
+ ),
+ ),
+ # Tests that require 64-bit architecture
+ Feature(
+ name="32-bit-pointer",
+ when=lambda cfg: sourceBuilds(
+ cfg,
+ """
+ int main(int, char**) {
+ static_assert(sizeof(void *) == 4);
+ }
+ """,
+ ),
+ ),
+ # Check for a Windows UCRT bug (fixed in UCRT/Windows 10.0.20348.0):
+ # https://developercommunity.visualstudio.com/t/utf-8-locales-break-ctype-functions-for-wchar-type/1653678
+ Feature(
+ name="win32-broken-utf8-wchar-ctype",
+ when=lambda cfg: not "_LIBCPP_HAS_LOCALIZATION" in compilerMacros(cfg)
+ or compilerMacros(cfg)["_LIBCPP_HAS_LOCALIZATION"] == "1"
+ and "_WIN32" in compilerMacros(cfg)
+ and not programSucceeds(
+ cfg,
+ """
+ #include <locale.h>
+ #include <wctype.h>
+ int main(int, char**) {
+ setlocale(LC_ALL, "en_US.UTF-8");
+ return towlower(L'\\xDA') != L'\\xFA';
+ }
+ """,
+ ),
+ ),
+ # Check for a Windows UCRT bug (fixed in UCRT/Windows 10.0.19041.0).
+ # https://developercommunity.visualstudio.com/t/printf-formatting-with-g-outputs-too/1660837
+ Feature(
+ name="win32-broken-printf-g-precision",
+ when=lambda cfg: "_WIN32" in compilerMacros(cfg)
+ and not programSucceeds(
+ cfg,
+ """
+ #include <stdio.h>
+ #include <string.h>
+ int main(int, char**) {
+ char buf[100];
+ snprintf(buf, sizeof(buf), "%#.*g", 0, 0.0);
+ return strcmp(buf, "0.");
+ }
+ """,
+ ),
+ ),
+ # Check for a Windows UCRT bug (not fixed upstream yet).
+ # With UCRT, printf("%a", 0.0) produces "0x0.0000000000000p+0",
+ # while other C runtimes produce just "0x0p+0".
+ # https://developercommunity.visualstudio.com/t/Printf-formatting-of-float-as-hex-prints/1660844
+ Feature(
+ name="win32-broken-printf-a-precision",
+ when=lambda cfg: "_WIN32" in compilerMacros(cfg)
+ and not programSucceeds(
+ cfg,
+ """
+ #include <stdio.h>
+ #include <string.h>
+ int main(int, char**) {
+ char buf[100];
+ snprintf(buf, sizeof(buf), "%a", 0.0);
+ return strcmp(buf, "0x0p+0");
+ }
+ """,
+ ),
+ ),
+ Feature(
+ name="has-unix-headers",
+ when=lambda cfg: sourceBuilds(
+ cfg,
+ """
+ #include <unistd.h>
+ #include <sys/wait.h>
+ int main(int, char**) {
+ int fd[2];
+ return pipe(fd);
+ }
+ """,
+ ),
+ ),
+ # Whether Bash can run on the executor.
+ # This is not always the case, for example when running on embedded systems.
+ #
+ # For the corner case of bash existing, but it being missing in the path
+ # set in %{exec} as "--env PATH=one-single-dir", the executor does find
+ # and executes bash, but bash then can't find any other common shell
+ # utilities. Test executing "bash -c 'bash --version'" to see if bash
+ # manages to find binaries to execute.
+ Feature(
+ name="executor-has-no-bash",
+ when=lambda cfg: runScriptExitCode(cfg, ["%{exec} bash -c 'bash --version'"]) != 0,
+ ),
+ # Whether module support for the platform is available.
+ Feature(
+ name="has-no-cxx-module-support",
+ # The libc of these platforms have functions with internal linkage.
+ # This is not allowed per C11 7.1.2 Standard headers/6
+ # Any declaration of a library function shall have external linkage.
+ when=lambda cfg: "__ANDROID__" in compilerMacros(cfg)
+ or "__FreeBSD__" in compilerMacros(cfg)
+ or ("_WIN32" in compilerMacros(cfg) and not _mingwSupportsModules(cfg))
+ or platform.system().lower().startswith("aix")
+ # Avoid building on platforms that don't support modules properly.
+ or not hasCompileFlag(cfg, "-Wno-reserved-module-identifier")
+ # older versions don't support extern "C++", newer versions don't support main in named module.
+ or not (
+ sourceBuilds(
+ cfg,
+ """
+ export module test;
+ extern "C++" int main(int, char**) { return 0; }
+ """,
+ )
+ or sourceBuilds(
+ cfg,
+ """
+ export module test;
+ int main(int, char**) { return 0; }
+ """,
+ )
+ ),
+ ),
+ # The time zone validation tests compare the output of zdump against the
+ # output generated by <chrono>'s time zone support.
+ Feature(
+ name="has-no-zdump",
+ when=lambda cfg: runScriptExitCode(cfg, ["zdump --version"]) != 0,
+ ),
+ Feature(
+ name="can-create-symlinks",
+ when=lambda cfg: "_WIN32" not in compilerMacros(cfg)
+ or programSucceeds(
+ cfg,
+ # Creation of symlinks require elevated privileges on Windows unless
+ # Windows developer mode is enabled.
+ """
+ #include <stdio.h>
+ #include <windows.h>
+ int main(int, char**) {
+ CHAR tempDirPath[MAX_PATH];
+ DWORD tempPathRet = GetTempPathA(MAX_PATH, tempDirPath);
+ if (tempPathRet == 0 || tempPathRet > MAX_PATH) {
+ return 1;
+ }
+
+ CHAR tempFilePath[MAX_PATH];
+ UINT uRetVal = GetTempFileNameA(
+ tempDirPath,
+ "cxx", // Prefix
+ 0, // Unique=0 also implies file creation.
+ tempFilePath);
+ if (uRetVal == 0) {
+ return 1;
+ }
+
+ CHAR symlinkFilePath[MAX_PATH];
+ int ret = sprintf_s(symlinkFilePath, MAX_PATH, "%s_symlink", tempFilePath);
+ if (ret == -1) {
+ DeleteFileA(tempFilePath);
+ return 1;
+ }
+
+ // Requires either administrator, or developer mode enabled.
+ BOOL bCreatedSymlink = CreateSymbolicLinkA(symlinkFilePath,
+ tempFilePath,
+ SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE);
+ if (!bCreatedSymlink) {
+ DeleteFileA(tempFilePath);
+ return 1;
+ }
+
+ DeleteFileA(tempFilePath);
+ DeleteFileA(symlinkFilePath);
+ return 0;
+ }
+ """,
+ ),
+ ),
+]
diff --git a/libcxx/utils/libcxx/test/features/platform.py b/libcxx/utils/libcxx/test/features/platform.py
new file mode 100644
index 0000000..db9d393
--- /dev/null
+++ b/libcxx/utils/libcxx/test/features/platform.py
@@ -0,0 +1,132 @@
+# ===----------------------------------------------------------------------===##
+#
+# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+# See https://llvm.org/LICENSE.txt for license information.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+#
+# ===----------------------------------------------------------------------===##
+
+from libcxx.test.dsl import programOutput, Feature, compilerMacros, programSucceeds, AddCompileFlag, sourceBuilds
+import platform
+import sys
+
+def _getAndroidDeviceApi(cfg):
+ return int(
+ programOutput(
+ cfg,
+ r"""
+ #include <android/api-level.h>
+ #include <stdio.h>
+ int main(int, char**) {
+ printf("%d\n", android_get_device_api_level());
+ return 0;
+ }
+ """,
+ )
+ )
+
+# Add features representing the target platform name: darwin, linux, windows, etc...
+features = [
+ Feature(name="darwin", when=lambda cfg: "__APPLE__" in compilerMacros(cfg)),
+ Feature(name="windows", when=lambda cfg: "_WIN32" in compilerMacros(cfg)),
+ Feature(
+ name="windows-dll",
+ when=lambda cfg: "_WIN32" in compilerMacros(cfg)
+ and sourceBuilds(
+ cfg,
+ """
+ #include <iostream>
+ int main(int, char**) { return 0; }
+ """,
+ )
+ and programSucceeds(
+ cfg,
+ """
+ #include <iostream>
+ #include <windows.h>
+ #include <winnt.h>
+ int main(int, char**) {
+ // Get a pointer to a data member that gets linked from the C++
+ // library. This must be a data member (functions can get
+ // thunk inside the calling executable), and must not be
+ // something that is defined inline in headers.
+ void *ptr = &std::cout;
+ // Get a handle to the current main executable.
+ void *exe = GetModuleHandle(NULL);
+ // The handle points at the PE image header. Navigate through
+ // the header structure to find the size of the PE image (the
+ // executable).
+ PIMAGE_DOS_HEADER dosheader = (PIMAGE_DOS_HEADER)exe;
+ PIMAGE_NT_HEADERS ntheader = (PIMAGE_NT_HEADERS)((BYTE *)dosheader + dosheader->e_lfanew);
+ PIMAGE_OPTIONAL_HEADER peheader = &ntheader->OptionalHeader;
+ void *exeend = (BYTE*)exe + peheader->SizeOfImage;
+ // Check if the tested pointer - the data symbol from the
+ // C++ library - is located within the exe.
+ if (ptr >= exe && ptr <= exeend)
+ return 1;
+ // Return success if it was outside of the executable, i.e.
+ // loaded from a DLL.
+ return 0;
+ }
+ """,
+ ),
+ actions=[AddCompileFlag("-DTEST_WINDOWS_DLL")],
+ ),
+ Feature(name="linux", when=lambda cfg: "__linux__" in compilerMacros(cfg)),
+ Feature(name="android", when=lambda cfg: "__ANDROID__" in compilerMacros(cfg)),
+ Feature(
+ name=lambda cfg: "android-device-api={}".format(_getAndroidDeviceApi(cfg)),
+ when=lambda cfg: "__ANDROID__" in compilerMacros(cfg),
+ ),
+ Feature(
+ name="LIBCXX-ANDROID-FIXME",
+ when=lambda cfg: "__ANDROID__" in compilerMacros(cfg),
+ ),
+ Feature(name="netbsd", when=lambda cfg: "__NetBSD__" in compilerMacros(cfg)),
+ Feature(name="freebsd", when=lambda cfg: "__FreeBSD__" in compilerMacros(cfg)),
+ Feature(
+ name="LIBCXX-FREEBSD-FIXME",
+ when=lambda cfg: "__FreeBSD__" in compilerMacros(cfg),
+ ),
+ Feature(
+ name="LIBCXX-PICOLIBC-FIXME",
+ when=lambda cfg: sourceBuilds(
+ cfg,
+ """
+ #include <string.h>
+ #ifndef __PICOLIBC__
+ #error not picolibc
+ #endif
+ int main(int, char**) { return 0; }
+ """,
+ ),
+ ),
+ Feature(
+ name="LIBCXX-AMDGPU-FIXME",
+ when=lambda cfg: "__AMDGPU__" in compilerMacros(cfg),
+ ),
+ Feature(
+ name="LIBCXX-NVPTX-FIXME",
+ when=lambda cfg: "__NVPTX__" in compilerMacros(cfg),
+ ),
+]
+
+# Add features representing the build host platform name.
+# The build host could differ from the target platform for cross-compilation.
+features += [
+ Feature(name="buildhost={}".format(sys.platform.lower().strip())),
+ # sys.platform can often be represented by a "sub-system", such as 'win32', 'cygwin', 'mingw', freebsd13 & etc.
+ # We define a consolidated feature on a few platforms.
+ Feature(
+ name="buildhost=windows",
+ when=lambda cfg: platform.system().lower().startswith("windows"),
+ ),
+ Feature(
+ name="buildhost=freebsd",
+ when=lambda cfg: platform.system().lower().startswith("freebsd"),
+ ),
+ Feature(
+ name="buildhost=aix",
+ when=lambda cfg: platform.system().lower().startswith("aix"),
+ ),
+]
diff --git a/libcxx/utils/libcxx/test/format.py b/libcxx/utils/libcxx/test/format.py
index 975209c..76e9115 100644
--- a/libcxx/utils/libcxx/test/format.py
+++ b/libcxx/utils/libcxx/test/format.py
@@ -99,7 +99,7 @@ def parseScript(test, preamble):
substitutions.append(
(
"%{verify}",
- "%{cxx} %s %{flags} %{compile_flags} -fsyntax-only -Wno-error -Xclang -verify -Xclang -verify-ignore-unexpected=note -ferror-limit=0",
+ "%{cxx} %s %{flags} %{compile_flags} -U_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER -fsyntax-only -Wno-error -Xclang -verify -Xclang -verify-ignore-unexpected=note -ferror-limit=0",
)
)
substitutions.append(("%{run}", "%{exec} %t.exe"))
diff --git a/libcxx/utils/libcxx/test/modules.py b/libcxx/utils/libcxx/test/modules.py
index bd4fbe7..b93846b 100644
--- a/libcxx/utils/libcxx/test/modules.py
+++ b/libcxx/utils/libcxx/test/modules.py
@@ -166,7 +166,7 @@ class module_test_generator:
f'" > {self.tmp_prefix}.{header}.cppm'
)
- # Extract the information of the module partition using lang-tidy
+ # Extract the information of the module partition using clang-tidy
print(
f"// RUN: {self.clang_tidy} {self.tmp_prefix}.{header}.cppm "
" --checks='-*,libcpp-header-exportable-declarations' "
@@ -222,6 +222,7 @@ class module_test_generator:
print(f'// RUN: echo -e "' f"{include}" f'" > {self.tmp_prefix}.{header}.cpp')
print(
f"// RUN: {self.clang_tidy} {self.tmp_prefix}.{header}.cpp "
+ " --system-headers "
" --checks='-*,libcpp-header-exportable-declarations' "
" -config='{CheckOptions: [ "
" {"
diff --git a/libcxx/utils/libcxx/test/params.py b/libcxx/utils/libcxx/test/params.py
index c02d6df..299aa28 100644
--- a/libcxx/utils/libcxx/test/params.py
+++ b/libcxx/utils/libcxx/test/params.py
@@ -11,7 +11,7 @@ import shlex
from pathlib import Path
from libcxx.test.dsl import *
-from libcxx.test.features import _isClang, _isAppleClang, _isGCC, _isMSVC
+from libcxx.test.features.compiler import _isClang, _isAppleClang, _isGCC, _isMSVC
_warningFlags = [