aboutsummaryrefslogtreecommitdiff
path: root/libcxx/include
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2022-07-03 14:10:23 +0000
committerDimitry Andric <dim@FreeBSD.org>2022-07-03 14:10:23 +0000
commit145449b1e420787bb99721a429341fa6be3adfb6 (patch)
tree1d56ae694a6de602e348dd80165cf881a36600ed /libcxx/include
parentecbca9f5fb7d7613d2b94982c4825eb0d33d6842 (diff)
downloadsrc-145449b1e420787bb99721a429341fa6be3adfb6.tar.gz
src-145449b1e420787bb99721a429341fa6be3adfb6.zip
Vendor import of llvm-project main llvmorg-15-init-15358-g53dc0f107877.vendor/llvm-project/llvmorg-15-init-15358-g53dc0f107877
Diffstat (limited to 'libcxx/include')
-rw-r--r--libcxx/include/__algorithm/adjacent_find.h2
-rw-r--r--libcxx/include/__algorithm/all_of.h2
-rw-r--r--libcxx/include/__algorithm/any_of.h2
-rw-r--r--libcxx/include/__algorithm/binary_search.h20
-rw-r--r--libcxx/include/__algorithm/clamp.h4
-rw-r--r--libcxx/include/__algorithm/comp.h2
-rw-r--r--libcxx/include/__algorithm/comp_ref_type.h33
-rw-r--r--libcxx/include/__algorithm/copy.h107
-rw-r--r--libcxx/include/__algorithm/copy_backward.h66
-rw-r--r--libcxx/include/__algorithm/copy_if.h2
-rw-r--r--libcxx/include/__algorithm/copy_n.h2
-rw-r--r--libcxx/include/__algorithm/count.h2
-rw-r--r--libcxx/include/__algorithm/count_if.h2
-rw-r--r--libcxx/include/__algorithm/equal.h2
-rw-r--r--libcxx/include/__algorithm/equal_range.h12
-rw-r--r--libcxx/include/__algorithm/fill.h2
-rw-r--r--libcxx/include/__algorithm/fill_n.h2
-rw-r--r--libcxx/include/__algorithm/find.h2
-rw-r--r--libcxx/include/__algorithm/find_end.h2
-rw-r--r--libcxx/include/__algorithm/find_first_of.h2
-rw-r--r--libcxx/include/__algorithm/find_if.h2
-rw-r--r--libcxx/include/__algorithm/find_if_not.h2
-rw-r--r--libcxx/include/__algorithm/for_each.h2
-rw-r--r--libcxx/include/__algorithm/for_each_n.h2
-rw-r--r--libcxx/include/__algorithm/generate.h2
-rw-r--r--libcxx/include/__algorithm/generate_n.h2
-rw-r--r--libcxx/include/__algorithm/half_positive.h2
-rw-r--r--libcxx/include/__algorithm/in_found_result.h49
-rw-r--r--libcxx/include/__algorithm/in_fun_result.h49
-rw-r--r--libcxx/include/__algorithm/in_in_out_result.h36
-rw-r--r--libcxx/include/__algorithm/in_in_result.h30
-rw-r--r--libcxx/include/__algorithm/in_out_out_result.h54
-rw-r--r--libcxx/include/__algorithm/in_out_result.h29
-rw-r--r--libcxx/include/__algorithm/includes.h2
-rw-r--r--libcxx/include/__algorithm/inplace_merge.h10
-rw-r--r--libcxx/include/__algorithm/is_heap.h2
-rw-r--r--libcxx/include/__algorithm/is_heap_until.h2
-rw-r--r--libcxx/include/__algorithm/is_partitioned.h2
-rw-r--r--libcxx/include/__algorithm/is_permutation.h2
-rw-r--r--libcxx/include/__algorithm/is_sorted.h2
-rw-r--r--libcxx/include/__algorithm/is_sorted_until.h2
-rw-r--r--libcxx/include/__algorithm/iter_swap.h2
-rw-r--r--libcxx/include/__algorithm/iterator_operations.h47
-rw-r--r--libcxx/include/__algorithm/lexicographical_compare.h2
-rw-r--r--libcxx/include/__algorithm/lower_bound.h69
-rw-r--r--libcxx/include/__algorithm/make_heap.h2
-rw-r--r--libcxx/include/__algorithm/make_projected.h51
-rw-r--r--libcxx/include/__algorithm/max.h2
-rw-r--r--libcxx/include/__algorithm/max_element.h2
-rw-r--r--libcxx/include/__algorithm/merge.h2
-rw-r--r--libcxx/include/__algorithm/min.h2
-rw-r--r--libcxx/include/__algorithm/min_element.h2
-rw-r--r--libcxx/include/__algorithm/min_max_result.h56
-rw-r--r--libcxx/include/__algorithm/minmax.h52
-rw-r--r--libcxx/include/__algorithm/minmax_element.h122
-rw-r--r--libcxx/include/__algorithm/mismatch.h4
-rw-r--r--libcxx/include/__algorithm/move.h119
-rw-r--r--libcxx/include/__algorithm/move_backward.h4
-rw-r--r--libcxx/include/__algorithm/next_permutation.h2
-rw-r--r--libcxx/include/__algorithm/none_of.h2
-rw-r--r--libcxx/include/__algorithm/nth_element.h3
-rw-r--r--libcxx/include/__algorithm/partial_sort.h3
-rw-r--r--libcxx/include/__algorithm/partial_sort_copy.h2
-rw-r--r--libcxx/include/__algorithm/partition.h2
-rw-r--r--libcxx/include/__algorithm/partition_copy.h4
-rw-r--r--libcxx/include/__algorithm/partition_point.h6
-rw-r--r--libcxx/include/__algorithm/pop_heap.h20
-rw-r--r--libcxx/include/__algorithm/prev_permutation.h2
-rw-r--r--libcxx/include/__algorithm/push_heap.h2
-rw-r--r--libcxx/include/__algorithm/ranges_adjacent_find.h78
-rw-r--r--libcxx/include/__algorithm/ranges_all_of.h68
-rw-r--r--libcxx/include/__algorithm/ranges_any_of.h68
-rw-r--r--libcxx/include/__algorithm/ranges_binary_search.h63
-rw-r--r--libcxx/include/__algorithm/ranges_copy.h65
-rw-r--r--libcxx/include/__algorithm/ranges_copy_backward.h67
-rw-r--r--libcxx/include/__algorithm/ranges_copy_if.h81
-rw-r--r--libcxx/include/__algorithm/ranges_copy_n.h76
-rw-r--r--libcxx/include/__algorithm/ranges_count.h62
-rw-r--r--libcxx/include/__algorithm/ranges_count_if.h72
-rw-r--r--libcxx/include/__algorithm/ranges_equal.h115
-rw-r--r--libcxx/include/__algorithm/ranges_fill.h59
-rw-r--r--libcxx/include/__algorithm/ranges_fill_n.h48
-rw-r--r--libcxx/include/__algorithm/ranges_find.h63
-rw-r--r--libcxx/include/__algorithm/ranges_find_first_of.h101
-rw-r--r--libcxx/include/__algorithm/ranges_find_if.h71
-rw-r--r--libcxx/include/__algorithm/ranges_find_if_not.h63
-rw-r--r--libcxx/include/__algorithm/ranges_for_each.h78
-rw-r--r--libcxx/include/__algorithm/ranges_for_each_n.h67
-rw-r--r--libcxx/include/__algorithm/ranges_is_partitioned.h81
-rw-r--r--libcxx/include/__algorithm/ranges_is_sorted.h61
-rw-r--r--libcxx/include/__algorithm/ranges_is_sorted_until.h76
-rw-r--r--libcxx/include/__algorithm/ranges_lexicographical_compare.h98
-rw-r--r--libcxx/include/__algorithm/ranges_lower_bound.h66
-rw-r--r--libcxx/include/__algorithm/ranges_max.h93
-rw-r--r--libcxx/include/__algorithm/ranges_max_element.h61
-rw-r--r--libcxx/include/__algorithm/ranges_min.h89
-rw-r--r--libcxx/include/__algorithm/ranges_min_element.h73
-rw-r--r--libcxx/include/__algorithm/ranges_minmax.h133
-rw-r--r--libcxx/include/__algorithm/ranges_minmax_element.h72
-rw-r--r--libcxx/include/__algorithm/ranges_mismatch.h85
-rw-r--r--libcxx/include/__algorithm/ranges_move.h83
-rw-r--r--libcxx/include/__algorithm/ranges_move_backward.h75
-rw-r--r--libcxx/include/__algorithm/ranges_none_of.h68
-rw-r--r--libcxx/include/__algorithm/ranges_replace.h74
-rw-r--r--libcxx/include/__algorithm/ranges_replace_if.h77
-rw-r--r--libcxx/include/__algorithm/ranges_reverse.h83
-rw-r--r--libcxx/include/__algorithm/ranges_sort.h78
-rw-r--r--libcxx/include/__algorithm/ranges_stable_sort.h78
-rw-r--r--libcxx/include/__algorithm/ranges_swap_ranges.h69
-rw-r--r--libcxx/include/__algorithm/ranges_transform.h170
-rw-r--r--libcxx/include/__algorithm/ranges_upper_bound.h75
-rw-r--r--libcxx/include/__algorithm/remove.h2
-rw-r--r--libcxx/include/__algorithm/remove_copy.h2
-rw-r--r--libcxx/include/__algorithm/remove_copy_if.h2
-rw-r--r--libcxx/include/__algorithm/remove_if.h4
-rw-r--r--libcxx/include/__algorithm/replace.h2
-rw-r--r--libcxx/include/__algorithm/replace_copy.h2
-rw-r--r--libcxx/include/__algorithm/replace_copy_if.h2
-rw-r--r--libcxx/include/__algorithm/replace_if.h2
-rw-r--r--libcxx/include/__algorithm/reverse.h2
-rw-r--r--libcxx/include/__algorithm/reverse_copy.h2
-rw-r--r--libcxx/include/__algorithm/rotate.h5
-rw-r--r--libcxx/include/__algorithm/rotate_copy.h2
-rw-r--r--libcxx/include/__algorithm/sample.h8
-rw-r--r--libcxx/include/__algorithm/search.h4
-rw-r--r--libcxx/include/__algorithm/search_n.h2
-rw-r--r--libcxx/include/__algorithm/set_difference.h2
-rw-r--r--libcxx/include/__algorithm/set_intersection.h2
-rw-r--r--libcxx/include/__algorithm/set_symmetric_difference.h2
-rw-r--r--libcxx/include/__algorithm/set_union.h2
-rw-r--r--libcxx/include/__algorithm/shift_left.h2
-rw-r--r--libcxx/include/__algorithm/shift_right.h2
-rw-r--r--libcxx/include/__algorithm/shuffle.h3
-rw-r--r--libcxx/include/__algorithm/sift_down.h35
-rw-r--r--libcxx/include/__algorithm/sort.h918
-rw-r--r--libcxx/include/__algorithm/sort_heap.h2
-rw-r--r--libcxx/include/__algorithm/stable_partition.h10
-rw-r--r--libcxx/include/__algorithm/stable_sort.h51
-rw-r--r--libcxx/include/__algorithm/swap_ranges.h3
-rw-r--r--libcxx/include/__algorithm/transform.h2
-rw-r--r--libcxx/include/__algorithm/unique.h2
-rw-r--r--libcxx/include/__algorithm/unique_copy.h3
-rw-r--r--libcxx/include/__algorithm/unwrap_iter.h34
-rw-r--r--libcxx/include/__algorithm/upper_bound.h6
-rw-r--r--libcxx/include/__assert66
-rw-r--r--libcxx/include/__availability89
-rw-r--r--libcxx/include/__bit/bit_cast.h16
-rw-r--r--libcxx/include/__bit/byteswap.h4
-rw-r--r--libcxx/include/__bit_reference34
-rw-r--r--libcxx/include/__bits2
-rw-r--r--libcxx/include/__bsd_locale_defaults.h8
-rw-r--r--libcxx/include/__bsd_locale_fallbacks.h8
-rw-r--r--libcxx/include/__charconv/chars_format.h2
-rw-r--r--libcxx/include/__charconv/from_chars_result.h2
-rw-r--r--libcxx/include/__charconv/tables.h130
-rw-r--r--libcxx/include/__charconv/to_chars_base_10.h127
-rw-r--r--libcxx/include/__charconv/to_chars_result.h2
-rw-r--r--libcxx/include/__chrono/calendar.h1236
-rw-r--r--libcxx/include/__chrono/convert_to_timespec.h2
-rw-r--r--libcxx/include/__chrono/day.h99
-rw-r--r--libcxx/include/__chrono/duration.h4
-rw-r--r--libcxx/include/__chrono/file_clock.h2
-rw-r--r--libcxx/include/__chrono/hh_mm_ss.h112
-rw-r--r--libcxx/include/__chrono/high_resolution_clock.h2
-rw-r--r--libcxx/include/__chrono/literals.h49
-rw-r--r--libcxx/include/__chrono/month.h118
-rw-r--r--libcxx/include/__chrono/month_weekday.h106
-rw-r--r--libcxx/include/__chrono/monthday.h160
-rw-r--r--libcxx/include/__chrono/steady_clock.h2
-rw-r--r--libcxx/include/__chrono/system_clock.h2
-rw-r--r--libcxx/include/__chrono/time_point.h2
-rw-r--r--libcxx/include/__chrono/weekday.h185
-rw-r--r--libcxx/include/__chrono/year.h114
-rw-r--r--libcxx/include/__chrono/year_month.h114
-rw-r--r--libcxx/include/__chrono/year_month_day.h323
-rw-r--r--libcxx/include/__chrono/year_month_weekday.h255
-rw-r--r--libcxx/include/__compare/common_comparison_category.h2
-rw-r--r--libcxx/include/__compare/compare_partial_order_fallback.h6
-rw-r--r--libcxx/include/__compare/compare_strong_order_fallback.h6
-rw-r--r--libcxx/include/__compare/compare_three_way.h6
-rw-r--r--libcxx/include/__compare/compare_three_way_result.h2
-rw-r--r--libcxx/include/__compare/compare_weak_order_fallback.h6
-rw-r--r--libcxx/include/__compare/is_eq.h2
-rw-r--r--libcxx/include/__compare/ordering.h2
-rw-r--r--libcxx/include/__compare/partial_order.h6
-rw-r--r--libcxx/include/__compare/strong_order.h6
-rw-r--r--libcxx/include/__compare/synth_three_way.h8
-rw-r--r--libcxx/include/__compare/three_way_comparable.h6
-rw-r--r--libcxx/include/__compare/weak_order.h6
-rw-r--r--libcxx/include/__concepts/arithmetic.h6
-rw-r--r--libcxx/include/__concepts/assignable.h6
-rw-r--r--libcxx/include/__concepts/boolean_testable.h6
-rw-r--r--libcxx/include/__concepts/class_or_enum.h7
-rw-r--r--libcxx/include/__concepts/common_reference_with.h6
-rw-r--r--libcxx/include/__concepts/common_with.h6
-rw-r--r--libcxx/include/__concepts/constructible.h6
-rw-r--r--libcxx/include/__concepts/convertible_to.h6
-rw-r--r--libcxx/include/__concepts/copyable.h6
-rw-r--r--libcxx/include/__concepts/derived_from.h6
-rw-r--r--libcxx/include/__concepts/destructible.h6
-rw-r--r--libcxx/include/__concepts/different_from.h6
-rw-r--r--libcxx/include/__concepts/equality_comparable.h6
-rw-r--r--libcxx/include/__concepts/invocable.h6
-rw-r--r--libcxx/include/__concepts/movable.h6
-rw-r--r--libcxx/include/__concepts/predicate.h6
-rw-r--r--libcxx/include/__concepts/regular.h6
-rw-r--r--libcxx/include/__concepts/relation.h6
-rw-r--r--libcxx/include/__concepts/same_as.h6
-rw-r--r--libcxx/include/__concepts/semiregular.h6
-rw-r--r--libcxx/include/__concepts/swappable.h6
-rw-r--r--libcxx/include/__concepts/totally_ordered.h6
-rw-r--r--libcxx/include/__config1912
-rw-r--r--libcxx/include/__coroutine/coroutine_handle.h4
-rw-r--r--libcxx/include/__coroutine/coroutine_traits.h2
-rw-r--r--libcxx/include/__coroutine/noop_coroutine_handle.h4
-rw-r--r--libcxx/include/__coroutine/trivial_awaitables.h2
-rw-r--r--libcxx/include/__debug157
-rw-r--r--libcxx/include/__errc2
-rw-r--r--libcxx/include/__filesystem/copy_options.h4
-rw-r--r--libcxx/include/__filesystem/directory_entry.h23
-rw-r--r--libcxx/include/__filesystem/directory_iterator.h39
-rw-r--r--libcxx/include/__filesystem/directory_options.h4
-rw-r--r--libcxx/include/__filesystem/file_status.h4
-rw-r--r--libcxx/include/__filesystem/file_time_type.h7
-rw-r--r--libcxx/include/__filesystem/file_type.h4
-rw-r--r--libcxx/include/__filesystem/filesystem_error.h4
-rw-r--r--libcxx/include/__filesystem/operations.h198
-rw-r--r--libcxx/include/__filesystem/path.h228
-rw-r--r--libcxx/include/__filesystem/path_iterator.h6
-rw-r--r--libcxx/include/__filesystem/perm_options.h4
-rw-r--r--libcxx/include/__filesystem/perms.h4
-rw-r--r--libcxx/include/__filesystem/recursive_directory_iterator.h8
-rw-r--r--libcxx/include/__filesystem/space_info.h4
-rw-r--r--libcxx/include/__filesystem/u8path.h12
-rw-r--r--libcxx/include/__format/buffer.h369
-rw-r--r--libcxx/include/__format/concepts.h53
-rw-r--r--libcxx/include/__format/enable_insertable.h35
-rw-r--r--libcxx/include/__format/format_arg.h317
-rw-r--r--libcxx/include/__format/format_arg_store.h253
-rw-r--r--libcxx/include/__format/format_args.h58
-rw-r--r--libcxx/include/__format/format_context.h34
-rw-r--r--libcxx/include/__format/format_error.h2
-rw-r--r--libcxx/include/__format/format_fwd.h25
-rw-r--r--libcxx/include/__format/format_parse_context.h10
-rw-r--r--libcxx/include/__format/format_string.h12
-rw-r--r--libcxx/include/__format/format_to_n_result.h7
-rw-r--r--libcxx/include/__format/formatter.h25
-rw-r--r--libcxx/include/__format/formatter_bool.h134
-rw-r--r--libcxx/include/__format/formatter_char.h100
-rw-r--r--libcxx/include/__format/formatter_floating_point.h17
-rw-r--r--libcxx/include/__format/formatter_integer.h163
-rw-r--r--libcxx/include/__format/formatter_integral.h612
-rw-r--r--libcxx/include/__format/formatter_output.h304
-rw-r--r--libcxx/include/__format/formatter_pointer.h62
-rw-r--r--libcxx/include/__format/formatter_string.h119
-rw-r--r--libcxx/include/__format/parser_std_format_spec.h649
-rw-r--r--libcxx/include/__functional/binary_function.h27
-rw-r--r--libcxx/include/__functional/binary_negate.h8
-rw-r--r--libcxx/include/__functional/bind.h15
-rw-r--r--libcxx/include/__functional/bind_back.h13
-rw-r--r--libcxx/include/__functional/bind_front.h4
-rw-r--r--libcxx/include/__functional/binder1st.h5
-rw-r--r--libcxx/include/__functional/binder2nd.h5
-rw-r--r--libcxx/include/__functional/boyer_moore_searcher.h313
-rw-r--r--libcxx/include/__functional/compose.h2
-rw-r--r--libcxx/include/__functional/default_searcher.h4
-rw-r--r--libcxx/include/__functional/function.h21
-rw-r--r--libcxx/include/__functional/hash.h231
-rw-r--r--libcxx/include/__functional/identity.h13
-rw-r--r--libcxx/include/__functional/invoke.h541
-rw-r--r--libcxx/include/__functional/is_transparent.h2
-rw-r--r--libcxx/include/__functional/mem_fn.h114
-rw-r--r--libcxx/include/__functional/mem_fun_ref.h18
-rw-r--r--libcxx/include/__functional/not_fn.h5
-rw-r--r--libcxx/include/__functional/operations.h208
-rw-r--r--libcxx/include/__functional/perfect_forward.h105
-rw-r--r--libcxx/include/__functional/pointer_to_binary_function.h4
-rw-r--r--libcxx/include/__functional/pointer_to_unary_function.h4
-rw-r--r--libcxx/include/__functional/ranges_operations.h10
-rw-r--r--libcxx/include/__functional/reference_wrapper.h116
-rw-r--r--libcxx/include/__functional/unary_function.h26
-rw-r--r--libcxx/include/__functional/unary_negate.h4
-rw-r--r--libcxx/include/__functional/unwrap_ref.h2
-rw-r--r--libcxx/include/__functional/weak_result_type.h304
-rw-r--r--libcxx/include/__functional_base32
-rw-r--r--libcxx/include/__fwd/span.h37
-rw-r--r--libcxx/include/__fwd/string_view.h37
-rw-r--r--libcxx/include/__hash_table199
-rw-r--r--libcxx/include/__ios/fpos.h79
-rw-r--r--libcxx/include/__iterator/access.h2
-rw-r--r--libcxx/include/__iterator/advance.h54
-rw-r--r--libcxx/include/__iterator/back_insert_iterator.h4
-rw-r--r--libcxx/include/__iterator/bounded_iter.h229
-rw-r--r--libcxx/include/__iterator/common_iterator.h39
-rw-r--r--libcxx/include/__iterator/concepts.h24
-rw-r--r--libcxx/include/__iterator/counted_iterator.h10
-rw-r--r--libcxx/include/__iterator/data.h2
-rw-r--r--libcxx/include/__iterator/default_sentinel.h6
-rw-r--r--libcxx/include/__iterator/distance.h6
-rw-r--r--libcxx/include/__iterator/empty.h2
-rw-r--r--libcxx/include/__iterator/erase_if_container.h2
-rw-r--r--libcxx/include/__iterator/front_insert_iterator.h2
-rw-r--r--libcxx/include/__iterator/incrementable_traits.h6
-rw-r--r--libcxx/include/__iterator/indirectly_comparable.h8
-rw-r--r--libcxx/include/__iterator/insert_iterator.h4
-rw-r--r--libcxx/include/__iterator/istream_iterator.h15
-rw-r--r--libcxx/include/__iterator/istreambuf_iterator.h18
-rw-r--r--libcxx/include/__iterator/iter_move.h74
-rw-r--r--libcxx/include/__iterator/iter_swap.h7
-rw-r--r--libcxx/include/__iterator/iterator.h2
-rw-r--r--libcxx/include/__iterator/iterator_traits.h67
-rw-r--r--libcxx/include/__iterator/mergeable.h41
-rw-r--r--libcxx/include/__iterator/move_iterator.h175
-rw-r--r--libcxx/include/__iterator/move_sentinel.h57
-rw-r--r--libcxx/include/__iterator/next.h18
-rw-r--r--libcxx/include/__iterator/ostream_iterator.h3
-rw-r--r--libcxx/include/__iterator/ostreambuf_iterator.h3
-rw-r--r--libcxx/include/__iterator/permutable.h35
-rw-r--r--libcxx/include/__iterator/prev.h13
-rw-r--r--libcxx/include/__iterator/projected.h6
-rw-r--r--libcxx/include/__iterator/readable_traits.h6
-rw-r--r--libcxx/include/__iterator/reverse_access.h8
-rw-r--r--libcxx/include/__iterator/reverse_iterator.h175
-rw-r--r--libcxx/include/__iterator/size.h7
-rw-r--r--libcxx/include/__iterator/sortable.h37
-rw-r--r--libcxx/include/__iterator/unreachable_sentinel.h6
-rw-r--r--libcxx/include/__iterator/wrap_iter.h16
-rw-r--r--libcxx/include/__libcpp_version1
-rw-r--r--libcxx/include/__locale27
-rw-r--r--libcxx/include/__mbstate_t.h2
-rw-r--r--libcxx/include/__memory/addressof.h2
-rw-r--r--libcxx/include/__memory/allocate_at_least.h61
-rw-r--r--libcxx/include/__memory/allocation_guard.h4
-rw-r--r--libcxx/include/__memory/allocator.h25
-rw-r--r--libcxx/include/__memory/allocator_arg_t.h4
-rw-r--r--libcxx/include/__memory/allocator_traits.h2
-rw-r--r--libcxx/include/__memory/assume_aligned.h46
-rw-r--r--libcxx/include/__memory/auto_ptr.h7
-rw-r--r--libcxx/include/__memory/compressed_pair.h157
-rw-r--r--libcxx/include/__memory/concepts.h8
-rw-r--r--libcxx/include/__memory/construct_at.h30
-rw-r--r--libcxx/include/__memory/pointer_traits.h9
-rw-r--r--libcxx/include/__memory/ranges_construct_at.h6
-rw-r--r--libcxx/include/__memory/ranges_uninitialized_algorithms.h8
-rw-r--r--libcxx/include/__memory/raw_storage_iterator.h7
-rw-r--r--libcxx/include/__memory/shared_ptr.h277
-rw-r--r--libcxx/include/__memory/temporary_buffer.h10
-rw-r--r--libcxx/include/__memory/uninitialized_algorithms.h153
-rw-r--r--libcxx/include/__memory/unique_ptr.h27
-rw-r--r--libcxx/include/__memory/uses_allocator.h9
-rw-r--r--libcxx/include/__mutex_base7
-rw-r--r--libcxx/include/__node_handle4
-rw-r--r--libcxx/include/__nullptr61
-rw-r--r--libcxx/include/__numeric/accumulate.h2
-rw-r--r--libcxx/include/__numeric/gcd_lcm.h2
-rw-r--r--libcxx/include/__numeric/inner_product.h2
-rw-r--r--libcxx/include/__random/bernoulli_distribution.h4
-rw-r--r--libcxx/include/__random/binomial_distribution.h5
-rw-r--r--libcxx/include/__random/cauchy_distribution.h4
-rw-r--r--libcxx/include/__random/chi_squared_distribution.h2
-rw-r--r--libcxx/include/__random/clamp_to_integral.h2
-rw-r--r--libcxx/include/__random/default_random_engine.h2
-rw-r--r--libcxx/include/__random/discard_block_engine.h2
-rw-r--r--libcxx/include/__random/discrete_distribution.h5
-rw-r--r--libcxx/include/__random/exponential_distribution.h4
-rw-r--r--libcxx/include/__random/extreme_value_distribution.h4
-rw-r--r--libcxx/include/__random/fisher_f_distribution.h4
-rw-r--r--libcxx/include/__random/gamma_distribution.h4
-rw-r--r--libcxx/include/__random/generate_canonical.h2
-rw-r--r--libcxx/include/__random/geometric_distribution.h4
-rw-r--r--libcxx/include/__random/independent_bits_engine.h2
-rw-r--r--libcxx/include/__random/is_seed_sequence.h2
-rw-r--r--libcxx/include/__random/is_valid.h58
-rw-r--r--libcxx/include/__random/knuth_b.h2
-rw-r--r--libcxx/include/__random/linear_congruential_engine.h6
-rw-r--r--libcxx/include/__random/log2.h2
-rw-r--r--libcxx/include/__random/lognormal_distribution.h2
-rw-r--r--libcxx/include/__random/mersenne_twister_engine.h2
-rw-r--r--libcxx/include/__random/negative_binomial_distribution.h5
-rw-r--r--libcxx/include/__random/normal_distribution.h4
-rw-r--r--libcxx/include/__random/piecewise_constant_distribution.h4
-rw-r--r--libcxx/include/__random/piecewise_linear_distribution.h4
-rw-r--r--libcxx/include/__random/poisson_distribution.h5
-rw-r--r--libcxx/include/__random/random_device.h12
-rw-r--r--libcxx/include/__random/ranlux.h2
-rw-r--r--libcxx/include/__random/seed_seq.h76
-rw-r--r--libcxx/include/__random/shuffle_order_engine.h2
-rw-r--r--libcxx/include/__random/student_t_distribution.h4
-rw-r--r--libcxx/include/__random/subtract_with_carry_engine.h2
-rw-r--r--libcxx/include/__random/uniform_int_distribution.h7
-rw-r--r--libcxx/include/__random/uniform_random_bit_generator.h6
-rw-r--r--libcxx/include/__random/uniform_real_distribution.h4
-rw-r--r--libcxx/include/__random/weibull_distribution.h2
-rw-r--r--libcxx/include/__ranges/access.h26
-rw-r--r--libcxx/include/__ranges/all.h25
-rw-r--r--libcxx/include/__ranges/common_view.h22
-rw-r--r--libcxx/include/__ranges/concepts.h14
-rw-r--r--libcxx/include/__ranges/copyable_box.h36
-rw-r--r--libcxx/include/__ranges/counted.h22
-rw-r--r--libcxx/include/__ranges/dangling.h6
-rw-r--r--libcxx/include/__ranges/data.h10
-rw-r--r--libcxx/include/__ranges/drop_view.h201
-rw-r--r--libcxx/include/__ranges/empty.h6
-rw-r--r--libcxx/include/__ranges/empty_view.h13
-rw-r--r--libcxx/include/__ranges/enable_borrowed_range.h9
-rw-r--r--libcxx/include/__ranges/enable_view.h6
-rw-r--r--libcxx/include/__ranges/filter_view.h259
-rw-r--r--libcxx/include/__ranges/iota_view.h116
-rw-r--r--libcxx/include/__ranges/join_view.h60
-rw-r--r--libcxx/include/__ranges/lazy_split_view.h465
-rw-r--r--libcxx/include/__ranges/non_propagating_cache.h12
-rw-r--r--libcxx/include/__ranges/owning_view.h12
-rw-r--r--libcxx/include/__ranges/range_adaptor.h12
-rw-r--r--libcxx/include/__ranges/rbegin.h130
-rw-r--r--libcxx/include/__ranges/ref_view.h8
-rw-r--r--libcxx/include/__ranges/rend.h134
-rw-r--r--libcxx/include/__ranges/reverse_view.h48
-rw-r--r--libcxx/include/__ranges/single_view.h34
-rw-r--r--libcxx/include/__ranges/size.h161
-rw-r--r--libcxx/include/__ranges/subrange.h37
-rw-r--r--libcxx/include/__ranges/take_view.h396
-rw-r--r--libcxx/include/__ranges/transform_view.h42
-rw-r--r--libcxx/include/__ranges/view_interface.h45
-rw-r--r--libcxx/include/__ranges/views.h35
-rw-r--r--libcxx/include/__ranges/zip_view.h511
-rw-r--r--libcxx/include/__split_buffer42
-rw-r--r--libcxx/include/__std_stream2
-rw-r--r--libcxx/include/__string/char_traits.h (renamed from libcxx/include/__string)444
-rw-r--r--libcxx/include/__string/extern_template_lists.h131
-rw-r--r--libcxx/include/__thread/poll_with_backoff.h8
-rw-r--r--libcxx/include/__thread/timed_backoff_policy.h6
-rw-r--r--libcxx/include/__threading_support67
-rw-r--r--libcxx/include/__tree44
-rw-r--r--libcxx/include/__tuple7
-rw-r--r--libcxx/include/__type_traits/add_const.h30
-rw-r--r--libcxx/include/__type_traits/add_cv.h30
-rw-r--r--libcxx/include/__type_traits/add_lvalue_reference.h33
-rw-r--r--libcxx/include/__type_traits/add_pointer.h41
-rw-r--r--libcxx/include/__type_traits/add_rvalue_reference.h33
-rw-r--r--libcxx/include/__type_traits/add_volatile.h30
-rw-r--r--libcxx/include/__type_traits/alignment_of.h32
-rw-r--r--libcxx/include/__type_traits/apply_cv.h76
-rw-r--r--libcxx/include/__type_traits/conditional.h53
-rw-r--r--libcxx/include/__type_traits/conjunction.h57
-rw-r--r--libcxx/include/__type_traits/decay.h65
-rw-r--r--libcxx/include/__type_traits/disjunction.h53
-rw-r--r--libcxx/include/__type_traits/enable_if.h31
-rw-r--r--libcxx/include/__type_traits/extent.h55
-rw-r--r--libcxx/include/__type_traits/has_unique_object_representation.h36
-rw-r--r--libcxx/include/__type_traits/has_virtual_destructor.h40
-rw-r--r--libcxx/include/__type_traits/integral_constant.h50
-rw-r--r--libcxx/include/__type_traits/is_abstract.h31
-rw-r--r--libcxx/include/__type_traits/is_aggregate.h33
-rw-r--r--libcxx/include/__type_traits/is_arithmetic.h34
-rw-r--r--libcxx/include/__type_traits/is_array.h52
-rw-r--r--libcxx/include/__type_traits/is_assignable.h66
-rw-r--r--libcxx/include/__type_traits/is_base_of.h32
-rw-r--r--libcxx/include/__type_traits/is_bounded_array.h38
-rw-r--r--libcxx/include/__type_traits/is_callable.h32
-rw-r--r--libcxx/include/__type_traits/is_class.h33
-rw-r--r--libcxx/include/__type_traits/is_compound.h46
-rw-r--r--libcxx/include/__type_traits/is_const.h45
-rw-r--r--libcxx/include/__type_traits/is_constant_evaluated.h32
-rw-r--r--libcxx/include/__type_traits/is_constructible.h33
-rw-r--r--libcxx/include/__type_traits/is_convertible.h108
-rw-r--r--libcxx/include/__type_traits/is_copy_assignable.h35
-rw-r--r--libcxx/include/__type_traits/is_copy_constructible.h36
-rw-r--r--libcxx/include/__type_traits/is_core_convertible.h36
-rw-r--r--libcxx/include/__type_traits/is_default_constructible.h34
-rw-r--r--libcxx/include/__type_traits/is_destructible.h102
-rw-r--r--libcxx/include/__type_traits/is_empty.h32
-rw-r--r--libcxx/include/__type_traits/is_enum.h32
-rw-r--r--libcxx/include/__type_traits/is_final.h36
-rw-r--r--libcxx/include/__type_traits/is_floating_point.h37
-rw-r--r--libcxx/include/__type_traits/is_function.h43
-rw-r--r--libcxx/include/__type_traits/is_fundamental.h49
-rw-r--r--libcxx/include/__type_traits/is_integral.h72
-rw-r--r--libcxx/include/__type_traits/is_literal_type.h34
-rw-r--r--libcxx/include/__type_traits/is_member_function_pointer.h64
-rw-r--r--libcxx/include/__type_traits/is_member_object_pointer.h46
-rw-r--r--libcxx/include/__type_traits/is_member_pointer.h45
-rw-r--r--libcxx/include/__type_traits/is_move_assignable.h36
-rw-r--r--libcxx/include/__type_traits/is_move_constructible.h35
-rw-r--r--libcxx/include/__type_traits/is_nothrow_assignable.h59
-rw-r--r--libcxx/include/__type_traits/is_nothrow_constructible.h75
-rw-r--r--libcxx/include/__type_traits/is_nothrow_copy_assignable.h35
-rw-r--r--libcxx/include/__type_traits/is_nothrow_copy_constructible.h35
-rw-r--r--libcxx/include/__type_traits/is_nothrow_default_constructible.h33
-rw-r--r--libcxx/include/__type_traits/is_nothrow_destructible.h90
-rw-r--r--libcxx/include/__type_traits/is_nothrow_move_assignable.h36
-rw-r--r--libcxx/include/__type_traits/is_nothrow_move_constructible.h34
-rw-r--r--libcxx/include/__type_traits/is_null_pointer.h41
-rw-r--r--libcxx/include/__type_traits/is_object.h52
-rw-r--r--libcxx/include/__type_traits/is_pod.h43
-rw-r--r--libcxx/include/__type_traits/is_pointer.h57
-rw-r--r--libcxx/include/__type_traits/is_polymorphic.h32
-rw-r--r--libcxx/include/__type_traits/is_reference.h70
-rw-r--r--libcxx/include/__type_traits/is_reference_wrapper.h31
-rw-r--r--libcxx/include/__type_traits/is_referenceable.h33
-rw-r--r--libcxx/include/__type_traits/is_same.h44
-rw-r--r--libcxx/include/__type_traits/is_scalar.h61
-rw-r--r--libcxx/include/__type_traits/is_scoped_enum.h42
-rw-r--r--libcxx/include/__type_traits/is_signed.h55
-rw-r--r--libcxx/include/__type_traits/is_standard_layout.h36
-rw-r--r--libcxx/include/__type_traits/is_trivial.h37
-rw-r--r--libcxx/include/__type_traits/is_trivially_assignable.h33
-rw-r--r--libcxx/include/__type_traits/is_trivially_constructible.h34
-rw-r--r--libcxx/include/__type_traits/is_trivially_copy_assignable.h35
-rw-r--r--libcxx/include/__type_traits/is_trivially_copy_constructible.h34
-rw-r--r--libcxx/include/__type_traits/is_trivially_copyable.h32
-rw-r--r--libcxx/include/__type_traits/is_trivially_default_constructible.h33
-rw-r--r--libcxx/include/__type_traits/is_trivially_destructible.h52
-rw-r--r--libcxx/include/__type_traits/is_trivially_move_assignable.h36
-rw-r--r--libcxx/include/__type_traits/is_trivially_move_constructible.h34
-rw-r--r--libcxx/include/__type_traits/is_unbounded_array.h37
-rw-r--r--libcxx/include/__type_traits/is_union.h32
-rw-r--r--libcxx/include/__type_traits/is_unsigned.h58
-rw-r--r--libcxx/include/__type_traits/is_void.h45
-rw-r--r--libcxx/include/__type_traits/is_volatile.h45
-rw-r--r--libcxx/include/__type_traits/negation.h33
-rw-r--r--libcxx/include/__type_traits/rank.h36
-rw-r--r--libcxx/include/__type_traits/remove_all_extents.h34
-rw-r--r--libcxx/include/__type_traits/remove_const.h28
-rw-r--r--libcxx/include/__type_traits/remove_cv.h30
-rw-r--r--libcxx/include/__type_traits/remove_extent.h34
-rw-r--r--libcxx/include/__type_traits/remove_pointer.h32
-rw-r--r--libcxx/include/__type_traits/remove_reference.h31
-rw-r--r--libcxx/include/__type_traits/remove_volatile.h28
-rw-r--r--libcxx/include/__type_traits/type_identity.h33
-rw-r--r--libcxx/include/__type_traits/underlying_type.h41
-rw-r--r--libcxx/include/__type_traits/void_t.h29
-rw-r--r--libcxx/include/__undef_macros21
-rw-r--r--libcxx/include/__utility/as_const.h2
-rw-r--r--libcxx/include/__utility/auto_cast.h2
-rw-r--r--libcxx/include/__utility/cmp.h11
-rw-r--r--libcxx/include/__utility/declval.h2
-rw-r--r--libcxx/include/__utility/exchange.h2
-rw-r--r--libcxx/include/__utility/forward.h5
-rw-r--r--libcxx/include/__utility/in_place.h2
-rw-r--r--libcxx/include/__utility/integer_sequence.h2
-rw-r--r--libcxx/include/__utility/move.h7
-rw-r--r--libcxx/include/__utility/pair.h26
-rw-r--r--libcxx/include/__utility/piecewise_construct.h2
-rw-r--r--libcxx/include/__utility/priority_tag.h2
-rw-r--r--libcxx/include/__utility/rel_ops.h2
-rw-r--r--libcxx/include/__utility/swap.h2
-rw-r--r--libcxx/include/__utility/to_underlying.h2
-rw-r--r--libcxx/include/__utility/transaction.h2
-rw-r--r--libcxx/include/__utility/unreachable.h38
-rw-r--r--libcxx/include/__variant/monostate.h2
-rw-r--r--libcxx/include/algorithm571
-rw-r--r--libcxx/include/any14
-rw-r--r--libcxx/include/array53
-rw-r--r--libcxx/include/atomic31
-rw-r--r--libcxx/include/barrier48
-rw-r--r--libcxx/include/bit306
-rw-r--r--libcxx/include/bitset26
-rw-r--r--libcxx/include/cassert3
-rw-r--r--libcxx/include/ccomplex5
-rw-r--r--libcxx/include/cctype3
-rw-r--r--libcxx/include/cerrno3
-rw-r--r--libcxx/include/cfenv3
-rw-r--r--libcxx/include/cfloat3
-rw-r--r--libcxx/include/charconv344
-rw-r--r--libcxx/include/chrono14
-rw-r--r--libcxx/include/cinttypes3
-rw-r--r--libcxx/include/ciso6463
-rw-r--r--libcxx/include/climits3
-rw-r--r--libcxx/include/clocale3
-rw-r--r--libcxx/include/cmath3
-rw-r--r--libcxx/include/codecvt33
-rw-r--r--libcxx/include/compare3
-rw-r--r--libcxx/include/complex3
-rw-r--r--libcxx/include/complex.h2
-rw-r--r--libcxx/include/concepts3
-rw-r--r--libcxx/include/condition_variable3
-rw-r--r--libcxx/include/coroutine10
-rw-r--r--libcxx/include/csetjmp3
-rw-r--r--libcxx/include/csignal8
-rw-r--r--libcxx/include/cstdarg3
-rw-r--r--libcxx/include/cstdbool3
-rw-r--r--libcxx/include/cstddef49
-rw-r--r--libcxx/include/cstdint3
-rw-r--r--libcxx/include/cstdio3
-rw-r--r--libcxx/include/cstdlib15
-rw-r--r--libcxx/include/cstring3
-rw-r--r--libcxx/include/ctgmath3
-rw-r--r--libcxx/include/ctime21
-rw-r--r--libcxx/include/ctype.h2
-rw-r--r--libcxx/include/cuchar61
-rw-r--r--libcxx/include/cwchar3
-rw-r--r--libcxx/include/cwctype3
-rw-r--r--libcxx/include/deque59
-rw-r--r--libcxx/include/errno.h2
-rw-r--r--libcxx/include/exception17
-rw-r--r--libcxx/include/execution3
-rw-r--r--libcxx/include/experimental/__config15
-rw-r--r--libcxx/include/experimental/__memory3
-rw-r--r--libcxx/include/experimental/algorithm3
-rw-r--r--libcxx/include/experimental/coroutine15
-rw-r--r--libcxx/include/experimental/deque4
-rw-r--r--libcxx/include/experimental/filesystem256
-rw-r--r--libcxx/include/experimental/forward_list4
-rw-r--r--libcxx/include/experimental/functional75
-rw-r--r--libcxx/include/experimental/iterator4
-rw-r--r--libcxx/include/experimental/list4
-rw-r--r--libcxx/include/experimental/map4
-rw-r--r--libcxx/include/experimental/memory_resource6
-rw-r--r--libcxx/include/experimental/propagate_const10
-rw-r--r--libcxx/include/experimental/regex4
-rw-r--r--libcxx/include/experimental/set4
-rw-r--r--libcxx/include/experimental/simd16
-rw-r--r--libcxx/include/experimental/string4
-rw-r--r--libcxx/include/experimental/type_traits3
-rw-r--r--libcxx/include/experimental/unordered_map12
-rw-r--r--libcxx/include/experimental/unordered_set4
-rw-r--r--libcxx/include/experimental/utility3
-rw-r--r--libcxx/include/experimental/vector4
-rw-r--r--libcxx/include/ext/__hash26
-rw-r--r--libcxx/include/ext/hash_map8
-rw-r--r--libcxx/include/ext/hash_set8
-rw-r--r--libcxx/include/fenv.h2
-rw-r--r--libcxx/include/filesystem10
-rw-r--r--libcxx/include/float.h2
-rw-r--r--libcxx/include/format522
-rw-r--r--libcxx/include/forward_list40
-rw-r--r--libcxx/include/fstream44
-rw-r--r--libcxx/include/functional19
-rw-r--r--libcxx/include/future60
-rw-r--r--libcxx/include/initializer_list3
-rw-r--r--libcxx/include/inttypes.h2
-rw-r--r--libcxx/include/iomanip175
-rw-r--r--libcxx/include/ios18
-rw-r--r--libcxx/include/iosfwd5
-rw-r--r--libcxx/include/iostream7
-rw-r--r--libcxx/include/istream12
-rw-r--r--libcxx/include/iterator161
-rw-r--r--libcxx/include/latch11
-rw-r--r--libcxx/include/limits16
-rw-r--r--libcxx/include/limits.h2
-rw-r--r--libcxx/include/list228
-rw-r--r--libcxx/include/locale140
-rw-r--r--libcxx/include/locale.h4
-rw-r--r--libcxx/include/map65
-rw-r--r--libcxx/include/math.h88
-rw-r--r--libcxx/include/memory57
-rw-r--r--libcxx/include/module.modulemap.in (renamed from libcxx/include/module.modulemap)464
-rw-r--r--libcxx/include/mutex8
-rw-r--r--libcxx/include/new14
-rw-r--r--libcxx/include/numbers7
-rw-r--r--libcxx/include/numeric10
-rw-r--r--libcxx/include/optional61
-rw-r--r--libcxx/include/ostream12
-rw-r--r--libcxx/include/queue18
-rw-r--r--libcxx/include/random13
-rw-r--r--libcxx/include/ranges100
-rw-r--r--libcxx/include/ratio15
-rw-r--r--libcxx/include/regex37
-rw-r--r--libcxx/include/scoped_allocator3
-rw-r--r--libcxx/include/semaphore7
-rw-r--r--libcxx/include/set37
-rw-r--r--libcxx/include/setjmp.h2
-rw-r--r--libcxx/include/shared_mutex9
-rw-r--r--libcxx/include/span255
-rw-r--r--libcxx/include/sstream12
-rw-r--r--libcxx/include/stack11
-rw-r--r--libcxx/include/stdatomic.h235
-rw-r--r--libcxx/include/stdbool.h3
-rw-r--r--libcxx/include/stddef.h11
-rw-r--r--libcxx/include/stdexcept3
-rw-r--r--libcxx/include/stdint.h2
-rw-r--r--libcxx/include/stdio.h4
-rw-r--r--libcxx/include/stdlib.h4
-rw-r--r--libcxx/include/streambuf11
-rw-r--r--libcxx/include/string2105
-rw-r--r--libcxx/include/string.h2
-rw-r--r--libcxx/include/string_view81
-rw-r--r--libcxx/include/strstream9
-rw-r--r--libcxx/include/system_error20
-rw-r--r--libcxx/include/tgmath.h2
-rw-r--r--libcxx/include/thread30
-rw-r--r--libcxx/include/tuple472
-rw-r--r--libcxx/include/type_traits2842
-rw-r--r--libcxx/include/typeindex16
-rw-r--r--libcxx/include/typeinfo3
-rw-r--r--libcxx/include/uchar.h52
-rw-r--r--libcxx/include/unordered_map65
-rw-r--r--libcxx/include/unordered_set125
-rw-r--r--libcxx/include/utility20
-rw-r--r--libcxx/include/valarray122
-rw-r--r--libcxx/include/variant47
-rw-r--r--libcxx/include/vector452
-rw-r--r--libcxx/include/version62
-rw-r--r--libcxx/include/wchar.h4
-rw-r--r--libcxx/include/wctype.h2
695 files changed, 26111 insertions, 13707 deletions
diff --git a/libcxx/include/__algorithm/adjacent_find.h b/libcxx/include/__algorithm/adjacent_find.h
index 29ad83f96810..83d8c260f27a 100644
--- a/libcxx/include/__algorithm/adjacent_find.h
+++ b/libcxx/include/__algorithm/adjacent_find.h
@@ -15,7 +15,7 @@
#include <__iterator/iterator_traits.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/all_of.h b/libcxx/include/__algorithm/all_of.h
index 817a4bc89ca0..3af32a577504 100644
--- a/libcxx/include/__algorithm/all_of.h
+++ b/libcxx/include/__algorithm/all_of.h
@@ -13,7 +13,7 @@
#include <__config>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/any_of.h b/libcxx/include/__algorithm/any_of.h
index f4116d913059..6fe6a0b6b3c4 100644
--- a/libcxx/include/__algorithm/any_of.h
+++ b/libcxx/include/__algorithm/any_of.h
@@ -13,7 +13,7 @@
#include <__config>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/binary_search.h b/libcxx/include/__algorithm/binary_search.h
index 2558dd0b27b9..121a741d070b 100644
--- a/libcxx/include/__algorithm/binary_search.h
+++ b/libcxx/include/__algorithm/binary_search.h
@@ -16,28 +16,20 @@
#include <__iterator/iterator_traits.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-template <class _Compare, class _ForwardIterator, class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
-bool
-__binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp)
-{
- __first = _VSTD::__lower_bound<_Compare>(__first, __last, __value_, __comp);
- return __first != __last && !__comp(__value_, *__first);
-}
-
template <class _ForwardIterator, class _Tp, class _Compare>
_LIBCPP_NODISCARD_EXT inline
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
bool
binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp)
{
- typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
- return _VSTD::__binary_search<_Comp_ref>(__first, __last, __value_, __comp);
+ using _Comp_ref = typename __comp_ref_type<_Compare>::type;
+ __first = std::lower_bound<_ForwardIterator, _Tp, _Comp_ref>(__first, __last, __value_, __comp);
+ return __first != __last && !__comp(__value_, *__first);
}
template <class _ForwardIterator, class _Tp>
@@ -46,8 +38,8 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
bool
binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_)
{
- return _VSTD::binary_search(__first, __last, __value_,
- __less<typename iterator_traits<_ForwardIterator>::value_type, _Tp>());
+ return std::binary_search(__first, __last, __value_,
+ __less<typename iterator_traits<_ForwardIterator>::value_type, _Tp>());
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/clamp.h b/libcxx/include/__algorithm/clamp.h
index a51c1015be3f..b3762b85a0bc 100644
--- a/libcxx/include/__algorithm/clamp.h
+++ b/libcxx/include/__algorithm/clamp.h
@@ -10,11 +10,11 @@
#define _LIBCPP___ALGORITHM_CLAMP_H
#include <__algorithm/comp.h>
+#include <__assert>
#include <__config>
-#include <__debug>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/comp.h b/libcxx/include/__algorithm/comp.h
index b3f971e4f052..62c06ae57f23 100644
--- a/libcxx/include/__algorithm/comp.h
+++ b/libcxx/include/__algorithm/comp.h
@@ -12,7 +12,7 @@
#include <__config>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/comp_ref_type.h b/libcxx/include/__algorithm/comp_ref_type.h
index 6cc6405686f5..4719871461cf 100644
--- a/libcxx/include/__algorithm/comp_ref_type.h
+++ b/libcxx/include/__algorithm/comp_ref_type.h
@@ -10,29 +10,24 @@
#define _LIBCPP___ALGORITHM_COMP_REF_TYPE_H
#include <__config>
-
-#ifdef _LIBCPP_DEBUG
-# include <__debug>
-# include <__utility/declval.h>
-#endif
+#include <__debug>
+#include <__utility/declval.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#ifdef _LIBCPP_DEBUG
-
template <class _Compare>
struct __debug_less
{
_Compare &__comp_;
- _LIBCPP_CONSTEXPR_AFTER_CXX17
+ _LIBCPP_CONSTEXPR_AFTER_CXX11
__debug_less(_Compare& __c) : __comp_(__c) {}
template <class _Tp, class _Up>
- _LIBCPP_CONSTEXPR_AFTER_CXX17
+ _LIBCPP_CONSTEXPR_AFTER_CXX11
bool operator()(const _Tp& __x, const _Up& __y)
{
bool __r = __comp_(__x, __y);
@@ -42,7 +37,7 @@ struct __debug_less
}
template <class _Tp, class _Up>
- _LIBCPP_CONSTEXPR_AFTER_CXX17
+ _LIBCPP_CONSTEXPR_AFTER_CXX11
bool operator()(_Tp& __x, _Up& __y)
{
bool __r = __comp_(__x, __y);
@@ -52,31 +47,31 @@ struct __debug_less
}
template <class _LHS, class _RHS>
- _LIBCPP_CONSTEXPR_AFTER_CXX17
+ _LIBCPP_CONSTEXPR_AFTER_CXX11
inline _LIBCPP_INLINE_VISIBILITY
decltype((void)declval<_Compare&>()(
declval<_LHS &>(), declval<_RHS &>()))
__do_compare_assert(int, _LHS & __l, _RHS & __r) {
- _LIBCPP_ASSERT(!__comp_(__l, __r),
+ _LIBCPP_DEBUG_ASSERT(!__comp_(__l, __r),
"Comparator does not induce a strict weak ordering");
+ (void)__l;
+ (void)__r;
}
template <class _LHS, class _RHS>
- _LIBCPP_CONSTEXPR_AFTER_CXX17
+ _LIBCPP_CONSTEXPR_AFTER_CXX11
inline _LIBCPP_INLINE_VISIBILITY
void __do_compare_assert(long, _LHS &, _RHS &) {}
};
-#endif // _LIBCPP_DEBUG
-
template <class _Comp>
struct __comp_ref_type {
// Pass the comparator by lvalue reference. Or in debug mode, using a
// debugging wrapper that stores a reference.
-#ifndef _LIBCPP_DEBUG
- typedef _Comp& type;
-#else
+#ifdef _LIBCPP_ENABLE_DEBUG_MODE
typedef __debug_less<_Comp> type;
+#else
+ typedef _Comp& type;
#endif
};
diff --git a/libcxx/include/__algorithm/copy.h b/libcxx/include/__algorithm/copy.h
index 65f0e0b0ef7d..886a1ac6ce3e 100644
--- a/libcxx/include/__algorithm/copy.h
+++ b/libcxx/include/__algorithm/copy.h
@@ -12,64 +12,93 @@
#include <__algorithm/unwrap_iter.h>
#include <__config>
#include <__iterator/iterator_traits.h>
+#include <__iterator/reverse_iterator.h>
+#include <__utility/move.h>
+#include <__utility/pair.h>
#include <cstring>
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
// copy
-template <class _InputIterator, class _OutputIterator>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
-_OutputIterator
-__copy_constexpr(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
-{
- for (; __first != __last; ++__first, (void) ++__result)
- *__result = *__first;
- return __result;
+template <class _InIter, class _Sent, class _OutIter>
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11
+pair<_InIter, _OutIter> __copy_impl(_InIter __first, _Sent __last, _OutIter __result) {
+ while (__first != __last) {
+ *__result = *__first;
+ ++__first;
+ ++__result;
+ }
+ return pair<_InIter, _OutIter>(std::move(__first), std::move(__result));
}
-template <class _InputIterator, class _OutputIterator>
-inline _LIBCPP_INLINE_VISIBILITY
-_OutputIterator
-__copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
-{
- return _VSTD::__copy_constexpr(__first, __last, __result);
+template <class _InValueT,
+ class _OutValueT,
+ class = __enable_if_t<is_same<typename remove_const<_InValueT>::type, _OutValueT>::value
+ && is_trivially_copy_assignable<_OutValueT>::value> >
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11
+pair<_InValueT*, _OutValueT*> __copy_impl(_InValueT* __first, _InValueT* __last, _OutValueT* __result) {
+ if (__libcpp_is_constant_evaluated()
+// TODO: Remove this once GCC supports __builtin_memmove during constant evaluation
+#ifndef _LIBCPP_COMPILER_GCC
+ && !is_trivially_copyable<_InValueT>::value
+#endif
+ )
+ return std::__copy_impl<_InValueT*, _InValueT*, _OutValueT*>(__first, __last, __result);
+ const size_t __n = static_cast<size_t>(__last - __first);
+ if (__n > 0)
+ ::__builtin_memmove(__result, __first, __n * sizeof(_OutValueT));
+ return std::make_pair(__first + __n, __result + __n);
+}
+
+template <class _InIter, class _OutIter,
+ __enable_if_t<is_same<typename remove_const<__iter_value_type<_InIter> >::type, __iter_value_type<_OutIter> >::value
+ && __is_cpp17_contiguous_iterator<_InIter>::value
+ && __is_cpp17_contiguous_iterator<_OutIter>::value
+ && is_trivially_copy_assignable<__iter_value_type<_OutIter> >::value, int> = 0>
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11
+pair<reverse_iterator<_InIter>, reverse_iterator<_OutIter> >
+__copy_impl(reverse_iterator<_InIter> __first,
+ reverse_iterator<_InIter> __last,
+ reverse_iterator<_OutIter> __result) {
+ auto __first_base = std::__unwrap_iter(__first.base());
+ auto __last_base = std::__unwrap_iter(__last.base());
+ auto __result_base = std::__unwrap_iter(__result.base());
+ auto __result_first = __result_base - (__first_base - __last_base);
+ std::__copy_impl(__last_base, __first_base, __result_first);
+ return std::make_pair(__last, reverse_iterator<_OutIter>(std::__rewrap_iter(__result.base(), __result_first)));
+}
+
+template <class _InIter, class _Sent, class _OutIter,
+ __enable_if_t<!(is_copy_constructible<_InIter>::value
+ && is_copy_constructible<_Sent>::value
+ && is_copy_constructible<_OutIter>::value), int> = 0 >
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11
+pair<_InIter, _OutIter> __copy(_InIter __first, _Sent __last, _OutIter __result) {
+ return std::__copy_impl(std::move(__first), std::move(__last), std::move(__result));
}
-template <class _Tp, class _Up>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
- is_same<typename remove_const<_Tp>::type, _Up>::value &&
- is_trivially_copy_assignable<_Up>::value,
- _Up*
->::type
-__copy(_Tp* __first, _Tp* __last, _Up* __result)
-{
- const size_t __n = static_cast<size_t>(__last - __first);
- if (__n > 0)
- _VSTD::memmove(__result, __first, __n * sizeof(_Up));
- return __result + __n;
+template <class _InIter, class _Sent, class _OutIter,
+ __enable_if_t<is_copy_constructible<_InIter>::value
+ && is_copy_constructible<_Sent>::value
+ && is_copy_constructible<_OutIter>::value, int> = 0>
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11
+pair<_InIter, _OutIter>
+__copy(_InIter __first, _Sent __last, _OutIter __result) {
+ auto __ret = std::__copy_impl(std::__unwrap_iter(__first), std::__unwrap_iter(__last), std::__unwrap_iter(__result));
+ return std::make_pair(std::__rewrap_iter(__first, __ret.first), std::__rewrap_iter(__result, __ret.second));
}
template <class _InputIterator, class _OutputIterator>
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
_OutputIterator
-copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
-{
- if (__libcpp_is_constant_evaluated()) {
- return _VSTD::__copy_constexpr(__first, __last, __result);
- } else {
- return _VSTD::__rewrap_iter(__result,
- _VSTD::__copy(_VSTD::__unwrap_iter(__first),
- _VSTD::__unwrap_iter(__last),
- _VSTD::__unwrap_iter(__result)));
- }
+copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result) {
+ return std::__copy(__first, __last, __result).second;
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/copy_backward.h b/libcxx/include/__algorithm/copy_backward.h
index ac733290abe4..dd43a91ffa87 100644
--- a/libcxx/include/__algorithm/copy_backward.h
+++ b/libcxx/include/__algorithm/copy_backward.h
@@ -9,69 +9,43 @@
#ifndef _LIBCPP___ALGORITHM_COPY_BACKWARD_H
#define _LIBCPP___ALGORITHM_COPY_BACKWARD_H
+#include <__algorithm/copy.h>
#include <__algorithm/unwrap_iter.h>
#include <__config>
#include <__iterator/iterator_traits.h>
+#include <__iterator/reverse_iterator.h>
#include <cstring>
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-template <class _BidirectionalIterator, class _OutputIterator>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
-_OutputIterator
-__copy_backward_constexpr(_BidirectionalIterator __first, _BidirectionalIterator __last, _OutputIterator __result)
-{
- while (__first != __last)
- *--__result = *--__last;
- return __result;
+template <class _Iter1, class _Sent1, class _Iter2>
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11
+pair<_Iter1, _Iter2> __copy_backward_impl(_Iter1 __first, _Sent1 __last, _Iter2 __result) {
+ auto __ret = std::__copy(reverse_iterator<_Iter1>(__last),
+ reverse_iterator<_Sent1>(__first),
+ reverse_iterator<_Iter2>(__result));
+ return pair<_Iter1, _Iter2>(__ret.first.base(), __ret.second.base());
}
-template <class _BidirectionalIterator, class _OutputIterator>
-inline _LIBCPP_INLINE_VISIBILITY
-_OutputIterator
-__copy_backward(_BidirectionalIterator __first, _BidirectionalIterator __last, _OutputIterator __result)
-{
- return _VSTD::__copy_backward_constexpr(__first, __last, __result);
-}
-
-template <class _Tp, class _Up>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
- is_same<typename remove_const<_Tp>::type, _Up>::value &&
- is_trivially_copy_assignable<_Up>::value,
- _Up*
->::type
-__copy_backward(_Tp* __first, _Tp* __last, _Up* __result)
-{
- const size_t __n = static_cast<size_t>(__last - __first);
- if (__n > 0)
- {
- __result -= __n;
- _VSTD::memmove(__result, __first, __n * sizeof(_Up));
- }
- return __result;
+template <class _Iter1, class _Sent1, class _Iter2>
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11
+pair<_Iter1, _Iter2> __copy_backward(_Iter1 __first, _Sent1 __last, _Iter2 __result) {
+ auto __ret = std::__copy_backward_impl(std::__unwrap_iter(__first),
+ std::__unwrap_iter(__last),
+ std::__unwrap_iter(__result));
+ return pair<_Iter1, _Iter2>(std::__rewrap_iter(__first, __ret.first), std::__rewrap_iter(__result, __ret.second));
}
template <class _BidirectionalIterator1, class _BidirectionalIterator2>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
_BidirectionalIterator2
-copy_backward(_BidirectionalIterator1 __first, _BidirectionalIterator1 __last,
- _BidirectionalIterator2 __result)
-{
- if (__libcpp_is_constant_evaluated()) {
- return _VSTD::__copy_backward_constexpr(__first, __last, __result);
- } else {
- return _VSTD::__rewrap_iter(__result,
- _VSTD::__copy_backward(_VSTD::__unwrap_iter(__first),
- _VSTD::__unwrap_iter(__last),
- _VSTD::__unwrap_iter(__result)));
- }
+copy_backward(_BidirectionalIterator1 __first, _BidirectionalIterator1 __last, _BidirectionalIterator2 __result) {
+ return std::__copy_backward(__first, __last, __result).second;
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/copy_if.h b/libcxx/include/__algorithm/copy_if.h
index d32514d999b5..9c3cd29e2413 100644
--- a/libcxx/include/__algorithm/copy_if.h
+++ b/libcxx/include/__algorithm/copy_if.h
@@ -12,7 +12,7 @@
#include <__config>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/copy_n.h b/libcxx/include/__algorithm/copy_n.h
index cdcc0d50dbf1..8b915af63c0d 100644
--- a/libcxx/include/__algorithm/copy_n.h
+++ b/libcxx/include/__algorithm/copy_n.h
@@ -15,7 +15,7 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/count.h b/libcxx/include/__algorithm/count.h
index 81a2c186f83b..e18128cae8a8 100644
--- a/libcxx/include/__algorithm/count.h
+++ b/libcxx/include/__algorithm/count.h
@@ -14,7 +14,7 @@
#include <__iterator/iterator_traits.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/count_if.h b/libcxx/include/__algorithm/count_if.h
index 00f5d671da57..1ec2d83394e1 100644
--- a/libcxx/include/__algorithm/count_if.h
+++ b/libcxx/include/__algorithm/count_if.h
@@ -14,7 +14,7 @@
#include <__iterator/iterator_traits.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/equal.h b/libcxx/include/__algorithm/equal.h
index 4c9ad05ad6b8..ca1bc6bc5665 100644
--- a/libcxx/include/__algorithm/equal.h
+++ b/libcxx/include/__algorithm/equal.h
@@ -16,7 +16,7 @@
#include <__iterator/iterator_traits.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/equal_range.h b/libcxx/include/__algorithm/equal_range.h
index e13f0bdd9695..2a07364bb66f 100644
--- a/libcxx/include/__algorithm/equal_range.h
+++ b/libcxx/include/__algorithm/equal_range.h
@@ -12,13 +12,18 @@
#include <__algorithm/comp.h>
#include <__algorithm/comp_ref_type.h>
#include <__algorithm/half_positive.h>
+#include <__algorithm/iterator_operations.h>
#include <__algorithm/lower_bound.h>
#include <__algorithm/upper_bound.h>
#include <__config>
-#include <iterator>
+#include <__functional/identity.h>
+#include <__iterator/advance.h>
+#include <__iterator/distance.h>
+#include <__iterator/iterator_traits.h>
+#include <__utility/pair.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -46,10 +51,11 @@ __equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __va
}
else
{
+ auto __proj = std::__identity();
_ForwardIterator __mp1 = __m;
return pair<_ForwardIterator, _ForwardIterator>
(
- _VSTD::__lower_bound<_Compare>(__first, __m, __value_, __comp),
+ _VSTD::__lower_bound_impl<_StdIterOps>(__first, __m, __value_, __comp, __proj),
_VSTD::__upper_bound<_Compare>(++__mp1, __last, __value_, __comp)
);
}
diff --git a/libcxx/include/__algorithm/fill.h b/libcxx/include/__algorithm/fill.h
index 0cb36b02c831..be5b4740a52a 100644
--- a/libcxx/include/__algorithm/fill.h
+++ b/libcxx/include/__algorithm/fill.h
@@ -15,7 +15,7 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/fill_n.h b/libcxx/include/__algorithm/fill_n.h
index 857ac1415731..590c8f38f3fd 100644
--- a/libcxx/include/__algorithm/fill_n.h
+++ b/libcxx/include/__algorithm/fill_n.h
@@ -14,7 +14,7 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/find.h b/libcxx/include/__algorithm/find.h
index 2a6dfbe41a94..641b85e2f645 100644
--- a/libcxx/include/__algorithm/find.h
+++ b/libcxx/include/__algorithm/find.h
@@ -13,7 +13,7 @@
#include <__config>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/find_end.h b/libcxx/include/__algorithm/find_end.h
index dd0f7d7ac03d..0220c0939711 100644
--- a/libcxx/include/__algorithm/find_end.h
+++ b/libcxx/include/__algorithm/find_end.h
@@ -15,7 +15,7 @@
#include <__iterator/iterator_traits.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/find_first_of.h b/libcxx/include/__algorithm/find_first_of.h
index 69354f61769f..b968329fc318 100644
--- a/libcxx/include/__algorithm/find_first_of.h
+++ b/libcxx/include/__algorithm/find_first_of.h
@@ -15,7 +15,7 @@
#include <__iterator/iterator_traits.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/find_if.h b/libcxx/include/__algorithm/find_if.h
index a94196a16ac5..aa98171a1f61 100644
--- a/libcxx/include/__algorithm/find_if.h
+++ b/libcxx/include/__algorithm/find_if.h
@@ -13,7 +13,7 @@
#include <__config>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/find_if_not.h b/libcxx/include/__algorithm/find_if_not.h
index e057db5efa49..61ddab0b9805 100644
--- a/libcxx/include/__algorithm/find_if_not.h
+++ b/libcxx/include/__algorithm/find_if_not.h
@@ -13,7 +13,7 @@
#include <__config>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/for_each.h b/libcxx/include/__algorithm/for_each.h
index 1612ffa5c002..bfbd37c3a3a4 100644
--- a/libcxx/include/__algorithm/for_each.h
+++ b/libcxx/include/__algorithm/for_each.h
@@ -13,7 +13,7 @@
#include <__config>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/for_each_n.h b/libcxx/include/__algorithm/for_each_n.h
index 00e3fb9c1db8..2552b40c2781 100644
--- a/libcxx/include/__algorithm/for_each_n.h
+++ b/libcxx/include/__algorithm/for_each_n.h
@@ -14,7 +14,7 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/generate.h b/libcxx/include/__algorithm/generate.h
index 10834cdb7438..dacbd8c68195 100644
--- a/libcxx/include/__algorithm/generate.h
+++ b/libcxx/include/__algorithm/generate.h
@@ -12,7 +12,7 @@
#include <__config>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/generate_n.h b/libcxx/include/__algorithm/generate_n.h
index 595007cdd34b..2650e9e5d8b7 100644
--- a/libcxx/include/__algorithm/generate_n.h
+++ b/libcxx/include/__algorithm/generate_n.h
@@ -13,7 +13,7 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/half_positive.h b/libcxx/include/__algorithm/half_positive.h
index 5d36ff5da985..7666ef1449c6 100644
--- a/libcxx/include/__algorithm/half_positive.h
+++ b/libcxx/include/__algorithm/half_positive.h
@@ -13,7 +13,7 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/in_found_result.h b/libcxx/include/__algorithm/in_found_result.h
new file mode 100644
index 000000000000..d43f45cd80ef
--- /dev/null
+++ b/libcxx/include/__algorithm/in_found_result.h
@@ -0,0 +1,49 @@
+// -*- 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___ALGORITHM_IN_FOUND_RESULT_H
+#define _LIBCPP___ALGORITHM_IN_FOUND_RESULT_H
+
+#include <__concepts/convertible_to.h>
+#include <__config>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+template <class _InIter1>
+struct in_found_result {
+ _LIBCPP_NO_UNIQUE_ADDRESS _InIter1 in;
+ bool found;
+
+ template <class _InIter2>
+ requires convertible_to<const _InIter1&, _InIter2>
+ _LIBCPP_HIDE_FROM_ABI constexpr operator in_found_result<_InIter2>() const & {
+ return {in, found};
+ }
+
+ template <class _InIter2>
+ requires convertible_to<_InIter1, _InIter2>
+ _LIBCPP_HIDE_FROM_ABI constexpr operator in_found_result<_InIter2>() && {
+ return {std::move(in), found};
+ }
+};
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_IN_FOUND_RESULT_H
diff --git a/libcxx/include/__algorithm/in_fun_result.h b/libcxx/include/__algorithm/in_fun_result.h
new file mode 100644
index 000000000000..21efa655063d
--- /dev/null
+++ b/libcxx/include/__algorithm/in_fun_result.h
@@ -0,0 +1,49 @@
+// -*- 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___ALGORITHM_IN_FUN_RESULT_H
+#define _LIBCPP___ALGORITHM_IN_FUN_RESULT_H
+
+#include <__concepts/convertible_to.h>
+#include <__config>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+namespace ranges {
+template <class _InIter1, class _Func1>
+struct in_fun_result {
+ _LIBCPP_NO_UNIQUE_ADDRESS _InIter1 in;
+ _LIBCPP_NO_UNIQUE_ADDRESS _Func1 fun;
+
+ template <class _InIter2, class _Func2>
+ requires convertible_to<const _InIter1&, _InIter2> && convertible_to<const _Func1&, _Func2>
+ _LIBCPP_HIDE_FROM_ABI constexpr operator in_fun_result<_InIter2, _Func2>() const & {
+ return {in, fun};
+ }
+
+ template <class _InIter2, class _Func2>
+ requires convertible_to<_InIter1, _InIter2> && convertible_to<_Func1, _Func2>
+ _LIBCPP_HIDE_FROM_ABI constexpr operator in_fun_result<_InIter2, _Func2>() && {
+ return {std::move(in), std::move(fun)};
+ }
+};
+} // namespace ranges
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___ALGORITHM_IN_FUN_RESULT_H
diff --git a/libcxx/include/__algorithm/in_in_out_result.h b/libcxx/include/__algorithm/in_in_out_result.h
index e365eb58eb62..e45fef187e0d 100644
--- a/libcxx/include/__algorithm/in_in_out_result.h
+++ b/libcxx/include/__algorithm/in_in_out_result.h
@@ -14,35 +14,43 @@
#include <__config>
#include <__utility/move.h>
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
_LIBCPP_BEGIN_NAMESPACE_STD
-#ifndef _LIBCPP_HAS_NO_CONCEPTS
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
namespace ranges {
-template <class _I1, class _I2, class _O1>
+
+template <class _InIter1, class _InIter2, class _OutIter1>
struct in_in_out_result {
- [[no_unique_address]] _I1 in1;
- [[no_unique_address]] _I2 in2;
- [[no_unique_address]] _O1 out;
+ _LIBCPP_NO_UNIQUE_ADDRESS _InIter1 in1;
+ _LIBCPP_NO_UNIQUE_ADDRESS _InIter2 in2;
+ _LIBCPP_NO_UNIQUE_ADDRESS _OutIter1 out;
- template <class _II1, class _II2, class _OO1>
- requires convertible_to<const _I1&, _II1> && convertible_to<const _I2&, _II2> && convertible_to<const _O1&, _OO1>
+ template <class _InIter3, class _InIter4, class _OutIter2>
+ requires convertible_to<const _InIter1&, _InIter3>
+ && convertible_to<const _InIter2&, _InIter4> && convertible_to<const _OutIter1&, _OutIter2>
_LIBCPP_HIDE_FROM_ABI constexpr
- operator in_in_out_result<_II1, _II2, _OO1>() const& {
+ operator in_in_out_result<_InIter3, _InIter4, _OutIter2>() const& {
return {in1, in2, out};
}
- template <class _II1, class _II2, class _OO1>
- requires convertible_to<_I1, _II1> && convertible_to<_I2, _II2> && convertible_to<_O1, _OO1>
+ template <class _InIter3, class _InIter4, class _OutIter2>
+ requires convertible_to<_InIter1, _InIter3>
+ && convertible_to<_InIter2, _InIter4> && convertible_to<_OutIter1, _OutIter2>
_LIBCPP_HIDE_FROM_ABI constexpr
- operator in_in_out_result<_II1, _II2, _OO1>() && {
- return {_VSTD::move(in1), _VSTD::move(in2), _VSTD::move(out)};
+ operator in_in_out_result<_InIter3, _InIter4, _OutIter2>() && {
+ return {std::move(in1), std::move(in2), std::move(out)};
}
};
+
} // namespace ranges
-#endif // _LIBCPP_HAS_NO_CONCEPTS
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
_LIBCPP_END_NAMESPACE_STD
-#endif // _LIBCPP___ALGORITHM_IN_IN_RESULT_H
+#endif // _LIBCPP___ALGORITHM_IN_IN_OUT_RESULT_H
diff --git a/libcxx/include/__algorithm/in_in_result.h b/libcxx/include/__algorithm/in_in_result.h
index ed14ecedbbdf..39e64ced33b2 100644
--- a/libcxx/include/__algorithm/in_in_result.h
+++ b/libcxx/include/__algorithm/in_in_result.h
@@ -14,31 +14,39 @@
#include <__config>
#include <__utility/move.h>
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
_LIBCPP_BEGIN_NAMESPACE_STD
-#ifndef _LIBCPP_HAS_NO_CONCEPTS
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
namespace ranges {
-template <class _I1, class _I2>
+
+template <class _InIter1, class _InIter2>
struct in_in_result {
- [[no_unique_address]] _I1 in1;
- [[no_unique_address]] _I2 in2;
+ _LIBCPP_NO_UNIQUE_ADDRESS _InIter1 in1;
+ _LIBCPP_NO_UNIQUE_ADDRESS _InIter2 in2;
- template <class _II1, class _II2>
- requires convertible_to<const _I1&, _II1> && convertible_to<const _I2&, _II2>
+ template <class _InIter3, class _InIter4>
+ requires convertible_to<const _InIter1&, _InIter3> && convertible_to<const _InIter2&, _InIter4>
_LIBCPP_HIDE_FROM_ABI constexpr
- operator in_in_result<_II1, _II2>() const & {
+ operator in_in_result<_InIter3, _InIter4>() const & {
return {in1, in2};
}
- template <class _II1, class _II2>
- requires convertible_to<_I1, _II1> && convertible_to<_I2, _II2>
+ template <class _InIter3, class _InIter4>
+ requires convertible_to<_InIter1, _InIter3> && convertible_to<_InIter2, _InIter4>
_LIBCPP_HIDE_FROM_ABI constexpr
- operator in_in_result<_II1, _II2>() && { return {_VSTD::move(in1), _VSTD::move(in2)}; }
+ operator in_in_result<_InIter3, _InIter4>() && {
+ return {std::move(in1), std::move(in2)};
+ }
};
+
} // namespace ranges
-#endif // _LIBCPP_HAS_NO_CONCEPTS
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/in_out_out_result.h b/libcxx/include/__algorithm/in_out_out_result.h
new file mode 100644
index 000000000000..52a883b17627
--- /dev/null
+++ b/libcxx/include/__algorithm/in_out_out_result.h
@@ -0,0 +1,54 @@
+// -*- 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___ALGORITHM_IN_OUT_OUT_RESULT_H
+#define _LIBCPP___ALGORITHM_IN_OUT_OUT_RESULT_H
+
+#include <__concepts/convertible_to.h>
+#include <__config>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+namespace ranges {
+template <class _InIter1, class _OutIter1, class _OutIter2>
+struct in_out_out_result {
+ _LIBCPP_NO_UNIQUE_ADDRESS _InIter1 in;
+ _LIBCPP_NO_UNIQUE_ADDRESS _OutIter1 out1;
+ _LIBCPP_NO_UNIQUE_ADDRESS _OutIter2 out2;
+
+ template <class _InIter2, class _OutIter3, class _OutIter4>
+ requires convertible_to<const _InIter1&, _InIter2>
+ && convertible_to<const _OutIter1&, _OutIter3> && convertible_to<const _OutIter2&, _OutIter4>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ operator in_out_out_result<_InIter2, _OutIter3, _OutIter4>() const& {
+ return {in, out1, out2};
+ }
+
+ template <class _InIter2, class _OutIter3, class _OutIter4>
+ requires convertible_to<_InIter1, _InIter2>
+ && convertible_to<_OutIter1, _OutIter3> && convertible_to<_OutIter2, _OutIter4>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ operator in_out_out_result<_InIter2, _OutIter3, _OutIter4>() && {
+ return {std::move(in), std::move(out1), std::move(out2)};
+ }
+};
+} // namespace ranges
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___ALGORITHM_IN_OUT_OUT_RESULT_H
diff --git a/libcxx/include/__algorithm/in_out_result.h b/libcxx/include/__algorithm/in_out_result.h
index 8a58d6ada10c..47e6f3907943 100644
--- a/libcxx/include/__algorithm/in_out_result.h
+++ b/libcxx/include/__algorithm/in_out_result.h
@@ -15,37 +15,38 @@
#include <__utility/move.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
namespace ranges {
-template<class _InputIterator, class _OutputIterator>
+template<class _InIter1, class _OutIter1>
struct in_out_result {
- [[no_unique_address]] _InputIterator in;
- [[no_unique_address]] _OutputIterator out;
+ _LIBCPP_NO_UNIQUE_ADDRESS _InIter1 in;
+ _LIBCPP_NO_UNIQUE_ADDRESS _OutIter1 out;
- template <class _InputIterator2, class _OutputIterator2>
- requires convertible_to<const _InputIterator&, _InputIterator2> && convertible_to<const _OutputIterator&,
- _OutputIterator2>
+ template <class _InIter2, class _OutIter2>
+ requires convertible_to<const _InIter1&, _InIter2> && convertible_to<const _OutIter1&, _OutIter2>
_LIBCPP_HIDE_FROM_ABI
- constexpr operator in_out_result<_InputIterator2, _OutputIterator2>() const & {
+ constexpr operator in_out_result<_InIter2, _OutIter2>() const & {
return {in, out};
}
- template <class _InputIterator2, class _OutputIterator2>
- requires convertible_to<_InputIterator, _InputIterator2> && convertible_to<_OutputIterator, _OutputIterator2>
+ template <class _InIter2, class _OutIter2>
+ requires convertible_to<_InIter1, _InIter2> && convertible_to<_OutIter1, _OutIter2>
_LIBCPP_HIDE_FROM_ABI
- constexpr operator in_out_result<_InputIterator2, _OutputIterator2>() && {
- return {_VSTD::move(in), _VSTD::move(out)};
+ constexpr operator in_out_result<_InIter2, _OutIter2>() && {
+ return {std::move(in), std::move(out)};
}
};
} // namespace ranges
-#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/includes.h b/libcxx/include/__algorithm/includes.h
index 9d0bc694c0d3..4c87e8d22116 100644
--- a/libcxx/include/__algorithm/includes.h
+++ b/libcxx/include/__algorithm/includes.h
@@ -15,7 +15,7 @@
#include <__iterator/iterator_traits.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/inplace_merge.h b/libcxx/include/__algorithm/inplace_merge.h
index e6f1efc011b1..58919ddbae76 100644
--- a/libcxx/include/__algorithm/inplace_merge.h
+++ b/libcxx/include/__algorithm/inplace_merge.h
@@ -17,12 +17,15 @@
#include <__algorithm/rotate.h>
#include <__algorithm/upper_bound.h>
#include <__config>
+#include <__iterator/advance.h>
+#include <__iterator/distance.h>
#include <__iterator/iterator_traits.h>
+#include <__iterator/reverse_iterator.h>
#include <__utility/swap.h>
#include <memory>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
@@ -166,7 +169,7 @@ __inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle,
__len11 = __len1 / 2;
__m1 = __first;
_VSTD::advance(__m1, __len11);
- __m2 = _VSTD::__lower_bound<_Compare>(__middle, __last, *__m1, __comp);
+ __m2 = std::lower_bound(__middle, __last, *__m1, __comp);
__len21 = _VSTD::distance(__middle, __m2);
}
difference_type __len12 = __len1 - __len11; // distance(__m1, __middle)
@@ -208,7 +211,10 @@ inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _
difference_type __len1 = _VSTD::distance(__first, __middle);
difference_type __len2 = _VSTD::distance(__middle, __last);
difference_type __buf_size = _VSTD::min(__len1, __len2);
+// TODO: Remove the use of std::get_temporary_buffer
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
pair<value_type*, ptrdiff_t> __buf = _VSTD::get_temporary_buffer<value_type>(__buf_size);
+_LIBCPP_SUPPRESS_DEPRECATED_POP
unique_ptr<value_type, __return_temporary_buffer> __h(__buf.first);
typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
return _VSTD::__inplace_merge<_Comp_ref>(__first, __middle, __last, __comp, __len1, __len2,
diff --git a/libcxx/include/__algorithm/is_heap.h b/libcxx/include/__algorithm/is_heap.h
index 925ba8bfb8bd..fe44e634f6dd 100644
--- a/libcxx/include/__algorithm/is_heap.h
+++ b/libcxx/include/__algorithm/is_heap.h
@@ -16,7 +16,7 @@
#include <__iterator/iterator_traits.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/is_heap_until.h b/libcxx/include/__algorithm/is_heap_until.h
index aa23b6d039d3..39f313eb0d3f 100644
--- a/libcxx/include/__algorithm/is_heap_until.h
+++ b/libcxx/include/__algorithm/is_heap_until.h
@@ -15,7 +15,7 @@
#include <__iterator/iterator_traits.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/is_partitioned.h b/libcxx/include/__algorithm/is_partitioned.h
index e5b2214aa069..b4f421cfc053 100644
--- a/libcxx/include/__algorithm/is_partitioned.h
+++ b/libcxx/include/__algorithm/is_partitioned.h
@@ -12,7 +12,7 @@
#include <__config>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/is_permutation.h b/libcxx/include/__algorithm/is_permutation.h
index 344aa763ad0e..cdd742048412 100644
--- a/libcxx/include/__algorithm/is_permutation.h
+++ b/libcxx/include/__algorithm/is_permutation.h
@@ -17,7 +17,7 @@
#include <__iterator/next.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/is_sorted.h b/libcxx/include/__algorithm/is_sorted.h
index 57953295a888..56de95bb31b7 100644
--- a/libcxx/include/__algorithm/is_sorted.h
+++ b/libcxx/include/__algorithm/is_sorted.h
@@ -16,7 +16,7 @@
#include <__iterator/iterator_traits.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/is_sorted_until.h b/libcxx/include/__algorithm/is_sorted_until.h
index 57cad47761d9..338d28508c17 100644
--- a/libcxx/include/__algorithm/is_sorted_until.h
+++ b/libcxx/include/__algorithm/is_sorted_until.h
@@ -15,7 +15,7 @@
#include <__iterator/iterator_traits.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/iter_swap.h b/libcxx/include/__algorithm/iter_swap.h
index 9f7d0d77630c..038859e1361d 100644
--- a/libcxx/include/__algorithm/iter_swap.h
+++ b/libcxx/include/__algorithm/iter_swap.h
@@ -14,7 +14,7 @@
#include <__utility/swap.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/iterator_operations.h b/libcxx/include/__algorithm/iterator_operations.h
new file mode 100644
index 000000000000..c02f9bf649df
--- /dev/null
+++ b/libcxx/include/__algorithm/iterator_operations.h
@@ -0,0 +1,47 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___ALGORIHTM_ITERATOR_OPERATIONS_H
+#define _LIBCPP___ALGORIHTM_ITERATOR_OPERATIONS_H
+
+#include <__config>
+#include <__iterator/advance.h>
+#include <__iterator/distance.h>
+#include <__iterator/iterator_traits.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+struct _RangesIterOps {
+ static constexpr auto advance = ranges::advance;
+ static constexpr auto distance = ranges::distance;
+};
+#endif
+
+struct _StdIterOps {
+
+ template <class _Iterator, class _Distance>
+ _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_AFTER_CXX11 void advance(_Iterator& __iter, _Distance __count) {
+ return std::advance(__iter, __count);
+ }
+
+ template <class _Iterator>
+ _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_AFTER_CXX11
+ typename iterator_traits<_Iterator>::difference_type distance(_Iterator __first, _Iterator __last) {
+ return std::distance(__first, __last);
+ }
+
+};
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___ALGORIHTM_ITERATOR_OPERATIONS_H
diff --git a/libcxx/include/__algorithm/lexicographical_compare.h b/libcxx/include/__algorithm/lexicographical_compare.h
index 55a1da620125..30ddf2408120 100644
--- a/libcxx/include/__algorithm/lexicographical_compare.h
+++ b/libcxx/include/__algorithm/lexicographical_compare.h
@@ -15,7 +15,7 @@
#include <__iterator/iterator_traits.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/lower_bound.h b/libcxx/include/__algorithm/lower_bound.h
index 663a0b16228e..fbcd5c7e908a 100644
--- a/libcxx/include/__algorithm/lower_bound.h
+++ b/libcxx/include/__algorithm/lower_bound.h
@@ -11,54 +11,55 @@
#include <__algorithm/comp.h>
#include <__algorithm/half_positive.h>
+#include <__algorithm/iterator_operations.h>
#include <__config>
-#include <iterator>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
+#include <__iterator/advance.h>
+#include <__iterator/distance.h>
+#include <__iterator/iterator_traits.h>
+#include <__type_traits/is_callable.h>
+#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-template <class _Compare, class _ForwardIterator, class _Tp>
-_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator
-__lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp)
-{
- typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type;
- difference_type __len = _VSTD::distance(__first, __last);
- while (__len != 0)
- {
- difference_type __l2 = _VSTD::__half_positive(__len);
- _ForwardIterator __m = __first;
- _VSTD::advance(__m, __l2);
- if (__comp(*__m, __value_))
- {
- __first = ++__m;
- __len -= __l2 + 1;
- }
- else
- __len = __l2;
+template <class _IterOps, class _Iter, class _Sent, class _Type, class _Proj, class _Comp>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
+_Iter __lower_bound_impl(_Iter __first, _Sent __last, const _Type& __value, _Comp& __comp, _Proj& __proj) {
+ auto __len = _IterOps::distance(__first, __last);
+
+ while (__len != 0) {
+ auto __l2 = std::__half_positive(__len);
+ _Iter __m = __first;
+ _IterOps::advance(__m, __l2);
+ if (std::__invoke(__comp, std::__invoke(__proj, *__m), __value)) {
+ __first = ++__m;
+ __len -= __l2 + 1;
+ } else {
+ __len = __l2;
}
- return __first;
+ }
+ return __first;
}
template <class _ForwardIterator, class _Tp, class _Compare>
-_LIBCPP_NODISCARD_EXT inline
-_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
-_ForwardIterator
-lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp)
-{
- return _VSTD::__lower_bound<_Compare&>(__first, __last, __value_, __comp);
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
+_ForwardIterator lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp) {
+ static_assert(__is_callable<_Compare, decltype(*__first), const _Tp&>::value,
+ "The comparator has to be callable");
+ auto __proj = std::__identity();
+ return std::__lower_bound_impl<_StdIterOps>(__first, __last, __value_, __comp, __proj);
}
template <class _ForwardIterator, class _Tp>
-_LIBCPP_NODISCARD_EXT inline
-_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
-_ForwardIterator
-lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_)
-{
- return _VSTD::lower_bound(__first, __last, __value_,
- __less<typename iterator_traits<_ForwardIterator>::value_type, _Tp>());
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
+_ForwardIterator lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_) {
+ return std::lower_bound(__first, __last, __value_,
+ __less<typename iterator_traits<_ForwardIterator>::value_type, _Tp>());
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/make_heap.h b/libcxx/include/__algorithm/make_heap.h
index f489addaf5cc..acac0aabf1e4 100644
--- a/libcxx/include/__algorithm/make_heap.h
+++ b/libcxx/include/__algorithm/make_heap.h
@@ -16,7 +16,7 @@
#include <__iterator/iterator_traits.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/make_projected.h b/libcxx/include/__algorithm/make_projected.h
new file mode 100644
index 000000000000..8141c4ed176f
--- /dev/null
+++ b/libcxx/include/__algorithm/make_projected.h
@@ -0,0 +1,51 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_MAKE_PROJECTED_H
+#define _LIBCPP___ALGORITHM_MAKE_PROJECTED_H
+
+#include <__concepts/same_as.h>
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
+#include <__utility/forward.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+
+template <class _Comp, class _Proj>
+_LIBCPP_HIDE_FROM_ABI constexpr static
+decltype(auto) __make_projected_comp(_Comp& __comp, _Proj& __proj) {
+ if constexpr (same_as<_Proj, identity>) {
+ // Avoid creating the lambda and just use the pristine comparator -- for certain algorithms, this would enable
+ // optimizations that rely on the type of the comparator.
+ return __comp;
+
+ } else {
+ return [&](auto&& __lhs, auto&& __rhs) {
+ return std::invoke(__comp,
+ std::invoke(__proj, std::forward<decltype(__lhs)>(__lhs)),
+ std::invoke(__proj, std::forward<decltype(__rhs)>(__rhs)));
+ };
+ }
+}
+
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_MAKE_PROJECTED_H
diff --git a/libcxx/include/__algorithm/max.h b/libcxx/include/__algorithm/max.h
index 0bbc971e0a9c..345b235a2193 100644
--- a/libcxx/include/__algorithm/max.h
+++ b/libcxx/include/__algorithm/max.h
@@ -16,7 +16,7 @@
#include <initializer_list>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
diff --git a/libcxx/include/__algorithm/max_element.h b/libcxx/include/__algorithm/max_element.h
index db2937260582..795ec8e1ddc1 100644
--- a/libcxx/include/__algorithm/max_element.h
+++ b/libcxx/include/__algorithm/max_element.h
@@ -15,7 +15,7 @@
#include <__iterator/iterator_traits.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/merge.h b/libcxx/include/__algorithm/merge.h
index 91826493771a..48360ed5b445 100644
--- a/libcxx/include/__algorithm/merge.h
+++ b/libcxx/include/__algorithm/merge.h
@@ -16,7 +16,7 @@
#include <__iterator/iterator_traits.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/min.h b/libcxx/include/__algorithm/min.h
index ed2d3b87828a..3d8c73d78f11 100644
--- a/libcxx/include/__algorithm/min.h
+++ b/libcxx/include/__algorithm/min.h
@@ -16,7 +16,7 @@
#include <initializer_list>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
diff --git a/libcxx/include/__algorithm/min_element.h b/libcxx/include/__algorithm/min_element.h
index 407c7f93336d..129833d42bda 100644
--- a/libcxx/include/__algorithm/min_element.h
+++ b/libcxx/include/__algorithm/min_element.h
@@ -15,7 +15,7 @@
#include <__iterator/iterator_traits.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/min_max_result.h b/libcxx/include/__algorithm/min_max_result.h
new file mode 100644
index 000000000000..ca77dcc5725a
--- /dev/null
+++ b/libcxx/include/__algorithm/min_max_result.h
@@ -0,0 +1,56 @@
+// -*- 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___ALGORITHM_MIN_MAX_RESULT_H
+#define _LIBCPP___ALGORITHM_MIN_MAX_RESULT_H
+
+#include <__concepts/convertible_to.h>
+#include <__config>
+#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
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+namespace ranges {
+
+template <class _T1>
+struct min_max_result {
+ _LIBCPP_NO_UNIQUE_ADDRESS _T1 min;
+ _LIBCPP_NO_UNIQUE_ADDRESS _T1 max;
+
+ template <class _T2>
+ requires convertible_to<const _T1&, _T2>
+ _LIBCPP_HIDE_FROM_ABI constexpr operator min_max_result<_T2>() const & {
+ return {min, max};
+ }
+
+ template <class _T2>
+ requires convertible_to<_T1, _T2>
+ _LIBCPP_HIDE_FROM_ABI constexpr operator min_max_result<_T2>() && {
+ return {std::move(min), std::move(max)};
+ }
+};
+
+} // namespace ranges
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_MIN_MAX_RESULT_H
diff --git a/libcxx/include/__algorithm/minmax.h b/libcxx/include/__algorithm/minmax.h
index 0bf88a70b8aa..7e10b8b8350c 100644
--- a/libcxx/include/__algorithm/minmax.h
+++ b/libcxx/include/__algorithm/minmax.h
@@ -10,12 +10,15 @@
#define _LIBCPP___ALGORITHM_MINMAX_H
#include <__algorithm/comp.h>
+#include <__algorithm/minmax_element.h>
#include <__config>
+#include <__functional/identity.h>
+#include <__type_traits/is_callable.h>
+#include <__utility/pair.h>
#include <initializer_list>
-#include <utility>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -36,47 +39,18 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
pair<const _Tp&, const _Tp&>
minmax(const _Tp& __a, const _Tp& __b)
{
- return _VSTD::minmax(__a, __b, __less<_Tp>());
+ return std::minmax(__a, __b, __less<_Tp>());
}
#ifndef _LIBCPP_CXX03_LANG
template<class _Tp, class _Compare>
-_LIBCPP_NODISCARD_EXT inline
-_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
-pair<_Tp, _Tp>
-minmax(initializer_list<_Tp> __t, _Compare __comp)
-{
- typedef typename initializer_list<_Tp>::const_iterator _Iter;
- _Iter __first = __t.begin();
- _Iter __last = __t.end();
- pair<_Tp, _Tp> __result(*__first, *__first);
-
- ++__first;
- if (__t.size() % 2 == 0)
- {
- if (__comp(*__first, __result.first))
- __result.first = *__first;
- else
- __result.second = *__first;
- ++__first;
- }
-
- while (__first != __last)
- {
- _Tp __prev = *__first++;
- if (__comp(*__first, __prev)) {
- if ( __comp(*__first, __result.first)) __result.first = *__first;
- if (!__comp(__prev, __result.second)) __result.second = __prev;
- }
- else {
- if ( __comp(__prev, __result.first)) __result.first = __prev;
- if (!__comp(*__first, __result.second)) __result.second = *__first;
- }
-
- __first++;
- }
- return __result;
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11
+pair<_Tp, _Tp> minmax(initializer_list<_Tp> __t, _Compare __comp) {
+ static_assert(__is_callable<_Compare, _Tp, _Tp>::value, "The comparator has to be callable");
+ __identity __proj;
+ auto __ret = std::__minmax_element_impl(__t.begin(), __t.end(), __comp, __proj);
+ return pair<_Tp, _Tp>(*__ret.first, *__ret.second);
}
template<class _Tp>
@@ -85,7 +59,7 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
pair<_Tp, _Tp>
minmax(initializer_list<_Tp> __t)
{
- return _VSTD::minmax(__t, __less<_Tp>());
+ return std::minmax(__t, __less<_Tp>());
}
#endif // _LIBCPP_CXX03_LANG
diff --git a/libcxx/include/__algorithm/minmax_element.h b/libcxx/include/__algorithm/minmax_element.h
index 5d768603843b..fe5f20bf1c7f 100644
--- a/libcxx/include/__algorithm/minmax_element.h
+++ b/libcxx/include/__algorithm/minmax_element.h
@@ -11,73 +11,89 @@
#include <__algorithm/comp.h>
#include <__config>
+#include <__functional/identity.h>
#include <__iterator/iterator_traits.h>
-#include <utility>
+#include <__utility/pair.h>
+#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
+template <class _Comp, class _Proj>
+class _MinmaxElementLessFunc {
+ _Comp& __comp;
+ _Proj& __proj;
+
+public:
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
+ _MinmaxElementLessFunc(_Comp& __comp_, _Proj& __proj_) : __comp(__comp_), __proj(__proj_) {}
+
+ template <class _Iter>
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11
+ bool operator()(_Iter& __it1, _Iter& __it2) {
+ return std::__invoke(__comp, std::__invoke(__proj, *__it1), std::__invoke(__proj, *__it2));
+ }
+};
+
+template <class _Iter, class _Sent, class _Proj, class _Comp>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11
+pair<_Iter, _Iter> __minmax_element_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
+ auto __less = _MinmaxElementLessFunc<_Comp, _Proj>(__comp, __proj);
+
+ pair<_Iter, _Iter> __result(__first, __first);
+ if (__first == __last || ++__first == __last)
+ return __result;
+
+ if (__less(__first, __result.first))
+ __result.first = __first;
+ else
+ __result.second = __first;
+
+ while (++__first != __last) {
+ _Iter __i = __first;
+ if (++__first == __last) {
+ if (__less(__i, __result.first))
+ __result.first = __i;
+ else if (!__less(__i, __result.second))
+ __result.second = __i;
+ return __result;
+ }
+
+ if (__less(__first, __i)) {
+ if (__less(__first, __result.first))
+ __result.first = __first;
+ if (!__less(__i, __result.second))
+ __result.second = __i;
+ } else {
+ if (__less(__i, __result.first))
+ __result.first = __i;
+ if (!__less(__first, __result.second))
+ __result.second = __first;
+ }
+ }
+
+ return __result;
+}
+
template <class _ForwardIterator, class _Compare>
_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_AFTER_CXX11
pair<_ForwardIterator, _ForwardIterator>
-minmax_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
-{
+minmax_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) {
static_assert(__is_cpp17_forward_iterator<_ForwardIterator>::value,
- "std::minmax_element requires a ForwardIterator");
- pair<_ForwardIterator, _ForwardIterator> __result(__first, __first);
- if (__first != __last)
- {
- if (++__first != __last)
- {
- if (__comp(*__first, *__result.first))
- __result.first = __first;
- else
- __result.second = __first;
- while (++__first != __last)
- {
- _ForwardIterator __i = __first;
- if (++__first == __last)
- {
- if (__comp(*__i, *__result.first))
- __result.first = __i;
- else if (!__comp(*__i, *__result.second))
- __result.second = __i;
- break;
- }
- else
- {
- if (__comp(*__first, *__i))
- {
- if (__comp(*__first, *__result.first))
- __result.first = __first;
- if (!__comp(*__i, *__result.second))
- __result.second = __i;
- }
- else
- {
- if (__comp(*__i, *__result.first))
- __result.first = __i;
- if (!__comp(*__first, *__result.second))
- __result.second = __first;
- }
- }
- }
- }
- }
- return __result;
+ "std::minmax_element requires a ForwardIterator");
+ static_assert(__is_callable<_Compare, decltype(*__first), decltype(*__first)>::value,
+ "The comparator has to be callable");
+ auto __proj = __identity();
+ return std::__minmax_element_impl(__first, __last, __comp, __proj);
}
template <class _ForwardIterator>
-_LIBCPP_NODISCARD_EXT inline
-_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
-pair<_ForwardIterator, _ForwardIterator>
-minmax_element(_ForwardIterator __first, _ForwardIterator __last)
-{
- return _VSTD::minmax_element(__first, __last,
- __less<typename iterator_traits<_ForwardIterator>::value_type>());
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11
+pair<_ForwardIterator, _ForwardIterator> minmax_element(_ForwardIterator __first, _ForwardIterator __last) {
+ return std::minmax_element(__first, __last, __less<typename iterator_traits<_ForwardIterator>::value_type>());
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/mismatch.h b/libcxx/include/__algorithm/mismatch.h
index 230ade03df19..f2011faf2f9a 100644
--- a/libcxx/include/__algorithm/mismatch.h
+++ b/libcxx/include/__algorithm/mismatch.h
@@ -13,10 +13,10 @@
#include <__algorithm/comp.h>
#include <__config>
#include <__iterator/iterator_traits.h>
-#include <utility>
+#include <__utility/pair.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/move.h b/libcxx/include/__algorithm/move.h
index fa118f471669..0b08d31c176e 100644
--- a/libcxx/include/__algorithm/move.h
+++ b/libcxx/include/__algorithm/move.h
@@ -11,66 +11,103 @@
#include <__algorithm/unwrap_iter.h>
#include <__config>
+#include <__iterator/iterator_traits.h>
+#include <__iterator/reverse_iterator.h>
#include <__utility/move.h>
+#include <__utility/pair.h>
#include <cstring>
#include <type_traits>
-#include <utility>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
// move
-template <class _InputIterator, class _OutputIterator>
+template <class _InIter, class _Sent, class _OutIter>
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
-_OutputIterator
-__move_constexpr(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
-{
- for (; __first != __last; ++__first, (void) ++__result)
- *__result = _VSTD::move(*__first);
- return __result;
+pair<_InIter, _OutIter> __move_impl(_InIter __first, _Sent __last, _OutIter __result) {
+ while (__first != __last) {
+ *__result = std::move(*__first);
+ ++__first;
+ ++__result;
+ }
+ return std::make_pair(std::move(__first), std::move(__result));
}
-template <class _InputIterator, class _OutputIterator>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
-_OutputIterator
-__move(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
-{
- return _VSTD::__move_constexpr(__first, __last, __result);
+template <class _InType,
+ class _OutType,
+ class = __enable_if_t<is_same<typename remove_const<_InType>::type, _OutType>::value
+ && is_trivially_move_assignable<_OutType>::value> >
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11
+pair<_InType*, _OutType*> __move_impl(_InType* __first, _InType* __last, _OutType* __result) {
+ if (__libcpp_is_constant_evaluated()
+// TODO: Remove this once GCC supports __builtin_memmove during constant evaluation
+#ifndef _LIBCPP_COMPILER_GCC
+ && !is_trivially_copyable<_InType>::value
+#endif
+ )
+ return std::__move_impl<_InType*, _InType*, _OutType*>(__first, __last, __result);
+ const size_t __n = static_cast<size_t>(__last - __first);
+ ::__builtin_memmove(__result, __first, __n * sizeof(_OutType));
+ return std::make_pair(__first + __n, __result + __n);
}
-template <class _Tp, class _Up>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
-typename enable_if
-<
- is_same<typename remove_const<_Tp>::type, _Up>::value &&
- is_trivially_move_assignable<_Up>::value,
- _Up*
->::type
-__move(_Tp* __first, _Tp* __last, _Up* __result)
-{
- const size_t __n = static_cast<size_t>(__last - __first);
- if (__n > 0)
- _VSTD::memmove(__result, __first, __n * sizeof(_Up));
- return __result + __n;
+template <class>
+struct __is_trivially_move_assignable_unwrapped_impl : false_type {};
+
+template <class _Type>
+struct __is_trivially_move_assignable_unwrapped_impl<_Type*> : is_trivially_move_assignable<_Type> {};
+
+template <class _Iter>
+struct __is_trivially_move_assignable_unwrapped
+ : __is_trivially_move_assignable_unwrapped_impl<decltype(std::__unwrap_iter<_Iter>(std::declval<_Iter>()))> {};
+
+template <class _InIter,
+ class _OutIter,
+ __enable_if_t<is_same<typename remove_const<typename iterator_traits<_InIter>::value_type>::type,
+ typename iterator_traits<_OutIter>::value_type>::value
+ && __is_cpp17_contiguous_iterator<_InIter>::value
+ && __is_cpp17_contiguous_iterator<_OutIter>::value
+ && is_trivially_move_assignable<__iter_value_type<_OutIter> >::value, int> = 0>
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14
+pair<reverse_iterator<_InIter>, reverse_iterator<_OutIter> >
+__move_impl(reverse_iterator<_InIter> __first,
+ reverse_iterator<_InIter> __last,
+ reverse_iterator<_OutIter> __result) {
+ auto __first_base = std::__unwrap_iter(__first.base());
+ auto __last_base = std::__unwrap_iter(__last.base());
+ auto __result_base = std::__unwrap_iter(__result.base());
+ auto __result_first = __result_base - (__first_base - __last_base);
+ std::__move_impl(__last_base, __first_base, __result_first);
+ return std::make_pair(__last, reverse_iterator<_OutIter>(std::__rewrap_iter(__result.base(), __result_first)));
+}
+
+template <class _InIter, class _Sent, class _OutIter>
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11
+__enable_if_t<is_copy_constructible<_InIter>::value
+ && is_copy_constructible<_Sent>::value
+ && is_copy_constructible<_OutIter>::value, pair<_InIter, _OutIter> >
+__move(_InIter __first, _Sent __last, _OutIter __result) {
+ auto __ret = std::__move_impl(std::__unwrap_iter(__first), std::__unwrap_iter(__last), std::__unwrap_iter(__result));
+ return std::make_pair(std::__rewrap_iter(__first, __ret.first), std::__rewrap_iter(__result, __ret.second));
+}
+
+template <class _InIter, class _Sent, class _OutIter>
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11
+__enable_if_t<!is_copy_constructible<_InIter>::value
+ || !is_copy_constructible<_Sent>::value
+ || !is_copy_constructible<_OutIter>::value, pair<_InIter, _OutIter> >
+__move(_InIter __first, _Sent __last, _OutIter __result) {
+ return std::__move_impl(std::move(__first), std::move(__last), std::move(__result));
}
template <class _InputIterator, class _OutputIterator>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
-_OutputIterator
-move(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
-{
- if (__libcpp_is_constant_evaluated()) {
- return _VSTD::__move_constexpr(__first, __last, __result);
- } else {
- return _VSTD::__rewrap_iter(__result,
- _VSTD::__move(_VSTD::__unwrap_iter(__first),
- _VSTD::__unwrap_iter(__last),
- _VSTD::__unwrap_iter(__result)));
- }
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
+_OutputIterator move(_InputIterator __first, _InputIterator __last, _OutputIterator __result) {
+ return std::__move(__first, __last, __result).second;
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/move_backward.h b/libcxx/include/__algorithm/move_backward.h
index a4e3828b6069..a56f6b826ce3 100644
--- a/libcxx/include/__algorithm/move_backward.h
+++ b/libcxx/include/__algorithm/move_backward.h
@@ -11,12 +11,12 @@
#include <__algorithm/unwrap_iter.h>
#include <__config>
+#include <__utility/move.h>
#include <cstring>
#include <type_traits>
-#include <utility>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/next_permutation.h b/libcxx/include/__algorithm/next_permutation.h
index eb81cceb7bbc..05e56f4a17ff 100644
--- a/libcxx/include/__algorithm/next_permutation.h
+++ b/libcxx/include/__algorithm/next_permutation.h
@@ -17,7 +17,7 @@
#include <__utility/swap.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/none_of.h b/libcxx/include/__algorithm/none_of.h
index 10339e2418c8..b34b1e00ddb8 100644
--- a/libcxx/include/__algorithm/none_of.h
+++ b/libcxx/include/__algorithm/none_of.h
@@ -13,7 +13,7 @@
#include <__config>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/nth_element.h b/libcxx/include/__algorithm/nth_element.h
index 3afbd6c61846..60b9280f75f0 100644
--- a/libcxx/include/__algorithm/nth_element.h
+++ b/libcxx/include/__algorithm/nth_element.h
@@ -13,6 +13,7 @@
#include <__algorithm/comp_ref_type.h>
#include <__algorithm/sort.h>
#include <__config>
+#include <__debug>
#include <__iterator/iterator_traits.h>
#include <__utility/swap.h>
@@ -21,7 +22,7 @@
#endif
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/partial_sort.h b/libcxx/include/__algorithm/partial_sort.h
index a92a7e56610a..3870c0cc9335 100644
--- a/libcxx/include/__algorithm/partial_sort.h
+++ b/libcxx/include/__algorithm/partial_sort.h
@@ -15,6 +15,7 @@
#include <__algorithm/sift_down.h>
#include <__algorithm/sort_heap.h>
#include <__config>
+#include <__debug>
#include <__iterator/iterator_traits.h>
#include <__utility/swap.h>
@@ -23,7 +24,7 @@
#endif
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/partial_sort_copy.h b/libcxx/include/__algorithm/partial_sort_copy.h
index 67a62bae1f5a..7ed1e538e9b8 100644
--- a/libcxx/include/__algorithm/partial_sort_copy.h
+++ b/libcxx/include/__algorithm/partial_sort_copy.h
@@ -18,7 +18,7 @@
#include <__iterator/iterator_traits.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/partition.h b/libcxx/include/__algorithm/partition.h
index 131c5d3735d5..73d94831ed87 100644
--- a/libcxx/include/__algorithm/partition.h
+++ b/libcxx/include/__algorithm/partition.h
@@ -14,7 +14,7 @@
#include <__utility/swap.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/partition_copy.h b/libcxx/include/__algorithm/partition_copy.h
index d34944589b9e..cacde0bfd47b 100644
--- a/libcxx/include/__algorithm/partition_copy.h
+++ b/libcxx/include/__algorithm/partition_copy.h
@@ -11,10 +11,10 @@
#include <__config>
#include <__iterator/iterator_traits.h>
-#include <utility> // pair
+#include <__utility/pair.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/partition_point.h b/libcxx/include/__algorithm/partition_point.h
index 18e6e6f6812f..1675534e60d5 100644
--- a/libcxx/include/__algorithm/partition_point.h
+++ b/libcxx/include/__algorithm/partition_point.h
@@ -11,10 +11,12 @@
#include <__algorithm/half_positive.h>
#include <__config>
-#include <iterator>
+#include <__iterator/advance.h>
+#include <__iterator/distance.h>
+#include <__iterator/iterator_traits.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/pop_heap.h b/libcxx/include/__algorithm/pop_heap.h
index c1cc8016ac91..2932a5e31dbc 100644
--- a/libcxx/include/__algorithm/pop_heap.h
+++ b/libcxx/include/__algorithm/pop_heap.h
@@ -11,13 +11,14 @@
#include <__algorithm/comp.h>
#include <__algorithm/comp_ref_type.h>
+#include <__algorithm/push_heap.h>
#include <__algorithm/sift_down.h>
#include <__config>
#include <__iterator/iterator_traits.h>
-#include <__utility/swap.h>
+#include <__utility/move.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -28,10 +29,21 @@ void
__pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp,
typename iterator_traits<_RandomAccessIterator>::difference_type __len)
{
+ using value_type = typename iterator_traits<_RandomAccessIterator>::value_type;
+
if (__len > 1)
{
- swap(*__first, *--__last);
- _VSTD::__sift_down<_Compare>(__first, __comp, __len - 1, __first);
+ value_type __top = std::move(*__first); // create a hole at __first
+ _RandomAccessIterator __hole = std::__floyd_sift_down<_Compare>(__first, __comp, __len);
+ --__last;
+ if (__hole == __last) {
+ *__hole = std::move(__top);
+ } else {
+ *__hole = std::move(*__last);
+ ++__hole;
+ *__last = std::move(__top);
+ std::__sift_up<_Compare>(__first, __hole, __comp, __hole - __first);
+ }
}
}
diff --git a/libcxx/include/__algorithm/prev_permutation.h b/libcxx/include/__algorithm/prev_permutation.h
index 457c2695b324..9dbc1dad0124 100644
--- a/libcxx/include/__algorithm/prev_permutation.h
+++ b/libcxx/include/__algorithm/prev_permutation.h
@@ -17,7 +17,7 @@
#include <__utility/swap.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/push_heap.h b/libcxx/include/__algorithm/push_heap.h
index 864d419fa203..66973e082f14 100644
--- a/libcxx/include/__algorithm/push_heap.h
+++ b/libcxx/include/__algorithm/push_heap.h
@@ -16,7 +16,7 @@
#include <__utility/move.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/ranges_adjacent_find.h b/libcxx/include/__algorithm/ranges_adjacent_find.h
new file mode 100644
index 000000000000..e798d568299d
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_adjacent_find.h
@@ -0,0 +1,78 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_RANGES_ADJACENT_FIND_H
+#define _LIBCPP___ALGORITHM_RANGES_ADJACENT_FIND_H
+
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/projected.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/dangling.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+namespace __adjacent_find {
+struct __fn {
+
+ template <class _Iter, class _Sent, class _Proj, class _Pred>
+ _LIBCPP_HIDE_FROM_ABI constexpr static
+ _Iter __adjacent_find_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) {
+ if (__first == __last)
+ return __first;
+
+ auto __i = __first;
+ while (++__i != __last) {
+ if (std::invoke(__pred, std::invoke(__proj, *__first), std::invoke(__proj, *__i)))
+ return __first;
+ __first = __i;
+ }
+ return __i;
+ }
+
+ template <forward_iterator _Iter, sentinel_for<_Iter> _Sent,
+ class _Proj = identity,
+ indirect_binary_predicate<projected<_Iter, _Proj>, projected<_Iter, _Proj>> _Pred = ranges::equal_to>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ _Iter operator()(_Iter __first, _Sent __last, _Pred __pred = {}, _Proj __proj = {}) const {
+ return __adjacent_find_impl(std::move(__first), std::move(__last), __pred, __proj);
+ }
+
+ template <forward_range _Range,
+ class _Proj = identity,
+ indirect_binary_predicate<projected<iterator_t<_Range>, _Proj>,
+ projected<iterator_t<_Range>, _Proj>> _Pred = ranges::equal_to>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ borrowed_iterator_t<_Range> operator()(_Range&& __range, _Pred __pred = {}, _Proj __proj = {}) const {
+ return __adjacent_find_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj);
+ }
+};
+} // namespace __adjacent_find
+
+inline namespace __cpo {
+ inline constexpr auto adjacent_find = __adjacent_find::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_ADJACENT_FIND_H
diff --git a/libcxx/include/__algorithm/ranges_all_of.h b/libcxx/include/__algorithm/ranges_all_of.h
new file mode 100644
index 000000000000..a146865652a7
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_all_of.h
@@ -0,0 +1,68 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_RANGES_ALL_OF_H
+#define _LIBCPP___ALGORITHM_RANGES_ALL_OF_H
+
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
+#include <__iterator/concepts.h>
+#include <__iterator/projected.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+namespace __all_of {
+struct __fn {
+
+ template <class _Iter, class _Sent, class _Proj, class _Pred>
+ _LIBCPP_HIDE_FROM_ABI constexpr static
+ bool __all_of_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) {
+ for (; __first != __last; ++__first) {
+ if (!std::invoke(__pred, std::invoke(__proj, *__first)))
+ return false;
+ }
+ return true;
+ }
+
+ template <input_iterator _Iter, sentinel_for<_Iter> _Sent, class _Proj = identity,
+ indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ bool operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const {
+ return __all_of_impl(std::move(__first), std::move(__last), __pred, __proj);
+ }
+
+ template <input_range _Range, class _Proj = identity,
+ indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ bool operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const {
+ return __all_of_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj);
+ }
+};
+} // namespace __all_of
+
+inline namespace __cpo {
+ inline constexpr auto all_of = __all_of::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_ALL_OF_H
diff --git a/libcxx/include/__algorithm/ranges_any_of.h b/libcxx/include/__algorithm/ranges_any_of.h
new file mode 100644
index 000000000000..11c52cbe21ea
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_any_of.h
@@ -0,0 +1,68 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_RANGES_ANY_OF_H
+#define _LIBCPP___ALGORITHM_RANGES_ANY_OF_H
+
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
+#include <__iterator/concepts.h>
+#include <__iterator/projected.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+namespace __any_of {
+struct __fn {
+
+ template <class _Iter, class _Sent, class _Proj, class _Pred>
+ _LIBCPP_HIDE_FROM_ABI constexpr static
+ bool __any_of_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) {
+ for (; __first != __last; ++__first) {
+ if (std::invoke(__pred, std::invoke(__proj, *__first)))
+ return true;
+ }
+ return false;
+ }
+
+ template <input_iterator _Iter, sentinel_for<_Iter> _Sent, class _Proj = identity,
+ indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ bool operator()(_Iter __first, _Sent __last, _Pred __pred = {}, _Proj __proj = {}) const {
+ return __any_of_impl(std::move(__first), std::move(__last), __pred, __proj);
+ }
+
+ template <input_range _Range, class _Proj = identity,
+ indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ bool operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const {
+ return __any_of_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj);
+ }
+};
+} // namespace __any_of
+
+inline namespace __cpo {
+ inline constexpr auto any_of = __any_of::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_ANY_OF_H
diff --git a/libcxx/include/__algorithm/ranges_binary_search.h b/libcxx/include/__algorithm/ranges_binary_search.h
new file mode 100644
index 000000000000..68359fb1388f
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_binary_search.h
@@ -0,0 +1,63 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_RANGES_BINARY_SEARCH_H
+#define _LIBCPP___ALGORITHM_RANGES_BINARY_SEARCH_H
+
+#include <__algorithm/iterator_operations.h>
+#include <__algorithm/lower_bound.h>
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/projected.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+namespace __binary_search {
+struct __fn {
+ template <forward_iterator _Iter, sentinel_for<_Iter> _Sent, class _Type, class _Proj = identity,
+ indirect_strict_weak_order<const _Type*, projected<_Iter, _Proj>> _Comp = ranges::less>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ bool operator()(_Iter __first, _Sent __last, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const {
+ auto __ret = std::__lower_bound_impl<_RangesIterOps>(__first, __last, __value, __comp, __proj);
+ return __ret != __last && !std::invoke(__comp, __value, std::invoke(__proj, *__first));
+ }
+
+ template <forward_range _Range, class _Type, class _Proj = identity,
+ indirect_strict_weak_order<const _Type*, projected<iterator_t<_Range>, _Proj>> _Comp = ranges::less>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ bool operator()(_Range&& __r, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const {
+ auto __first = ranges::begin(__r);
+ auto __last = ranges::end(__r);
+ auto __ret = std::__lower_bound_impl<_RangesIterOps>(__first, __last, __value, __comp, __proj);
+ return __ret != __last && !std::invoke(__comp, __value, std::invoke(__proj, *__first));
+ }
+};
+} // namespace __binary_search
+
+inline namespace __cpo {
+ inline constexpr auto binary_search = __binary_search::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_BINARY_SEARCH_H
diff --git a/libcxx/include/__algorithm/ranges_copy.h b/libcxx/include/__algorithm/ranges_copy.h
new file mode 100644
index 000000000000..f5d6d5cd139a
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_copy.h
@@ -0,0 +1,65 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_RANGES_COPY_H
+#define _LIBCPP___ALGORITHM_RANGES_COPY_H
+
+#include <__algorithm/copy.h>
+#include <__algorithm/in_out_result.h>
+#include <__config>
+#include <__functional/identity.h>
+#include <__iterator/concepts.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/dangling.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+
+template <class _InIter, class _OutIter>
+using copy_result = in_out_result<_InIter, _OutIter>;
+
+namespace __copy {
+struct __fn {
+
+ template <input_iterator _InIter, sentinel_for<_InIter> _Sent, weakly_incrementable _OutIter>
+ requires indirectly_copyable<_InIter, _OutIter>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ copy_result<_InIter, _OutIter> operator()(_InIter __first, _Sent __last, _OutIter __result) const {
+ auto __ret = std::__copy(std::move(__first), std::move(__last), std::move(__result));
+ return {std::move(__ret.first), std::move(__ret.second)};
+ }
+
+ template <input_range _Range, weakly_incrementable _OutIter>
+ requires indirectly_copyable<iterator_t<_Range>, _OutIter>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ copy_result<borrowed_iterator_t<_Range>, _OutIter> operator()(_Range&& __r, _OutIter __result) const {
+ auto __ret = std::__copy(ranges::begin(__r), ranges::end(__r), std::move(__result));
+ return {std::move(__ret.first), std::move(__ret.second)};
+ }
+};
+} // namespace __copy
+
+inline namespace __cpo {
+ inline constexpr auto copy = __copy::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_COPY_H
diff --git a/libcxx/include/__algorithm/ranges_copy_backward.h b/libcxx/include/__algorithm/ranges_copy_backward.h
new file mode 100644
index 000000000000..49c1b26add6d
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_copy_backward.h
@@ -0,0 +1,67 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_RANGES_COPY_BACKWARD_H
+#define _LIBCPP___ALGORITHM_RANGES_COPY_BACKWARD_H
+
+#include <__algorithm/copy_backward.h>
+#include <__algorithm/in_out_result.h>
+#include <__config>
+#include <__iterator/concepts.h>
+#include <__iterator/reverse_iterator.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/dangling.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+
+template<class _Ip, class _Op>
+using copy_backward_result = in_out_result<_Ip, _Op>;
+
+namespace __copy_backward {
+struct __fn {
+
+ template <bidirectional_iterator _InIter1, sentinel_for<_InIter1> _Sent1, bidirectional_iterator _InIter2>
+ requires indirectly_copyable<_InIter1, _InIter2>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ copy_backward_result<_InIter1, _InIter2> operator()(_InIter1 __first, _Sent1 __last, _InIter2 __result) const {
+ auto __ret = std::__copy_backward(std::move(__first), std::move(__last), std::move(__result));
+ return {std::move(__ret.first), std::move(__ret.second)};
+ }
+
+ template <bidirectional_range _Range, bidirectional_iterator _Iter>
+ requires indirectly_copyable<iterator_t<_Range>, _Iter>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ copy_backward_result<borrowed_iterator_t<_Range>, _Iter> operator()(_Range&& __r, _Iter __result) const {
+ auto __ret = std::__copy_backward(ranges::begin(__r),
+ ranges::end(__r),
+ std::move(__result));
+ return {std::move(__ret.first), std::move(__ret.second)};
+ }
+};
+} // namespace __copy_backward
+
+inline namespace __cpo {
+ inline constexpr auto copy_backward = __copy_backward::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_COPY_BACKWARD_H
diff --git a/libcxx/include/__algorithm/ranges_copy_if.h b/libcxx/include/__algorithm/ranges_copy_if.h
new file mode 100644
index 000000000000..492104fbbfba
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_copy_if.h
@@ -0,0 +1,81 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_RANGES_COPY_IF_H
+#define _LIBCPP___ALGORITHM_RANGES_COPY_IF_H
+
+#include <__algorithm/in_out_result.h>
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
+#include <__iterator/concepts.h>
+#include <__iterator/projected.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/dangling.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+
+template<class _Ip, class _Op>
+using copy_if_result = in_out_result<_Ip, _Op>;
+
+namespace __copy_if {
+struct __fn {
+
+ template <class _InIter, class _Sent, class _OutIter, class _Proj, class _Pred>
+ _LIBCPP_HIDE_FROM_ABI static constexpr
+ copy_if_result <_InIter, _OutIter>
+ __copy_if_impl(_InIter __first, _Sent __last, _OutIter __result, _Pred& __pred, _Proj& __proj) {
+ for (; __first != __last; ++__first) {
+ if (std::invoke(__pred, std::invoke(__proj, *__first))) {
+ *__result = *__first;
+ ++__result;
+ }
+ }
+ return {std::move(__first), std::move(__result)};
+ }
+
+ template <input_iterator _Iter, sentinel_for<_Iter> _Sent, weakly_incrementable _OutIter, class _Proj = identity,
+ indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
+ requires indirectly_copyable<_Iter, _OutIter>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ copy_if_result<_Iter, _OutIter>
+ operator()(_Iter __first, _Sent __last, _OutIter __result, _Pred __pred, _Proj __proj = {}) const {
+ return __copy_if_impl(std::move(__first), std::move(__last), std::move(__result), __pred, __proj);
+ }
+
+ template <input_range _Range, weakly_incrementable _OutIter, class _Proj = identity,
+ indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred>
+ requires indirectly_copyable<iterator_t<_Range>, _OutIter>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ copy_if_result<borrowed_iterator_t<_Range>, _OutIter>
+ operator()(_Range&& __r, _OutIter __result, _Pred __pred, _Proj __proj = {}) const {
+ return __copy_if_impl(ranges::begin(__r), ranges::end(__r), std::move(__result), __pred, __proj);
+ }
+};
+} // namespace __copy_if
+
+inline namespace __cpo {
+ inline constexpr auto copy_if = __copy_if::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_COPY_IF_H
diff --git a/libcxx/include/__algorithm/ranges_copy_n.h b/libcxx/include/__algorithm/ranges_copy_n.h
new file mode 100644
index 000000000000..eaa05c954686
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_copy_n.h
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_RANGES_COPY_N_H
+#define _LIBCPP___ALGORITHM_RANGES_COPY_N_H
+
+#include <__algorithm/copy.h>
+#include <__algorithm/in_out_result.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)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+namespace ranges {
+
+template <class _Ip, class _Op>
+using copy_n_result = in_out_result<_Ip, _Op>;
+
+namespace __copy_n {
+struct __fn {
+
+ 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));
+ }
+};
+} // namespace __copy_n
+
+inline namespace __cpo {
+ inline constexpr auto copy_n = __copy_n::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___ALGORITHM_RANGES_COPY_N_H
diff --git a/libcxx/include/__algorithm/ranges_count.h b/libcxx/include/__algorithm/ranges_count.h
new file mode 100644
index 000000000000..670df26911d0
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_count.h
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_RANGES_COUNT_H
+#define _LIBCPP___ALGORITHM_RANGES_COUNT_H
+
+#include <__algorithm/ranges_count_if.h>
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/incrementable_traits.h>
+#include <__iterator/iterator_traits.h>
+#include <__iterator/projected.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+namespace __count {
+struct __fn {
+ template <input_iterator _Iter, sentinel_for<_Iter> _Sent, class _Type, class _Proj = identity>
+ requires indirect_binary_predicate<ranges::equal_to, projected<_Iter, _Proj>, const _Type*>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ iter_difference_t<_Iter> operator()(_Iter __first, _Sent __last, const _Type& __value, _Proj __proj = {}) const {
+ auto __pred = [&](auto&& __e) { return __e == __value; };
+ return ranges::__count_if_impl(std::move(__first), std::move(__last), __pred, __proj);
+ }
+
+ template <input_range _Range, class _Type, class _Proj = identity>
+ requires indirect_binary_predicate<ranges::equal_to, projected<iterator_t<_Range>, _Proj>, const _Type*>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ range_difference_t<_Range> operator()(_Range&& __r, const _Type& __value, _Proj __proj = {}) const {
+ auto __pred = [&](auto&& __e) { return __e == __value; };
+ return ranges::__count_if_impl(ranges::begin(__r), ranges::end(__r), __pred, __proj);
+ }
+};
+} // namespace __count
+
+inline namespace __cpo {
+ inline constexpr auto count = __count::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_COUNT_H
diff --git a/libcxx/include/__algorithm/ranges_count_if.h b/libcxx/include/__algorithm/ranges_count_if.h
new file mode 100644
index 000000000000..0f34ee9f2b1b
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_count_if.h
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_RANGES_COUNT_IF_H
+#define _LIBCPP___ALGORITHM_RANGES_COUNT_IF_H
+
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/incrementable_traits.h>
+#include <__iterator/iterator_traits.h>
+#include <__iterator/projected.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+template <class _Iter, class _Sent, class _Proj, class _Pred>
+_LIBCPP_HIDE_FROM_ABI constexpr
+iter_difference_t<_Iter> __count_if_impl(_Iter __first, _Sent __last,
+ _Pred& __pred, _Proj& __proj) {
+ iter_difference_t<_Iter> __counter(0);
+ for (; __first != __last; ++__first) {
+ if (std::invoke(__pred, std::invoke(__proj, *__first)))
+ ++__counter;
+ }
+ return __counter;
+}
+
+namespace __count_if {
+struct __fn {
+ template <input_iterator _Iter, sentinel_for<_Iter> _Sent, class _Proj = identity,
+ indirect_unary_predicate<projected<_Iter, _Proj>> _Predicate>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ iter_difference_t<_Iter> operator()(_Iter __first, _Sent __last, _Predicate __pred, _Proj __proj = {}) const {
+ return ranges::__count_if_impl(std::move(__first), std::move(__last), __pred, __proj);
+ }
+
+ template <input_range _Range, class _Proj = identity,
+ indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Predicate>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ range_difference_t<_Range> operator()(_Range&& __r, _Predicate __pred, _Proj __proj = {}) const {
+ return ranges::__count_if_impl(ranges::begin(__r), ranges::end(__r), __pred, __proj);
+ }
+};
+} // namespace __count_if
+
+inline namespace __cpo {
+ inline constexpr auto count_if = __count_if::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_COUNT_IF_H
diff --git a/libcxx/include/__algorithm/ranges_equal.h b/libcxx/include/__algorithm/ranges_equal.h
new file mode 100644
index 000000000000..c5f2d2332216
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_equal.h
@@ -0,0 +1,115 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_RANGES_EQUAL_H
+#define _LIBCPP___ALGORITHM_RANGES_EQUAL_H
+
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/distance.h>
+#include <__iterator/indirectly_comparable.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+namespace __equal {
+struct __fn {
+private:
+ template <class _Iter1, class _Sent1,
+ class _Iter2, class _Sent2,
+ class _Pred,
+ class _Proj1,
+ class _Proj2>
+ _LIBCPP_HIDE_FROM_ABI constexpr static
+ bool __equal_impl(_Iter1 __first1, _Sent1 __last1,
+ _Iter2 __first2, _Sent2 __last2,
+ _Pred& __pred,
+ _Proj1& __proj1,
+ _Proj2& __proj2) {
+ while (__first1 != __last1 && __first2 != __last2) {
+ if (!std::invoke(__pred, std::invoke(__proj1, *__first1), std::invoke(__proj2, *__first2)))
+ return false;
+ ++__first1;
+ ++__first2;
+ }
+ return __first1 == __last1 && __first2 == __last2;
+ }
+
+public:
+
+ template <input_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
+ input_iterator _Iter2, sentinel_for<_Iter2> _Sent2,
+ class _Pred = ranges::equal_to,
+ class _Proj1 = identity,
+ class _Proj2 = identity>
+ requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ bool operator()(_Iter1 __first1, _Sent1 __last1,
+ _Iter2 __first2, _Sent2 __last2,
+ _Pred __pred = {},
+ _Proj1 __proj1 = {},
+ _Proj2 __proj2 = {}) const {
+ if constexpr (sized_sentinel_for<_Sent1, _Iter1> && sized_sentinel_for<_Sent2, _Iter2>) {
+ if (__last1 - __first1 != __last2 - __first2)
+ return false;
+ }
+ return __equal_impl(std::move(__first1), std::move(__last1),
+ std::move(__first2), std::move(__last2),
+ __pred,
+ __proj1,
+ __proj2);
+ }
+
+ template <input_range _Range1,
+ input_range _Range2,
+ class _Pred = ranges::equal_to,
+ class _Proj1 = identity,
+ class _Proj2 = identity>
+ requires indirectly_comparable<iterator_t<_Range1>, iterator_t<_Range2>, _Pred, _Proj1, _Proj2>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ bool operator()(_Range1&& __range1,
+ _Range2&& __range2,
+ _Pred __pred = {},
+ _Proj1 __proj1 = {},
+ _Proj2 __proj2 = {}) const {
+ if constexpr (sized_range<_Range1> && sized_range<_Range2>) {
+ if (ranges::distance(__range1) != ranges::distance(__range2))
+ return false;
+ }
+ return __equal_impl(ranges::begin(__range1), ranges::end(__range1),
+ ranges::begin(__range2), ranges::end(__range2),
+ __pred,
+ __proj1,
+ __proj2);
+ return false;
+ }
+};
+} // namespace __equal
+
+inline namespace __cpo {
+ inline constexpr auto equal = __equal::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_EQUAL_H
diff --git a/libcxx/include/__algorithm/ranges_fill.h b/libcxx/include/__algorithm/ranges_fill.h
new file mode 100644
index 000000000000..846e31885141
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_fill.h
@@ -0,0 +1,59 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_RANGES_FILL_H
+#define _LIBCPP___ALGORITHM_RANGES_FILL_H
+
+#include <__algorithm/ranges_fill_n.h>
+#include <__config>
+#include <__iterator/concepts.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/dangling.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+namespace __fill {
+struct __fn {
+ template <class _Type, output_iterator<const _Type&> _Iter, sentinel_for<_Iter> _Sent>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ _Iter operator()(_Iter __first, _Sent __last, const _Type& __value) const {
+ if constexpr(random_access_iterator<_Iter>) {
+ return ranges::fill_n(__first, __last - __first, __value);
+ } else {
+ for (; __first != __last; ++__first)
+ *__first = __value;
+ return __first;
+ }
+ }
+
+ template <class _Type, output_range<const _Type&> _Range>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ borrowed_iterator_t<_Range> operator()(_Range&& __range, const _Type& __value) const {
+ return (*this)(ranges::begin(__range), ranges::end(__range), __value);
+ }
+};
+} // namespace __fill
+
+inline namespace __cpo {
+ inline constexpr auto fill = __fill::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_FILL_H
diff --git a/libcxx/include/__algorithm/ranges_fill_n.h b/libcxx/include/__algorithm/ranges_fill_n.h
new file mode 100644
index 000000000000..d93c573406ec
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_fill_n.h
@@ -0,0 +1,48 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_RANGES_FILL_N_H
+#define _LIBCPP___ALGORITHM_RANGES_FILL_N_H
+
+#include <__config>
+#include <__iterator/concepts.h>
+#include <__iterator/incrementable_traits.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+namespace __fill_n {
+struct __fn {
+ template <class _Type, output_iterator<const _Type&> _Iter>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ _Iter operator()(_Iter __first, iter_difference_t<_Iter> __n, const _Type& __value) const {
+ for (; __n != 0; --__n) {
+ *__first = __value;
+ ++__first;
+ }
+ return __first;
+ }
+};
+} // namespace __fill_n
+
+inline namespace __cpo {
+ inline constexpr auto fill_n = __fill_n::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_FILL_N_H
diff --git a/libcxx/include/__algorithm/ranges_find.h b/libcxx/include/__algorithm/ranges_find.h
new file mode 100644
index 000000000000..ca6d2f438295
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_find.h
@@ -0,0 +1,63 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_RANGES_FIND_H
+#define _LIBCPP___ALGORITHM_RANGES_FIND_H
+
+#include <__algorithm/ranges_find_if.h>
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/projected.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/dangling.h>
+#include <__utility/forward.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+namespace __find {
+struct __fn {
+ template <input_iterator _Ip, sentinel_for<_Ip> _Sp, class _Tp, class _Proj = identity>
+ requires indirect_binary_predicate<ranges::equal_to, projected<_Ip, _Proj>, const _Tp*>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ _Ip operator()(_Ip __first, _Sp __last, const _Tp& __value, _Proj __proj = {}) const {
+ auto __pred = [&](auto&& __e) { return std::forward<decltype(__e)>(__e) == __value; };
+ return ranges::__find_if_impl(std::move(__first), std::move(__last), __pred, __proj);
+ }
+
+ template <input_range _Rp, class _Tp, class _Proj = identity>
+ requires indirect_binary_predicate<ranges::equal_to, projected<iterator_t<_Rp>, _Proj>, const _Tp*>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ borrowed_iterator_t<_Rp> operator()(_Rp&& __r, const _Tp& __value, _Proj __proj = {}) const {
+ auto __pred = [&](auto&& __e) { return std::forward<decltype(__e)>(__e) == __value; };
+ return ranges::__find_if_impl(ranges::begin(__r), ranges::end(__r), __pred, __proj);
+ }
+};
+} // namespace __find
+
+inline namespace __cpo {
+ inline constexpr auto find = __find::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_FIND_H
diff --git a/libcxx/include/__algorithm/ranges_find_first_of.h b/libcxx/include/__algorithm/ranges_find_first_of.h
new file mode 100644
index 000000000000..ae31d38e6a95
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_find_first_of.h
@@ -0,0 +1,101 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_RANGES_FIND_FIRST_OF_H
+#define _LIBCPP___ALGORITHM_RANGES_FIND_FIRST_OF_H
+
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/indirectly_comparable.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/dangling.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+namespace __find_first_of {
+struct __fn {
+
+ template <class _Iter1, class _Sent1, class _Iter2, class _Sent2, class _Pred, class _Proj1, class _Proj2>
+ _LIBCPP_HIDE_FROM_ABI constexpr static
+ _Iter1 __find_first_of_impl(_Iter1 __first1, _Sent1 __last1,
+ _Iter2 __first2, _Sent2 __last2,
+ _Pred& __pred,
+ _Proj1& __proj1,
+ _Proj2& __proj2) {
+ for (; __first1 != __last1; ++__first1) {
+ for (auto __j = __first2; __j != __last2; ++__j) {
+ if (std::invoke(__pred, std::invoke(__proj1, *__first1), std::invoke(__proj2, *__j)))
+ return __first1;
+ }
+ }
+ return __first1;
+ }
+
+ template <input_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
+ forward_iterator _Iter2, sentinel_for<_Iter2> _Sent2,
+ class _Pred = ranges::equal_to,
+ class _Proj1 = identity,
+ class _Proj2 = identity>
+ requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ _Iter1 operator()(_Iter1 __first1, _Sent1 __last1,
+ _Iter2 __first2, _Sent2 __last2,
+ _Pred __pred = {},
+ _Proj1 __proj1 = {},
+ _Proj2 __proj2 = {}) const {
+ return __find_first_of_impl(std::move(__first1), std::move(__last1),
+ std::move(__first2), std::move(__last2),
+ __pred,
+ __proj1,
+ __proj2);
+ }
+
+ template <input_range _Range1,
+ forward_range _Range2,
+ class _Pred = ranges::equal_to,
+ class _Proj1 = identity,
+ class _Proj2 = identity>
+ requires indirectly_comparable<iterator_t<_Range1>, iterator_t<_Range2>, _Pred, _Proj1, _Proj2>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ borrowed_iterator_t<_Range1> operator()(_Range1&& __range1,
+ _Range2&& __range2,
+ _Pred __pred = {},
+ _Proj1 __proj1 = {},
+ _Proj2 __proj2 = {}) const {
+ return __find_first_of_impl(ranges::begin(__range1), ranges::end(__range1),
+ ranges::begin(__range2), ranges::end(__range2),
+ __pred,
+ __proj1,
+ __proj2);
+ }
+
+};
+} // namespace __find_first_of
+
+inline namespace __cpo {
+ inline constexpr auto find_first_of = __find_first_of::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_FIND_FIRST_OF_H
diff --git a/libcxx/include/__algorithm/ranges_find_if.h b/libcxx/include/__algorithm/ranges_find_if.h
new file mode 100644
index 000000000000..65ac122f6677
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_find_if.h
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_RANGES_FIND_IF_H
+#define _LIBCPP___ALGORITHM_RANGES_FIND_IF_H
+
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/projected.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/dangling.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+
+template <class _Ip, class _Sp, class _Pred, class _Proj>
+_LIBCPP_HIDE_FROM_ABI static constexpr
+_Ip __find_if_impl(_Ip __first, _Sp __last, _Pred& __pred, _Proj& __proj) {
+ for (; __first != __last; ++__first) {
+ if (std::invoke(__pred, std::invoke(__proj, *__first)))
+ break;
+ }
+ return __first;
+}
+
+namespace __find_if {
+struct __fn {
+
+ template <input_iterator _Ip, sentinel_for<_Ip> _Sp, class _Proj = identity,
+ indirect_unary_predicate<projected<_Ip, _Proj>> _Pred>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ _Ip operator()(_Ip __first, _Sp __last, _Pred __pred, _Proj __proj = {}) const {
+ return ranges::__find_if_impl(std::move(__first), std::move(__last), __pred, __proj);
+ }
+
+ template <input_range _Rp, class _Proj = identity,
+ indirect_unary_predicate<projected<iterator_t<_Rp>, _Proj>> _Pred>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ borrowed_iterator_t<_Rp> operator()(_Rp&& __r, _Pred __pred, _Proj __proj = {}) const {
+ return ranges::__find_if_impl(ranges::begin(__r), ranges::end(__r), __pred, __proj);
+ }
+};
+} // namespace __find_if
+
+inline namespace __cpo {
+ inline constexpr auto find_if = __find_if::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_FIND_IF_H
diff --git a/libcxx/include/__algorithm/ranges_find_if_not.h b/libcxx/include/__algorithm/ranges_find_if_not.h
new file mode 100644
index 000000000000..9a1adf71fc58
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_find_if_not.h
@@ -0,0 +1,63 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_RANGES_FIND_IF_NOT_H
+#define _LIBCPP___ALGORITHM_RANGES_FIND_IF_NOT_H
+
+#include <__algorithm/ranges_find_if.h>
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/projected.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/dangling.h>
+#include <__utility/forward.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+namespace __find_if_not {
+struct __fn {
+ template <input_iterator _Ip, sentinel_for<_Ip> _Sp, class _Proj = identity,
+ indirect_unary_predicate<projected<_Ip, _Proj>> _Pred>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ _Ip operator()(_Ip __first, _Sp __last, _Pred __pred, _Proj __proj = {}) const {
+ auto __pred2 = [&](auto&& __e) { return !std::invoke(__pred, std::forward<decltype(__e)>(__e)); };
+ return ranges::__find_if_impl(std::move(__first), std::move(__last), __pred2, __proj);
+ }
+
+ template <input_range _Rp, class _Proj = identity,
+ indirect_unary_predicate<projected<iterator_t<_Rp>, _Proj>> _Pred>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ borrowed_iterator_t<_Rp> operator()(_Rp&& __r, _Pred __pred, _Proj __proj = {}) const {
+ auto __pred2 = [&](auto&& __e) { return !std::invoke(__pred, std::forward<decltype(__e)>(__e)); };
+ return ranges::__find_if_impl(ranges::begin(__r), ranges::end(__r), __pred2, __proj);
+ }
+};
+} // namespace __find_if_not
+
+inline namespace __cpo {
+ inline constexpr auto find_if_not = __find_if_not::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_FIND_IF_NOT_H
diff --git a/libcxx/include/__algorithm/ranges_for_each.h b/libcxx/include/__algorithm/ranges_for_each.h
new file mode 100644
index 000000000000..f284c0ee3ad4
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_for_each.h
@@ -0,0 +1,78 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_RANGES_FOR_EACH_H
+#define _LIBCPP___ALGORITHM_RANGES_FOR_EACH_H
+
+#include <__algorithm/in_fun_result.h>
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
+#include <__iterator/concepts.h>
+#include <__iterator/projected.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/dangling.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+
+template <class _Iter, class _Func>
+using for_each_result = in_fun_result<_Iter, _Func>;
+
+namespace __for_each {
+struct __fn {
+private:
+ template <class _Iter, class _Sent, class _Proj, class _Func>
+ _LIBCPP_HIDE_FROM_ABI constexpr static
+ for_each_result<_Iter, _Func> __for_each_impl(_Iter __first, _Sent __last, _Func& __func, _Proj& __proj) {
+ for (; __first != __last; ++__first)
+ std::invoke(__func, std::invoke(__proj, *__first));
+ return {std::move(__first), std::move(__func)};
+ }
+
+public:
+ template <input_iterator _Iter, sentinel_for<_Iter> _Sent,
+ class _Proj = identity,
+ indirectly_unary_invocable<projected<_Iter, _Proj>> _Func>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ for_each_result<_Iter, _Func> operator()(_Iter __first, _Sent __last, _Func __func, _Proj __proj = {}) const {
+ return __for_each_impl(std::move(__first), std::move(__last), __func, __proj);
+ }
+
+ template <input_range _Range,
+ class _Proj = identity,
+ indirectly_unary_invocable<projected<iterator_t<_Range>, _Proj>> _Func>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ for_each_result<borrowed_iterator_t<_Range>, _Func> operator()(_Range&& __range,
+ _Func __func,
+ _Proj __proj = {}) const {
+ return __for_each_impl(ranges::begin(__range), ranges::end(__range), __func, __proj);
+ }
+
+};
+} // namespace __for_each
+
+inline namespace __cpo {
+ inline constexpr auto for_each = __for_each::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_FOR_EACH_H
diff --git a/libcxx/include/__algorithm/ranges_for_each_n.h b/libcxx/include/__algorithm/ranges_for_each_n.h
new file mode 100644
index 000000000000..ddf8b047cdb2
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_for_each_n.h
@@ -0,0 +1,67 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_RANGES_FOR_EACH_N_H
+#define _LIBCPP___ALGORITHM_RANGES_FOR_EACH_N_H
+
+#include <__algorithm/in_fun_result.h>
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
+#include <__iterator/concepts.h>
+#include <__iterator/incrementable_traits.h>
+#include <__iterator/iterator_traits.h>
+#include <__iterator/projected.h>
+#include <__ranges/concepts.h>
+#include <__ranges/dangling.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+
+template <class _Iter, class _Func>
+using for_each_n_result = in_fun_result<_Iter, _Func>;
+
+namespace __for_each_n {
+struct __fn {
+
+ template <input_iterator _Iter,
+ class _Proj = identity,
+ indirectly_unary_invocable<projected<_Iter, _Proj>> _Func>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ for_each_n_result<_Iter, _Func> operator()(_Iter __first,
+ iter_difference_t<_Iter> __count,
+ _Func __func,
+ _Proj __proj = {}) const {
+ while (__count-- > 0) {
+ std::invoke(__func, std::invoke(__proj, *__first));
+ ++__first;
+ }
+ return {std::move(__first), std::move(__func)};
+ }
+
+};
+} // namespace __for_each_n
+
+inline namespace __cpo {
+ inline constexpr auto for_each_n = __for_each_n::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_FOR_EACH_N_H
diff --git a/libcxx/include/__algorithm/ranges_is_partitioned.h b/libcxx/include/__algorithm/ranges_is_partitioned.h
new file mode 100644
index 000000000000..3d572895ebe1
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_is_partitioned.h
@@ -0,0 +1,81 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_RANGES_IS_PARTITIONED_H
+#define _LIBCPP___ALGORITHM_RANGES_IS_PARTITIONED_H
+
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
+#include <__iterator/concepts.h>
+#include <__iterator/indirectly_comparable.h>
+#include <__iterator/projected.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+namespace __is_partitioned {
+struct __fn {
+
+ template <class _Iter, class _Sent, class _Proj, class _Pred>
+ _LIBCPP_HIDE_FROM_ABI constexpr static
+ bool __is_parititioned_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) {
+ for (; __first != __last; ++__first) {
+ if (!std::invoke(__pred, std::invoke(__proj, *__first)))
+ break;
+ }
+
+ if (__first == __last)
+ return true;
+ ++__first;
+
+ for (; __first != __last; ++__first) {
+ if (std::invoke(__pred, std::invoke(__proj, *__first)))
+ return false;
+ }
+
+ return true;
+ }
+
+ template <input_iterator _Iter, sentinel_for<_Iter> _Sent,
+ class _Proj = identity,
+ indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ bool operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const {
+ return __is_parititioned_impl(std::move(__first), std::move(__last), __pred, __proj);
+ }
+
+ template <input_range _Range,
+ class _Proj = identity,
+ indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ bool operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const {
+ return __is_parititioned_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj);
+ }
+};
+} // namespace __is_partitioned
+
+inline namespace __cpo {
+ inline constexpr auto is_partitioned = __is_partitioned::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_IS_PARTITIONED_H
diff --git a/libcxx/include/__algorithm/ranges_is_sorted.h b/libcxx/include/__algorithm/ranges_is_sorted.h
new file mode 100644
index 000000000000..938e69afba8d
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_is_sorted.h
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP__ALGORITHM_RANGES_IS_SORTED_H
+#define _LIBCPP__ALGORITHM_RANGES_IS_SORTED_H
+
+#include <__algorithm/ranges_is_sorted_until.h>
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/projected.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+namespace __is_sorted {
+struct __fn {
+ template <forward_iterator _Iter, sentinel_for<_Iter> _Sent,
+ class _Proj = identity,
+ indirect_strict_weak_order<projected<_Iter, _Proj>> _Comp = ranges::less>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ bool operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
+ return ranges::__is_sorted_until_impl(std::move(__first), __last, __comp, __proj) == __last;
+ }
+
+ template <forward_range _Range,
+ class _Proj = identity,
+ indirect_strict_weak_order<projected<iterator_t<_Range>, _Proj>> _Comp = ranges::less>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ bool operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const {
+ auto __last = ranges::end(__range);
+ return ranges::__is_sorted_until_impl(ranges::begin(__range), __last, __comp, __proj) == __last;
+ }
+};
+} // namespace __is_sorted
+
+inline namespace __cpo {
+ inline constexpr auto is_sorted = __is_sorted::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP__ALGORITHM_RANGES_IS_SORTED_H
diff --git a/libcxx/include/__algorithm/ranges_is_sorted_until.h b/libcxx/include/__algorithm/ranges_is_sorted_until.h
new file mode 100644
index 000000000000..c8f0608e1255
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_is_sorted_until.h
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP__ALGORITHM_RANGES_IS_SORTED_UNTIL_H
+#define _LIBCPP__ALGORITHM_RANGES_IS_SORTED_UNTIL_H
+
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/projected.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/dangling.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+
+template <class _Iter, class _Sent, class _Proj, class _Comp>
+_LIBCPP_HIDE_FROM_ABI constexpr
+_Iter __is_sorted_until_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
+ if (__first == __last)
+ return __first;
+ auto __i = __first;
+ while (++__i != __last) {
+ if (std::invoke(__comp, std::invoke(__proj, *__i), std::invoke(__proj, *__first)))
+ return __i;
+ __first = __i;
+ }
+ return __i;
+}
+
+namespace __is_sorted_until {
+struct __fn {
+ template <forward_iterator _Iter, sentinel_for<_Iter> _Sent,
+ class _Proj = identity,
+ indirect_strict_weak_order<projected<_Iter, _Proj>> _Comp = ranges::less>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ _Iter operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
+ return ranges::__is_sorted_until_impl(std::move(__first), std::move(__last), __comp, __proj);
+ }
+
+ template <forward_range _Range,
+ class _Proj = identity,
+ indirect_strict_weak_order<projected<iterator_t<_Range>, _Proj>> _Comp = ranges::less>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ borrowed_iterator_t<_Range> operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const {
+ return ranges::__is_sorted_until_impl(ranges::begin(__range), ranges::end(__range), __comp, __proj);
+ }
+};
+} // namespace __is_sorted_until
+
+inline namespace __cpo {
+ inline constexpr auto is_sorted_until = __is_sorted_until::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP__ALGORITHM_RANGES_IS_SORTED_UNTIL_H
diff --git a/libcxx/include/__algorithm/ranges_lexicographical_compare.h b/libcxx/include/__algorithm/ranges_lexicographical_compare.h
new file mode 100644
index 000000000000..fe709f7a7f70
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_lexicographical_compare.h
@@ -0,0 +1,98 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_RANGES_LEXICOGRAPHICAL_COMPARE_H
+#define _LIBCPP___ALGORITHM_RANGES_LEXICOGRAPHICAL_COMPARE_H
+
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/projected.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+namespace __lexicographical_compare {
+struct __fn {
+
+ template <class _Iter1, class _Sent1, class _Iter2, class _Sent2, class _Proj1, class _Proj2, class _Comp>
+ _LIBCPP_HIDE_FROM_ABI constexpr static
+ bool __lexicographical_compare_impl(_Iter1 __first1, _Sent1 __last1,
+ _Iter2 __first2, _Sent2 __last2,
+ _Comp& __comp,
+ _Proj1& __proj1,
+ _Proj2& __proj2) {
+ while (__first2 != __last2) {
+ if (__first1 == __last1
+ || std::invoke(__comp, std::invoke(__proj1, *__first1), std::invoke(__proj2, *__first2)))
+ return true;
+ if (std::invoke(__comp, std::invoke(__proj2, *__first2), std::invoke(__proj1, *__first1)))
+ return false;
+ ++__first1;
+ ++__first2;
+ }
+ return false;
+ }
+
+ template <input_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
+ input_iterator _Iter2, sentinel_for<_Iter2> _Sent2,
+ class _Proj1 = identity,
+ class _Proj2 = identity,
+ indirect_strict_weak_order<projected<_Iter1, _Proj1>, projected<_Iter2, _Proj2>> _Comp = ranges::less>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ bool operator()(_Iter1 __first1, _Sent1 __last1,
+ _Iter2 __first2, _Sent2 __last2,
+ _Comp __comp = {},
+ _Proj1 __proj1 = {},
+ _Proj2 __proj2 = {}) const {
+ return __lexicographical_compare_impl(std::move(__first1), std::move(__last1),
+ std::move(__first2), std::move(__last2),
+ __comp,
+ __proj1,
+ __proj2);
+ }
+
+ template <input_range _Range1,
+ input_range _Range2,
+ class _Proj1 = identity,
+ class _Proj2 = identity,
+ indirect_strict_weak_order<projected<iterator_t<_Range1>, _Proj1>,
+ projected<iterator_t<_Range2>, _Proj2>> _Comp = ranges::less>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ bool operator()(_Range1&& __range1, _Range2&& __range2, _Comp __comp = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const {
+ return __lexicographical_compare_impl(ranges::begin(__range1), ranges::end(__range1),
+ ranges::begin(__range2), ranges::end(__range2),
+ __comp,
+ __proj1,
+ __proj2);
+ }
+
+};
+} // namespace __lexicographical_compare
+
+inline namespace __cpo {
+ inline constexpr auto lexicographical_compare = __lexicographical_compare::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_LEXICOGRAPHICAL_COMPARE_H
diff --git a/libcxx/include/__algorithm/ranges_lower_bound.h b/libcxx/include/__algorithm/ranges_lower_bound.h
new file mode 100644
index 000000000000..a73470465cfd
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_lower_bound.h
@@ -0,0 +1,66 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_RANGES_LOWER_BOUND_H
+#define _LIBCPP___ALGORITHM_RANGES_LOWER_BOUND_H
+
+#include <__algorithm/iterator_operations.h>
+#include <__algorithm/lower_bound.h>
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/advance.h>
+#include <__iterator/concepts.h>
+#include <__iterator/iterator_traits.h>
+#include <__iterator/projected.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/dangling.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+
+namespace __lower_bound {
+struct __fn {
+ template <forward_iterator _Iter, sentinel_for<_Iter> _Sent, class _Type, class _Proj = identity,
+ indirect_strict_weak_order<const _Type*, projected<_Iter, _Proj>> _Comp = ranges::less>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ _Iter operator()(_Iter __first, _Sent __last, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const {
+ return std::__lower_bound_impl<_RangesIterOps>(__first, __last, __value, __comp, __proj);
+ }
+
+ template <forward_range _Range, class _Type, class _Proj = identity,
+ indirect_strict_weak_order<const _Type*, projected<iterator_t<_Range>, _Proj>> _Comp = ranges::less>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ borrowed_iterator_t<_Range> operator()(_Range&& __r,
+ const _Type& __value,
+ _Comp __comp = {},
+ _Proj __proj = {}) const {
+ return std::__lower_bound_impl<_RangesIterOps>(ranges::begin(__r), ranges::end(__r), __value, __comp, __proj);
+ }
+};
+} // namespace __lower_bound
+
+inline namespace __cpo {
+ inline constexpr auto lower_bound = __lower_bound::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_LOWER_BOUND_H
diff --git a/libcxx/include/__algorithm/ranges_max.h b/libcxx/include/__algorithm/ranges_max.h
new file mode 100644
index 000000000000..f48bc3ececa2
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_max.h
@@ -0,0 +1,93 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_RANGES_MAX_H
+#define _LIBCPP___ALGORITHM_RANGES_MAX_H
+
+#include <__algorithm/ranges_min_element.h>
+#include <__assert>
+#include <__concepts/copyable.h>
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/projected.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__utility/move.h>
+#include <initializer_list>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+namespace __max {
+struct __fn {
+ template <class _Tp, class _Proj = identity,
+ indirect_strict_weak_order<projected<const _Tp*, _Proj>> _Comp = ranges::less>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ const _Tp& operator()(const _Tp& __a, const _Tp& __b, _Comp __comp = {}, _Proj __proj = {}) const {
+ return std::invoke(__comp, std::invoke(__proj, __a), std::invoke(__proj, __b)) ? __b : __a;
+ }
+
+ template <copyable _Tp, class _Proj = identity,
+ indirect_strict_weak_order<projected<const _Tp*, _Proj>> _Comp = ranges::less>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ _Tp operator()(initializer_list<_Tp> __il, _Comp __comp = {}, _Proj __proj = {}) const {
+ _LIBCPP_ASSERT(__il.begin() != __il.end(), "initializer_list must contain at least one element");
+
+ auto __comp_lhs_rhs_swapped = [&](auto&& __lhs, auto&& __rhs) { return std::invoke(__comp, __rhs, __lhs); };
+ return *ranges::__min_element_impl(__il.begin(), __il.end(), __comp_lhs_rhs_swapped, __proj);
+ }
+
+ template <input_range _Rp, class _Proj = identity,
+ indirect_strict_weak_order<projected<iterator_t<_Rp>, _Proj>> _Comp = ranges::less>
+ requires indirectly_copyable_storable<iterator_t<_Rp>, range_value_t<_Rp>*>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ range_value_t<_Rp> operator()(_Rp&& __r, _Comp __comp = {}, _Proj __proj = {}) const {
+ auto __first = ranges::begin(__r);
+ auto __last = ranges::end(__r);
+
+ _LIBCPP_ASSERT(__first != __last, "range must contain at least one element");
+
+ if constexpr (forward_range<_Rp>) {
+ auto __comp_lhs_rhs_swapped = [&](auto&& __lhs, auto&& __rhs) { return std::invoke(__comp, __rhs, __lhs); };
+ return *ranges::__min_element_impl(std::move(__first), std::move(__last), __comp_lhs_rhs_swapped, __proj);
+ } else {
+ range_value_t<_Rp> __result = *__first;
+ while (++__first != __last) {
+ if (std::invoke(__comp, std::invoke(__proj, __result), std::invoke(__proj, *__first)))
+ __result = *__first;
+ }
+ return __result;
+ }
+ }
+};
+} // namespace __max
+
+inline namespace __cpo {
+ inline constexpr auto max = __max::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP_STD_VER > 17 && && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_MAX_H
diff --git a/libcxx/include/__algorithm/ranges_max_element.h b/libcxx/include/__algorithm/ranges_max_element.h
new file mode 100644
index 000000000000..d8d7242e176b
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_max_element.h
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_RANGES_MAX_ELEMENT_H
+#define _LIBCPP___ALGORITHM_RANGES_MAX_ELEMENT_H
+
+#include <__algorithm/ranges_min_element.h>
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/projected.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/dangling.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+namespace __max_element {
+struct __fn {
+ template <forward_iterator _Ip, sentinel_for<_Ip> _Sp, class _Proj = identity,
+ indirect_strict_weak_order<projected<_Ip, _Proj>> _Comp = ranges::less>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ _Ip operator()(_Ip __first, _Sp __last, _Comp __comp = {}, _Proj __proj = {}) const {
+ auto __comp_lhs_rhs_swapped = [&](auto&& __lhs, auto&& __rhs) { return std::invoke(__comp, __rhs, __lhs); };
+ return ranges::__min_element_impl(__first, __last, __comp_lhs_rhs_swapped, __proj);
+ }
+
+ template <forward_range _Rp, class _Proj = identity,
+ indirect_strict_weak_order<projected<iterator_t<_Rp>, _Proj>> _Comp = ranges::less>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ borrowed_iterator_t<_Rp> operator()(_Rp&& __r, _Comp __comp = {}, _Proj __proj = {}) const {
+ auto __comp_lhs_rhs_swapped = [&](auto&& __lhs, auto&& __rhs) { return std::invoke(__comp, __rhs, __lhs); };
+ return ranges::__min_element_impl(ranges::begin(__r), ranges::end(__r), __comp_lhs_rhs_swapped, __proj);
+ }
+};
+} // namespace __max_element
+
+inline namespace __cpo {
+ inline constexpr auto max_element = __max_element::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_MAX_ELEMENT_H
diff --git a/libcxx/include/__algorithm/ranges_min.h b/libcxx/include/__algorithm/ranges_min.h
new file mode 100644
index 000000000000..0bb1e72ac5ac
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_min.h
@@ -0,0 +1,89 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_RANGES_MIN_H
+#define _LIBCPP___ALGORITHM_RANGES_MIN_H
+
+#include <__algorithm/ranges_min_element.h>
+#include <__assert>
+#include <__concepts/copyable.h>
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/projected.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <initializer_list>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+namespace __min {
+struct __fn {
+ template <class _Tp, class _Proj = identity,
+ indirect_strict_weak_order<projected<const _Tp*, _Proj>> _Comp = ranges::less>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ const _Tp& operator()(const _Tp& __a, const _Tp& __b, _Comp __comp = {}, _Proj __proj = {}) const {
+ return std::invoke(__comp, std::invoke(__proj, __b), std::invoke(__proj, __a)) ? __b : __a;
+ }
+
+ template <copyable _Tp, class _Proj = identity,
+ indirect_strict_weak_order<projected<const _Tp*, _Proj>> _Comp = ranges::less>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ _Tp operator()(initializer_list<_Tp> __il, _Comp __comp = {}, _Proj __proj = {}) const {
+ _LIBCPP_ASSERT(__il.begin() != __il.end(), "initializer_list must contain at least one element");
+ return *ranges::__min_element_impl(__il.begin(), __il.end(), __comp, __proj);
+ }
+
+ template <input_range _Rp, class _Proj = identity,
+ indirect_strict_weak_order<projected<iterator_t<_Rp>, _Proj>> _Comp = ranges::less>
+ requires indirectly_copyable_storable<iterator_t<_Rp>, range_value_t<_Rp>*>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ range_value_t<_Rp> operator()(_Rp&& __r, _Comp __comp = {}, _Proj __proj = {}) const {
+ auto __first = ranges::begin(__r);
+ auto __last = ranges::end(__r);
+
+ _LIBCPP_ASSERT(__first != __last, "range must contain at least one element");
+
+ if constexpr (forward_range<_Rp>) {
+ return *ranges::__min_element_impl(__first, __last, __comp, __proj);
+ } else {
+ range_value_t<_Rp> __result = *__first;
+ while (++__first != __last) {
+ if (std::invoke(__comp, std::invoke(__proj, *__first), std::invoke(__proj, __result)))
+ __result = *__first;
+ }
+ return __result;
+ }
+ }
+};
+} // namespace __min
+
+inline namespace __cpo {
+ inline constexpr auto min = __min::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP_STD_VER > 17 && && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_MIN_H
diff --git a/libcxx/include/__algorithm/ranges_min_element.h b/libcxx/include/__algorithm/ranges_min_element.h
new file mode 100644
index 000000000000..ae82dceb9ad8
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_min_element.h
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_RANGES_MIN_ELEMENT_H
+#define _LIBCPP___ALGORITHM_RANGES_MIN_ELEMENT_H
+
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/projected.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/dangling.h>
+#include <__utility/forward.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+
+template <class _Ip, class _Sp, class _Proj, class _Comp>
+_LIBCPP_HIDE_FROM_ABI static constexpr
+_Ip __min_element_impl(_Ip __first, _Sp __last, _Comp& __comp, _Proj& __proj) {
+ if (__first == __last)
+ return __first;
+
+ _Ip __i = __first;
+ while (++__i != __last)
+ if (std::invoke(__comp, std::invoke(__proj, *__i), std::invoke(__proj, *__first)))
+ __first = __i;
+ return __first;
+}
+
+namespace __min_element {
+struct __fn {
+ template <forward_iterator _Ip, sentinel_for<_Ip> _Sp, class _Proj = identity,
+ indirect_strict_weak_order<projected<_Ip, _Proj>> _Comp = ranges::less>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ _Ip operator()(_Ip __first, _Sp __last, _Comp __comp = {}, _Proj __proj = {}) const {
+ return ranges::__min_element_impl(__first, __last, __comp, __proj);
+ }
+
+ template <forward_range _Rp, class _Proj = identity,
+ indirect_strict_weak_order<projected<iterator_t<_Rp>, _Proj>> _Comp = ranges::less>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ borrowed_iterator_t<_Rp> operator()(_Rp&& __r, _Comp __comp = {}, _Proj __proj = {}) const {
+ return ranges::__min_element_impl(ranges::begin(__r), ranges::end(__r), __comp, __proj);
+ }
+};
+} // namespace __min_element
+
+inline namespace __cpo {
+ inline constexpr auto min_element = __min_element::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_MIN_ELEMENT_H
diff --git a/libcxx/include/__algorithm/ranges_minmax.h b/libcxx/include/__algorithm/ranges_minmax.h
new file mode 100644
index 000000000000..2f4bba0e7cc0
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_minmax.h
@@ -0,0 +1,133 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_RANGES_MINMAX_H
+#define _LIBCPP___ALGORITHM_RANGES_MINMAX_H
+
+#include <__algorithm/min_max_result.h>
+#include <__algorithm/minmax_element.h>
+#include <__assert>
+#include <__concepts/copyable.h>
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/projected.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__utility/forward.h>
+#include <__utility/move.h>
+#include <initializer_list>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+template <class _T1>
+using minmax_result = min_max_result<_T1>;
+
+namespace __minmax {
+struct __fn {
+ template <class _Type, class _Proj = identity,
+ indirect_strict_weak_order<projected<const _Type*, _Proj>> _Comp = ranges::less>
+ _LIBCPP_HIDE_FROM_ABI constexpr ranges::minmax_result<const _Type&>
+ operator()(const _Type& __a, const _Type& __b, _Comp __comp = {}, _Proj __proj = {}) const {
+ if (std::invoke(__comp, std::invoke(__proj, __b), std::invoke(__proj, __a)))
+ return {__b, __a};
+ return {__a, __b};
+ }
+
+ template <copyable _Type, class _Proj = identity,
+ indirect_strict_weak_order<projected<const _Type*, _Proj>> _Comp = ranges::less>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ ranges::minmax_result<_Type> operator()(initializer_list<_Type> __il, _Comp __comp = {}, _Proj __proj = {}) const {
+ _LIBCPP_ASSERT(__il.begin() != __il.end(), "initializer_list has to contain at least one element");
+ auto __iters = std::__minmax_element_impl(__il.begin(), __il.end(), __comp, __proj);
+ return ranges::minmax_result<_Type> { *__iters.first, *__iters.second };
+ }
+
+ template <input_range _Range, class _Proj = identity,
+ indirect_strict_weak_order<projected<iterator_t<_Range>, _Proj>> _Comp = ranges::less>
+ requires indirectly_copyable_storable<iterator_t<_Range>, range_value_t<_Range>*>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ ranges::minmax_result<range_value_t<_Range>> operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const {
+ auto __first = ranges::begin(__r);
+ auto __last = ranges::end(__r);
+ using _ValueT = range_value_t<_Range>;
+
+ _LIBCPP_ASSERT(__first != __last, "range has to contain at least one element");
+
+ if constexpr (forward_range<_Range>) {
+ auto __result = std::__minmax_element_impl(__first, __last, __comp, __proj);
+ return {*__result.first, *__result.second};
+ } else {
+ // input_iterators can't be copied, so the implementation for input_iterators has to store
+ // the values instead of a pointer to the correct values
+ auto __less = [&](auto&& __a, auto&& __b) -> bool {
+ return std::invoke(__comp, std::invoke(__proj, std::forward<decltype(__a)>(__a)),
+ std::invoke(__proj, std::forward<decltype(__b)>(__b)));
+ };
+
+ ranges::minmax_result<_ValueT> __result = {*__first, __result.min};
+ if (__first == __last || ++__first == __last)
+ return __result;
+
+ if (__less(*__first, __result.min))
+ __result.min = *__first;
+ else
+ __result.max = *__first;
+
+ while (++__first != __last) {
+ _ValueT __i = *__first;
+ if (++__first == __last) {
+ if (__less(__i, __result.min))
+ __result.min = __i;
+ else if (!__less(__i, __result.max))
+ __result.max = __i;
+ return __result;
+ }
+
+ if (__less(*__first, __i)) {
+ if (__less(*__first, __result.min))
+ __result.min = *__first;
+ if (!__less(__i, __result.max))
+ __result.max = std::move(__i);
+ } else {
+ if (__less(__i, __result.min))
+ __result.min = std::move(__i);
+ if (!__less(*__first, __result.max))
+ __result.max = *__first;
+ }
+ }
+ return __result;
+ }
+ }
+};
+} // namespace __minmax
+
+inline namespace __cpo {
+ inline constexpr auto minmax = __minmax::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_MINMAX_H
diff --git a/libcxx/include/__algorithm/ranges_minmax_element.h b/libcxx/include/__algorithm/ranges_minmax_element.h
new file mode 100644
index 000000000000..b7bb26cefe95
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_minmax_element.h
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_RANGES_MINMAX_ELEMENT_H
+#define _LIBCPP___ALGORITHM_RANGES_MINMAX_ELEMENT_H
+
+#include <__algorithm/min_max_result.h>
+#include <__algorithm/minmax_element.h>
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/projected.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/dangling.h>
+#include <__utility/forward.h>
+#include <__utility/move.h>
+#include <__utility/pair.h>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+
+template <class _T1>
+using minmax_element_result = min_max_result<_T1>;
+
+namespace __minmax_element {
+struct __fn {
+ template <forward_iterator _Ip, sentinel_for<_Ip> _Sp, class _Proj = identity,
+ indirect_strict_weak_order<projected<_Ip, _Proj>> _Comp = ranges::less>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ ranges::minmax_element_result<_Ip> operator()(_Ip __first, _Sp __last, _Comp __comp = {}, _Proj __proj = {}) const {
+ auto __ret = std::__minmax_element_impl(std::move(__first), std::move(__last), __comp, __proj);
+ return {__ret.first, __ret.second};
+ }
+
+ template <forward_range _Rp, class _Proj = identity,
+ indirect_strict_weak_order<projected<iterator_t<_Rp>, _Proj>> _Comp = ranges::less>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ ranges::minmax_element_result<borrowed_iterator_t<_Rp>>
+ operator()(_Rp&& __r, _Comp __comp = {}, _Proj __proj = {}) const {
+ auto __ret = std::__minmax_element_impl(ranges::begin(__r), ranges::end(__r), __comp, __proj);
+ return {__ret.first, __ret.second};
+ }
+};
+} // namespace __minmax_element
+
+inline namespace __cpo {
+ inline constexpr auto minmax_element = __minmax_element::__fn{};
+} // namespace __cpo
+
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_MINMAX_H
diff --git a/libcxx/include/__algorithm/ranges_mismatch.h b/libcxx/include/__algorithm/ranges_mismatch.h
new file mode 100644
index 000000000000..4c1440b5da06
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_mismatch.h
@@ -0,0 +1,85 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_RANGES_MISMATCH_H
+#define _LIBCPP___ALGORITHM_RANGES_MISMATCH_H
+
+#include <__algorithm/in_in_result.h>
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/indirectly_comparable.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/dangling.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+namespace ranges {
+
+template <class _I1, class _I2>
+using mismatch_result = in_in_result<_I1, _I2>;
+
+namespace __mismatch {
+struct __fn {
+ template <class _I1, class _S1, class _I2, class _S2,
+ class _Pred, class _Proj1, class _Proj2>
+ static _LIBCPP_HIDE_FROM_ABI constexpr
+ mismatch_result<_I1, _I2>
+ __go(_I1 __first1, _S1 __last1, _I2 __first2, _S2 __last2,
+ _Pred& __pred, _Proj1& __proj1, _Proj2& __proj2) {
+ while (__first1 != __last1 && __first2 != __last2) {
+ if (!std::invoke(__pred, std::invoke(__proj1, *__first1), std::invoke(__proj2, *__first2)))
+ break;
+ ++__first1;
+ ++__first2;
+ }
+ return {std::move(__first1), std::move(__first2)};
+ }
+
+ template <input_iterator _I1, sentinel_for<_I1> _S1,
+ input_iterator _I2, sentinel_for<_I2> _S2,
+ class _Pred = ranges::equal_to, class _Proj1 = identity, class _Proj2 = identity>
+ requires indirectly_comparable<_I1, _I2, _Pred, _Proj1, _Proj2>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ mismatch_result<_I1, _I2> operator()(_I1 __first1, _S1 __last1, _I2 __first2, _S2 __last2,
+ _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const {
+ return __go(std::move(__first1), __last1, std::move(__first2), __last2, __pred, __proj1, __proj2);
+ }
+
+ template <input_range _R1, input_range _R2,
+ class _Pred = ranges::equal_to, class _Proj1 = identity, class _Proj2 = identity>
+ requires indirectly_comparable<iterator_t<_R1>, iterator_t<_R2>, _Pred, _Proj1, _Proj2>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ mismatch_result<borrowed_iterator_t<_R1>, borrowed_iterator_t<_R2>>
+ operator()(_R1&& __r1, _R2&& __r2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const {
+ return __go(ranges::begin(__r1), ranges::end(__r1), ranges::begin(__r2), ranges::end(__r2),
+ __pred, __proj1, __proj2);
+ }
+};
+} // namespace __mismatch
+
+inline namespace __cpo {
+ constexpr inline auto mismatch = __mismatch::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___ALGORITHM_RANGES_MISMATCH_H
diff --git a/libcxx/include/__algorithm/ranges_move.h b/libcxx/include/__algorithm/ranges_move.h
new file mode 100644
index 000000000000..ad4342d7c989
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_move.h
@@ -0,0 +1,83 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_RANGES_MOVE_H
+#define _LIBCPP___ALGORITHM_RANGES_MOVE_H
+
+#include <__algorithm/in_out_result.h>
+#include <__algorithm/move.h>
+#include <__config>
+#include <__iterator/concepts.h>
+#include <__iterator/iter_move.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/dangling.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+
+template <class _InIter, class _OutIter>
+using move_result = in_out_result<_InIter, _OutIter>;
+
+namespace __move {
+struct __fn {
+
+ template <class _InIter, class _Sent, class _OutIter>
+ requires __iter_move::__move_deref<_InIter> // check that we are allowed to std::move() the value
+ _LIBCPP_HIDE_FROM_ABI constexpr static
+ move_result<_InIter, _OutIter> __move_impl(_InIter __first, _Sent __last, _OutIter __result) {
+ auto __ret = std::__move(std::move(__first), std::move(__last), std::move(__result));
+ return {std::move(__ret.first), std::move(__ret.second)};
+ }
+
+ template <class _InIter, class _Sent, class _OutIter>
+ _LIBCPP_HIDE_FROM_ABI constexpr static
+ move_result<_InIter, _OutIter> __move_impl(_InIter __first, _Sent __last, _OutIter __result) {
+ while (__first != __last) {
+ *__result = ranges::iter_move(__first);
+ ++__first;
+ ++__result;
+ }
+ return {std::move(__first), std::move(__result)};
+ }
+
+ template <input_iterator _InIter, sentinel_for<_InIter> _Sent, weakly_incrementable _OutIter>
+ requires indirectly_movable<_InIter, _OutIter>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ move_result<_InIter, _OutIter> operator()(_InIter __first, _Sent __last, _OutIter __result) const {
+ return __move_impl(std::move(__first), std::move(__last), std::move(__result));
+ }
+
+ template <input_range _Range, weakly_incrementable _OutIter>
+ requires indirectly_movable<iterator_t<_Range>, _OutIter>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ move_result<borrowed_iterator_t<_Range>, _OutIter> operator()(_Range&& __range, _OutIter __result) const {
+ return __move_impl(ranges::begin(__range), ranges::end(__range), std::move(__result));
+ }
+
+};
+} // namespace __move
+
+inline namespace __cpo {
+ inline constexpr auto move = __move::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_MOVE_H
diff --git a/libcxx/include/__algorithm/ranges_move_backward.h b/libcxx/include/__algorithm/ranges_move_backward.h
new file mode 100644
index 000000000000..b3dfa7139603
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_move_backward.h
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_RANGES_MOVE_BACKWARD_H
+#define _LIBCPP___ALGORITHM_RANGES_MOVE_BACKWARD_H
+
+#include <__algorithm/in_out_result.h>
+#include <__algorithm/ranges_move.h>
+#include <__config>
+#include <__iterator/concepts.h>
+#include <__iterator/iter_move.h>
+#include <__iterator/next.h>
+#include <__iterator/reverse_iterator.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/dangling.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+
+template <class _InIter, class _OutIter>
+using move_backward_result = in_out_result<_InIter, _OutIter>;
+
+namespace __move_backward {
+struct __fn {
+
+ template <class _InIter, class _Sent, class _OutIter>
+ _LIBCPP_HIDE_FROM_ABI constexpr static
+ move_backward_result<_InIter, _OutIter> __move_backward_impl(_InIter __first, _Sent __last, _OutIter __result) {
+ auto __ret = ranges::move(std::make_reverse_iterator(ranges::next(__first, __last)),
+ std::make_reverse_iterator(__first),
+ std::make_reverse_iterator(__result));
+ return {std::move(__ret.in.base()), std::move(__ret.out.base())};
+ }
+
+ template <bidirectional_iterator _InIter, sentinel_for<_InIter> _Sent, bidirectional_iterator _OutIter>
+ requires indirectly_movable<_InIter, _OutIter>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ move_backward_result<_InIter, _OutIter> operator()(_InIter __first, _Sent __last, _OutIter __result) const {
+ return __move_backward_impl(std::move(__first), std::move(__last), std::move(__result));
+ }
+
+ template <bidirectional_range _Range, bidirectional_iterator _Iter>
+ requires indirectly_movable<iterator_t<_Range>, _Iter>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ move_backward_result<borrowed_iterator_t<_Range>, _Iter> operator()(_Range&& __range, _Iter __result) const {
+ return __move_backward_impl(ranges::begin(__range), ranges::end(__range), std::move(__result));
+ }
+
+};
+} // namespace __move_backward
+
+inline namespace __cpo {
+ inline constexpr auto move_backward = __move_backward::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_MOVE_BACKWARD_H
diff --git a/libcxx/include/__algorithm/ranges_none_of.h b/libcxx/include/__algorithm/ranges_none_of.h
new file mode 100644
index 000000000000..706ff5cd741d
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_none_of.h
@@ -0,0 +1,68 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_RANGES_NONE_OF_H
+#define _LIBCPP___ALGORITHM_RANGES_NONE_OF_H
+
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
+#include <__iterator/concepts.h>
+#include <__iterator/projected.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+namespace __none_of {
+struct __fn {
+
+ template <class _Iter, class _Sent, class _Proj, class _Pred>
+ _LIBCPP_HIDE_FROM_ABI constexpr static
+ bool __none_of_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) {
+ for (; __first != __last; ++__first) {
+ if (std::invoke(__pred, std::invoke(__proj, *__first)))
+ return false;
+ }
+ return true;
+ }
+
+ template <input_iterator _Iter, sentinel_for<_Iter> _Sent, class _Proj = identity,
+ indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ bool operator()(_Iter __first, _Sent __last, _Pred __pred = {}, _Proj __proj = {}) const {
+ return __none_of_impl(std::move(__first), std::move(__last), __pred, __proj);
+ }
+
+ template <input_range _Range, class _Proj = identity,
+ indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ bool operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const {
+ return __none_of_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj);
+ }
+};
+} // namespace __none_of
+
+inline namespace __cpo {
+ inline constexpr auto none_of = __none_of::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_NONE_OF_H
diff --git a/libcxx/include/__algorithm/ranges_replace.h b/libcxx/include/__algorithm/ranges_replace.h
new file mode 100644
index 000000000000..5e74c3ff80cb
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_replace.h
@@ -0,0 +1,74 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_RANGES_REPLACE_H
+#define _LIBCPP___ALGORITHM_RANGES_REPLACE_H
+
+#include <__algorithm/ranges_replace_if.h>
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/projected.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/dangling.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined (_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+namespace __replace {
+struct __fn {
+
+ template <input_iterator _Iter, sentinel_for<_Iter> _Sent,
+ class _Type1,
+ class _Type2,
+ class _Proj = identity>
+ requires indirectly_writable<_Iter, const _Type2&>
+ && indirect_binary_predicate<ranges::equal_to, projected<_Iter, _Proj>, const _Type1*>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ _Iter operator()(_Iter __first, _Sent __last,
+ const _Type1& __old_value,
+ const _Type2& __new_value,
+ _Proj __proj = {}) const {
+ auto __pred = [&](const auto& __val) { return __val == __old_value; };
+ return ranges::__replace_if_impl(std::move(__first), std::move(__last), __pred, __new_value, __proj);
+ }
+
+ template <input_range _Range,
+ class _Type1,
+ class _Type2,
+ class _Proj = identity>
+ requires indirectly_writable<iterator_t<_Range>, const _Type2&>
+ && indirect_binary_predicate<ranges::equal_to, projected<iterator_t<_Range>, _Proj>, const _Type1*>
+ _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range>
+ operator()(_Range&& __range, const _Type1& __old_value, const _Type2& __new_value, _Proj __proj = {}) const {
+ auto __pred = [&](auto&& __val) { return __val == __old_value; };
+ return ranges::__replace_if_impl(ranges::begin(__range), ranges::end(__range), __pred, __new_value, __proj);
+ }
+
+};
+} // namespace __replace
+
+inline namespace __cpo {
+ inline constexpr auto replace = __replace::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined (_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_REPLACE_H
diff --git a/libcxx/include/__algorithm/ranges_replace_if.h b/libcxx/include/__algorithm/ranges_replace_if.h
new file mode 100644
index 000000000000..0f9555fc35c2
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_replace_if.h
@@ -0,0 +1,77 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_RANGES_REPLACE_IF_H
+#define _LIBCPP___ALGORITHM_RANGES_REPLACE_IF_H
+
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
+#include <__iterator/concepts.h>
+#include <__iterator/projected.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/dangling.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined (_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+
+template <class _Iter, class _Sent, class _Type, class _Proj, class _Pred>
+_LIBCPP_HIDE_FROM_ABI constexpr
+_Iter __replace_if_impl(_Iter __first, _Sent __last, _Pred& __pred, const _Type& __new_value, _Proj& __proj) {
+ for (; __first != __last; ++__first) {
+ if (std::invoke(__pred, std::invoke(__proj, *__first)))
+ *__first = __new_value;
+ }
+ return __first;
+}
+
+namespace __replace_if {
+struct __fn {
+
+ template <input_iterator _Iter, sentinel_for<_Iter> _Sent,
+ class _Type,
+ class _Proj = identity,
+ indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
+ requires indirectly_writable<_Iter, const _Type&>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ _Iter operator()(_Iter __first, _Sent __last, _Pred __pred, const _Type& __new_value, _Proj __proj = {}) const {
+ return ranges::__replace_if_impl(std::move(__first), std::move(__last), __pred, __new_value, __proj);
+ }
+
+ template <input_range _Range,
+ class _Type,
+ class _Proj = identity,
+ indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred>
+ requires indirectly_writable<iterator_t<_Range>, const _Type&>
+ _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range>
+ operator()(_Range&& __range, _Pred __pred, const _Type& __new_value, _Proj __proj = {}) const {
+ return ranges::__replace_if_impl(ranges::begin(__range), ranges::end(__range), __pred, __new_value, __proj);
+ }
+
+};
+} // namespace __replace_if
+
+inline namespace __cpo {
+ inline constexpr auto replace_if = __replace_if::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined (_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_REPLACE_IF_H
diff --git a/libcxx/include/__algorithm/ranges_reverse.h b/libcxx/include/__algorithm/ranges_reverse.h
new file mode 100644
index 000000000000..e7555d0f9acd
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_reverse.h
@@ -0,0 +1,83 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_RANGES_REVERSE_H
+#define _LIBCPP___ALGORITHM_RANGES_REVERSE_H
+
+#include <__config>
+#include <__iterator/concepts.h>
+#include <__iterator/iter_swap.h>
+#include <__iterator/next.h>
+#include <__iterator/permutable.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/dangling.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+namespace __reverse {
+struct __fn {
+
+ template <bidirectional_iterator _Iter, sentinel_for<_Iter> _Sent>
+ requires permutable<_Iter>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ _Iter operator()(_Iter __first, _Sent __last) const {
+ if constexpr (random_access_iterator<_Iter>) {
+ if (__first == __last)
+ return __first;
+
+ auto __end = ranges::next(__first, __last);
+ auto __ret = __end;
+
+ while (__first < --__end) {
+ ranges::iter_swap(__first, __end);
+ ++__first;
+ }
+ return __ret;
+ } else {
+ auto __end = ranges::next(__first, __last);
+ auto __ret = __end;
+
+ while (__first != __end) {
+ if (__first == --__end)
+ break;
+
+ ranges::iter_swap(__first, __end);
+ ++__first;
+ }
+ return __ret;
+ }
+ }
+
+ template <bidirectional_range _Range>
+ requires permutable<iterator_t<_Range>>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ borrowed_iterator_t<_Range> operator()(_Range&& __range) const {
+ return (*this)(ranges::begin(__range), ranges::end(__range));
+ }
+
+};
+} // namespace __reverse
+
+inline namespace __cpo {
+ inline constexpr auto reverse = __reverse::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_REVERSE_H
diff --git a/libcxx/include/__algorithm/ranges_sort.h b/libcxx/include/__algorithm/ranges_sort.h
new file mode 100644
index 000000000000..8297940df237
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_sort.h
@@ -0,0 +1,78 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_RANGES_SORT_H
+#define _LIBCPP___ALGORITHM_RANGES_SORT_H
+
+#include <__algorithm/make_projected.h>
+#include <__algorithm/sort.h>
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/iterator_traits.h>
+#include <__iterator/next.h>
+#include <__iterator/projected.h>
+#include <__iterator/sortable.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/dangling.h>
+#include <__utility/forward.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+namespace __sort {
+
+struct __fn {
+ template <class _Iter, class _Sent, class _Comp, class _Proj>
+ _LIBCPP_HIDE_FROM_ABI constexpr static
+ _Iter __sort_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
+ auto __last_iter = ranges::next(__first, __last);
+
+ auto&& __projected_comp = ranges::__make_projected_comp(__comp, __proj);
+ std::__sort_impl(std::move(__first), __last_iter, __projected_comp);
+
+ return __last_iter;
+ }
+
+ template <random_access_iterator _Iter, sentinel_for<_Iter> _Sent, class _Comp = ranges::less, class _Proj = identity>
+ requires sortable<_Iter, _Comp, _Proj>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ _Iter operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
+ return __sort_fn_impl(std::move(__first), std::move(__last), __comp, __proj);
+ }
+
+ template <random_access_range _Range, class _Comp = ranges::less, class _Proj = identity>
+ requires sortable<iterator_t<_Range>, _Comp, _Proj>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ borrowed_iterator_t<_Range> operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const {
+ return __sort_fn_impl(ranges::begin(__r), ranges::end(__r), __comp, __proj);
+ }
+};
+
+} // namespace __sort
+
+inline namespace __cpo {
+ inline constexpr auto sort = __sort::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_SORT_H
diff --git a/libcxx/include/__algorithm/ranges_stable_sort.h b/libcxx/include/__algorithm/ranges_stable_sort.h
new file mode 100644
index 000000000000..20e840426434
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_stable_sort.h
@@ -0,0 +1,78 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_RANGES_STABLE_SORT_H
+#define _LIBCPP___ALGORITHM_RANGES_STABLE_SORT_H
+
+#include <__algorithm/make_projected.h>
+#include <__algorithm/stable_sort.h>
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/iterator_traits.h>
+#include <__iterator/next.h>
+#include <__iterator/projected.h>
+#include <__iterator/sortable.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/dangling.h>
+#include <__utility/forward.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+namespace __stable_sort {
+
+struct __fn {
+ template <class _Iter, class _Sent, class _Comp, class _Proj>
+ _LIBCPP_HIDE_FROM_ABI
+ static _Iter __stable_sort_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
+ auto __last_iter = ranges::next(__first, __last);
+
+ auto&& __projected_comp = ranges::__make_projected_comp(__comp, __proj);
+ std::__stable_sort_impl(std::move(__first), __last_iter, __projected_comp);
+
+ return __last_iter;
+ }
+
+ template <random_access_iterator _Iter, sentinel_for<_Iter> _Sent, class _Comp = ranges::less, class _Proj = identity>
+ requires sortable<_Iter, _Comp, _Proj>
+ _LIBCPP_HIDE_FROM_ABI
+ _Iter operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
+ return __stable_sort_fn_impl(std::move(__first), std::move(__last), __comp, __proj);
+ }
+
+ template <random_access_range _Range, class _Comp = ranges::less, class _Proj = identity>
+ requires sortable<iterator_t<_Range>, _Comp, _Proj>
+ _LIBCPP_HIDE_FROM_ABI
+ borrowed_iterator_t<_Range> operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const {
+ return __stable_sort_fn_impl(ranges::begin(__r), ranges::end(__r), __comp, __proj);
+ }
+};
+
+} // namespace __stable_sort
+
+inline namespace __cpo {
+ inline constexpr auto stable_sort = __stable_sort::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_STABLE_SORT_H
diff --git a/libcxx/include/__algorithm/ranges_swap_ranges.h b/libcxx/include/__algorithm/ranges_swap_ranges.h
new file mode 100644
index 000000000000..3254e1c60abb
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_swap_ranges.h
@@ -0,0 +1,69 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_RANGES_SWAP_RANGES_H
+#define _LIBCPP___ALGORITHM_RANGES_SWAP_RANGES_H
+
+#include <__algorithm/in_in_result.h>
+#include <__config>
+#include <__iterator/concepts.h>
+#include <__iterator/iter_swap.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/dangling.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+
+template <class _I1, class _I2>
+using swap_ranges_result = in_in_result<_I1, _I2>;
+
+namespace __swap_ranges {
+struct __fn {
+ template <input_iterator _I1, sentinel_for<_I1> _S1,
+ input_iterator _I2, sentinel_for<_I2> _S2>
+ requires indirectly_swappable<_I1, _I2>
+ _LIBCPP_HIDE_FROM_ABI constexpr swap_ranges_result<_I1, _I2>
+ operator()(_I1 __first1, _S1 __last1, _I2 __first2, _S2 __last2) const {
+ while (__first1 != __last1 && __first2 != __last2) {
+ ranges::iter_swap(__first1, __first2);
+ ++__first1;
+ ++__first2;
+ }
+ return {_VSTD::move(__first1), _VSTD::move(__first2)};
+ }
+
+ template <input_range _R1, input_range _R2>
+ requires indirectly_swappable<iterator_t<_R1>, iterator_t<_R2>>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ swap_ranges_result<borrowed_iterator_t<_R1>, borrowed_iterator_t<_R2>>
+ operator()(_R1&& __r1, _R2&& __r2) const {
+ return operator()(ranges::begin(__r1), ranges::end(__r1),
+ ranges::begin(__r2), ranges::end(__r2));
+ }
+};
+} // namespace __swap_ranges
+
+inline namespace __cpo {
+ inline constexpr auto swap_ranges = __swap_ranges::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_SWAP_RANGES_H
diff --git a/libcxx/include/__algorithm/ranges_transform.h b/libcxx/include/__algorithm/ranges_transform.h
new file mode 100644
index 000000000000..3c13b1b79ff3
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_transform.h
@@ -0,0 +1,170 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_RANGES_TRANSFORM_H
+#define _LIBCPP___ALGORITHM_RANGES_TRANSFORM_H
+
+#include <__algorithm/in_in_out_result.h>
+#include <__algorithm/in_out_result.h>
+#include <__concepts/constructible.h>
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
+#include <__iterator/concepts.h>
+#include <__iterator/projected.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/dangling.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+
+template <class _Ip, class _Op>
+using unary_transform_result = in_out_result<_Ip, _Op>;
+
+template <class _I1, class _I2, class _O1>
+using binary_transform_result = in_in_out_result<_I1, _I2, _O1>;
+
+namespace __transform {
+struct __fn {
+private:
+ template <class _InIter, class _Sent,
+ class _OutIter,
+ class _Func,
+ class _Proj>
+ _LIBCPP_HIDE_FROM_ABI static constexpr
+ unary_transform_result<_InIter, _OutIter> __unary(_InIter __first, _Sent __last,
+ _OutIter __result,
+ _Func& __operation,
+ _Proj& __projection) {
+ while (__first != __last) {
+ *__result = std::invoke(__operation, std::invoke(__projection, *__first));
+ ++__first;
+ ++__result;
+ }
+
+ return {std::move(__first), std::move(__result)};
+ }
+
+ template <class _InIter1, class _Sent1,
+ class _InIter2, class _Sent2,
+ class _OutIter,
+ class _Func,
+ class _Proj1,
+ class _Proj2>
+ _LIBCPP_HIDE_FROM_ABI static constexpr binary_transform_result<_InIter1, _InIter2, _OutIter>
+ __binary(_InIter1 __first1, _Sent1 __last1,
+ _InIter2 __first2, _Sent2 __last2,
+ _OutIter __result,
+ _Func& __binary_operation,
+ _Proj1& __projection1,
+ _Proj2& __projection2) {
+ while (__first1 != __last1 && __first2 != __last2) {
+ *__result = std::invoke(__binary_operation, std::invoke(__projection1, *__first1),
+ std::invoke(__projection2, *__first2));
+ ++__first1;
+ ++__first2;
+ ++__result;
+ }
+ return {std::move(__first1), std::move(__first2), std::move(__result)};
+ }
+public:
+ template <input_iterator _InIter, sentinel_for<_InIter> _Sent,
+ weakly_incrementable _OutIter,
+ copy_constructible _Func,
+ class _Proj = identity>
+ requires indirectly_writable<_OutIter, indirect_result_t<_Func&, projected<_InIter, _Proj>>>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ unary_transform_result<_InIter, _OutIter> operator()(_InIter __first, _Sent __last,
+ _OutIter __result,
+ _Func __operation,
+ _Proj __proj = {}) const {
+ return __unary(std::move(__first), std::move(__last), std::move(__result), __operation, __proj);
+ }
+
+ template <input_range _Range,
+ weakly_incrementable _OutIter,
+ copy_constructible _Func,
+ class _Proj = identity>
+ requires indirectly_writable<_OutIter, indirect_result_t<_Func, projected<iterator_t<_Range>, _Proj>>>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ unary_transform_result<borrowed_iterator_t<_Range>, _OutIter> operator()(_Range&& __range,
+ _OutIter __result,
+ _Func __operation,
+ _Proj __projection = {}) const {
+ return __unary(ranges::begin(__range), ranges::end(__range), std::move(__result), __operation, __projection);
+ }
+
+ template <input_iterator _InIter1, sentinel_for<_InIter1> _Sent1,
+ input_iterator _InIter2, sentinel_for<_InIter2> _Sent2,
+ weakly_incrementable _OutIter,
+ copy_constructible _Func,
+ class _Proj1 = identity,
+ class _Proj2 = identity>
+ requires indirectly_writable<_OutIter, indirect_result_t<_Func&, projected<_InIter1, _Proj1>,
+ projected<_InIter2, _Proj2>>>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ binary_transform_result<_InIter1, _InIter2, _OutIter> operator()(_InIter1 __first1, _Sent1 __last1,
+ _InIter2 __first2, _Sent2 __last2,
+ _OutIter __result,
+ _Func __binary_operation,
+ _Proj1 __projection1 = {},
+ _Proj2 __projection2 = {}) const {
+ return __binary(std::move(__first1), std::move(__last1),
+ std::move(__first2), std::move(__last2),
+ std::move(__result),
+ __binary_operation,
+ __projection1,
+ __projection2);
+ }
+
+ template <input_range _Range1,
+ input_range _Range2,
+ weakly_incrementable _OutIter,
+ copy_constructible _Func,
+ class _Proj1 = identity,
+ class _Proj2 = identity>
+ requires indirectly_writable<_OutIter, indirect_result_t<_Func&, projected<iterator_t<_Range1>, _Proj1>,
+ projected<iterator_t<_Range2>, _Proj2>>>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ binary_transform_result<borrowed_iterator_t<_Range1>, borrowed_iterator_t<_Range2>, _OutIter>
+ operator()(_Range1&& __range1,
+ _Range2&& __range2,
+ _OutIter __result,
+ _Func __binary_operation,
+ _Proj1 __projection1 = {},
+ _Proj2 __projection2 = {}) const {
+ return __binary(ranges::begin(__range1), ranges::end(__range1),
+ ranges::begin(__range2), ranges::end(__range2),
+ std::move(__result),
+ __binary_operation,
+ __projection1,
+ __projection2);
+ }
+
+};
+} // namespace __transform
+
+inline namespace __cpo {
+ inline constexpr auto transform = __transform::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_TRANSFORM_H
diff --git a/libcxx/include/__algorithm/ranges_upper_bound.h b/libcxx/include/__algorithm/ranges_upper_bound.h
new file mode 100644
index 000000000000..94b5269c86af
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_upper_bound.h
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_RANGES_UPPER_BOUND_H
+#define _LIBCPP___ALGORITHM_RANGES_UPPER_BOUND_H
+
+#include <__algorithm/iterator_operations.h>
+#include <__algorithm/lower_bound.h>
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/projected.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/dangling.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+namespace __upper_bound {
+struct __fn {
+ template <forward_iterator _Iter, sentinel_for<_Iter> _Sent, class _Type, class _Proj = identity,
+ indirect_strict_weak_order<const _Type*, projected<_Iter, _Proj>> _Comp = ranges::less>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ _Iter operator()(_Iter __first, _Sent __last, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const {
+ auto __comp_lhs_rhs_swapped = [&](const auto& __lhs, const auto& __rhs) {
+ return !std::invoke(__comp, __rhs, __lhs);
+ };
+
+ return std::__lower_bound_impl<_RangesIterOps>(__first, __last, __value, __comp_lhs_rhs_swapped, __proj);
+ }
+
+ template <forward_range _Range, class _Type, class _Proj = identity,
+ indirect_strict_weak_order<const _Type*, projected<iterator_t<_Range>, _Proj>> _Comp = ranges::less>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ borrowed_iterator_t<_Range> operator()(_Range&& __r,
+ const _Type& __value,
+ _Comp __comp = {},
+ _Proj __proj = {}) const {
+ auto __comp_lhs_rhs_swapped = [&](const auto& __lhs, const auto& __rhs) {
+ return !std::invoke(__comp, __rhs, __lhs);
+ };
+
+ return std::__lower_bound_impl<_RangesIterOps>(ranges::begin(__r),
+ ranges::end(__r),
+ __value,
+ __comp_lhs_rhs_swapped,
+ __proj);
+ }
+};
+} // namespace __upper_bound
+
+inline namespace __cpo {
+ inline constexpr auto upper_bound = __upper_bound::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_UPPER_BOUND_H
diff --git a/libcxx/include/__algorithm/remove.h b/libcxx/include/__algorithm/remove.h
index 681b9cc768d9..c00f96f78a63 100644
--- a/libcxx/include/__algorithm/remove.h
+++ b/libcxx/include/__algorithm/remove.h
@@ -15,7 +15,7 @@
#include <__utility/move.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/remove_copy.h b/libcxx/include/__algorithm/remove_copy.h
index 338ca94300bb..a29a385af9ac 100644
--- a/libcxx/include/__algorithm/remove_copy.h
+++ b/libcxx/include/__algorithm/remove_copy.h
@@ -12,7 +12,7 @@
#include <__config>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/remove_copy_if.h b/libcxx/include/__algorithm/remove_copy_if.h
index a55638722074..36ddba4883ab 100644
--- a/libcxx/include/__algorithm/remove_copy_if.h
+++ b/libcxx/include/__algorithm/remove_copy_if.h
@@ -12,7 +12,7 @@
#include <__config>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/remove_if.h b/libcxx/include/__algorithm/remove_if.h
index 36f817cfa6e1..0ae131498d22 100644
--- a/libcxx/include/__algorithm/remove_if.h
+++ b/libcxx/include/__algorithm/remove_if.h
@@ -11,10 +11,10 @@
#include <__algorithm/find_if.h>
#include <__config>
-#include <utility>
+#include <__utility/move.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/replace.h b/libcxx/include/__algorithm/replace.h
index 2bc96ffc87dc..d0ae8f65d4a2 100644
--- a/libcxx/include/__algorithm/replace.h
+++ b/libcxx/include/__algorithm/replace.h
@@ -12,7 +12,7 @@
#include <__config>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/replace_copy.h b/libcxx/include/__algorithm/replace_copy.h
index c6c5fe32e81c..7c8a5a0b93cb 100644
--- a/libcxx/include/__algorithm/replace_copy.h
+++ b/libcxx/include/__algorithm/replace_copy.h
@@ -12,7 +12,7 @@
#include <__config>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/replace_copy_if.h b/libcxx/include/__algorithm/replace_copy_if.h
index 274d8e630ef1..9d8a68fdc0f3 100644
--- a/libcxx/include/__algorithm/replace_copy_if.h
+++ b/libcxx/include/__algorithm/replace_copy_if.h
@@ -12,7 +12,7 @@
#include <__config>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/replace_if.h b/libcxx/include/__algorithm/replace_if.h
index bcc3feb2f507..37c719a34c84 100644
--- a/libcxx/include/__algorithm/replace_if.h
+++ b/libcxx/include/__algorithm/replace_if.h
@@ -12,7 +12,7 @@
#include <__config>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/reverse.h b/libcxx/include/__algorithm/reverse.h
index 1198aeaf41f4..0202cd740833 100644
--- a/libcxx/include/__algorithm/reverse.h
+++ b/libcxx/include/__algorithm/reverse.h
@@ -14,7 +14,7 @@
#include <__iterator/iterator_traits.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/reverse_copy.h b/libcxx/include/__algorithm/reverse_copy.h
index 002c0344a794..158390707803 100644
--- a/libcxx/include/__algorithm/reverse_copy.h
+++ b/libcxx/include/__algorithm/reverse_copy.h
@@ -12,7 +12,7 @@
#include <__config>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/rotate.h b/libcxx/include/__algorithm/rotate.h
index fd6d3e9c114f..c9ea5bad4c5a 100644
--- a/libcxx/include/__algorithm/rotate.h
+++ b/libcxx/include/__algorithm/rotate.h
@@ -16,11 +16,12 @@
#include <__iterator/iterator_traits.h>
#include <__iterator/next.h>
#include <__iterator/prev.h>
+#include <__utility/move.h>
#include <__utility/swap.h>
-#include <iterator>
+#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/rotate_copy.h b/libcxx/include/__algorithm/rotate_copy.h
index f9e644c88d0e..ab569ef7c6be 100644
--- a/libcxx/include/__algorithm/rotate_copy.h
+++ b/libcxx/include/__algorithm/rotate_copy.h
@@ -13,7 +13,7 @@
#include <__config>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/sample.h b/libcxx/include/__algorithm/sample.h
index 33264c4ea3a7..e04466a08d5a 100644
--- a/libcxx/include/__algorithm/sample.h
+++ b/libcxx/include/__algorithm/sample.h
@@ -10,13 +10,15 @@
#define _LIBCPP___ALGORITHM_SAMPLE_H
#include <__algorithm/min.h>
+#include <__assert>
#include <__config>
-#include <__debug>
+#include <__iterator/distance.h>
+#include <__iterator/iterator_traits.h>
#include <__random/uniform_int_distribution.h>
-#include <iterator>
+#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
diff --git a/libcxx/include/__algorithm/search.h b/libcxx/include/__algorithm/search.h
index cfaec0ed1e17..d89ec2b1c5bc 100644
--- a/libcxx/include/__algorithm/search.h
+++ b/libcxx/include/__algorithm/search.h
@@ -13,10 +13,10 @@
#include <__algorithm/comp.h>
#include <__config>
#include <__iterator/iterator_traits.h>
-#include <utility>
+#include <__utility/pair.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/search_n.h b/libcxx/include/__algorithm/search_n.h
index e4576cc76ac4..4c083de65ee2 100644
--- a/libcxx/include/__algorithm/search_n.h
+++ b/libcxx/include/__algorithm/search_n.h
@@ -16,7 +16,7 @@
#include <type_traits> // __convert_to_integral
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/set_difference.h b/libcxx/include/__algorithm/set_difference.h
index 00f61e070b4b..5e2dca24e446 100644
--- a/libcxx/include/__algorithm/set_difference.h
+++ b/libcxx/include/__algorithm/set_difference.h
@@ -16,7 +16,7 @@
#include <__iterator/iterator_traits.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/set_intersection.h b/libcxx/include/__algorithm/set_intersection.h
index f6aa38217d95..c4163fcd4c3c 100644
--- a/libcxx/include/__algorithm/set_intersection.h
+++ b/libcxx/include/__algorithm/set_intersection.h
@@ -15,7 +15,7 @@
#include <__iterator/iterator_traits.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/set_symmetric_difference.h b/libcxx/include/__algorithm/set_symmetric_difference.h
index 5b5c2acff773..2dbfb35d7be6 100644
--- a/libcxx/include/__algorithm/set_symmetric_difference.h
+++ b/libcxx/include/__algorithm/set_symmetric_difference.h
@@ -16,7 +16,7 @@
#include <__iterator/iterator_traits.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/set_union.h b/libcxx/include/__algorithm/set_union.h
index 5b3e3af79b4f..0ec6b09380ed 100644
--- a/libcxx/include/__algorithm/set_union.h
+++ b/libcxx/include/__algorithm/set_union.h
@@ -16,7 +16,7 @@
#include <__iterator/iterator_traits.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/shift_left.h b/libcxx/include/__algorithm/shift_left.h
index 0466a3188a75..33f06d57e23a 100644
--- a/libcxx/include/__algorithm/shift_left.h
+++ b/libcxx/include/__algorithm/shift_left.h
@@ -15,7 +15,7 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/shift_right.h b/libcxx/include/__algorithm/shift_right.h
index 121712e85532..14bc761598b2 100644
--- a/libcxx/include/__algorithm/shift_right.h
+++ b/libcxx/include/__algorithm/shift_right.h
@@ -18,7 +18,7 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/shuffle.h b/libcxx/include/__algorithm/shuffle.h
index 7f6ad50e241e..6c6ff5675dad 100644
--- a/libcxx/include/__algorithm/shuffle.h
+++ b/libcxx/include/__algorithm/shuffle.h
@@ -10,6 +10,7 @@
#define _LIBCPP___ALGORITHM_SHUFFLE_H
#include <__config>
+#include <__debug>
#include <__iterator/iterator_traits.h>
#include <__random/uniform_int_distribution.h>
#include <__utility/swap.h>
@@ -17,7 +18,7 @@
#include <cstdint>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
diff --git a/libcxx/include/__algorithm/sift_down.h b/libcxx/include/__algorithm/sift_down.h
index bf5447698cd6..0351a1c578b0 100644
--- a/libcxx/include/__algorithm/sift_down.h
+++ b/libcxx/include/__algorithm/sift_down.h
@@ -9,12 +9,13 @@
#ifndef _LIBCPP___ALGORITHM_SIFT_DOWN_H
#define _LIBCPP___ALGORITHM_SIFT_DOWN_H
+#include <__assert>
#include <__config>
#include <__iterator/iterator_traits.h>
#include <__utility/move.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -73,6 +74,38 @@ __sift_down(_RandomAccessIterator __first, _Compare __comp,
*__start = _VSTD::move(__top);
}
+template <class _Compare, class _RandomAccessIterator>
+_LIBCPP_CONSTEXPR_AFTER_CXX11 _RandomAccessIterator
+__floyd_sift_down(_RandomAccessIterator __first, _Compare __comp,
+ typename iterator_traits<_RandomAccessIterator>::difference_type __len)
+{
+ using difference_type = typename iterator_traits<_RandomAccessIterator>::difference_type;
+ _LIBCPP_ASSERT(__len >= 2, "shouldn't be called unless __len >= 2");
+
+ _RandomAccessIterator __hole = __first;
+ _RandomAccessIterator __child_i = __first;
+ difference_type __child = 0;
+
+ while (true) {
+ __child_i += difference_type(__child + 1);
+ __child = 2 * __child + 1;
+
+ if ((__child + 1) < __len && __comp(*__child_i, *(__child_i + difference_type(1)))) {
+ // right-child exists and is greater than left-child
+ ++__child_i;
+ ++__child;
+ }
+
+ // swap __hole with its largest child
+ *__hole = std::move(*__child_i);
+ __hole = __child_i;
+
+ // if __hole is now a leaf, we're done
+ if (__child > (__len - 2) / 2)
+ return __hole;
+ }
+}
+
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___ALGORITHM_SIFT_DOWN_H
diff --git a/libcxx/include/__algorithm/sort.h b/libcxx/include/__algorithm/sort.h
index 5e09b280080a..f7406a5170e1 100644
--- a/libcxx/include/__algorithm/sort.h
+++ b/libcxx/include/__algorithm/sort.h
@@ -14,8 +14,14 @@
#include <__algorithm/min_element.h>
#include <__algorithm/partial_sort.h>
#include <__algorithm/unwrap_iter.h>
+#include <__bits>
#include <__config>
+#include <__debug>
+#include <__functional/operations.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/iterator_traits.h>
#include <__utility/swap.h>
+#include <climits>
#include <memory>
#if defined(_LIBCPP_DEBUG_RANDOMIZE_UNSPECIFIED_STABILITY)
@@ -23,7 +29,7 @@
#endif
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -31,442 +37,489 @@ _LIBCPP_BEGIN_NAMESPACE_STD
// stable, 2-3 compares, 0-2 swaps
template <class _Compare, class _ForwardIterator>
-_LIBCPP_CONSTEXPR_AFTER_CXX11 unsigned
-__sort3(_ForwardIterator __x, _ForwardIterator __y, _ForwardIterator __z, _Compare __c)
-{
- unsigned __r = 0;
- if (!__c(*__y, *__x)) // if x <= y
+_LIBCPP_CONSTEXPR_AFTER_CXX11 unsigned __sort3(_ForwardIterator __x, _ForwardIterator __y, _ForwardIterator __z,
+ _Compare __c) {
+ unsigned __r = 0;
+ if (!__c(*__y, *__x)) // if x <= y
+ {
+ if (!__c(*__z, *__y)) // if y <= z
+ return __r; // x <= y && y <= z
+ // x <= y && y > z
+ swap(*__y, *__z); // x <= z && y < z
+ __r = 1;
+ if (__c(*__y, *__x)) // if x > y
{
- if (!__c(*__z, *__y)) // if y <= z
- return __r; // x <= y && y <= z
- // x <= y && y > z
- swap(*__y, *__z); // x <= z && y < z
- __r = 1;
- if (__c(*__y, *__x)) // if x > y
- {
- swap(*__x, *__y); // x < y && y <= z
- __r = 2;
- }
- return __r; // x <= y && y < z
- }
- if (__c(*__z, *__y)) // x > y, if y > z
- {
- swap(*__x, *__z); // x < y && y < z
- __r = 1;
- return __r;
- }
- swap(*__x, *__y); // x > y && y <= z
- __r = 1; // x < y && x <= z
- if (__c(*__z, *__y)) // if y > z
- {
- swap(*__y, *__z); // x <= y && y < z
- __r = 2;
+ swap(*__x, *__y); // x < y && y <= z
+ __r = 2;
}
+ return __r; // x <= y && y < z
+ }
+ if (__c(*__z, *__y)) // x > y, if y > z
+ {
+ swap(*__x, *__z); // x < y && y < z
+ __r = 1;
return __r;
-} // x <= y && y <= z
+ }
+ swap(*__x, *__y); // x > y && y <= z
+ __r = 1; // x < y && x <= z
+ if (__c(*__z, *__y)) // if y > z
+ {
+ swap(*__y, *__z); // x <= y && y < z
+ __r = 2;
+ }
+ return __r;
+} // x <= y && y <= z
// stable, 3-6 compares, 0-5 swaps
template <class _Compare, class _ForwardIterator>
-unsigned
-__sort4(_ForwardIterator __x1, _ForwardIterator __x2, _ForwardIterator __x3,
- _ForwardIterator __x4, _Compare __c)
-{
- unsigned __r = _VSTD::__sort3<_Compare>(__x1, __x2, __x3, __c);
- if (__c(*__x4, *__x3))
- {
- swap(*__x3, *__x4);
+unsigned __sort4(_ForwardIterator __x1, _ForwardIterator __x2, _ForwardIterator __x3, _ForwardIterator __x4,
+ _Compare __c) {
+ unsigned __r = _VSTD::__sort3<_Compare>(__x1, __x2, __x3, __c);
+ if (__c(*__x4, *__x3)) {
+ swap(*__x3, *__x4);
+ ++__r;
+ if (__c(*__x3, *__x2)) {
+ swap(*__x2, *__x3);
+ ++__r;
+ if (__c(*__x2, *__x1)) {
+ swap(*__x1, *__x2);
++__r;
- if (__c(*__x3, *__x2))
- {
- swap(*__x2, *__x3);
- ++__r;
- if (__c(*__x2, *__x1))
- {
- swap(*__x1, *__x2);
- ++__r;
- }
- }
+ }
}
- return __r;
+ }
+ return __r;
}
// stable, 4-10 compares, 0-9 swaps
template <class _Compare, class _ForwardIterator>
-_LIBCPP_HIDDEN
-unsigned
-__sort5(_ForwardIterator __x1, _ForwardIterator __x2, _ForwardIterator __x3,
- _ForwardIterator __x4, _ForwardIterator __x5, _Compare __c)
-{
- unsigned __r = _VSTD::__sort4<_Compare>(__x1, __x2, __x3, __x4, __c);
- if (__c(*__x5, *__x4))
- {
- swap(*__x4, *__x5);
+_LIBCPP_HIDDEN unsigned __sort5(_ForwardIterator __x1, _ForwardIterator __x2, _ForwardIterator __x3,
+ _ForwardIterator __x4, _ForwardIterator __x5, _Compare __c) {
+ unsigned __r = _VSTD::__sort4<_Compare>(__x1, __x2, __x3, __x4, __c);
+ if (__c(*__x5, *__x4)) {
+ swap(*__x4, *__x5);
+ ++__r;
+ if (__c(*__x4, *__x3)) {
+ swap(*__x3, *__x4);
+ ++__r;
+ if (__c(*__x3, *__x2)) {
+ swap(*__x2, *__x3);
++__r;
- if (__c(*__x4, *__x3))
- {
- swap(*__x3, *__x4);
- ++__r;
- if (__c(*__x3, *__x2))
- {
- swap(*__x2, *__x3);
- ++__r;
- if (__c(*__x2, *__x1))
- {
- swap(*__x1, *__x2);
- ++__r;
- }
- }
+ if (__c(*__x2, *__x1)) {
+ swap(*__x1, *__x2);
+ ++__r;
}
+ }
}
- return __r;
+ }
+ return __r;
+}
+
+// The comparator being simple is a prerequisite for using the branchless optimization.
+template <class _Tp>
+struct __is_simple_comparator : false_type {};
+template <class _Tp>
+struct __is_simple_comparator<__less<_Tp>&> : true_type {};
+template <class _Tp>
+struct __is_simple_comparator<less<_Tp>&> : true_type {};
+template <class _Tp>
+struct __is_simple_comparator<greater<_Tp>&> : true_type {};
+#if _LIBCPP_STD_VER > 17
+template <>
+struct __is_simple_comparator<ranges::less&> : true_type {};
+template <>
+struct __is_simple_comparator<ranges::greater&> : true_type {};
+#endif
+
+template <class _Compare, class _Iter, class _Tp = typename iterator_traits<_Iter>::value_type>
+using __use_branchless_sort =
+ integral_constant<bool, __is_cpp17_contiguous_iterator<_Iter>::value && sizeof(_Tp) <= sizeof(void*) &&
+ is_arithmetic<_Tp>::value && __is_simple_comparator<_Compare>::value>;
+
+// Ensures that __c(*__x, *__y) is true by swapping *__x and *__y if necessary.
+template <class _Compare, class _RandomAccessIterator>
+inline _LIBCPP_HIDE_FROM_ABI void __cond_swap(_RandomAccessIterator __x, _RandomAccessIterator __y, _Compare __c) {
+ using value_type = typename iterator_traits<_RandomAccessIterator>::value_type;
+ bool __r = __c(*__x, *__y);
+ value_type __tmp = __r ? *__x : *__y;
+ *__y = __r ? *__y : *__x;
+ *__x = __tmp;
+}
+
+// Ensures that *__x, *__y and *__z are ordered according to the comparator __c,
+// under the assumption that *__y and *__z are already ordered.
+template <class _Compare, class _RandomAccessIterator>
+inline _LIBCPP_HIDE_FROM_ABI void __partially_sorted_swap(_RandomAccessIterator __x, _RandomAccessIterator __y,
+ _RandomAccessIterator __z, _Compare __c) {
+ using value_type = typename iterator_traits<_RandomAccessIterator>::value_type;
+ bool __r = __c(*__z, *__x);
+ value_type __tmp = __r ? *__z : *__x;
+ *__z = __r ? *__x : *__z;
+ __r = __c(__tmp, *__y);
+ *__x = __r ? *__x : *__y;
+ *__y = __r ? *__y : __tmp;
+}
+
+template <class _Compare, class _RandomAccessIterator>
+inline _LIBCPP_HIDE_FROM_ABI __enable_if_t<__use_branchless_sort<_Compare, _RandomAccessIterator>::value, void>
+__sort3_maybe_branchless(_RandomAccessIterator __x1, _RandomAccessIterator __x2, _RandomAccessIterator __x3,
+ _Compare __c) {
+ _VSTD::__cond_swap<_Compare>(__x2, __x3, __c);
+ _VSTD::__partially_sorted_swap<_Compare>(__x1, __x2, __x3, __c);
+}
+
+template <class _Compare, class _RandomAccessIterator>
+inline _LIBCPP_HIDE_FROM_ABI __enable_if_t<!__use_branchless_sort<_Compare, _RandomAccessIterator>::value, void>
+__sort3_maybe_branchless(_RandomAccessIterator __x1, _RandomAccessIterator __x2, _RandomAccessIterator __x3,
+ _Compare __c) {
+ _VSTD::__sort3<_Compare>(__x1, __x2, __x3, __c);
+}
+
+template <class _Compare, class _RandomAccessIterator>
+inline _LIBCPP_HIDE_FROM_ABI __enable_if_t<__use_branchless_sort<_Compare, _RandomAccessIterator>::value, void>
+__sort4_maybe_branchless(_RandomAccessIterator __x1, _RandomAccessIterator __x2, _RandomAccessIterator __x3,
+ _RandomAccessIterator __x4, _Compare __c) {
+ _VSTD::__cond_swap<_Compare>(__x1, __x3, __c);
+ _VSTD::__cond_swap<_Compare>(__x2, __x4, __c);
+ _VSTD::__cond_swap<_Compare>(__x1, __x2, __c);
+ _VSTD::__cond_swap<_Compare>(__x3, __x4, __c);
+ _VSTD::__cond_swap<_Compare>(__x2, __x3, __c);
+}
+
+template <class _Compare, class _RandomAccessIterator>
+inline _LIBCPP_HIDE_FROM_ABI __enable_if_t<!__use_branchless_sort<_Compare, _RandomAccessIterator>::value, void>
+__sort4_maybe_branchless(_RandomAccessIterator __x1, _RandomAccessIterator __x2, _RandomAccessIterator __x3,
+ _RandomAccessIterator __x4, _Compare __c) {
+ _VSTD::__sort4<_Compare>(__x1, __x2, __x3, __x4, __c);
+}
+
+template <class _Compare, class _RandomAccessIterator>
+inline _LIBCPP_HIDE_FROM_ABI __enable_if_t<__use_branchless_sort<_Compare, _RandomAccessIterator>::value, void>
+__sort5_maybe_branchless(_RandomAccessIterator __x1, _RandomAccessIterator __x2, _RandomAccessIterator __x3,
+ _RandomAccessIterator __x4, _RandomAccessIterator __x5, _Compare __c) {
+ _VSTD::__cond_swap<_Compare>(__x1, __x2, __c);
+ _VSTD::__cond_swap<_Compare>(__x4, __x5, __c);
+ _VSTD::__partially_sorted_swap<_Compare>(__x3, __x4, __x5, __c);
+ _VSTD::__cond_swap<_Compare>(__x2, __x5, __c);
+ _VSTD::__partially_sorted_swap<_Compare>(__x1, __x3, __x4, __c);
+ _VSTD::__partially_sorted_swap<_Compare>(__x2, __x3, __x4, __c);
+}
+
+template <class _Compare, class _RandomAccessIterator>
+inline _LIBCPP_HIDE_FROM_ABI __enable_if_t<!__use_branchless_sort<_Compare, _RandomAccessIterator>::value, void>
+__sort5_maybe_branchless(_RandomAccessIterator __x1, _RandomAccessIterator __x2, _RandomAccessIterator __x3,
+ _RandomAccessIterator __x4, _RandomAccessIterator __x5, _Compare __c) {
+ _VSTD::__sort5<_Compare>(__x1, __x2, __x3, __x4, __x5, __c);
}
// Assumes size > 0
template <class _Compare, class _BidirectionalIterator>
-_LIBCPP_CONSTEXPR_AFTER_CXX11 void
-__selection_sort(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp)
-{
- _BidirectionalIterator __lm1 = __last;
- for (--__lm1; __first != __lm1; ++__first)
- {
- _BidirectionalIterator __i = _VSTD::min_element(__first, __last, __comp);
- if (__i != __first)
- swap(*__first, *__i);
- }
+_LIBCPP_CONSTEXPR_AFTER_CXX11 void __selection_sort(_BidirectionalIterator __first, _BidirectionalIterator __last,
+ _Compare __comp) {
+ _BidirectionalIterator __lm1 = __last;
+ for (--__lm1; __first != __lm1; ++__first) {
+ _BidirectionalIterator __i = _VSTD::min_element(__first, __last, __comp);
+ if (__i != __first)
+ swap(*__first, *__i);
+ }
}
template <class _Compare, class _BidirectionalIterator>
-void
-__insertion_sort(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp)
-{
- typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;
- if (__first != __last)
- {
- _BidirectionalIterator __i = __first;
- for (++__i; __i != __last; ++__i)
- {
- _BidirectionalIterator __j = __i;
- value_type __t(_VSTD::move(*__j));
- for (_BidirectionalIterator __k = __i; __k != __first && __comp(__t, *--__k); --__j)
- *__j = _VSTD::move(*__k);
- *__j = _VSTD::move(__t);
- }
+void __insertion_sort(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) {
+ typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;
+ if (__first != __last) {
+ _BidirectionalIterator __i = __first;
+ for (++__i; __i != __last; ++__i) {
+ _BidirectionalIterator __j = __i;
+ value_type __t(_VSTD::move(*__j));
+ for (_BidirectionalIterator __k = __i; __k != __first && __comp(__t, *--__k); --__j)
+ *__j = _VSTD::move(*__k);
+ *__j = _VSTD::move(__t);
}
+ }
}
template <class _Compare, class _RandomAccessIterator>
-void
-__insertion_sort_3(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
-{
- typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
- typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
- _RandomAccessIterator __j = __first+difference_type(2);
- _VSTD::__sort3<_Compare>(__first, __first+difference_type(1), __j, __comp);
- for (_RandomAccessIterator __i = __j+difference_type(1); __i != __last; ++__i)
- {
- if (__comp(*__i, *__j))
- {
- value_type __t(_VSTD::move(*__i));
- _RandomAccessIterator __k = __j;
- __j = __i;
- do
- {
- *__j = _VSTD::move(*__k);
- __j = __k;
- } while (__j != __first && __comp(__t, *--__k));
- *__j = _VSTD::move(__t);
- }
- __j = __i;
+void __insertion_sort_3(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) {
+ typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
+ typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
+ _RandomAccessIterator __j = __first + difference_type(2);
+ _VSTD::__sort3_maybe_branchless<_Compare>(__first, __first + difference_type(1), __j, __comp);
+ for (_RandomAccessIterator __i = __j + difference_type(1); __i != __last; ++__i) {
+ if (__comp(*__i, *__j)) {
+ value_type __t(_VSTD::move(*__i));
+ _RandomAccessIterator __k = __j;
+ __j = __i;
+ do {
+ *__j = _VSTD::move(*__k);
+ __j = __k;
+ } while (__j != __first && __comp(__t, *--__k));
+ *__j = _VSTD::move(__t);
}
+ __j = __i;
+ }
}
template <class _Compare, class _RandomAccessIterator>
-bool
-__insertion_sort_incomplete(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
-{
- typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
- switch (__last - __first)
- {
+bool __insertion_sort_incomplete(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) {
+ typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
+ switch (__last - __first) {
+ case 0:
+ case 1:
+ return true;
+ case 2:
+ if (__comp(*--__last, *__first))
+ swap(*__first, *__last);
+ return true;
+ case 3:
+ _VSTD::__sort3_maybe_branchless<_Compare>(__first, __first + difference_type(1), --__last, __comp);
+ return true;
+ case 4:
+ _VSTD::__sort4_maybe_branchless<_Compare>(__first, __first + difference_type(1), __first + difference_type(2),
+ --__last, __comp);
+ return true;
+ case 5:
+ _VSTD::__sort5_maybe_branchless<_Compare>(__first, __first + difference_type(1), __first + difference_type(2),
+ __first + difference_type(3), --__last, __comp);
+ return true;
+ }
+ typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
+ _RandomAccessIterator __j = __first + difference_type(2);
+ _VSTD::__sort3_maybe_branchless<_Compare>(__first, __first + difference_type(1), __j, __comp);
+ const unsigned __limit = 8;
+ unsigned __count = 0;
+ for (_RandomAccessIterator __i = __j + difference_type(1); __i != __last; ++__i) {
+ if (__comp(*__i, *__j)) {
+ value_type __t(_VSTD::move(*__i));
+ _RandomAccessIterator __k = __j;
+ __j = __i;
+ do {
+ *__j = _VSTD::move(*__k);
+ __j = __k;
+ } while (__j != __first && __comp(__t, *--__k));
+ *__j = _VSTD::move(__t);
+ if (++__count == __limit)
+ return ++__i == __last;
+ }
+ __j = __i;
+ }
+ return true;
+}
+
+template <class _Compare, class _BidirectionalIterator>
+void __insertion_sort_move(_BidirectionalIterator __first1, _BidirectionalIterator __last1,
+ typename iterator_traits<_BidirectionalIterator>::value_type* __first2, _Compare __comp) {
+ typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;
+ if (__first1 != __last1) {
+ __destruct_n __d(0);
+ unique_ptr<value_type, __destruct_n&> __h(__first2, __d);
+ value_type* __last2 = __first2;
+ ::new ((void*)__last2) value_type(_VSTD::move(*__first1));
+ __d.template __incr<value_type>();
+ for (++__last2; ++__first1 != __last1; ++__last2) {
+ value_type* __j2 = __last2;
+ value_type* __i2 = __j2;
+ if (__comp(*__first1, *--__i2)) {
+ ::new ((void*)__j2) value_type(_VSTD::move(*__i2));
+ __d.template __incr<value_type>();
+ for (--__j2; __i2 != __first2 && __comp(*__first1, *--__i2); --__j2)
+ *__j2 = _VSTD::move(*__i2);
+ *__j2 = _VSTD::move(*__first1);
+ } else {
+ ::new ((void*)__j2) value_type(_VSTD::move(*__first1));
+ __d.template __incr<value_type>();
+ }
+ }
+ __h.release();
+ }
+}
+
+template <class _Compare, class _RandomAccessIterator>
+void __introsort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp,
+ typename iterator_traits<_RandomAccessIterator>::difference_type __depth) {
+ typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
+ typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
+ const difference_type __limit =
+ is_trivially_copy_constructible<value_type>::value && is_trivially_copy_assignable<value_type>::value ? 30 : 6;
+ while (true) {
+ __restart:
+ difference_type __len = __last - __first;
+ switch (__len) {
case 0:
case 1:
- return true;
+ return;
case 2:
- if (__comp(*--__last, *__first))
- swap(*__first, *__last);
- return true;
+ if (__comp(*--__last, *__first))
+ swap(*__first, *__last);
+ return;
case 3:
- _VSTD::__sort3<_Compare>(__first, __first+difference_type(1), --__last, __comp);
- return true;
+ _VSTD::__sort3_maybe_branchless<_Compare>(__first, __first + difference_type(1), --__last, __comp);
+ return;
case 4:
- _VSTD::__sort4<_Compare>(__first, __first+difference_type(1), __first+difference_type(2), --__last, __comp);
- return true;
+ _VSTD::__sort4_maybe_branchless<_Compare>(__first, __first + difference_type(1), __first + difference_type(2),
+ --__last, __comp);
+ return;
case 5:
- _VSTD::__sort5<_Compare>(__first, __first+difference_type(1), __first+difference_type(2), __first+difference_type(3), --__last, __comp);
- return true;
+ _VSTD::__sort5_maybe_branchless<_Compare>(__first, __first + difference_type(1), __first + difference_type(2),
+ __first + difference_type(3), --__last, __comp);
+ return;
}
- typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
- _RandomAccessIterator __j = __first+difference_type(2);
- _VSTD::__sort3<_Compare>(__first, __first+difference_type(1), __j, __comp);
- const unsigned __limit = 8;
- unsigned __count = 0;
- for (_RandomAccessIterator __i = __j+difference_type(1); __i != __last; ++__i)
- {
- if (__comp(*__i, *__j))
- {
- value_type __t(_VSTD::move(*__i));
- _RandomAccessIterator __k = __j;
- __j = __i;
- do
- {
- *__j = _VSTD::move(*__k);
- __j = __k;
- } while (__j != __first && __comp(__t, *--__k));
- *__j = _VSTD::move(__t);
- if (++__count == __limit)
- return ++__i == __last;
- }
- __j = __i;
+ if (__len <= __limit) {
+ _VSTD::__insertion_sort_3<_Compare>(__first, __last, __comp);
+ return;
}
- return true;
-}
-
-template <class _Compare, class _BidirectionalIterator>
-void
-__insertion_sort_move(_BidirectionalIterator __first1, _BidirectionalIterator __last1,
- typename iterator_traits<_BidirectionalIterator>::value_type* __first2, _Compare __comp)
-{
- typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;
- if (__first1 != __last1)
+ // __len > 5
+ if (__depth == 0) {
+ // Fallback to heap sort as Introsort suggests.
+ _VSTD::__partial_sort<_Compare>(__first, __last, __last, __comp);
+ return;
+ }
+ --__depth;
+ _RandomAccessIterator __m = __first;
+ _RandomAccessIterator __lm1 = __last;
+ --__lm1;
+ unsigned __n_swaps;
{
- __destruct_n __d(0);
- unique_ptr<value_type, __destruct_n&> __h(__first2, __d);
- value_type* __last2 = __first2;
- ::new ((void*)__last2) value_type(_VSTD::move(*__first1));
- __d.template __incr<value_type>();
- for (++__last2; ++__first1 != __last1; ++__last2)
- {
- value_type* __j2 = __last2;
- value_type* __i2 = __j2;
- if (__comp(*__first1, *--__i2))
- {
- ::new ((void*)__j2) value_type(_VSTD::move(*__i2));
- __d.template __incr<value_type>();
- for (--__j2; __i2 != __first2 && __comp(*__first1, *--__i2); --__j2)
- *__j2 = _VSTD::move(*__i2);
- *__j2 = _VSTD::move(*__first1);
- }
- else
- {
- ::new ((void*)__j2) value_type(_VSTD::move(*__first1));
- __d.template __incr<value_type>();
- }
- }
- __h.release();
+ difference_type __delta;
+ if (__len >= 1000) {
+ __delta = __len / 2;
+ __m += __delta;
+ __delta /= 2;
+ __n_swaps = _VSTD::__sort5<_Compare>(__first, __first + __delta, __m, __m + __delta, __lm1, __comp);
+ } else {
+ __delta = __len / 2;
+ __m += __delta;
+ __n_swaps = _VSTD::__sort3<_Compare>(__first, __m, __lm1, __comp);
+ }
}
-}
-
-template <class _Compare, class _RandomAccessIterator>
-void
-__introsort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp,
- typename iterator_traits<_RandomAccessIterator>::difference_type __depth)
-{
- typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
- typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
- const difference_type __limit = is_trivially_copy_constructible<value_type>::value &&
- is_trivially_copy_assignable<value_type>::value ? 30 : 6;
- while (true)
+ // *__m is median
+ // partition [__first, __m) < *__m and *__m <= [__m, __last)
+ // (this inhibits tossing elements equivalent to __m around unnecessarily)
+ _RandomAccessIterator __i = __first;
+ _RandomAccessIterator __j = __lm1;
+ // j points beyond range to be tested, *__m is known to be <= *__lm1
+ // The search going up is known to be guarded but the search coming down isn't.
+ // Prime the downward search with a guard.
+ if (!__comp(*__i, *__m)) // if *__first == *__m
{
- __restart:
- difference_type __len = __last - __first;
- switch (__len)
- {
- case 0:
- case 1:
- return;
- case 2:
- if (__comp(*--__last, *__first))
- swap(*__first, *__last);
- return;
- case 3:
- _VSTD::__sort3<_Compare>(__first, __first+difference_type(1), --__last, __comp);
- return;
- case 4:
- _VSTD::__sort4<_Compare>(__first, __first+difference_type(1), __first+difference_type(2), --__last, __comp);
- return;
- case 5:
- _VSTD::__sort5<_Compare>(__first, __first+difference_type(1), __first+difference_type(2), __first+difference_type(3), --__last, __comp);
- return;
- }
- if (__len <= __limit)
- {
- _VSTD::__insertion_sort_3<_Compare>(__first, __last, __comp);
- return;
- }
- // __len > 5
- if (__depth == 0)
- {
- // Fallback to heap sort as Introsort suggests.
- _VSTD::__partial_sort<_Compare>(__first, __last, __last, __comp);
- return;
- }
- --__depth;
- _RandomAccessIterator __m = __first;
- _RandomAccessIterator __lm1 = __last;
- --__lm1;
- unsigned __n_swaps;
- {
- difference_type __delta;
- if (__len >= 1000)
- {
- __delta = __len/2;
- __m += __delta;
- __delta /= 2;
- __n_swaps = _VSTD::__sort5<_Compare>(__first, __first + __delta, __m, __m+__delta, __lm1, __comp);
- }
- else
- {
- __delta = __len/2;
- __m += __delta;
- __n_swaps = _VSTD::__sort3<_Compare>(__first, __m, __lm1, __comp);
- }
- }
- // *__m is median
- // partition [__first, __m) < *__m and *__m <= [__m, __last)
- // (this inhibits tossing elements equivalent to __m around unnecessarily)
- _RandomAccessIterator __i = __first;
- _RandomAccessIterator __j = __lm1;
- // j points beyond range to be tested, *__m is known to be <= *__lm1
- // The search going up is known to be guarded but the search coming down isn't.
- // Prime the downward search with a guard.
- if (!__comp(*__i, *__m)) // if *__first == *__m
- {
- // *__first == *__m, *__first doesn't go in first part
- // manually guard downward moving __j against __i
- while (true)
- {
- if (__i == --__j)
- {
- // *__first == *__m, *__m <= all other elements
- // Parition instead into [__first, __i) == *__first and *__first < [__i, __last)
- ++__i; // __first + 1
- __j = __last;
- if (!__comp(*__first, *--__j)) // we need a guard if *__first == *(__last-1)
- {
- while (true)
- {
- if (__i == __j)
- return; // [__first, __last) all equivalent elements
- if (__comp(*__first, *__i))
- {
- swap(*__i, *__j);
- ++__n_swaps;
- ++__i;
- break;
- }
- ++__i;
- }
- }
- // [__first, __i) == *__first and *__first < [__j, __last) and __j == __last - 1
- if (__i == __j)
- return;
- while (true)
- {
- while (!__comp(*__first, *__i))
- ++__i;
- while (__comp(*__first, *--__j))
- ;
- if (__i >= __j)
- break;
- swap(*__i, *__j);
- ++__n_swaps;
- ++__i;
- }
- // [__first, __i) == *__first and *__first < [__i, __last)
- // The first part is sorted, sort the second part
- // _VSTD::__sort<_Compare>(__i, __last, __comp);
- __first = __i;
- goto __restart;
- }
- if (__comp(*__j, *__m))
- {
- swap(*__i, *__j);
- ++__n_swaps;
- break; // found guard for downward moving __j, now use unguarded partition
- }
- }
- }
- // It is known that *__i < *__m
- ++__i;
- // j points beyond range to be tested, *__m is known to be <= *__lm1
- // if not yet partitioned...
- if (__i < __j)
- {
- // known that *(__i - 1) < *__m
- // known that __i <= __m
- while (true)
- {
- // __m still guards upward moving __i
- while (__comp(*__i, *__m))
- ++__i;
- // It is now known that a guard exists for downward moving __j
- while (!__comp(*--__j, *__m))
- ;
- if (__i > __j)
- break;
+ // *__first == *__m, *__first doesn't go in first part
+ // manually guard downward moving __j against __i
+ while (true) {
+ if (__i == --__j) {
+ // *__first == *__m, *__m <= all other elements
+ // Parition instead into [__first, __i) == *__first and *__first < [__i, __last)
+ ++__i; // __first + 1
+ __j = __last;
+ if (!__comp(*__first, *--__j)) // we need a guard if *__first == *(__last-1)
+ {
+ while (true) {
+ if (__i == __j)
+ return; // [__first, __last) all equivalent elements
+ if (__comp(*__first, *__i)) {
swap(*__i, *__j);
++__n_swaps;
- // It is known that __m != __j
- // If __m just moved, follow it
- if (__m == __i)
- __m = __j;
++__i;
+ break;
+ }
+ ++__i;
}
- }
- // [__first, __i) < *__m and *__m <= [__i, __last)
- if (__i != __m && __comp(*__m, *__i))
- {
- swap(*__i, *__m);
+ }
+ // [__first, __i) == *__first and *__first < [__j, __last) and __j == __last - 1
+ if (__i == __j)
+ return;
+ while (true) {
+ while (!__comp(*__first, *__i))
+ ++__i;
+ while (__comp(*__first, *--__j))
+ ;
+ if (__i >= __j)
+ break;
+ swap(*__i, *__j);
++__n_swaps;
+ ++__i;
+ }
+ // [__first, __i) == *__first and *__first < [__i, __last)
+ // The first part is sorted, sort the second part
+ // _VSTD::__sort<_Compare>(__i, __last, __comp);
+ __first = __i;
+ goto __restart;
}
- // [__first, __i) < *__i and *__i <= [__i+1, __last)
- // If we were given a perfect partition, see if insertion sort is quick...
- if (__n_swaps == 0)
- {
- bool __fs = _VSTD::__insertion_sort_incomplete<_Compare>(__first, __i, __comp);
- if (_VSTD::__insertion_sort_incomplete<_Compare>(__i+difference_type(1), __last, __comp))
- {
- if (__fs)
- return;
- __last = __i;
- continue;
- }
- else
- {
- if (__fs)
- {
- __first = ++__i;
- continue;
- }
- }
+ if (__comp(*__j, *__m)) {
+ swap(*__i, *__j);
+ ++__n_swaps;
+ break; // found guard for downward moving __j, now use unguarded partition
}
- // sort smaller range with recursive call and larger with tail recursion elimination
- if (__i - __first < __last - __i)
- {
- _VSTD::__introsort<_Compare>(__first, __i, __comp, __depth);
+ }
+ }
+ // It is known that *__i < *__m
+ ++__i;
+ // j points beyond range to be tested, *__m is known to be <= *__lm1
+ // if not yet partitioned...
+ if (__i < __j) {
+ // known that *(__i - 1) < *__m
+ // known that __i <= __m
+ while (true) {
+ // __m still guards upward moving __i
+ while (__comp(*__i, *__m))
+ ++__i;
+ // It is now known that a guard exists for downward moving __j
+ while (!__comp(*--__j, *__m))
+ ;
+ if (__i > __j)
+ break;
+ swap(*__i, *__j);
+ ++__n_swaps;
+ // It is known that __m != __j
+ // If __m just moved, follow it
+ if (__m == __i)
+ __m = __j;
+ ++__i;
+ }
+ }
+ // [__first, __i) < *__m and *__m <= [__i, __last)
+ if (__i != __m && __comp(*__m, *__i)) {
+ swap(*__i, *__m);
+ ++__n_swaps;
+ }
+ // [__first, __i) < *__i and *__i <= [__i+1, __last)
+ // If we were given a perfect partition, see if insertion sort is quick...
+ if (__n_swaps == 0) {
+ bool __fs = _VSTD::__insertion_sort_incomplete<_Compare>(__first, __i, __comp);
+ if (_VSTD::__insertion_sort_incomplete<_Compare>(__i + difference_type(1), __last, __comp)) {
+ if (__fs)
+ return;
+ __last = __i;
+ continue;
+ } else {
+ if (__fs) {
__first = ++__i;
+ continue;
}
- else
- {
- _VSTD::__introsort<_Compare>(__i + difference_type(1), __last, __comp, __depth);
- __last = __i;
- }
+ }
+ }
+ // sort smaller range with recursive call and larger with tail recursion elimination
+ if (__i - __first < __last - __i) {
+ _VSTD::__introsort<_Compare>(__first, __i, __comp, __depth);
+ __first = ++__i;
+ } else {
+ _VSTD::__introsort<_Compare>(__i + difference_type(1), __last, __comp, __depth);
+ __last = __i;
}
+ }
}
template <typename _Number>
inline _LIBCPP_HIDE_FROM_ABI _Number __log2i(_Number __n) {
+ if (__n == 0)
+ return 0;
+ if (sizeof(__n) <= sizeof(unsigned))
+ return sizeof(unsigned) * CHAR_BIT - 1 - __libcpp_clz(static_cast<unsigned>(__n));
+ if (sizeof(__n) <= sizeof(unsigned long))
+ return sizeof(unsigned long) * CHAR_BIT - 1 - __libcpp_clz(static_cast<unsigned long>(__n));
+ if (sizeof(__n) <= sizeof(unsigned long long))
+ return sizeof(unsigned long long) * CHAR_BIT - 1 - __libcpp_clz(static_cast<unsigned long long>(__n));
+
_Number __log2 = 0;
while (__n > 1) {
__log2++;
@@ -483,72 +536,71 @@ void __sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compar
}
template <class _Compare, class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
-void
-__sort(_Tp** __first, _Tp** __last, __less<_Tp*>&)
-{
- __less<uintptr_t> __comp;
- _VSTD::__sort<__less<uintptr_t>&, uintptr_t*>((uintptr_t*)__first, (uintptr_t*)__last, __comp);
+inline _LIBCPP_INLINE_VISIBILITY void __sort(_Tp** __first, _Tp** __last, __less<_Tp*>&) {
+ __less<uintptr_t> __comp;
+ _VSTD::__sort<__less<uintptr_t>&, uintptr_t*>((uintptr_t*)__first, (uintptr_t*)__last, __comp);
}
-_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<char>&, char*>(char*, char*, __less<char>&))
+extern template _LIBCPP_FUNC_VIS void __sort<__less<char>&, char*>(char*, char*, __less<char>&);
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<wchar_t>&, wchar_t*>(wchar_t*, wchar_t*, __less<wchar_t>&))
+extern template _LIBCPP_FUNC_VIS void __sort<__less<wchar_t>&, wchar_t*>(wchar_t*, wchar_t*, __less<wchar_t>&);
#endif
-_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<signed char>&, signed char*>(signed char*, signed char*, __less<signed char>&))
-_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<unsigned char>&, unsigned char*>(unsigned char*, unsigned char*, __less<unsigned char>&))
-_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<short>&, short*>(short*, short*, __less<short>&))
-_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<unsigned short>&, unsigned short*>(unsigned short*, unsigned short*, __less<unsigned short>&))
-_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<int>&, int*>(int*, int*, __less<int>&))
-_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<unsigned>&, unsigned*>(unsigned*, unsigned*, __less<unsigned>&))
-_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<long>&, long*>(long*, long*, __less<long>&))
-_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<unsigned long>&, unsigned long*>(unsigned long*, unsigned long*, __less<unsigned long>&))
-_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<long long>&, long long*>(long long*, long long*, __less<long long>&))
-_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<unsigned long long>&, unsigned long long*>(unsigned long long*, unsigned long long*, __less<unsigned long long>&))
-_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<float>&, float*>(float*, float*, __less<float>&))
-_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<double>&, double*>(double*, double*, __less<double>&))
-_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<long double>&, long double*>(long double*, long double*, __less<long double>&))
-
-_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<char>&, char*>(char*, char*, __less<char>&))
+extern template _LIBCPP_FUNC_VIS void __sort<__less<signed char>&, signed char*>(signed char*, signed char*, __less<signed char>&);
+extern template _LIBCPP_FUNC_VIS void __sort<__less<unsigned char>&, unsigned char*>(unsigned char*, unsigned char*, __less<unsigned char>&);
+extern template _LIBCPP_FUNC_VIS void __sort<__less<short>&, short*>(short*, short*, __less<short>&);
+extern template _LIBCPP_FUNC_VIS void __sort<__less<unsigned short>&, unsigned short*>(unsigned short*, unsigned short*, __less<unsigned short>&);
+extern template _LIBCPP_FUNC_VIS void __sort<__less<int>&, int*>(int*, int*, __less<int>&);
+extern template _LIBCPP_FUNC_VIS void __sort<__less<unsigned>&, unsigned*>(unsigned*, unsigned*, __less<unsigned>&);
+extern template _LIBCPP_FUNC_VIS void __sort<__less<long>&, long*>(long*, long*, __less<long>&);
+extern template _LIBCPP_FUNC_VIS void __sort<__less<unsigned long>&, unsigned long*>(unsigned long*, unsigned long*, __less<unsigned long>&);
+extern template _LIBCPP_FUNC_VIS void __sort<__less<long long>&, long long*>(long long*, long long*, __less<long long>&);
+extern template _LIBCPP_FUNC_VIS void __sort<__less<unsigned long long>&, unsigned long long*>(unsigned long long*, unsigned long long*, __less<unsigned long long>&);
+extern template _LIBCPP_FUNC_VIS void __sort<__less<float>&, float*>(float*, float*, __less<float>&);
+extern template _LIBCPP_FUNC_VIS void __sort<__less<double>&, double*>(double*, double*, __less<double>&);
+extern template _LIBCPP_FUNC_VIS void __sort<__less<long double>&, long double*>(long double*, long double*, __less<long double>&);
+
+extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<char>&, char*>(char*, char*, __less<char>&);
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<wchar_t>&, wchar_t*>(wchar_t*, wchar_t*, __less<wchar_t>&))
+extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<wchar_t>&, wchar_t*>(wchar_t*, wchar_t*, __less<wchar_t>&);
#endif
-_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<signed char>&, signed char*>(signed char*, signed char*, __less<signed char>&))
-_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned char>&, unsigned char*>(unsigned char*, unsigned char*, __less<unsigned char>&))
-_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<short>&, short*>(short*, short*, __less<short>&))
-_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned short>&, unsigned short*>(unsigned short*, unsigned short*, __less<unsigned short>&))
-_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<int>&, int*>(int*, int*, __less<int>&))
-_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned>&, unsigned*>(unsigned*, unsigned*, __less<unsigned>&))
-_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<long>&, long*>(long*, long*, __less<long>&))
-_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned long>&, unsigned long*>(unsigned long*, unsigned long*, __less<unsigned long>&))
-_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<long long>&, long long*>(long long*, long long*, __less<long long>&))
-_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned long long>&, unsigned long long*>(unsigned long long*, unsigned long long*, __less<unsigned long long>&))
-_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<float>&, float*>(float*, float*, __less<float>&))
-_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<double>&, double*>(double*, double*, __less<double>&))
-_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<long double>&, long double*>(long double*, long double*, __less<long double>&))
-
-_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS unsigned __sort5<__less<long double>&, long double*>(long double*, long double*, long double*, long double*, long double*, __less<long double>&))
-
-template <class _RandomAccessIterator, class _Compare>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
-void
-sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
-{
+extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<signed char>&, signed char*>(signed char*, signed char*, __less<signed char>&);
+extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned char>&, unsigned char*>(unsigned char*, unsigned char*, __less<unsigned char>&);
+extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<short>&, short*>(short*, short*, __less<short>&);
+extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned short>&, unsigned short*>(unsigned short*, unsigned short*, __less<unsigned short>&);
+extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<int>&, int*>(int*, int*, __less<int>&);
+extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned>&, unsigned*>(unsigned*, unsigned*, __less<unsigned>&);
+extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<long>&, long*>(long*, long*, __less<long>&);
+extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned long>&, unsigned long*>(unsigned long*, unsigned long*, __less<unsigned long>&);
+extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<long long>&, long long*>(long long*, long long*, __less<long long>&);
+extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned long long>&, unsigned long long*>(unsigned long long*, unsigned long long*, __less<unsigned long long>&);
+extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<float>&, float*>(float*, float*, __less<float>&);
+extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<double>&, double*>(double*, double*, __less<double>&);
+extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<long double>&, long double*>(long double*, long double*, __less<long double>&);
+
+extern template _LIBCPP_FUNC_VIS unsigned __sort5<__less<long double>&, long double*>(long double*, long double*, long double*, long double*, long double*, __less<long double>&);
+
+template <class _RandomAccessIterator, class _Comp>
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
+void __sort_impl(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp& __comp) {
_LIBCPP_DEBUG_RANDOMIZE_RANGE(__first, __last);
- typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
+ using _Comp_ref = typename __comp_ref_type<_Comp>::type;
if (__libcpp_is_constant_evaluated()) {
- _VSTD::__partial_sort<_Comp_ref>(__first, __last, __last, _Comp_ref(__comp));
+ std::__partial_sort<_Comp_ref>(__first, __last, __last, _Comp_ref(__comp));
} else {
- _VSTD::__sort<_Comp_ref>(_VSTD::__unwrap_iter(__first), _VSTD::__unwrap_iter(__last), _Comp_ref(__comp));
+ std::__sort<_Comp_ref>(std::__unwrap_iter(__first), std::__unwrap_iter(__last), _Comp_ref(__comp));
}
}
+template <class _RandomAccessIterator, class _Comp>
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
+void sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp) {
+ std::__sort_impl(std::move(__first), std::move(__last), __comp);
+}
+
template <class _RandomAccessIterator>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
-void
-sort(_RandomAccessIterator __first, _RandomAccessIterator __last)
-{
- _VSTD::sort(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
+void sort(_RandomAccessIterator __first, _RandomAccessIterator __last) {
+ std::sort(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/sort_heap.h b/libcxx/include/__algorithm/sort_heap.h
index 64291ff2e8c9..3a63d744fc1c 100644
--- a/libcxx/include/__algorithm/sort_heap.h
+++ b/libcxx/include/__algorithm/sort_heap.h
@@ -17,7 +17,7 @@
#include <type_traits> // swap
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/stable_partition.h b/libcxx/include/__algorithm/stable_partition.h
index 331f0fde77dc..969ac7a6173e 100644
--- a/libcxx/include/__algorithm/stable_partition.h
+++ b/libcxx/include/__algorithm/stable_partition.h
@@ -11,12 +11,14 @@
#include <__algorithm/rotate.h>
#include <__config>
+#include <__iterator/advance.h>
+#include <__iterator/distance.h>
#include <__iterator/iterator_traits.h>
#include <__utility/swap.h>
#include <memory>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -130,7 +132,10 @@ __stable_partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate
unique_ptr<value_type, __return_temporary_buffer> __h;
if (__len >= __alloc_limit)
{
+// TODO: Remove the use of std::get_temporary_buffer
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
__p = _VSTD::get_temporary_buffer<value_type>(__len);
+_LIBCPP_SUPPRESS_DEPRECATED_POP
__h.reset(__p.first);
}
return _VSTD::__stable_partition<_Predicate&>(__first, __last, __pred, __len, __p, forward_iterator_tag());
@@ -276,7 +281,10 @@ __stable_partition(_BidirectionalIterator __first, _BidirectionalIterator __last
unique_ptr<value_type, __return_temporary_buffer> __h;
if (__len >= __alloc_limit)
{
+// TODO: Remove the use of std::get_temporary_buffer
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
__p = _VSTD::get_temporary_buffer<value_type>(__len);
+_LIBCPP_SUPPRESS_DEPRECATED_POP
__h.reset(__p.first);
}
return _VSTD::__stable_partition<_Predicate&>(__first, __last, __pred, __len, __p, bidirectional_iterator_tag());
diff --git a/libcxx/include/__algorithm/stable_sort.h b/libcxx/include/__algorithm/stable_sort.h
index 4ae17e0e4d94..e3479aad62e6 100644
--- a/libcxx/include/__algorithm/stable_sort.h
+++ b/libcxx/include/__algorithm/stable_sort.h
@@ -15,12 +15,13 @@
#include <__algorithm/sort.h>
#include <__config>
#include <__iterator/iterator_traits.h>
+#include <__utility/move.h>
#include <__utility/swap.h>
#include <memory>
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -199,30 +200,36 @@ __stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp
}
template <class _RandomAccessIterator, class _Compare>
-inline _LIBCPP_INLINE_VISIBILITY
-void
-stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
-{
- typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
- typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
- difference_type __len = __last - __first;
- pair<value_type*, ptrdiff_t> __buf(0, 0);
- unique_ptr<value_type, __return_temporary_buffer> __h;
- if (__len > static_cast<difference_type>(__stable_sort_switch<value_type>::value))
- {
- __buf = _VSTD::get_temporary_buffer<value_type>(__len);
- __h.reset(__buf.first);
- }
- typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
- _VSTD::__stable_sort<_Comp_ref>(__first, __last, __comp, __len, __buf.first, __buf.second);
+inline _LIBCPP_HIDE_FROM_ABI
+void __stable_sort_impl(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare& __comp) {
+ using value_type = typename iterator_traits<_RandomAccessIterator>::value_type;
+ using difference_type = typename iterator_traits<_RandomAccessIterator>::difference_type;
+
+ difference_type __len = __last - __first;
+ pair<value_type*, ptrdiff_t> __buf(0, 0);
+ unique_ptr<value_type, __return_temporary_buffer> __h;
+ if (__len > static_cast<difference_type>(__stable_sort_switch<value_type>::value)) {
+// TODO: Remove the use of std::get_temporary_buffer
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
+ __buf = std::get_temporary_buffer<value_type>(__len);
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+ __h.reset(__buf.first);
+ }
+
+ using _Comp_ref = typename __comp_ref_type<_Compare>::type;
+ std::__stable_sort<_Comp_ref>(__first, __last, __comp, __len, __buf.first, __buf.second);
+}
+
+template <class _RandomAccessIterator, class _Compare>
+inline _LIBCPP_HIDE_FROM_ABI
+void stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) {
+ std::__stable_sort_impl(std::move(__first), std::move(__last), __comp);
}
template <class _RandomAccessIterator>
-inline _LIBCPP_INLINE_VISIBILITY
-void
-stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last)
-{
- _VSTD::stable_sort(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
+inline _LIBCPP_HIDE_FROM_ABI
+void stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last) {
+ std::stable_sort(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/swap_ranges.h b/libcxx/include/__algorithm/swap_ranges.h
index 2b099c7361f1..0422265bb4be 100644
--- a/libcxx/include/__algorithm/swap_ranges.h
+++ b/libcxx/include/__algorithm/swap_ranges.h
@@ -11,10 +11,9 @@
#include <__config>
#include <__utility/swap.h>
-#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/transform.h b/libcxx/include/__algorithm/transform.h
index 494cb7128d29..f9db806f5b94 100644
--- a/libcxx/include/__algorithm/transform.h
+++ b/libcxx/include/__algorithm/transform.h
@@ -12,7 +12,7 @@
#include <__config>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/unique.h b/libcxx/include/__algorithm/unique.h
index e17ff1567fa9..264d727d93c8 100644
--- a/libcxx/include/__algorithm/unique.h
+++ b/libcxx/include/__algorithm/unique.h
@@ -16,7 +16,7 @@
#include <__utility/move.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/unique_copy.h b/libcxx/include/__algorithm/unique_copy.h
index 4833ae9b59f5..f58517749f51 100644
--- a/libcxx/include/__algorithm/unique_copy.h
+++ b/libcxx/include/__algorithm/unique_copy.h
@@ -12,10 +12,9 @@
#include <__algorithm/comp.h>
#include <__config>
#include <__iterator/iterator_traits.h>
-#include <utility>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/unwrap_iter.h b/libcxx/include/__algorithm/unwrap_iter.h
index 35765330bb7f..7d1807b7bbf9 100644
--- a/libcxx/include/__algorithm/unwrap_iter.h
+++ b/libcxx/include/__algorithm/unwrap_iter.h
@@ -10,12 +10,12 @@
#define _LIBCPP___ALGORITHM_UNWRAP_ITER_H
#include <__config>
+#include <__iterator/iterator_traits.h>
#include <__memory/pointer_traits.h>
-#include <iterator>
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -43,7 +43,7 @@ struct __unwrap_iter_impl {
}
};
-#if _LIBCPP_DEBUG_LEVEL < 2
+#ifndef _LIBCPP_ENABLE_DEBUG_MODE
template <class _Iter>
struct __unwrap_iter_impl<_Iter, true> {
@@ -53,7 +53,7 @@ struct __unwrap_iter_impl<_Iter, true> {
}
};
-#endif // _LIBCPP_DEBUG_LEVEL < 2
+#endif // !_LIBCPP_ENABLE_DEBUG_MODE
template<class _Iter, class _Impl = __unwrap_iter_impl<_Iter> >
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
@@ -63,20 +63,34 @@ __unwrap_iter(_Iter __i) _NOEXCEPT
return _Impl::__apply(__i);
}
+template <class _OrigIter, class _UnwrappedIter>
+struct __rewrap_iter_impl {
+ static _LIBCPP_CONSTEXPR _OrigIter __apply(_OrigIter __first, _UnwrappedIter __result) {
+ // Precondition: __result is reachable from __first
+ // Precondition: _OrigIter is a contiguous iterator
+ return __first + (__result - std::__unwrap_iter(__first));
+ }
+};
+
+template <class _OrigIter>
+struct __rewrap_iter_impl<_OrigIter, _OrigIter> {
+ static _LIBCPP_CONSTEXPR _OrigIter __apply(_OrigIter, _OrigIter __result) {
+ return __result;
+ }
+};
+
template<class _OrigIter>
-_LIBCPP_HIDE_FROM_ABI
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
_OrigIter __rewrap_iter(_OrigIter, _OrigIter __result)
{
return __result;
}
-template<class _OrigIter, class _UnwrappedIter>
-_LIBCPP_HIDE_FROM_ABI
+template<class _OrigIter, class _UnwrappedIter, class _Impl = __rewrap_iter_impl<_OrigIter, _UnwrappedIter> >
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
_OrigIter __rewrap_iter(_OrigIter __first, _UnwrappedIter __result)
{
- // Precondition: __result is reachable from __first
- // Precondition: _OrigIter is a contiguous iterator
- return __first + (__result - _VSTD::__unwrap_iter(__first));
+ return _Impl::__apply(__first, __result);
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/upper_bound.h b/libcxx/include/__algorithm/upper_bound.h
index c064f1e35b9a..c6483607e3c6 100644
--- a/libcxx/include/__algorithm/upper_bound.h
+++ b/libcxx/include/__algorithm/upper_bound.h
@@ -12,10 +12,12 @@
#include <__algorithm/comp.h>
#include <__algorithm/half_positive.h>
#include <__config>
-#include <iterator>
+#include <__iterator/advance.h>
+#include <__iterator/distance.h>
+#include <__iterator/iterator_traits.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__assert b/libcxx/include/__assert
new file mode 100644
index 000000000000..84ddcd25b0b5
--- /dev/null
+++ b/libcxx/include/__assert
@@ -0,0 +1,66 @@
+// -*- 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___ASSERT
+#define _LIBCPP___ASSERT
+
+#include <__availability>
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+// This is for backwards compatibility with code that might have been enabling
+// assertions through the Debug mode previously.
+// TODO: In LLVM 16, make it an error to define _LIBCPP_DEBUG
+#if defined(_LIBCPP_DEBUG)
+# ifndef _LIBCPP_ENABLE_ASSERTIONS
+# define _LIBCPP_ENABLE_ASSERTIONS 1
+# endif
+#endif
+
+// Automatically enable assertions when the debug mode is enabled.
+#if defined(_LIBCPP_ENABLE_DEBUG_MODE)
+# ifndef _LIBCPP_ENABLE_ASSERTIONS
+# define _LIBCPP_ENABLE_ASSERTIONS 1
+# endif
+#endif
+
+#ifndef _LIBCPP_ENABLE_ASSERTIONS
+# define _LIBCPP_ENABLE_ASSERTIONS _LIBCPP_ENABLE_ASSERTIONS_DEFAULT
+#endif
+
+#if _LIBCPP_ENABLE_ASSERTIONS != 0 && _LIBCPP_ENABLE_ASSERTIONS != 1
+# error "_LIBCPP_ENABLE_ASSERTIONS must be set to 0 or 1"
+#endif
+
+#if _LIBCPP_ENABLE_ASSERTIONS
+# define _LIBCPP_ASSERT(expression, message) \
+ (__builtin_expect(static_cast<bool>(expression), 1) ? \
+ (void)0 : \
+ ::std::__libcpp_assertion_handler(__FILE__, __LINE__, #expression, message))
+#elif !defined(_LIBCPP_ASSERTIONS_DISABLE_ASSUME) && __has_builtin(__builtin_assume)
+# define _LIBCPP_ASSERT(expression, message) \
+ (_LIBCPP_DIAGNOSTIC_PUSH \
+ _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wassume") \
+ __builtin_assume(static_cast<bool>(expression)) \
+ _LIBCPP_DIAGNOSTIC_POP)
+#else
+# define _LIBCPP_ASSERT(expression, message) ((void)0)
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+_LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_AVAILABILITY_ASSERTION_HANDLER
+void __libcpp_assertion_handler(char const* __file, int __line, char const* __expression, char const* __message);
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___ASSERT
diff --git a/libcxx/include/__availability b/libcxx/include/__availability
index 4652a6fd91b4..f9d824509f3d 100644
--- a/libcxx/include/__availability
+++ b/libcxx/include/__availability
@@ -13,7 +13,7 @@
#include <__config>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-# pragma GCC system_header
+# pragma GCC system_header
#endif
// Libc++ is shipped by various vendors. In particular, it is used as a system
@@ -91,6 +91,10 @@
// other exception types. These were put in the shared library to prevent
// code bloat from every user program defining the vtable for these exception
// types.
+ //
+ // Note that when exceptions are disabled, the methods that normally throw
+ // these exceptions can be used even on older deployment targets, but those
+ // methods will abort instead of throwing.
# define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS
# define _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS
# define _LIBCPP_AVAILABILITY_BAD_ANY_CAST
@@ -99,10 +103,15 @@
# define _LIBCPP_AVAILABILITY_UNCAUGHT_EXCEPTIONS
// This controls the availability of the sized version of ::operator delete,
- // which was added to the dylib later.
+ // ::operator delete[], and their align_val_t variants, which were all added
+ // in C++17, and hence not present in early dylibs.
# define _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE
// This controls the availability of the std::future_error exception.
+ //
+ // Note that when exceptions are disabled, the methods that normally throw
+ // std::future_error can be used even on older deployment targets, but those
+ // methods will abort instead of throwing.
# define _LIBCPP_AVAILABILITY_FUTURE_ERROR
// This controls the availability of std::type_info's vtable.
@@ -126,16 +135,14 @@
# define _LIBCPP_AVAILABILITY_FILESYSTEM_POP
// # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_filesystem
- // This controls the availability of std::to_chars.
-# define _LIBCPP_AVAILABILITY_TO_CHARS
-
// This controls the availability of floating-point std::to_chars functions.
// These overloads were added later than the integer overloads.
# define _LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT
// This controls the availability of the C++20 synchronization library,
// which requires shared library support for various operations
- // (see libcxx/src/atomic.cpp).
+ // (see libcxx/src/atomic.cpp). This includes <barier>, <latch>,
+ // <semaphore>, and notification functions on std::atomic.
# define _LIBCPP_AVAILABILITY_SYNC
// # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_atomic_wait
// # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_barrier
@@ -149,10 +156,27 @@
# define _LIBCPP_AVAILABILITY_FORMAT
// # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_format
+ // This controls whether the std::__libcpp_assertion_handler default
+ // assertion handler is provided by the library.
+ //
+ // Note that when users provide their own custom assertion handler,
+ // it doesn't matter whether the dylib provides a default handler,
+ // and the availability markup can actually give a false positive
+ // diagnostic (it will think that no handler is provided, when in
+ // reality the user has provided their own).
+ //
+ // Users can pass -D_LIBCPP_AVAILABILITY_CUSTOM_ASSERTION_HANDLER_PROVIDED
+ // to the compiler to tell the library to ignore the fact that the
+ // default handler isn't available on their deployment target. Note that
+ // defining this macro but failing to define a custom assertion handler
+ // will lead to a load-time error on back-deployment targets, so it
+ // should be avoided.
+# define _LIBCPP_AVAILABILITY_DEFAULT_ASSERTION_HANDLER
+
#elif defined(__APPLE__)
# define _LIBCPP_AVAILABILITY_SHARED_MUTEX \
- __attribute__((availability(macosx,strict,introduced=10.12))) \
+ __attribute__((availability(macos,strict,introduced=10.12))) \
__attribute__((availability(ios,strict,introduced=10.0))) \
__attribute__((availability(tvos,strict,introduced=10.0))) \
__attribute__((availability(watchos,strict,introduced=3.0)))
@@ -164,24 +188,27 @@
# define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_timed_mutex
# endif
+ // Note: bad_optional_access & friends were not introduced in the matching
+ // macOS and iOS versions, so the version mismatch between macOS and others
+ // is intended.
# define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS \
- __attribute__((availability(macosx,strict,introduced=10.13))) \
- __attribute__((availability(ios,strict,introduced=11.0))) \
- __attribute__((availability(tvos,strict,introduced=11.0))) \
- __attribute__((availability(watchos,strict,introduced=4.0)))
+ __attribute__((availability(macos,strict,introduced=10.13))) \
+ __attribute__((availability(ios,strict,introduced=12.0))) \
+ __attribute__((availability(tvos,strict,introduced=12.0))) \
+ __attribute__((availability(watchos,strict,introduced=5.0)))
# define _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS \
_LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS
# define _LIBCPP_AVAILABILITY_BAD_ANY_CAST \
_LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS
# define _LIBCPP_AVAILABILITY_UNCAUGHT_EXCEPTIONS \
- __attribute__((availability(macosx,strict,introduced=10.12))) \
+ __attribute__((availability(macos,strict,introduced=10.12))) \
__attribute__((availability(ios,strict,introduced=10.0))) \
__attribute__((availability(tvos,strict,introduced=10.0))) \
__attribute__((availability(watchos,strict,introduced=3.0)))
# define _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE \
- __attribute__((availability(macosx,strict,introduced=10.12))) \
+ __attribute__((availability(macos,strict,introduced=10.12))) \
__attribute__((availability(ios,strict,introduced=10.0))) \
__attribute__((availability(tvos,strict,introduced=10.0))) \
__attribute__((availability(watchos,strict,introduced=3.0)))
@@ -190,26 +217,26 @@
__attribute__((availability(ios,strict,introduced=6.0)))
# define _LIBCPP_AVAILABILITY_TYPEINFO_VTABLE \
- __attribute__((availability(macosx,strict,introduced=10.9))) \
+ __attribute__((availability(macos,strict,introduced=10.9))) \
__attribute__((availability(ios,strict,introduced=7.0)))
# define _LIBCPP_AVAILABILITY_LOCALE_CATEGORY \
- __attribute__((availability(macosx,strict,introduced=10.9))) \
+ __attribute__((availability(macos,strict,introduced=10.9))) \
__attribute__((availability(ios,strict,introduced=7.0)))
# define _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR \
- __attribute__((availability(macosx,strict,introduced=10.9))) \
+ __attribute__((availability(macos,strict,introduced=10.9))) \
__attribute__((availability(ios,strict,introduced=7.0)))
# define _LIBCPP_AVAILABILITY_FILESYSTEM \
- __attribute__((availability(macosx,strict,introduced=10.15))) \
+ __attribute__((availability(macos,strict,introduced=10.15))) \
__attribute__((availability(ios,strict,introduced=13.0))) \
__attribute__((availability(tvos,strict,introduced=13.0))) \
__attribute__((availability(watchos,strict,introduced=6.0)))
# define _LIBCPP_AVAILABILITY_FILESYSTEM_PUSH \
- _Pragma("clang attribute push(__attribute__((availability(macosx,strict,introduced=10.15))), apply_to=any(function,record))") \
- _Pragma("clang attribute push(__attribute__((availability(ios,strict,introduced=13.0))), apply_to=any(function,record))") \
- _Pragma("clang attribute push(__attribute__((availability(tvos,strict,introduced=13.0))), apply_to=any(function,record))") \
+ _Pragma("clang attribute push(__attribute__((availability(macos,strict,introduced=10.15))), apply_to=any(function,record))") \
+ _Pragma("clang attribute push(__attribute__((availability(ios,strict,introduced=13.0))), apply_to=any(function,record))") \
+ _Pragma("clang attribute push(__attribute__((availability(tvos,strict,introduced=13.0))), apply_to=any(function,record))") \
_Pragma("clang attribute push(__attribute__((availability(watchos,strict,introduced=6.0))), apply_to=any(function,record))")
# define _LIBCPP_AVAILABILITY_FILESYSTEM_POP \
_Pragma("clang attribute pop") \
@@ -223,14 +250,11 @@
# define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_filesystem
# endif
-# define _LIBCPP_AVAILABILITY_TO_CHARS \
- _LIBCPP_AVAILABILITY_FILESYSTEM
-
# define _LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT \
__attribute__((unavailable))
# define _LIBCPP_AVAILABILITY_SYNC \
- __attribute__((availability(macosx,strict,introduced=11.0))) \
+ __attribute__((availability(macos,strict,introduced=11.0))) \
__attribute__((availability(ios,strict,introduced=14.0))) \
__attribute__((availability(tvos,strict,introduced=14.0))) \
__attribute__((availability(watchos,strict,introduced=7.0)))
@@ -244,13 +268,12 @@
# define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_semaphore
# endif
- // This controls the availability of the C++20 format library.
- // The library is in development and not ABI stable yet. P2216 is
- // retroactively accepted in C++20. This paper contains ABI breaking
- // changes.
# define _LIBCPP_AVAILABILITY_FORMAT \
__attribute__((unavailable))
# define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_format
+
+# define _LIBCPP_AVAILABILITY_DEFAULT_ASSERTION_HANDLER \
+ __attribute__((unavailable))
#else
// ...New vendors can add availability markup here...
@@ -274,4 +297,14 @@
# define _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS
#endif
+// Define the special assertion handler availability attribute, which can be silenced by
+// users if they provide their own custom assertion handler. The rest of the code should
+// not use the *_DEFAULT_* macro directly, since that would make it ignore the fact that
+// the user provided a custom handler.
+#if defined(_LIBCPP_AVAILABILITY_CUSTOM_ASSERTION_HANDLER_PROVIDED)
+# define _LIBCPP_AVAILABILITY_ASSERTION_HANDLER /* nothing */
+#else
+# define _LIBCPP_AVAILABILITY_ASSERTION_HANDLER _LIBCPP_AVAILABILITY_DEFAULT_ASSERTION_HANDLER
+#endif
+
#endif // _LIBCPP___AVAILABILITY
diff --git a/libcxx/include/__bit/bit_cast.h b/libcxx/include/__bit/bit_cast.h
index 6cfe4d799490..831207671ec9 100644
--- a/libcxx/include/__bit/bit_cast.h
+++ b/libcxx/include/__bit/bit_cast.h
@@ -14,21 +14,19 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER > 17
-template<class _ToType, class _FromType, class = enable_if_t<
- sizeof(_ToType) == sizeof(_FromType) &&
- is_trivially_copyable_v<_ToType> &&
- is_trivially_copyable_v<_FromType>
->>
-_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI
-constexpr _ToType bit_cast(_FromType const& __from) noexcept {
- return __builtin_bit_cast(_ToType, __from);
+template <class _ToType, class _FromType>
+ requires(sizeof(_ToType) == sizeof(_FromType) &&
+ is_trivially_copyable_v<_ToType> &&
+ is_trivially_copyable_v<_FromType>)
+_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _ToType bit_cast(const _FromType& __from) noexcept {
+ return __builtin_bit_cast(_ToType, __from);
}
#endif // _LIBCPP_STD_VER > 17
diff --git a/libcxx/include/__bit/byteswap.h b/libcxx/include/__bit/byteswap.h
index 970074ed98ce..6fa8d48bafa4 100644
--- a/libcxx/include/__bit/byteswap.h
+++ b/libcxx/include/__bit/byteswap.h
@@ -21,7 +21,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 20 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 20
template <integral _Tp>
_LIBCPP_HIDE_FROM_ABI constexpr _Tp byteswap(_Tp __val) noexcept {
@@ -48,7 +48,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr _Tp byteswap(_Tp __val) noexcept {
}
}
-#endif // _LIBCPP_STD_VER > 20 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 20
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__bit_reference b/libcxx/include/__bit_reference
index a60a5c721907..8c4f1badbd35 100644
--- a/libcxx/include/__bit_reference
+++ b/libcxx/include/__bit_reference
@@ -10,12 +10,16 @@
#ifndef _LIBCPP___BIT_REFERENCE
#define _LIBCPP___BIT_REFERENCE
+#include <__algorithm/min.h>
#include <__bits>
#include <__config>
-#include <algorithm>
+#include <__iterator/iterator_traits.h>
+#include <__memory/pointer_traits.h>
+#include <cstring>
+#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
@@ -65,6 +69,16 @@ public:
return *this;
}
+#if _LIBCPP_STD_VER > 20
+ _LIBCPP_HIDE_FROM_ABI const __bit_reference& operator=(bool __x) const noexcept {
+ if (__x)
+ *__seg_ |= __mask_;
+ else
+ *__seg_ &= ~__mask_;
+ return *this;
+ }
+#endif
+
_LIBCPP_INLINE_VISIBILITY
__bit_reference& operator=(const __bit_reference& __x) _NOEXCEPT
{return operator=(static_cast<bool>(__x));}
@@ -74,7 +88,7 @@ public:
{return __bit_iterator<_Cp, false>(__seg_, static_cast<unsigned>(__libcpp_ctz(__mask_)));}
private:
_LIBCPP_INLINE_VISIBILITY
- __bit_reference(__storage_pointer __s, __storage_type __m) _NOEXCEPT
+ explicit __bit_reference(__storage_pointer __s, __storage_type __m) _NOEXCEPT
: __seg_(__s), __mask_(__m) {}
};
@@ -150,7 +164,7 @@ public:
private:
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_CONSTEXPR
- __bit_const_reference(__storage_pointer __s, __storage_type __m) _NOEXCEPT
+ explicit __bit_const_reference(__storage_pointer __s, __storage_type __m) _NOEXCEPT
: __seg_(__s), __mask_(__m) {}
__bit_const_reference& operator=(const __bit_const_reference&) = delete;
@@ -1095,7 +1109,11 @@ public:
typedef typename _Cp::difference_type difference_type;
typedef bool value_type;
typedef __bit_iterator pointer;
+#ifndef _LIBCPP_ABI_BITSET_VECTOR_BOOL_CONST_SUBSCRIPT_RETURN_BOOL
typedef typename conditional<_IsConst, __bit_const_reference<_Cp>, __bit_reference<_Cp> >::type reference;
+#else
+ using reference = typename conditional<_IsConst, bool, __bit_reference<_Cp> >::type;
+#endif
typedef random_access_iterator_tag iterator_category;
private:
@@ -1135,8 +1153,10 @@ public:
return *this;
}
- _LIBCPP_INLINE_VISIBILITY reference operator*() const _NOEXCEPT
- {return reference(__seg_, __storage_type(1) << __ctz_);}
+ _LIBCPP_INLINE_VISIBILITY reference operator*() const _NOEXCEPT {
+ return typename conditional<_IsConst, __bit_const_reference<_Cp>, __bit_reference<_Cp> >
+ ::type(__seg_, __storage_type(1) << __ctz_);
+ }
_LIBCPP_INLINE_VISIBILITY __bit_iterator& operator++()
{
@@ -1236,7 +1256,7 @@ public:
private:
_LIBCPP_INLINE_VISIBILITY
- __bit_iterator(__storage_pointer __s, unsigned __ctz) _NOEXCEPT
+ explicit __bit_iterator(__storage_pointer __s, unsigned __ctz) _NOEXCEPT
: __seg_(__s), __ctz_(__ctz) {}
friend typename _Cp::__self;
diff --git a/libcxx/include/__bits b/libcxx/include/__bits
index b565a782358c..1eee8f576e9e 100644
--- a/libcxx/include/__bits
+++ b/libcxx/include/__bits
@@ -13,7 +13,7 @@
#include <__config>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
diff --git a/libcxx/include/__bsd_locale_defaults.h b/libcxx/include/__bsd_locale_defaults.h
index 0d6506c62576..4d990482d4a3 100644
--- a/libcxx/include/__bsd_locale_defaults.h
+++ b/libcxx/include/__bsd_locale_defaults.h
@@ -11,11 +11,11 @@
// we will define the mapping from an internal macro to the real BSD symbol.
//===----------------------------------------------------------------------===//
-#ifndef _LIBCPP_BSD_LOCALE_DEFAULTS_H
-#define _LIBCPP_BSD_LOCALE_DEFAULTS_H
+#ifndef _LIBCPP___BSD_LOCALE_DEFAULTS_H
+#define _LIBCPP___BSD_LOCALE_DEFAULTS_H
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
#define __libcpp_mb_cur_max_l(loc) MB_CUR_MAX_L(loc)
@@ -33,4 +33,4 @@
#define __libcpp_asprintf_l(...) asprintf_l(__VA_ARGS__)
#define __libcpp_sscanf_l(...) sscanf_l(__VA_ARGS__)
-#endif // _LIBCPP_BSD_LOCALE_DEFAULTS_H
+#endif // _LIBCPP___BSD_LOCALE_DEFAULTS_H
diff --git a/libcxx/include/__bsd_locale_fallbacks.h b/libcxx/include/__bsd_locale_fallbacks.h
index a5788d9777b5..3d5b78574480 100644
--- a/libcxx/include/__bsd_locale_fallbacks.h
+++ b/libcxx/include/__bsd_locale_fallbacks.h
@@ -10,15 +10,15 @@
// of those functions for non-BSD platforms.
//===----------------------------------------------------------------------===//
-#ifndef _LIBCPP_BSD_LOCALE_FALLBACKS_DEFAULTS_H
-#define _LIBCPP_BSD_LOCALE_FALLBACKS_DEFAULTS_H
+#ifndef _LIBCPP___BSD_LOCALE_FALLBACKS_H
+#define _LIBCPP___BSD_LOCALE_FALLBACKS_H
#include <memory>
#include <stdarg.h>
#include <stdlib.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -140,4 +140,4 @@ int __libcpp_sscanf_l(const char *__s, locale_t __l, const char *__format, ...)
_LIBCPP_END_NAMESPACE_STD
-#endif // _LIBCPP_BSD_LOCALE_FALLBACKS_DEFAULTS_H
+#endif // _LIBCPP___BSD_LOCALE_FALLBACKS_H
diff --git a/libcxx/include/__charconv/chars_format.h b/libcxx/include/__charconv/chars_format.h
index 22e70b56fb8c..0875079e6c7a 100644
--- a/libcxx/include/__charconv/chars_format.h
+++ b/libcxx/include/__charconv/chars_format.h
@@ -14,7 +14,7 @@
#include <__utility/to_underlying.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__charconv/from_chars_result.h b/libcxx/include/__charconv/from_chars_result.h
index fbd7d508115f..2cc3c11ef64f 100644
--- a/libcxx/include/__charconv/from_chars_result.h
+++ b/libcxx/include/__charconv/from_chars_result.h
@@ -14,7 +14,7 @@
#include <__errc>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__charconv/tables.h b/libcxx/include/__charconv/tables.h
new file mode 100644
index 000000000000..a2f7f7ce29b3
--- /dev/null
+++ b/libcxx/include/__charconv/tables.h
@@ -0,0 +1,130 @@
+// -*- 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___CHARCONV_TABLES
+#define _LIBCPP___CHARCONV_TABLES
+
+#include <__config>
+#include <cstdint>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#ifndef _LIBCPP_CXX03_LANG
+
+namespace __itoa {
+
+/// Contains the charconv helper tables.
+///
+/// In C++17 these could be inline constexpr variable, but libc++ supports
+/// charconv for integrals in C++11 mode.
+template <class = void>
+struct __table {
+ static const char __base_2_lut[64];
+ static const char __base_8_lut[128];
+ static const char __base_16_lut[512];
+
+ static const uint32_t __pow10_32[10];
+ static const uint64_t __pow10_64[20];
+ static const char __digits_base_10[200];
+};
+
+template <class _Tp>
+const char __table<_Tp>::__base_2_lut[64] = {
+ '0', '0', '0', '0', '0', '0', '0', '1', '0', '0', '1', '0', '0', '0', '1', '1', '0', '1', '0', '0', '0', '1',
+ '0', '1', '0', '1', '1', '0', '0', '1', '1', '1', '1', '0', '0', '0', '1', '0', '0', '1', '1', '0', '1', '0',
+ '1', '0', '1', '1', '1', '1', '0', '0', '1', '1', '0', '1', '1', '1', '1', '0', '1', '1', '1', '1'};
+
+template <class _Tp>
+const char __table<_Tp>::__base_8_lut[128] = {
+ '0', '0', '0', '1', '0', '2', '0', '3', '0', '4', '0', '5', '0', '6', '0', '7', '1', '0', '1', '1', '1', '2',
+ '1', '3', '1', '4', '1', '5', '1', '6', '1', '7', '2', '0', '2', '1', '2', '2', '2', '3', '2', '4', '2', '5',
+ '2', '6', '2', '7', '3', '0', '3', '1', '3', '2', '3', '3', '3', '4', '3', '5', '3', '6', '3', '7', '4', '0',
+ '4', '1', '4', '2', '4', '3', '4', '4', '4', '5', '4', '6', '4', '7', '5', '0', '5', '1', '5', '2', '5', '3',
+ '5', '4', '5', '5', '5', '6', '5', '7', '6', '0', '6', '1', '6', '2', '6', '3', '6', '4', '6', '5', '6', '6',
+ '6', '7', '7', '0', '7', '1', '7', '2', '7', '3', '7', '4', '7', '5', '7', '6', '7', '7'};
+
+template <class _Tp>
+const char __table<_Tp>::__base_16_lut[512] = {
+ '0', '0', '0', '1', '0', '2', '0', '3', '0', '4', '0', '5', '0', '6', '0', '7', '0', '8', '0', '9', '0', 'a', '0',
+ 'b', '0', 'c', '0', 'd', '0', 'e', '0', 'f', '1', '0', '1', '1', '1', '2', '1', '3', '1', '4', '1', '5', '1', '6',
+ '1', '7', '1', '8', '1', '9', '1', 'a', '1', 'b', '1', 'c', '1', 'd', '1', 'e', '1', 'f', '2', '0', '2', '1', '2',
+ '2', '2', '3', '2', '4', '2', '5', '2', '6', '2', '7', '2', '8', '2', '9', '2', 'a', '2', 'b', '2', 'c', '2', 'd',
+ '2', 'e', '2', 'f', '3', '0', '3', '1', '3', '2', '3', '3', '3', '4', '3', '5', '3', '6', '3', '7', '3', '8', '3',
+ '9', '3', 'a', '3', 'b', '3', 'c', '3', 'd', '3', 'e', '3', 'f', '4', '0', '4', '1', '4', '2', '4', '3', '4', '4',
+ '4', '5', '4', '6', '4', '7', '4', '8', '4', '9', '4', 'a', '4', 'b', '4', 'c', '4', 'd', '4', 'e', '4', 'f', '5',
+ '0', '5', '1', '5', '2', '5', '3', '5', '4', '5', '5', '5', '6', '5', '7', '5', '8', '5', '9', '5', 'a', '5', 'b',
+ '5', 'c', '5', 'd', '5', 'e', '5', 'f', '6', '0', '6', '1', '6', '2', '6', '3', '6', '4', '6', '5', '6', '6', '6',
+ '7', '6', '8', '6', '9', '6', 'a', '6', 'b', '6', 'c', '6', 'd', '6', 'e', '6', 'f', '7', '0', '7', '1', '7', '2',
+ '7', '3', '7', '4', '7', '5', '7', '6', '7', '7', '7', '8', '7', '9', '7', 'a', '7', 'b', '7', 'c', '7', 'd', '7',
+ 'e', '7', 'f', '8', '0', '8', '1', '8', '2', '8', '3', '8', '4', '8', '5', '8', '6', '8', '7', '8', '8', '8', '9',
+ '8', 'a', '8', 'b', '8', 'c', '8', 'd', '8', 'e', '8', 'f', '9', '0', '9', '1', '9', '2', '9', '3', '9', '4', '9',
+ '5', '9', '6', '9', '7', '9', '8', '9', '9', '9', 'a', '9', 'b', '9', 'c', '9', 'd', '9', 'e', '9', 'f', 'a', '0',
+ 'a', '1', 'a', '2', 'a', '3', 'a', '4', 'a', '5', 'a', '6', 'a', '7', 'a', '8', 'a', '9', 'a', 'a', 'a', 'b', 'a',
+ 'c', 'a', 'd', 'a', 'e', 'a', 'f', 'b', '0', 'b', '1', 'b', '2', 'b', '3', 'b', '4', 'b', '5', 'b', '6', 'b', '7',
+ 'b', '8', 'b', '9', 'b', 'a', 'b', 'b', 'b', 'c', 'b', 'd', 'b', 'e', 'b', 'f', 'c', '0', 'c', '1', 'c', '2', 'c',
+ '3', 'c', '4', 'c', '5', 'c', '6', 'c', '7', 'c', '8', 'c', '9', 'c', 'a', 'c', 'b', 'c', 'c', 'c', 'd', 'c', 'e',
+ 'c', 'f', 'd', '0', 'd', '1', 'd', '2', 'd', '3', 'd', '4', 'd', '5', 'd', '6', 'd', '7', 'd', '8', 'd', '9', 'd',
+ 'a', 'd', 'b', 'd', 'c', 'd', 'd', 'd', 'e', 'd', 'f', 'e', '0', 'e', '1', 'e', '2', 'e', '3', 'e', '4', 'e', '5',
+ 'e', '6', 'e', '7', 'e', '8', 'e', '9', 'e', 'a', 'e', 'b', 'e', 'c', 'e', 'd', 'e', 'e', 'e', 'f', 'f', '0', 'f',
+ '1', 'f', '2', 'f', '3', 'f', '4', 'f', '5', 'f', '6', 'f', '7', 'f', '8', 'f', '9', 'f', 'a', 'f', 'b', 'f', 'c',
+ 'f', 'd', 'f', 'e', 'f', 'f'};
+
+template <class _Tp>
+const uint32_t __table<_Tp>::__pow10_32[10] = {
+ UINT32_C(0), UINT32_C(10), UINT32_C(100), UINT32_C(1000), UINT32_C(10000),
+ UINT32_C(100000), UINT32_C(1000000), UINT32_C(10000000), UINT32_C(100000000), UINT32_C(1000000000)};
+
+template <class _Tp>
+const uint64_t __table<_Tp>::__pow10_64[20] = {UINT64_C(0),
+ UINT64_C(10),
+ UINT64_C(100),
+ UINT64_C(1000),
+ UINT64_C(10000),
+ UINT64_C(100000),
+ UINT64_C(1000000),
+ UINT64_C(10000000),
+ UINT64_C(100000000),
+ UINT64_C(1000000000),
+ UINT64_C(10000000000),
+ UINT64_C(100000000000),
+ UINT64_C(1000000000000),
+ UINT64_C(10000000000000),
+ UINT64_C(100000000000000),
+ UINT64_C(1000000000000000),
+ UINT64_C(10000000000000000),
+ UINT64_C(100000000000000000),
+ UINT64_C(1000000000000000000),
+ UINT64_C(10000000000000000000)};
+
+template <class _Tp>
+const char __table<_Tp>::__digits_base_10[200] = {
+ // clang-format off
+ '0', '0', '0', '1', '0', '2', '0', '3', '0', '4', '0', '5', '0', '6', '0', '7', '0', '8', '0', '9',
+ '1', '0', '1', '1', '1', '2', '1', '3', '1', '4', '1', '5', '1', '6', '1', '7', '1', '8', '1', '9',
+ '2', '0', '2', '1', '2', '2', '2', '3', '2', '4', '2', '5', '2', '6', '2', '7', '2', '8', '2', '9',
+ '3', '0', '3', '1', '3', '2', '3', '3', '3', '4', '3', '5', '3', '6', '3', '7', '3', '8', '3', '9',
+ '4', '0', '4', '1', '4', '2', '4', '3', '4', '4', '4', '5', '4', '6', '4', '7', '4', '8', '4', '9',
+ '5', '0', '5', '1', '5', '2', '5', '3', '5', '4', '5', '5', '5', '6', '5', '7', '5', '8', '5', '9',
+ '6', '0', '6', '1', '6', '2', '6', '3', '6', '4', '6', '5', '6', '6', '6', '7', '6', '8', '6', '9',
+ '7', '0', '7', '1', '7', '2', '7', '3', '7', '4', '7', '5', '7', '6', '7', '7', '7', '8', '7', '9',
+ '8', '0', '8', '1', '8', '2', '8', '3', '8', '4', '8', '5', '8', '6', '8', '7', '8', '8', '8', '9',
+ '9', '0', '9', '1', '9', '2', '9', '3', '9', '4', '9', '5', '9', '6', '9', '7', '9', '8', '9', '9'};
+// clang-format on
+
+} // namespace __itoa
+
+#endif // _LIBCPP_CXX03_LANG
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___CHARCONV_TABLES
diff --git a/libcxx/include/__charconv/to_chars_base_10.h b/libcxx/include/__charconv/to_chars_base_10.h
new file mode 100644
index 000000000000..91c209559aff
--- /dev/null
+++ b/libcxx/include/__charconv/to_chars_base_10.h
@@ -0,0 +1,127 @@
+// -*- 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___CHARCONV_TO_CHARS_BASE_10_H
+#define _LIBCPP___CHARCONV_TO_CHARS_BASE_10_H
+
+#include <__algorithm/copy_n.h>
+#include <__charconv/tables.h>
+#include <__config>
+#include <cstdint>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#ifndef _LIBCPP_CXX03_LANG
+
+namespace __itoa {
+
+_LIBCPP_HIDE_FROM_ABI inline char* __append1(char* __first, uint32_t __value) noexcept {
+ *__first = '0' + static_cast<char>(__value);
+ return __first + 1;
+}
+
+_LIBCPP_HIDE_FROM_ABI inline char* __append2(char* __first, uint32_t __value) noexcept {
+ return std::copy_n(&__table<>::__digits_base_10[__value * 2], 2, __first);
+}
+
+_LIBCPP_HIDE_FROM_ABI inline char* __append3(char* __first, uint32_t __value) noexcept {
+ return __itoa::__append2(__itoa::__append1(__first, __value / 100), __value % 100);
+}
+
+_LIBCPP_HIDE_FROM_ABI inline char* __append4(char* __first, uint32_t __value) noexcept {
+ return __itoa::__append2(__itoa::__append2(__first, __value / 100), __value % 100);
+}
+
+_LIBCPP_HIDE_FROM_ABI inline char* __append5(char* __first, uint32_t __value) noexcept {
+ return __itoa::__append4(__itoa::__append1(__first, __value / 10000), __value % 10000);
+}
+
+_LIBCPP_HIDE_FROM_ABI inline char* __append6(char* __first, uint32_t __value) noexcept {
+ return __itoa::__append4(__itoa::__append2(__first, __value / 10000), __value % 10000);
+}
+
+_LIBCPP_HIDE_FROM_ABI inline char* __append7(char* __first, uint32_t __value) noexcept {
+ return __itoa::__append6(__itoa::__append1(__first, __value / 1000000), __value % 1000000);
+}
+
+_LIBCPP_HIDE_FROM_ABI inline char* __append8(char* __first, uint32_t __value) noexcept {
+ return __itoa::__append6(__itoa::__append2(__first, __value / 1000000), __value % 1000000);
+}
+
+_LIBCPP_HIDE_FROM_ABI inline char* __append9(char* __first, uint32_t __value) noexcept {
+ return __itoa::__append8(__itoa::__append1(__first, __value / 100000000), __value % 100000000);
+}
+
+// This function is used for uint32_t and uint64_t.
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI char* __append10(char* __first, _Tp __value) noexcept {
+ return __itoa::__append8(__itoa::__append2(__first, static_cast<uint32_t>(__value / 100000000)),
+ static_cast<uint32_t>(__value % 100000000));
+}
+
+_LIBCPP_HIDE_FROM_ABI inline char* __base_10_u32(char* __first, uint32_t __value) noexcept {
+ if (__value < 1000000) {
+ if (__value < 10000) {
+ if (__value < 100) {
+ // 0 <= __value < 100
+ if (__value < 10)
+ return __itoa::__append1(__first, __value);
+ return __itoa::__append2(__first, __value);
+ }
+ // 100 <= __value < 10'000
+ if (__value < 1000)
+ return __itoa::__append3(__first, __value);
+ return __itoa::__append4(__first, __value);
+ }
+
+ // 10'000 <= __value < 1'000'000
+ if (__value < 100000)
+ return __itoa::__append5(__first, __value);
+ return __itoa::__append6(__first, __value);
+ }
+
+ // __value => 1'000'000
+ if (__value < 100000000) {
+ // 1'000'000 <= __value < 100'000'000
+ if (__value < 10000000)
+ return __itoa::__append7(__first, __value);
+ return __itoa::__append8(__first, __value);
+ }
+
+ // 100'000'000 <= __value < max
+ if (__value < 1000000000)
+ return __itoa::__append9(__first, __value);
+ return __itoa::__append10(__first, __value);
+}
+
+_LIBCPP_HIDE_FROM_ABI inline char* __base_10_u64(char* __buffer, uint64_t __value) noexcept {
+ if (__value <= UINT32_MAX)
+ return __itoa::__base_10_u32(__buffer, static_cast<uint32_t>(__value));
+
+ // Numbers in the range UINT32_MAX <= val < 10'000'000'000 always contain 10
+ // digits and are outputted after this if statement.
+ if (__value >= 10000000000) {
+ // This function properly deterimines the first non-zero leading digit.
+ __buffer = __itoa::__base_10_u32(__buffer, static_cast<uint32_t>(__value / 10000000000));
+ __value %= 10000000000;
+ }
+ return __itoa::__append10(__buffer, __value);
+}
+
+} // namespace __itoa
+
+#endif // _LIBCPP_CXX03_LANG
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___CHARCONV_TO_CHARS_BASE_10_H
diff --git a/libcxx/include/__charconv/to_chars_result.h b/libcxx/include/__charconv/to_chars_result.h
index f515ee3122c1..b4bc6ac2635b 100644
--- a/libcxx/include/__charconv/to_chars_result.h
+++ b/libcxx/include/__charconv/to_chars_result.h
@@ -14,7 +14,7 @@
#include <__errc>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__chrono/calendar.h b/libcxx/include/__chrono/calendar.h
index 745f7f5cf529..d3762a631c91 100644
--- a/libcxx/include/__chrono/calendar.h
+++ b/libcxx/include/__chrono/calendar.h
@@ -11,20 +11,13 @@
#define _LIBCPP___CHRONO_CALENDAR_H
#include <__chrono/duration.h>
-#include <__chrono/system_clock.h>
#include <__chrono/time_point.h>
#include <__config>
-#include <limits>
-#include <ratio>
-#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
-_LIBCPP_PUSH_MACROS
-#include <__undef_macros>
-
#if _LIBCPP_STD_VER > 17
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -38,1239 +31,14 @@ using local_time = time_point<local_t, Duration>;
using local_seconds = local_time<seconds>;
using local_days = local_time<days>;
-struct last_spec { explicit last_spec() = default; };
-
-class day {
-private:
- unsigned char __d;
-public:
- day() = default;
- explicit inline constexpr day(unsigned __val) noexcept : __d(static_cast<unsigned char>(__val)) {}
- inline constexpr day& operator++() noexcept { ++__d; return *this; }
- inline constexpr day operator++(int) noexcept { day __tmp = *this; ++(*this); return __tmp; }
- inline constexpr day& operator--() noexcept { --__d; return *this; }
- inline constexpr day operator--(int) noexcept { day __tmp = *this; --(*this); return __tmp; }
- constexpr day& operator+=(const days& __dd) noexcept;
- constexpr day& operator-=(const days& __dd) noexcept;
- explicit inline constexpr operator unsigned() const noexcept { return __d; }
- inline constexpr bool ok() const noexcept { return __d >= 1 && __d <= 31; }
- };
-
-
-inline constexpr
-bool operator==(const day& __lhs, const day& __rhs) noexcept
-{ return static_cast<unsigned>(__lhs) == static_cast<unsigned>(__rhs); }
-
-inline constexpr
-bool operator!=(const day& __lhs, const day& __rhs) noexcept
-{ return !(__lhs == __rhs); }
-
-inline constexpr
-bool operator< (const day& __lhs, const day& __rhs) noexcept
-{ return static_cast<unsigned>(__lhs) < static_cast<unsigned>(__rhs); }
-
-inline constexpr
-bool operator> (const day& __lhs, const day& __rhs) noexcept
-{ return __rhs < __lhs; }
-
-inline constexpr
-bool operator<=(const day& __lhs, const day& __rhs) noexcept
-{ return !(__rhs < __lhs);}
-
-inline constexpr
-bool operator>=(const day& __lhs, const day& __rhs) noexcept
-{ return !(__lhs < __rhs); }
-
-inline constexpr
-day operator+ (const day& __lhs, const days& __rhs) noexcept
-{ return day(static_cast<unsigned>(__lhs) + __rhs.count()); }
-
-inline constexpr
-day operator+ (const days& __lhs, const day& __rhs) noexcept
-{ return __rhs + __lhs; }
-
-inline constexpr
-day operator- (const day& __lhs, const days& __rhs) noexcept
-{ return __lhs + -__rhs; }
-
-inline constexpr
-days operator-(const day& __lhs, const day& __rhs) noexcept
-{ return days(static_cast<int>(static_cast<unsigned>(__lhs)) -
- static_cast<int>(static_cast<unsigned>(__rhs))); }
-
-inline constexpr day& day::operator+=(const days& __dd) noexcept
-{ *this = *this + __dd; return *this; }
-
-inline constexpr day& day::operator-=(const days& __dd) noexcept
-{ *this = *this - __dd; return *this; }
-
-
-class month {
-private:
- unsigned char __m;
-public:
- month() = default;
- explicit inline constexpr month(unsigned __val) noexcept : __m(static_cast<unsigned char>(__val)) {}
- inline constexpr month& operator++() noexcept { ++__m; return *this; }
- inline constexpr month operator++(int) noexcept { month __tmp = *this; ++(*this); return __tmp; }
- inline constexpr month& operator--() noexcept { --__m; return *this; }
- inline constexpr month operator--(int) noexcept { month __tmp = *this; --(*this); return __tmp; }
- constexpr month& operator+=(const months& __m1) noexcept;
- constexpr month& operator-=(const months& __m1) noexcept;
- explicit inline constexpr operator unsigned() const noexcept { return __m; }
- inline constexpr bool ok() const noexcept { return __m >= 1 && __m <= 12; }
-};
-
-
-inline constexpr
-bool operator==(const month& __lhs, const month& __rhs) noexcept
-{ return static_cast<unsigned>(__lhs) == static_cast<unsigned>(__rhs); }
-
-inline constexpr
-bool operator!=(const month& __lhs, const month& __rhs) noexcept
-{ return !(__lhs == __rhs); }
-
-inline constexpr
-bool operator< (const month& __lhs, const month& __rhs) noexcept
-{ return static_cast<unsigned>(__lhs) < static_cast<unsigned>(__rhs); }
-
-inline constexpr
-bool operator> (const month& __lhs, const month& __rhs) noexcept
-{ return __rhs < __lhs; }
-
-inline constexpr
-bool operator<=(const month& __lhs, const month& __rhs) noexcept
-{ return !(__rhs < __lhs); }
-
-inline constexpr
-bool operator>=(const month& __lhs, const month& __rhs) noexcept
-{ return !(__lhs < __rhs); }
-
-inline constexpr
-month operator+ (const month& __lhs, const months& __rhs) noexcept
-{
- auto const __mu = static_cast<long long>(static_cast<unsigned>(__lhs)) + (__rhs.count() - 1);
- auto const __yr = (__mu >= 0 ? __mu : __mu - 11) / 12;
- return month{static_cast<unsigned>(__mu - __yr * 12 + 1)};
-}
-
-inline constexpr
-month operator+ (const months& __lhs, const month& __rhs) noexcept
-{ return __rhs + __lhs; }
-
-inline constexpr
-month operator- (const month& __lhs, const months& __rhs) noexcept
-{ return __lhs + -__rhs; }
-
-inline constexpr
-months operator-(const month& __lhs, const month& __rhs) noexcept
-{
- auto const __dm = static_cast<unsigned>(__lhs) - static_cast<unsigned>(__rhs);
- return months(__dm <= 11 ? __dm : __dm + 12);
-}
-
-inline constexpr month& month::operator+=(const months& __dm) noexcept
-{ *this = *this + __dm; return *this; }
-
-inline constexpr month& month::operator-=(const months& __dm) noexcept
-{ *this = *this - __dm; return *this; }
-
-
-class year {
-private:
- short __y;
-public:
- year() = default;
- explicit inline constexpr year(int __val) noexcept : __y(static_cast<short>(__val)) {}
-
- inline constexpr year& operator++() noexcept { ++__y; return *this; }
- inline constexpr year operator++(int) noexcept { year __tmp = *this; ++(*this); return __tmp; }
- inline constexpr year& operator--() noexcept { --__y; return *this; }
- inline constexpr year operator--(int) noexcept { year __tmp = *this; --(*this); return __tmp; }
- constexpr year& operator+=(const years& __dy) noexcept;
- constexpr year& operator-=(const years& __dy) noexcept;
- inline constexpr year operator+() const noexcept { return *this; }
- inline constexpr year operator-() const noexcept { return year{-__y}; }
-
- inline constexpr bool is_leap() const noexcept { return __y % 4 == 0 && (__y % 100 != 0 || __y % 400 == 0); }
- explicit inline constexpr operator int() const noexcept { return __y; }
- constexpr bool ok() const noexcept;
- static inline constexpr year min() noexcept { return year{-32767}; }
- static inline constexpr year max() noexcept { return year{ 32767}; }
-};
-
-
-inline constexpr
-bool operator==(const year& __lhs, const year& __rhs) noexcept
-{ return static_cast<int>(__lhs) == static_cast<int>(__rhs); }
-
-inline constexpr
-bool operator!=(const year& __lhs, const year& __rhs) noexcept
-{ return !(__lhs == __rhs); }
-
-inline constexpr
-bool operator< (const year& __lhs, const year& __rhs) noexcept
-{ return static_cast<int>(__lhs) < static_cast<int>(__rhs); }
-
-inline constexpr
-bool operator> (const year& __lhs, const year& __rhs) noexcept
-{ return __rhs < __lhs; }
-
-inline constexpr
-bool operator<=(const year& __lhs, const year& __rhs) noexcept
-{ return !(__rhs < __lhs); }
-
-inline constexpr
-bool operator>=(const year& __lhs, const year& __rhs) noexcept
-{ return !(__lhs < __rhs); }
-
-inline constexpr
-year operator+ (const year& __lhs, const years& __rhs) noexcept
-{ return year(static_cast<int>(__lhs) + __rhs.count()); }
-
-inline constexpr
-year operator+ (const years& __lhs, const year& __rhs) noexcept
-{ return __rhs + __lhs; }
-
-inline constexpr
-year operator- (const year& __lhs, const years& __rhs) noexcept
-{ return __lhs + -__rhs; }
-
-inline constexpr
-years operator-(const year& __lhs, const year& __rhs) noexcept
-{ return years{static_cast<int>(__lhs) - static_cast<int>(__rhs)}; }
-
-
-inline constexpr year& year::operator+=(const years& __dy) noexcept
-{ *this = *this + __dy; return *this; }
-
-inline constexpr year& year::operator-=(const years& __dy) noexcept
-{ *this = *this - __dy; return *this; }
-
-inline constexpr bool year::ok() const noexcept
-{ return static_cast<int>(min()) <= __y && __y <= static_cast<int>(max()); }
-
-class weekday_indexed;
-class weekday_last;
-
-class weekday {
-private:
- unsigned char __wd;
- static constexpr unsigned char __weekday_from_days(int __days) noexcept;
-public:
- weekday() = default;
- inline explicit constexpr weekday(unsigned __val) noexcept : __wd(static_cast<unsigned char>(__val == 7 ? 0 : __val)) {}
- inline constexpr weekday(const sys_days& __sysd) noexcept
- : __wd(__weekday_from_days(__sysd.time_since_epoch().count())) {}
- inline explicit constexpr weekday(const local_days& __locd) noexcept
- : __wd(__weekday_from_days(__locd.time_since_epoch().count())) {}
-
- inline constexpr weekday& operator++() noexcept { __wd = (__wd == 6 ? 0 : __wd + 1); return *this; }
- inline constexpr weekday operator++(int) noexcept { weekday __tmp = *this; ++(*this); return __tmp; }
- inline constexpr weekday& operator--() noexcept { __wd = (__wd == 0 ? 6 : __wd - 1); return *this; }
- inline constexpr weekday operator--(int) noexcept { weekday __tmp = *this; --(*this); return __tmp; }
- constexpr weekday& operator+=(const days& __dd) noexcept;
- constexpr weekday& operator-=(const days& __dd) noexcept;
- inline constexpr unsigned c_encoding() const noexcept { return __wd; }
- inline constexpr unsigned iso_encoding() const noexcept { return __wd == 0u ? 7 : __wd; }
- inline constexpr bool ok() const noexcept { return __wd <= 6; }
- constexpr weekday_indexed operator[](unsigned __index) const noexcept;
- constexpr weekday_last operator[](last_spec) const noexcept;
-};
-
-
-// https://howardhinnant.github.io/date_algorithms.html#weekday_from_days
-inline constexpr
-unsigned char weekday::__weekday_from_days(int __days) noexcept
-{
- return static_cast<unsigned char>(
- static_cast<unsigned>(__days >= -4 ? (__days+4) % 7 : (__days+5) % 7 + 6)
- );
-}
-
-inline constexpr
-bool operator==(const weekday& __lhs, const weekday& __rhs) noexcept
-{ return __lhs.c_encoding() == __rhs.c_encoding(); }
-
-inline constexpr
-bool operator!=(const weekday& __lhs, const weekday& __rhs) noexcept
-{ return !(__lhs == __rhs); }
-
-inline constexpr
-bool operator< (const weekday& __lhs, const weekday& __rhs) noexcept
-{ return __lhs.c_encoding() < __rhs.c_encoding(); }
-
-inline constexpr
-bool operator> (const weekday& __lhs, const weekday& __rhs) noexcept
-{ return __rhs < __lhs; }
-
-inline constexpr
-bool operator<=(const weekday& __lhs, const weekday& __rhs) noexcept
-{ return !(__rhs < __lhs);}
-
-inline constexpr
-bool operator>=(const weekday& __lhs, const weekday& __rhs) noexcept
-{ return !(__lhs < __rhs); }
-
-constexpr weekday operator+(const weekday& __lhs, const days& __rhs) noexcept
-{
- auto const __mu = static_cast<long long>(__lhs.c_encoding()) + __rhs.count();
- auto const __yr = (__mu >= 0 ? __mu : __mu - 6) / 7;
- return weekday{static_cast<unsigned>(__mu - __yr * 7)};
-}
-
-constexpr weekday operator+(const days& __lhs, const weekday& __rhs) noexcept
-{ return __rhs + __lhs; }
-
-constexpr weekday operator-(const weekday& __lhs, const days& __rhs) noexcept
-{ return __lhs + -__rhs; }
-
-constexpr days operator-(const weekday& __lhs, const weekday& __rhs) noexcept
-{
- const int __wdu = __lhs.c_encoding() - __rhs.c_encoding();
- const int __wk = (__wdu >= 0 ? __wdu : __wdu-6) / 7;
- return days{__wdu - __wk * 7};
-}
-
-inline constexpr weekday& weekday::operator+=(const days& __dd) noexcept
-{ *this = *this + __dd; return *this; }
-
-inline constexpr weekday& weekday::operator-=(const days& __dd) noexcept
-{ *this = *this - __dd; return *this; }
-
-
-class weekday_indexed {
-private:
- chrono::weekday __wd;
- unsigned char __idx;
-public:
- weekday_indexed() = default;
- inline constexpr weekday_indexed(const chrono::weekday& __wdval, unsigned __idxval) noexcept
- : __wd{__wdval}, __idx(__idxval) {}
- inline constexpr chrono::weekday weekday() const noexcept { return __wd; }
- inline constexpr unsigned index() const noexcept { return __idx; }
- inline constexpr bool ok() const noexcept { return __wd.ok() && __idx >= 1 && __idx <= 5; }
-};
-
-inline constexpr
-bool operator==(const weekday_indexed& __lhs, const weekday_indexed& __rhs) noexcept
-{ return __lhs.weekday() == __rhs.weekday() && __lhs.index() == __rhs.index(); }
-
-inline constexpr
-bool operator!=(const weekday_indexed& __lhs, const weekday_indexed& __rhs) noexcept
-{ return !(__lhs == __rhs); }
-
-
-class weekday_last {
-private:
- chrono::weekday __wd;
-public:
- explicit constexpr weekday_last(const chrono::weekday& __val) noexcept
- : __wd{__val} {}
- constexpr chrono::weekday weekday() const noexcept { return __wd; }
- constexpr bool ok() const noexcept { return __wd.ok(); }
-};
-
-inline constexpr
-bool operator==(const weekday_last& __lhs, const weekday_last& __rhs) noexcept
-{ return __lhs.weekday() == __rhs.weekday(); }
-
-inline constexpr
-bool operator!=(const weekday_last& __lhs, const weekday_last& __rhs) noexcept
-{ return !(__lhs == __rhs); }
-
-inline constexpr
-weekday_indexed weekday::operator[](unsigned __index) const noexcept { return weekday_indexed{*this, __index}; }
-
-inline constexpr
-weekday_last weekday::operator[](last_spec) const noexcept { return weekday_last{*this}; }
-
-
+struct last_spec { _LIBCPP_HIDE_FROM_ABI explicit last_spec() = default; };
inline constexpr last_spec last{};
-inline constexpr weekday Sunday{0};
-inline constexpr weekday Monday{1};
-inline constexpr weekday Tuesday{2};
-inline constexpr weekday Wednesday{3};
-inline constexpr weekday Thursday{4};
-inline constexpr weekday Friday{5};
-inline constexpr weekday Saturday{6};
-
-inline constexpr month January{1};
-inline constexpr month February{2};
-inline constexpr month March{3};
-inline constexpr month April{4};
-inline constexpr month May{5};
-inline constexpr month June{6};
-inline constexpr month July{7};
-inline constexpr month August{8};
-inline constexpr month September{9};
-inline constexpr month October{10};
-inline constexpr month November{11};
-inline constexpr month December{12};
-
-
-class month_day {
-private:
- chrono::month __m;
- chrono::day __d;
-public:
- month_day() = default;
- constexpr month_day(const chrono::month& __mval, const chrono::day& __dval) noexcept
- : __m{__mval}, __d{__dval} {}
- inline constexpr chrono::month month() const noexcept { return __m; }
- inline constexpr chrono::day day() const noexcept { return __d; }
- constexpr bool ok() const noexcept;
-};
-
-inline constexpr
-bool month_day::ok() const noexcept
-{
- if (!__m.ok()) return false;
- const unsigned __dval = static_cast<unsigned>(__d);
- if (__dval < 1 || __dval > 31) return false;
- if (__dval <= 29) return true;
-// Now we've got either 30 or 31
- const unsigned __mval = static_cast<unsigned>(__m);
- if (__mval == 2) return false;
- if (__mval == 4 || __mval == 6 || __mval == 9 || __mval == 11)
- return __dval == 30;
- return true;
-}
-
-inline constexpr
-bool operator==(const month_day& __lhs, const month_day& __rhs) noexcept
-{ return __lhs.month() == __rhs.month() && __lhs.day() == __rhs.day(); }
-
-inline constexpr
-bool operator!=(const month_day& __lhs, const month_day& __rhs) noexcept
-{ return !(__lhs == __rhs); }
-
-inline constexpr
-month_day operator/(const month& __lhs, const day& __rhs) noexcept
-{ return month_day{__lhs, __rhs}; }
-
-constexpr
-month_day operator/(const day& __lhs, const month& __rhs) noexcept
-{ return __rhs / __lhs; }
-
-inline constexpr
-month_day operator/(const month& __lhs, int __rhs) noexcept
-{ return __lhs / day(__rhs); }
-
-constexpr
-month_day operator/(int __lhs, const day& __rhs) noexcept
-{ return month(__lhs) / __rhs; }
-
-constexpr
-month_day operator/(const day& __lhs, int __rhs) noexcept
-{ return month(__rhs) / __lhs; }
-
-
-inline constexpr
-bool operator< (const month_day& __lhs, const month_day& __rhs) noexcept
-{ return __lhs.month() != __rhs.month() ? __lhs.month() < __rhs.month() : __lhs.day() < __rhs.day(); }
-
-inline constexpr
-bool operator> (const month_day& __lhs, const month_day& __rhs) noexcept
-{ return __rhs < __lhs; }
-
-inline constexpr
-bool operator<=(const month_day& __lhs, const month_day& __rhs) noexcept
-{ return !(__rhs < __lhs);}
-
-inline constexpr
-bool operator>=(const month_day& __lhs, const month_day& __rhs) noexcept
-{ return !(__lhs < __rhs); }
-
-
-
-class month_day_last {
-private:
- chrono::month __m;
-public:
- explicit constexpr month_day_last(const chrono::month& __val) noexcept
- : __m{__val} {}
- inline constexpr chrono::month month() const noexcept { return __m; }
- inline constexpr bool ok() const noexcept { return __m.ok(); }
-};
-
-inline constexpr
-bool operator==(const month_day_last& __lhs, const month_day_last& __rhs) noexcept
-{ return __lhs.month() == __rhs.month(); }
-
-inline constexpr
-bool operator!=(const month_day_last& __lhs, const month_day_last& __rhs) noexcept
-{ return !(__lhs == __rhs); }
-inline constexpr
-bool operator< (const month_day_last& __lhs, const month_day_last& __rhs) noexcept
-{ return __lhs.month() < __rhs.month(); }
-inline constexpr
-bool operator> (const month_day_last& __lhs, const month_day_last& __rhs) noexcept
-{ return __rhs < __lhs; }
-
-inline constexpr
-bool operator<=(const month_day_last& __lhs, const month_day_last& __rhs) noexcept
-{ return !(__rhs < __lhs);}
-
-inline constexpr
-bool operator>=(const month_day_last& __lhs, const month_day_last& __rhs) noexcept
-{ return !(__lhs < __rhs); }
-
-inline constexpr
-month_day_last operator/(const month& __lhs, last_spec) noexcept
-{ return month_day_last{__lhs}; }
-
-inline constexpr
-month_day_last operator/(last_spec, const month& __rhs) noexcept
-{ return month_day_last{__rhs}; }
-
-inline constexpr
-month_day_last operator/(int __lhs, last_spec) noexcept
-{ return month_day_last{month(__lhs)}; }
-
-inline constexpr
-month_day_last operator/(last_spec, int __rhs) noexcept
-{ return month_day_last{month(__rhs)}; }
-
-
-class month_weekday {
-private:
- chrono::month __m;
- chrono::weekday_indexed __wdi;
-public:
- constexpr month_weekday(const chrono::month& __mval, const chrono::weekday_indexed& __wdival) noexcept
- : __m{__mval}, __wdi{__wdival} {}
- inline constexpr chrono::month month() const noexcept { return __m; }
- inline constexpr chrono::weekday_indexed weekday_indexed() const noexcept { return __wdi; }
- inline constexpr bool ok() const noexcept { return __m.ok() && __wdi.ok(); }
-};
-
-inline constexpr
-bool operator==(const month_weekday& __lhs, const month_weekday& __rhs) noexcept
-{ return __lhs.month() == __rhs.month() && __lhs.weekday_indexed() == __rhs.weekday_indexed(); }
-
-inline constexpr
-bool operator!=(const month_weekday& __lhs, const month_weekday& __rhs) noexcept
-{ return !(__lhs == __rhs); }
-
-inline constexpr
-month_weekday operator/(const month& __lhs, const weekday_indexed& __rhs) noexcept
-{ return month_weekday{__lhs, __rhs}; }
-
-inline constexpr
-month_weekday operator/(int __lhs, const weekday_indexed& __rhs) noexcept
-{ return month_weekday{month(__lhs), __rhs}; }
-
-inline constexpr
-month_weekday operator/(const weekday_indexed& __lhs, const month& __rhs) noexcept
-{ return month_weekday{__rhs, __lhs}; }
-
-inline constexpr
-month_weekday operator/(const weekday_indexed& __lhs, int __rhs) noexcept
-{ return month_weekday{month(__rhs), __lhs}; }
-
-
-class month_weekday_last {
- chrono::month __m;
- chrono::weekday_last __wdl;
- public:
- constexpr month_weekday_last(const chrono::month& __mval, const chrono::weekday_last& __wdlval) noexcept
- : __m{__mval}, __wdl{__wdlval} {}
- inline constexpr chrono::month month() const noexcept { return __m; }
- inline constexpr chrono::weekday_last weekday_last() const noexcept { return __wdl; }
- inline constexpr bool ok() const noexcept { return __m.ok() && __wdl.ok(); }
-};
-
-inline constexpr
-bool operator==(const month_weekday_last& __lhs, const month_weekday_last& __rhs) noexcept
-{ return __lhs.month() == __rhs.month() && __lhs.weekday_last() == __rhs.weekday_last(); }
-
-inline constexpr
-bool operator!=(const month_weekday_last& __lhs, const month_weekday_last& __rhs) noexcept
-{ return !(__lhs == __rhs); }
-
-
-inline constexpr
-month_weekday_last operator/(const month& __lhs, const weekday_last& __rhs) noexcept
-{ return month_weekday_last{__lhs, __rhs}; }
-
-inline constexpr
-month_weekday_last operator/(int __lhs, const weekday_last& __rhs) noexcept
-{ return month_weekday_last{month(__lhs), __rhs}; }
-
-inline constexpr
-month_weekday_last operator/(const weekday_last& __lhs, const month& __rhs) noexcept
-{ return month_weekday_last{__rhs, __lhs}; }
-
-inline constexpr
-month_weekday_last operator/(const weekday_last& __lhs, int __rhs) noexcept
-{ return month_weekday_last{month(__rhs), __lhs}; }
-
-
-class year_month {
- chrono::year __y;
- chrono::month __m;
-public:
- year_month() = default;
- constexpr year_month(const chrono::year& __yval, const chrono::month& __mval) noexcept
- : __y{__yval}, __m{__mval} {}
- inline constexpr chrono::year year() const noexcept { return __y; }
- inline constexpr chrono::month month() const noexcept { return __m; }
- inline constexpr year_month& operator+=(const months& __dm) noexcept { this->__m += __dm; return *this; }
- inline constexpr year_month& operator-=(const months& __dm) noexcept { this->__m -= __dm; return *this; }
- inline constexpr year_month& operator+=(const years& __dy) noexcept { this->__y += __dy; return *this; }
- inline constexpr year_month& operator-=(const years& __dy) noexcept { this->__y -= __dy; return *this; }
- inline constexpr bool ok() const noexcept { return __y.ok() && __m.ok(); }
-};
-
-inline constexpr
-year_month operator/(const year& __y, const month& __m) noexcept { return year_month{__y, __m}; }
-
-inline constexpr
-year_month operator/(const year& __y, int __m) noexcept { return year_month{__y, month(__m)}; }
-
-inline constexpr
-bool operator==(const year_month& __lhs, const year_month& __rhs) noexcept
-{ return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month(); }
-
-inline constexpr
-bool operator!=(const year_month& __lhs, const year_month& __rhs) noexcept
-{ return !(__lhs == __rhs); }
-
-inline constexpr
-bool operator< (const year_month& __lhs, const year_month& __rhs) noexcept
-{ return __lhs.year() != __rhs.year() ? __lhs.year() < __rhs.year() : __lhs.month() < __rhs.month(); }
-
-inline constexpr
-bool operator> (const year_month& __lhs, const year_month& __rhs) noexcept
-{ return __rhs < __lhs; }
-
-inline constexpr
-bool operator<=(const year_month& __lhs, const year_month& __rhs) noexcept
-{ return !(__rhs < __lhs);}
-
-inline constexpr
-bool operator>=(const year_month& __lhs, const year_month& __rhs) noexcept
-{ return !(__lhs < __rhs); }
-
-constexpr year_month operator+(const year_month& __lhs, const months& __rhs) noexcept
-{
- int __dmi = static_cast<int>(static_cast<unsigned>(__lhs.month())) - 1 + __rhs.count();
- const int __dy = (__dmi >= 0 ? __dmi : __dmi-11) / 12;
- __dmi = __dmi - __dy * 12 + 1;
- return (__lhs.year() + years(__dy)) / month(static_cast<unsigned>(__dmi));
-}
-
-constexpr year_month operator+(const months& __lhs, const year_month& __rhs) noexcept
-{ return __rhs + __lhs; }
-
-constexpr year_month operator+(const year_month& __lhs, const years& __rhs) noexcept
-{ return (__lhs.year() + __rhs) / __lhs.month(); }
-
-constexpr year_month operator+(const years& __lhs, const year_month& __rhs) noexcept
-{ return __rhs + __lhs; }
-
-constexpr months operator-(const year_month& __lhs, const year_month& __rhs) noexcept
-{ return (__lhs.year() - __rhs.year()) + months(static_cast<unsigned>(__lhs.month()) - static_cast<unsigned>(__rhs.month())); }
-
-constexpr year_month operator-(const year_month& __lhs, const months& __rhs) noexcept
-{ return __lhs + -__rhs; }
-
-constexpr year_month operator-(const year_month& __lhs, const years& __rhs) noexcept
-{ return __lhs + -__rhs; }
-
-class year_month_day_last;
-
-class year_month_day {
-private:
- chrono::year __y;
- chrono::month __m;
- chrono::day __d;
-public:
- year_month_day() = default;
- inline constexpr year_month_day(
- const chrono::year& __yval, const chrono::month& __mval, const chrono::day& __dval) noexcept
- : __y{__yval}, __m{__mval}, __d{__dval} {}
- constexpr year_month_day(const year_month_day_last& __ymdl) noexcept;
- inline constexpr year_month_day(const sys_days& __sysd) noexcept
- : year_month_day(__from_days(__sysd.time_since_epoch())) {}
- inline explicit constexpr year_month_day(const local_days& __locd) noexcept
- : year_month_day(__from_days(__locd.time_since_epoch())) {}
-
- constexpr year_month_day& operator+=(const months& __dm) noexcept;
- constexpr year_month_day& operator-=(const months& __dm) noexcept;
- constexpr year_month_day& operator+=(const years& __dy) noexcept;
- constexpr year_month_day& operator-=(const years& __dy) noexcept;
-
- inline constexpr chrono::year year() const noexcept { return __y; }
- inline constexpr chrono::month month() const noexcept { return __m; }
- inline constexpr chrono::day day() const noexcept { return __d; }
- inline constexpr operator sys_days() const noexcept { return sys_days{__to_days()}; }
- inline explicit constexpr operator local_days() const noexcept { return local_days{__to_days()}; }
-
- constexpr bool ok() const noexcept;
-
- static constexpr year_month_day __from_days(days __d) noexcept;
- constexpr days __to_days() const noexcept;
-};
-
-
-// https://howardhinnant.github.io/date_algorithms.html#civil_from_days
-inline constexpr
-year_month_day
-year_month_day::__from_days(days __d) noexcept
-{
- static_assert(numeric_limits<unsigned>::digits >= 18, "");
- static_assert(numeric_limits<int>::digits >= 20 , "");
- const int __z = __d.count() + 719468;
- const int __era = (__z >= 0 ? __z : __z - 146096) / 146097;
- const unsigned __doe = static_cast<unsigned>(__z - __era * 146097); // [0, 146096]
- const unsigned __yoe = (__doe - __doe/1460 + __doe/36524 - __doe/146096) / 365; // [0, 399]
- const int __yr = static_cast<int>(__yoe) + __era * 400;
- const unsigned __doy = __doe - (365 * __yoe + __yoe/4 - __yoe/100); // [0, 365]
- const unsigned __mp = (5 * __doy + 2)/153; // [0, 11]
- const unsigned __dy = __doy - (153 * __mp + 2)/5 + 1; // [1, 31]
- const unsigned __mth = __mp + (__mp < 10 ? 3 : -9); // [1, 12]
- return year_month_day{chrono::year{__yr + (__mth <= 2)}, chrono::month{__mth}, chrono::day{__dy}};
-}
-
-// https://howardhinnant.github.io/date_algorithms.html#days_from_civil
-inline constexpr days year_month_day::__to_days() const noexcept
-{
- static_assert(numeric_limits<unsigned>::digits >= 18, "");
- static_assert(numeric_limits<int>::digits >= 20 , "");
-
- const int __yr = static_cast<int>(__y) - (__m <= February);
- const unsigned __mth = static_cast<unsigned>(__m);
- const unsigned __dy = static_cast<unsigned>(__d);
-
- const int __era = (__yr >= 0 ? __yr : __yr - 399) / 400;
- const unsigned __yoe = static_cast<unsigned>(__yr - __era * 400); // [0, 399]
- const unsigned __doy = (153 * (__mth + (__mth > 2 ? -3 : 9)) + 2) / 5 + __dy-1; // [0, 365]
- const unsigned __doe = __yoe * 365 + __yoe/4 - __yoe/100 + __doy; // [0, 146096]
- return days{__era * 146097 + static_cast<int>(__doe) - 719468};
-}
-
-inline constexpr
-bool operator==(const year_month_day& __lhs, const year_month_day& __rhs) noexcept
-{ return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month() && __lhs.day() == __rhs.day(); }
-
-inline constexpr
-bool operator!=(const year_month_day& __lhs, const year_month_day& __rhs) noexcept
-{ return !(__lhs == __rhs); }
-
-inline constexpr
-bool operator< (const year_month_day& __lhs, const year_month_day& __rhs) noexcept
-{
- if (__lhs.year() < __rhs.year()) return true;
- if (__lhs.year() > __rhs.year()) return false;
- if (__lhs.month() < __rhs.month()) return true;
- if (__lhs.month() > __rhs.month()) return false;
- return __lhs.day() < __rhs.day();
-}
-
-inline constexpr
-bool operator> (const year_month_day& __lhs, const year_month_day& __rhs) noexcept
-{ return __rhs < __lhs; }
-
-inline constexpr
-bool operator<=(const year_month_day& __lhs, const year_month_day& __rhs) noexcept
-{ return !(__rhs < __lhs);}
-
-inline constexpr
-bool operator>=(const year_month_day& __lhs, const year_month_day& __rhs) noexcept
-{ return !(__lhs < __rhs); }
-
-inline constexpr
-year_month_day operator/(const year_month& __lhs, const day& __rhs) noexcept
-{ return year_month_day{__lhs.year(), __lhs.month(), __rhs}; }
-
-inline constexpr
-year_month_day operator/(const year_month& __lhs, int __rhs) noexcept
-{ return __lhs / day(__rhs); }
-
-inline constexpr
-year_month_day operator/(const year& __lhs, const month_day& __rhs) noexcept
-{ return __lhs / __rhs.month() / __rhs.day(); }
-
-inline constexpr
-year_month_day operator/(int __lhs, const month_day& __rhs) noexcept
-{ return year(__lhs) / __rhs; }
-
-inline constexpr
-year_month_day operator/(const month_day& __lhs, const year& __rhs) noexcept
-{ return __rhs / __lhs; }
-
-inline constexpr
-year_month_day operator/(const month_day& __lhs, int __rhs) noexcept
-{ return year(__rhs) / __lhs; }
-
-
-inline constexpr
-year_month_day operator+(const year_month_day& __lhs, const months& __rhs) noexcept
-{ return (__lhs.year()/__lhs.month() + __rhs)/__lhs.day(); }
-
-inline constexpr
-year_month_day operator+(const months& __lhs, const year_month_day& __rhs) noexcept
-{ return __rhs + __lhs; }
-
-inline constexpr
-year_month_day operator-(const year_month_day& __lhs, const months& __rhs) noexcept
-{ return __lhs + -__rhs; }
-
-inline constexpr
-year_month_day operator+(const year_month_day& __lhs, const years& __rhs) noexcept
-{ return (__lhs.year() + __rhs) / __lhs.month() / __lhs.day(); }
-
-inline constexpr
-year_month_day operator+(const years& __lhs, const year_month_day& __rhs) noexcept
-{ return __rhs + __lhs; }
-
-inline constexpr
-year_month_day operator-(const year_month_day& __lhs, const years& __rhs) noexcept
-{ return __lhs + -__rhs; }
-
-inline constexpr year_month_day& year_month_day::operator+=(const months& __dm) noexcept { *this = *this + __dm; return *this; }
-inline constexpr year_month_day& year_month_day::operator-=(const months& __dm) noexcept { *this = *this - __dm; return *this; }
-inline constexpr year_month_day& year_month_day::operator+=(const years& __dy) noexcept { *this = *this + __dy; return *this; }
-inline constexpr year_month_day& year_month_day::operator-=(const years& __dy) noexcept { *this = *this - __dy; return *this; }
-
-class year_month_day_last {
-private:
- chrono::year __y;
- chrono::month_day_last __mdl;
-public:
- constexpr year_month_day_last(const year& __yval, const month_day_last& __mdlval) noexcept
- : __y{__yval}, __mdl{__mdlval} {}
-
- constexpr year_month_day_last& operator+=(const months& __m) noexcept;
- constexpr year_month_day_last& operator-=(const months& __m) noexcept;
- constexpr year_month_day_last& operator+=(const years& __y) noexcept;
- constexpr year_month_day_last& operator-=(const years& __y) noexcept;
-
- inline constexpr chrono::year year() const noexcept { return __y; }
- inline constexpr chrono::month month() const noexcept { return __mdl.month(); }
- inline constexpr chrono::month_day_last month_day_last() const noexcept { return __mdl; }
- constexpr chrono::day day() const noexcept;
- inline constexpr operator sys_days() const noexcept { return sys_days{year()/month()/day()}; }
- inline explicit constexpr operator local_days() const noexcept { return local_days{year()/month()/day()}; }
- inline constexpr bool ok() const noexcept { return __y.ok() && __mdl.ok(); }
-};
-
-inline constexpr
-chrono::day year_month_day_last::day() const noexcept
-{
- constexpr chrono::day __d[] =
- {
- chrono::day(31), chrono::day(28), chrono::day(31),
- chrono::day(30), chrono::day(31), chrono::day(30),
- chrono::day(31), chrono::day(31), chrono::day(30),
- chrono::day(31), chrono::day(30), chrono::day(31)
- };
- return (month() != February || !__y.is_leap()) && month().ok() ?
- __d[static_cast<unsigned>(month()) - 1] : chrono::day{29};
-}
-
-inline constexpr
-bool operator==(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept
-{ return __lhs.year() == __rhs.year() && __lhs.month_day_last() == __rhs.month_day_last(); }
-
-inline constexpr
-bool operator!=(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept
-{ return !(__lhs == __rhs); }
-
-inline constexpr
-bool operator< (const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept
-{
- if (__lhs.year() < __rhs.year()) return true;
- if (__lhs.year() > __rhs.year()) return false;
- return __lhs.month_day_last() < __rhs.month_day_last();
-}
-
-inline constexpr
-bool operator> (const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept
-{ return __rhs < __lhs; }
-
-inline constexpr
-bool operator<=(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept
-{ return !(__rhs < __lhs);}
-
-inline constexpr
-bool operator>=(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept
-{ return !(__lhs < __rhs); }
-
-inline constexpr year_month_day_last operator/(const year_month& __lhs, last_spec) noexcept
-{ return year_month_day_last{__lhs.year(), month_day_last{__lhs.month()}}; }
-
-inline constexpr year_month_day_last operator/(const year& __lhs, const month_day_last& __rhs) noexcept
-{ return year_month_day_last{__lhs, __rhs}; }
-
-inline constexpr year_month_day_last operator/(int __lhs, const month_day_last& __rhs) noexcept
-{ return year_month_day_last{year{__lhs}, __rhs}; }
-
-inline constexpr year_month_day_last operator/(const month_day_last& __lhs, const year& __rhs) noexcept
-{ return __rhs / __lhs; }
-
-inline constexpr year_month_day_last operator/(const month_day_last& __lhs, int __rhs) noexcept
-{ return year{__rhs} / __lhs; }
-
-
-inline constexpr
-year_month_day_last operator+(const year_month_day_last& __lhs, const months& __rhs) noexcept
-{ return (__lhs.year() / __lhs.month() + __rhs) / last; }
-
-inline constexpr
-year_month_day_last operator+(const months& __lhs, const year_month_day_last& __rhs) noexcept
-{ return __rhs + __lhs; }
-
-inline constexpr
-year_month_day_last operator-(const year_month_day_last& __lhs, const months& __rhs) noexcept
-{ return __lhs + (-__rhs); }
-
-inline constexpr
-year_month_day_last operator+(const year_month_day_last& __lhs, const years& __rhs) noexcept
-{ return year_month_day_last{__lhs.year() + __rhs, __lhs.month_day_last()}; }
-
-inline constexpr
-year_month_day_last operator+(const years& __lhs, const year_month_day_last& __rhs) noexcept
-{ return __rhs + __lhs; }
-
-inline constexpr
-year_month_day_last operator-(const year_month_day_last& __lhs, const years& __rhs) noexcept
-{ return __lhs + (-__rhs); }
-
-inline constexpr year_month_day_last& year_month_day_last::operator+=(const months& __dm) noexcept { *this = *this + __dm; return *this; }
-inline constexpr year_month_day_last& year_month_day_last::operator-=(const months& __dm) noexcept { *this = *this - __dm; return *this; }
-inline constexpr year_month_day_last& year_month_day_last::operator+=(const years& __dy) noexcept { *this = *this + __dy; return *this; }
-inline constexpr year_month_day_last& year_month_day_last::operator-=(const years& __dy) noexcept { *this = *this - __dy; return *this; }
-
-inline constexpr year_month_day::year_month_day(const year_month_day_last& __ymdl) noexcept
- : __y{__ymdl.year()}, __m{__ymdl.month()}, __d{__ymdl.day()} {}
-
-inline constexpr bool year_month_day::ok() const noexcept
-{
- if (!__y.ok() || !__m.ok()) return false;
- return chrono::day{1} <= __d && __d <= (__y / __m / last).day();
-}
-
-class year_month_weekday {
- chrono::year __y;
- chrono::month __m;
- chrono::weekday_indexed __wdi;
-public:
- year_month_weekday() = default;
- constexpr year_month_weekday(const chrono::year& __yval, const chrono::month& __mval,
- const chrono::weekday_indexed& __wdival) noexcept
- : __y{__yval}, __m{__mval}, __wdi{__wdival} {}
- constexpr year_month_weekday(const sys_days& __sysd) noexcept
- : year_month_weekday(__from_days(__sysd.time_since_epoch())) {}
- inline explicit constexpr year_month_weekday(const local_days& __locd) noexcept
- : year_month_weekday(__from_days(__locd.time_since_epoch())) {}
- constexpr year_month_weekday& operator+=(const months& m) noexcept;
- constexpr year_month_weekday& operator-=(const months& m) noexcept;
- constexpr year_month_weekday& operator+=(const years& y) noexcept;
- constexpr year_month_weekday& operator-=(const years& y) noexcept;
-
- inline constexpr chrono::year year() const noexcept { return __y; }
- inline constexpr chrono::month month() const noexcept { return __m; }
- inline constexpr chrono::weekday weekday() const noexcept { return __wdi.weekday(); }
- inline constexpr unsigned index() const noexcept { return __wdi.index(); }
- inline constexpr chrono::weekday_indexed weekday_indexed() const noexcept { return __wdi; }
-
- inline constexpr operator sys_days() const noexcept { return sys_days{__to_days()}; }
- inline explicit constexpr operator local_days() const noexcept { return local_days{__to_days()}; }
- inline constexpr bool ok() const noexcept
- {
- if (!__y.ok() || !__m.ok() || !__wdi.ok()) return false;
- if (__wdi.index() <= 4) return true;
- auto __nth_weekday_day =
- __wdi.weekday() -
- chrono::weekday{static_cast<sys_days>(__y / __m / 1)} +
- days{(__wdi.index() - 1) * 7 + 1};
- return static_cast<unsigned>(__nth_weekday_day.count()) <=
- static_cast<unsigned>((__y / __m / last).day());
- }
-
- static constexpr year_month_weekday __from_days(days __d) noexcept;
- constexpr days __to_days() const noexcept;
-};
-
-inline constexpr
-year_month_weekday year_month_weekday::__from_days(days __d) noexcept
-{
- const sys_days __sysd{__d};
- const chrono::weekday __wd = chrono::weekday(__sysd);
- const year_month_day __ymd = year_month_day(__sysd);
- return year_month_weekday{__ymd.year(), __ymd.month(),
- __wd[(static_cast<unsigned>(__ymd.day())-1)/7+1]};
-}
-
-inline constexpr
-days year_month_weekday::__to_days() const noexcept
-{
- const sys_days __sysd = sys_days(__y/__m/1);
- return (__sysd + (__wdi.weekday() - chrono::weekday(__sysd) + days{(__wdi.index()-1)*7}))
- .time_since_epoch();
-}
-
-inline constexpr
-bool operator==(const year_month_weekday& __lhs, const year_month_weekday& __rhs) noexcept
-{ return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month() && __lhs.weekday_indexed() == __rhs.weekday_indexed(); }
-
-inline constexpr
-bool operator!=(const year_month_weekday& __lhs, const year_month_weekday& __rhs) noexcept
-{ return !(__lhs == __rhs); }
-
-inline constexpr
-year_month_weekday operator/(const year_month& __lhs, const weekday_indexed& __rhs) noexcept
-{ return year_month_weekday{__lhs.year(), __lhs.month(), __rhs}; }
-
-inline constexpr
-year_month_weekday operator/(const year& __lhs, const month_weekday& __rhs) noexcept
-{ return year_month_weekday{__lhs, __rhs.month(), __rhs.weekday_indexed()}; }
-
-inline constexpr
-year_month_weekday operator/(int __lhs, const month_weekday& __rhs) noexcept
-{ return year(__lhs) / __rhs; }
-
-inline constexpr
-year_month_weekday operator/(const month_weekday& __lhs, const year& __rhs) noexcept
-{ return __rhs / __lhs; }
-
-inline constexpr
-year_month_weekday operator/(const month_weekday& __lhs, int __rhs) noexcept
-{ return year(__rhs) / __lhs; }
-
-
-inline constexpr
-year_month_weekday operator+(const year_month_weekday& __lhs, const months& __rhs) noexcept
-{ return (__lhs.year() / __lhs.month() + __rhs) / __lhs.weekday_indexed(); }
-
-inline constexpr
-year_month_weekday operator+(const months& __lhs, const year_month_weekday& __rhs) noexcept
-{ return __rhs + __lhs; }
-
-inline constexpr
-year_month_weekday operator-(const year_month_weekday& __lhs, const months& __rhs) noexcept
-{ return __lhs + (-__rhs); }
-
-inline constexpr
-year_month_weekday operator+(const year_month_weekday& __lhs, const years& __rhs) noexcept
-{ return year_month_weekday{__lhs.year() + __rhs, __lhs.month(), __lhs.weekday_indexed()}; }
-
-inline constexpr
-year_month_weekday operator+(const years& __lhs, const year_month_weekday& __rhs) noexcept
-{ return __rhs + __lhs; }
-
-inline constexpr
-year_month_weekday operator-(const year_month_weekday& __lhs, const years& __rhs) noexcept
-{ return __lhs + (-__rhs); }
-
-
-inline constexpr year_month_weekday& year_month_weekday::operator+=(const months& __dm) noexcept { *this = *this + __dm; return *this; }
-inline constexpr year_month_weekday& year_month_weekday::operator-=(const months& __dm) noexcept { *this = *this - __dm; return *this; }
-inline constexpr year_month_weekday& year_month_weekday::operator+=(const years& __dy) noexcept { *this = *this + __dy; return *this; }
-inline constexpr year_month_weekday& year_month_weekday::operator-=(const years& __dy) noexcept { *this = *this - __dy; return *this; }
-
-class year_month_weekday_last {
-private:
- chrono::year __y;
- chrono::month __m;
- chrono::weekday_last __wdl;
-public:
- constexpr year_month_weekday_last(const chrono::year& __yval, const chrono::month& __mval,
- const chrono::weekday_last& __wdlval) noexcept
- : __y{__yval}, __m{__mval}, __wdl{__wdlval} {}
- constexpr year_month_weekday_last& operator+=(const months& __dm) noexcept;
- constexpr year_month_weekday_last& operator-=(const months& __dm) noexcept;
- constexpr year_month_weekday_last& operator+=(const years& __dy) noexcept;
- constexpr year_month_weekday_last& operator-=(const years& __dy) noexcept;
-
- inline constexpr chrono::year year() const noexcept { return __y; }
- inline constexpr chrono::month month() const noexcept { return __m; }
- inline constexpr chrono::weekday weekday() const noexcept { return __wdl.weekday(); }
- inline constexpr chrono::weekday_last weekday_last() const noexcept { return __wdl; }
- inline constexpr operator sys_days() const noexcept { return sys_days{__to_days()}; }
- inline explicit constexpr operator local_days() const noexcept { return local_days{__to_days()}; }
- inline constexpr bool ok() const noexcept { return __y.ok() && __m.ok() && __wdl.ok(); }
-
- constexpr days __to_days() const noexcept;
-
-};
-
-inline constexpr
-days year_month_weekday_last::__to_days() const noexcept
-{
- const sys_days __last = sys_days{__y/__m/last};
- return (__last - (chrono::weekday{__last} - __wdl.weekday())).time_since_epoch();
-
-}
-
-inline constexpr
-bool operator==(const year_month_weekday_last& __lhs, const year_month_weekday_last& __rhs) noexcept
-{ return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month() && __lhs.weekday_last() == __rhs.weekday_last(); }
-
-inline constexpr
-bool operator!=(const year_month_weekday_last& __lhs, const year_month_weekday_last& __rhs) noexcept
-{ return !(__lhs == __rhs); }
-
-
-inline constexpr
-year_month_weekday_last operator/(const year_month& __lhs, const weekday_last& __rhs) noexcept
-{ return year_month_weekday_last{__lhs.year(), __lhs.month(), __rhs}; }
-
-inline constexpr
-year_month_weekday_last operator/(const year& __lhs, const month_weekday_last& __rhs) noexcept
-{ return year_month_weekday_last{__lhs, __rhs.month(), __rhs.weekday_last()}; }
-
-inline constexpr
-year_month_weekday_last operator/(int __lhs, const month_weekday_last& __rhs) noexcept
-{ return year(__lhs) / __rhs; }
-
-inline constexpr
-year_month_weekday_last operator/(const month_weekday_last& __lhs, const year& __rhs) noexcept
-{ return __rhs / __lhs; }
-
-inline constexpr
-year_month_weekday_last operator/(const month_weekday_last& __lhs, int __rhs) noexcept
-{ return year(__rhs) / __lhs; }
-
-
-inline constexpr
-year_month_weekday_last operator+(const year_month_weekday_last& __lhs, const months& __rhs) noexcept
-{ return (__lhs.year() / __lhs.month() + __rhs) / __lhs.weekday_last(); }
-
-inline constexpr
-year_month_weekday_last operator+(const months& __lhs, const year_month_weekday_last& __rhs) noexcept
-{ return __rhs + __lhs; }
-
-inline constexpr
-year_month_weekday_last operator-(const year_month_weekday_last& __lhs, const months& __rhs) noexcept
-{ return __lhs + (-__rhs); }
-
-inline constexpr
-year_month_weekday_last operator+(const year_month_weekday_last& __lhs, const years& __rhs) noexcept
-{ return year_month_weekday_last{__lhs.year() + __rhs, __lhs.month(), __lhs.weekday_last()}; }
-
-inline constexpr
-year_month_weekday_last operator+(const years& __lhs, const year_month_weekday_last& __rhs) noexcept
-{ return __rhs + __lhs; }
-
-inline constexpr
-year_month_weekday_last operator-(const year_month_weekday_last& __lhs, const years& __rhs) noexcept
-{ return __lhs + (-__rhs); }
-
-inline constexpr year_month_weekday_last& year_month_weekday_last::operator+=(const months& __dm) noexcept { *this = *this + __dm; return *this; }
-inline constexpr year_month_weekday_last& year_month_weekday_last::operator-=(const months& __dm) noexcept { *this = *this - __dm; return *this; }
-inline constexpr year_month_weekday_last& year_month_weekday_last::operator+=(const years& __dy) noexcept { *this = *this + __dy; return *this; }
-inline constexpr year_month_weekday_last& year_month_weekday_last::operator-=(const years& __dy) noexcept { *this = *this - __dy; return *this; }
-
-
-template <class _Duration>
-class hh_mm_ss
-{
-private:
- static_assert(__is_duration<_Duration>::value, "template parameter of hh_mm_ss must be a std::chrono::duration");
- using __CommonType = common_type_t<_Duration, chrono::seconds>;
-
- static constexpr uint64_t __pow10(unsigned __exp)
- {
- uint64_t __ret = 1;
- for (unsigned __i = 0; __i < __exp; ++__i)
- __ret *= 10U;
- return __ret;
- }
-
- static constexpr unsigned __width(uint64_t __n, uint64_t __d = 10, unsigned __w = 0)
- {
- if (__n >= 2 && __d != 0 && __w < 19)
- return 1 + __width(__n, __d % __n * 10, __w+1);
- return 0;
- }
-
-public:
- static unsigned constexpr fractional_width = __width(__CommonType::period::den) < 19 ?
- __width(__CommonType::period::den) : 6u;
- using precision = duration<typename __CommonType::rep, ratio<1, __pow10(fractional_width)>>;
-
- constexpr hh_mm_ss() noexcept : hh_mm_ss{_Duration::zero()} {}
-
- constexpr explicit hh_mm_ss(_Duration __d) noexcept :
- __is_neg(__d < _Duration(0)),
- __h(duration_cast<chrono::hours> (abs(__d))),
- __m(duration_cast<chrono::minutes>(abs(__d) - hours())),
- __s(duration_cast<chrono::seconds>(abs(__d) - hours() - minutes())),
- __f(duration_cast<precision> (abs(__d) - hours() - minutes() - seconds()))
- {}
-
- constexpr bool is_negative() const noexcept { return __is_neg; }
- constexpr chrono::hours hours() const noexcept { return __h; }
- constexpr chrono::minutes minutes() const noexcept { return __m; }
- constexpr chrono::seconds seconds() const noexcept { return __s; }
- constexpr precision subseconds() const noexcept { return __f; }
-
- constexpr precision to_duration() const noexcept
- {
- auto __dur = __h + __m + __s + __f;
- return __is_neg ? -__dur : __dur;
- }
-
- constexpr explicit operator precision() const noexcept { return to_duration(); }
-
-private:
- bool __is_neg;
- chrono::hours __h;
- chrono::minutes __m;
- chrono::seconds __s;
- precision __f;
-};
-
-constexpr bool is_am(const hours& __h) noexcept { return __h >= hours( 0) && __h < hours(12); }
-constexpr bool is_pm(const hours& __h) noexcept { return __h >= hours(12) && __h < hours(24); }
-
-constexpr hours make12(const hours& __h) noexcept
-{
- if (__h == hours( 0)) return hours(12);
- else if (__h <= hours(12)) return __h;
- else return __h - hours(12);
-}
-
-constexpr hours make24(const hours& __h, bool __is_pm) noexcept
-{
- if (__is_pm)
- return __h == hours(12) ? __h : __h + hours(12);
- else
- return __h == hours(12) ? hours(0) : __h;
-}
-
-} // namespace chrono
-
-inline namespace literals
-{
- inline namespace chrono_literals
- {
- constexpr chrono::day operator ""d(unsigned long long __d) noexcept
- {
- return chrono::day(static_cast<unsigned>(__d));
- }
-
- constexpr chrono::year operator ""y(unsigned long long __y) noexcept
- {
- return chrono::year(static_cast<int>(__y));
- }
-} // namespace chrono_literals
-} // namespace literals
-
-namespace chrono { // hoist the literals into namespace std::chrono
- using namespace literals::chrono_literals;
} // namespace chrono
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_STD_VER > 17
-_LIBCPP_POP_MACROS
-
#endif // _LIBCPP___CHRONO_CALENDAR_H
diff --git a/libcxx/include/__chrono/convert_to_timespec.h b/libcxx/include/__chrono/convert_to_timespec.h
index 0106e6dec3e1..e8631d135fee 100644
--- a/libcxx/include/__chrono/convert_to_timespec.h
+++ b/libcxx/include/__chrono/convert_to_timespec.h
@@ -14,7 +14,7 @@
#include <limits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
diff --git a/libcxx/include/__chrono/day.h b/libcxx/include/__chrono/day.h
new file mode 100644
index 000000000000..7e425558e359
--- /dev/null
+++ b/libcxx/include/__chrono/day.h
@@ -0,0 +1,99 @@
+// -*- 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___CHRONO_DAY_H
+#define _LIBCPP___CHRONO_DAY_H
+
+#include <__chrono/duration.h>
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace chrono
+{
+
+class day {
+private:
+ unsigned char __d;
+public:
+ _LIBCPP_HIDE_FROM_ABI day() = default;
+ _LIBCPP_HIDE_FROM_ABI explicit inline constexpr day(unsigned __val) noexcept : __d(static_cast<unsigned char>(__val)) {}
+ _LIBCPP_HIDE_FROM_ABI inline constexpr day& operator++() noexcept { ++__d; return *this; }
+ _LIBCPP_HIDE_FROM_ABI inline constexpr day operator++(int) noexcept { day __tmp = *this; ++(*this); return __tmp; }
+ _LIBCPP_HIDE_FROM_ABI inline constexpr day& operator--() noexcept { --__d; return *this; }
+ _LIBCPP_HIDE_FROM_ABI inline constexpr day operator--(int) noexcept { day __tmp = *this; --(*this); return __tmp; }
+ _LIBCPP_HIDE_FROM_ABI constexpr day& operator+=(const days& __dd) noexcept;
+ _LIBCPP_HIDE_FROM_ABI constexpr day& operator-=(const days& __dd) noexcept;
+ _LIBCPP_HIDE_FROM_ABI explicit inline constexpr operator unsigned() const noexcept { return __d; }
+ _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __d >= 1 && __d <= 31; }
+ };
+
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+bool operator==(const day& __lhs, const day& __rhs) noexcept
+{ return static_cast<unsigned>(__lhs) == static_cast<unsigned>(__rhs); }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+bool operator!=(const day& __lhs, const day& __rhs) noexcept
+{ return !(__lhs == __rhs); }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+bool operator< (const day& __lhs, const day& __rhs) noexcept
+{ return static_cast<unsigned>(__lhs) < static_cast<unsigned>(__rhs); }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+bool operator> (const day& __lhs, const day& __rhs) noexcept
+{ return __rhs < __lhs; }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+bool operator<=(const day& __lhs, const day& __rhs) noexcept
+{ return !(__rhs < __lhs);}
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+bool operator>=(const day& __lhs, const day& __rhs) noexcept
+{ return !(__lhs < __rhs); }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+day operator+ (const day& __lhs, const days& __rhs) noexcept
+{ return day(static_cast<unsigned>(__lhs) + __rhs.count()); }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+day operator+ (const days& __lhs, const day& __rhs) noexcept
+{ return __rhs + __lhs; }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+day operator- (const day& __lhs, const days& __rhs) noexcept
+{ return __lhs + -__rhs; }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+days operator-(const day& __lhs, const day& __rhs) noexcept
+{ return days(static_cast<int>(static_cast<unsigned>(__lhs)) -
+ static_cast<int>(static_cast<unsigned>(__rhs))); }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+day& day::operator+=(const days& __dd) noexcept
+{ *this = *this + __dd; return *this; }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+day& day::operator-=(const days& __dd) noexcept
+{ *this = *this - __dd; return *this; }
+
+} // namespace chrono
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17
+
+#endif // _LIBCPP___CHRONO_DAY_H
diff --git a/libcxx/include/__chrono/duration.h b/libcxx/include/__chrono/duration.h
index 24801772ec5d..f5207594291e 100644
--- a/libcxx/include/__chrono/duration.h
+++ b/libcxx/include/__chrono/duration.h
@@ -16,7 +16,7 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
@@ -251,7 +251,7 @@ public:
explicit duration(const _Rep2& __r,
typename enable_if
<
- is_convertible<_Rep2, rep>::value &&
+ is_convertible<const _Rep2&, rep>::value &&
(treat_as_floating_point<rep>::value ||
!treat_as_floating_point<_Rep2>::value)
>::type* = nullptr)
diff --git a/libcxx/include/__chrono/file_clock.h b/libcxx/include/__chrono/file_clock.h
index cd8758f81908..b8e08e78ba72 100644
--- a/libcxx/include/__chrono/file_clock.h
+++ b/libcxx/include/__chrono/file_clock.h
@@ -18,7 +18,7 @@
#include <ratio>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
#ifndef _LIBCPP_CXX03_LANG
diff --git a/libcxx/include/__chrono/hh_mm_ss.h b/libcxx/include/__chrono/hh_mm_ss.h
new file mode 100644
index 000000000000..6b3c5c09e68e
--- /dev/null
+++ b/libcxx/include/__chrono/hh_mm_ss.h
@@ -0,0 +1,112 @@
+// -*- 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___CHRONO_HH_MM_SS_H
+#define _LIBCPP___CHRONO_HH_MM_SS_H
+
+#include <__chrono/duration.h>
+#include <__chrono/time_point.h>
+#include <__config>
+#include <ratio>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace chrono
+{
+
+template <class _Duration>
+class hh_mm_ss
+{
+private:
+ static_assert(__is_duration<_Duration>::value, "template parameter of hh_mm_ss must be a std::chrono::duration");
+ using __CommonType = common_type_t<_Duration, chrono::seconds>;
+
+ _LIBCPP_HIDE_FROM_ABI static constexpr uint64_t __pow10(unsigned __exp)
+ {
+ uint64_t __ret = 1;
+ for (unsigned __i = 0; __i < __exp; ++__i)
+ __ret *= 10U;
+ return __ret;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI static constexpr unsigned __width(uint64_t __n, uint64_t __d = 10, unsigned __w = 0)
+ {
+ if (__n >= 2 && __d != 0 && __w < 19)
+ return 1 + __width(__n, __d % __n * 10, __w+1);
+ return 0;
+ }
+
+public:
+ _LIBCPP_HIDE_FROM_ABI static unsigned constexpr fractional_width = __width(__CommonType::period::den) < 19 ?
+ __width(__CommonType::period::den) : 6u;
+ using precision = duration<typename __CommonType::rep, ratio<1, __pow10(fractional_width)>>;
+
+ _LIBCPP_HIDE_FROM_ABI constexpr hh_mm_ss() noexcept : hh_mm_ss{_Duration::zero()} {}
+
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit hh_mm_ss(_Duration __d) noexcept :
+ __is_neg(__d < _Duration(0)),
+ __h(duration_cast<chrono::hours> (abs(__d))),
+ __m(duration_cast<chrono::minutes>(abs(__d) - hours())),
+ __s(duration_cast<chrono::seconds>(abs(__d) - hours() - minutes())),
+ __f(duration_cast<precision> (abs(__d) - hours() - minutes() - seconds()))
+ {}
+
+ _LIBCPP_HIDE_FROM_ABI constexpr bool is_negative() const noexcept { return __is_neg; }
+ _LIBCPP_HIDE_FROM_ABI constexpr chrono::hours hours() const noexcept { return __h; }
+ _LIBCPP_HIDE_FROM_ABI constexpr chrono::minutes minutes() const noexcept { return __m; }
+ _LIBCPP_HIDE_FROM_ABI constexpr chrono::seconds seconds() const noexcept { return __s; }
+ _LIBCPP_HIDE_FROM_ABI constexpr precision subseconds() const noexcept { return __f; }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr precision to_duration() const noexcept
+ {
+ auto __dur = __h + __m + __s + __f;
+ return __is_neg ? -__dur : __dur;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit operator precision() const noexcept { return to_duration(); }
+
+private:
+ bool __is_neg;
+ chrono::hours __h;
+ chrono::minutes __m;
+ chrono::seconds __s;
+ precision __f;
+};
+
+_LIBCPP_HIDE_FROM_ABI constexpr bool is_am(const hours& __h) noexcept { return __h >= hours( 0) && __h < hours(12); }
+_LIBCPP_HIDE_FROM_ABI constexpr bool is_pm(const hours& __h) noexcept { return __h >= hours(12) && __h < hours(24); }
+
+_LIBCPP_HIDE_FROM_ABI constexpr hours make12(const hours& __h) noexcept
+{
+ if (__h == hours( 0)) return hours(12);
+ else if (__h <= hours(12)) return __h;
+ else return __h - hours(12);
+}
+
+_LIBCPP_HIDE_FROM_ABI constexpr hours make24(const hours& __h, bool __is_pm) noexcept
+{
+ if (__is_pm)
+ return __h == hours(12) ? __h : __h + hours(12);
+ else
+ return __h == hours(12) ? hours(0) : __h;
+}
+} // namespace chrono
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17
+
+#endif // _LIBCPP___CHRONO_HH_MM_SS_H
diff --git a/libcxx/include/__chrono/high_resolution_clock.h b/libcxx/include/__chrono/high_resolution_clock.h
index f5cde4acb979..778ff44f3d09 100644
--- a/libcxx/include/__chrono/high_resolution_clock.h
+++ b/libcxx/include/__chrono/high_resolution_clock.h
@@ -15,7 +15,7 @@
#include <__config>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__chrono/literals.h b/libcxx/include/__chrono/literals.h
new file mode 100644
index 000000000000..50529bd44ad1
--- /dev/null
+++ b/libcxx/include/__chrono/literals.h
@@ -0,0 +1,49 @@
+// -*- 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___CHRONO_LITERALS_H
+#define _LIBCPP___CHRONO_LITERALS_H
+
+#include <__chrono/day.h>
+#include <__chrono/year.h>
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+inline namespace literals
+{
+ inline namespace chrono_literals
+ {
+ _LIBCPP_HIDE_FROM_ABI constexpr chrono::day operator ""d(unsigned long long __d) noexcept
+ {
+ return chrono::day(static_cast<unsigned>(__d));
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr chrono::year operator ""y(unsigned long long __y) noexcept
+ {
+ return chrono::year(static_cast<int>(__y));
+ }
+} // namespace chrono_literals
+} // namespace literals
+
+namespace chrono { // hoist the literals into namespace std::chrono
+ using namespace literals::chrono_literals;
+} // namespace chrono
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17
+
+#endif // _LIBCPP___CHRONO_LITERALS_H
diff --git a/libcxx/include/__chrono/month.h b/libcxx/include/__chrono/month.h
new file mode 100644
index 000000000000..5aeb5b397182
--- /dev/null
+++ b/libcxx/include/__chrono/month.h
@@ -0,0 +1,118 @@
+// -*- 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___CHRONO_MONTH_H
+#define _LIBCPP___CHRONO_MONTH_H
+
+#include <__chrono/duration.h>
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace chrono
+{
+
+class month {
+private:
+ unsigned char __m;
+public:
+ _LIBCPP_HIDE_FROM_ABI month() = default;
+ _LIBCPP_HIDE_FROM_ABI explicit inline constexpr month(unsigned __val) noexcept : __m(static_cast<unsigned char>(__val)) {}
+ _LIBCPP_HIDE_FROM_ABI inline constexpr month& operator++() noexcept { ++__m; return *this; }
+ _LIBCPP_HIDE_FROM_ABI inline constexpr month operator++(int) noexcept { month __tmp = *this; ++(*this); return __tmp; }
+ _LIBCPP_HIDE_FROM_ABI inline constexpr month& operator--() noexcept { --__m; return *this; }
+ _LIBCPP_HIDE_FROM_ABI inline constexpr month operator--(int) noexcept { month __tmp = *this; --(*this); return __tmp; }
+ _LIBCPP_HIDE_FROM_ABI constexpr month& operator+=(const months& __m1) noexcept;
+ _LIBCPP_HIDE_FROM_ABI constexpr month& operator-=(const months& __m1) noexcept;
+ _LIBCPP_HIDE_FROM_ABI explicit inline constexpr operator unsigned() const noexcept { return __m; }
+ _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __m >= 1 && __m <= 12; }
+};
+
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+bool operator==(const month& __lhs, const month& __rhs) noexcept
+{ return static_cast<unsigned>(__lhs) == static_cast<unsigned>(__rhs); }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+bool operator!=(const month& __lhs, const month& __rhs) noexcept
+{ return !(__lhs == __rhs); }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+bool operator< (const month& __lhs, const month& __rhs) noexcept
+{ return static_cast<unsigned>(__lhs) < static_cast<unsigned>(__rhs); }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+bool operator> (const month& __lhs, const month& __rhs) noexcept
+{ return __rhs < __lhs; }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+bool operator<=(const month& __lhs, const month& __rhs) noexcept
+{ return !(__rhs < __lhs); }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+bool operator>=(const month& __lhs, const month& __rhs) noexcept
+{ return !(__lhs < __rhs); }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+month operator+ (const month& __lhs, const months& __rhs) noexcept
+{
+ auto const __mu = static_cast<long long>(static_cast<unsigned>(__lhs)) + (__rhs.count() - 1);
+ auto const __yr = (__mu >= 0 ? __mu : __mu - 11) / 12;
+ return month{static_cast<unsigned>(__mu - __yr * 12 + 1)};
+}
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+month operator+ (const months& __lhs, const month& __rhs) noexcept
+{ return __rhs + __lhs; }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+month operator- (const month& __lhs, const months& __rhs) noexcept
+{ return __lhs + -__rhs; }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+months operator-(const month& __lhs, const month& __rhs) noexcept
+{
+ auto const __dm = static_cast<unsigned>(__lhs) - static_cast<unsigned>(__rhs);
+ return months(__dm <= 11 ? __dm : __dm + 12);
+}
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+month& month::operator+=(const months& __dm) noexcept
+{ *this = *this + __dm; return *this; }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+month& month::operator-=(const months& __dm) noexcept
+{ *this = *this - __dm; return *this; }
+
+inline constexpr month January{1};
+inline constexpr month February{2};
+inline constexpr month March{3};
+inline constexpr month April{4};
+inline constexpr month May{5};
+inline constexpr month June{6};
+inline constexpr month July{7};
+inline constexpr month August{8};
+inline constexpr month September{9};
+inline constexpr month October{10};
+inline constexpr month November{11};
+inline constexpr month December{12};
+
+} // namespace chrono
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17
+
+#endif // _LIBCPP___CHRONO_MONTH_H
diff --git a/libcxx/include/__chrono/month_weekday.h b/libcxx/include/__chrono/month_weekday.h
new file mode 100644
index 000000000000..270051397017
--- /dev/null
+++ b/libcxx/include/__chrono/month_weekday.h
@@ -0,0 +1,106 @@
+// -*- 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___CHRONO_MONTH_WEEKDAY_H
+#define _LIBCPP___CHRONO_MONTH_WEEKDAY_H
+
+#include <__chrono/month.h>
+#include <__chrono/weekday.h>
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace chrono
+{
+
+class month_weekday {
+private:
+ chrono::month __m;
+ chrono::weekday_indexed __wdi;
+public:
+ _LIBCPP_HIDE_FROM_ABI constexpr month_weekday(const chrono::month& __mval, const chrono::weekday_indexed& __wdival) noexcept
+ : __m{__mval}, __wdi{__wdival} {}
+ _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __m; }
+ _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::weekday_indexed weekday_indexed() const noexcept { return __wdi; }
+ _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __m.ok() && __wdi.ok(); }
+};
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+bool operator==(const month_weekday& __lhs, const month_weekday& __rhs) noexcept
+{ return __lhs.month() == __rhs.month() && __lhs.weekday_indexed() == __rhs.weekday_indexed(); }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+bool operator!=(const month_weekday& __lhs, const month_weekday& __rhs) noexcept
+{ return !(__lhs == __rhs); }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+month_weekday operator/(const month& __lhs, const weekday_indexed& __rhs) noexcept
+{ return month_weekday{__lhs, __rhs}; }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+month_weekday operator/(int __lhs, const weekday_indexed& __rhs) noexcept
+{ return month_weekday{month(__lhs), __rhs}; }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+month_weekday operator/(const weekday_indexed& __lhs, const month& __rhs) noexcept
+{ return month_weekday{__rhs, __lhs}; }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+month_weekday operator/(const weekday_indexed& __lhs, int __rhs) noexcept
+{ return month_weekday{month(__rhs), __lhs}; }
+
+
+class month_weekday_last {
+ chrono::month __m;
+ chrono::weekday_last __wdl;
+ public:
+ _LIBCPP_HIDE_FROM_ABI constexpr month_weekday_last(const chrono::month& __mval, const chrono::weekday_last& __wdlval) noexcept
+ : __m{__mval}, __wdl{__wdlval} {}
+ _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __m; }
+ _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::weekday_last weekday_last() const noexcept { return __wdl; }
+ _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __m.ok() && __wdl.ok(); }
+};
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+bool operator==(const month_weekday_last& __lhs, const month_weekday_last& __rhs) noexcept
+{ return __lhs.month() == __rhs.month() && __lhs.weekday_last() == __rhs.weekday_last(); }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+bool operator!=(const month_weekday_last& __lhs, const month_weekday_last& __rhs) noexcept
+{ return !(__lhs == __rhs); }
+
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+month_weekday_last operator/(const month& __lhs, const weekday_last& __rhs) noexcept
+{ return month_weekday_last{__lhs, __rhs}; }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+month_weekday_last operator/(int __lhs, const weekday_last& __rhs) noexcept
+{ return month_weekday_last{month(__lhs), __rhs}; }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+month_weekday_last operator/(const weekday_last& __lhs, const month& __rhs) noexcept
+{ return month_weekday_last{__rhs, __lhs}; }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+month_weekday_last operator/(const weekday_last& __lhs, int __rhs) noexcept
+{ return month_weekday_last{month(__rhs), __lhs}; }
+} // namespace chrono
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17
+
+#endif // _LIBCPP___CHRONO_MONTH_WEEKDAY_H
diff --git a/libcxx/include/__chrono/monthday.h b/libcxx/include/__chrono/monthday.h
new file mode 100644
index 000000000000..485f0d4299b5
--- /dev/null
+++ b/libcxx/include/__chrono/monthday.h
@@ -0,0 +1,160 @@
+// -*- 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___CHRONO_MONTHDAY_H
+#define _LIBCPP___CHRONO_MONTHDAY_H
+
+#include <__chrono/calendar.h>
+#include <__chrono/day.h>
+#include <__chrono/month.h>
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace chrono
+{
+
+class month_day {
+private:
+ chrono::month __m;
+ chrono::day __d;
+public:
+ _LIBCPP_HIDE_FROM_ABI month_day() = default;
+ _LIBCPP_HIDE_FROM_ABI constexpr month_day(const chrono::month& __mval, const chrono::day& __dval) noexcept
+ : __m{__mval}, __d{__dval} {}
+ _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __m; }
+ _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::day day() const noexcept { return __d; }
+ _LIBCPP_HIDE_FROM_ABI constexpr bool ok() const noexcept;
+};
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+bool month_day::ok() const noexcept
+{
+ if (!__m.ok()) return false;
+ const unsigned __dval = static_cast<unsigned>(__d);
+ if (__dval < 1 || __dval > 31) return false;
+ if (__dval <= 29) return true;
+// Now we've got either 30 or 31
+ const unsigned __mval = static_cast<unsigned>(__m);
+ if (__mval == 2) return false;
+ if (__mval == 4 || __mval == 6 || __mval == 9 || __mval == 11)
+ return __dval == 30;
+ return true;
+}
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+bool operator==(const month_day& __lhs, const month_day& __rhs) noexcept
+{ return __lhs.month() == __rhs.month() && __lhs.day() == __rhs.day(); }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+bool operator!=(const month_day& __lhs, const month_day& __rhs) noexcept
+{ return !(__lhs == __rhs); }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+month_day operator/(const month& __lhs, const day& __rhs) noexcept
+{ return month_day{__lhs, __rhs}; }
+
+_LIBCPP_HIDE_FROM_ABI constexpr
+month_day operator/(const day& __lhs, const month& __rhs) noexcept
+{ return __rhs / __lhs; }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+month_day operator/(const month& __lhs, int __rhs) noexcept
+{ return __lhs / day(__rhs); }
+
+_LIBCPP_HIDE_FROM_ABI constexpr
+month_day operator/(int __lhs, const day& __rhs) noexcept
+{ return month(__lhs) / __rhs; }
+
+_LIBCPP_HIDE_FROM_ABI constexpr
+month_day operator/(const day& __lhs, int __rhs) noexcept
+{ return month(__rhs) / __lhs; }
+
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+bool operator< (const month_day& __lhs, const month_day& __rhs) noexcept
+{ return __lhs.month() != __rhs.month() ? __lhs.month() < __rhs.month() : __lhs.day() < __rhs.day(); }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+bool operator> (const month_day& __lhs, const month_day& __rhs) noexcept
+{ return __rhs < __lhs; }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+bool operator<=(const month_day& __lhs, const month_day& __rhs) noexcept
+{ return !(__rhs < __lhs);}
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+bool operator>=(const month_day& __lhs, const month_day& __rhs) noexcept
+{ return !(__lhs < __rhs); }
+
+
+
+class month_day_last {
+private:
+ chrono::month __m;
+public:
+ _LIBCPP_HIDE_FROM_ABI explicit constexpr month_day_last(const chrono::month& __val) noexcept
+ : __m{__val} {}
+ _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __m; }
+ _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __m.ok(); }
+};
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+bool operator==(const month_day_last& __lhs, const month_day_last& __rhs) noexcept
+{ return __lhs.month() == __rhs.month(); }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+bool operator!=(const month_day_last& __lhs, const month_day_last& __rhs) noexcept
+{ return !(__lhs == __rhs); }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+bool operator< (const month_day_last& __lhs, const month_day_last& __rhs) noexcept
+{ return __lhs.month() < __rhs.month(); }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+bool operator> (const month_day_last& __lhs, const month_day_last& __rhs) noexcept
+{ return __rhs < __lhs; }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+bool operator<=(const month_day_last& __lhs, const month_day_last& __rhs) noexcept
+{ return !(__rhs < __lhs);}
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+bool operator>=(const month_day_last& __lhs, const month_day_last& __rhs) noexcept
+{ return !(__lhs < __rhs); }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+month_day_last operator/(const month& __lhs, last_spec) noexcept
+{ return month_day_last{__lhs}; }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+month_day_last operator/(last_spec, const month& __rhs) noexcept
+{ return month_day_last{__rhs}; }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+month_day_last operator/(int __lhs, last_spec) noexcept
+{ return month_day_last{month(__lhs)}; }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+month_day_last operator/(last_spec, int __rhs) noexcept
+{ return month_day_last{month(__rhs)}; }
+
+} // namespace chrono
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17
+
+#endif // _LIBCPP___CHRONO_MONTHDAY_H
diff --git a/libcxx/include/__chrono/steady_clock.h b/libcxx/include/__chrono/steady_clock.h
index 5ba911df843e..657e5eef6c37 100644
--- a/libcxx/include/__chrono/steady_clock.h
+++ b/libcxx/include/__chrono/steady_clock.h
@@ -15,7 +15,7 @@
#include <__config>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__chrono/system_clock.h b/libcxx/include/__chrono/system_clock.h
index 9c977d369e1b..2922b78a74cb 100644
--- a/libcxx/include/__chrono/system_clock.h
+++ b/libcxx/include/__chrono/system_clock.h
@@ -16,7 +16,7 @@
#include <ctime>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__chrono/time_point.h b/libcxx/include/__chrono/time_point.h
index c042e125145a..ac2d347a0dca 100644
--- a/libcxx/include/__chrono/time_point.h
+++ b/libcxx/include/__chrono/time_point.h
@@ -16,7 +16,7 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
diff --git a/libcxx/include/__chrono/weekday.h b/libcxx/include/__chrono/weekday.h
new file mode 100644
index 000000000000..bad6781110f1
--- /dev/null
+++ b/libcxx/include/__chrono/weekday.h
@@ -0,0 +1,185 @@
+// -*- 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___CHRONO_WEEKDAY_H
+#define _LIBCPP___CHRONO_WEEKDAY_H
+
+#include <__chrono/calendar.h>
+#include <__chrono/duration.h>
+#include <__chrono/system_clock.h>
+#include <__chrono/time_point.h>
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace chrono
+{
+
+class weekday_indexed;
+class weekday_last;
+
+class weekday {
+private:
+ unsigned char __wd;
+ _LIBCPP_HIDE_FROM_ABI static constexpr unsigned char __weekday_from_days(int __days) noexcept;
+public:
+ _LIBCPP_HIDE_FROM_ABI weekday() = default;
+ _LIBCPP_HIDE_FROM_ABI inline explicit constexpr weekday(unsigned __val) noexcept : __wd(static_cast<unsigned char>(__val == 7 ? 0 : __val)) {}
+ _LIBCPP_HIDE_FROM_ABI inline constexpr weekday(const sys_days& __sysd) noexcept
+ : __wd(__weekday_from_days(__sysd.time_since_epoch().count())) {}
+ _LIBCPP_HIDE_FROM_ABI inline explicit constexpr weekday(const local_days& __locd) noexcept
+ : __wd(__weekday_from_days(__locd.time_since_epoch().count())) {}
+
+ _LIBCPP_HIDE_FROM_ABI inline constexpr weekday& operator++() noexcept { __wd = (__wd == 6 ? 0 : __wd + 1); return *this; }
+ _LIBCPP_HIDE_FROM_ABI inline constexpr weekday operator++(int) noexcept { weekday __tmp = *this; ++(*this); return __tmp; }
+ _LIBCPP_HIDE_FROM_ABI inline constexpr weekday& operator--() noexcept { __wd = (__wd == 0 ? 6 : __wd - 1); return *this; }
+ _LIBCPP_HIDE_FROM_ABI inline constexpr weekday operator--(int) noexcept { weekday __tmp = *this; --(*this); return __tmp; }
+ _LIBCPP_HIDE_FROM_ABI constexpr weekday& operator+=(const days& __dd) noexcept;
+ _LIBCPP_HIDE_FROM_ABI constexpr weekday& operator-=(const days& __dd) noexcept;
+ _LIBCPP_HIDE_FROM_ABI inline constexpr unsigned c_encoding() const noexcept { return __wd; }
+ _LIBCPP_HIDE_FROM_ABI inline constexpr unsigned iso_encoding() const noexcept { return __wd == 0u ? 7 : __wd; }
+ _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __wd <= 6; }
+ _LIBCPP_HIDE_FROM_ABI constexpr weekday_indexed operator[](unsigned __index) const noexcept;
+ _LIBCPP_HIDE_FROM_ABI constexpr weekday_last operator[](last_spec) const noexcept;
+};
+
+
+// https://howardhinnant.github.io/date_algorithms.html#weekday_from_days
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+unsigned char weekday::__weekday_from_days(int __days) noexcept
+{
+ return static_cast<unsigned char>(
+ static_cast<unsigned>(__days >= -4 ? (__days+4) % 7 : (__days+5) % 7 + 6)
+ );
+}
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+bool operator==(const weekday& __lhs, const weekday& __rhs) noexcept
+{ return __lhs.c_encoding() == __rhs.c_encoding(); }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+bool operator!=(const weekday& __lhs, const weekday& __rhs) noexcept
+{ return !(__lhs == __rhs); }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+bool operator< (const weekday& __lhs, const weekday& __rhs) noexcept
+{ return __lhs.c_encoding() < __rhs.c_encoding(); }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+bool operator> (const weekday& __lhs, const weekday& __rhs) noexcept
+{ return __rhs < __lhs; }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+bool operator<=(const weekday& __lhs, const weekday& __rhs) noexcept
+{ return !(__rhs < __lhs);}
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+bool operator>=(const weekday& __lhs, const weekday& __rhs) noexcept
+{ return !(__lhs < __rhs); }
+
+_LIBCPP_HIDE_FROM_ABI constexpr
+weekday operator+(const weekday& __lhs, const days& __rhs) noexcept
+{
+ auto const __mu = static_cast<long long>(__lhs.c_encoding()) + __rhs.count();
+ auto const __yr = (__mu >= 0 ? __mu : __mu - 6) / 7;
+ return weekday{static_cast<unsigned>(__mu - __yr * 7)};
+}
+
+_LIBCPP_HIDE_FROM_ABI constexpr
+weekday operator+(const days& __lhs, const weekday& __rhs) noexcept
+{ return __rhs + __lhs; }
+
+_LIBCPP_HIDE_FROM_ABI constexpr
+weekday operator-(const weekday& __lhs, const days& __rhs) noexcept
+{ return __lhs + -__rhs; }
+
+_LIBCPP_HIDE_FROM_ABI constexpr
+days operator-(const weekday& __lhs, const weekday& __rhs) noexcept
+{
+ const int __wdu = __lhs.c_encoding() - __rhs.c_encoding();
+ const int __wk = (__wdu >= 0 ? __wdu : __wdu-6) / 7;
+ return days{__wdu - __wk * 7};
+}
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+weekday& weekday::operator+=(const days& __dd) noexcept
+{ *this = *this + __dd; return *this; }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+weekday& weekday::operator-=(const days& __dd) noexcept
+{ *this = *this - __dd; return *this; }
+
+class weekday_indexed {
+private:
+ chrono::weekday __wd;
+ unsigned char __idx;
+public:
+ _LIBCPP_HIDE_FROM_ABI weekday_indexed() = default;
+ _LIBCPP_HIDE_FROM_ABI inline constexpr weekday_indexed(const chrono::weekday& __wdval, unsigned __idxval) noexcept
+ : __wd{__wdval}, __idx(__idxval) {}
+ _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::weekday weekday() const noexcept { return __wd; }
+ _LIBCPP_HIDE_FROM_ABI inline constexpr unsigned index() const noexcept { return __idx; }
+ _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __wd.ok() && __idx >= 1 && __idx <= 5; }
+};
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+bool operator==(const weekday_indexed& __lhs, const weekday_indexed& __rhs) noexcept
+{ return __lhs.weekday() == __rhs.weekday() && __lhs.index() == __rhs.index(); }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+bool operator!=(const weekday_indexed& __lhs, const weekday_indexed& __rhs) noexcept
+{ return !(__lhs == __rhs); }
+
+
+class weekday_last {
+private:
+ chrono::weekday __wd;
+public:
+ _LIBCPP_HIDE_FROM_ABI explicit constexpr weekday_last(const chrono::weekday& __val) noexcept
+ : __wd{__val} {}
+ _LIBCPP_HIDE_FROM_ABI constexpr chrono::weekday weekday() const noexcept { return __wd; }
+ _LIBCPP_HIDE_FROM_ABI constexpr bool ok() const noexcept { return __wd.ok(); }
+};
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+bool operator==(const weekday_last& __lhs, const weekday_last& __rhs) noexcept
+{ return __lhs.weekday() == __rhs.weekday(); }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+bool operator!=(const weekday_last& __lhs, const weekday_last& __rhs) noexcept
+{ return !(__lhs == __rhs); }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+weekday_indexed weekday::operator[](unsigned __index) const noexcept { return weekday_indexed{*this, __index}; }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+weekday_last weekday::operator[](last_spec) const noexcept { return weekday_last{*this}; }
+
+
+inline constexpr weekday Sunday{0};
+inline constexpr weekday Monday{1};
+inline constexpr weekday Tuesday{2};
+inline constexpr weekday Wednesday{3};
+inline constexpr weekday Thursday{4};
+inline constexpr weekday Friday{5};
+inline constexpr weekday Saturday{6};
+
+} // namespace chrono
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17
+
+#endif // _LIBCPP___CHRONO_WEEKDAY_H
diff --git a/libcxx/include/__chrono/year.h b/libcxx/include/__chrono/year.h
new file mode 100644
index 000000000000..a641fe1c93b0
--- /dev/null
+++ b/libcxx/include/__chrono/year.h
@@ -0,0 +1,114 @@
+// -*- 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___CHRONO_YEAR_H
+#define _LIBCPP___CHRONO_YEAR_H
+
+#include <__chrono/duration.h>
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+#if _LIBCPP_STD_VER > 17
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace chrono
+{
+
+class year {
+private:
+ short __y;
+public:
+ _LIBCPP_HIDE_FROM_ABI year() = default;
+ _LIBCPP_HIDE_FROM_ABI explicit inline constexpr year(int __val) noexcept : __y(static_cast<short>(__val)) {}
+
+ _LIBCPP_HIDE_FROM_ABI inline constexpr year& operator++() noexcept { ++__y; return *this; }
+ _LIBCPP_HIDE_FROM_ABI inline constexpr year operator++(int) noexcept { year __tmp = *this; ++(*this); return __tmp; }
+ _LIBCPP_HIDE_FROM_ABI inline constexpr year& operator--() noexcept { --__y; return *this; }
+ _LIBCPP_HIDE_FROM_ABI inline constexpr year operator--(int) noexcept { year __tmp = *this; --(*this); return __tmp; }
+ _LIBCPP_HIDE_FROM_ABI constexpr year& operator+=(const years& __dy) noexcept;
+ _LIBCPP_HIDE_FROM_ABI constexpr year& operator-=(const years& __dy) noexcept;
+ _LIBCPP_HIDE_FROM_ABI inline constexpr year operator+() const noexcept { return *this; }
+ _LIBCPP_HIDE_FROM_ABI inline constexpr year operator-() const noexcept { return year{-__y}; }
+
+ _LIBCPP_HIDE_FROM_ABI inline constexpr bool is_leap() const noexcept { return __y % 4 == 0 && (__y % 100 != 0 || __y % 400 == 0); }
+ _LIBCPP_HIDE_FROM_ABI explicit inline constexpr operator int() const noexcept { return __y; }
+ _LIBCPP_HIDE_FROM_ABI constexpr bool ok() const noexcept;
+ _LIBCPP_HIDE_FROM_ABI static inline constexpr year min() noexcept { return year{-32767}; }
+ _LIBCPP_HIDE_FROM_ABI static inline constexpr year max() noexcept { return year{ 32767}; }
+};
+
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+bool operator==(const year& __lhs, const year& __rhs) noexcept
+{ return static_cast<int>(__lhs) == static_cast<int>(__rhs); }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+bool operator!=(const year& __lhs, const year& __rhs) noexcept
+{ return !(__lhs == __rhs); }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+bool operator< (const year& __lhs, const year& __rhs) noexcept
+{ return static_cast<int>(__lhs) < static_cast<int>(__rhs); }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+bool operator> (const year& __lhs, const year& __rhs) noexcept
+{ return __rhs < __lhs; }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+bool operator<=(const year& __lhs, const year& __rhs) noexcept
+{ return !(__rhs < __lhs); }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+bool operator>=(const year& __lhs, const year& __rhs) noexcept
+{ return !(__lhs < __rhs); }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+year operator+ (const year& __lhs, const years& __rhs) noexcept
+{ return year(static_cast<int>(__lhs) + __rhs.count()); }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+year operator+ (const years& __lhs, const year& __rhs) noexcept
+{ return __rhs + __lhs; }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+year operator- (const year& __lhs, const years& __rhs) noexcept
+{ return __lhs + -__rhs; }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+years operator-(const year& __lhs, const year& __rhs) noexcept
+{ return years{static_cast<int>(__lhs) - static_cast<int>(__rhs)}; }
+
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+year& year::operator+=(const years& __dy) noexcept
+{ *this = *this + __dy; return *this; }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+year& year::operator-=(const years& __dy) noexcept
+{ *this = *this - __dy; return *this; }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+bool year::ok() const noexcept
+{ return static_cast<int>(min()) <= __y && __y <= static_cast<int>(max()); }
+} // namespace chrono
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___CHRONO_YEAR_H
diff --git a/libcxx/include/__chrono/year_month.h b/libcxx/include/__chrono/year_month.h
new file mode 100644
index 000000000000..51b19caa1124
--- /dev/null
+++ b/libcxx/include/__chrono/year_month.h
@@ -0,0 +1,114 @@
+// -*- 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___CHRONO_YEAR_MONTH_H
+#define _LIBCPP___CHRONO_YEAR_MONTH_H
+
+#include <__chrono/duration.h>
+#include <__chrono/month.h>
+#include <__chrono/year.h>
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace chrono
+{
+
+class year_month {
+ chrono::year __y;
+ chrono::month __m;
+public:
+ _LIBCPP_HIDE_FROM_ABI year_month() = default;
+ _LIBCPP_HIDE_FROM_ABI constexpr year_month(const chrono::year& __yval, const chrono::month& __mval) noexcept
+ : __y{__yval}, __m{__mval} {}
+ _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::year year() const noexcept { return __y; }
+ _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __m; }
+ _LIBCPP_HIDE_FROM_ABI inline constexpr year_month& operator+=(const months& __dm) noexcept { this->__m += __dm; return *this; }
+ _LIBCPP_HIDE_FROM_ABI inline constexpr year_month& operator-=(const months& __dm) noexcept { this->__m -= __dm; return *this; }
+ _LIBCPP_HIDE_FROM_ABI inline constexpr year_month& operator+=(const years& __dy) noexcept { this->__y += __dy; return *this; }
+ _LIBCPP_HIDE_FROM_ABI inline constexpr year_month& operator-=(const years& __dy) noexcept { this->__y -= __dy; return *this; }
+ _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __y.ok() && __m.ok(); }
+};
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+year_month operator/(const year& __y, const month& __m) noexcept { return year_month{__y, __m}; }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+year_month operator/(const year& __y, int __m) noexcept { return year_month{__y, month(__m)}; }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+bool operator==(const year_month& __lhs, const year_month& __rhs) noexcept
+{ return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month(); }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+bool operator!=(const year_month& __lhs, const year_month& __rhs) noexcept
+{ return !(__lhs == __rhs); }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+bool operator< (const year_month& __lhs, const year_month& __rhs) noexcept
+{ return __lhs.year() != __rhs.year() ? __lhs.year() < __rhs.year() : __lhs.month() < __rhs.month(); }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+bool operator> (const year_month& __lhs, const year_month& __rhs) noexcept
+{ return __rhs < __lhs; }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+bool operator<=(const year_month& __lhs, const year_month& __rhs) noexcept
+{ return !(__rhs < __lhs);}
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+bool operator>=(const year_month& __lhs, const year_month& __rhs) noexcept
+{ return !(__lhs < __rhs); }
+
+_LIBCPP_HIDE_FROM_ABI constexpr
+year_month operator+(const year_month& __lhs, const months& __rhs) noexcept
+{
+ int __dmi = static_cast<int>(static_cast<unsigned>(__lhs.month())) - 1 + __rhs.count();
+ const int __dy = (__dmi >= 0 ? __dmi : __dmi-11) / 12;
+ __dmi = __dmi - __dy * 12 + 1;
+ return (__lhs.year() + years(__dy)) / month(static_cast<unsigned>(__dmi));
+}
+
+_LIBCPP_HIDE_FROM_ABI constexpr
+year_month operator+(const months& __lhs, const year_month& __rhs) noexcept
+{ return __rhs + __lhs; }
+
+_LIBCPP_HIDE_FROM_ABI constexpr
+year_month operator+(const year_month& __lhs, const years& __rhs) noexcept
+{ return (__lhs.year() + __rhs) / __lhs.month(); }
+
+_LIBCPP_HIDE_FROM_ABI constexpr
+year_month operator+(const years& __lhs, const year_month& __rhs) noexcept
+{ return __rhs + __lhs; }
+
+_LIBCPP_HIDE_FROM_ABI constexpr
+months operator-(const year_month& __lhs, const year_month& __rhs) noexcept
+{ return (__lhs.year() - __rhs.year()) + months(static_cast<unsigned>(__lhs.month()) - static_cast<unsigned>(__rhs.month())); }
+
+_LIBCPP_HIDE_FROM_ABI constexpr
+year_month operator-(const year_month& __lhs, const months& __rhs) noexcept
+{ return __lhs + -__rhs; }
+
+_LIBCPP_HIDE_FROM_ABI constexpr
+year_month operator-(const year_month& __lhs, const years& __rhs) noexcept
+{ return __lhs + -__rhs; }
+
+} // namespace chrono
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17
+
+#endif // _LIBCPP___CHRONO_YEAR_MONTH_H
diff --git a/libcxx/include/__chrono/year_month_day.h b/libcxx/include/__chrono/year_month_day.h
new file mode 100644
index 000000000000..957716aab690
--- /dev/null
+++ b/libcxx/include/__chrono/year_month_day.h
@@ -0,0 +1,323 @@
+// -*- 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___CHRONO_YEAR_MONTH_DAY_H
+#define _LIBCPP___CHRONO_YEAR_MONTH_DAY_H
+
+#include <__chrono/calendar.h>
+#include <__chrono/day.h>
+#include <__chrono/duration.h>
+#include <__chrono/month.h>
+#include <__chrono/monthday.h>
+#include <__chrono/system_clock.h>
+#include <__chrono/time_point.h>
+#include <__chrono/year.h>
+#include <__chrono/year_month.h>
+#include <__config>
+#include <limits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace chrono
+{
+
+class year_month_day_last;
+
+class year_month_day {
+private:
+ chrono::year __y;
+ chrono::month __m;
+ chrono::day __d;
+public:
+ _LIBCPP_HIDE_FROM_ABI year_month_day() = default;
+ _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day(
+ const chrono::year& __yval, const chrono::month& __mval, const chrono::day& __dval) noexcept
+ : __y{__yval}, __m{__mval}, __d{__dval} {}
+ _LIBCPP_HIDE_FROM_ABI constexpr year_month_day(const year_month_day_last& __ymdl) noexcept;
+ _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day(const sys_days& __sysd) noexcept
+ : year_month_day(__from_days(__sysd.time_since_epoch())) {}
+ _LIBCPP_HIDE_FROM_ABI inline explicit constexpr year_month_day(const local_days& __locd) noexcept
+ : year_month_day(__from_days(__locd.time_since_epoch())) {}
+
+ _LIBCPP_HIDE_FROM_ABI constexpr year_month_day& operator+=(const months& __dm) noexcept;
+ _LIBCPP_HIDE_FROM_ABI constexpr year_month_day& operator-=(const months& __dm) noexcept;
+ _LIBCPP_HIDE_FROM_ABI constexpr year_month_day& operator+=(const years& __dy) noexcept;
+ _LIBCPP_HIDE_FROM_ABI constexpr year_month_day& operator-=(const years& __dy) noexcept;
+
+ _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::year year() const noexcept { return __y; }
+ _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __m; }
+ _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::day day() const noexcept { return __d; }
+ _LIBCPP_HIDE_FROM_ABI inline constexpr operator sys_days() const noexcept { return sys_days{__to_days()}; }
+ _LIBCPP_HIDE_FROM_ABI inline explicit constexpr operator local_days() const noexcept { return local_days{__to_days()}; }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr bool ok() const noexcept;
+
+ _LIBCPP_HIDE_FROM_ABI static constexpr year_month_day __from_days(days __d) noexcept;
+ _LIBCPP_HIDE_FROM_ABI constexpr days __to_days() const noexcept;
+};
+
+
+// https://howardhinnant.github.io/date_algorithms.html#civil_from_days
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+year_month_day year_month_day::__from_days(days __d) noexcept
+{
+ static_assert(numeric_limits<unsigned>::digits >= 18, "");
+ static_assert(numeric_limits<int>::digits >= 20 , "");
+ const int __z = __d.count() + 719468;
+ const int __era = (__z >= 0 ? __z : __z - 146096) / 146097;
+ const unsigned __doe = static_cast<unsigned>(__z - __era * 146097); // [0, 146096]
+ const unsigned __yoe = (__doe - __doe/1460 + __doe/36524 - __doe/146096) / 365; // [0, 399]
+ const int __yr = static_cast<int>(__yoe) + __era * 400;
+ const unsigned __doy = __doe - (365 * __yoe + __yoe/4 - __yoe/100); // [0, 365]
+ const unsigned __mp = (5 * __doy + 2)/153; // [0, 11]
+ const unsigned __dy = __doy - (153 * __mp + 2)/5 + 1; // [1, 31]
+ const unsigned __mth = __mp + (__mp < 10 ? 3 : -9); // [1, 12]
+ return year_month_day{chrono::year{__yr + (__mth <= 2)}, chrono::month{__mth}, chrono::day{__dy}};
+}
+
+// https://howardhinnant.github.io/date_algorithms.html#days_from_civil
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+days year_month_day::__to_days() const noexcept
+{
+ static_assert(numeric_limits<unsigned>::digits >= 18, "");
+ static_assert(numeric_limits<int>::digits >= 20 , "");
+
+ const int __yr = static_cast<int>(__y) - (__m <= February);
+ const unsigned __mth = static_cast<unsigned>(__m);
+ const unsigned __dy = static_cast<unsigned>(__d);
+
+ const int __era = (__yr >= 0 ? __yr : __yr - 399) / 400;
+ const unsigned __yoe = static_cast<unsigned>(__yr - __era * 400); // [0, 399]
+ const unsigned __doy = (153 * (__mth + (__mth > 2 ? -3 : 9)) + 2) / 5 + __dy-1; // [0, 365]
+ const unsigned __doe = __yoe * 365 + __yoe/4 - __yoe/100 + __doy; // [0, 146096]
+ return days{__era * 146097 + static_cast<int>(__doe) - 719468};
+}
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+bool operator==(const year_month_day& __lhs, const year_month_day& __rhs) noexcept
+{ return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month() && __lhs.day() == __rhs.day(); }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+bool operator!=(const year_month_day& __lhs, const year_month_day& __rhs) noexcept
+{ return !(__lhs == __rhs); }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+bool operator< (const year_month_day& __lhs, const year_month_day& __rhs) noexcept
+{
+ if (__lhs.year() < __rhs.year()) return true;
+ if (__lhs.year() > __rhs.year()) return false;
+ if (__lhs.month() < __rhs.month()) return true;
+ if (__lhs.month() > __rhs.month()) return false;
+ return __lhs.day() < __rhs.day();
+}
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+bool operator> (const year_month_day& __lhs, const year_month_day& __rhs) noexcept
+{ return __rhs < __lhs; }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+bool operator<=(const year_month_day& __lhs, const year_month_day& __rhs) noexcept
+{ return !(__rhs < __lhs);}
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+bool operator>=(const year_month_day& __lhs, const year_month_day& __rhs) noexcept
+{ return !(__lhs < __rhs); }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+year_month_day operator/(const year_month& __lhs, const day& __rhs) noexcept
+{ return year_month_day{__lhs.year(), __lhs.month(), __rhs}; }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+year_month_day operator/(const year_month& __lhs, int __rhs) noexcept
+{ return __lhs / day(__rhs); }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+year_month_day operator/(const year& __lhs, const month_day& __rhs) noexcept
+{ return __lhs / __rhs.month() / __rhs.day(); }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+year_month_day operator/(int __lhs, const month_day& __rhs) noexcept
+{ return year(__lhs) / __rhs; }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+year_month_day operator/(const month_day& __lhs, const year& __rhs) noexcept
+{ return __rhs / __lhs; }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+year_month_day operator/(const month_day& __lhs, int __rhs) noexcept
+{ return year(__rhs) / __lhs; }
+
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+year_month_day operator+(const year_month_day& __lhs, const months& __rhs) noexcept
+{ return (__lhs.year()/__lhs.month() + __rhs)/__lhs.day(); }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+year_month_day operator+(const months& __lhs, const year_month_day& __rhs) noexcept
+{ return __rhs + __lhs; }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+year_month_day operator-(const year_month_day& __lhs, const months& __rhs) noexcept
+{ return __lhs + -__rhs; }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+year_month_day operator+(const year_month_day& __lhs, const years& __rhs) noexcept
+{ return (__lhs.year() + __rhs) / __lhs.month() / __lhs.day(); }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+year_month_day operator+(const years& __lhs, const year_month_day& __rhs) noexcept
+{ return __rhs + __lhs; }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+year_month_day operator-(const year_month_day& __lhs, const years& __rhs) noexcept
+{ return __lhs + -__rhs; }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day& year_month_day::operator+=(const months& __dm) noexcept { *this = *this + __dm; return *this; }
+_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day& year_month_day::operator-=(const months& __dm) noexcept { *this = *this - __dm; return *this; }
+_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day& year_month_day::operator+=(const years& __dy) noexcept { *this = *this + __dy; return *this; }
+_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day& year_month_day::operator-=(const years& __dy) noexcept { *this = *this - __dy; return *this; }
+
+class year_month_day_last {
+private:
+ chrono::year __y;
+ chrono::month_day_last __mdl;
+public:
+ _LIBCPP_HIDE_FROM_ABI constexpr year_month_day_last(const year& __yval, const month_day_last& __mdlval) noexcept
+ : __y{__yval}, __mdl{__mdlval} {}
+
+ _LIBCPP_HIDE_FROM_ABI constexpr year_month_day_last& operator+=(const months& __m) noexcept;
+ _LIBCPP_HIDE_FROM_ABI constexpr year_month_day_last& operator-=(const months& __m) noexcept;
+ _LIBCPP_HIDE_FROM_ABI constexpr year_month_day_last& operator+=(const years& __y) noexcept;
+ _LIBCPP_HIDE_FROM_ABI constexpr year_month_day_last& operator-=(const years& __y) noexcept;
+
+ _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::year year() const noexcept { return __y; }
+ _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __mdl.month(); }
+ _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month_day_last month_day_last() const noexcept { return __mdl; }
+ _LIBCPP_HIDE_FROM_ABI constexpr chrono::day day() const noexcept;
+ _LIBCPP_HIDE_FROM_ABI inline constexpr operator sys_days() const noexcept { return sys_days{year()/month()/day()}; }
+ _LIBCPP_HIDE_FROM_ABI inline explicit constexpr operator local_days() const noexcept { return local_days{year()/month()/day()}; }
+ _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __y.ok() && __mdl.ok(); }
+};
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+chrono::day year_month_day_last::day() const noexcept
+{
+ constexpr chrono::day __d[] =
+ {
+ chrono::day(31), chrono::day(28), chrono::day(31),
+ chrono::day(30), chrono::day(31), chrono::day(30),
+ chrono::day(31), chrono::day(31), chrono::day(30),
+ chrono::day(31), chrono::day(30), chrono::day(31)
+ };
+ return (month() != February || !__y.is_leap()) && month().ok() ?
+ __d[static_cast<unsigned>(month()) - 1] : chrono::day{29};
+}
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+bool operator==(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept
+{ return __lhs.year() == __rhs.year() && __lhs.month_day_last() == __rhs.month_day_last(); }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+bool operator!=(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept
+{ return !(__lhs == __rhs); }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+bool operator< (const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept
+{
+ if (__lhs.year() < __rhs.year()) return true;
+ if (__lhs.year() > __rhs.year()) return false;
+ return __lhs.month_day_last() < __rhs.month_day_last();
+}
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+bool operator> (const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept
+{ return __rhs < __lhs; }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+bool operator<=(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept
+{ return !(__rhs < __lhs);}
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+bool operator>=(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept
+{ return !(__lhs < __rhs); }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+year_month_day_last operator/(const year_month& __lhs, last_spec) noexcept
+{ return year_month_day_last{__lhs.year(), month_day_last{__lhs.month()}}; }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+year_month_day_last operator/(const year& __lhs, const month_day_last& __rhs) noexcept
+{ return year_month_day_last{__lhs, __rhs}; }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+year_month_day_last operator/(int __lhs, const month_day_last& __rhs) noexcept
+{ return year_month_day_last{year{__lhs}, __rhs}; }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day_last
+operator/(const month_day_last& __lhs, const year& __rhs) noexcept
+{ return __rhs / __lhs; }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+year_month_day_last operator/(const month_day_last& __lhs, int __rhs) noexcept
+{ return year{__rhs} / __lhs; }
+
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+year_month_day_last operator+(const year_month_day_last& __lhs, const months& __rhs) noexcept
+{ return (__lhs.year() / __lhs.month() + __rhs) / last; }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+year_month_day_last operator+(const months& __lhs, const year_month_day_last& __rhs) noexcept
+{ return __rhs + __lhs; }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+year_month_day_last operator-(const year_month_day_last& __lhs, const months& __rhs) noexcept
+{ return __lhs + (-__rhs); }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+year_month_day_last operator+(const year_month_day_last& __lhs, const years& __rhs) noexcept
+{ return year_month_day_last{__lhs.year() + __rhs, __lhs.month_day_last()}; }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+year_month_day_last operator+(const years& __lhs, const year_month_day_last& __rhs) noexcept
+{ return __rhs + __lhs; }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+year_month_day_last operator-(const year_month_day_last& __lhs, const years& __rhs) noexcept
+{ return __lhs + (-__rhs); }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day_last& year_month_day_last::operator+=(const months& __dm) noexcept { *this = *this + __dm; return *this; }
+_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day_last& year_month_day_last::operator-=(const months& __dm) noexcept { *this = *this - __dm; return *this; }
+_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day_last& year_month_day_last::operator+=(const years& __dy) noexcept { *this = *this + __dy; return *this; }
+_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day_last& year_month_day_last::operator-=(const years& __dy) noexcept { *this = *this - __dy; return *this; }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+year_month_day::year_month_day(const year_month_day_last& __ymdl) noexcept
+ : __y{__ymdl.year()}, __m{__ymdl.month()}, __d{__ymdl.day()} {}
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+bool year_month_day::ok() const noexcept
+{
+ if (!__y.ok() || !__m.ok()) return false;
+ return chrono::day{1} <= __d && __d <= (__y / __m / last).day();
+}
+
+} // namespace chrono
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17
+
+#endif // _LIBCPP___CHRONO_YEAR_MONTH_DAY_H
diff --git a/libcxx/include/__chrono/year_month_weekday.h b/libcxx/include/__chrono/year_month_weekday.h
new file mode 100644
index 000000000000..9ba81e7e3f65
--- /dev/null
+++ b/libcxx/include/__chrono/year_month_weekday.h
@@ -0,0 +1,255 @@
+// -*- 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___CHRONO_YEAR_MONTH_WEEKDAY_H
+#define _LIBCPP___CHRONO_YEAR_MONTH_WEEKDAY_H
+
+#include <__chrono/calendar.h>
+#include <__chrono/day.h>
+#include <__chrono/duration.h>
+#include <__chrono/month.h>
+#include <__chrono/month_weekday.h>
+#include <__chrono/system_clock.h>
+#include <__chrono/time_point.h>
+#include <__chrono/weekday.h>
+#include <__chrono/year.h>
+#include <__chrono/year_month.h>
+#include <__chrono/year_month_day.h>
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace chrono
+{
+
+class year_month_weekday {
+ chrono::year __y;
+ chrono::month __m;
+ chrono::weekday_indexed __wdi;
+public:
+ _LIBCPP_HIDE_FROM_ABI year_month_weekday() = default;
+ _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday(const chrono::year& __yval, const chrono::month& __mval,
+ const chrono::weekday_indexed& __wdival) noexcept
+ : __y{__yval}, __m{__mval}, __wdi{__wdival} {}
+ _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday(const sys_days& __sysd) noexcept
+ : year_month_weekday(__from_days(__sysd.time_since_epoch())) {}
+ _LIBCPP_HIDE_FROM_ABI inline explicit constexpr year_month_weekday(const local_days& __locd) noexcept
+ : year_month_weekday(__from_days(__locd.time_since_epoch())) {}
+ _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday& operator+=(const months& m) noexcept;
+ _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday& operator-=(const months& m) noexcept;
+ _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday& operator+=(const years& y) noexcept;
+ _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday& operator-=(const years& y) noexcept;
+
+ _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::year year() const noexcept { return __y; }
+ _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __m; }
+ _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::weekday weekday() const noexcept { return __wdi.weekday(); }
+ _LIBCPP_HIDE_FROM_ABI inline constexpr unsigned index() const noexcept { return __wdi.index(); }
+ _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::weekday_indexed weekday_indexed() const noexcept { return __wdi; }
+
+ _LIBCPP_HIDE_FROM_ABI inline constexpr operator sys_days() const noexcept { return sys_days{__to_days()}; }
+ _LIBCPP_HIDE_FROM_ABI inline explicit constexpr operator local_days() const noexcept { return local_days{__to_days()}; }
+ _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept
+ {
+ if (!__y.ok() || !__m.ok() || !__wdi.ok()) return false;
+ if (__wdi.index() <= 4) return true;
+ auto __nth_weekday_day =
+ __wdi.weekday() -
+ chrono::weekday{static_cast<sys_days>(__y / __m / 1)} +
+ days{(__wdi.index() - 1) * 7 + 1};
+ return static_cast<unsigned>(__nth_weekday_day.count()) <=
+ static_cast<unsigned>((__y / __m / last).day());
+ }
+
+ _LIBCPP_HIDE_FROM_ABI static constexpr year_month_weekday __from_days(days __d) noexcept;
+ _LIBCPP_HIDE_FROM_ABI constexpr days __to_days() const noexcept;
+};
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+year_month_weekday year_month_weekday::__from_days(days __d) noexcept
+{
+ const sys_days __sysd{__d};
+ const chrono::weekday __wd = chrono::weekday(__sysd);
+ const year_month_day __ymd = year_month_day(__sysd);
+ return year_month_weekday{__ymd.year(), __ymd.month(),
+ __wd[(static_cast<unsigned>(__ymd.day())-1)/7+1]};
+}
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+days year_month_weekday::__to_days() const noexcept
+{
+ const sys_days __sysd = sys_days(__y/__m/1);
+ return (__sysd + (__wdi.weekday() - chrono::weekday(__sysd) + days{(__wdi.index()-1)*7}))
+ .time_since_epoch();
+}
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+bool operator==(const year_month_weekday& __lhs, const year_month_weekday& __rhs) noexcept
+{ return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month() && __lhs.weekday_indexed() == __rhs.weekday_indexed(); }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+bool operator!=(const year_month_weekday& __lhs, const year_month_weekday& __rhs) noexcept
+{ return !(__lhs == __rhs); }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+year_month_weekday operator/(const year_month& __lhs, const weekday_indexed& __rhs) noexcept
+{ return year_month_weekday{__lhs.year(), __lhs.month(), __rhs}; }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+year_month_weekday operator/(const year& __lhs, const month_weekday& __rhs) noexcept
+{ return year_month_weekday{__lhs, __rhs.month(), __rhs.weekday_indexed()}; }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+year_month_weekday operator/(int __lhs, const month_weekday& __rhs) noexcept
+{ return year(__lhs) / __rhs; }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+year_month_weekday operator/(const month_weekday& __lhs, const year& __rhs) noexcept
+{ return __rhs / __lhs; }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+year_month_weekday operator/(const month_weekday& __lhs, int __rhs) noexcept
+{ return year(__rhs) / __lhs; }
+
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+year_month_weekday operator+(const year_month_weekday& __lhs, const months& __rhs) noexcept
+{ return (__lhs.year() / __lhs.month() + __rhs) / __lhs.weekday_indexed(); }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+year_month_weekday operator+(const months& __lhs, const year_month_weekday& __rhs) noexcept
+{ return __rhs + __lhs; }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+year_month_weekday operator-(const year_month_weekday& __lhs, const months& __rhs) noexcept
+{ return __lhs + (-__rhs); }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+year_month_weekday operator+(const year_month_weekday& __lhs, const years& __rhs) noexcept
+{ return year_month_weekday{__lhs.year() + __rhs, __lhs.month(), __lhs.weekday_indexed()}; }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+year_month_weekday operator+(const years& __lhs, const year_month_weekday& __rhs) noexcept
+{ return __rhs + __lhs; }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+year_month_weekday operator-(const year_month_weekday& __lhs, const years& __rhs) noexcept
+{ return __lhs + (-__rhs); }
+
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday& year_month_weekday::operator+=(const months& __dm) noexcept { *this = *this + __dm; return *this; }
+_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday& year_month_weekday::operator-=(const months& __dm) noexcept { *this = *this - __dm; return *this; }
+_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday& year_month_weekday::operator+=(const years& __dy) noexcept { *this = *this + __dy; return *this; }
+_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday& year_month_weekday::operator-=(const years& __dy) noexcept { *this = *this - __dy; return *this; }
+
+class year_month_weekday_last {
+private:
+ chrono::year __y;
+ chrono::month __m;
+ chrono::weekday_last __wdl;
+public:
+ _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday_last(const chrono::year& __yval, const chrono::month& __mval,
+ const chrono::weekday_last& __wdlval) noexcept
+ : __y{__yval}, __m{__mval}, __wdl{__wdlval} {}
+ _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday_last& operator+=(const months& __dm) noexcept;
+ _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday_last& operator-=(const months& __dm) noexcept;
+ _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday_last& operator+=(const years& __dy) noexcept;
+ _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday_last& operator-=(const years& __dy) noexcept;
+
+ _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::year year() const noexcept { return __y; }
+ _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __m; }
+ _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::weekday weekday() const noexcept { return __wdl.weekday(); }
+ _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::weekday_last weekday_last() const noexcept { return __wdl; }
+ _LIBCPP_HIDE_FROM_ABI inline constexpr operator sys_days() const noexcept { return sys_days{__to_days()}; }
+ _LIBCPP_HIDE_FROM_ABI inline explicit constexpr operator local_days() const noexcept { return local_days{__to_days()}; }
+ _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __y.ok() && __m.ok() && __wdl.ok(); }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr days __to_days() const noexcept;
+
+};
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+days year_month_weekday_last::__to_days() const noexcept
+{
+ const sys_days __last = sys_days{__y/__m/last};
+ return (__last - (chrono::weekday{__last} - __wdl.weekday())).time_since_epoch();
+
+}
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+bool operator==(const year_month_weekday_last& __lhs, const year_month_weekday_last& __rhs) noexcept
+{ return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month() && __lhs.weekday_last() == __rhs.weekday_last(); }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+bool operator!=(const year_month_weekday_last& __lhs, const year_month_weekday_last& __rhs) noexcept
+{ return !(__lhs == __rhs); }
+
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+year_month_weekday_last operator/(const year_month& __lhs, const weekday_last& __rhs) noexcept
+{ return year_month_weekday_last{__lhs.year(), __lhs.month(), __rhs}; }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+year_month_weekday_last operator/(const year& __lhs, const month_weekday_last& __rhs) noexcept
+{ return year_month_weekday_last{__lhs, __rhs.month(), __rhs.weekday_last()}; }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+year_month_weekday_last operator/(int __lhs, const month_weekday_last& __rhs) noexcept
+{ return year(__lhs) / __rhs; }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+year_month_weekday_last operator/(const month_weekday_last& __lhs, const year& __rhs) noexcept
+{ return __rhs / __lhs; }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+year_month_weekday_last operator/(const month_weekday_last& __lhs, int __rhs) noexcept
+{ return year(__rhs) / __lhs; }
+
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+year_month_weekday_last operator+(const year_month_weekday_last& __lhs, const months& __rhs) noexcept
+{ return (__lhs.year() / __lhs.month() + __rhs) / __lhs.weekday_last(); }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+year_month_weekday_last operator+(const months& __lhs, const year_month_weekday_last& __rhs) noexcept
+{ return __rhs + __lhs; }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+year_month_weekday_last operator-(const year_month_weekday_last& __lhs, const months& __rhs) noexcept
+{ return __lhs + (-__rhs); }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+year_month_weekday_last operator+(const year_month_weekday_last& __lhs, const years& __rhs) noexcept
+{ return year_month_weekday_last{__lhs.year() + __rhs, __lhs.month(), __lhs.weekday_last()}; }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+year_month_weekday_last operator+(const years& __lhs, const year_month_weekday_last& __rhs) noexcept
+{ return __rhs + __lhs; }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr
+year_month_weekday_last operator-(const year_month_weekday_last& __lhs, const years& __rhs) noexcept
+{ return __lhs + (-__rhs); }
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last& year_month_weekday_last::operator+=(const months& __dm) noexcept { *this = *this + __dm; return *this; }
+_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last& year_month_weekday_last::operator-=(const months& __dm) noexcept { *this = *this - __dm; return *this; }
+_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last& year_month_weekday_last::operator+=(const years& __dy) noexcept { *this = *this + __dy; return *this; }
+_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last& year_month_weekday_last::operator-=(const years& __dy) noexcept { *this = *this - __dy; return *this; }
+
+} // namespace chrono
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17
+
+#endif // _LIBCPP___CHRONO_YEAR_MONTH_WEEKDAY_H
diff --git a/libcxx/include/__compare/common_comparison_category.h b/libcxx/include/__compare/common_comparison_category.h
index 37a28db1d650..deab171846e2 100644
--- a/libcxx/include/__compare/common_comparison_category.h
+++ b/libcxx/include/__compare/common_comparison_category.h
@@ -14,7 +14,7 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__compare/compare_partial_order_fallback.h b/libcxx/include/__compare/compare_partial_order_fallback.h
index 895523b38fb3..ba746d6c7d9c 100644
--- a/libcxx/include/__compare/compare_partial_order_fallback.h
+++ b/libcxx/include/__compare/compare_partial_order_fallback.h
@@ -17,12 +17,12 @@
#include <type_traits>
#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17
// [cmp.alg]
namespace __compare_partial_order_fallback {
@@ -66,7 +66,7 @@ inline namespace __cpo {
inline constexpr auto compare_partial_order_fallback = __compare_partial_order_fallback::__fn{};
} // namespace __cpo
-#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__compare/compare_strong_order_fallback.h b/libcxx/include/__compare/compare_strong_order_fallback.h
index 5fee7b478068..312a08ef7e90 100644
--- a/libcxx/include/__compare/compare_strong_order_fallback.h
+++ b/libcxx/include/__compare/compare_strong_order_fallback.h
@@ -17,12 +17,12 @@
#include <type_traits>
#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17
// [cmp.alg]
namespace __compare_strong_order_fallback {
@@ -63,7 +63,7 @@ inline namespace __cpo {
inline constexpr auto compare_strong_order_fallback = __compare_strong_order_fallback::__fn{};
} // namespace __cpo
-#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__compare/compare_three_way.h b/libcxx/include/__compare/compare_three_way.h
index d7f339eda992..fdbba04a78e6 100644
--- a/libcxx/include/__compare/compare_three_way.h
+++ b/libcxx/include/__compare/compare_three_way.h
@@ -15,12 +15,12 @@
#include <__utility/forward.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17
struct _LIBCPP_TEMPLATE_VIS compare_three_way
{
@@ -34,7 +34,7 @@ struct _LIBCPP_TEMPLATE_VIS compare_three_way
using is_transparent = void;
};
-#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__compare/compare_three_way_result.h b/libcxx/include/__compare/compare_three_way_result.h
index 14908c6bbc1b..7b03597ab1c1 100644
--- a/libcxx/include/__compare/compare_three_way_result.h
+++ b/libcxx/include/__compare/compare_three_way_result.h
@@ -13,7 +13,7 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__compare/compare_weak_order_fallback.h b/libcxx/include/__compare/compare_weak_order_fallback.h
index 0abd4f2dfbee..844d67608703 100644
--- a/libcxx/include/__compare/compare_weak_order_fallback.h
+++ b/libcxx/include/__compare/compare_weak_order_fallback.h
@@ -17,12 +17,12 @@
#include <type_traits>
#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17
// [cmp.alg]
namespace __compare_weak_order_fallback {
@@ -63,7 +63,7 @@ inline namespace __cpo {
inline constexpr auto compare_weak_order_fallback = __compare_weak_order_fallback::__fn{};
} // namespace __cpo
-#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__compare/is_eq.h b/libcxx/include/__compare/is_eq.h
index 906cb0709e77..49648924e81f 100644
--- a/libcxx/include/__compare/is_eq.h
+++ b/libcxx/include/__compare/is_eq.h
@@ -13,7 +13,7 @@
#include <__config>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__compare/ordering.h b/libcxx/include/__compare/ordering.h
index d4087bc85ba1..1d466d669eec 100644
--- a/libcxx/include/__compare/ordering.h
+++ b/libcxx/include/__compare/ordering.h
@@ -13,7 +13,7 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__compare/partial_order.h b/libcxx/include/__compare/partial_order.h
index ac8b405a4090..970f01b3f1b0 100644
--- a/libcxx/include/__compare/partial_order.h
+++ b/libcxx/include/__compare/partial_order.h
@@ -18,12 +18,12 @@
#include <type_traits>
#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17
// [cmp.alg]
namespace __partial_order {
@@ -64,7 +64,7 @@ inline namespace __cpo {
inline constexpr auto partial_order = __partial_order::__fn{};
} // namespace __cpo
-#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__compare/strong_order.h b/libcxx/include/__compare/strong_order.h
index 42f060387d59..67c7b2910bd5 100644
--- a/libcxx/include/__compare/strong_order.h
+++ b/libcxx/include/__compare/strong_order.h
@@ -21,7 +21,7 @@
#include <type_traits>
#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
@@ -29,7 +29,7 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17
// [cmp.alg]
namespace __strong_order {
@@ -127,7 +127,7 @@ inline namespace __cpo {
inline constexpr auto strong_order = __strong_order::__fn{};
} // namespace __cpo
-#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__compare/synth_three_way.h b/libcxx/include/__compare/synth_three_way.h
index 0f302c0fa11f..fa8cbda79ba2 100644
--- a/libcxx/include/__compare/synth_three_way.h
+++ b/libcxx/include/__compare/synth_three_way.h
@@ -16,12 +16,12 @@
#include <__utility/declval.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17
// [expos.only.func]
@@ -42,9 +42,9 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr auto __synth_three_way =
};
template <class _Tp, class _Up = _Tp>
-using __synth_three_way_result = decltype(__synth_three_way(declval<_Tp&>(), declval<_Up&>()));
+using __synth_three_way_result = decltype(std::__synth_three_way(declval<_Tp&>(), declval<_Up&>()));
-#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__compare/three_way_comparable.h b/libcxx/include/__compare/three_way_comparable.h
index c4794949007b..b317d750590e 100644
--- a/libcxx/include/__compare/three_way_comparable.h
+++ b/libcxx/include/__compare/three_way_comparable.h
@@ -19,12 +19,12 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17
template<class _Tp, class _Cat>
concept __compares_as =
@@ -51,7 +51,7 @@ concept three_way_comparable_with =
{ __u <=> __t } -> __compares_as<_Cat>;
};
-#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__compare/weak_order.h b/libcxx/include/__compare/weak_order.h
index ce914b232108..c2fae1a98deb 100644
--- a/libcxx/include/__compare/weak_order.h
+++ b/libcxx/include/__compare/weak_order.h
@@ -19,12 +19,12 @@
#include <type_traits>
#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17
// [cmp.alg]
namespace __weak_order {
@@ -93,7 +93,7 @@ inline namespace __cpo {
inline constexpr auto weak_order = __weak_order::__fn{};
} // namespace __cpo
-#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__concepts/arithmetic.h b/libcxx/include/__concepts/arithmetic.h
index 9a1383904db6..023f031e7e07 100644
--- a/libcxx/include/__concepts/arithmetic.h
+++ b/libcxx/include/__concepts/arithmetic.h
@@ -13,12 +13,12 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17
// [concepts.arithmetic], arithmetic concepts
@@ -41,7 +41,7 @@ concept __libcpp_unsigned_integer = __libcpp_is_unsigned_integer<_Tp>::value;
template <class _Tp>
concept __libcpp_signed_integer = __libcpp_is_signed_integer<_Tp>::value;
-#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__concepts/assignable.h b/libcxx/include/__concepts/assignable.h
index 9cfc7c0e8318..7f187a39f8f8 100644
--- a/libcxx/include/__concepts/assignable.h
+++ b/libcxx/include/__concepts/assignable.h
@@ -16,12 +16,12 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17
// [concept.assignable]
@@ -33,7 +33,7 @@ concept assignable_from =
{ __lhs = _VSTD::forward<_Rhs>(__rhs) } -> same_as<_Lhs>;
};
-#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__concepts/boolean_testable.h b/libcxx/include/__concepts/boolean_testable.h
index 638fc3b20330..a96bde711749 100644
--- a/libcxx/include/__concepts/boolean_testable.h
+++ b/libcxx/include/__concepts/boolean_testable.h
@@ -14,12 +14,12 @@
#include <__utility/forward.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17
// [concepts.booleantestable]
@@ -31,7 +31,7 @@ concept __boolean_testable = __boolean_testable_impl<_Tp> && requires(_Tp&& __t)
{ !_VSTD::forward<_Tp>(__t) } -> __boolean_testable_impl;
};
-#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__concepts/class_or_enum.h b/libcxx/include/__concepts/class_or_enum.h
index aa8606a21929..9fd62ba89243 100644
--- a/libcxx/include/__concepts/class_or_enum.h
+++ b/libcxx/include/__concepts/class_or_enum.h
@@ -13,12 +13,12 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17
// Whether a type is a class type or enumeration type according to the Core wording.
@@ -26,10 +26,11 @@ template<class _Tp>
concept __class_or_enum = is_class_v<_Tp> || is_union_v<_Tp> || is_enum_v<_Tp>;
// Work around Clang bug https://llvm.org/PR52970
+// TODO: remove this workaround once libc++ no longer has to support Clang 13 (it was fixed in Clang 14).
template<class _Tp>
concept __workaround_52970 = is_class_v<__uncvref_t<_Tp>> || is_union_v<__uncvref_t<_Tp>>;
-#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__concepts/common_reference_with.h b/libcxx/include/__concepts/common_reference_with.h
index 3269e3ae89fe..cae2f5bccce0 100644
--- a/libcxx/include/__concepts/common_reference_with.h
+++ b/libcxx/include/__concepts/common_reference_with.h
@@ -15,12 +15,12 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17
// [concept.commonref]
@@ -30,7 +30,7 @@ concept common_reference_with =
convertible_to<_Tp, common_reference_t<_Tp, _Up>> &&
convertible_to<_Up, common_reference_t<_Tp, _Up>>;
-#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__concepts/common_with.h b/libcxx/include/__concepts/common_with.h
index b575aea5f77f..1b5f4da4af9a 100644
--- a/libcxx/include/__concepts/common_with.h
+++ b/libcxx/include/__concepts/common_with.h
@@ -15,12 +15,12 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17
// [concept.common]
@@ -40,7 +40,7 @@ concept common_with =
add_lvalue_reference_t<const _Tp>,
add_lvalue_reference_t<const _Up>>>;
-#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__concepts/constructible.h b/libcxx/include/__concepts/constructible.h
index 9bba8118b899..aaf515417e4c 100644
--- a/libcxx/include/__concepts/constructible.h
+++ b/libcxx/include/__concepts/constructible.h
@@ -15,12 +15,12 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17
// [concept.constructible]
template<class _Tp, class... _Args>
@@ -49,7 +49,7 @@ concept copy_constructible =
constructible_from<_Tp, const _Tp&> && convertible_to<const _Tp&, _Tp> &&
constructible_from<_Tp, const _Tp> && convertible_to<const _Tp, _Tp>;
-#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__concepts/convertible_to.h b/libcxx/include/__concepts/convertible_to.h
index 795b0bd7494c..5d9d43710421 100644
--- a/libcxx/include/__concepts/convertible_to.h
+++ b/libcxx/include/__concepts/convertible_to.h
@@ -14,12 +14,12 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17
// [concept.convertible]
@@ -30,7 +30,7 @@ concept convertible_to =
static_cast<_To>(declval<_From>());
};
-#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__concepts/copyable.h b/libcxx/include/__concepts/copyable.h
index cfeeec86917e..c5d8a80b9dad 100644
--- a/libcxx/include/__concepts/copyable.h
+++ b/libcxx/include/__concepts/copyable.h
@@ -15,12 +15,12 @@
#include <__config>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17
// [concepts.object]
@@ -32,7 +32,7 @@ concept copyable =
assignable_from<_Tp&, const _Tp&> &&
assignable_from<_Tp&, const _Tp>;
-#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__concepts/derived_from.h b/libcxx/include/__concepts/derived_from.h
index f7c83bf31fba..4b2914794735 100644
--- a/libcxx/include/__concepts/derived_from.h
+++ b/libcxx/include/__concepts/derived_from.h
@@ -13,12 +13,12 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17
// [concept.derived]
@@ -27,7 +27,7 @@ concept derived_from =
is_base_of_v<_Bp, _Dp> &&
is_convertible_v<const volatile _Dp*, const volatile _Bp*>;
-#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__concepts/destructible.h b/libcxx/include/__concepts/destructible.h
index 800ee2d56f04..90a043d314c2 100644
--- a/libcxx/include/__concepts/destructible.h
+++ b/libcxx/include/__concepts/destructible.h
@@ -13,19 +13,19 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17
// [concept.destructible]
template<class _Tp>
concept destructible = is_nothrow_destructible_v<_Tp>;
-#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__concepts/different_from.h b/libcxx/include/__concepts/different_from.h
index 5def31e652a5..3066372e8683 100644
--- a/libcxx/include/__concepts/different_from.h
+++ b/libcxx/include/__concepts/different_from.h
@@ -14,17 +14,17 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17
template<class _Tp, class _Up>
concept __different_from = !same_as<remove_cvref_t<_Tp>, remove_cvref_t<_Up>>;
-#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__concepts/equality_comparable.h b/libcxx/include/__concepts/equality_comparable.h
index 5df812c2600d..7c750c5937b5 100644
--- a/libcxx/include/__concepts/equality_comparable.h
+++ b/libcxx/include/__concepts/equality_comparable.h
@@ -15,12 +15,12 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17
// [concept.equalitycomparable]
@@ -46,7 +46,7 @@ concept equality_comparable_with =
__make_const_lvalue_ref<_Up>>> &&
__weakly_equality_comparable_with<_Tp, _Up>;
-#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__concepts/invocable.h b/libcxx/include/__concepts/invocable.h
index 0a8d9b7255ab..d90389e97f3b 100644
--- a/libcxx/include/__concepts/invocable.h
+++ b/libcxx/include/__concepts/invocable.h
@@ -15,12 +15,12 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17
// [concept.invocable]
@@ -34,7 +34,7 @@ concept invocable = requires(_Fn&& __fn, _Args&&... __args) {
template<class _Fn, class... _Args>
concept regular_invocable = invocable<_Fn, _Args...>;
-#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__concepts/movable.h b/libcxx/include/__concepts/movable.h
index dd0b8fb56d5b..639219ed6b48 100644
--- a/libcxx/include/__concepts/movable.h
+++ b/libcxx/include/__concepts/movable.h
@@ -16,12 +16,12 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17
// [concepts.object]
@@ -32,7 +32,7 @@ concept movable =
assignable_from<_Tp&, _Tp> &&
swappable<_Tp>;
-#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__concepts/predicate.h b/libcxx/include/__concepts/predicate.h
index 8e885406316d..cb239752309f 100644
--- a/libcxx/include/__concepts/predicate.h
+++ b/libcxx/include/__concepts/predicate.h
@@ -15,12 +15,12 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17
// [concept.predicate]
@@ -28,7 +28,7 @@ template<class _Fn, class... _Args>
concept predicate =
regular_invocable<_Fn, _Args...> && __boolean_testable<invoke_result_t<_Fn, _Args...>>;
-#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__concepts/regular.h b/libcxx/include/__concepts/regular.h
index d292e8d72dbe..d15728d298bd 100644
--- a/libcxx/include/__concepts/regular.h
+++ b/libcxx/include/__concepts/regular.h
@@ -14,19 +14,19 @@
#include <__config>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17
// [concept.object]
template<class _Tp>
concept regular = semiregular<_Tp> && equality_comparable<_Tp>;
-#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__concepts/relation.h b/libcxx/include/__concepts/relation.h
index c6ff20d15195..7d5141cac74c 100644
--- a/libcxx/include/__concepts/relation.h
+++ b/libcxx/include/__concepts/relation.h
@@ -13,12 +13,12 @@
#include <__config>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17
// [concept.relation]
@@ -37,7 +37,7 @@ concept equivalence_relation = relation<_Rp, _Tp, _Up>;
template<class _Rp, class _Tp, class _Up>
concept strict_weak_order = relation<_Rp, _Tp, _Up>;
-#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__concepts/same_as.h b/libcxx/include/__concepts/same_as.h
index 5a912b6f41c8..765490661148 100644
--- a/libcxx/include/__concepts/same_as.h
+++ b/libcxx/include/__concepts/same_as.h
@@ -13,12 +13,12 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17
// [concept.same]
@@ -28,7 +28,7 @@ concept __same_as_impl = _IsSame<_Tp, _Up>::value;
template<class _Tp, class _Up>
concept same_as = __same_as_impl<_Tp, _Up> && __same_as_impl<_Up, _Tp>;
-#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__concepts/semiregular.h b/libcxx/include/__concepts/semiregular.h
index 4b96fe6dfba6..d15bb3ba42ba 100644
--- a/libcxx/include/__concepts/semiregular.h
+++ b/libcxx/include/__concepts/semiregular.h
@@ -14,19 +14,19 @@
#include <__config>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17
// [concept.object]
template<class _Tp>
concept semiregular = copyable<_Tp> && default_initializable<_Tp>;
-#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__concepts/swappable.h b/libcxx/include/__concepts/swappable.h
index d45249738535..fef940f21fed 100644
--- a/libcxx/include/__concepts/swappable.h
+++ b/libcxx/include/__concepts/swappable.h
@@ -20,12 +20,12 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17
// [concept.swappable]
@@ -109,7 +109,7 @@ concept swappable_with =
ranges::swap(_VSTD::forward<_Up>(__u), _VSTD::forward<_Tp>(__t));
};
-#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__concepts/totally_ordered.h b/libcxx/include/__concepts/totally_ordered.h
index d8dd4a4944d0..25347790de07 100644
--- a/libcxx/include/__concepts/totally_ordered.h
+++ b/libcxx/include/__concepts/totally_ordered.h
@@ -15,12 +15,12 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17
// [concept.totallyordered]
@@ -50,7 +50,7 @@ concept totally_ordered_with =
__make_const_lvalue_ref<_Up>>> &&
__partially_ordered_with<_Tp, _Up>;
-#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__config b/libcxx/include/__config
index 3c3d4b57c76e..e4b7d25edf34 100644
--- a/libcxx/include/__config
+++ b/libcxx/include/__config
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef _LIBCPP_CONFIG
-#define _LIBCPP_CONFIG
+#ifndef _LIBCPP___CONFIG
+#define _LIBCPP___CONFIG
#include <__config_site>
@@ -19,332 +19,300 @@
#endif
#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
-#pragma GCC system_header
+# pragma GCC system_header
#endif
#ifdef __cplusplus
-#define _LIBCPP_VERSION 14000
+# define _LIBCPP_VERSION 15000
-#ifndef _LIBCPP_ABI_VERSION
-# define _LIBCPP_ABI_VERSION 1
-#endif
-
-#if __STDC_HOSTED__ == 0
-# define _LIBCPP_FREESTANDING
-#endif
+# if __STDC_HOSTED__ == 0
+# define _LIBCPP_FREESTANDING
+# endif
-#ifndef _LIBCPP_STD_VER
-# if __cplusplus <= 201103L
-# define _LIBCPP_STD_VER 11
-# elif __cplusplus <= 201402L
-# define _LIBCPP_STD_VER 14
-# elif __cplusplus <= 201703L
-# define _LIBCPP_STD_VER 17
-# elif __cplusplus <= 202002L
-# define _LIBCPP_STD_VER 20
+# ifndef _LIBCPP_STD_VER
+# if __cplusplus <= 201103L
+# define _LIBCPP_STD_VER 11
+# elif __cplusplus <= 201402L
+# define _LIBCPP_STD_VER 14
+# elif __cplusplus <= 201703L
+# define _LIBCPP_STD_VER 17
+# elif __cplusplus <= 202002L
+# define _LIBCPP_STD_VER 20
+# else
+# define _LIBCPP_STD_VER 22 // current year, or date of c++2b ratification
+# endif
+# endif // _LIBCPP_STD_VER
+
+# if defined(__ELF__)
+# define _LIBCPP_OBJECT_FORMAT_ELF 1
+# elif defined(__MACH__)
+# define _LIBCPP_OBJECT_FORMAT_MACHO 1
+# elif defined(_WIN32)
+# define _LIBCPP_OBJECT_FORMAT_COFF 1
+# elif defined(__wasm__)
+# define _LIBCPP_OBJECT_FORMAT_WASM 1
+# elif defined(_AIX)
+# define _LIBCPP_OBJECT_FORMAT_XCOFF 1
# else
-# define _LIBCPP_STD_VER 21 // current year, or date of c++2b ratification
-# endif
-#endif // _LIBCPP_STD_VER
-
-#if defined(__ELF__)
-# define _LIBCPP_OBJECT_FORMAT_ELF 1
-#elif defined(__MACH__)
-# define _LIBCPP_OBJECT_FORMAT_MACHO 1
-#elif defined(_WIN32)
-# define _LIBCPP_OBJECT_FORMAT_COFF 1
-#elif defined(__wasm__)
-# define _LIBCPP_OBJECT_FORMAT_WASM 1
-#else
- // ... add new file formats here ...
-#endif
+// ... add new file formats here ...
+# endif
-#if defined(_LIBCPP_ABI_UNSTABLE) || _LIBCPP_ABI_VERSION >= 2
+# if _LIBCPP_ABI_VERSION >= 2
// Change short string representation so that string data starts at offset 0,
// improving its alignment in some cases.
-# define _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
+# define _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
// Fix deque iterator type in order to support incomplete types.
-# define _LIBCPP_ABI_INCOMPLETE_TYPES_IN_DEQUE
+# define _LIBCPP_ABI_INCOMPLETE_TYPES_IN_DEQUE
// Fix undefined behavior in how std::list stores its linked nodes.
-# define _LIBCPP_ABI_LIST_REMOVE_NODE_POINTER_UB
+# define _LIBCPP_ABI_LIST_REMOVE_NODE_POINTER_UB
// Fix undefined behavior in how __tree stores its end and parent nodes.
-# define _LIBCPP_ABI_TREE_REMOVE_NODE_POINTER_UB
+# define _LIBCPP_ABI_TREE_REMOVE_NODE_POINTER_UB
// Fix undefined behavior in how __hash_table stores its pointer types.
-# define _LIBCPP_ABI_FIX_UNORDERED_NODE_POINTER_UB
-# define _LIBCPP_ABI_FORWARD_LIST_REMOVE_NODE_POINTER_UB
-# define _LIBCPP_ABI_FIX_UNORDERED_CONTAINER_SIZE_TYPE
+# define _LIBCPP_ABI_FIX_UNORDERED_NODE_POINTER_UB
+# define _LIBCPP_ABI_FORWARD_LIST_REMOVE_NODE_POINTER_UB
+# define _LIBCPP_ABI_FIX_UNORDERED_CONTAINER_SIZE_TYPE
// Define a key function for `bad_function_call` in the library, to centralize
// its vtable and typeinfo to libc++ rather than having all other libraries
// using that class define their own copies.
-# define _LIBCPP_ABI_BAD_FUNCTION_CALL_KEY_FUNCTION
+# define _LIBCPP_ABI_BAD_FUNCTION_CALL_KEY_FUNCTION
// Override the default return value of exception::what() for
// bad_function_call::what() with a string that is specific to
// bad_function_call (see http://wg21.link/LWG2233). This is an ABI break
// because it changes the vtable layout of bad_function_call.
-# define _LIBCPP_ABI_BAD_FUNCTION_CALL_GOOD_WHAT_MESSAGE
+# define _LIBCPP_ABI_BAD_FUNCTION_CALL_GOOD_WHAT_MESSAGE
// Enable optimized version of __do_get_(un)signed which avoids redundant copies.
-# define _LIBCPP_ABI_OPTIMIZED_LOCALE_NUM_GET
-// In C++20 and later, don't derive std::plus from std::binary_function,
-// nor std::negate from std::unary_function.
-# define _LIBCPP_ABI_NO_BINDER_BASES
+# define _LIBCPP_ABI_OPTIMIZED_LOCALE_NUM_GET
// Give reverse_iterator<T> one data member of type T, not two.
// Also, in C++17 and later, don't derive iterator types from std::iterator.
-# define _LIBCPP_ABI_NO_ITERATOR_BASES
+# define _LIBCPP_ABI_NO_ITERATOR_BASES
// Use the smallest possible integer type to represent the index of the variant.
// Previously libc++ used "unsigned int" exclusively.
-# define _LIBCPP_ABI_VARIANT_INDEX_TYPE_OPTIMIZATION
+# define _LIBCPP_ABI_VARIANT_INDEX_TYPE_OPTIMIZATION
// Unstable attempt to provide a more optimized std::function
-# define _LIBCPP_ABI_OPTIMIZED_FUNCTION
+# define _LIBCPP_ABI_OPTIMIZED_FUNCTION
// All the regex constants must be distinct and nonzero.
-# define _LIBCPP_ABI_REGEX_CONSTANTS_NONZERO
-// Use raw pointers, not wrapped ones, for std::span's iterator type.
-# define _LIBCPP_ABI_SPAN_POINTER_ITERATORS
+# define _LIBCPP_ABI_REGEX_CONSTANTS_NONZERO
// Re-worked external template instantiations for std::string with a focus on
// performance and fast-path inlining.
-# define _LIBCPP_ABI_STRING_OPTIMIZED_EXTERNAL_INSTANTIATION
+# define _LIBCPP_ABI_STRING_OPTIMIZED_EXTERNAL_INSTANTIATION
// Enable clang::trivial_abi on std::unique_ptr.
-# define _LIBCPP_ABI_ENABLE_UNIQUE_PTR_TRIVIAL_ABI
+# define _LIBCPP_ABI_ENABLE_UNIQUE_PTR_TRIVIAL_ABI
// Enable clang::trivial_abi on std::shared_ptr and std::weak_ptr
-# define _LIBCPP_ABI_ENABLE_SHARED_PTR_TRIVIAL_ABI
+# define _LIBCPP_ABI_ENABLE_SHARED_PTR_TRIVIAL_ABI
// std::random_device holds some state when it uses an implementation that gets
// entropy from a file (see _LIBCPP_USING_DEV_RANDOM). When switching from this
// implementation to another one on a platform that has already shipped
// std::random_device, one needs to retain the same object layout to remain ABI
// compatible. This switch removes these workarounds for platforms that don't care
// about ABI compatibility.
-# define _LIBCPP_ABI_NO_RANDOM_DEVICE_COMPATIBILITY_LAYOUT
-// Remove basic_string common base
-# define _LIBCPP_ABI_NO_BASIC_STRING_BASE_CLASS
-#elif _LIBCPP_ABI_VERSION == 1
-# if !defined(_LIBCPP_OBJECT_FORMAT_COFF)
+# define _LIBCPP_ABI_NO_RANDOM_DEVICE_COMPATIBILITY_LAYOUT
+// Don't export the legacy __basic_string_common class and its methods from the built library.
+# define _LIBCPP_ABI_DO_NOT_EXPORT_BASIC_STRING_COMMON
+// Don't export the legacy __vector_base_common class and its methods from the built library.
+# define _LIBCPP_ABI_DO_NOT_EXPORT_VECTOR_BASE_COMMON
+// According to the Standard, `bitset::operator[] const` returns bool
+# define _LIBCPP_ABI_BITSET_VECTOR_BOOL_CONST_SUBSCRIPT_RETURN_BOOL
+// Remove the base 10 implementation of std::to_chars from the dylib.
+// The implementation moved to the header, but we still export the symbols from
+// the dylib for backwards compatibility.
+# define _LIBCPP_ABI_DO_NOT_EXPORT_TO_CHARS_BASE_10
+# elif _LIBCPP_ABI_VERSION == 1
+# if !(defined(_LIBCPP_OBJECT_FORMAT_COFF) || defined(_LIBCPP_OBJECT_FORMAT_XCOFF))
// Enable compiling copies of now inline methods into the dylib to support
// applications compiled against older libraries. This is unnecessary with
// COFF dllexport semantics, since dllexport forces a non-inline definition
// of inline functions to be emitted anyway. Our own non-inline copy would
-// conflict with the dllexport-emitted copy, so we disable it.
-# define _LIBCPP_DEPRECATED_ABI_LEGACY_LIBRARY_DEFINITIONS_FOR_INLINE_FUNCTIONS
-# endif
+// conflict with the dllexport-emitted copy, so we disable it. For XCOFF,
+// the linker will take issue with the symbols in the shared object if the
+// weak inline methods get visibility (such as from -fvisibility-inlines-hidden),
+// so disable it.
+# define _LIBCPP_DEPRECATED_ABI_LEGACY_LIBRARY_DEFINITIONS_FOR_INLINE_FUNCTIONS
+# endif
// Feature macros for disabling pre ABI v1 features. All of these options
// are deprecated.
-# if defined(__FreeBSD__)
-# define _LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR
+# if defined(__FreeBSD__)
+# define _LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR
+# endif
# endif
-#endif
-
-// By default, don't use a nullptr_t emulation type in C++03.
-//
-// This is technically an ABI break from previous releases, however it is
-// very unlikely to impact anyone. If a user is impacted by this break,
-// they can return to using the C++03 nullptr emulation by defining
-// _LIBCPP_ABI_USE_CXX03_NULLPTR_EMULATION.
-//
-// This switch will be removed entirely in favour of never providing a
-// C++03 emulation after one release.
-//
-// IMPORTANT: IF YOU ARE READING THIS AND YOU TURN THIS MACRO ON, PLEASE LEAVE
-// A COMMENT ON https://reviews.llvm.org/D109459 OR YOU WILL BE BROKEN
-// IN THE FUTURE WHEN WE REMOVE THE ABILITY TO USE THE C++03 EMULATION.
-#ifndef _LIBCPP_ABI_USE_CXX03_NULLPTR_EMULATION
-# define _LIBCPP_ABI_ALWAYS_USE_CXX11_NULLPTR
-#endif
-#if defined(_LIBCPP_BUILDING_LIBRARY) || defined(_LIBCPP_ABI_UNSTABLE) || _LIBCPP_ABI_VERSION >= 2
+# if defined(_LIBCPP_BUILDING_LIBRARY) || _LIBCPP_ABI_VERSION >= 2
// 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.
-# define _LIBCPP_ABI_ENABLE_ADDITIONAL_IOSTREAM_EXPLICIT_INSTANTIATIONS_1
+# define _LIBCPP_ABI_ENABLE_ADDITIONAL_IOSTREAM_EXPLICIT_INSTANTIATIONS_1
// Define a key function for `bad_function_call` in the library, to centralize
// its vtable and typeinfo to libc++ rather than having all other libraries
// using that class define their own copies.
-# define _LIBCPP_ABI_BAD_FUNCTION_CALL_KEY_FUNCTION
-#endif
+# define _LIBCPP_ABI_BAD_FUNCTION_CALL_KEY_FUNCTION
+# endif
-#define _LIBCPP_CONCAT1(_LIBCPP_X,_LIBCPP_Y) _LIBCPP_X##_LIBCPP_Y
-#define _LIBCPP_CONCAT(_LIBCPP_X,_LIBCPP_Y) _LIBCPP_CONCAT1(_LIBCPP_X,_LIBCPP_Y)
+# define _LIBCPP_TOSTRING2(x) # x
+# define _LIBCPP_TOSTRING(x) _LIBCPP_TOSTRING2(x)
-#ifndef _LIBCPP_ABI_NAMESPACE
-# define _LIBCPP_ABI_NAMESPACE _LIBCPP_CONCAT(__,_LIBCPP_ABI_VERSION)
-#endif
-
-#if __cplusplus < 201103L
-#define _LIBCPP_CXX03_LANG
-#endif
+# if __cplusplus < 201103L
+# define _LIBCPP_CXX03_LANG
+# endif
-#ifndef __has_attribute
-#define __has_attribute(__x) 0
-#endif
+# ifndef __has_attribute
+# define __has_attribute(__x) 0
+# endif
-#ifndef __has_builtin
-#define __has_builtin(__x) 0
-#endif
+# ifndef __has_builtin
+# define __has_builtin(__x) 0
+# endif
-#ifndef __has_extension
-#define __has_extension(__x) 0
-#endif
+# ifndef __has_extension
+# define __has_extension(__x) 0
+# endif
-#ifndef __has_feature
-#define __has_feature(__x) 0
-#endif
+# ifndef __has_feature
+# define __has_feature(__x) 0
+# endif
-#ifndef __has_cpp_attribute
-#define __has_cpp_attribute(__x) 0
-#endif
+# ifndef __has_cpp_attribute
+# define __has_cpp_attribute(__x) 0
+# endif
// '__is_identifier' returns '0' if '__x' is a reserved identifier provided by
// the compiler and '1' otherwise.
-#ifndef __is_identifier
-#define __is_identifier(__x) 1
-#endif
+# ifndef __is_identifier
+# define __is_identifier(__x) 1
+# endif
-#ifndef __has_declspec_attribute
-#define __has_declspec_attribute(__x) 0
-#endif
+# ifndef __has_declspec_attribute
+# define __has_declspec_attribute(__x) 0
+# endif
-#define __has_keyword(__x) !(__is_identifier(__x))
+# define __has_keyword(__x) !(__is_identifier(__x))
-#ifndef __has_include
-#define __has_include(...) 0
-#endif
+# ifndef __has_include
+# define __has_include(...) 0
+# endif
-#if defined(__apple_build_version__)
-# define _LIBCPP_COMPILER_CLANG_BASED
-# define _LIBCPP_APPLE_CLANG_VER (__apple_build_version__ / 10000)
-#elif defined(__clang__)
-# define _LIBCPP_COMPILER_CLANG_BASED
-# define _LIBCPP_CLANG_VER (__clang_major__ * 100 + __clang_minor__)
-#elif defined(__GNUC__)
-# define _LIBCPP_COMPILER_GCC
-#elif defined(_MSC_VER)
-# define _LIBCPP_COMPILER_MSVC
-#elif defined(__IBMCPP__)
-# define _LIBCPP_COMPILER_IBM
-#endif
+# if defined(__apple_build_version__)
+# define _LIBCPP_COMPILER_CLANG_BASED
+# define _LIBCPP_APPLE_CLANG_VER (__apple_build_version__ / 10000)
+# elif defined(__clang__)
+# define _LIBCPP_COMPILER_CLANG_BASED
+# define _LIBCPP_CLANG_VER (__clang_major__ * 100 + __clang_minor__)
+# elif defined(__GNUC__)
+# define _LIBCPP_COMPILER_GCC
+# elif defined(_MSC_VER)
+# define _LIBCPP_COMPILER_MSVC
+# endif
-#if defined(_LIBCPP_COMPILER_GCC) && __cplusplus < 201103L
-#error "libc++ does not support using GCC with C++03. Please enable C++11"
-#endif
+# if !defined(_LIBCPP_COMPILER_CLANG_BASED) && __cplusplus < 201103L
+# error "libc++ only supports C++03 with Clang-based compilers. Please enable C++11"
+# endif
// FIXME: ABI detection should be done via compiler builtin macros. This
// is just a placeholder until Clang implements such macros. For now assume
// that Windows compilers pretending to be MSVC++ target the Microsoft ABI,
// and allow the user to explicitly specify the ABI to handle cases where this
// heuristic falls short.
-#if defined(_LIBCPP_ABI_FORCE_ITANIUM) && defined(_LIBCPP_ABI_FORCE_MICROSOFT)
-# error "Only one of _LIBCPP_ABI_FORCE_ITANIUM and _LIBCPP_ABI_FORCE_MICROSOFT can be defined"
-#elif defined(_LIBCPP_ABI_FORCE_ITANIUM)
-# define _LIBCPP_ABI_ITANIUM
-#elif defined(_LIBCPP_ABI_FORCE_MICROSOFT)
-# define _LIBCPP_ABI_MICROSOFT
-#else
-# if defined(_WIN32) && defined(_MSC_VER)
+# if defined(_LIBCPP_ABI_FORCE_ITANIUM) && defined(_LIBCPP_ABI_FORCE_MICROSOFT)
+# error "Only one of _LIBCPP_ABI_FORCE_ITANIUM and _LIBCPP_ABI_FORCE_MICROSOFT can be defined"
+# elif defined(_LIBCPP_ABI_FORCE_ITANIUM)
+# define _LIBCPP_ABI_ITANIUM
+# elif defined(_LIBCPP_ABI_FORCE_MICROSOFT)
# define _LIBCPP_ABI_MICROSOFT
# else
-# define _LIBCPP_ABI_ITANIUM
+# if defined(_WIN32) && defined(_MSC_VER)
+# define _LIBCPP_ABI_MICROSOFT
+# else
+# define _LIBCPP_ABI_ITANIUM
+# endif
# endif
-#endif
-#if defined(_LIBCPP_ABI_MICROSOFT) && !defined(_LIBCPP_NO_VCRUNTIME)
-# define _LIBCPP_ABI_VCRUNTIME
-#endif
+# if defined(_LIBCPP_ABI_MICROSOFT) && !defined(_LIBCPP_NO_VCRUNTIME)
+# define _LIBCPP_ABI_VCRUNTIME
+# endif
// Need to detect which libc we're using if we're on Linux.
-#if defined(__linux__)
-# 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 // defined(__linux__)
-
-#if defined(__MVS__)
-# include <features.h> // for __NATIVE_ASCII_F
-#endif
-
-#ifdef __LITTLE_ENDIAN__
-# if __LITTLE_ENDIAN__
-# define _LIBCPP_LITTLE_ENDIAN
-# endif // __LITTLE_ENDIAN__
-#endif // __LITTLE_ENDIAN__
+# if defined(__linux__)
+# 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 // defined(__linux__)
-#ifdef __BIG_ENDIAN__
-# if __BIG_ENDIAN__
-# define _LIBCPP_BIG_ENDIAN
-# endif // __BIG_ENDIAN__
-#endif // __BIG_ENDIAN__
+# if defined(__MVS__)
+# include <features.h> // for __NATIVE_ASCII_F
+# endif
-#ifdef __BYTE_ORDER__
-# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
-# define _LIBCPP_LITTLE_ENDIAN
-# elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
-# define _LIBCPP_BIG_ENDIAN
-# endif // __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
-#endif // __BYTE_ORDER__
-
-#ifdef __FreeBSD__
-# include <sys/endian.h>
-# include <osreldate.h>
-# if _BYTE_ORDER == _LITTLE_ENDIAN
+# ifdef __LITTLE_ENDIAN__
+# if __LITTLE_ENDIAN__
+# define _LIBCPP_LITTLE_ENDIAN
+# endif // __LITTLE_ENDIAN__
+# endif // __LITTLE_ENDIAN__
+
+# ifdef __BIG_ENDIAN__
+# if __BIG_ENDIAN__
+# define _LIBCPP_BIG_ENDIAN
+# endif // __BIG_ENDIAN__
+# endif // __BIG_ENDIAN__
+
+# ifdef __BYTE_ORDER__
+# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+# define _LIBCPP_LITTLE_ENDIAN
+# elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+# define _LIBCPP_BIG_ENDIAN
+# endif // __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+# endif // __BYTE_ORDER__
+
+# ifdef __FreeBSD__
+# include <sys/endian.h>
+# include <osreldate.h>
+# if _BYTE_ORDER == _LITTLE_ENDIAN
+# define _LIBCPP_LITTLE_ENDIAN
+# else // _BYTE_ORDER == _LITTLE_ENDIAN
+# define _LIBCPP_BIG_ENDIAN
+# endif // _BYTE_ORDER == _LITTLE_ENDIAN
+# endif // __FreeBSD__
+
+# if defined(__NetBSD__) || defined(__OpenBSD__)
+# include <sys/endian.h>
+# if _BYTE_ORDER == _LITTLE_ENDIAN
+# define _LIBCPP_LITTLE_ENDIAN
+# else // _BYTE_ORDER == _LITTLE_ENDIAN
+# define _LIBCPP_BIG_ENDIAN
+# endif // _BYTE_ORDER == _LITTLE_ENDIAN
+# endif // defined(__NetBSD__) || defined(__OpenBSD__)
+
+# if defined(_WIN32)
+# define _LIBCPP_WIN32API
# define _LIBCPP_LITTLE_ENDIAN
-# else // _BYTE_ORDER == _LITTLE_ENDIAN
-# define _LIBCPP_BIG_ENDIAN
-# endif // _BYTE_ORDER == _LITTLE_ENDIAN
-#endif // __FreeBSD__
-
-#if defined(__NetBSD__) || defined(__OpenBSD__)
-# include <sys/endian.h>
-# if _BYTE_ORDER == _LITTLE_ENDIAN
-# define _LIBCPP_LITTLE_ENDIAN
-# else // _BYTE_ORDER == _LITTLE_ENDIAN
-# define _LIBCPP_BIG_ENDIAN
-# endif // _BYTE_ORDER == _LITTLE_ENDIAN
-#endif // defined(__NetBSD__) || defined(__OpenBSD__)
-
-#if defined(_WIN32)
-# define _LIBCPP_WIN32API
-# define _LIBCPP_LITTLE_ENDIAN
-# define _LIBCPP_SHORT_WCHAR 1
+# define _LIBCPP_SHORT_WCHAR 1
// Both MinGW and native MSVC provide a "MSVC"-like environment
-# define _LIBCPP_MSVCRT_LIKE
+# define _LIBCPP_MSVCRT_LIKE
// If mingw not explicitly detected, assume using MS C runtime only if
// a MS compatibility version is specified.
-# if defined(_MSC_VER) && !defined(__MINGW32__)
-# define _LIBCPP_MSVCRT // Using Microsoft's C Runtime library
-# endif
-# if (defined(_M_AMD64) || defined(__x86_64__)) || (defined(_M_ARM) || defined(__arm__))
-# define _LIBCPP_HAS_BITSCAN64
-# endif
-# define _LIBCPP_HAS_OPEN_WITH_WCHAR
-# if defined(_LIBCPP_MSVCRT)
-# define _LIBCPP_HAS_QUICK_EXIT
-# endif
+# if defined(_MSC_VER) && !defined(__MINGW32__)
+# define _LIBCPP_MSVCRT // Using Microsoft's C Runtime library
+# endif
+# if (defined(_M_AMD64) || defined(__x86_64__)) || (defined(_M_ARM) || defined(__arm__))
+# define _LIBCPP_HAS_BITSCAN64
+# endif
+# define _LIBCPP_HAS_OPEN_WITH_WCHAR
+# endif // defined(_WIN32)
-// Some CRT APIs are unavailable to store apps
-# if defined(WINAPI_FAMILY)
-# include <winapifamily.h>
-# if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && \
- (!defined(WINAPI_PARTITION_SYSTEM) || \
- !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_SYSTEM))
-# define _LIBCPP_WINDOWS_STORE_APP
+# ifdef __sun__
+# include <sys/isa_defs.h>
+# ifdef _LITTLE_ENDIAN
+# define _LIBCPP_LITTLE_ENDIAN
+# else
+# define _LIBCPP_BIG_ENDIAN
# endif
-# endif
-#endif // defined(_WIN32)
+# endif // __sun__
-#ifdef __sun__
-# include <sys/isa_defs.h>
-# ifdef _LITTLE_ENDIAN
-# define _LIBCPP_LITTLE_ENDIAN
-# else
-# define _LIBCPP_BIG_ENDIAN
+# if defined(_AIX) && !defined(__64BIT__)
+// The size of wchar is 2 byte on 32-bit mode on AIX.
+# define _LIBCPP_SHORT_WCHAR 1
# endif
-#endif // __sun__
-
-#if defined(_AIX) && !defined(__64BIT__)
- // The size of wchar is 2 byte on 32-bit mode on AIX.
-# define _LIBCPP_SHORT_WCHAR 1
-#endif
// Libc++ supports various implementations of std::random_device.
//
@@ -384,806 +352,568 @@
// Use rand_s(), for use on Windows.
// When this option is used, the token passed to `std::random_device`'s
// constructor *must* be "/dev/urandom" -- anything else is an error.
-#if defined(__OpenBSD__) || defined(__APPLE__)
-# define _LIBCPP_USING_ARC4_RANDOM
-#elif defined(__wasi__)
-# define _LIBCPP_USING_GETENTROPY
-#elif defined(__Fuchsia__)
-# define _LIBCPP_USING_FUCHSIA_CPRNG
-#elif defined(__native_client__)
-# define _LIBCPP_USING_NACL_RANDOM
-#elif defined(_LIBCPP_WIN32API)
-# define _LIBCPP_USING_WIN32_RANDOM
-#else
-# define _LIBCPP_USING_DEV_RANDOM
-#endif
-
-#if !defined(_LIBCPP_LITTLE_ENDIAN) && !defined(_LIBCPP_BIG_ENDIAN)
-# include <endian.h>
-# if __BYTE_ORDER == __LITTLE_ENDIAN
-# define _LIBCPP_LITTLE_ENDIAN
-# elif __BYTE_ORDER == __BIG_ENDIAN
-# define _LIBCPP_BIG_ENDIAN
-# else // __BYTE_ORDER == __BIG_ENDIAN
-# error unable to determine endian
+# if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || \
+ defined(__DragonFly__) || defined(__sun__)
+# define _LIBCPP_USING_ARC4_RANDOM
+# elif defined(__wasi__) || defined(__EMSCRIPTEN__)
+# define _LIBCPP_USING_GETENTROPY
+# elif defined(__Fuchsia__)
+# define _LIBCPP_USING_FUCHSIA_CPRNG
+# elif defined(__native_client__)
+# define _LIBCPP_USING_NACL_RANDOM
+# elif defined(_LIBCPP_WIN32API)
+# define _LIBCPP_USING_WIN32_RANDOM
+# else
+# define _LIBCPP_USING_DEV_RANDOM
# endif
-#endif // !defined(_LIBCPP_LITTLE_ENDIAN) && !defined(_LIBCPP_BIG_ENDIAN)
-#if __has_attribute(__no_sanitize__) && !defined(_LIBCPP_COMPILER_GCC)
-# define _LIBCPP_NO_CFI __attribute__((__no_sanitize__("cfi")))
-#else
-# define _LIBCPP_NO_CFI
-#endif
-
-// If the compiler supports using_if_exists, pretend we have those functions and they'll
-// be picked up if the C library provides them.
-//
-// TODO: Once we drop support for Clang 12, we can assume the compiler supports using_if_exists
-// for platforms that don't have a conforming C11 library, so we can drop this whole thing.
-#if __has_attribute(using_if_exists)
-# define _LIBCPP_HAS_TIMESPEC_GET
-# define _LIBCPP_HAS_QUICK_EXIT
-# define _LIBCPP_HAS_ALIGNED_ALLOC
-#else
-#if (defined(__ISO_C_VISIBLE) && (__ISO_C_VISIBLE >= 2011)) || __cplusplus >= 201103L
-# if defined(__FreeBSD__)
-# define _LIBCPP_HAS_ALIGNED_ALLOC
-# define _LIBCPP_HAS_QUICK_EXIT
-# if __FreeBSD_version >= 1300064 || \
- (__FreeBSD_version >= 1201504 && __FreeBSD_version < 1300000)
-# define _LIBCPP_HAS_TIMESPEC_GET
-# endif
-# elif defined(__BIONIC__)
-# if __ANDROID_API__ >= 21
-# define _LIBCPP_HAS_QUICK_EXIT
+# if !defined(_LIBCPP_LITTLE_ENDIAN) && !defined(_LIBCPP_BIG_ENDIAN)
+# include <endian.h>
+# if __BYTE_ORDER == __LITTLE_ENDIAN
+# define _LIBCPP_LITTLE_ENDIAN
+# elif __BYTE_ORDER == __BIG_ENDIAN
+# define _LIBCPP_BIG_ENDIAN
+# else // __BYTE_ORDER == __BIG_ENDIAN
+# error unable to determine endian
# endif
-# if __ANDROID_API__ >= 28
-# define _LIBCPP_HAS_ALIGNED_ALLOC
-# endif
-# if __ANDROID_API__ >= 29
-# define _LIBCPP_HAS_TIMESPEC_GET
-# endif
-# elif defined(__Fuchsia__) || defined(__wasi__) || defined(__NetBSD__)
-# define _LIBCPP_HAS_ALIGNED_ALLOC
-# define _LIBCPP_HAS_QUICK_EXIT
-# define _LIBCPP_HAS_TIMESPEC_GET
-# elif defined(__OpenBSD__)
-# define _LIBCPP_HAS_ALIGNED_ALLOC
-# define _LIBCPP_HAS_TIMESPEC_GET
-# elif defined(__linux__)
-# if !defined(_LIBCPP_HAS_MUSL_LIBC)
-# if _LIBCPP_GLIBC_PREREQ(2, 15) || defined(__BIONIC__)
-# define _LIBCPP_HAS_QUICK_EXIT
-# endif
-# if _LIBCPP_GLIBC_PREREQ(2, 17)
-# define _LIBCPP_HAS_ALIGNED_ALLOC
-# define _LIBCPP_HAS_TIMESPEC_GET
-# endif
-# else // defined(_LIBCPP_HAS_MUSL_LIBC)
-# define _LIBCPP_HAS_ALIGNED_ALLOC
-# define _LIBCPP_HAS_QUICK_EXIT
-# define _LIBCPP_HAS_TIMESPEC_GET
-# endif
-# elif defined(_LIBCPP_MSVCRT)
- // Using Microsoft's C Runtime library, not MinGW
-# define _LIBCPP_HAS_TIMESPEC_GET
-# elif defined(__APPLE__)
- // timespec_get and aligned_alloc were introduced in macOS 10.15 and
- // aligned releases
-# 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_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ >= 130000) || \
- (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ >= 60000))
-# define _LIBCPP_HAS_ALIGNED_ALLOC
-# define _LIBCPP_HAS_TIMESPEC_GET
-# endif
-# endif // __APPLE__
-#endif
-#endif // __has_attribute(using_if_exists)
-
-#ifndef _LIBCPP_CXX03_LANG
-# define _LIBCPP_ALIGNOF(_Tp) alignof(_Tp)
-#elif defined(_LIBCPP_COMPILER_CLANG_BASED)
-# define _LIBCPP_ALIGNOF(_Tp) _Alignof(_Tp)
-#else
-# error "We don't know a correct way to implement alignof(T) in C++03 outside of Clang"
-#endif
+# endif // !defined(_LIBCPP_LITTLE_ENDIAN) && !defined(_LIBCPP_BIG_ENDIAN)
-#define _LIBCPP_PREFERRED_ALIGNOF(_Tp) __alignof(_Tp)
+# if __has_attribute(__no_sanitize__) && !defined(_LIBCPP_COMPILER_GCC)
+# define _LIBCPP_NO_CFI __attribute__((__no_sanitize__("cfi")))
+# else
+# define _LIBCPP_NO_CFI
+# endif
-#if defined(_LIBCPP_COMPILER_CLANG_BASED)
+# ifndef _LIBCPP_CXX03_LANG
-#if defined(_LIBCPP_ALTERNATE_STRING_LAYOUT)
-# error _LIBCPP_ALTERNATE_STRING_LAYOUT is deprecated, please use _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT instead
-#endif
-#if defined(__APPLE__) && !defined(__i386__) && !defined(__x86_64__) && \
- (!defined(__arm__) || __ARM_ARCH_7K__ >= 2)
-# define _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
-#endif
+# define _LIBCPP_ALIGNOF(_Tp) alignof(_Tp)
+# define _ALIGNAS_TYPE(x) alignas(x)
+# define _ALIGNAS(x) alignas(x)
+# define _LIBCPP_NORETURN [[noreturn]]
+# define _NOEXCEPT noexcept
+# define _NOEXCEPT_(x) noexcept(x)
-#if __has_feature(cxx_alignas)
-# define _ALIGNAS_TYPE(x) alignas(x)
-# define _ALIGNAS(x) alignas(x)
-#else
-# define _ALIGNAS_TYPE(x) __attribute__((__aligned__(_LIBCPP_ALIGNOF(x))))
-# define _ALIGNAS(x) __attribute__((__aligned__(x)))
-#endif
+# else
+
+# define _LIBCPP_ALIGNOF(_Tp) _Alignof(_Tp)
+# define _ALIGNAS_TYPE(x) __attribute__((__aligned__(_LIBCPP_ALIGNOF(x))))
+# define _ALIGNAS(x) __attribute__((__aligned__(x)))
+# define _LIBCPP_NORETURN __attribute__((noreturn))
+# define _LIBCPP_HAS_NO_NOEXCEPT
+# define nullptr __nullptr
+# define _NOEXCEPT throw()
+# define _NOEXCEPT_(x)
-#if __cplusplus < 201103L
typedef __char16_t char16_t;
typedef __char32_t char32_t;
-#endif
-
-#if !__has_feature(cxx_exceptions)
-# define _LIBCPP_NO_EXCEPTIONS
-#endif
-
-#if !(__has_feature(cxx_strong_enums))
-#define _LIBCPP_HAS_NO_STRONG_ENUMS
-#endif
-#if __has_feature(cxx_attributes)
-# define _LIBCPP_NORETURN [[noreturn]]
-#else
-# define _LIBCPP_NORETURN __attribute__ ((noreturn))
-#endif
-
-#if !(__has_feature(cxx_nullptr))
-# if (__has_extension(cxx_nullptr) || __has_keyword(__nullptr)) && defined(_LIBCPP_ABI_ALWAYS_USE_CXX11_NULLPTR)
-# define nullptr __nullptr
-# else
-# define _LIBCPP_HAS_NO_NULLPTR
# endif
-#endif
-// Objective-C++ features (opt-in)
-#if __has_feature(objc_arc)
-#define _LIBCPP_HAS_OBJC_ARC
-#endif
+# if !defined(__cpp_exceptions) || __cpp_exceptions < 199711L
+# define _LIBCPP_NO_EXCEPTIONS
+# endif
-#if __has_feature(objc_arc_weak)
-#define _LIBCPP_HAS_OBJC_ARC_WEAK
-#endif
+# define _LIBCPP_PREFERRED_ALIGNOF(_Tp) __alignof(_Tp)
-#if __has_extension(blocks)
-# define _LIBCPP_HAS_EXTENSION_BLOCKS
-#endif
+# if defined(_LIBCPP_COMPILER_CLANG_BASED)
-#if defined(_LIBCPP_HAS_EXTENSION_BLOCKS) && defined(__APPLE__)
-# define _LIBCPP_HAS_BLOCKS_RUNTIME
-#endif
+# if defined(__APPLE__) && !defined(__i386__) && !defined(__x86_64__) && (!defined(__arm__) || __ARM_ARCH_7K__ >= 2)
+# define _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
+# endif
-#if !(__has_feature(cxx_noexcept))
-#define _LIBCPP_HAS_NO_NOEXCEPT
-#endif
+// Objective-C++ features (opt-in)
+# if __has_feature(objc_arc)
+# define _LIBCPP_HAS_OBJC_ARC
+# endif
-#if !__has_feature(address_sanitizer)
-#define _LIBCPP_HAS_NO_ASAN
-#endif
+# if __has_feature(objc_arc_weak)
+# define _LIBCPP_HAS_OBJC_ARC_WEAK
+# endif
-// Allow for build-time disabling of unsigned integer sanitization
-#if __has_attribute(no_sanitize)
-#define _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK __attribute__((__no_sanitize__("unsigned-integer-overflow")))
-#endif
+# if __has_extension(blocks)
+# define _LIBCPP_HAS_EXTENSION_BLOCKS
+# endif
-#define _LIBCPP_ALWAYS_INLINE __attribute__ ((__always_inline__))
+# if defined(_LIBCPP_HAS_EXTENSION_BLOCKS) && defined(__APPLE__)
+# define _LIBCPP_HAS_BLOCKS_RUNTIME
+# endif
-#define _LIBCPP_DISABLE_EXTENSION_WARNING __extension__
+# if !__has_feature(address_sanitizer)
+# define _LIBCPP_HAS_NO_ASAN
+# endif
-#elif defined(_LIBCPP_COMPILER_GCC)
+// Allow for build-time disabling of unsigned integer sanitization
+# if __has_attribute(no_sanitize)
+# define _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK __attribute__((__no_sanitize__("unsigned-integer-overflow")))
+# endif
-#define _ALIGNAS(x) __attribute__((__aligned__(x)))
-#define _ALIGNAS_TYPE(x) __attribute__((__aligned__(_LIBCPP_ALIGNOF(x))))
+# define _LIBCPP_ALWAYS_INLINE __attribute__((__always_inline__))
-#define _LIBCPP_NORETURN __attribute__((noreturn))
+# define _LIBCPP_DISABLE_EXTENSION_WARNING __extension__
-#if !defined(__EXCEPTIONS)
-# define _LIBCPP_NO_EXCEPTIONS
-#endif
+# elif defined(_LIBCPP_COMPILER_GCC)
-#if !defined(__SANITIZE_ADDRESS__)
-#define _LIBCPP_HAS_NO_ASAN
-#endif
-
-#define _LIBCPP_ALWAYS_INLINE __attribute__ ((__always_inline__))
-
-#define _LIBCPP_DISABLE_EXTENSION_WARNING __extension__
+# if !defined(__SANITIZE_ADDRESS__)
+# define _LIBCPP_HAS_NO_ASAN
+# endif
-#elif defined(_LIBCPP_COMPILER_MSVC)
+# define _LIBCPP_ALWAYS_INLINE __attribute__((__always_inline__))
-#define _LIBCPP_TOSTRING2(x) #x
-#define _LIBCPP_TOSTRING(x) _LIBCPP_TOSTRING2(x)
-#define _LIBCPP_WARNING(x) __pragma(message(__FILE__ "(" _LIBCPP_TOSTRING(__LINE__) ") : warning note: " x))
+# define _LIBCPP_DISABLE_EXTENSION_WARNING __extension__
-#if _MSC_VER < 1900
-#error "MSVC versions prior to Visual Studio 2015 are not supported"
-#endif
+# elif defined(_LIBCPP_COMPILER_MSVC)
-#define __alignof__ __alignof
-#define _LIBCPP_NORETURN __declspec(noreturn)
-#define _ALIGNAS(x) __declspec(align(x))
-#define _ALIGNAS_TYPE(x) alignas(x)
+# define _LIBCPP_WARNING(x) __pragma(message(__FILE__ "(" _LIBCPP_TOSTRING(__LINE__) ") : warning note: " x))
-#define _LIBCPP_WEAK
+# if _MSC_VER < 1900
+# error "MSVC versions prior to Visual Studio 2015 are not supported"
+# endif
-#define _LIBCPP_HAS_NO_ASAN
+# define _LIBCPP_NORETURN __declspec(noreturn)
-#define _LIBCPP_ALWAYS_INLINE __forceinline
+# define _LIBCPP_WEAK
-#define _LIBCPP_HAS_NO_VECTOR_EXTENSION
+# define _LIBCPP_HAS_NO_ASAN
-#define _LIBCPP_DISABLE_EXTENSION_WARNING
+# define _LIBCPP_ALWAYS_INLINE __forceinline
-#elif defined(_LIBCPP_COMPILER_IBM)
+# define _LIBCPP_HAS_NO_VECTOR_EXTENSION
-#define _ALIGNAS(x) __attribute__((__aligned__(x)))
-#define _ALIGNAS_TYPE(x) __attribute__((__aligned__(_LIBCPP_ALIGNOF(x))))
-#define _ATTRIBUTE(x) __attribute__((x))
-#define _LIBCPP_NORETURN __attribute__((noreturn))
+# define _LIBCPP_DISABLE_EXTENSION_WARNING
-#define _LIBCPP_HAS_NO_UNICODE_CHARS
+# endif // _LIBCPP_COMPILER_[CLANG|GCC|MSVC]
-#if defined(_AIX)
-#define __MULTILOCALE_API
-#endif
+# if defined(_LIBCPP_OBJECT_FORMAT_COFF)
-#define _LIBCPP_HAS_NO_ASAN
+# ifdef _DLL
+# define _LIBCPP_CRT_FUNC __declspec(dllimport)
+# else
+# define _LIBCPP_CRT_FUNC
+# endif
-#define _LIBCPP_ALWAYS_INLINE __attribute__ ((__always_inline__))
+# if defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS) || (defined(__MINGW32__) && !defined(_LIBCPP_BUILDING_LIBRARY))
+# define _LIBCPP_DLL_VIS
+# define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS
+# define _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS
+# define _LIBCPP_OVERRIDABLE_FUNC_VIS
+# define _LIBCPP_EXPORTED_FROM_ABI
+# elif defined(_LIBCPP_BUILDING_LIBRARY)
+# define _LIBCPP_DLL_VIS __declspec(dllexport)
+# if defined(__MINGW32__)
+# define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS _LIBCPP_DLL_VIS
+# define _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS
+# else
+# define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS
+# define _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS _LIBCPP_DLL_VIS
+# endif
+# define _LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_DLL_VIS
+# define _LIBCPP_EXPORTED_FROM_ABI __declspec(dllexport)
+# else
+# define _LIBCPP_DLL_VIS __declspec(dllimport)
+# define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS _LIBCPP_DLL_VIS
+# define _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS
+# define _LIBCPP_OVERRIDABLE_FUNC_VIS
+# define _LIBCPP_EXPORTED_FROM_ABI __declspec(dllimport)
+# endif
-#define _LIBCPP_HAS_NO_VECTOR_EXTENSION
+# define _LIBCPP_TYPE_VIS _LIBCPP_DLL_VIS
+# define _LIBCPP_FUNC_VIS _LIBCPP_DLL_VIS
+# define _LIBCPP_EXCEPTION_ABI _LIBCPP_DLL_VIS
+# define _LIBCPP_HIDDEN
+# define _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+# define _LIBCPP_TEMPLATE_VIS
+# define _LIBCPP_TEMPLATE_DATA_VIS
+# define _LIBCPP_ENUM_VIS
-#define _LIBCPP_DISABLE_EXTENSION_WARNING
+# else
-#endif // _LIBCPP_COMPILER_[CLANG|GCC|MSVC|IBM]
+# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS)
+# define _LIBCPP_VISIBILITY(vis) __attribute__((__visibility__(vis)))
+# else
+# define _LIBCPP_VISIBILITY(vis)
+# endif
-#if defined(_LIBCPP_OBJECT_FORMAT_COFF)
+# define _LIBCPP_HIDDEN _LIBCPP_VISIBILITY("hidden")
+# define _LIBCPP_FUNC_VIS _LIBCPP_VISIBILITY("default")
+# define _LIBCPP_TYPE_VIS _LIBCPP_VISIBILITY("default")
+# define _LIBCPP_TEMPLATE_DATA_VIS _LIBCPP_VISIBILITY("default")
+# define _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_VISIBILITY("default")
+# define _LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_VISIBILITY("default")
+# define _LIBCPP_EXCEPTION_ABI _LIBCPP_VISIBILITY("default")
+# define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS _LIBCPP_VISIBILITY("default")
+# define _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS
-#ifdef _DLL
-# define _LIBCPP_CRT_FUNC __declspec(dllimport)
-#else
-# define _LIBCPP_CRT_FUNC
-#endif
+# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS)
+// The inline should be removed once PR32114 is resolved
+# define _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS inline _LIBCPP_HIDDEN
+# else
+# define _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+# endif
-#if defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS)
-# define _LIBCPP_DLL_VIS
-# define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS
-# define _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS
-# define _LIBCPP_OVERRIDABLE_FUNC_VIS
-# define _LIBCPP_EXPORTED_FROM_ABI
-#elif defined(_LIBCPP_BUILDING_LIBRARY)
-# define _LIBCPP_DLL_VIS __declspec(dllexport)
-# if defined(__MINGW32__)
-# define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS _LIBCPP_DLL_VIS
-# define _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS
-# else
-# define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS
-# define _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS _LIBCPP_DLL_VIS
-# endif
-# define _LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_DLL_VIS
-# define _LIBCPP_EXPORTED_FROM_ABI __declspec(dllexport)
-#else
-# define _LIBCPP_DLL_VIS __declspec(dllimport)
-# define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS _LIBCPP_DLL_VIS
-# define _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS
-# define _LIBCPP_OVERRIDABLE_FUNC_VIS
-# define _LIBCPP_EXPORTED_FROM_ABI __declspec(dllimport)
-#endif
+# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS)
+# if __has_attribute(__type_visibility__)
+# define _LIBCPP_TEMPLATE_VIS __attribute__((__type_visibility__("default")))
+# else
+# define _LIBCPP_TEMPLATE_VIS __attribute__((__visibility__("default")))
+# endif
+# else
+# define _LIBCPP_TEMPLATE_VIS
+# endif
-#define _LIBCPP_TYPE_VIS _LIBCPP_DLL_VIS
-#define _LIBCPP_FUNC_VIS _LIBCPP_DLL_VIS
-#define _LIBCPP_EXCEPTION_ABI _LIBCPP_DLL_VIS
-#define _LIBCPP_HIDDEN
-#define _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
-#define _LIBCPP_TEMPLATE_VIS
-#define _LIBCPP_TEMPLATE_DATA_VIS
-#define _LIBCPP_ENUM_VIS
+# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS) && __has_attribute(__type_visibility__)
+# define _LIBCPP_ENUM_VIS __attribute__((__type_visibility__("default")))
+# else
+# define _LIBCPP_ENUM_VIS
+# endif
-#endif // defined(_LIBCPP_OBJECT_FORMAT_COFF)
+# endif // defined(_LIBCPP_OBJECT_FORMAT_COFF)
-#ifndef _LIBCPP_HIDDEN
-# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS)
-# define _LIBCPP_HIDDEN __attribute__ ((__visibility__("hidden")))
+# if __has_attribute(internal_linkage)
+# define _LIBCPP_INTERNAL_LINKAGE __attribute__((internal_linkage))
# else
-# define _LIBCPP_HIDDEN
+# define _LIBCPP_INTERNAL_LINKAGE _LIBCPP_ALWAYS_INLINE
# endif
-#endif
-#ifndef _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
-# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS)
-// The inline should be removed once PR32114 is resolved
-# define _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS inline _LIBCPP_HIDDEN
+# if __has_attribute(exclude_from_explicit_instantiation)
+# define _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION __attribute__((__exclude_from_explicit_instantiation__))
# else
-# define _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+// Try to approximate the effect of exclude_from_explicit_instantiation
+// (which is that entities are not assumed to be provided by explicit
+// template instantiations in the dylib) by always inlining those entities.
+# define _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION _LIBCPP_ALWAYS_INLINE
# endif
-#endif
-#ifndef _LIBCPP_FUNC_VIS
-# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS)
-# define _LIBCPP_FUNC_VIS __attribute__ ((__visibility__("default")))
-# else
-# define _LIBCPP_FUNC_VIS
+# ifndef _LIBCPP_HIDE_FROM_ABI_PER_TU
+# ifndef _LIBCPP_HIDE_FROM_ABI_PER_TU_BY_DEFAULT
+# define _LIBCPP_HIDE_FROM_ABI_PER_TU 0
+# else
+# define _LIBCPP_HIDE_FROM_ABI_PER_TU 1
+# endif
# endif
-#endif
-#ifndef _LIBCPP_TYPE_VIS
-# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS)
-# define _LIBCPP_TYPE_VIS __attribute__ ((__visibility__("default")))
-# else
-# define _LIBCPP_TYPE_VIS
+# ifndef _LIBCPP_HIDE_FROM_ABI
+# if _LIBCPP_HIDE_FROM_ABI_PER_TU
+# define _LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDDEN _LIBCPP_INTERNAL_LINKAGE
+# else
+# define _LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDDEN _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION
+# endif
# endif
-#endif
-#ifndef _LIBCPP_TEMPLATE_VIS
-# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS)
-# if __has_attribute(__type_visibility__)
-# define _LIBCPP_TEMPLATE_VIS __attribute__ ((__type_visibility__("default")))
+# ifdef _LIBCPP_BUILDING_LIBRARY
+# if _LIBCPP_ABI_VERSION > 1
+# define _LIBCPP_HIDE_FROM_ABI_AFTER_V1 _LIBCPP_HIDE_FROM_ABI
# else
-# define _LIBCPP_TEMPLATE_VIS __attribute__ ((__visibility__("default")))
+# define _LIBCPP_HIDE_FROM_ABI_AFTER_V1
# endif
# else
-# define _LIBCPP_TEMPLATE_VIS
+# define _LIBCPP_HIDE_FROM_ABI_AFTER_V1 _LIBCPP_HIDE_FROM_ABI
# endif
-#endif
-#ifndef _LIBCPP_TEMPLATE_DATA_VIS
-# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS)
-# define _LIBCPP_TEMPLATE_DATA_VIS __attribute__ ((__visibility__("default")))
-# else
-# define _LIBCPP_TEMPLATE_DATA_VIS
-# endif
-#endif
+// Just so we can migrate to the new macros gradually.
+# define _LIBCPP_INLINE_VISIBILITY _LIBCPP_HIDE_FROM_ABI
-#ifndef _LIBCPP_EXPORTED_FROM_ABI
-# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS)
-# define _LIBCPP_EXPORTED_FROM_ABI __attribute__((__visibility__("default")))
-# else
-# define _LIBCPP_EXPORTED_FROM_ABI
-# endif
-#endif
+// Inline namespaces are available in Clang/GCC/MSVC regardless of C++ dialect.
+// clang-format off
+# define _LIBCPP_BEGIN_NAMESPACE_STD namespace std { inline namespace _LIBCPP_ABI_NAMESPACE {
+# define _LIBCPP_END_NAMESPACE_STD }}
+# define _VSTD std
-#ifndef _LIBCPP_OVERRIDABLE_FUNC_VIS
-#define _LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_FUNC_VIS
-#endif
+_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
-#ifndef _LIBCPP_EXCEPTION_ABI
-# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS)
-# define _LIBCPP_EXCEPTION_ABI __attribute__ ((__visibility__("default")))
+# if _LIBCPP_STD_VER > 14
+# define _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM \
+ _LIBCPP_BEGIN_NAMESPACE_STD inline namespace __fs { namespace filesystem {
# else
-# define _LIBCPP_EXCEPTION_ABI
+# define _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM \
+ _LIBCPP_BEGIN_NAMESPACE_STD namespace __fs { namespace filesystem {
# endif
-#endif
-#ifndef _LIBCPP_ENUM_VIS
-# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS) && __has_attribute(__type_visibility__)
-# define _LIBCPP_ENUM_VIS __attribute__ ((__type_visibility__("default")))
-# else
-# define _LIBCPP_ENUM_VIS
-# endif
-#endif
+# define _LIBCPP_END_NAMESPACE_FILESYSTEM _LIBCPP_END_NAMESPACE_STD }}
+// clang-format on
-#ifndef _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS
-# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS)
-# define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __attribute__ ((__visibility__("default")))
-# else
-# define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS
-# endif
-#endif
+# define _VSTD_FS std::__fs::filesystem
-#ifndef _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS
-#define _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS
-#endif
+# if __has_attribute(__enable_if__)
+# define _LIBCPP_PREFERRED_OVERLOAD __attribute__((__enable_if__(true, "")))
+# endif
-#if __has_attribute(internal_linkage)
-# define _LIBCPP_INTERNAL_LINKAGE __attribute__ ((internal_linkage))
-#else
-# define _LIBCPP_INTERNAL_LINKAGE _LIBCPP_ALWAYS_INLINE
-#endif
+# ifndef __SIZEOF_INT128__
+# define _LIBCPP_HAS_NO_INT128
+# endif
-#if __has_attribute(exclude_from_explicit_instantiation)
-# define _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION __attribute__ ((__exclude_from_explicit_instantiation__))
-#else
- // Try to approximate the effect of exclude_from_explicit_instantiation
- // (which is that entities are not assumed to be provided by explicit
- // template instantiations in the dylib) by always inlining those entities.
-# define _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION _LIBCPP_ALWAYS_INLINE
-#endif
+# ifdef _LIBCPP_CXX03_LANG
+# define static_assert(...) _Static_assert(__VA_ARGS__)
+# define decltype(...) __decltype(__VA_ARGS__)
+# endif // _LIBCPP_CXX03_LANG
-#ifndef _LIBCPP_HIDE_FROM_ABI_PER_TU
-# ifndef _LIBCPP_HIDE_FROM_ABI_PER_TU_BY_DEFAULT
-# define _LIBCPP_HIDE_FROM_ABI_PER_TU 0
+# ifdef _LIBCPP_CXX03_LANG
+# define _LIBCPP_CONSTEXPR
# else
-# define _LIBCPP_HIDE_FROM_ABI_PER_TU 1
+# define _LIBCPP_CONSTEXPR constexpr
# endif
-#endif
-#ifndef _LIBCPP_HIDE_FROM_ABI
-# if _LIBCPP_HIDE_FROM_ABI_PER_TU
-# define _LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDDEN _LIBCPP_INTERNAL_LINKAGE
+# ifndef __cpp_consteval
+# define _LIBCPP_CONSTEVAL _LIBCPP_CONSTEXPR
# else
-# define _LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDDEN _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION
+# define _LIBCPP_CONSTEVAL consteval
# endif
-#endif
-#ifdef _LIBCPP_BUILDING_LIBRARY
-# if _LIBCPP_ABI_VERSION > 1
-# define _LIBCPP_HIDE_FROM_ABI_AFTER_V1 _LIBCPP_HIDE_FROM_ABI
+# ifdef __GNUC__
+# define _LIBCPP_NOALIAS __attribute__((__malloc__))
# else
-# define _LIBCPP_HIDE_FROM_ABI_AFTER_V1
+# define _LIBCPP_NOALIAS
# endif
-#else
-# define _LIBCPP_HIDE_FROM_ABI_AFTER_V1 _LIBCPP_HIDE_FROM_ABI
-#endif
-
-// Just so we can migrate to the new macros gradually.
-#define _LIBCPP_INLINE_VISIBILITY _LIBCPP_HIDE_FROM_ABI
-
-// Inline namespaces are available in Clang/GCC/MSVC regardless of C++ dialect.
-#define _LIBCPP_BEGIN_NAMESPACE_STD namespace std { inline namespace _LIBCPP_ABI_NAMESPACE {
-#define _LIBCPP_END_NAMESPACE_STD } }
-#define _VSTD std
-_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
-
-#if _LIBCPP_STD_VER > 14
-#define _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM \
- _LIBCPP_BEGIN_NAMESPACE_STD inline namespace __fs { namespace filesystem {
-#else
-#define _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM \
- _LIBCPP_BEGIN_NAMESPACE_STD namespace __fs { namespace filesystem {
-#endif
-
-#define _LIBCPP_END_NAMESPACE_FILESYSTEM \
- _LIBCPP_END_NAMESPACE_STD } }
-
-#define _VSTD_FS _VSTD::__fs::filesystem
-
-#if __has_attribute(__enable_if__)
-# define _LIBCPP_PREFERRED_OVERLOAD __attribute__ ((__enable_if__(true, "")))
-#endif
-
-#ifndef _LIBCPP_HAS_NO_NOEXCEPT
-# define _NOEXCEPT noexcept
-# define _NOEXCEPT_(x) noexcept(x)
-#else
-# define _NOEXCEPT throw()
-# define _NOEXCEPT_(x)
-#endif
-
-#ifdef _LIBCPP_HAS_NO_UNICODE_CHARS
-typedef unsigned short char16_t;
-typedef unsigned int char32_t;
-#endif
-
-#ifndef __SIZEOF_INT128__
-#define _LIBCPP_HAS_NO_INT128
-#endif
-
-#ifdef _LIBCPP_CXX03_LANG
-# define static_assert(...) _Static_assert(__VA_ARGS__)
-# define decltype(...) __decltype(__VA_ARGS__)
-#endif // _LIBCPP_CXX03_LANG
-
-#ifdef _LIBCPP_CXX03_LANG
-# define _LIBCPP_CONSTEXPR
-#else
-# define _LIBCPP_CONSTEXPR constexpr
-#endif
-
-#ifndef __cpp_consteval
-# define _LIBCPP_CONSTEVAL _LIBCPP_CONSTEXPR
-#else
-# define _LIBCPP_CONSTEVAL consteval
-#endif
-#if _LIBCPP_STD_VER <= 17 || !defined(__cpp_concepts) || __cpp_concepts < 201907L
-#define _LIBCPP_HAS_NO_CONCEPTS
-#endif
-
-#ifdef __GNUC__
-# define _LIBCPP_NOALIAS __attribute__((__malloc__))
-#else
-# define _LIBCPP_NOALIAS
-#endif
-
-#if __has_attribute(using_if_exists)
-# define _LIBCPP_USING_IF_EXISTS __attribute__((using_if_exists))
-#else
-# define _LIBCPP_USING_IF_EXISTS
-#endif
-
-#ifdef _LIBCPP_HAS_NO_STRONG_ENUMS
-# define _LIBCPP_DECLARE_STRONG_ENUM(x) struct _LIBCPP_TYPE_VIS x { enum __lx
-# define _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(x) \
- __lx __v_; \
- _LIBCPP_INLINE_VISIBILITY x(__lx __v) : __v_(__v) {} \
- _LIBCPP_INLINE_VISIBILITY explicit x(int __v) : __v_(static_cast<__lx>(__v)) {} \
- _LIBCPP_INLINE_VISIBILITY operator int() const {return __v_;} \
- };
-#else // _LIBCPP_HAS_NO_STRONG_ENUMS
-# define _LIBCPP_DECLARE_STRONG_ENUM(x) enum class _LIBCPP_ENUM_VIS x
-# define _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(x)
-#endif // _LIBCPP_HAS_NO_STRONG_ENUMS
-
-// _LIBCPP_DEBUG potential values:
-// - undefined: No assertions. This is the default.
-// - 0: Basic assertions
-// - 1: Basic assertions + iterator validity checks + unspecified behavior randomization.
-# if !defined(_LIBCPP_DEBUG)
-# define _LIBCPP_DEBUG_LEVEL 0
-# elif _LIBCPP_DEBUG == 0
-# define _LIBCPP_DEBUG_LEVEL 1
-# elif _LIBCPP_DEBUG == 1
-# define _LIBCPP_DEBUG_LEVEL 2
+# if __has_attribute(using_if_exists)
+# define _LIBCPP_USING_IF_EXISTS __attribute__((using_if_exists))
# else
-# error Supported values for _LIBCPP_DEBUG are 0 and 1
+# define _LIBCPP_USING_IF_EXISTS
# endif
-# if _LIBCPP_DEBUG_LEVEL >= 2 && !defined(_LIBCPP_CXX03_LANG)
-# define _LIBCPP_DEBUG_RANDOMIZE_UNSPECIFIED_STABILITY
+# ifdef _LIBCPP_CXX03_LANG
+# define _LIBCPP_DECLARE_STRONG_ENUM(x) \
+ struct _LIBCPP_TYPE_VIS x { \
+ enum __lx
+// clang-format off
+# define _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(x) \
+ __lx __v_; \
+ _LIBCPP_INLINE_VISIBILITY x(__lx __v) : __v_(__v) {} \
+ _LIBCPP_INLINE_VISIBILITY explicit x(int __v) : __v_(static_cast<__lx>(__v)) {} \
+ _LIBCPP_INLINE_VISIBILITY operator int() const { return __v_; } \
+ };
+// clang-format on
+
+# else // _LIBCPP_CXX03_LANG
+# define _LIBCPP_DECLARE_STRONG_ENUM(x) enum class _LIBCPP_ENUM_VIS x
+# define _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(x)
+# endif // _LIBCPP_CXX03_LANG
+
+# if defined(__APPLE__) || defined(__FreeBSD__) || defined(_LIBCPP_MSVCRT_LIKE) || defined(__sun__) || \
+ defined(__NetBSD__)
+# define _LIBCPP_LOCALE__L_EXTENSIONS 1
# endif
-# if defined(_LIBCPP_DEBUG_RANDOMIZE_UNSPECIFIED_STABILITY)
-# if defined(_LIBCPP_CXX03_LANG)
-# error Support for unspecified stability is only for C++11 and higher
-# endif
-# define _LIBCPP_DEBUG_RANDOMIZE_RANGE(__first, __last) \
- do { \
- if (!__builtin_is_constant_evaluated()) \
- _VSTD::shuffle(__first, __last, __libcpp_debug_randomizer()); \
- } while (false)
-# else
-# define _LIBCPP_DEBUG_RANDOMIZE_RANGE(__first, __last) \
- do { \
- } while (false)
+# ifdef __FreeBSD__
+# define _DECLARE_C99_LDBL_MATH 1
# endif
-// Libc++ allows disabling extern template instantiation declarations by
-// means of users defining _LIBCPP_DISABLE_EXTERN_TEMPLATE.
-//
-// Furthermore, when the Debug mode is enabled, we disable extern declarations
-// when building user code because we don't want to use the functions compiled
-// in the library, which might not have had the debug mode enabled when built.
-// However, some extern declarations need to be used, because code correctness
-// depends on it (several instances in <locale>). Those special declarations
-// are declared with _LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE, which is enabled
-// even when the debug mode is enabled.
-#if defined(_LIBCPP_DISABLE_EXTERN_TEMPLATE)
-# define _LIBCPP_EXTERN_TEMPLATE(...) /* nothing */
-# define _LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(...) /* nothing */
-#elif _LIBCPP_DEBUG_LEVEL >= 1 && !defined(_LIBCPP_BUILDING_LIBRARY)
-# define _LIBCPP_EXTERN_TEMPLATE(...) /* nothing */
-# define _LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(...) extern template __VA_ARGS__;
-#else
-# define _LIBCPP_EXTERN_TEMPLATE(...) extern template __VA_ARGS__;
-# define _LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(...) extern template __VA_ARGS__;
-#endif
-
-#if defined(__APPLE__) || defined(__FreeBSD__) || defined(_LIBCPP_MSVCRT_LIKE) || \
- defined(__sun__) || defined(__NetBSD__)
-#define _LIBCPP_LOCALE__L_EXTENSIONS 1
-#endif
-
-#ifdef __FreeBSD__
-#define _DECLARE_C99_LDBL_MATH 1
-#endif
-
// If we are getting operator new from the MSVC CRT, then allocation overloads
// for align_val_t were added in 19.12, aka VS 2017 version 15.3.
-#if defined(_LIBCPP_MSVCRT) && defined(_MSC_VER) && _MSC_VER < 1912
-# define _LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION
-#elif defined(_LIBCPP_ABI_VCRUNTIME) && !defined(__cpp_aligned_new)
- // We're deferring to Microsoft's STL to provide aligned new et al. We don't
- // have it unless the language feature test macro is defined.
-# define _LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION
-#elif defined(__MVS__)
-# define _LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION
-#endif
+# if defined(_LIBCPP_MSVCRT) && defined(_MSC_VER) && _MSC_VER < 1912
+# define _LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION
+# elif defined(_LIBCPP_ABI_VCRUNTIME) && !defined(__cpp_aligned_new)
+// We're deferring to Microsoft's STL to provide aligned new et al. We don't
+// have it unless the language feature test macro is defined.
+# define _LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION
+# elif defined(__MVS__)
+# define _LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION
+# endif
-#if defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION) || \
- (!defined(__cpp_aligned_new) || __cpp_aligned_new < 201606)
-# define _LIBCPP_HAS_NO_ALIGNED_ALLOCATION
-#endif
+# if defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION) || (!defined(__cpp_aligned_new) || __cpp_aligned_new < 201606)
+# define _LIBCPP_HAS_NO_ALIGNED_ALLOCATION
+# endif
-#if defined(__APPLE__) || defined(__FreeBSD__)
-#define _LIBCPP_HAS_DEFAULTRUNELOCALE
-#endif
+# if defined(__APPLE__) || defined(__FreeBSD__)
+# define _LIBCPP_HAS_DEFAULTRUNELOCALE
+# endif
-#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__sun__)
-#define _LIBCPP_WCTYPE_IS_MASK
-#endif
+# if defined(__APPLE__) || defined(__FreeBSD__) || defined(__sun__)
+# define _LIBCPP_WCTYPE_IS_MASK
+# endif
-#if _LIBCPP_STD_VER <= 17 || !defined(__cpp_char8_t)
-#define _LIBCPP_HAS_NO_CHAR8_T
-#endif
+# if _LIBCPP_STD_VER <= 17 || !defined(__cpp_char8_t)
+# define _LIBCPP_HAS_NO_CHAR8_T
+# endif
// Deprecation macros.
//
// Deprecations warnings are always enabled, except when users explicitly opt-out
// by defining _LIBCPP_DISABLE_DEPRECATION_WARNINGS.
-#if !defined(_LIBCPP_DISABLE_DEPRECATION_WARNINGS)
-# if __has_attribute(deprecated)
-# define _LIBCPP_DEPRECATED __attribute__ ((deprecated))
-# elif _LIBCPP_STD_VER > 11
-# define _LIBCPP_DEPRECATED [[deprecated]]
+# if !defined(_LIBCPP_DISABLE_DEPRECATION_WARNINGS)
+# if __has_attribute(deprecated)
+# define _LIBCPP_DEPRECATED __attribute__((deprecated))
+# define _LIBCPP_DEPRECATED_(m) __attribute__((deprected(m)))
+# elif _LIBCPP_STD_VER > 11
+# define _LIBCPP_DEPRECATED [[deprecated]]
+# define _LIBCPP_DEPRECATED_(m) [[deprecated(m)]]
+# else
+# define _LIBCPP_DEPRECATED
+# define _LIBCPP_DEPRECATED_(m)
+# endif
# else
# define _LIBCPP_DEPRECATED
+# define _LIBCPP_DEPRECATED_(m)
# endif
-#else
-# define _LIBCPP_DEPRECATED
-#endif
-#if !defined(_LIBCPP_CXX03_LANG)
-# define _LIBCPP_DEPRECATED_IN_CXX11 _LIBCPP_DEPRECATED
-#else
-# define _LIBCPP_DEPRECATED_IN_CXX11
-#endif
+# if !defined(_LIBCPP_CXX03_LANG)
+# define _LIBCPP_DEPRECATED_IN_CXX11 _LIBCPP_DEPRECATED
+# else
+# define _LIBCPP_DEPRECATED_IN_CXX11
+# endif
-#if _LIBCPP_STD_VER >= 14
-# define _LIBCPP_DEPRECATED_IN_CXX14 _LIBCPP_DEPRECATED
-#else
-# define _LIBCPP_DEPRECATED_IN_CXX14
-#endif
+# if _LIBCPP_STD_VER > 11
+# define _LIBCPP_DEPRECATED_IN_CXX14 _LIBCPP_DEPRECATED
+# else
+# define _LIBCPP_DEPRECATED_IN_CXX14
+# endif
-#if _LIBCPP_STD_VER >= 17
-# define _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_DEPRECATED
-#else
-# define _LIBCPP_DEPRECATED_IN_CXX17
-#endif
+# if _LIBCPP_STD_VER > 14
+# define _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_DEPRECATED
+# else
+# define _LIBCPP_DEPRECATED_IN_CXX17
+# endif
-#if _LIBCPP_STD_VER > 17
-# define _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_DEPRECATED
-#else
-# define _LIBCPP_DEPRECATED_IN_CXX20
-#endif
+# if _LIBCPP_STD_VER > 17
+# define _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_DEPRECATED
+# else
+# define _LIBCPP_DEPRECATED_IN_CXX20
+# endif
-#if !defined(_LIBCPP_HAS_NO_CHAR8_T)
-# define _LIBCPP_DEPRECATED_WITH_CHAR8_T _LIBCPP_DEPRECATED
-#else
-# define _LIBCPP_DEPRECATED_WITH_CHAR8_T
-#endif
+# if !defined(_LIBCPP_HAS_NO_CHAR8_T)
+# define _LIBCPP_DEPRECATED_WITH_CHAR8_T _LIBCPP_DEPRECATED
+# else
+# define _LIBCPP_DEPRECATED_WITH_CHAR8_T
+# endif
// Macros to enter and leave a state where deprecation warnings are suppressed.
-#if defined(_LIBCPP_COMPILER_CLANG_BASED) || defined(_LIBCPP_COMPILER_GCC)
-# define _LIBCPP_SUPPRESS_DEPRECATED_PUSH \
- _Pragma("GCC diagnostic push") \
- _Pragma("GCC diagnostic ignored \"-Wdeprecated\"") \
- _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
-# define _LIBCPP_SUPPRESS_DEPRECATED_POP \
- _Pragma("GCC diagnostic pop")
-#else
-# define _LIBCPP_SUPPRESS_DEPRECATED_PUSH
-# define _LIBCPP_SUPPRESS_DEPRECATED_POP
-#endif
+# if defined(_LIBCPP_COMPILER_CLANG_BASED) || defined(_LIBCPP_COMPILER_GCC)
+# define _LIBCPP_SUPPRESS_DEPRECATED_PUSH \
+ _Pragma("GCC diagnostic push") _Pragma("GCC diagnostic ignored \"-Wdeprecated\"") \
+ _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
+# define _LIBCPP_SUPPRESS_DEPRECATED_POP _Pragma("GCC diagnostic pop")
+# else
+# define _LIBCPP_SUPPRESS_DEPRECATED_PUSH
+# define _LIBCPP_SUPPRESS_DEPRECATED_POP
+# endif
-#if _LIBCPP_STD_VER <= 11
-# define _LIBCPP_EXPLICIT_AFTER_CXX11
-#else
-# define _LIBCPP_EXPLICIT_AFTER_CXX11 explicit
-#endif
+# if _LIBCPP_STD_VER <= 11
+# define _LIBCPP_EXPLICIT_AFTER_CXX11
+# else
+# define _LIBCPP_EXPLICIT_AFTER_CXX11 explicit
+# endif
-#if _LIBCPP_STD_VER > 11
-# define _LIBCPP_CONSTEXPR_AFTER_CXX11 constexpr
-#else
-# define _LIBCPP_CONSTEXPR_AFTER_CXX11
-#endif
+# if _LIBCPP_STD_VER > 11
+# define _LIBCPP_CONSTEXPR_AFTER_CXX11 constexpr
+# else
+# define _LIBCPP_CONSTEXPR_AFTER_CXX11
+# endif
-#if _LIBCPP_STD_VER > 14
-# define _LIBCPP_CONSTEXPR_AFTER_CXX14 constexpr
-#else
-# define _LIBCPP_CONSTEXPR_AFTER_CXX14
-#endif
+# if _LIBCPP_STD_VER > 14
+# define _LIBCPP_CONSTEXPR_AFTER_CXX14 constexpr
+# else
+# define _LIBCPP_CONSTEXPR_AFTER_CXX14
+# endif
-#if _LIBCPP_STD_VER > 17
-# define _LIBCPP_CONSTEXPR_AFTER_CXX17 constexpr
-#else
-# define _LIBCPP_CONSTEXPR_AFTER_CXX17
-#endif
+# if _LIBCPP_STD_VER > 17
+# define _LIBCPP_CONSTEXPR_AFTER_CXX17 constexpr
+# else
+# define _LIBCPP_CONSTEXPR_AFTER_CXX17
+# endif
-#if __has_cpp_attribute(nodiscard) || defined(_LIBCPP_COMPILER_MSVC)
-# define _LIBCPP_NODISCARD [[nodiscard]]
-#elif defined(_LIBCPP_COMPILER_CLANG_BASED) && !defined(_LIBCPP_CXX03_LANG)
-# define _LIBCPP_NODISCARD [[clang::warn_unused_result]]
-#else
+# if __has_cpp_attribute(nodiscard) || defined(_LIBCPP_COMPILER_MSVC)
+# define _LIBCPP_NODISCARD [[nodiscard]]
+# elif defined(_LIBCPP_COMPILER_CLANG_BASED) && !defined(_LIBCPP_CXX03_LANG)
+# define _LIBCPP_NODISCARD [[clang::warn_unused_result]]
+# else
// We can't use GCC's [[gnu::warn_unused_result]] and
// __attribute__((warn_unused_result)), because GCC does not silence them via
// (void) cast.
-# define _LIBCPP_NODISCARD
-#endif
+# define _LIBCPP_NODISCARD
+# endif
// _LIBCPP_NODISCARD_EXT may be used to apply [[nodiscard]] to entities not
// specified as such as an extension.
-#if defined(_LIBCPP_ENABLE_NODISCARD) && !defined(_LIBCPP_DISABLE_NODISCARD_EXT)
-# define _LIBCPP_NODISCARD_EXT _LIBCPP_NODISCARD
-#else
-# define _LIBCPP_NODISCARD_EXT
-#endif
+# if defined(_LIBCPP_ENABLE_NODISCARD) && !defined(_LIBCPP_DISABLE_NODISCARD_EXT)
+# define _LIBCPP_NODISCARD_EXT _LIBCPP_NODISCARD
+# else
+# define _LIBCPP_NODISCARD_EXT
+# endif
-#if !defined(_LIBCPP_DISABLE_NODISCARD_AFTER_CXX17) && \
- (_LIBCPP_STD_VER > 17 || defined(_LIBCPP_ENABLE_NODISCARD))
-# define _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_NODISCARD
-#else
-# define _LIBCPP_NODISCARD_AFTER_CXX17
-#endif
+# if !defined(_LIBCPP_DISABLE_NODISCARD_AFTER_CXX17) && (_LIBCPP_STD_VER > 17 || defined(_LIBCPP_ENABLE_NODISCARD))
+# define _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_NODISCARD
+# else
+# define _LIBCPP_NODISCARD_AFTER_CXX17
+# endif
-#if __has_attribute(no_destroy)
-# define _LIBCPP_NO_DESTROY __attribute__((__no_destroy__))
-#else
-# define _LIBCPP_NO_DESTROY
-#endif
+# if __has_attribute(no_destroy)
+# define _LIBCPP_NO_DESTROY __attribute__((__no_destroy__))
+# else
+# define _LIBCPP_NO_DESTROY
+# endif
-#ifndef _LIBCPP_HAS_NO_ASAN
-extern "C" _LIBCPP_FUNC_VIS void __sanitizer_annotate_contiguous_container(
- const void *, const void *, const void *, const void *);
-#endif
+# ifndef _LIBCPP_HAS_NO_ASAN
+ extern "C" _LIBCPP_FUNC_VIS void
+ __sanitizer_annotate_contiguous_container(const void*, const void*, const void*, const void*);
+# endif
// Try to find out if RTTI is disabled.
-#if defined(_LIBCPP_COMPILER_CLANG_BASED) && !__has_feature(cxx_rtti)
-# define _LIBCPP_NO_RTTI
-#elif defined(__GNUC__) && !defined(__GXX_RTTI)
-# define _LIBCPP_NO_RTTI
-#elif defined(_LIBCPP_COMPILER_MSVC) && !defined(_CPPRTTI)
-# define _LIBCPP_NO_RTTI
-#endif
+# if !defined(__cpp_rtti) || __cpp_rtti < 199711L
+# define _LIBCPP_NO_RTTI
+# endif
-#ifndef _LIBCPP_WEAK
-#define _LIBCPP_WEAK __attribute__((__weak__))
-#endif
+# ifndef _LIBCPP_WEAK
+# define _LIBCPP_WEAK __attribute__((__weak__))
+# endif
// Thread API
-#if !defined(_LIBCPP_HAS_NO_THREADS) && \
- !defined(_LIBCPP_HAS_THREAD_API_PTHREAD) && \
- !defined(_LIBCPP_HAS_THREAD_API_WIN32) && \
- !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
-# if defined(__FreeBSD__) || \
- defined(__wasi__) || \
- defined(__NetBSD__) || \
- defined(__OpenBSD__) || \
- defined(__NuttX__) || \
- defined(__linux__) || \
- defined(__GNU__) || \
- defined(__APPLE__) || \
- defined(__sun__) || \
- defined(__MVS__) || \
- defined(_AIX)
-# define _LIBCPP_HAS_THREAD_API_PTHREAD
-# elif defined(__Fuchsia__)
- // TODO(44575): Switch to C11 thread API when possible.
-# define _LIBCPP_HAS_THREAD_API_PTHREAD
-# elif defined(_LIBCPP_WIN32API)
-# define _LIBCPP_HAS_THREAD_API_WIN32
-# else
-# error "No thread API"
-# endif // _LIBCPP_HAS_THREAD_API
-#endif // _LIBCPP_HAS_NO_THREADS
-
-#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
-#if defined(__ANDROID__) && __ANDROID_API__ >= 30
-#define _LIBCPP_HAS_COND_CLOCKWAIT
-#elif defined(_LIBCPP_GLIBC_PREREQ)
-#if _LIBCPP_GLIBC_PREREQ(2, 30)
-#define _LIBCPP_HAS_COND_CLOCKWAIT
-#endif
-#endif
-#endif
+// clang-format off
+# if !defined(_LIBCPP_HAS_NO_THREADS) && \
+ !defined(_LIBCPP_HAS_THREAD_API_PTHREAD) && \
+ !defined(_LIBCPP_HAS_THREAD_API_WIN32) && \
+ !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
+
+# if defined(__FreeBSD__) || \
+ defined(__wasi__) || \
+ defined(__NetBSD__) || \
+ defined(__OpenBSD__) || \
+ defined(__NuttX__) || \
+ defined(__linux__) || \
+ defined(__GNU__) || \
+ defined(__APPLE__) || \
+ defined(__sun__) || \
+ defined(__MVS__) || \
+ defined(_AIX) || \
+ defined(__EMSCRIPTEN__)
+// clang-format on
+# define _LIBCPP_HAS_THREAD_API_PTHREAD
+# elif defined(__Fuchsia__)
+// TODO(44575): Switch to C11 thread API when possible.
+# define _LIBCPP_HAS_THREAD_API_PTHREAD
+# elif defined(_LIBCPP_WIN32API)
+# define _LIBCPP_HAS_THREAD_API_WIN32
+# else
+# error "No thread API"
+# endif // _LIBCPP_HAS_THREAD_API
+# endif // _LIBCPP_HAS_NO_THREADS
+
+# if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
+# if defined(__ANDROID__) && __ANDROID_API__ >= 30
+# define _LIBCPP_HAS_COND_CLOCKWAIT
+# elif defined(_LIBCPP_GLIBC_PREREQ)
+# if _LIBCPP_GLIBC_PREREQ(2, 30)
+# define _LIBCPP_HAS_COND_CLOCKWAIT
+# endif
+# endif
+# endif
-#if defined(_LIBCPP_HAS_NO_THREADS) && defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
-#error _LIBCPP_HAS_THREAD_API_PTHREAD may only be defined when \
+# if defined(_LIBCPP_HAS_NO_THREADS) && defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
+# error _LIBCPP_HAS_THREAD_API_PTHREAD may only be defined when \
_LIBCPP_HAS_NO_THREADS is not defined.
-#endif
+# endif
-#if defined(_LIBCPP_HAS_NO_THREADS) && defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
-#error _LIBCPP_HAS_THREAD_API_EXTERNAL may not be defined when \
+# if defined(_LIBCPP_HAS_NO_THREADS) && defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
+# error _LIBCPP_HAS_THREAD_API_EXTERNAL may not be defined when \
_LIBCPP_HAS_NO_THREADS is defined.
-#endif
+# endif
-#if defined(_LIBCPP_HAS_NO_MONOTONIC_CLOCK) && !defined(_LIBCPP_HAS_NO_THREADS)
-#error _LIBCPP_HAS_NO_MONOTONIC_CLOCK may only be defined when \
+# if defined(_LIBCPP_HAS_NO_MONOTONIC_CLOCK) && !defined(_LIBCPP_HAS_NO_THREADS)
+# error _LIBCPP_HAS_NO_MONOTONIC_CLOCK may only be defined when \
_LIBCPP_HAS_NO_THREADS is defined.
-#endif
+# endif
-#if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(__STDCPP_THREADS__)
-#define __STDCPP_THREADS__ 1
-#endif
+# if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(__STDCPP_THREADS__)
+# define __STDCPP_THREADS__ 1
+# endif
// The glibc and Bionic implementation of pthreads implements
// pthread_mutex_destroy as nop for regular mutexes. Additionally, Win32
@@ -1195,11 +925,13 @@ extern "C" _LIBCPP_FUNC_VIS void __sanitizer_annotate_contiguous_container(
//
// TODO(EricWF): Enable this optimization on Bionic after speaking to their
// respective stakeholders.
-#if (defined(_LIBCPP_HAS_THREAD_API_PTHREAD) && defined(__GLIBC__)) \
- || (defined(_LIBCPP_HAS_THREAD_API_C11) && defined(__Fuchsia__)) \
- || defined(_LIBCPP_HAS_THREAD_API_WIN32)
-# define _LIBCPP_HAS_TRIVIAL_MUTEX_DESTRUCTION
-#endif
+// clang-format off
+# if (defined(_LIBCPP_HAS_THREAD_API_PTHREAD) && defined(__GLIBC__)) || \
+ (defined(_LIBCPP_HAS_THREAD_API_C11) && defined(__Fuchsia__)) || \
+ defined(_LIBCPP_HAS_THREAD_API_WIN32)
+// clang-format on
+# define _LIBCPP_HAS_TRIVIAL_MUTEX_DESTRUCTION
+# endif
// Destroying a condvar is a nop on Windows.
//
@@ -1209,225 +941,245 @@ extern "C" _LIBCPP_FUNC_VIS void __sanitizer_annotate_contiguous_container(
//
// TODO(EricWF): This is potentially true for some pthread implementations
// as well.
-#if (defined(_LIBCPP_HAS_THREAD_API_C11) && defined(__Fuchsia__)) || \
- defined(_LIBCPP_HAS_THREAD_API_WIN32)
-# define _LIBCPP_HAS_TRIVIAL_CONDVAR_DESTRUCTION
-#endif
+# if (defined(_LIBCPP_HAS_THREAD_API_C11) && defined(__Fuchsia__)) || defined(_LIBCPP_HAS_THREAD_API_WIN32)
+# define _LIBCPP_HAS_TRIVIAL_CONDVAR_DESTRUCTION
+# endif
// Some systems do not provide gets() in their C library, for security reasons.
-#if defined(_LIBCPP_MSVCRT) || \
- (defined(__FreeBSD_version) && __FreeBSD_version >= 1300043) || \
- defined(__OpenBSD__)
-# define _LIBCPP_C_HAS_NO_GETS
-#endif
-
-#if defined(__BIONIC__) || defined(__NuttX__) || \
- defined(__Fuchsia__) || defined(__wasi__) || \
- defined(_LIBCPP_HAS_MUSL_LIBC) || defined(__OpenBSD__)
-#define _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE
-#endif
+# if defined(_LIBCPP_MSVCRT) || (defined(__FreeBSD_version) && __FreeBSD_version >= 1300043) || defined(__OpenBSD__)
+# define _LIBCPP_C_HAS_NO_GETS
+# endif
-#if __has_feature(cxx_atomic) || __has_extension(c_atomic) || __has_keyword(_Atomic)
-# define _LIBCPP_HAS_C_ATOMIC_IMP
-#elif defined(_LIBCPP_COMPILER_GCC)
-# define _LIBCPP_HAS_GCC_ATOMIC_IMP
-#endif
+# if defined(__BIONIC__) || defined(__NuttX__) || defined(__Fuchsia__) || defined(__wasi__) || \
+ defined(_LIBCPP_HAS_MUSL_LIBC) || defined(__OpenBSD__)
+# define _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE
+# endif
-#if !defined(_LIBCPP_HAS_C_ATOMIC_IMP) && \
- !defined(_LIBCPP_HAS_GCC_ATOMIC_IMP) && \
- !defined(_LIBCPP_HAS_EXTERNAL_ATOMIC_IMP)
-# define _LIBCPP_HAS_NO_ATOMIC_HEADER
-#else
-# ifndef _LIBCPP_ATOMIC_FLAG_TYPE
-# define _LIBCPP_ATOMIC_FLAG_TYPE bool
+# if __has_feature(cxx_atomic) || __has_extension(c_atomic) || __has_keyword(_Atomic)
+# define _LIBCPP_HAS_C_ATOMIC_IMP
+# elif defined(_LIBCPP_COMPILER_GCC)
+# define _LIBCPP_HAS_GCC_ATOMIC_IMP
# endif
-# ifdef _LIBCPP_FREESTANDING
-# define _LIBCPP_ATOMIC_ONLY_USE_BUILTINS
+
+# if !defined(_LIBCPP_HAS_C_ATOMIC_IMP) && !defined(_LIBCPP_HAS_GCC_ATOMIC_IMP) && \
+ !defined(_LIBCPP_HAS_EXTERNAL_ATOMIC_IMP)
+# define _LIBCPP_HAS_NO_ATOMIC_HEADER
+# else
+# ifndef _LIBCPP_ATOMIC_FLAG_TYPE
+# define _LIBCPP_ATOMIC_FLAG_TYPE bool
+# endif
+# ifdef _LIBCPP_FREESTANDING
+# define _LIBCPP_ATOMIC_ONLY_USE_BUILTINS
+# endif
# endif
-#endif
-#ifndef _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
-#define _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
-#endif
+# ifndef _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
+# define _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
+# endif
-#if defined(_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS)
-# if defined(__clang__) && __has_attribute(acquire_capability)
+# if defined(_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS)
+# if defined(__clang__) && __has_attribute(acquire_capability)
// Work around the attribute handling in clang. When both __declspec and
// __attribute__ are present, the processing goes awry preventing the definition
// of the types. In MinGW mode, __declspec evaluates to __attribute__, and thus
// combining the two does work.
-# if !defined(_MSC_VER)
-# define _LIBCPP_HAS_THREAD_SAFETY_ANNOTATIONS
+# if !defined(_MSC_VER)
+# define _LIBCPP_HAS_THREAD_SAFETY_ANNOTATIONS
+# endif
# endif
# endif
-#endif
-#ifdef _LIBCPP_HAS_THREAD_SAFETY_ANNOTATIONS
-# define _LIBCPP_THREAD_SAFETY_ANNOTATION(x) __attribute__((x))
-#else
-# define _LIBCPP_THREAD_SAFETY_ANNOTATION(x)
-#endif
+# ifdef _LIBCPP_HAS_THREAD_SAFETY_ANNOTATIONS
+# define _LIBCPP_THREAD_SAFETY_ANNOTATION(x) __attribute__((x))
+# else
+# define _LIBCPP_THREAD_SAFETY_ANNOTATION(x)
+# endif
-#if __has_attribute(require_constant_initialization)
-# define _LIBCPP_SAFE_STATIC __attribute__((__require_constant_initialization__))
-#else
-# define _LIBCPP_SAFE_STATIC
-#endif
+# if _LIBCPP_STD_VER > 17
+# define _LIBCPP_CONSTINIT constinit
+# elif __has_attribute(require_constant_initialization)
+# define _LIBCPP_CONSTINIT __attribute__((__require_constant_initialization__))
+# else
+# define _LIBCPP_CONSTINIT
+# endif
-#if __has_attribute(diagnose_if) && !defined(_LIBCPP_DISABLE_ADDITIONAL_DIAGNOSTICS)
-# define _LIBCPP_DIAGNOSE_WARNING(...) \
- __attribute__((diagnose_if(__VA_ARGS__, "warning")))
-# define _LIBCPP_DIAGNOSE_ERROR(...) \
- __attribute__((diagnose_if(__VA_ARGS__, "error")))
-#else
-# define _LIBCPP_DIAGNOSE_WARNING(...)
-# define _LIBCPP_DIAGNOSE_ERROR(...)
-#endif
+# if __has_attribute(diagnose_if) && !defined(_LIBCPP_DISABLE_ADDITIONAL_DIAGNOSTICS)
+# define _LIBCPP_DIAGNOSE_WARNING(...) __attribute__((diagnose_if(__VA_ARGS__, "warning")))
+# define _LIBCPP_DIAGNOSE_ERROR(...) __attribute__((diagnose_if(__VA_ARGS__, "error")))
+# else
+# define _LIBCPP_DIAGNOSE_WARNING(...)
+# define _LIBCPP_DIAGNOSE_ERROR(...)
+# endif
// Use a function like macro to imply that it must be followed by a semicolon
-#if __cplusplus > 201402L && __has_cpp_attribute(fallthrough)
-# define _LIBCPP_FALLTHROUGH() [[fallthrough]]
-#elif __has_cpp_attribute(clang::fallthrough)
-# define _LIBCPP_FALLTHROUGH() [[clang::fallthrough]]
-#elif __has_attribute(__fallthrough__)
-# define _LIBCPP_FALLTHROUGH() __attribute__((__fallthrough__))
-#else
-# define _LIBCPP_FALLTHROUGH() ((void)0)
-#endif
+# if __has_cpp_attribute(fallthrough)
+# define _LIBCPP_FALLTHROUGH() [[fallthrough]]
+# elif __has_attribute(__fallthrough__)
+# define _LIBCPP_FALLTHROUGH() __attribute__((__fallthrough__))
+# else
+# define _LIBCPP_FALLTHROUGH() ((void)0)
+# endif
-#if __has_attribute(__nodebug__)
-#define _LIBCPP_NODEBUG __attribute__((__nodebug__))
-#else
-#define _LIBCPP_NODEBUG
-#endif
+# if __has_attribute(__nodebug__)
+# define _LIBCPP_NODEBUG __attribute__((__nodebug__))
+# else
+# define _LIBCPP_NODEBUG
+# endif
-#if __has_attribute(__standalone_debug__)
-#define _LIBCPP_STANDALONE_DEBUG __attribute__((__standalone_debug__))
-#else
-#define _LIBCPP_STANDALONE_DEBUG
-#endif
+# if __has_attribute(__standalone_debug__)
+# define _LIBCPP_STANDALONE_DEBUG __attribute__((__standalone_debug__))
+# else
+# define _LIBCPP_STANDALONE_DEBUG
+# endif
-#if __has_attribute(__preferred_name__)
-#define _LIBCPP_PREFERRED_NAME(x) __attribute__((__preferred_name__(x)))
-#else
-#define _LIBCPP_PREFERRED_NAME(x)
-#endif
+# if __has_attribute(__preferred_name__)
+# define _LIBCPP_PREFERRED_NAME(x) __attribute__((__preferred_name__(x)))
+# else
+# define _LIBCPP_PREFERRED_NAME(x)
+# endif
// We often repeat things just for handling wide characters in the library.
// When wide characters are disabled, it can be useful to have a quick way of
// disabling it without having to resort to #if-#endif, which has a larger
// impact on readability.
-#if defined(_LIBCPP_HAS_NO_WIDE_CHARACTERS)
-# define _LIBCPP_IF_WIDE_CHARACTERS(...)
-#else
-# define _LIBCPP_IF_WIDE_CHARACTERS(...) __VA_ARGS__
-#endif
-
-#if defined(_LIBCPP_ABI_MICROSOFT) && \
- (defined(_LIBCPP_COMPILER_MSVC) || __has_declspec_attribute(empty_bases))
-# define _LIBCPP_DECLSPEC_EMPTY_BASES __declspec(empty_bases)
-#else
-# define _LIBCPP_DECLSPEC_EMPTY_BASES
-#endif
-
-#if defined(_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES)
-#define _LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR
-#define _LIBCPP_ENABLE_CXX17_REMOVED_BINDERS
-#define _LIBCPP_ENABLE_CXX17_REMOVED_RANDOM_SHUFFLE
-#define _LIBCPP_ENABLE_CXX17_REMOVED_UNEXPECTED_FUNCTIONS
-#endif // _LIBCPP_ENABLE_CXX17_REMOVED_FEATURES
-
-#if defined(_LIBCPP_ENABLE_CXX20_REMOVED_FEATURES)
-#define _LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS
-#define _LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS
-#define _LIBCPP_ENABLE_CXX20_REMOVED_NEGATORS
-#define _LIBCPP_ENABLE_CXX20_REMOVED_RAW_STORAGE_ITERATOR
-#define _LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS
-#endif // _LIBCPP_ENABLE_CXX20_REMOVED_FEATURES
-
-#if !defined(__cpp_impl_coroutine) || __cpp_impl_coroutine < 201902L
-#define _LIBCPP_HAS_NO_CXX20_COROUTINES
-#endif
-
-#if defined(_LIBCPP_COMPILER_IBM)
-#define _LIBCPP_HAS_NO_PRAGMA_PUSH_POP_MACRO
-#endif
+# if defined(_LIBCPP_HAS_NO_WIDE_CHARACTERS)
+# define _LIBCPP_IF_WIDE_CHARACTERS(...)
+# else
+# define _LIBCPP_IF_WIDE_CHARACTERS(...) __VA_ARGS__
+# endif
-#if defined(_LIBCPP_HAS_NO_PRAGMA_PUSH_POP_MACRO)
-# define _LIBCPP_PUSH_MACROS
-# define _LIBCPP_POP_MACROS
-#else
- // Don't warn about macro conflicts when we can restore them at the
- // end of the header.
-# ifndef _LIBCPP_DISABLE_MACRO_CONFLICT_WARNINGS
-# define _LIBCPP_DISABLE_MACRO_CONFLICT_WARNINGS
-# endif
-# if defined(_LIBCPP_COMPILER_MSVC)
-# define _LIBCPP_PUSH_MACROS \
- __pragma(push_macro("min")) \
- __pragma(push_macro("max"))
-# define _LIBCPP_POP_MACROS \
- __pragma(pop_macro("min")) \
- __pragma(pop_macro("max"))
+# if defined(_LIBCPP_ABI_MICROSOFT) && (defined(_LIBCPP_COMPILER_MSVC) || __has_declspec_attribute(empty_bases))
+# define _LIBCPP_DECLSPEC_EMPTY_BASES __declspec(empty_bases)
# else
-# define _LIBCPP_PUSH_MACROS \
- _Pragma("push_macro(\"min\")") \
- _Pragma("push_macro(\"max\")")
-# define _LIBCPP_POP_MACROS \
- _Pragma("pop_macro(\"min\")") \
- _Pragma("pop_macro(\"max\")")
+# define _LIBCPP_DECLSPEC_EMPTY_BASES
# endif
-#endif // defined(_LIBCPP_HAS_NO_PRAGMA_PUSH_POP_MACRO)
-#ifndef _LIBCPP_NO_AUTO_LINK
-# if defined(_LIBCPP_ABI_MICROSOFT) && !defined(_LIBCPP_BUILDING_LIBRARY)
-# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS)
-# pragma comment(lib, "c++.lib")
-# else
-# pragma comment(lib, "libc++.lib")
-# endif
-# endif // defined(_LIBCPP_ABI_MICROSOFT) && !defined(_LIBCPP_BUILDING_LIBRARY)
-#endif // _LIBCPP_NO_AUTO_LINK
+# if defined(_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES)
+# define _LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR
+# define _LIBCPP_ENABLE_CXX17_REMOVED_BINDERS
+# define _LIBCPP_ENABLE_CXX17_REMOVED_RANDOM_SHUFFLE
+# define _LIBCPP_ENABLE_CXX17_REMOVED_UNEXPECTED_FUNCTIONS
+# define _LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION
+# endif // _LIBCPP_ENABLE_CXX17_REMOVED_FEATURES
+
+# if defined(_LIBCPP_ENABLE_CXX20_REMOVED_FEATURES)
+# define _LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS
+# define _LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_VOID_SPECIALIZATION
+# define _LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS
+# define _LIBCPP_ENABLE_CXX20_REMOVED_NEGATORS
+# define _LIBCPP_ENABLE_CXX20_REMOVED_RAW_STORAGE_ITERATOR
+# define _LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS
+# endif // _LIBCPP_ENABLE_CXX20_REMOVED_FEATURES
+
+# if !defined(__cpp_impl_coroutine) || __cpp_impl_coroutine < 201902L
+# define _LIBCPP_HAS_NO_CXX20_COROUTINES
+# endif
+
+# define _LIBCPP_PUSH_MACROS _Pragma("push_macro(\"min\")") _Pragma("push_macro(\"max\")")
+# define _LIBCPP_POP_MACROS _Pragma("pop_macro(\"min\")") _Pragma("pop_macro(\"max\")")
+
+# ifndef _LIBCPP_NO_AUTO_LINK
+# if defined(_LIBCPP_ABI_MICROSOFT) && !defined(_LIBCPP_BUILDING_LIBRARY)
+# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS)
+# pragma comment(lib, "c++.lib")
+# else
+# pragma comment(lib, "libc++.lib")
+# endif
+# endif // defined(_LIBCPP_ABI_MICROSOFT) && !defined(_LIBCPP_BUILDING_LIBRARY)
+# endif // _LIBCPP_NO_AUTO_LINK
// Configures the fopen close-on-exec mode character, if any. This string will
// be appended to any mode string used by fstream for fopen/fdopen.
//
// Not all platforms support this, but it helps avoid fd-leaks on platforms that
// do.
-#if defined(__BIONIC__)
-# define _LIBCPP_FOPEN_CLOEXEC_MODE "e"
-#else
-# define _LIBCPP_FOPEN_CLOEXEC_MODE
-#endif
+# if defined(__BIONIC__)
+# define _LIBCPP_FOPEN_CLOEXEC_MODE "e"
+# else
+# define _LIBCPP_FOPEN_CLOEXEC_MODE
+# endif
// Support for _FILE_OFFSET_BITS=64 landed gradually in Android, so the full set
// of functions used in cstdio may not be available for low API levels when
// using 64-bit file offsets on LP32.
-#if defined(__BIONIC__) && defined(__USE_FILE_OFFSET64) && __ANDROID_API__ < 24
-#define _LIBCPP_HAS_NO_FGETPOS_FSETPOS
-#endif
+# if defined(__BIONIC__) && defined(__USE_FILE_OFFSET64) && __ANDROID_API__ < 24
+# define _LIBCPP_HAS_NO_FGETPOS_FSETPOS
+# endif
-#if __has_attribute(init_priority)
- // TODO: Remove this once we drop support for building libc++ with old Clangs
-# if (defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER < 1200) || \
- (defined(__apple_build_version__) && __apple_build_version__ < 13000000)
-# define _LIBCPP_INIT_PRIORITY_MAX __attribute__((init_priority(101)))
-# else
-# define _LIBCPP_INIT_PRIORITY_MAX __attribute__((init_priority(100)))
-# endif
-#else
-# define _LIBCPP_INIT_PRIORITY_MAX
-#endif
+# if __has_attribute(init_priority)
+// TODO: Remove this once we drop support for building libc++ with old Clangs
+# if (defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER < 1200) || \
+ (defined(__apple_build_version__) && __apple_build_version__ < 13000000)
+# define _LIBCPP_INIT_PRIORITY_MAX __attribute__((init_priority(101)))
+# else
+# define _LIBCPP_INIT_PRIORITY_MAX __attribute__((init_priority(100)))
+# endif
+# else
+# define _LIBCPP_INIT_PRIORITY_MAX
+# endif
-#if defined(__GNUC__) || defined(__clang__)
- // The attribute uses 1-based indices for ordinary and static member functions.
- // The attribute uses 2-based indices for non-static member functions.
-# define _LIBCPP_ATTRIBUTE_FORMAT(archetype, format_string_index, first_format_arg_index) \
- __attribute__((__format__(archetype, format_string_index, first_format_arg_index)))
-#else
-# define _LIBCPP_ATTRIBUTE_FORMAT(archetype, format_string_index, first_format_arg_index) /* nothing */
-#endif
+# if defined(__GNUC__) || defined(__clang__)
+// The attribute uses 1-based indices for ordinary and static member functions.
+// The attribute uses 2-based indices for non-static member functions.
+# define _LIBCPP_ATTRIBUTE_FORMAT(archetype, format_string_index, first_format_arg_index) \
+ __attribute__((__format__(archetype, format_string_index, first_format_arg_index)))
+# else
+# define _LIBCPP_ATTRIBUTE_FORMAT(archetype, format_string_index, first_format_arg_index) /* nothing */
+# endif
+
+# if __has_cpp_attribute(msvc::no_unique_address)
+// MSVC implements [[no_unique_address]] as a silent no-op currently.
+// (If/when MSVC breaks its C++ ABI, it will be changed to work as intended.)
+// However, MSVC implements [[msvc::no_unique_address]] which does what
+// [[no_unique_address]] is supposed to do, in general.
+
+// Clang-cl does not yet (14.0) implement either [[no_unique_address]] or
+// [[msvc::no_unique_address]] though. If/when it does implement
+// [[msvc::no_unique_address]], this should be preferred though.
+# define _LIBCPP_NO_UNIQUE_ADDRESS [[msvc::no_unique_address]]
+# elif __has_cpp_attribute(no_unique_address)
+# define _LIBCPP_NO_UNIQUE_ADDRESS [[no_unique_address]]
+# else
+# define _LIBCPP_NO_UNIQUE_ADDRESS /* nothing */
+// Note that this can be replaced by #error as soon as clang-cl
+// implements msvc::no_unique_address, since there should be no C++20
+// compiler that doesn't support one of the two attributes at that point.
+// We generally don't want to use this macro outside of C++20-only code,
+// because using it conditionally in one language version only would make
+// the ABI inconsistent.
+# endif
+
+# ifdef _LIBCPP_COMPILER_CLANG_BASED
+# define _LIBCPP_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push")
+# define _LIBCPP_DIAGNOSTIC_POP _Pragma("clang diagnostic pop")
+# define _LIBCPP_CLANG_DIAGNOSTIC_IGNORED(str) _Pragma(_LIBCPP_TOSTRING(clang diagnostic ignored str))
+# define _LIBCPP_GCC_DIAGNOSTIC_IGNORED(str)
+# elif defined(_LIBCPP_COMPILER_GCC)
+# define _LIBCPP_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push")
+# define _LIBCPP_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop")
+# define _LIBCPP_CLANG_DIAGNOSTIC_IGNORED(str)
+# define _LIBCPP_GCC_DIAGNOSTIC_IGNORED(str) _Pragma(_LIBCPP_TOSTRING(GCC diagnostic ignored str))
+# else
+# define _LIBCPP_DIAGNOSTIC_PUSH
+# define _LIBCPP_DIAGNOSTIC_POP
+# define _LIBCPP_CLANG_DIAGNOSTIC_IGNORED(str)
+# define _LIBCPP_GCC_DIAGNOSTIC_IGNORED(str)
+# endif
+
+# if defined(_AIX) && !defined(_LIBCPP_COMPILER_GCC)
+# define _LIBCPP_PACKED_BYTE_FOR_AIX _Pragma("pack(1)")
+# define _LIBCPP_PACKED_BYTE_FOR_AIX_END _Pragma("pack(pop)")
+# else
+# define _LIBCPP_PACKED_BYTE_FOR_AIX /* empty */
+# define _LIBCPP_PACKED_BYTE_FOR_AIX_END /* empty */
+# endif
+
+# if __has_attribute(__packed__)
+# define _LIBCPP_PACKED __attribute__((__packed__))
+# else
+# define _LIBCPP_PACKED
+# endif
#endif // __cplusplus
-#endif // _LIBCPP_CONFIG
+#endif // _LIBCPP___CONFIG
diff --git a/libcxx/include/__coroutine/coroutine_handle.h b/libcxx/include/__coroutine/coroutine_handle.h
index 64657c0585b9..4bf323789217 100644
--- a/libcxx/include/__coroutine/coroutine_handle.h
+++ b/libcxx/include/__coroutine/coroutine_handle.h
@@ -9,15 +9,15 @@
#ifndef _LIBCPP___COROUTINE_COROUTINE_HANDLE_H
#define _LIBCPP___COROUTINE_COROUTINE_HANDLE_H
+#include <__assert>
#include <__config>
-#include <__debug>
#include <__functional/hash.h>
#include <__memory/addressof.h>
#include <compare>
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CXX20_COROUTINES)
diff --git a/libcxx/include/__coroutine/coroutine_traits.h b/libcxx/include/__coroutine/coroutine_traits.h
index bfa69552bd79..0a5229b45945 100644
--- a/libcxx/include/__coroutine/coroutine_traits.h
+++ b/libcxx/include/__coroutine/coroutine_traits.h
@@ -13,7 +13,7 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CXX20_COROUTINES)
diff --git a/libcxx/include/__coroutine/noop_coroutine_handle.h b/libcxx/include/__coroutine/noop_coroutine_handle.h
index a29e202f4e4f..7a2c672057cb 100644
--- a/libcxx/include/__coroutine/noop_coroutine_handle.h
+++ b/libcxx/include/__coroutine/noop_coroutine_handle.h
@@ -13,7 +13,7 @@
#include <__coroutine/coroutine_handle.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CXX20_COROUTINES)
@@ -66,7 +66,7 @@ private:
friend coroutine_handle<noop_coroutine_promise> noop_coroutine() noexcept;
#if __has_builtin(__builtin_coro_noop)
- _LIBCPP_HIDE_FROM_ABI coroutine_handle() noexcept {
+ _LIBCPP_HIDE_FROM_ABI coroutine_handle() noexcept {
this->__handle_ = __builtin_coro_noop();
}
diff --git a/libcxx/include/__coroutine/trivial_awaitables.h b/libcxx/include/__coroutine/trivial_awaitables.h
index c434f83b78bb..31399ab29a00 100644
--- a/libcxx/include/__coroutine/trivial_awaitables.h
+++ b/libcxx/include/__coroutine/trivial_awaitables.h
@@ -13,7 +13,7 @@
#include <__coroutine/coroutine_handle.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CXX20_COROUTINES)
diff --git a/libcxx/include/__debug b/libcxx/include/__debug
index a1e21a703224..d3dd202b54ab 100644
--- a/libcxx/include/__debug
+++ b/libcxx/include/__debug
@@ -7,79 +7,52 @@
//
//===----------------------------------------------------------------------===//
-#ifndef _LIBCPP_DEBUG_H
-#define _LIBCPP_DEBUG_H
+#ifndef _LIBCPP___DEBUG
+#define _LIBCPP___DEBUG
+#include <__assert>
#include <__config>
-#include <iosfwd>
+#include <cstddef>
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
-#if defined(_LIBCPP_HAS_NO_NULLPTR)
-# include <cstddef>
+// Catch invalid uses of the legacy _LIBCPP_DEBUG toggle.
+#if defined(_LIBCPP_DEBUG) && _LIBCPP_DEBUG != 0 && !defined(_LIBCPP_ENABLE_DEBUG_MODE)
+# error "Enabling the debug mode now requires having configured the library with support for the debug mode"
#endif
-#if _LIBCPP_DEBUG_LEVEL >= 1 || defined(_LIBCPP_BUILDING_LIBRARY)
-# include <cstddef>
-# include <cstdio>
-# include <cstdlib>
+#if defined(_LIBCPP_ENABLE_DEBUG_MODE) && !defined(_LIBCPP_CXX03_LANG) && !defined(_LIBCPP_DEBUG_RANDOMIZE_UNSPECIFIED_STABILITY)
+# define _LIBCPP_DEBUG_RANDOMIZE_UNSPECIFIED_STABILITY
#endif
-#if _LIBCPP_DEBUG_LEVEL == 0
-# define _LIBCPP_DEBUG_ASSERT(x, m) ((void)0)
-# define _LIBCPP_ASSERT_IMPL(x, m) ((void)0)
-#elif _LIBCPP_DEBUG_LEVEL == 1
-# define _LIBCPP_DEBUG_ASSERT(x, m) ((void)0)
-# define _LIBCPP_ASSERT_IMPL(x, m) ((x) ? (void)0 : _VSTD::__libcpp_debug_function(_VSTD::__libcpp_debug_info(__FILE__, __LINE__, #x, m)))
-#elif _LIBCPP_DEBUG_LEVEL == 2
-# define _LIBCPP_DEBUG_ASSERT(x, m) _LIBCPP_ASSERT(__libcpp_is_constant_evaluated() || (x), m)
-# define _LIBCPP_ASSERT_IMPL(x, m) ((x) ? (void)0 : _VSTD::__libcpp_debug_function(_VSTD::__libcpp_debug_info(__FILE__, __LINE__, #x, m)))
+// TODO: Define this as a function instead
+#if defined(_LIBCPP_DEBUG_RANDOMIZE_UNSPECIFIED_STABILITY)
+# if defined(_LIBCPP_CXX03_LANG)
+# error Support for unspecified stability is only for C++11 and higher
+# endif
+# define _LIBCPP_DEBUG_RANDOMIZE_RANGE(__first, __last) \
+ do { \
+ if (!__builtin_is_constant_evaluated()) \
+ std::shuffle(__first, __last, __libcpp_debug_randomizer()); \
+ } while (false)
#else
-# error _LIBCPP_DEBUG_LEVEL must be one of 0, 1, 2
+# define _LIBCPP_DEBUG_RANDOMIZE_RANGE(__first, __last) \
+ do { \
+ } while (false)
#endif
-#if !defined(_LIBCPP_ASSERT)
-# define _LIBCPP_ASSERT(x, m) _LIBCPP_ASSERT_IMPL(x, m)
+#ifdef _LIBCPP_ENABLE_DEBUG_MODE
+# define _LIBCPP_DEBUG_ASSERT(x, m) _LIBCPP_ASSERT(::std::__libcpp_is_constant_evaluated() || (x), m)
+#else
+# define _LIBCPP_DEBUG_ASSERT(x, m) ((void)0)
#endif
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-struct _LIBCPP_TEMPLATE_VIS __libcpp_debug_info {
- _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
- __libcpp_debug_info()
- : __file_(nullptr), __line_(-1), __pred_(nullptr), __msg_(nullptr) {}
- _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
- __libcpp_debug_info(const char* __f, int __l, const char* __p, const char* __m)
- : __file_(__f), __line_(__l), __pred_(__p), __msg_(__m) {}
-
- _LIBCPP_FUNC_VIS string what() const;
-
- const char* __file_;
- int __line_;
- const char* __pred_;
- const char* __msg_;
-};
-
-/// __libcpp_debug_function_type - The type of the assertion failure handler.
-typedef void(*__libcpp_debug_function_type)(__libcpp_debug_info const&);
-
-/// __libcpp_debug_function - The handler function called when a _LIBCPP_ASSERT
-/// fails.
-extern _LIBCPP_EXPORTED_FROM_ABI __libcpp_debug_function_type __libcpp_debug_function;
-
-/// __libcpp_abort_debug_function - A debug handler that aborts when called.
-_LIBCPP_NORETURN _LIBCPP_FUNC_VIS
-void __libcpp_abort_debug_function(__libcpp_debug_info const&);
-
-/// __libcpp_set_debug_function - Set the debug handler to the specified
-/// function.
-_LIBCPP_FUNC_VIS
-bool __libcpp_set_debug_function(__libcpp_debug_function_type __func);
+#if defined(_LIBCPP_ENABLE_DEBUG_MODE) || defined(_LIBCPP_BUILDING_LIBRARY)
-#if _LIBCPP_DEBUG_LEVEL == 2 || defined(_LIBCPP_BUILDING_LIBRARY)
+_LIBCPP_BEGIN_NAMESPACE_STD
struct _LIBCPP_TYPE_VIS __c_node;
@@ -89,15 +62,9 @@ struct _LIBCPP_TYPE_VIS __i_node
__i_node* __next_;
__c_node* __c_;
-#ifndef _LIBCPP_CXX03_LANG
__i_node(const __i_node&) = delete;
__i_node& operator=(const __i_node&) = delete;
-#else
-private:
- __i_node(const __i_node&);
- __i_node& operator=(const __i_node&);
-public:
-#endif
+
_LIBCPP_INLINE_VISIBILITY
__i_node(void* __i, __i_node* __next, __c_node* __c)
: __i_(__i), __next_(__next), __c_(__c) {}
@@ -112,17 +79,11 @@ struct _LIBCPP_TYPE_VIS __c_node
__i_node** end_;
__i_node** cap_;
-#ifndef _LIBCPP_CXX03_LANG
__c_node(const __c_node&) = delete;
__c_node& operator=(const __c_node&) = delete;
-#else
-private:
- __c_node(const __c_node&);
- __c_node& operator=(const __c_node&);
-public:
-#endif
+
_LIBCPP_INLINE_VISIBILITY
- __c_node(void* __c, __c_node* __next)
+ explicit __c_node(void* __c, __c_node* __next)
: __c_(__c), __next_(__next), beg_(nullptr), end_(nullptr), cap_(nullptr) {}
virtual ~__c_node();
@@ -139,7 +100,7 @@ template <class _Cont>
struct _C_node
: public __c_node
{
- _C_node(void* __c, __c_node* __n)
+ explicit _C_node(void* __c, __c_node* __n)
: __c_node(__c, __n) {}
virtual bool __dereferenceable(const void*) const;
@@ -197,17 +158,11 @@ class _LIBCPP_TYPE_VIS __libcpp_db
__i_node** __iend_;
size_t __isz_;
- __libcpp_db();
+ explicit __libcpp_db();
public:
-#ifndef _LIBCPP_CXX03_LANG
__libcpp_db(const __libcpp_db&) = delete;
__libcpp_db& operator=(const __libcpp_db&) = delete;
-#else
-private:
- __libcpp_db(const __libcpp_db&);
- __libcpp_db& operator=(const __libcpp_db&);
-public:
-#endif
+
~__libcpp_db();
class __db_c_iterator;
@@ -266,12 +221,15 @@ private:
_LIBCPP_FUNC_VIS __libcpp_db* __get_db();
_LIBCPP_FUNC_VIS const __libcpp_db* __get_const_db();
+_LIBCPP_END_NAMESPACE_STD
-#endif // _LIBCPP_DEBUG_LEVEL == 2 || defined(_LIBCPP_BUILDING_LIBRARY)
+#endif // defined(_LIBCPP_ENABLE_DEBUG_MODE) || defined(_LIBCPP_BUILDING_LIBRARY)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
template <class _Tp>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 inline void __debug_db_insert_c(_Tp* __c) {
-#if _LIBCPP_DEBUG_LEVEL == 2
+#ifdef _LIBCPP_ENABLE_DEBUG_MODE
if (!__libcpp_is_constant_evaluated())
__get_db()->__insert_c(__c);
#else
@@ -281,7 +239,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 inline void __debug_db_inser
template <class _Tp>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 inline void __debug_db_insert_i(_Tp* __i) {
-#if _LIBCPP_DEBUG_LEVEL == 2
+#ifdef _LIBCPP_ENABLE_DEBUG_MODE
if (!__libcpp_is_constant_evaluated())
__get_db()->__insert_i(__i);
#else
@@ -289,6 +247,37 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 inline void __debug_db_inser
#endif
}
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 inline void __debug_db_erase_c(_Tp* __c) {
+#ifdef _LIBCPP_ENABLE_DEBUG_MODE
+ if (!__libcpp_is_constant_evaluated())
+ __get_db()->__erase_c(__c);
+#else
+ (void)(__c);
+#endif
+}
+
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 inline void __debug_db_swap(_Tp* __lhs, _Tp* __rhs) {
+#ifdef _LIBCPP_ENABLE_DEBUG_MODE
+ if (!__libcpp_is_constant_evaluated())
+ __get_db()->swap(__lhs, __rhs);
+#else
+ (void)(__lhs);
+ (void)(__rhs);
+#endif
+}
+
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 inline void __debug_db_invalidate_all(_Tp* __c) {
+#ifdef _LIBCPP_ENABLE_DEBUG_MODE
+ if (!__libcpp_is_constant_evaluated())
+ __get_db()->__invalidate_all(__c);
+#else
+ (void)(__c);
+#endif
+}
+
_LIBCPP_END_NAMESPACE_STD
-#endif // _LIBCPP_DEBUG_H
+#endif // _LIBCPP___DEBUG
diff --git a/libcxx/include/__errc b/libcxx/include/__errc
index 68d5fa320150..17bbe0e2afce 100644
--- a/libcxx/include/__errc
+++ b/libcxx/include/__errc
@@ -104,7 +104,7 @@ enum class errc
#include <cerrno>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__filesystem/copy_options.h b/libcxx/include/__filesystem/copy_options.h
index c0140d45717b..2e037403f6f2 100644
--- a/libcxx/include/__filesystem/copy_options.h
+++ b/libcxx/include/__filesystem/copy_options.h
@@ -13,6 +13,10 @@
#include <__availability>
#include <__config>
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
#ifndef _LIBCPP_CXX03_LANG
_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
diff --git a/libcxx/include/__filesystem/directory_entry.h b/libcxx/include/__filesystem/directory_entry.h
index 91dd1a214588..5ba3ef96de48 100644
--- a/libcxx/include/__filesystem/directory_entry.h
+++ b/libcxx/include/__filesystem/directory_entry.h
@@ -11,6 +11,7 @@
#define _LIBCPP___FILESYSTEM_DIRECTORY_ENTRY_H
#include <__availability>
+#include <__chrono/time_point.h>
#include <__config>
#include <__errc>
#include <__filesystem/file_status.h>
@@ -20,12 +21,16 @@
#include <__filesystem/operations.h>
#include <__filesystem/path.h>
#include <__filesystem/perms.h>
-#include <chrono>
+#include <__utility/unreachable.h>
#include <cstdint>
#include <cstdlib>
#include <iosfwd>
#include <system_error>
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
_LIBCPP_PUSH_MACROS
#include <__undef_macros>
@@ -249,7 +254,7 @@ public:
private:
friend class directory_iterator;
friend class recursive_directory_iterator;
- friend class __dir_stream;
+ friend class _LIBCPP_HIDDEN __dir_stream;
enum _CacheType : unsigned char {
_Empty,
@@ -358,7 +363,7 @@ private:
__ec->clear();
return __data_.__type_;
}
- _LIBCPP_UNREACHABLE();
+ __libcpp_unreachable();
}
_LIBCPP_INLINE_VISIBILITY
@@ -379,7 +384,7 @@ private:
return __data_.__type_;
}
}
- _LIBCPP_UNREACHABLE();
+ __libcpp_unreachable();
}
_LIBCPP_INLINE_VISIBILITY
@@ -394,7 +399,7 @@ private:
case _RefreshSymlink:
return file_status(__get_ft(__ec), __data_.__non_sym_perms_);
}
- _LIBCPP_UNREACHABLE();
+ __libcpp_unreachable();
}
_LIBCPP_INLINE_VISIBILITY
@@ -410,7 +415,7 @@ private:
case _RefreshSymlinkUnresolved:
return file_status(__get_sym_ft(__ec), __data_.__sym_perms_);
}
- _LIBCPP_UNREACHABLE();
+ __libcpp_unreachable();
}
_LIBCPP_INLINE_VISIBILITY
@@ -435,7 +440,7 @@ private:
return __data_.__size_;
}
}
- _LIBCPP_UNREACHABLE();
+ __libcpp_unreachable();
}
_LIBCPP_INLINE_VISIBILITY
@@ -454,7 +459,7 @@ private:
return __data_.__nlink_;
}
}
- _LIBCPP_UNREACHABLE();
+ __libcpp_unreachable();
}
_LIBCPP_INLINE_VISIBILITY
@@ -477,7 +482,7 @@ private:
return __data_.__write_time_;
}
}
- _LIBCPP_UNREACHABLE();
+ __libcpp_unreachable();
}
private:
diff --git a/libcxx/include/__filesystem/directory_iterator.h b/libcxx/include/__filesystem/directory_iterator.h
index 1cb1794efdae..5ff2f01ac7b2 100644
--- a/libcxx/include/__filesystem/directory_iterator.h
+++ b/libcxx/include/__filesystem/directory_iterator.h
@@ -10,9 +10,9 @@
#ifndef _LIBCPP___FILESYSTEM_DIRECTORY_ITERATOR_H
#define _LIBCPP___FILESYSTEM_DIRECTORY_ITERATOR_H
+#include <__assert>
#include <__availability>
#include <__config>
-#include <__debug>
#include <__filesystem/directory_entry.h>
#include <__filesystem/directory_options.h>
#include <__filesystem/path.h>
@@ -23,6 +23,10 @@
#include <cstddef>
#include <system_error>
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
#ifndef _LIBCPP_CXX03_LANG
_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
@@ -40,25 +44,31 @@ public:
public:
//ctor & dtor
+ _LIBCPP_HIDE_FROM_ABI
directory_iterator() noexcept {}
+ _LIBCPP_HIDE_FROM_ABI
explicit directory_iterator(const path& __p)
: directory_iterator(__p, nullptr) {}
+ _LIBCPP_HIDE_FROM_ABI
directory_iterator(const path& __p, directory_options __opts)
: directory_iterator(__p, nullptr, __opts) {}
+ _LIBCPP_HIDE_FROM_ABI
directory_iterator(const path& __p, error_code& __ec)
: directory_iterator(__p, &__ec) {}
+ _LIBCPP_HIDE_FROM_ABI
directory_iterator(const path& __p, directory_options __opts,
error_code& __ec)
: directory_iterator(__p, &__ec, __opts) {}
- directory_iterator(const directory_iterator&) = default;
- directory_iterator(directory_iterator&&) = default;
- directory_iterator& operator=(const directory_iterator&) = default;
+ _LIBCPP_HIDE_FROM_ABI directory_iterator(const directory_iterator&) = default;
+ _LIBCPP_HIDE_FROM_ABI directory_iterator(directory_iterator&&) = default;
+ _LIBCPP_HIDE_FROM_ABI directory_iterator& operator=(const directory_iterator&) = default;
+ _LIBCPP_HIDE_FROM_ABI
directory_iterator& operator=(directory_iterator&& __o) noexcept {
// non-default implementation provided to support self-move assign.
if (this != &__o) {
@@ -67,27 +77,32 @@ public:
return *this;
}
- ~directory_iterator() = default;
+ _LIBCPP_HIDE_FROM_ABI ~directory_iterator() = default;
+ _LIBCPP_HIDE_FROM_ABI
const directory_entry& operator*() const {
_LIBCPP_ASSERT(__imp_, "The end iterator cannot be dereferenced");
return __dereference();
}
+ _LIBCPP_HIDE_FROM_ABI
const directory_entry* operator->() const { return &**this; }
+ _LIBCPP_HIDE_FROM_ABI
directory_iterator& operator++() { return __increment(); }
+ _LIBCPP_HIDE_FROM_ABI
__dir_element_proxy operator++(int) {
__dir_element_proxy __p(**this);
__increment();
return __p;
}
+ _LIBCPP_HIDE_FROM_ABI
directory_iterator& increment(error_code& __ec) { return __increment(&__ec); }
private:
- inline _LIBCPP_INLINE_VISIBILITY friend bool
+ inline _LIBCPP_HIDE_FROM_ABI friend bool
operator==(const directory_iterator& __lhs,
const directory_iterator& __rhs) noexcept;
@@ -106,25 +121,25 @@ private:
shared_ptr<__dir_stream> __imp_;
};
-inline _LIBCPP_INLINE_VISIBILITY bool
+inline _LIBCPP_HIDE_FROM_ABI bool
operator==(const directory_iterator& __lhs,
const directory_iterator& __rhs) noexcept {
return __lhs.__imp_ == __rhs.__imp_;
}
-inline _LIBCPP_INLINE_VISIBILITY bool
+inline _LIBCPP_HIDE_FROM_ABI bool
operator!=(const directory_iterator& __lhs,
const directory_iterator& __rhs) noexcept {
return !(__lhs == __rhs);
}
// enable directory_iterator range-based for statements
-inline _LIBCPP_INLINE_VISIBILITY directory_iterator
+inline _LIBCPP_HIDE_FROM_ABI directory_iterator
begin(directory_iterator __iter) noexcept {
return __iter;
}
-inline _LIBCPP_INLINE_VISIBILITY directory_iterator
+inline _LIBCPP_HIDE_FROM_ABI directory_iterator
end(directory_iterator) noexcept {
return directory_iterator();
}
@@ -133,7 +148,7 @@ _LIBCPP_AVAILABILITY_FILESYSTEM_POP
_LIBCPP_END_NAMESPACE_FILESYSTEM
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17
template <>
_LIBCPP_AVAILABILITY_FILESYSTEM
@@ -143,7 +158,7 @@ template <>
_LIBCPP_AVAILABILITY_FILESYSTEM
inline constexpr bool _VSTD::ranges::enable_view<_VSTD_FS::directory_iterator> = true;
-#endif
+#endif // _LIBCPP_STD_VER > 17
#endif // _LIBCPP_CXX03_LANG
diff --git a/libcxx/include/__filesystem/directory_options.h b/libcxx/include/__filesystem/directory_options.h
index 79c0c2cbaa55..d3f8cc1deb21 100644
--- a/libcxx/include/__filesystem/directory_options.h
+++ b/libcxx/include/__filesystem/directory_options.h
@@ -13,6 +13,10 @@
#include <__availability>
#include <__config>
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
#ifndef _LIBCPP_CXX03_LANG
_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
diff --git a/libcxx/include/__filesystem/file_status.h b/libcxx/include/__filesystem/file_status.h
index a8f653ab44fc..ac3f6cbed9d7 100644
--- a/libcxx/include/__filesystem/file_status.h
+++ b/libcxx/include/__filesystem/file_status.h
@@ -15,6 +15,10 @@
#include <__filesystem/file_type.h>
#include <__filesystem/perms.h>
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
#ifndef _LIBCPP_CXX03_LANG
_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
diff --git a/libcxx/include/__filesystem/file_time_type.h b/libcxx/include/__filesystem/file_time_type.h
index 590146a06600..7c4932e603bc 100644
--- a/libcxx/include/__filesystem/file_time_type.h
+++ b/libcxx/include/__filesystem/file_time_type.h
@@ -11,8 +11,13 @@
#define _LIBCPP___FILESYSTEM_FILE_TIME_TYPE_H
#include <__availability>
+#include <__chrono/file_clock.h>
+#include <__chrono/time_point.h>
#include <__config>
-#include <chrono>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
#ifndef _LIBCPP_CXX03_LANG
diff --git a/libcxx/include/__filesystem/file_type.h b/libcxx/include/__filesystem/file_type.h
index 93bee86ad635..c756a05c848b 100644
--- a/libcxx/include/__filesystem/file_type.h
+++ b/libcxx/include/__filesystem/file_type.h
@@ -13,6 +13,10 @@
#include <__availability>
#include <__config>
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
#ifndef _LIBCPP_CXX03_LANG
_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
diff --git a/libcxx/include/__filesystem/filesystem_error.h b/libcxx/include/__filesystem/filesystem_error.h
index 0b1874b0e50e..e32b14c1b7bf 100644
--- a/libcxx/include/__filesystem/filesystem_error.h
+++ b/libcxx/include/__filesystem/filesystem_error.h
@@ -19,6 +19,10 @@
#include <system_error>
#include <type_traits>
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
#ifndef _LIBCPP_CXX03_LANG
_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
diff --git a/libcxx/include/__filesystem/operations.h b/libcxx/include/__filesystem/operations.h
index 918b4f9362e6..85c71f017f34 100644
--- a/libcxx/include/__filesystem/operations.h
+++ b/libcxx/include/__filesystem/operations.h
@@ -11,6 +11,7 @@
#define _LIBCPP___FILESYSTEM_OPERATIONS_H
#include <__availability>
+#include <__chrono/time_point.h>
#include <__config>
#include <__filesystem/copy_options.h>
#include <__filesystem/file_status.h>
@@ -20,10 +21,13 @@
#include <__filesystem/perm_options.h>
#include <__filesystem/perms.h>
#include <__filesystem/space_info.h>
-#include <chrono>
#include <cstdint>
#include <system_error>
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
#ifndef _LIBCPP_CXX03_LANG
_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
@@ -58,41 +62,41 @@ _LIBCPP_FUNC_VIS void __rename(const path& from, const path& to, error_code* ec
_LIBCPP_FUNC_VIS void __resize_file(const path& p, uintmax_t size, error_code* ec = nullptr);
_LIBCPP_FUNC_VIS path __temp_directory_path(error_code* __ec = nullptr);
-inline _LIBCPP_INLINE_VISIBILITY path absolute(const path& __p) { return __absolute(__p); }
-inline _LIBCPP_INLINE_VISIBILITY path absolute(const path& __p, error_code& __ec) { return __absolute(__p, &__ec); }
-inline _LIBCPP_INLINE_VISIBILITY path canonical(const path& __p) { return __canonical(__p); }
-inline _LIBCPP_INLINE_VISIBILITY path canonical(const path& __p, error_code& __ec) { return __canonical(__p, &__ec); }
-inline _LIBCPP_INLINE_VISIBILITY bool copy_file(const path& __from, const path& __to) { return __copy_file(__from, __to, copy_options::none); }
-inline _LIBCPP_INLINE_VISIBILITY bool copy_file(const path& __from, const path& __to, error_code& __ec) { return __copy_file(__from, __to, copy_options::none, &__ec); }
-inline _LIBCPP_INLINE_VISIBILITY bool copy_file(const path& __from, const path& __to, copy_options __opt) { return __copy_file(__from, __to, __opt); }
-inline _LIBCPP_INLINE_VISIBILITY bool copy_file(const path& __from, const path& __to, copy_options __opt, error_code& __ec) { return __copy_file(__from, __to, __opt, &__ec); }
-inline _LIBCPP_INLINE_VISIBILITY void copy_symlink(const path& __from, const path& __to) { __copy_symlink(__from, __to); }
-inline _LIBCPP_INLINE_VISIBILITY void copy_symlink(const path& __from, const path& __to, error_code& __ec) noexcept { __copy_symlink(__from, __to, &__ec); }
-inline _LIBCPP_INLINE_VISIBILITY void copy(const path& __from, const path& __to) { __copy(__from, __to, copy_options::none); }
-inline _LIBCPP_INLINE_VISIBILITY void copy(const path& __from, const path& __to, error_code& __ec) { __copy(__from, __to, copy_options::none, &__ec); }
-inline _LIBCPP_INLINE_VISIBILITY void copy(const path& __from, const path& __to, copy_options __opt) { __copy(__from, __to, __opt); }
-inline _LIBCPP_INLINE_VISIBILITY void copy(const path& __from, const path& __to, copy_options __opt, error_code& __ec) { __copy(__from, __to, __opt, &__ec); }
-inline _LIBCPP_INLINE_VISIBILITY bool create_directories(const path& __p) { return __create_directories(__p); }
-inline _LIBCPP_INLINE_VISIBILITY bool create_directories(const path& __p, error_code& __ec) { return __create_directories(__p, &__ec); }
-inline _LIBCPP_INLINE_VISIBILITY void create_directory_symlink(const path& __target, const path& __link) { __create_directory_symlink(__target, __link); }
-inline _LIBCPP_INLINE_VISIBILITY void create_directory_symlink(const path& __target, const path& __link, error_code& __ec) noexcept { __create_directory_symlink(__target, __link, &__ec); }
-inline _LIBCPP_INLINE_VISIBILITY bool create_directory(const path& __p) { return __create_directory(__p); }
-inline _LIBCPP_INLINE_VISIBILITY bool create_directory(const path& __p, error_code& __ec) noexcept { return __create_directory(__p, &__ec); }
-inline _LIBCPP_INLINE_VISIBILITY bool create_directory(const path& __p, const path& __attrs) { return __create_directory(__p, __attrs); }
-inline _LIBCPP_INLINE_VISIBILITY bool create_directory(const path& __p, const path& __attrs, error_code& __ec) noexcept { return __create_directory(__p, __attrs, &__ec); }
-inline _LIBCPP_INLINE_VISIBILITY void create_hard_link(const path& __target, const path& __link) { __create_hard_link(__target, __link); }
-inline _LIBCPP_INLINE_VISIBILITY void create_hard_link(const path& __target, const path& __link, error_code& __ec) noexcept { __create_hard_link(__target, __link, &__ec); }
-inline _LIBCPP_INLINE_VISIBILITY void create_symlink(const path& __target, const path& __link) { __create_symlink(__target, __link); }
-inline _LIBCPP_INLINE_VISIBILITY void create_symlink(const path& __target, const path& __link, error_code& __ec) noexcept { return __create_symlink(__target, __link, &__ec); }
-inline _LIBCPP_INLINE_VISIBILITY path current_path() { return __current_path(); }
-inline _LIBCPP_INLINE_VISIBILITY path current_path(error_code& __ec) { return __current_path(&__ec); }
-inline _LIBCPP_INLINE_VISIBILITY void current_path(const path& __p) { __current_path(__p); }
-inline _LIBCPP_INLINE_VISIBILITY void current_path(const path& __p, error_code& __ec) noexcept { __current_path(__p, &__ec); }
-inline _LIBCPP_INLINE_VISIBILITY bool equivalent(const path& __p1, const path& __p2) { return __equivalent(__p1, __p2); }
-inline _LIBCPP_INLINE_VISIBILITY bool equivalent(const path& __p1, const path& __p2, error_code& __ec) noexcept { return __equivalent(__p1, __p2, &__ec); }
-inline _LIBCPP_INLINE_VISIBILITY bool status_known(file_status __s) noexcept { return __s.type() != file_type::none; }
-inline _LIBCPP_INLINE_VISIBILITY bool exists(file_status __s) noexcept { return status_known(__s) && __s.type() != file_type::not_found; }
-inline _LIBCPP_INLINE_VISIBILITY bool exists(const path& __p) { return exists(__status(__p)); }
+inline _LIBCPP_HIDE_FROM_ABI path absolute(const path& __p) { return __absolute(__p); }
+inline _LIBCPP_HIDE_FROM_ABI path absolute(const path& __p, error_code& __ec) { return __absolute(__p, &__ec); }
+inline _LIBCPP_HIDE_FROM_ABI path canonical(const path& __p) { return __canonical(__p); }
+inline _LIBCPP_HIDE_FROM_ABI path canonical(const path& __p, error_code& __ec) { return __canonical(__p, &__ec); }
+inline _LIBCPP_HIDE_FROM_ABI bool copy_file(const path& __from, const path& __to) { return __copy_file(__from, __to, copy_options::none); }
+inline _LIBCPP_HIDE_FROM_ABI bool copy_file(const path& __from, const path& __to, error_code& __ec) { return __copy_file(__from, __to, copy_options::none, &__ec); }
+inline _LIBCPP_HIDE_FROM_ABI bool copy_file(const path& __from, const path& __to, copy_options __opt) { return __copy_file(__from, __to, __opt); }
+inline _LIBCPP_HIDE_FROM_ABI bool copy_file(const path& __from, const path& __to, copy_options __opt, error_code& __ec) { return __copy_file(__from, __to, __opt, &__ec); }
+inline _LIBCPP_HIDE_FROM_ABI void copy_symlink(const path& __from, const path& __to) { __copy_symlink(__from, __to); }
+inline _LIBCPP_HIDE_FROM_ABI void copy_symlink(const path& __from, const path& __to, error_code& __ec) noexcept { __copy_symlink(__from, __to, &__ec); }
+inline _LIBCPP_HIDE_FROM_ABI void copy(const path& __from, const path& __to) { __copy(__from, __to, copy_options::none); }
+inline _LIBCPP_HIDE_FROM_ABI void copy(const path& __from, const path& __to, error_code& __ec) { __copy(__from, __to, copy_options::none, &__ec); }
+inline _LIBCPP_HIDE_FROM_ABI void copy(const path& __from, const path& __to, copy_options __opt) { __copy(__from, __to, __opt); }
+inline _LIBCPP_HIDE_FROM_ABI void copy(const path& __from, const path& __to, copy_options __opt, error_code& __ec) { __copy(__from, __to, __opt, &__ec); }
+inline _LIBCPP_HIDE_FROM_ABI bool create_directories(const path& __p) { return __create_directories(__p); }
+inline _LIBCPP_HIDE_FROM_ABI bool create_directories(const path& __p, error_code& __ec) { return __create_directories(__p, &__ec); }
+inline _LIBCPP_HIDE_FROM_ABI void create_directory_symlink(const path& __target, const path& __link) { __create_directory_symlink(__target, __link); }
+inline _LIBCPP_HIDE_FROM_ABI void create_directory_symlink(const path& __target, const path& __link, error_code& __ec) noexcept { __create_directory_symlink(__target, __link, &__ec); }
+inline _LIBCPP_HIDE_FROM_ABI bool create_directory(const path& __p) { return __create_directory(__p); }
+inline _LIBCPP_HIDE_FROM_ABI bool create_directory(const path& __p, error_code& __ec) noexcept { return __create_directory(__p, &__ec); }
+inline _LIBCPP_HIDE_FROM_ABI bool create_directory(const path& __p, const path& __attrs) { return __create_directory(__p, __attrs); }
+inline _LIBCPP_HIDE_FROM_ABI bool create_directory(const path& __p, const path& __attrs, error_code& __ec) noexcept { return __create_directory(__p, __attrs, &__ec); }
+inline _LIBCPP_HIDE_FROM_ABI void create_hard_link(const path& __target, const path& __link) { __create_hard_link(__target, __link); }
+inline _LIBCPP_HIDE_FROM_ABI void create_hard_link(const path& __target, const path& __link, error_code& __ec) noexcept { __create_hard_link(__target, __link, &__ec); }
+inline _LIBCPP_HIDE_FROM_ABI void create_symlink(const path& __target, const path& __link) { __create_symlink(__target, __link); }
+inline _LIBCPP_HIDE_FROM_ABI void create_symlink(const path& __target, const path& __link, error_code& __ec) noexcept { return __create_symlink(__target, __link, &__ec); }
+inline _LIBCPP_HIDE_FROM_ABI path current_path() { return __current_path(); }
+inline _LIBCPP_HIDE_FROM_ABI path current_path(error_code& __ec) { return __current_path(&__ec); }
+inline _LIBCPP_HIDE_FROM_ABI void current_path(const path& __p) { __current_path(__p); }
+inline _LIBCPP_HIDE_FROM_ABI void current_path(const path& __p, error_code& __ec) noexcept { __current_path(__p, &__ec); }
+inline _LIBCPP_HIDE_FROM_ABI bool equivalent(const path& __p1, const path& __p2) { return __equivalent(__p1, __p2); }
+inline _LIBCPP_HIDE_FROM_ABI bool equivalent(const path& __p1, const path& __p2, error_code& __ec) noexcept { return __equivalent(__p1, __p2, &__ec); }
+inline _LIBCPP_HIDE_FROM_ABI bool status_known(file_status __s) noexcept { return __s.type() != file_type::none; }
+inline _LIBCPP_HIDE_FROM_ABI bool exists(file_status __s) noexcept { return status_known(__s) && __s.type() != file_type::not_found; }
+inline _LIBCPP_HIDE_FROM_ABI bool exists(const path& __p) { return exists(__status(__p)); }
inline _LIBCPP_INLINE_VISIBILITY bool exists(const path& __p, error_code& __ec) noexcept {
auto __s = __status(__p, &__ec);
@@ -101,45 +105,45 @@ inline _LIBCPP_INLINE_VISIBILITY bool exists(const path& __p, error_code& __ec)
return exists(__s);
}
-inline _LIBCPP_INLINE_VISIBILITY uintmax_t file_size(const path& __p) { return __file_size(__p); }
-inline _LIBCPP_INLINE_VISIBILITY uintmax_t file_size(const path& __p, error_code& __ec) noexcept { return __file_size(__p, &__ec); }
-inline _LIBCPP_INLINE_VISIBILITY uintmax_t hard_link_count(const path& __p) { return __hard_link_count(__p); }
-inline _LIBCPP_INLINE_VISIBILITY uintmax_t hard_link_count(const path& __p, error_code& __ec) noexcept { return __hard_link_count(__p, &__ec); }
-inline _LIBCPP_INLINE_VISIBILITY bool is_block_file(file_status __s) noexcept { return __s.type() == file_type::block; }
-inline _LIBCPP_INLINE_VISIBILITY bool is_block_file(const path& __p) { return is_block_file(__status(__p)); }
-inline _LIBCPP_INLINE_VISIBILITY bool is_block_file(const path& __p, error_code& __ec) noexcept { return is_block_file(__status(__p, &__ec)); }
-inline _LIBCPP_INLINE_VISIBILITY bool is_character_file(file_status __s) noexcept { return __s.type() == file_type::character; }
-inline _LIBCPP_INLINE_VISIBILITY bool is_character_file(const path& __p) { return is_character_file(__status(__p)); }
-inline _LIBCPP_INLINE_VISIBILITY bool is_character_file(const path& __p, error_code& __ec) noexcept { return is_character_file(__status(__p, &__ec)); }
-inline _LIBCPP_INLINE_VISIBILITY bool is_directory(file_status __s) noexcept { return __s.type() == file_type::directory; }
-inline _LIBCPP_INLINE_VISIBILITY bool is_directory(const path& __p) { return is_directory(__status(__p)); }
-inline _LIBCPP_INLINE_VISIBILITY bool is_directory(const path& __p, error_code& __ec) noexcept { return is_directory(__status(__p, &__ec)); }
+inline _LIBCPP_HIDE_FROM_ABI uintmax_t file_size(const path& __p) { return __file_size(__p); }
+inline _LIBCPP_HIDE_FROM_ABI uintmax_t file_size(const path& __p, error_code& __ec) noexcept { return __file_size(__p, &__ec); }
+inline _LIBCPP_HIDE_FROM_ABI uintmax_t hard_link_count(const path& __p) { return __hard_link_count(__p); }
+inline _LIBCPP_HIDE_FROM_ABI uintmax_t hard_link_count(const path& __p, error_code& __ec) noexcept { return __hard_link_count(__p, &__ec); }
+inline _LIBCPP_HIDE_FROM_ABI bool is_block_file(file_status __s) noexcept { return __s.type() == file_type::block; }
+inline _LIBCPP_HIDE_FROM_ABI bool is_block_file(const path& __p) { return is_block_file(__status(__p)); }
+inline _LIBCPP_HIDE_FROM_ABI bool is_block_file(const path& __p, error_code& __ec) noexcept { return is_block_file(__status(__p, &__ec)); }
+inline _LIBCPP_HIDE_FROM_ABI bool is_character_file(file_status __s) noexcept { return __s.type() == file_type::character; }
+inline _LIBCPP_HIDE_FROM_ABI bool is_character_file(const path& __p) { return is_character_file(__status(__p)); }
+inline _LIBCPP_HIDE_FROM_ABI bool is_character_file(const path& __p, error_code& __ec) noexcept { return is_character_file(__status(__p, &__ec)); }
+inline _LIBCPP_HIDE_FROM_ABI bool is_directory(file_status __s) noexcept { return __s.type() == file_type::directory; }
+inline _LIBCPP_HIDE_FROM_ABI bool is_directory(const path& __p) { return is_directory(__status(__p)); }
+inline _LIBCPP_HIDE_FROM_ABI bool is_directory(const path& __p, error_code& __ec) noexcept { return is_directory(__status(__p, &__ec)); }
_LIBCPP_FUNC_VIS bool __fs_is_empty(const path& p, error_code* ec = nullptr);
-inline _LIBCPP_INLINE_VISIBILITY bool is_empty(const path& __p) { return __fs_is_empty(__p); }
-inline _LIBCPP_INLINE_VISIBILITY bool is_empty(const path& __p, error_code& __ec) { return __fs_is_empty(__p, &__ec); }
-inline _LIBCPP_INLINE_VISIBILITY bool is_fifo(file_status __s) noexcept { return __s.type() == file_type::fifo; }
-inline _LIBCPP_INLINE_VISIBILITY bool is_fifo(const path& __p) { return is_fifo(__status(__p)); }
-inline _LIBCPP_INLINE_VISIBILITY bool is_fifo(const path& __p, error_code& __ec) noexcept { return is_fifo(__status(__p, &__ec)); }
-inline _LIBCPP_INLINE_VISIBILITY bool is_regular_file(file_status __s) noexcept { return __s.type() == file_type::regular; }
-inline _LIBCPP_INLINE_VISIBILITY bool is_regular_file(const path& __p) { return is_regular_file(__status(__p)); }
-inline _LIBCPP_INLINE_VISIBILITY bool is_regular_file(const path& __p, error_code& __ec) noexcept { return is_regular_file(__status(__p, &__ec)); }
-inline _LIBCPP_INLINE_VISIBILITY bool is_symlink(file_status __s) noexcept { return __s.type() == file_type::symlink; }
-inline _LIBCPP_INLINE_VISIBILITY bool is_symlink(const path& __p) { return is_symlink(__symlink_status(__p)); }
-inline _LIBCPP_INLINE_VISIBILITY bool is_symlink(const path& __p, error_code& __ec) noexcept { return is_symlink(__symlink_status(__p, &__ec)); }
-inline _LIBCPP_INLINE_VISIBILITY bool is_other(file_status __s) noexcept { return exists(__s) && !is_regular_file(__s) && !is_directory(__s) && !is_symlink(__s); }
-inline _LIBCPP_INLINE_VISIBILITY bool is_other(const path& __p) { return is_other(__status(__p)); }
-inline _LIBCPP_INLINE_VISIBILITY bool is_other(const path& __p, error_code& __ec) noexcept { return is_other(__status(__p, &__ec)); }
-inline _LIBCPP_INLINE_VISIBILITY bool is_socket(file_status __s) noexcept { return __s.type() == file_type::socket; }
-inline _LIBCPP_INLINE_VISIBILITY bool is_socket(const path& __p) { return is_socket(__status(__p)); }
-inline _LIBCPP_INLINE_VISIBILITY bool is_socket(const path& __p, error_code& __ec) noexcept { return is_socket(__status(__p, &__ec)); }
-inline _LIBCPP_INLINE_VISIBILITY file_time_type last_write_time(const path& __p) { return __last_write_time(__p); }
-inline _LIBCPP_INLINE_VISIBILITY file_time_type last_write_time(const path& __p, error_code& __ec) noexcept { return __last_write_time(__p, &__ec); }
-inline _LIBCPP_INLINE_VISIBILITY void last_write_time(const path& __p, file_time_type __t) { __last_write_time(__p, __t); }
-inline _LIBCPP_INLINE_VISIBILITY void last_write_time(const path& __p, file_time_type __t, error_code& __ec) noexcept { __last_write_time(__p, __t, &__ec); }
+inline _LIBCPP_HIDE_FROM_ABI bool is_empty(const path& __p) { return __fs_is_empty(__p); }
+inline _LIBCPP_HIDE_FROM_ABI bool is_empty(const path& __p, error_code& __ec) { return __fs_is_empty(__p, &__ec); }
+inline _LIBCPP_HIDE_FROM_ABI bool is_fifo(file_status __s) noexcept { return __s.type() == file_type::fifo; }
+inline _LIBCPP_HIDE_FROM_ABI bool is_fifo(const path& __p) { return is_fifo(__status(__p)); }
+inline _LIBCPP_HIDE_FROM_ABI bool is_fifo(const path& __p, error_code& __ec) noexcept { return is_fifo(__status(__p, &__ec)); }
+inline _LIBCPP_HIDE_FROM_ABI bool is_regular_file(file_status __s) noexcept { return __s.type() == file_type::regular; }
+inline _LIBCPP_HIDE_FROM_ABI bool is_regular_file(const path& __p) { return is_regular_file(__status(__p)); }
+inline _LIBCPP_HIDE_FROM_ABI bool is_regular_file(const path& __p, error_code& __ec) noexcept { return is_regular_file(__status(__p, &__ec)); }
+inline _LIBCPP_HIDE_FROM_ABI bool is_symlink(file_status __s) noexcept { return __s.type() == file_type::symlink; }
+inline _LIBCPP_HIDE_FROM_ABI bool is_symlink(const path& __p) { return is_symlink(__symlink_status(__p)); }
+inline _LIBCPP_HIDE_FROM_ABI bool is_symlink(const path& __p, error_code& __ec) noexcept { return is_symlink(__symlink_status(__p, &__ec)); }
+inline _LIBCPP_HIDE_FROM_ABI bool is_other(file_status __s) noexcept { return exists(__s) && !is_regular_file(__s) && !is_directory(__s) && !is_symlink(__s); }
+inline _LIBCPP_HIDE_FROM_ABI bool is_other(const path& __p) { return is_other(__status(__p)); }
+inline _LIBCPP_HIDE_FROM_ABI bool is_other(const path& __p, error_code& __ec) noexcept { return is_other(__status(__p, &__ec)); }
+inline _LIBCPP_HIDE_FROM_ABI bool is_socket(file_status __s) noexcept { return __s.type() == file_type::socket; }
+inline _LIBCPP_HIDE_FROM_ABI bool is_socket(const path& __p) { return is_socket(__status(__p)); }
+inline _LIBCPP_HIDE_FROM_ABI bool is_socket(const path& __p, error_code& __ec) noexcept { return is_socket(__status(__p, &__ec)); }
+inline _LIBCPP_HIDE_FROM_ABI file_time_type last_write_time(const path& __p) { return __last_write_time(__p); }
+inline _LIBCPP_HIDE_FROM_ABI file_time_type last_write_time(const path& __p, error_code& __ec) noexcept { return __last_write_time(__p, &__ec); }
+inline _LIBCPP_HIDE_FROM_ABI void last_write_time(const path& __p, file_time_type __t) { __last_write_time(__p, __t); }
+inline _LIBCPP_HIDE_FROM_ABI void last_write_time(const path& __p, file_time_type __t, error_code& __ec) noexcept { __last_write_time(__p, __t, &__ec); }
_LIBCPP_FUNC_VIS void __permissions(const path&, perms, perm_options, error_code* = nullptr);
-inline _LIBCPP_INLINE_VISIBILITY void permissions(const path& __p, perms __prms, perm_options __opts = perm_options::replace) { __permissions(__p, __prms, __opts); }
-inline _LIBCPP_INLINE_VISIBILITY void permissions(const path& __p, perms __prms, error_code& __ec) noexcept { __permissions(__p, __prms, perm_options::replace, &__ec); }
-inline _LIBCPP_INLINE_VISIBILITY void permissions(const path& __p, perms __prms, perm_options __opts, error_code& __ec) { __permissions(__p, __prms, __opts, &__ec); }
+inline _LIBCPP_HIDE_FROM_ABI void permissions(const path& __p, perms __prms, perm_options __opts = perm_options::replace) { __permissions(__p, __prms, __opts); }
+inline _LIBCPP_HIDE_FROM_ABI void permissions(const path& __p, perms __prms, error_code& __ec) noexcept { __permissions(__p, __prms, perm_options::replace, &__ec); }
+inline _LIBCPP_HIDE_FROM_ABI void permissions(const path& __p, perms __prms, perm_options __opts, error_code& __ec) { __permissions(__p, __prms, __opts, &__ec); }
inline _LIBCPP_INLINE_VISIBILITY path proximate(const path& __p, const path& __base, error_code& __ec) {
path __tmp = __weakly_canonical(__p, &__ec);
@@ -151,10 +155,10 @@ inline _LIBCPP_INLINE_VISIBILITY path proximate(const path& __p, const path& __b
return __tmp.lexically_proximate(__tmp_base);
}
-inline _LIBCPP_INLINE_VISIBILITY path proximate(const path& __p, error_code& __ec) { return proximate(__p, current_path(), __ec); }
-inline _LIBCPP_INLINE_VISIBILITY path proximate(const path& __p, const path& __base = current_path()) { return __weakly_canonical(__p).lexically_proximate(__weakly_canonical(__base)); }
-inline _LIBCPP_INLINE_VISIBILITY path read_symlink(const path& __p) { return __read_symlink(__p); }
-inline _LIBCPP_INLINE_VISIBILITY path read_symlink(const path& __p, error_code& __ec) { return __read_symlink(__p, &__ec); }
+inline _LIBCPP_HIDE_FROM_ABI path proximate(const path& __p, error_code& __ec) { return proximate(__p, current_path(), __ec); }
+inline _LIBCPP_HIDE_FROM_ABI path proximate(const path& __p, const path& __base = current_path()) { return __weakly_canonical(__p).lexically_proximate(__weakly_canonical(__base)); }
+inline _LIBCPP_HIDE_FROM_ABI path read_symlink(const path& __p) { return __read_symlink(__p); }
+inline _LIBCPP_HIDE_FROM_ABI path read_symlink(const path& __p, error_code& __ec) { return __read_symlink(__p, &__ec); }
inline _LIBCPP_INLINE_VISIBILITY path relative(const path& __p, const path& __base, error_code& __ec) {
path __tmp = __weakly_canonical(__p, &__ec);
@@ -166,27 +170,27 @@ inline _LIBCPP_INLINE_VISIBILITY path relative(const path& __p, const path& __ba
return __tmp.lexically_relative(__tmpbase);
}
-inline _LIBCPP_INLINE_VISIBILITY path relative(const path& __p, error_code& __ec) { return relative(__p, current_path(), __ec); }
-inline _LIBCPP_INLINE_VISIBILITY path relative(const path& __p, const path& __base = current_path()) { return __weakly_canonical(__p).lexically_relative(__weakly_canonical(__base)); }
-inline _LIBCPP_INLINE_VISIBILITY uintmax_t remove_all(const path& __p) { return __remove_all(__p); }
-inline _LIBCPP_INLINE_VISIBILITY uintmax_t remove_all(const path& __p, error_code& __ec) { return __remove_all(__p, &__ec); }
-inline _LIBCPP_INLINE_VISIBILITY bool remove(const path& __p) { return __remove(__p); }
-inline _LIBCPP_INLINE_VISIBILITY bool remove(const path& __p, error_code& __ec) noexcept { return __remove(__p, &__ec); }
-inline _LIBCPP_INLINE_VISIBILITY void rename(const path& __from, const path& __to) { return __rename(__from, __to); }
-inline _LIBCPP_INLINE_VISIBILITY void rename(const path& __from, const path& __to, error_code& __ec) noexcept { return __rename(__from, __to, &__ec); }
-inline _LIBCPP_INLINE_VISIBILITY void resize_file(const path& __p, uintmax_t __ns) { return __resize_file(__p, __ns); }
-inline _LIBCPP_INLINE_VISIBILITY void resize_file(const path& __p, uintmax_t __ns, error_code& __ec) noexcept { return __resize_file(__p, __ns, &__ec); }
+inline _LIBCPP_HIDE_FROM_ABI path relative(const path& __p, error_code& __ec) { return relative(__p, current_path(), __ec); }
+inline _LIBCPP_HIDE_FROM_ABI path relative(const path& __p, const path& __base = current_path()) { return __weakly_canonical(__p).lexically_relative(__weakly_canonical(__base)); }
+inline _LIBCPP_HIDE_FROM_ABI uintmax_t remove_all(const path& __p) { return __remove_all(__p); }
+inline _LIBCPP_HIDE_FROM_ABI uintmax_t remove_all(const path& __p, error_code& __ec) { return __remove_all(__p, &__ec); }
+inline _LIBCPP_HIDE_FROM_ABI bool remove(const path& __p) { return __remove(__p); }
+inline _LIBCPP_HIDE_FROM_ABI bool remove(const path& __p, error_code& __ec) noexcept { return __remove(__p, &__ec); }
+inline _LIBCPP_HIDE_FROM_ABI void rename(const path& __from, const path& __to) { return __rename(__from, __to); }
+inline _LIBCPP_HIDE_FROM_ABI void rename(const path& __from, const path& __to, error_code& __ec) noexcept { return __rename(__from, __to, &__ec); }
+inline _LIBCPP_HIDE_FROM_ABI void resize_file(const path& __p, uintmax_t __ns) { return __resize_file(__p, __ns); }
+inline _LIBCPP_HIDE_FROM_ABI void resize_file(const path& __p, uintmax_t __ns, error_code& __ec) noexcept { return __resize_file(__p, __ns, &__ec); }
_LIBCPP_FUNC_VIS space_info __space(const path&, error_code* __ec = nullptr);
-inline _LIBCPP_INLINE_VISIBILITY space_info space(const path& __p) { return __space(__p); }
-inline _LIBCPP_INLINE_VISIBILITY space_info space(const path& __p, error_code& __ec) noexcept { return __space(__p, &__ec); }
-inline _LIBCPP_INLINE_VISIBILITY file_status status(const path& __p) { return __status(__p); }
-inline _LIBCPP_INLINE_VISIBILITY file_status status(const path& __p, error_code& __ec) noexcept { return __status(__p, &__ec); }
-inline _LIBCPP_INLINE_VISIBILITY file_status symlink_status(const path& __p) { return __symlink_status(__p); }
-inline _LIBCPP_INLINE_VISIBILITY file_status symlink_status(const path& __p, error_code& __ec) noexcept { return __symlink_status(__p, &__ec); }
-inline _LIBCPP_INLINE_VISIBILITY path temp_directory_path() { return __temp_directory_path(); }
-inline _LIBCPP_INLINE_VISIBILITY path temp_directory_path(error_code& __ec) { return __temp_directory_path(&__ec); }
-inline _LIBCPP_INLINE_VISIBILITY path weakly_canonical(path const& __p) { return __weakly_canonical(__p); }
-inline _LIBCPP_INLINE_VISIBILITY path weakly_canonical(path const& __p, error_code& __ec) { return __weakly_canonical(__p, &__ec); }
+inline _LIBCPP_HIDE_FROM_ABI space_info space(const path& __p) { return __space(__p); }
+inline _LIBCPP_HIDE_FROM_ABI space_info space(const path& __p, error_code& __ec) noexcept { return __space(__p, &__ec); }
+inline _LIBCPP_HIDE_FROM_ABI file_status status(const path& __p) { return __status(__p); }
+inline _LIBCPP_HIDE_FROM_ABI file_status status(const path& __p, error_code& __ec) noexcept { return __status(__p, &__ec); }
+inline _LIBCPP_HIDE_FROM_ABI file_status symlink_status(const path& __p) { return __symlink_status(__p); }
+inline _LIBCPP_HIDE_FROM_ABI file_status symlink_status(const path& __p, error_code& __ec) noexcept { return __symlink_status(__p, &__ec); }
+inline _LIBCPP_HIDE_FROM_ABI path temp_directory_path() { return __temp_directory_path(); }
+inline _LIBCPP_HIDE_FROM_ABI path temp_directory_path(error_code& __ec) { return __temp_directory_path(&__ec); }
+inline _LIBCPP_HIDE_FROM_ABI path weakly_canonical(path const& __p) { return __weakly_canonical(__p); }
+inline _LIBCPP_HIDE_FROM_ABI path weakly_canonical(path const& __p, error_code& __ec) { return __weakly_canonical(__p, &__ec); }
_LIBCPP_AVAILABILITY_FILESYSTEM_POP
diff --git a/libcxx/include/__filesystem/path.h b/libcxx/include/__filesystem/path.h
index 77547cbacb7d..8fafd72c7e4f 100644
--- a/libcxx/include/__filesystem/path.h
+++ b/libcxx/include/__filesystem/path.h
@@ -10,6 +10,8 @@
#ifndef _LIBCPP___FILESYSTEM_PATH_H
#define _LIBCPP___FILESYSTEM_PATH_H
+#include <__algorithm/replace.h>
+#include <__algorithm/replace_copy.h>
#include <__availability>
#include <__config>
#include <__iterator/back_insert_iterator.h>
@@ -24,6 +26,10 @@
# include <locale>
#endif
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
#ifndef _LIBCPP_CXX03_LANG
_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
@@ -65,6 +71,7 @@ struct __can_convert_char<char32_t> {
};
template <class _ECharT>
+_LIBCPP_HIDE_FROM_ABI
typename enable_if<__can_convert_char<_ECharT>::value, bool>::type
__is_separator(_ECharT __e) {
#if defined(_LIBCPP_WIN32API)
@@ -95,10 +102,16 @@ struct __is_pathable_string<
: public __can_convert_char<_ECharT> {
using _Str = basic_string<_ECharT, _Traits, _Alloc>;
using _Base = __can_convert_char<_ECharT>;
+
+ _LIBCPP_HIDE_FROM_ABI
static _ECharT const* __range_begin(_Str const& __s) { return __s.data(); }
+
+ _LIBCPP_HIDE_FROM_ABI
static _ECharT const* __range_end(_Str const& __s) {
return __s.data() + __s.length();
}
+
+ _LIBCPP_HIDE_FROM_ABI
static _ECharT __first_or_null(_Str const& __s) {
return __s.empty() ? _ECharT{} : __s[0];
}
@@ -111,10 +124,16 @@ struct __is_pathable_string<
: public __can_convert_char<_ECharT> {
using _Str = basic_string_view<_ECharT, _Traits>;
using _Base = __can_convert_char<_ECharT>;
+
+ _LIBCPP_HIDE_FROM_ABI
static _ECharT const* __range_begin(_Str const& __s) { return __s.data(); }
+
+ _LIBCPP_HIDE_FROM_ABI
static _ECharT const* __range_end(_Str const& __s) {
return __s.data() + __s.length();
}
+
+ _LIBCPP_HIDE_FROM_ABI
static _ECharT __first_or_null(_Str const& __s) {
return __s.empty() ? _ECharT{} : __s[0];
}
@@ -132,7 +151,10 @@ struct __is_pathable_char_array<_Source, _ECharT*, _UPtr, true>
: __can_convert_char<typename remove_const<_ECharT>::type> {
using _Base = __can_convert_char<typename remove_const<_ECharT>::type>;
+ _LIBCPP_HIDE_FROM_ABI
static _ECharT const* __range_begin(const _ECharT* __b) { return __b; }
+
+ _LIBCPP_HIDE_FROM_ABI
static _ECharT const* __range_end(const _ECharT* __b) {
using _Iter = const _ECharT*;
const _ECharT __sentinel = _ECharT{};
@@ -142,6 +164,7 @@ struct __is_pathable_char_array<_Source, _ECharT*, _UPtr, true>
return __e;
}
+ _LIBCPP_HIDE_FROM_ABI
static _ECharT __first_or_null(const _ECharT* __b) { return *__b; }
};
@@ -158,9 +181,13 @@ struct __is_pathable_iter<
using _ECharT = typename iterator_traits<_Iter>::value_type;
using _Base = __can_convert_char<_ECharT>;
+ _LIBCPP_HIDE_FROM_ABI
static _Iter __range_begin(_Iter __b) { return __b; }
+
+ _LIBCPP_HIDE_FROM_ABI
static _NullSentinel __range_end(_Iter) { return _NullSentinel{}; }
+ _LIBCPP_HIDE_FROM_ABI
static _ECharT __first_or_null(_Iter __b) { return *__b; }
};
@@ -210,6 +237,7 @@ struct _PathCVT {
typedef __widen_from_utf8<sizeof(wchar_t) * __CHAR_BIT__> _Widener;
#endif
+ _LIBCPP_HIDE_FROM_ABI
static void __append_range(__path_string& __dest, _ECharT const* __b,
_ECharT const* __e) {
#if defined(_LIBCPP_WIN32API)
@@ -222,6 +250,7 @@ struct _PathCVT {
}
template <class _Iter>
+ _LIBCPP_HIDE_FROM_ABI
static void __append_range(__path_string& __dest, _Iter __b, _Iter __e) {
static_assert(!is_same<_Iter, _ECharT*>::value, "Call const overload");
if (__b == __e)
@@ -239,6 +268,7 @@ struct _PathCVT {
}
template <class _Iter>
+ _LIBCPP_HIDE_FROM_ABI
static void __append_range(__path_string& __dest, _Iter __b, _NullSentinel) {
static_assert(!is_same<_Iter, _ECharT*>::value, "Call const overload");
const _ECharT __sentinel = _ECharT{};
@@ -259,6 +289,7 @@ struct _PathCVT {
}
template <class _Source>
+ _LIBCPP_HIDE_FROM_ABI
static void __append_source(__path_string& __dest, _Source const& __s) {
using _Traits = __is_pathable<_Source>;
__append_range(__dest, _Traits::__range_begin(__s),
@@ -271,6 +302,7 @@ template <>
struct _PathCVT<__path_value> {
template <class _Iter>
+ _LIBCPP_HIDE_FROM_ABI
static typename enable_if<__is_exactly_cpp17_input_iterator<_Iter>::value>::type
__append_range(__path_string& __dest, _Iter __b, _Iter __e) {
for (; __b != __e; ++__b)
@@ -278,12 +310,14 @@ struct _PathCVT<__path_value> {
}
template <class _Iter>
+ _LIBCPP_HIDE_FROM_ABI
static typename enable_if<__is_cpp17_forward_iterator<_Iter>::value>::type
__append_range(__path_string& __dest, _Iter __b, _Iter __e) {
__dest.append(__b, __e);
}
template <class _Iter>
+ _LIBCPP_HIDE_FROM_ABI
static void __append_range(__path_string& __dest, _Iter __b, _NullSentinel) {
const char __sentinel = char{};
for (; *__b != __sentinel; ++__b)
@@ -291,6 +325,7 @@ struct _PathCVT<__path_value> {
}
template <class _Source>
+ _LIBCPP_HIDE_FROM_ABI
static void __append_source(__path_string& __dest, _Source const& __s) {
using _Traits = __is_pathable<_Source>;
__append_range(__dest, _Traits::__range_begin(__s),
@@ -302,6 +337,7 @@ struct _PathCVT<__path_value> {
template <>
struct _PathCVT<char> {
+ _LIBCPP_HIDE_FROM_ABI
static void
__append_string(__path_string& __dest, const basic_string<char> &__str) {
size_t __size = __char_to_wide(__str, nullptr, 0);
@@ -311,6 +347,7 @@ struct _PathCVT<char> {
}
template <class _Iter>
+ _LIBCPP_HIDE_FROM_ABI
static typename enable_if<__is_exactly_cpp17_input_iterator<_Iter>::value>::type
__append_range(__path_string& __dest, _Iter __b, _Iter __e) {
basic_string<char> __tmp(__b, __e);
@@ -318,6 +355,7 @@ struct _PathCVT<char> {
}
template <class _Iter>
+ _LIBCPP_HIDE_FROM_ABI
static typename enable_if<__is_cpp17_forward_iterator<_Iter>::value>::type
__append_range(__path_string& __dest, _Iter __b, _Iter __e) {
basic_string<char> __tmp(__b, __e);
@@ -325,6 +363,7 @@ struct _PathCVT<char> {
}
template <class _Iter>
+ _LIBCPP_HIDE_FROM_ABI
static void __append_range(__path_string& __dest, _Iter __b, _NullSentinel) {
const char __sentinel = char{};
basic_string<char> __tmp;
@@ -334,6 +373,7 @@ struct _PathCVT<char> {
}
template <class _Source>
+ _LIBCPP_HIDE_FROM_ABI
static void __append_source(__path_string& __dest, _Source const& __s) {
using _Traits = __is_pathable<_Source>;
__append_range(__dest, _Traits::__range_begin(__s),
@@ -347,6 +387,7 @@ struct _PathExport {
typedef __widen_from_utf8<sizeof(_ECharT) * __CHAR_BIT__> _Widener;
template <class _Str>
+ _LIBCPP_HIDE_FROM_ABI
static void __append(_Str& __dest, const __path_string& __src) {
string __utf8;
_Narrower()(back_inserter(__utf8), __src.data(), __src.data() + __src.size());
@@ -357,6 +398,7 @@ struct _PathExport {
template <>
struct _PathExport<char> {
template <class _Str>
+ _LIBCPP_HIDE_FROM_ABI
static void __append(_Str& __dest, const __path_string& __src) {
size_t __size = __wide_to_char(__src, nullptr, 0);
size_t __pos = __dest.size();
@@ -368,6 +410,7 @@ struct _PathExport<char> {
template <>
struct _PathExport<wchar_t> {
template <class _Str>
+ _LIBCPP_HIDE_FROM_ABI
static void __append(_Str& __dest, const __path_string& __src) {
__dest.append(__src.begin(), __src.end());
}
@@ -376,6 +419,7 @@ struct _PathExport<wchar_t> {
template <>
struct _PathExport<char16_t> {
template <class _Str>
+ _LIBCPP_HIDE_FROM_ABI
static void __append(_Str& __dest, const __path_string& __src) {
__dest.append(__src.begin(), __src.end());
}
@@ -387,6 +431,7 @@ struct _PathExport<char8_t> {
typedef __narrow_to_utf8<sizeof(wchar_t) * __CHAR_BIT__> _Narrower;
template <class _Str>
+ _LIBCPP_HIDE_FROM_ABI
static void __append(_Str& __dest, const __path_string& __src) {
_Narrower()(back_inserter(__dest), __src.data(), __src.data() + __src.size());
}
@@ -423,21 +468,23 @@ public:
};
// constructors and destructor
- _LIBCPP_INLINE_VISIBILITY path() noexcept {}
- _LIBCPP_INLINE_VISIBILITY path(const path& __p) : __pn_(__p.__pn_) {}
- _LIBCPP_INLINE_VISIBILITY path(path&& __p) noexcept
+ _LIBCPP_HIDE_FROM_ABI path() noexcept {}
+ _LIBCPP_HIDE_FROM_ABI path(const path& __p) : __pn_(__p.__pn_) {}
+ _LIBCPP_HIDE_FROM_ABI path(path&& __p) noexcept
: __pn_(_VSTD::move(__p.__pn_)) {}
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI
path(string_type&& __s, format = format::auto_format) noexcept
: __pn_(_VSTD::move(__s)) {}
template <class _Source, class = _EnableIfPathable<_Source, void> >
+ _LIBCPP_HIDE_FROM_ABI
path(const _Source& __src, format = format::auto_format) {
_SourceCVT<_Source>::__append_source(__pn_, __src);
}
template <class _InputIt>
+ _LIBCPP_HIDE_FROM_ABI
path(_InputIt __first, _InputIt __last, format = format::auto_format) {
typedef typename iterator_traits<_InputIt>::value_type _ItVal;
_PathCVT<_ItVal>::__append_range(__pn_, __first, __last);
@@ -454,41 +501,42 @@ public:
#endif
*/
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI
~path() = default;
// assignments
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI
path& operator=(const path& __p) {
__pn_ = __p.__pn_;
return *this;
}
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI
path& operator=(path&& __p) noexcept {
__pn_ = _VSTD::move(__p.__pn_);
return *this;
}
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI
path& operator=(string_type&& __s) noexcept {
__pn_ = _VSTD::move(__s);
return *this;
}
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI
path& assign(string_type&& __s) noexcept {
__pn_ = _VSTD::move(__s);
return *this;
}
template <class _Source>
- _LIBCPP_INLINE_VISIBILITY _EnableIfPathable<_Source>
+ _LIBCPP_HIDE_FROM_ABI _EnableIfPathable<_Source>
operator=(const _Source& __src) {
return this->assign(__src);
}
template <class _Source>
+ _LIBCPP_HIDE_FROM_ABI
_EnableIfPathable<_Source> assign(const _Source& __src) {
__pn_.clear();
_SourceCVT<_Source>::__append_source(__pn_, __src);
@@ -496,6 +544,7 @@ public:
}
template <class _InputIt>
+ _LIBCPP_HIDE_FROM_ABI
path& assign(_InputIt __first, _InputIt __last) {
typedef typename iterator_traits<_InputIt>::value_type _ItVal;
__pn_.clear();
@@ -506,6 +555,7 @@ public:
public:
// appends
#if defined(_LIBCPP_WIN32API)
+ _LIBCPP_HIDE_FROM_ABI
path& operator/=(const path& __p) {
auto __p_root_name = __p.__root_name();
auto __p_root_name_size = __p_root_name.size();
@@ -532,15 +582,18 @@ public:
}
template <class _Source>
+ _LIBCPP_HIDE_FROM_ABI
_EnableIfPathable<_Source> append(const _Source& __src) {
return operator/=(path(__src));
}
template <class _InputIt>
+ _LIBCPP_HIDE_FROM_ABI
path& append(_InputIt __first, _InputIt __last) {
return operator/=(path(__first, __last));
}
#else
+ _LIBCPP_HIDE_FROM_ABI
path& operator/=(const path& __p) {
if (__p.is_absolute()) {
__pn_ = __p.__pn_;
@@ -556,12 +609,13 @@ public:
// is known at compile time to be "/' since the user almost certainly intended
// to append a separator instead of overwriting the path with "/"
template <class _Source>
- _LIBCPP_INLINE_VISIBILITY _EnableIfPathable<_Source>
+ _LIBCPP_HIDE_FROM_ABI _EnableIfPathable<_Source>
operator/=(const _Source& __src) {
return this->append(__src);
}
template <class _Source>
+ _LIBCPP_HIDE_FROM_ABI
_EnableIfPathable<_Source> append(const _Source& __src) {
using _Traits = __is_pathable<_Source>;
using _CVT = _PathCVT<_SourceChar<_Source> >;
@@ -575,6 +629,7 @@ public:
}
template <class _InputIt>
+ _LIBCPP_HIDE_FROM_ABI
path& append(_InputIt __first, _InputIt __last) {
typedef typename iterator_traits<_InputIt>::value_type _ItVal;
static_assert(__can_convert_char<_ItVal>::value, "Must convertible");
@@ -589,37 +644,38 @@ public:
#endif
// concatenation
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI
path& operator+=(const path& __x) {
__pn_ += __x.__pn_;
return *this;
}
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI
path& operator+=(const string_type& __x) {
__pn_ += __x;
return *this;
}
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI
path& operator+=(__string_view __x) {
__pn_ += __x;
return *this;
}
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI
path& operator+=(const value_type* __x) {
__pn_ += __x;
return *this;
}
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI
path& operator+=(value_type __x) {
__pn_ += __x;
return *this;
}
template <class _ECharT>
+ _LIBCPP_HIDE_FROM_ABI
typename enable_if<__can_convert_char<_ECharT>::value, path&>::type
operator+=(_ECharT __x) {
_PathCVT<_ECharT>::__append_source(__pn_,
@@ -628,17 +684,20 @@ public:
}
template <class _Source>
+ _LIBCPP_HIDE_FROM_ABI
_EnableIfPathable<_Source> operator+=(const _Source& __x) {
return this->concat(__x);
}
template <class _Source>
+ _LIBCPP_HIDE_FROM_ABI
_EnableIfPathable<_Source> concat(const _Source& __x) {
_SourceCVT<_Source>::__append_source(__pn_, __x);
return *this;
}
template <class _InputIt>
+ _LIBCPP_HIDE_FROM_ABI
path& concat(_InputIt __first, _InputIt __last) {
typedef typename iterator_traits<_InputIt>::value_type _ItVal;
_PathCVT<_ItVal>::__append_range(__pn_, __first, __last);
@@ -646,9 +705,10 @@ public:
}
// modifiers
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI
void clear() noexcept { __pn_.clear(); }
+ _LIBCPP_HIDE_FROM_ABI
path& make_preferred() {
#if defined(_LIBCPP_WIN32API)
_VSTD::replace(__pn_.begin(), __pn_.end(), L'/', L'\\');
@@ -656,7 +716,7 @@ public:
return *this;
}
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI
path& remove_filename() {
auto __fname = __filename();
if (!__fname.empty())
@@ -664,6 +724,7 @@ public:
return *this;
}
+ _LIBCPP_HIDE_FROM_ABI
path& replace_filename(const path& __replacement) {
remove_filename();
return (*this /= __replacement);
@@ -671,25 +732,26 @@ public:
path& replace_extension(const path& __replacement = path());
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI
void swap(path& __rhs) noexcept { __pn_.swap(__rhs.__pn_); }
// private helper to allow reserving memory in the path
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI
void __reserve(size_t __s) { __pn_.reserve(__s); }
// native format observers
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI
const string_type& native() const noexcept { return __pn_; }
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI
const value_type* c_str() const noexcept { return __pn_.c_str(); }
- _LIBCPP_INLINE_VISIBILITY operator string_type() const { return __pn_; }
+ _LIBCPP_HIDE_FROM_ABI operator string_type() const { return __pn_; }
#if defined(_LIBCPP_WIN32API)
- _LIBCPP_INLINE_VISIBILITY _VSTD::wstring wstring() const { return __pn_; }
+ _LIBCPP_HIDE_FROM_ABI _VSTD::wstring wstring() const { return __pn_; }
+ _LIBCPP_HIDE_FROM_ABI
_VSTD::wstring generic_wstring() const {
_VSTD::wstring __s;
__s.resize(__pn_.size());
@@ -700,6 +762,7 @@ public:
#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
template <class _ECharT, class _Traits = char_traits<_ECharT>,
class _Allocator = allocator<_ECharT> >
+ _LIBCPP_HIDE_FROM_ABI
basic_string<_ECharT, _Traits, _Allocator>
string(const _Allocator& __a = _Allocator()) const {
using _Str = basic_string<_ECharT, _Traits, _Allocator>;
@@ -709,10 +772,10 @@ public:
return __s;
}
- _LIBCPP_INLINE_VISIBILITY _VSTD::string string() const {
+ _LIBCPP_HIDE_FROM_ABI _VSTD::string string() const {
return string<char>();
}
- _LIBCPP_INLINE_VISIBILITY __u8_string u8string() const {
+ _LIBCPP_HIDE_FROM_ABI __u8_string u8string() const {
using _CVT = __narrow_to_utf8<sizeof(wchar_t) * __CHAR_BIT__>;
__u8_string __s;
__s.reserve(__pn_.size());
@@ -720,16 +783,17 @@ public:
return __s;
}
- _LIBCPP_INLINE_VISIBILITY _VSTD::u16string u16string() const {
+ _LIBCPP_HIDE_FROM_ABI _VSTD::u16string u16string() const {
return string<char16_t>();
}
- _LIBCPP_INLINE_VISIBILITY _VSTD::u32string u32string() const {
+ _LIBCPP_HIDE_FROM_ABI _VSTD::u32string u32string() const {
return string<char32_t>();
}
// generic format observers
template <class _ECharT, class _Traits = char_traits<_ECharT>,
class _Allocator = allocator<_ECharT> >
+ _LIBCPP_HIDE_FROM_ABI
basic_string<_ECharT, _Traits, _Allocator>
generic_string(const _Allocator& __a = _Allocator()) const {
using _Str = basic_string<_ECharT, _Traits, _Allocator>;
@@ -742,9 +806,10 @@ public:
return __s;
}
- _VSTD::string generic_string() const { return generic_string<char>(); }
- _VSTD::u16string generic_u16string() const { return generic_string<char16_t>(); }
- _VSTD::u32string generic_u32string() const { return generic_string<char32_t>(); }
+ _LIBCPP_HIDE_FROM_ABI _VSTD::string generic_string() const { return generic_string<char>(); }
+ _LIBCPP_HIDE_FROM_ABI _VSTD::u16string generic_u16string() const { return generic_string<char16_t>(); }
+ _LIBCPP_HIDE_FROM_ABI _VSTD::u32string generic_u32string() const { return generic_string<char32_t>(); }
+ _LIBCPP_HIDE_FROM_ABI
__u8_string generic_u8string() const {
__u8_string __s = u8string();
_VSTD::replace(__s.begin(), __s.end(), '\\', '/');
@@ -753,16 +818,17 @@ public:
#endif /* !_LIBCPP_HAS_NO_LOCALIZATION */
#else /* _LIBCPP_WIN32API */
- _LIBCPP_INLINE_VISIBILITY _VSTD::string string() const { return __pn_; }
+ _LIBCPP_HIDE_FROM_ABI _VSTD::string string() const { return __pn_; }
#ifndef _LIBCPP_HAS_NO_CHAR8_T
- _LIBCPP_INLINE_VISIBILITY _VSTD::u8string u8string() const { return _VSTD::u8string(__pn_.begin(), __pn_.end()); }
+ _LIBCPP_HIDE_FROM_ABI _VSTD::u8string u8string() const { return _VSTD::u8string(__pn_.begin(), __pn_.end()); }
#else
- _LIBCPP_INLINE_VISIBILITY _VSTD::string u8string() const { return __pn_; }
+ _LIBCPP_HIDE_FROM_ABI _VSTD::string u8string() const { return __pn_; }
#endif
#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
template <class _ECharT, class _Traits = char_traits<_ECharT>,
class _Allocator = allocator<_ECharT> >
+ _LIBCPP_HIDE_FROM_ABI
basic_string<_ECharT, _Traits, _Allocator>
string(const _Allocator& __a = _Allocator()) const {
using _CVT = __widen_from_utf8<sizeof(_ECharT) * __CHAR_BIT__>;
@@ -774,39 +840,40 @@ public:
}
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
- _LIBCPP_INLINE_VISIBILITY _VSTD::wstring wstring() const {
+ _LIBCPP_HIDE_FROM_ABI _VSTD::wstring wstring() const {
return string<wchar_t>();
}
#endif
- _LIBCPP_INLINE_VISIBILITY _VSTD::u16string u16string() const {
+ _LIBCPP_HIDE_FROM_ABI _VSTD::u16string u16string() const {
return string<char16_t>();
}
- _LIBCPP_INLINE_VISIBILITY _VSTD::u32string u32string() const {
+ _LIBCPP_HIDE_FROM_ABI _VSTD::u32string u32string() const {
return string<char32_t>();
}
#endif /* !_LIBCPP_HAS_NO_LOCALIZATION */
// generic format observers
- _VSTD::string generic_string() const { return __pn_; }
+ _LIBCPP_HIDE_FROM_ABI _VSTD::string generic_string() const { return __pn_; }
#ifndef _LIBCPP_HAS_NO_CHAR8_T
- _VSTD::u8string generic_u8string() const { return _VSTD::u8string(__pn_.begin(), __pn_.end()); }
+ _LIBCPP_HIDE_FROM_ABI _VSTD::u8string generic_u8string() const { return _VSTD::u8string(__pn_.begin(), __pn_.end()); }
#else
- _VSTD::string generic_u8string() const { return __pn_; }
+ _LIBCPP_HIDE_FROM_ABI _VSTD::string generic_u8string() const { return __pn_; }
#endif
#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
template <class _ECharT, class _Traits = char_traits<_ECharT>,
class _Allocator = allocator<_ECharT> >
+ _LIBCPP_HIDE_FROM_ABI
basic_string<_ECharT, _Traits, _Allocator>
generic_string(const _Allocator& __a = _Allocator()) const {
return string<_ECharT, _Traits, _Allocator>(__a);
}
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
- _VSTD::wstring generic_wstring() const { return string<wchar_t>(); }
+ _LIBCPP_HIDE_FROM_ABI _VSTD::wstring generic_wstring() const { return string<wchar_t>(); }
#endif
- _VSTD::u16string generic_u16string() const { return string<char16_t>(); }
- _VSTD::u32string generic_u32string() const { return string<char32_t>(); }
+ _LIBCPP_HIDE_FROM_ABI _VSTD::u16string generic_u16string() const { return string<char16_t>(); }
+ _LIBCPP_HIDE_FROM_ABI _VSTD::u32string generic_u32string() const { return string<char32_t>(); }
#endif /* !_LIBCPP_HAS_NO_LOCALIZATION */
#endif /* !_LIBCPP_WIN32API */
@@ -823,77 +890,77 @@ private:
public:
// compare
- _LIBCPP_INLINE_VISIBILITY int compare(const path& __p) const noexcept {
+ _LIBCPP_HIDE_FROM_ABI int compare(const path& __p) const noexcept {
return __compare(__p.__pn_);
}
- _LIBCPP_INLINE_VISIBILITY int compare(const string_type& __s) const {
+ _LIBCPP_HIDE_FROM_ABI int compare(const string_type& __s) const {
return __compare(__s);
}
- _LIBCPP_INLINE_VISIBILITY int compare(__string_view __s) const {
+ _LIBCPP_HIDE_FROM_ABI int compare(__string_view __s) const {
return __compare(__s);
}
- _LIBCPP_INLINE_VISIBILITY int compare(const value_type* __s) const {
+ _LIBCPP_HIDE_FROM_ABI int compare(const value_type* __s) const {
return __compare(__s);
}
// decomposition
- _LIBCPP_INLINE_VISIBILITY path root_name() const {
+ _LIBCPP_HIDE_FROM_ABI path root_name() const {
return string_type(__root_name());
}
- _LIBCPP_INLINE_VISIBILITY path root_directory() const {
+ _LIBCPP_HIDE_FROM_ABI path root_directory() const {
return string_type(__root_directory());
}
- _LIBCPP_INLINE_VISIBILITY path root_path() const {
+ _LIBCPP_HIDE_FROM_ABI path root_path() const {
#if defined(_LIBCPP_WIN32API)
return string_type(__root_path_raw());
#else
return root_name().append(string_type(__root_directory()));
#endif
}
- _LIBCPP_INLINE_VISIBILITY path relative_path() const {
+ _LIBCPP_HIDE_FROM_ABI path relative_path() const {
return string_type(__relative_path());
}
- _LIBCPP_INLINE_VISIBILITY path parent_path() const {
+ _LIBCPP_HIDE_FROM_ABI path parent_path() const {
return string_type(__parent_path());
}
- _LIBCPP_INLINE_VISIBILITY path filename() const {
+ _LIBCPP_HIDE_FROM_ABI path filename() const {
return string_type(__filename());
}
- _LIBCPP_INLINE_VISIBILITY path stem() const { return string_type(__stem()); }
- _LIBCPP_INLINE_VISIBILITY path extension() const {
+ _LIBCPP_HIDE_FROM_ABI path stem() const { return string_type(__stem()); }
+ _LIBCPP_HIDE_FROM_ABI path extension() const {
return string_type(__extension());
}
// query
- _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY bool
+ _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI bool
empty() const noexcept {
return __pn_.empty();
}
- _LIBCPP_INLINE_VISIBILITY bool has_root_name() const {
+ _LIBCPP_HIDE_FROM_ABI bool has_root_name() const {
return !__root_name().empty();
}
- _LIBCPP_INLINE_VISIBILITY bool has_root_directory() const {
+ _LIBCPP_HIDE_FROM_ABI bool has_root_directory() const {
return !__root_directory().empty();
}
- _LIBCPP_INLINE_VISIBILITY bool has_root_path() const {
+ _LIBCPP_HIDE_FROM_ABI bool has_root_path() const {
return !__root_path_raw().empty();
}
- _LIBCPP_INLINE_VISIBILITY bool has_relative_path() const {
+ _LIBCPP_HIDE_FROM_ABI bool has_relative_path() const {
return !__relative_path().empty();
}
- _LIBCPP_INLINE_VISIBILITY bool has_parent_path() const {
+ _LIBCPP_HIDE_FROM_ABI bool has_parent_path() const {
return !__parent_path().empty();
}
- _LIBCPP_INLINE_VISIBILITY bool has_filename() const {
+ _LIBCPP_HIDE_FROM_ABI bool has_filename() const {
return !__filename().empty();
}
- _LIBCPP_INLINE_VISIBILITY bool has_stem() const { return !__stem().empty(); }
- _LIBCPP_INLINE_VISIBILITY bool has_extension() const {
+ _LIBCPP_HIDE_FROM_ABI bool has_stem() const { return !__stem().empty(); }
+ _LIBCPP_HIDE_FROM_ABI bool has_extension() const {
return !__extension().empty();
}
- _LIBCPP_INLINE_VISIBILITY bool is_absolute() const {
+ _LIBCPP_HIDE_FROM_ABI bool is_absolute() const {
#if defined(_LIBCPP_WIN32API)
__string_view __root_name_str = __root_name();
__string_view __root_dir = __root_directory();
@@ -917,13 +984,13 @@ public:
return has_root_directory();
#endif
}
- _LIBCPP_INLINE_VISIBILITY bool is_relative() const { return !is_absolute(); }
+ _LIBCPP_HIDE_FROM_ABI bool is_relative() const { return !is_absolute(); }
// relative paths
path lexically_normal() const;
path lexically_relative(const path& __base) const;
- _LIBCPP_INLINE_VISIBILITY path lexically_proximate(const path& __base) const {
+ _LIBCPP_HIDE_FROM_ABI path lexically_proximate(const path& __base) const {
path __result = this->lexically_relative(__base);
if (__result.native().empty())
return *this;
@@ -939,7 +1006,7 @@ public:
#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
template <class _CharT, class _Traits>
- _LIBCPP_INLINE_VISIBILITY friend
+ _LIBCPP_HIDE_FROM_ABI friend
typename enable_if<is_same<_CharT, value_type>::value &&
is_same<_Traits, char_traits<value_type> >::value,
basic_ostream<_CharT, _Traits>&>::type
@@ -949,7 +1016,7 @@ public:
}
template <class _CharT, class _Traits>
- _LIBCPP_INLINE_VISIBILITY friend
+ _LIBCPP_HIDE_FROM_ABI friend
typename enable_if<!is_same<_CharT, value_type>::value ||
!is_same<_Traits, char_traits<value_type> >::value,
basic_ostream<_CharT, _Traits>&>::type
@@ -959,42 +1026,41 @@ public:
}
template <class _CharT, class _Traits>
- _LIBCPP_INLINE_VISIBILITY friend basic_istream<_CharT, _Traits>&
+ _LIBCPP_HIDE_FROM_ABI friend basic_istream<_CharT, _Traits>&
operator>>(basic_istream<_CharT, _Traits>& __is, path& __p) {
basic_string<_CharT, _Traits> __tmp;
- __is >> __quoted(__tmp);
+ __is >> _VSTD::__quoted(__tmp);
__p = __tmp;
return __is;
}
#endif // !_LIBCPP_HAS_NO_LOCALIZATION
- friend _LIBCPP_INLINE_VISIBILITY bool operator==(const path& __lhs, const path& __rhs) noexcept {
+ friend _LIBCPP_HIDE_FROM_ABI bool operator==(const path& __lhs, const path& __rhs) noexcept {
return __lhs.__compare(__rhs.__pn_) == 0;
}
- friend _LIBCPP_INLINE_VISIBILITY bool operator!=(const path& __lhs, const path& __rhs) noexcept {
+ friend _LIBCPP_HIDE_FROM_ABI bool operator!=(const path& __lhs, const path& __rhs) noexcept {
return __lhs.__compare(__rhs.__pn_) != 0;
}
- friend _LIBCPP_INLINE_VISIBILITY bool operator<(const path& __lhs, const path& __rhs) noexcept {
+ friend _LIBCPP_HIDE_FROM_ABI bool operator<(const path& __lhs, const path& __rhs) noexcept {
return __lhs.__compare(__rhs.__pn_) < 0;
}
- friend _LIBCPP_INLINE_VISIBILITY bool operator<=(const path& __lhs, const path& __rhs) noexcept {
+ friend _LIBCPP_HIDE_FROM_ABI bool operator<=(const path& __lhs, const path& __rhs) noexcept {
return __lhs.__compare(__rhs.__pn_) <= 0;
}
- friend _LIBCPP_INLINE_VISIBILITY bool operator>(const path& __lhs, const path& __rhs) noexcept {
+ friend _LIBCPP_HIDE_FROM_ABI bool operator>(const path& __lhs, const path& __rhs) noexcept {
return __lhs.__compare(__rhs.__pn_) > 0;
}
- friend _LIBCPP_INLINE_VISIBILITY bool operator>=(const path& __lhs, const path& __rhs) noexcept {
+ friend _LIBCPP_HIDE_FROM_ABI bool operator>=(const path& __lhs, const path& __rhs) noexcept {
return __lhs.__compare(__rhs.__pn_) >= 0;
}
- friend _LIBCPP_INLINE_VISIBILITY path operator/(const path& __lhs,
- const path& __rhs) {
+ friend _LIBCPP_HIDE_FROM_ABI path operator/(const path& __lhs, const path& __rhs) {
path __result(__lhs);
__result /= __rhs;
return __result;
}
private:
- inline _LIBCPP_INLINE_VISIBILITY path&
+ inline _LIBCPP_HIDE_FROM_ABI path&
__assign_view(__string_view const& __s) noexcept {
__pn_ = string_type(__s);
return *this;
@@ -1002,7 +1068,7 @@ private:
string_type __pn_;
};
-inline _LIBCPP_INLINE_VISIBILITY void swap(path& __lhs, path& __rhs) noexcept {
+inline _LIBCPP_HIDE_FROM_ABI void swap(path& __lhs, path& __rhs) noexcept {
__lhs.swap(__rhs);
}
diff --git a/libcxx/include/__filesystem/path_iterator.h b/libcxx/include/__filesystem/path_iterator.h
index 08039e4c8a36..6f2baf8f7a29 100644
--- a/libcxx/include/__filesystem/path_iterator.h
+++ b/libcxx/include/__filesystem/path_iterator.h
@@ -10,15 +10,19 @@
#ifndef _LIBCPP___FILESYSTEM_PATH_ITERATOR_H
#define _LIBCPP___FILESYSTEM_PATH_ITERATOR_H
+#include <__assert>
#include <__availability>
#include <__config>
-#include <__debug>
#include <__filesystem/path.h>
#include <__iterator/iterator_traits.h>
#include <cstddef>
#include <string>
#include <string_view>
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
#ifndef _LIBCPP_CXX03_LANG
_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
diff --git a/libcxx/include/__filesystem/perm_options.h b/libcxx/include/__filesystem/perm_options.h
index 62cd8f575650..f7580a2473d0 100644
--- a/libcxx/include/__filesystem/perm_options.h
+++ b/libcxx/include/__filesystem/perm_options.h
@@ -13,6 +13,10 @@
#include <__availability>
#include <__config>
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
#ifndef _LIBCPP_CXX03_LANG
_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
diff --git a/libcxx/include/__filesystem/perms.h b/libcxx/include/__filesystem/perms.h
index 832f8b07e55c..0e5c7ed8d2e9 100644
--- a/libcxx/include/__filesystem/perms.h
+++ b/libcxx/include/__filesystem/perms.h
@@ -13,6 +13,10 @@
#include <__availability>
#include <__config>
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
#ifndef _LIBCPP_CXX03_LANG
_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
diff --git a/libcxx/include/__filesystem/recursive_directory_iterator.h b/libcxx/include/__filesystem/recursive_directory_iterator.h
index c26d0a381159..b20d201f5836 100644
--- a/libcxx/include/__filesystem/recursive_directory_iterator.h
+++ b/libcxx/include/__filesystem/recursive_directory_iterator.h
@@ -22,6 +22,10 @@
#include <cstddef>
#include <system_error>
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
#ifndef _LIBCPP_CXX03_LANG
_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
@@ -164,7 +168,7 @@ _LIBCPP_AVAILABILITY_FILESYSTEM_POP
_LIBCPP_END_NAMESPACE_FILESYSTEM
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17
template <>
_LIBCPP_AVAILABILITY_FILESYSTEM
@@ -174,7 +178,7 @@ template <>
_LIBCPP_AVAILABILITY_FILESYSTEM
inline constexpr bool _VSTD::ranges::enable_view<_VSTD_FS::recursive_directory_iterator> = true;
-#endif
+#endif // _LIBCPP_STD_VER > 17
#endif // _LIBCPP_CXX03_LANG
diff --git a/libcxx/include/__filesystem/space_info.h b/libcxx/include/__filesystem/space_info.h
index 098f085678e4..d7dc03af75a7 100644
--- a/libcxx/include/__filesystem/space_info.h
+++ b/libcxx/include/__filesystem/space_info.h
@@ -14,6 +14,10 @@
#include <__config>
#include <cstdint>
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
#ifndef _LIBCPP_CXX03_LANG
_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
diff --git a/libcxx/include/__filesystem/u8path.h b/libcxx/include/__filesystem/u8path.h
index dca3b0c5028b..d35faa14bb8a 100644
--- a/libcxx/include/__filesystem/u8path.h
+++ b/libcxx/include/__filesystem/u8path.h
@@ -10,11 +10,23 @@
#ifndef _LIBCPP___FILESYSTEM_U8PATH_H
#define _LIBCPP___FILESYSTEM_U8PATH_H
+#include <__algorithm/unwrap_iter.h>
#include <__availability>
#include <__config>
#include <__filesystem/path.h>
+#include <string>
#include <type_traits>
+// Only required on Windows for __widen_from_utf8, and included conservatively
+// because it requires support for localization.
+#if defined(_LIBCPP_WIN32API)
+# include <locale>
+#endif
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
#ifndef _LIBCPP_CXX03_LANG
_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
diff --git a/libcxx/include/__format/buffer.h b/libcxx/include/__format/buffer.h
new file mode 100644
index 000000000000..d9b08064dfb3
--- /dev/null
+++ b/libcxx/include/__format/buffer.h
@@ -0,0 +1,369 @@
+// -*- 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___FORMAT_BUFFER_H
+#define _LIBCPP___FORMAT_BUFFER_H
+
+#include <__algorithm/copy_n.h>
+#include <__algorithm/max.h>
+#include <__algorithm/min.h>
+#include <__algorithm/unwrap_iter.h>
+#include <__config>
+#include <__format/enable_insertable.h>
+#include <__format/format_to_n_result.h>
+#include <__format/formatter.h> // for __char_type TODO FMT Move the concept?
+#include <__iterator/back_insert_iterator.h>
+#include <__iterator/concepts.h>
+#include <__iterator/incrementable_traits.h>
+#include <__iterator/iterator_traits.h>
+#include <__iterator/wrap_iter.h>
+#include <__utility/move.h>
+#include <concepts>
+#include <cstddef>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 17
+
+namespace __format {
+
+/// A "buffer" that handles writing to the proper iterator.
+///
+/// This helper is used together with the @ref back_insert_iterator to offer
+/// type-erasure for the formatting functions. This reduces the number to
+/// template instantiations.
+template <__formatter::__char_type _CharT>
+class _LIBCPP_TEMPLATE_VIS __output_buffer {
+public:
+ using value_type = _CharT;
+
+ template <class _Tp>
+ _LIBCPP_HIDE_FROM_ABI explicit __output_buffer(_CharT* __ptr,
+ size_t __capacity, _Tp* __obj)
+ : __ptr_(__ptr), __capacity_(__capacity),
+ __flush_([](_CharT* __p, size_t __size, void* __o) {
+ static_cast<_Tp*>(__o)->flush(__p, __size);
+ }),
+ __obj_(__obj) {}
+
+ _LIBCPP_HIDE_FROM_ABI void reset(_CharT* __ptr, size_t __capacity) {
+ __ptr_ = __ptr;
+ __capacity_ = __capacity;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI auto make_output_iterator() {
+ return back_insert_iterator{*this};
+ }
+
+ // TODO FMT It would be nice to have an overload taking a
+ // basic_string_view<_CharT> and append it directly.
+ _LIBCPP_HIDE_FROM_ABI void push_back(_CharT __c) {
+ __ptr_[__size_++] = __c;
+
+ // Profiling showed flushing after adding is more efficient than flushing
+ // when entering the function.
+ if (__size_ == __capacity_)
+ flush();
+ }
+
+ _LIBCPP_HIDE_FROM_ABI void flush() {
+ __flush_(__ptr_, __size_, __obj_);
+ __size_ = 0;
+ }
+
+private:
+ _CharT* __ptr_;
+ size_t __capacity_;
+ size_t __size_{0};
+ void (*__flush_)(_CharT*, size_t, void*);
+ void* __obj_;
+};
+
+/// A storage using an internal buffer.
+///
+/// This storage is used when writing a single element to the output iterator
+/// is expensive.
+template <__formatter::__char_type _CharT>
+class _LIBCPP_TEMPLATE_VIS __internal_storage {
+public:
+ _LIBCPP_HIDE_FROM_ABI _CharT* begin() { return __buffer_; }
+
+ static constexpr size_t __buffer_size = 256 / sizeof(_CharT);
+
+private:
+ _CharT __buffer_[__buffer_size];
+};
+
+/// A storage writing directly to the storage.
+///
+/// This requires the storage to be a contiguous buffer of \a _CharT.
+/// Since the output is directly written to the underlying storage this class
+/// is just an empty class.
+template <__formatter::__char_type _CharT>
+class _LIBCPP_TEMPLATE_VIS __direct_storage {};
+
+template <class _OutIt, class _CharT>
+concept __enable_direct_output = __formatter::__char_type<_CharT> &&
+ (same_as<_OutIt, _CharT*>
+#ifndef _LIBCPP_ENABLE_DEBUG_MODE
+ || same_as<_OutIt, __wrap_iter<_CharT*>>
+#endif
+ );
+
+/// Write policy for directly writing to the underlying output.
+template <class _OutIt, __formatter::__char_type _CharT>
+class _LIBCPP_TEMPLATE_VIS __writer_direct {
+public:
+ _LIBCPP_HIDE_FROM_ABI explicit __writer_direct(_OutIt __out_it)
+ : __out_it_(__out_it) {}
+
+ _LIBCPP_HIDE_FROM_ABI auto out() { return __out_it_; }
+
+ _LIBCPP_HIDE_FROM_ABI void flush(_CharT*, size_t __size) {
+ // _OutIt can be a __wrap_iter<CharT*>. Therefore the original iterator
+ // is adjusted.
+ __out_it_ += __size;
+ }
+
+private:
+ _OutIt __out_it_;
+};
+
+/// Write policy for copying the buffer to the output.
+template <class _OutIt, __formatter::__char_type _CharT>
+class _LIBCPP_TEMPLATE_VIS __writer_iterator {
+public:
+ _LIBCPP_HIDE_FROM_ABI explicit __writer_iterator(_OutIt __out_it)
+ : __out_it_{_VSTD::move(__out_it)} {}
+
+ _LIBCPP_HIDE_FROM_ABI auto out() { return __out_it_; }
+
+ _LIBCPP_HIDE_FROM_ABI void flush(_CharT* __ptr, size_t __size) {
+ __out_it_ = _VSTD::copy_n(__ptr, __size, _VSTD::move(__out_it_));
+ }
+
+private:
+ _OutIt __out_it_;
+};
+
+/// Concept to see whether a \a _Container is insertable.
+///
+/// The concept is used to validate whether multiple calls to a
+/// \ref back_insert_iterator can be replace by a call to \c _Container::insert.
+///
+/// \note a \a _Container needs to opt-in to the concept by specializing
+/// \ref __enable_insertable.
+template <class _Container>
+concept __insertable =
+ __enable_insertable<_Container> && __formatter::__char_type<typename _Container::value_type> &&
+ requires(_Container& __t, add_pointer_t<typename _Container::value_type> __first,
+ add_pointer_t<typename _Container::value_type> __last) { __t.insert(__t.end(), __first, __last); };
+
+/// Extract the container type of a \ref back_insert_iterator.
+template <class _It>
+struct _LIBCPP_TEMPLATE_VIS __back_insert_iterator_container {
+ using type = void;
+};
+
+template <__insertable _Container>
+struct _LIBCPP_TEMPLATE_VIS __back_insert_iterator_container<back_insert_iterator<_Container>> {
+ using type = _Container;
+};
+
+/// Write policy for inserting the buffer in a container.
+template <class _Container>
+class _LIBCPP_TEMPLATE_VIS __writer_container {
+public:
+ using _CharT = typename _Container::value_type;
+
+ _LIBCPP_HIDE_FROM_ABI explicit __writer_container(back_insert_iterator<_Container> __out_it)
+ : __container_{__out_it.__get_container()} {}
+
+ _LIBCPP_HIDE_FROM_ABI auto out() { return back_inserter(*__container_); }
+
+ _LIBCPP_HIDE_FROM_ABI void flush(_CharT* __ptr, size_t __size) {
+ __container_->insert(__container_->end(), __ptr, __ptr + __size);
+ }
+
+private:
+ _Container* __container_;
+};
+
+/// Selects the type of the writer used for the output iterator.
+template <class _OutIt, class _CharT>
+class _LIBCPP_TEMPLATE_VIS __writer_selector {
+ using _Container = typename __back_insert_iterator_container<_OutIt>::type;
+
+public:
+ using type = conditional_t<!same_as<_Container, void>, __writer_container<_Container>,
+ conditional_t<__enable_direct_output<_OutIt, _CharT>, __writer_direct<_OutIt, _CharT>,
+ __writer_iterator<_OutIt, _CharT>>>;
+};
+
+/// The generic formatting buffer.
+template <class _OutIt, __formatter::__char_type _CharT>
+requires(output_iterator<_OutIt, const _CharT&>) class _LIBCPP_TEMPLATE_VIS
+ __format_buffer {
+ using _Storage =
+ conditional_t<__enable_direct_output<_OutIt, _CharT>,
+ __direct_storage<_CharT>, __internal_storage<_CharT>>;
+
+public:
+ _LIBCPP_HIDE_FROM_ABI explicit __format_buffer(_OutIt __out_it)
+ requires(same_as<_Storage, __internal_storage<_CharT>>)
+ : __output_(__storage_.begin(), __storage_.__buffer_size, this), __writer_(_VSTD::move(__out_it)) {}
+
+ _LIBCPP_HIDE_FROM_ABI explicit __format_buffer(_OutIt __out_it) requires(
+ same_as<_Storage, __direct_storage<_CharT>>)
+ : __output_(_VSTD::__unwrap_iter(__out_it), size_t(-1), this),
+ __writer_(_VSTD::move(__out_it)) {}
+
+ _LIBCPP_HIDE_FROM_ABI auto make_output_iterator() {
+ return __output_.make_output_iterator();
+ }
+
+ _LIBCPP_HIDE_FROM_ABI void flush(_CharT* __ptr, size_t __size) {
+ __writer_.flush(__ptr, __size);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI _OutIt out() && {
+ __output_.flush();
+ return _VSTD::move(__writer_).out();
+ }
+
+private:
+ _LIBCPP_NO_UNIQUE_ADDRESS _Storage __storage_;
+ __output_buffer<_CharT> __output_;
+ typename __writer_selector<_OutIt, _CharT>::type __writer_;
+};
+
+/// A buffer that counts the number of insertions.
+///
+/// Since \ref formatted_size only needs to know the size, the output itself is
+/// discarded.
+template <__formatter::__char_type _CharT>
+class _LIBCPP_TEMPLATE_VIS __formatted_size_buffer {
+public:
+ _LIBCPP_HIDE_FROM_ABI auto make_output_iterator() { return __output_.make_output_iterator(); }
+
+ _LIBCPP_HIDE_FROM_ABI void flush(const _CharT*, size_t __size) { __size_ += __size; }
+
+ _LIBCPP_HIDE_FROM_ABI size_t result() && {
+ __output_.flush();
+ return __size_;
+ }
+
+private:
+ __internal_storage<_CharT> __storage_;
+ __output_buffer<_CharT> __output_{__storage_.begin(), __storage_.__buffer_size, this};
+ size_t __size_{0};
+};
+
+/// The base of a buffer that counts and limits the number of insertions.
+template <class _OutIt, __formatter::__char_type _CharT, bool>
+ requires(output_iterator<_OutIt, const _CharT&>)
+struct _LIBCPP_TEMPLATE_VIS __format_to_n_buffer_base {
+ using _Size = iter_difference_t<_OutIt>;
+
+public:
+ _LIBCPP_HIDE_FROM_ABI explicit __format_to_n_buffer_base(_OutIt __out_it, _Size __n)
+ : __writer_(_VSTD::move(__out_it)), __n_(_VSTD::max(_Size(0), __n)) {}
+
+ _LIBCPP_HIDE_FROM_ABI void flush(_CharT* __ptr, size_t __size) {
+ if (_Size(__size_) <= __n_)
+ __writer_.flush(__ptr, _VSTD::min(_Size(__size), __n_ - __size_));
+ __size_ += __size;
+ }
+
+protected:
+ __internal_storage<_CharT> __storage_;
+ __output_buffer<_CharT> __output_{__storage_.begin(), __storage_.__buffer_size, this};
+ typename __writer_selector<_OutIt, _CharT>::type __writer_;
+
+ _Size __n_;
+ _Size __size_{0};
+};
+
+/// The base of a buffer that counts and limits the number of insertions.
+///
+/// This version is used when \c __enable_direct_output<_OutIt, _CharT> == true.
+///
+/// This class limits the size available the the direct writer so it will not
+/// exceed the maximum number of code units.
+template <class _OutIt, __formatter::__char_type _CharT>
+ requires(output_iterator<_OutIt, const _CharT&>)
+class _LIBCPP_TEMPLATE_VIS __format_to_n_buffer_base<_OutIt, _CharT, true> {
+ using _Size = iter_difference_t<_OutIt>;
+
+public:
+ _LIBCPP_HIDE_FROM_ABI explicit __format_to_n_buffer_base(_OutIt __out_it, _Size __n)
+ : __output_(_VSTD::__unwrap_iter(__out_it), __n, this), __writer_(_VSTD::move(__out_it)) {
+ if (__n <= 0) [[unlikely]]
+ __output_.reset(__storage_.begin(), __storage_.__buffer_size);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI void flush(_CharT* __ptr, size_t __size) {
+ // A flush to the direct writer happens in two occasions:
+ // - The format function has written the maximum number of allowed code
+ // units. At this point it's no longer valid to write to this writer. So
+ // switch to the internal storage. This internal storage doesn't need to
+ // be written anywhere so the flush for that storage writes no output.
+ // - The format_to_n function is finished. In this case there's no need to
+ // switch the buffer, but for simplicity the buffers are still switched.
+ // When the __n <= 0 the constructor already switched the buffers.
+ if (__size_ == 0 && __ptr != __storage_.begin()) {
+ __writer_.flush(__ptr, __size);
+ __output_.reset(__storage_.begin(), __storage_.__buffer_size);
+ }
+
+ __size_ += __size;
+ }
+
+protected:
+ __internal_storage<_CharT> __storage_;
+ __output_buffer<_CharT> __output_;
+ __writer_direct<_OutIt, _CharT> __writer_;
+
+ _Size __size_{0};
+};
+
+/// The buffer that counts and limits the number of insertions.
+template <class _OutIt, __formatter::__char_type _CharT>
+ requires(output_iterator<_OutIt, const _CharT&>)
+struct _LIBCPP_TEMPLATE_VIS __format_to_n_buffer final
+ : public __format_to_n_buffer_base< _OutIt, _CharT, __enable_direct_output<_OutIt, _CharT>> {
+ using _Base = __format_to_n_buffer_base<_OutIt, _CharT, __enable_direct_output<_OutIt, _CharT>>;
+ using _Size = iter_difference_t<_OutIt>;
+
+public:
+ _LIBCPP_HIDE_FROM_ABI explicit __format_to_n_buffer(_OutIt __out_it, _Size __n) : _Base(_VSTD::move(__out_it), __n) {}
+ _LIBCPP_HIDE_FROM_ABI auto make_output_iterator() { return this->__output_.make_output_iterator(); }
+
+ _LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt> result() && {
+ this->__output_.flush();
+ return {_VSTD::move(this->__writer_).out(), this->__size_};
+ }
+};
+} // namespace __format
+
+#endif //_LIBCPP_STD_VER > 17
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___FORMAT_BUFFER_H
diff --git a/libcxx/include/__format/concepts.h b/libcxx/include/__format/concepts.h
new file mode 100644
index 000000000000..8df6493b0aed
--- /dev/null
+++ b/libcxx/include/__format/concepts.h
@@ -0,0 +1,53 @@
+// -*- 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___FORMAT_CONCEPTS_H
+#define _LIBCPP___FORMAT_CONCEPTS_H
+
+#include <__concepts/same_as.h>
+#include <__concepts/semiregular.h>
+#include <__config>
+#include <__format/format_fwd.h>
+#include <__format/format_parse_context.h>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 17
+
+// The output iterator isn't specified. A formatter should accept any
+// output_iterator. This iterator is a minimal iterator to test the concept.
+// (Note testing for (w)format_context would be a valid choice, but requires
+// selecting the proper one depending on the type of _CharT.)
+template <class _CharT>
+using __fmt_iter_for = _CharT*;
+
+// The concept is based on P2286R6
+// It lacks the const of __cf as required by, the not yet accepted, LWG-3636.
+// The current formatters can't be easily adapted, but that is WIP.
+// TODO FMT properly implement this concepts once accepted.
+template <class _Tp, class _CharT>
+concept __formattable = (semiregular<formatter<remove_cvref_t<_Tp>, _CharT>>) &&
+ requires(formatter<remove_cvref_t<_Tp>, _CharT> __f,
+ formatter<remove_cvref_t<_Tp>, _CharT> __cf, _Tp __t,
+ basic_format_context<__fmt_iter_for<_CharT>, _CharT> __fc,
+ basic_format_parse_context<_CharT> __pc) {
+ { __f.parse(__pc) } -> same_as<typename basic_format_parse_context<_CharT>::iterator>;
+ { __cf.format(__t, __fc) } -> same_as<__fmt_iter_for<_CharT>>;
+ };
+
+#endif //_LIBCPP_STD_VER > 17
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___FORMAT_CONCEPTS_H
diff --git a/libcxx/include/__format/enable_insertable.h b/libcxx/include/__format/enable_insertable.h
new file mode 100644
index 000000000000..71b4252930de
--- /dev/null
+++ b/libcxx/include/__format/enable_insertable.h
@@ -0,0 +1,35 @@
+// -*- 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___FORMAT_ENABLE_INSERTABLE_H
+#define _LIBCPP___FORMAT_ENABLE_INSERTABLE_H
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 17
+
+namespace __format {
+
+/// Opt-in to enable \ref __insertable for a \a _Container.
+template <class _Container>
+inline constexpr bool __enable_insertable = false;
+
+} // namespace __format
+
+#endif //_LIBCPP_STD_VER > 17
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___FORMAT_ENABLE_INSERTABLE_H
diff --git a/libcxx/include/__format/format_arg.h b/libcxx/include/__format/format_arg.h
index e76b0dd50d3c..3f2afc898d2c 100644
--- a/libcxx/include/__format/format_arg.h
+++ b/libcxx/include/__format/format_arg.h
@@ -10,39 +10,41 @@
#ifndef _LIBCPP___FORMAT_FORMAT_ARG_H
#define _LIBCPP___FORMAT_FORMAT_ARG_H
+#include <__assert>
#include <__concepts/arithmetic.h>
#include <__config>
#include <__format/format_error.h>
#include <__format/format_fwd.h>
#include <__format/format_parse_context.h>
-#include <__functional_base>
+#include <__functional/invoke.h>
#include <__memory/addressof.h>
+#include <__utility/forward.h>
+#include <__utility/unreachable.h>
#include <__variant/monostate.h>
#include <string>
#include <string_view>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
-_LIBCPP_PUSH_MACROS
-#include <__undef_macros>
-
_LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER > 17
-// TODO FMT Remove this once we require compilers with proper C++20 support.
-// If the compiler has no concepts support, the format header will be disabled.
-// Without concepts support enable_if needs to be used and that too much effort
-// to support compilers with partial C++20 support.
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
-
namespace __format {
/// The type stored in @ref basic_format_arg.
///
/// @note The 128-bit types are unconditionally in the list to avoid the values
/// of the enums to depend on the availability of 128-bit integers.
+///
+/// @note The value is stored as a 5-bit value in the __packed_arg_t_bits. This
+/// limits the maximum number of elements to 32.
+/// When modifying update the test
+/// test/libcxx/utilities/format/format.arguments/format.arg/arg_t.compile.pass.cpp
+/// It could be packed in 4-bits but that means a new type directly becomes an
+/// ABI break. The packed type is 64-bit so this reduces the maximum number of
+/// packed elements from 16 to 12.
enum class _LIBCPP_ENUM_VIS __arg_t : uint8_t {
__none,
__boolean,
@@ -61,58 +63,151 @@ enum class _LIBCPP_ENUM_VIS __arg_t : uint8_t {
__ptr,
__handle
};
+
+inline constexpr unsigned __packed_arg_t_bits = 5;
+inline constexpr uint8_t __packed_arg_t_mask = 0x1f;
+
+inline constexpr unsigned __packed_types_storage_bits = 64;
+inline constexpr unsigned __packed_types_max = __packed_types_storage_bits / __packed_arg_t_bits;
+
+_LIBCPP_HIDE_FROM_ABI
+constexpr bool __use_packed_format_arg_store(size_t __size) { return __size <= __packed_types_max; }
+
+_LIBCPP_HIDE_FROM_ABI
+constexpr __arg_t __get_packed_type(uint64_t __types, size_t __id) {
+ _LIBCPP_ASSERT(__id <= __packed_types_max, "");
+
+ if (__id > 0)
+ __types >>= __id * __packed_arg_t_bits;
+
+ return static_cast<__format::__arg_t>(__types & __packed_arg_t_mask);
+}
+
} // namespace __format
template <class _Visitor, class _Context>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT decltype(auto)
-visit_format_arg(_Visitor&& __vis, basic_format_arg<_Context> __arg) {
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT decltype(auto) visit_format_arg(_Visitor&& __vis,
+ basic_format_arg<_Context> __arg) {
switch (__arg.__type_) {
case __format::__arg_t::__none:
- return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), monostate{});
+ return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__monostate_);
case __format::__arg_t::__boolean:
- return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__boolean);
+ return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__boolean_);
case __format::__arg_t::__char_type:
- return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__char_type);
+ return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__char_type_);
case __format::__arg_t::__int:
- return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__int);
+ return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__int_);
case __format::__arg_t::__long_long:
- return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__long_long);
+ return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__long_long_);
case __format::__arg_t::__i128:
-#ifndef _LIBCPP_HAS_NO_INT128
- return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__i128);
-#else
- _LIBCPP_UNREACHABLE();
-#endif
+# ifndef _LIBCPP_HAS_NO_INT128
+ return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__i128_);
+# else
+ __libcpp_unreachable();
+# endif
case __format::__arg_t::__unsigned:
- return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__unsigned);
+ return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__unsigned_);
case __format::__arg_t::__unsigned_long_long:
- return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis),
- __arg.__unsigned_long_long);
+ return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__unsigned_long_long_);
case __format::__arg_t::__u128:
-#ifndef _LIBCPP_HAS_NO_INT128
- return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__u128);
-#else
- _LIBCPP_UNREACHABLE();
-#endif
+# ifndef _LIBCPP_HAS_NO_INT128
+ return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__u128_);
+# else
+ __libcpp_unreachable();
+# endif
case __format::__arg_t::__float:
- return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__float);
+ return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__float_);
case __format::__arg_t::__double:
- return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__double);
+ return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__double_);
case __format::__arg_t::__long_double:
- return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__long_double);
+ return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__long_double_);
case __format::__arg_t::__const_char_type_ptr:
- return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis),
- __arg.__const_char_type_ptr);
+ return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__const_char_type_ptr_);
case __format::__arg_t::__string_view:
- return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__string_view);
+ return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__string_view_);
case __format::__arg_t::__ptr:
- return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__ptr);
+ return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__ptr_);
case __format::__arg_t::__handle:
- return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__handle);
+ return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis),
+ typename basic_format_arg<_Context>::handle{__arg.__value_.__handle_});
}
- _LIBCPP_UNREACHABLE();
+
+ __libcpp_unreachable();
}
+/// Contains the values used in basic_format_arg.
+///
+/// This is a separate type so it's possible to store the values and types in
+/// separate arrays.
+template <class _Context>
+class __basic_format_arg_value {
+ using _CharT = typename _Context::char_type;
+
+public:
+ /// Contains the implementation for basic_format_arg::handle.
+ struct __handle {
+ template <class _Tp>
+ _LIBCPP_HIDE_FROM_ABI explicit __handle(const _Tp& __v) noexcept
+ : __ptr_(_VSTD::addressof(__v)),
+ __format_([](basic_format_parse_context<_CharT>& __parse_ctx, _Context& __ctx, const void* __ptr) {
+ using _Formatter = typename _Context::template formatter_type<_Tp>;
+ using _Qp = conditional_t<requires { _Formatter().format(declval<const _Tp&>(), declval<_Context&>()); },
+ const _Tp, _Tp>;
+ _Formatter __f;
+ __parse_ctx.advance_to(__f.parse(__parse_ctx));
+ __ctx.advance_to(__f.format(*const_cast<_Qp*>(static_cast<const _Tp*>(__ptr)), __ctx));
+ }) {}
+
+ const void* __ptr_;
+ void (*__format_)(basic_format_parse_context<_CharT>&, _Context&, const void*);
+ };
+
+ union {
+ monostate __monostate_;
+ bool __boolean_;
+ _CharT __char_type_;
+ int __int_;
+ unsigned __unsigned_;
+ long long __long_long_;
+ unsigned long long __unsigned_long_long_;
+# ifndef _LIBCPP_HAS_NO_INT128
+ __int128_t __i128_;
+ __uint128_t __u128_;
+# endif
+ float __float_;
+ double __double_;
+ long double __long_double_;
+ const _CharT* __const_char_type_ptr_;
+ basic_string_view<_CharT> __string_view_;
+ const void* __ptr_;
+ __handle __handle_;
+ };
+
+ // These constructors contain the exact storage type used. If adjustments are
+ // required, these will be done in __create_format_arg.
+
+ _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value() noexcept : __monostate_() {}
+ _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(bool __value) noexcept : __boolean_(__value) {}
+ _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(_CharT __value) noexcept : __char_type_(__value) {}
+ _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(int __value) noexcept : __int_(__value) {}
+ _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(unsigned __value) noexcept : __unsigned_(__value) {}
+ _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(long long __value) noexcept : __long_long_(__value) {}
+ _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(unsigned long long __value) noexcept
+ : __unsigned_long_long_(__value) {}
+# ifndef _LIBCPP_HAS_NO_INT128
+ _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(__int128_t __value) noexcept : __i128_(__value) {}
+ _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(__uint128_t __value) noexcept : __u128_(__value) {}
+# endif
+ _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(float __value) noexcept : __float_(__value) {}
+ _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(double __value) noexcept : __double_(__value) {}
+ _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(long double __value) noexcept : __long_double_(__value) {}
+ _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(const _CharT* __value) noexcept : __const_char_type_ptr_(__value) {}
+ _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(basic_string_view<_CharT> __value) noexcept
+ : __string_view_(__value) {}
+ _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(const void* __value) noexcept : __ptr_(__value) {}
+ _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(__handle __value) noexcept : __handle_(__value) {}
+};
+
template <class _Context>
class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT basic_format_arg {
public:
@@ -139,154 +234,32 @@ private:
// .format(declval<const T&>(), declval<Context&>())
// shall be well-formed when treated as an unevaluated operand.
- template <class _Ctx, class... _Args>
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT friend __format_arg_store<_Ctx, _Args...>
- make_format_args(const _Args&...);
-
- template <class _Visitor, class _Ctx>
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT friend decltype(auto)
- visit_format_arg(_Visitor&& __vis, basic_format_arg<_Ctx> __arg);
-
- union {
- bool __boolean;
- char_type __char_type;
- int __int;
- unsigned __unsigned;
- long long __long_long;
- unsigned long long __unsigned_long_long;
-#ifndef _LIBCPP_HAS_NO_INT128
- __int128_t __i128;
- __uint128_t __u128;
-#endif
- float __float;
- double __double;
- long double __long_double;
- const char_type* __const_char_type_ptr;
- basic_string_view<char_type> __string_view;
- const void* __ptr;
- handle __handle;
- };
+public:
+ __basic_format_arg_value<_Context> __value_;
__format::__arg_t __type_;
- _LIBCPP_HIDE_FROM_ABI explicit basic_format_arg(bool __v) noexcept
- : __boolean(__v), __type_(__format::__arg_t::__boolean) {}
-
- template <class _Tp>
- _LIBCPP_HIDE_FROM_ABI explicit basic_format_arg(_Tp __v) noexcept
- requires(same_as<_Tp, char_type> ||
- (same_as<_Tp, char> && same_as<char_type, wchar_t>))
- : __char_type(__v), __type_(__format::__arg_t::__char_type) {}
-
- template <__libcpp_signed_integer _Tp>
- _LIBCPP_HIDE_FROM_ABI explicit basic_format_arg(_Tp __v) noexcept {
- if constexpr (sizeof(_Tp) <= sizeof(int)) {
- __int = static_cast<int>(__v);
- __type_ = __format::__arg_t::__int;
- } else if constexpr (sizeof(_Tp) <= sizeof(long long)) {
- __long_long = static_cast<long long>(__v);
- __type_ = __format::__arg_t::__long_long;
- }
-#ifndef _LIBCPP_HAS_NO_INT128
- else if constexpr (sizeof(_Tp) == sizeof(__int128_t)) {
- __i128 = __v;
- __type_ = __format::__arg_t::__i128;
- }
-#endif
- else
- static_assert(sizeof(_Tp) == 0, "An unsupported signed integer was used");
- }
-
- template <__libcpp_unsigned_integer _Tp>
- _LIBCPP_HIDE_FROM_ABI explicit basic_format_arg(_Tp __v) noexcept {
- if constexpr (sizeof(_Tp) <= sizeof(unsigned)) {
- __unsigned = static_cast<unsigned>(__v);
- __type_ = __format::__arg_t::__unsigned;
- } else if constexpr (sizeof(_Tp) <= sizeof(unsigned long long)) {
- __unsigned_long_long = static_cast<unsigned long long>(__v);
- __type_ = __format::__arg_t::__unsigned_long_long;
- }
-#ifndef _LIBCPP_HAS_NO_INT128
- else if constexpr (sizeof(_Tp) == sizeof(__int128_t)) {
- __u128 = __v;
- __type_ = __format::__arg_t::__u128;
- }
-#endif
- else
- static_assert(sizeof(_Tp) == 0,
- "An unsupported unsigned integer was used");
- }
-
- _LIBCPP_HIDE_FROM_ABI explicit basic_format_arg(float __v) noexcept
- : __float(__v), __type_(__format::__arg_t::__float) {}
-
- _LIBCPP_HIDE_FROM_ABI explicit basic_format_arg(double __v) noexcept
- : __double(__v), __type_(__format::__arg_t::__double) {}
-
- _LIBCPP_HIDE_FROM_ABI explicit basic_format_arg(long double __v) noexcept
- : __long_double(__v), __type_(__format::__arg_t::__long_double) {}
-
- // Note not a 'noexcept' function.
- _LIBCPP_HIDE_FROM_ABI explicit basic_format_arg(const char_type* __s)
- : __const_char_type_ptr(__s),
- __type_(__format::__arg_t::__const_char_type_ptr) {
- _LIBCPP_ASSERT(__s, "Used a nullptr argument to initialize a C-string");
- }
-
- template <class _Traits>
- _LIBCPP_HIDE_FROM_ABI explicit basic_format_arg(
- basic_string_view<char_type, _Traits> __s) noexcept
- : __string_view{__s.data(), __s.size()},
- __type_(__format::__arg_t::__string_view) {}
-
- template <class _Traits, class _Allocator>
- _LIBCPP_HIDE_FROM_ABI explicit basic_format_arg(
- const basic_string<char_type, _Traits, _Allocator>& __s) noexcept
- : __string_view{__s.data(), __s.size()},
- __type_(__format::__arg_t::__string_view) {}
-
- _LIBCPP_HIDE_FROM_ABI
- explicit basic_format_arg(nullptr_t) noexcept
- : __ptr(nullptr), __type_(__format::__arg_t::__ptr) {}
-
- template <class _Tp>
- requires is_void_v<_Tp> _LIBCPP_HIDE_FROM_ABI explicit basic_format_arg(_Tp* __p) noexcept
- : __ptr(__p), __type_(__format::__arg_t::__ptr) {}
-
- template <class _Tp>
- _LIBCPP_HIDE_FROM_ABI explicit basic_format_arg(const _Tp& __v) noexcept
- : __handle(__v), __type_(__format::__arg_t::__handle) {}
+ _LIBCPP_HIDE_FROM_ABI explicit basic_format_arg(__format::__arg_t __type,
+ __basic_format_arg_value<_Context> __value) noexcept
+ : __value_(__value), __type_(__type) {}
};
template <class _Context>
class _LIBCPP_TEMPLATE_VIS basic_format_arg<_Context>::handle {
- friend class basic_format_arg<_Context>;
-
public:
_LIBCPP_HIDE_FROM_ABI
void format(basic_format_parse_context<char_type>& __parse_ctx, _Context& __ctx) const {
- __format_(__parse_ctx, __ctx, __ptr_);
+ __handle_.__format_(__parse_ctx, __ctx, __handle_.__ptr_);
}
+ _LIBCPP_HIDE_FROM_ABI explicit handle(typename __basic_format_arg_value<_Context>::__handle __handle) noexcept
+ : __handle_(__handle) {}
+
private:
- const void* __ptr_;
- void (*__format_)(basic_format_parse_context<char_type>&, _Context&, const void*);
-
- template <class _Tp>
- _LIBCPP_HIDE_FROM_ABI explicit handle(const _Tp& __v) noexcept
- : __ptr_(_VSTD::addressof(__v)),
- __format_([](basic_format_parse_context<char_type>& __parse_ctx, _Context& __ctx, const void* __ptr) {
- typename _Context::template formatter_type<_Tp> __f;
- __parse_ctx.advance_to(__f.parse(__parse_ctx));
- __ctx.advance_to(__f.format(*static_cast<const _Tp*>(__ptr), __ctx));
- }) {}
+ typename __basic_format_arg_value<_Context>::__handle __handle_;
};
-#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
-
#endif //_LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
-_LIBCPP_POP_MACROS
-
#endif // _LIBCPP___FORMAT_FORMAT_ARG_H
diff --git a/libcxx/include/__format/format_arg_store.h b/libcxx/include/__format/format_arg_store.h
new file mode 100644
index 000000000000..6602dfeb956b
--- /dev/null
+++ b/libcxx/include/__format/format_arg_store.h
@@ -0,0 +1,253 @@
+// -*- 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___FORMAT_FORMAT_ARG_STORE_H
+#define _LIBCPP___FORMAT_FORMAT_ARG_STORE_H
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#include <__concepts/arithmetic.h>
+#include <__concepts/same_as.h>
+#include <__config>
+#include <__format/concepts.h>
+#include <__format/format_arg.h>
+#include <cstring>
+#include <string>
+#include <string_view>
+#include <type_traits>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 17
+
+namespace __format {
+
+/// \returns The @c __arg_t based on the type of the formatting argument.
+///
+/// \pre \c __formattable<_Tp, typename _Context::char_type>
+template <class _Context, class _Tp>
+consteval __arg_t __determine_arg_t();
+
+// Boolean
+template <class, same_as<bool> _Tp>
+consteval __arg_t __determine_arg_t() {
+ return __arg_t::__boolean;
+}
+
+// Char
+template <class _Context, same_as<typename _Context::char_type> _Tp>
+consteval __arg_t __determine_arg_t() {
+ return __arg_t::__char_type;
+}
+# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+template <class _Context, class _CharT>
+ requires(same_as<typename _Context::char_type, wchar_t> && same_as<_CharT, char>)
+consteval __arg_t __determine_arg_t() {
+ return __arg_t::__char_type;
+}
+# endif
+
+// Signed integers
+template <class, __libcpp_signed_integer _Tp>
+consteval __arg_t __determine_arg_t() {
+ if constexpr (sizeof(_Tp) <= sizeof(int))
+ return __arg_t::__int;
+ else if constexpr (sizeof(_Tp) <= sizeof(long long))
+ return __arg_t::__long_long;
+# ifndef _LIBCPP_HAS_NO_INT128
+ else if constexpr (sizeof(_Tp) == sizeof(__int128_t))
+ return __arg_t::__i128;
+# endif
+ else
+ static_assert(sizeof(_Tp) == 0, "an unsupported signed integer was used");
+}
+
+// Unsigned integers
+template <class, __libcpp_unsigned_integer _Tp>
+consteval __arg_t __determine_arg_t() {
+ if constexpr (sizeof(_Tp) <= sizeof(unsigned))
+ return __arg_t::__unsigned;
+ else if constexpr (sizeof(_Tp) <= sizeof(unsigned long long))
+ return __arg_t::__unsigned_long_long;
+# ifndef _LIBCPP_HAS_NO_INT128
+ else if constexpr (sizeof(_Tp) == sizeof(__uint128_t))
+ return __arg_t::__u128;
+# endif
+ else
+ static_assert(sizeof(_Tp) == 0, "an unsupported unsigned integer was used");
+}
+
+// Floating-point
+template <class, same_as<float> _Tp>
+consteval __arg_t __determine_arg_t() {
+ return __arg_t::__float;
+}
+template <class, same_as<double> _Tp>
+consteval __arg_t __determine_arg_t() {
+ return __arg_t::__double;
+}
+template <class, same_as<long double> _Tp>
+consteval __arg_t __determine_arg_t() {
+ return __arg_t::__long_double;
+}
+
+// Char pointer
+template <class _Context, class _Tp>
+ requires(same_as<typename _Context::char_type*, _Tp> || same_as<const typename _Context::char_type*, _Tp>)
+consteval __arg_t __determine_arg_t() {
+ return __arg_t::__const_char_type_ptr;
+}
+
+// Char array
+template <class _Context, class _Tp>
+ requires(is_array_v<_Tp> && same_as<_Tp, typename _Context::char_type[extent_v<_Tp>]>)
+consteval __arg_t __determine_arg_t() {
+ return __arg_t::__string_view;
+}
+
+// String view
+template <class _Context, class _Tp>
+ requires(same_as<typename _Context::char_type, typename _Tp::value_type> &&
+ same_as<_Tp, basic_string_view<typename _Tp::value_type, typename _Tp::traits_type>>)
+consteval __arg_t __determine_arg_t() {
+ return __arg_t::__string_view;
+}
+
+// String
+template <class _Context, class _Tp>
+ requires(
+ same_as<typename _Context::char_type, typename _Tp::value_type> &&
+ same_as<_Tp, basic_string<typename _Tp::value_type, typename _Tp::traits_type, typename _Tp::allocator_type>>)
+consteval __arg_t __determine_arg_t() {
+ return __arg_t::__string_view;
+}
+
+// Pointers
+template <class, class _Ptr>
+ requires(same_as<_Ptr, void*> || same_as<_Ptr, const void*> || same_as<_Ptr, nullptr_t>)
+consteval __arg_t __determine_arg_t() {
+ return __arg_t::__ptr;
+}
+
+// Handle
+//
+// Note this version can't be constrained avoiding ambiguous overloads.
+// That means it can be instantiated by disabled formatters. To solve this, a
+// constrained version for not formattable formatters is added. That overload
+// is marked as deleted to fail creating a storage type for disabled formatters.
+template <class _Context, class _Tp>
+consteval __arg_t __determine_arg_t() {
+ return __arg_t::__handle;
+}
+
+template <class _Context, class _Tp>
+ requires(!__formattable<_Tp, typename _Context::char_type>)
+consteval __arg_t __determine_arg_t() = delete;
+
+template <class _Context, class _Tp>
+_LIBCPP_HIDE_FROM_ABI basic_format_arg<_Context> __create_format_arg(_Tp&& __value) noexcept {
+ constexpr __arg_t __arg = __determine_arg_t<_Context, remove_cvref_t<_Tp>>();
+ static_assert(__arg != __arg_t::__none);
+
+ // Not all types can be used to directly initialize the
+ // __basic_format_arg_value. First handle all types needing adjustment, the
+ // final else requires no adjustment.
+ if constexpr (__arg == __arg_t::__char_type)
+ // On some platforms initializing a wchar_t from a char is a narrowing
+ // conversion.
+ return basic_format_arg<_Context>{__arg, static_cast<typename _Context::char_type>(__value)};
+ else if constexpr (__arg == __arg_t::__int)
+ return basic_format_arg<_Context>{__arg, static_cast<int>(__value)};
+ else if constexpr (__arg == __arg_t::__long_long)
+ return basic_format_arg<_Context>{__arg, static_cast<long long>(__value)};
+ else if constexpr (__arg == __arg_t::__unsigned)
+ return basic_format_arg<_Context>{__arg, static_cast<unsigned>(__value)};
+ else if constexpr (__arg == __arg_t::__unsigned_long_long)
+ return basic_format_arg<_Context>{__arg, static_cast<unsigned long long>(__value)};
+ else if constexpr (__arg == __arg_t::__string_view)
+ // Using std::size on a character array will add the NUL-terminator to the size.
+ if constexpr (is_array_v<remove_cvref_t<_Tp>>)
+ return basic_format_arg<_Context>{
+ __arg, basic_string_view<typename _Context::char_type>{__value, extent_v<remove_cvref_t<_Tp>> - 1}};
+ else
+ // When the _Traits or _Allocator are different an implicit conversion will
+ // fail.
+ return basic_format_arg<_Context>{
+ __arg, basic_string_view<typename _Context::char_type>{__value.data(), __value.size()}};
+ else if constexpr (__arg == __arg_t::__ptr)
+ return basic_format_arg<_Context>{__arg, static_cast<const void*>(__value)};
+ else if constexpr (__arg == __arg_t::__handle)
+ return basic_format_arg<_Context>{
+ __arg, typename __basic_format_arg_value<_Context>::__handle{_VSTD::forward<_Tp>(__value)}};
+ else
+ return basic_format_arg<_Context>{__arg, __value};
+}
+
+template <class _Context, class... _Args>
+_LIBCPP_HIDE_FROM_ABI void __create_packed_storage(uint64_t& __types, __basic_format_arg_value<_Context>* __values,
+ _Args&&... __args) noexcept {
+ int __shift = 0;
+ (
+ [&] {
+ basic_format_arg<_Context> __arg = __create_format_arg<_Context>(_VSTD::forward<_Args>(__args));
+ if (__shift != 0)
+ __types |= static_cast<uint64_t>(__arg.__type_) << __shift;
+ else
+ // Assigns the initial value.
+ __types = static_cast<uint64_t>(__arg.__type_);
+ __shift += __packed_arg_t_bits;
+ *__values++ = __arg.__value_;
+ }(),
+ ...);
+}
+
+template <class _Context, class... _Args>
+_LIBCPP_HIDE_FROM_ABI void __store_basic_format_arg(basic_format_arg<_Context>* __data, _Args&&... __args) noexcept {
+ ([&] { *__data++ = __create_format_arg<_Context>(_VSTD::forward<_Args>(__args)); }(), ...);
+}
+
+template <class _Context, size_t N>
+struct __packed_format_arg_store {
+ __basic_format_arg_value<_Context> __values_[N];
+ uint64_t __types_;
+};
+
+template <class _Context, size_t N>
+struct __unpacked_format_arg_store {
+ basic_format_arg<_Context> __args_[N];
+};
+
+} // namespace __format
+
+template <class _Context, class... _Args>
+struct _LIBCPP_TEMPLATE_VIS __format_arg_store {
+ _LIBCPP_HIDE_FROM_ABI
+ __format_arg_store(_Args&&... __args) noexcept {
+ if constexpr (sizeof...(_Args) != 0) {
+ if constexpr (__format::__use_packed_format_arg_store(sizeof...(_Args)))
+ __format::__create_packed_storage(__storage.__types_, __storage.__values_, _VSTD::forward<_Args>(__args)...);
+ else
+ __format::__store_basic_format_arg<_Context>(__storage.__args_, _VSTD::forward<_Args>(__args)...);
+ }
+ }
+
+ using _Storage = conditional_t<__format::__use_packed_format_arg_store(sizeof...(_Args)),
+ __format::__packed_format_arg_store<_Context, sizeof...(_Args)>,
+ __format::__unpacked_format_arg_store<_Context, sizeof...(_Args)>>;
+
+ _Storage __storage;
+};
+
+#endif //_LIBCPP_STD_VER > 17
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___FORMAT_FORMAT_ARG_STORE_H
diff --git a/libcxx/include/__format/format_args.h b/libcxx/include/__format/format_args.h
index 0a26b95d1b47..d90dc50acbd1 100644
--- a/libcxx/include/__format/format_args.h
+++ b/libcxx/include/__format/format_args.h
@@ -12,60 +12,68 @@
#include <__availability>
#include <__config>
+#include <__format/format_arg.h>
+#include <__format/format_arg_store.h>
#include <__format/format_fwd.h>
#include <cstddef>
+#include <cstdint>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
-_LIBCPP_PUSH_MACROS
-#include <__undef_macros>
-
_LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER > 17
-// TODO FMT Remove this once we require compilers with proper C++20 support.
-// If the compiler has no concepts support, the format header will be disabled.
-// Without concepts support enable_if needs to be used and that too much effort
-// to support compilers with partial C++20 support.
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
-
template <class _Context>
class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT basic_format_args {
public:
- // TODO FMT Implement [format.args]/5
- // [Note 1: Implementations are encouraged to optimize the representation of
- // basic_format_args for small number of formatting arguments by storing
- // indices of type alternatives separately from values and packing the
- // former. - end note]
- // Note: Change __format_arg_store to use a built-in array.
_LIBCPP_HIDE_FROM_ABI basic_format_args() noexcept = default;
template <class... _Args>
- _LIBCPP_HIDE_FROM_ABI basic_format_args(
- const __format_arg_store<_Context, _Args...>& __store) noexcept
- : __size_(sizeof...(_Args)), __data_(__store.__args.data()) {}
+ _LIBCPP_HIDE_FROM_ABI basic_format_args(const __format_arg_store<_Context, _Args...>& __store) noexcept
+ : __size_(sizeof...(_Args)) {
+ if constexpr (sizeof...(_Args) != 0) {
+ if constexpr (__format::__use_packed_format_arg_store(sizeof...(_Args))) {
+ __values_ = __store.__storage.__values_;
+ __types_ = __store.__storage.__types_;
+ } else
+ __args_ = __store.__storage.__args_;
+ }
+ }
_LIBCPP_HIDE_FROM_ABI
basic_format_arg<_Context> get(size_t __id) const noexcept {
- return __id < __size_ ? __data_[__id] : basic_format_arg<_Context>{};
+ if (__id >= __size_)
+ return basic_format_arg<_Context>{};
+
+ if (__format::__use_packed_format_arg_store(__size_))
+ return basic_format_arg<_Context>{__format::__get_packed_type(__types_, __id), __values_[__id]};
+
+ return __args_[__id];
}
_LIBCPP_HIDE_FROM_ABI size_t __size() const noexcept { return __size_; }
private:
size_t __size_{0};
- const basic_format_arg<_Context>* __data_{nullptr};
+ // [format.args]/5
+ // [Note 1: Implementations are encouraged to optimize the representation of
+ // basic_format_args for small number of formatting arguments by storing
+ // indices of type alternatives separately from values and packing the
+ // former. - end note]
+ union {
+ struct {
+ const __basic_format_arg_value<_Context>* __values_;
+ uint64_t __types_;
+ };
+ const basic_format_arg<_Context>* __args_;
+ };
};
-#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
-
#endif //_LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
-_LIBCPP_POP_MACROS
-
#endif // _LIBCPP___FORMAT_FORMAT_ARGS_H
diff --git a/libcxx/include/__format/format_context.h b/libcxx/include/__format/format_context.h
index 570bf7e90d9f..b9a41db05d51 100644
--- a/libcxx/include/__format/format_context.h
+++ b/libcxx/include/__format/format_context.h
@@ -12,11 +12,14 @@
#include <__availability>
#include <__config>
+#include <__format/buffer.h>
#include <__format/format_args.h>
#include <__format/format_fwd.h>
#include <__iterator/back_insert_iterator.h>
#include <__iterator/concepts.h>
+#include <__utility/move.h>
#include <concepts>
+#include <cstddef>
#ifndef _LIBCPP_HAS_NO_LOCALIZATION
#include <locale>
@@ -24,22 +27,13 @@
#endif
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
-_LIBCPP_PUSH_MACROS
-#include <__undef_macros>
-
_LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER > 17
-// TODO FMT Remove this once we require compilers with proper C++20 support.
-// If the compiler has no concepts support, the format header will be disabled.
-// Without concepts support enable_if needs to be used and that too much effort
-// to support compilers with partial C++20 support.
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
-
template <class _OutIt, class _CharT>
requires output_iterator<_OutIt, const _CharT&>
class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT basic_format_context;
@@ -69,16 +63,12 @@ __format_context_create(
}
#endif
-// TODO FMT Implement [format.context]/4
-// [Note 1: For a given type charT, implementations are encouraged to provide a
-// single instantiation of basic_format_context for appending to
-// basic_string<charT>, vector<charT>, or any other container with contiguous
-// storage by wrapping those in temporary objects with a uniform interface
-// (such as a span<charT>) and polymorphic reallocation. - end note]
-
-using format_context = basic_format_context<back_insert_iterator<string>, char>;
+using format_context =
+ basic_format_context<back_insert_iterator<__format::__output_buffer<char>>,
+ char>;
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-using wformat_context = basic_format_context<back_insert_iterator<wstring>, wchar_t>;
+using wformat_context = basic_format_context<
+ back_insert_iterator<__format::__output_buffer<wchar_t>>, wchar_t>;
#endif
template <class _OutIt, class _CharT>
@@ -101,7 +91,7 @@ public:
basic_format_context& operator=(const basic_format_context&) = delete;
_LIBCPP_HIDE_FROM_ABI basic_format_arg<basic_format_context>
- arg(size_t __id) const {
+ arg(size_t __id) const noexcept {
return __args_.get(__id);
}
#ifndef _LIBCPP_HAS_NO_LOCALIZATION
@@ -154,12 +144,8 @@ private:
#endif
};
-#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
-
#endif //_LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
-_LIBCPP_POP_MACROS
-
#endif // _LIBCPP___FORMAT_FORMAT_CONTEXT_H
diff --git a/libcxx/include/__format/format_error.h b/libcxx/include/__format/format_error.h
index ac1d708030d6..67ff41cbc3d8 100644
--- a/libcxx/include/__format/format_error.h
+++ b/libcxx/include/__format/format_error.h
@@ -18,7 +18,7 @@
#endif
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__format/format_fwd.h b/libcxx/include/__format/format_fwd.h
index 7da30aec5188..f7c72e21211a 100644
--- a/libcxx/include/__format/format_fwd.h
+++ b/libcxx/include/__format/format_fwd.h
@@ -13,44 +13,27 @@
#include <__availability>
#include <__config>
#include <__iterator/concepts.h>
-#include <__utility/forward.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
-_LIBCPP_PUSH_MACROS
-#include <__undef_macros>
-
_LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER > 17
-// TODO FMT Remove this once we require compilers with proper C++20 support.
-// If the compiler has no concepts support, the format header will be disabled.
-// Without concepts support enable_if needs to be used and that too much effort
-// to support compilers with partial C++20 support.
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
-
template <class _Context>
class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT basic_format_arg;
-template <class _Context, class... _Args>
-struct _LIBCPP_TEMPLATE_VIS __format_arg_store;
-
-template <class _Ctx, class... _Args>
-_LIBCPP_HIDE_FROM_ABI __format_arg_store<_Ctx, _Args...>
-make_format_args(const _Args&...);
+template <class _OutIt, class _CharT>
+ requires output_iterator<_OutIt, const _CharT&>
+class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT basic_format_context;
template <class _Tp, class _CharT = char>
struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter;
-#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
-
#endif //_LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
-_LIBCPP_POP_MACROS
-
#endif // _LIBCPP___FORMAT_FORMAT_FWD_H
diff --git a/libcxx/include/__format/format_parse_context.h b/libcxx/include/__format/format_parse_context.h
index 289cab9f0ee4..272b615d1048 100644
--- a/libcxx/include/__format/format_parse_context.h
+++ b/libcxx/include/__format/format_parse_context.h
@@ -15,19 +15,13 @@
#include <string_view>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER > 17
-// TODO FMT Remove this once we require compilers with proper C++20 support.
-// If the compiler has no concepts support, the format header will be disabled.
-// Without concepts support enable_if needs to be used and that too much effort
-// to support compilers with partial C++20 support.
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
-
template <class _CharT>
class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT basic_format_parse_context {
public:
@@ -100,8 +94,6 @@ using format_parse_context = basic_format_parse_context<char>;
using wformat_parse_context = basic_format_parse_context<wchar_t>;
#endif
-#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
-
#endif //_LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__format/format_string.h b/libcxx/include/__format/format_string.h
index 885e572fc068..51c3c7a1a6d8 100644
--- a/libcxx/include/__format/format_string.h
+++ b/libcxx/include/__format/format_string.h
@@ -10,26 +10,20 @@
#ifndef _LIBCPP___FORMAT_FORMAT_STRING_H
#define _LIBCPP___FORMAT_FORMAT_STRING_H
+#include <__assert>
#include <__config>
-#include <__debug>
#include <__format/format_error.h>
#include <cstddef>
#include <cstdint>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER > 17
-// TODO FMT Remove this once we require compilers with proper C++20 support.
-// If the compiler has no concepts support, the format header will be disabled.
-// Without concepts support enable_if needs to be used and that too much effort
-// to support compilers with partial C++20 support.
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
-
namespace __format {
template <class _CharT>
@@ -160,8 +154,6 @@ __parse_arg_id(const _CharT* __begin, const _CharT* __end, auto& __parse_ctx) {
} // namespace __format
-#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
-
#endif //_LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__format/format_to_n_result.h b/libcxx/include/__format/format_to_n_result.h
index b973dc5c1dfe..25caa1c9e98d 100644
--- a/libcxx/include/__format/format_to_n_result.h
+++ b/libcxx/include/__format/format_to_n_result.h
@@ -21,19 +21,12 @@ _LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER > 17
-// TODO FMT Remove this once we require compilers with proper C++20 support.
-// If the compiler has no concepts support, the format header will be disabled.
-// Without concepts support enable_if needs to be used and that too much effort
-// to support compilers with partial C++20 support.
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
-
template <class _OutIt>
struct _LIBCPP_TEMPLATE_VIS format_to_n_result {
_OutIt out;
iter_difference_t<_OutIt> size;
};
-#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
#endif //_LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__format/formatter.h b/libcxx/include/__format/formatter.h
index 38b73bba32f3..c39e25b354eb 100644
--- a/libcxx/include/__format/formatter.h
+++ b/libcxx/include/__format/formatter.h
@@ -12,32 +12,27 @@
#include <__algorithm/copy.h>
#include <__algorithm/fill_n.h>
+#include <__algorithm/transform.h>
+#include <__assert>
#include <__availability>
+#include <__concepts/same_as.h>
#include <__config>
#include <__format/format_error.h>
#include <__format/format_fwd.h>
#include <__format/format_string.h>
#include <__format/parser_std_format_spec.h>
-#include <concepts>
+#include <__utility/move.h>
+#include <__utility/unreachable.h>
#include <string_view>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
-_LIBCPP_PUSH_MACROS
-#include <__undef_macros>
-
_LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER > 17
-// TODO FMT Remove this once we require compilers with proper C++20 support.
-// If the compiler has no concepts support, the format header will be disabled.
-// Without concepts support enable_if needs to be used and that too much effort
-// to support compilers with partial C++20 support.
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
-
/// The default formatter template.
///
/// [format.formatter.spec]/5
@@ -120,7 +115,7 @@ __padding_size(size_t __size, size_t __width,
size_t __fill = __width - __size;
switch (__align) {
case __format_spec::_Flags::_Alignment::__default:
- _LIBCPP_UNREACHABLE();
+ __libcpp_unreachable();
case __format_spec::_Flags::_Alignment::__left:
return {0, __fill};
@@ -136,7 +131,7 @@ __padding_size(size_t __size, size_t __width,
case __format_spec::_Flags::_Alignment::__right:
return {__fill, 0};
}
- _LIBCPP_UNREACHABLE();
+ __libcpp_unreachable();
}
/**
@@ -279,12 +274,8 @@ __write_unicode(output_iterator<const _CharT&> auto __out_it,
} // namespace __formatter
-#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
-
#endif //_LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
-_LIBCPP_POP_MACROS
-
#endif // _LIBCPP___FORMAT_FORMATTER_H
diff --git a/libcxx/include/__format/formatter_bool.h b/libcxx/include/__format/formatter_bool.h
index 1e40bc0a435a..4c9d3fc77473 100644
--- a/libcxx/include/__format/formatter_bool.h
+++ b/libcxx/include/__format/formatter_bool.h
@@ -10,136 +10,66 @@
#ifndef _LIBCPP___FORMAT_FORMATTER_BOOL_H
#define _LIBCPP___FORMAT_FORMATTER_BOOL_H
+#include <__algorithm/copy.h>
#include <__availability>
#include <__config>
+#include <__debug>
#include <__format/format_error.h>
#include <__format/format_fwd.h>
+#include <__format/format_parse_context.h>
#include <__format/formatter.h>
#include <__format/formatter_integral.h>
#include <__format/parser_std_format_spec.h>
+#include <__utility/unreachable.h>
#include <string_view>
#ifndef _LIBCPP_HAS_NO_LOCALIZATION
-#include <locale>
+# include <locale>
#endif
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER > 17
-// TODO FMT Remove this once we require compilers with proper C++20 support.
-// If the compiler has no concepts support, the format header will be disabled.
-// Without concepts support enable_if needs to be used and that too much effort
-// to support compilers with partial C++20 support.
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
-
-namespace __format_spec {
-
-template <class _CharT>
-class _LIBCPP_TEMPLATE_VIS __parser_bool : public __parser_integral<_CharT> {
+template <__formatter::__char_type _CharT>
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<bool, _CharT> {
public:
- _LIBCPP_HIDE_FROM_ABI constexpr auto parse(auto& __parse_ctx)
- -> decltype(__parse_ctx.begin()) {
- auto __it = __parser_integral<_CharT>::__parse(__parse_ctx);
-
- switch (this->__type) {
- case _Flags::_Type::__default:
- this->__type = _Flags::_Type::__string;
- [[fallthrough]];
- case _Flags::_Type::__string:
- this->__handle_bool();
- break;
-
- case _Flags::_Type::__char:
- this->__handle_char();
- break;
+ _LIBCPP_HIDE_FROM_ABI constexpr auto
+ parse(basic_format_parse_context<_CharT>& __parse_ctx) -> decltype(__parse_ctx.begin()) {
+ auto __result = __parser_.__parse(__parse_ctx, __format_spec::__fields_integral);
+ __format_spec::__process_parsed_bool(__parser_);
+ return __result;
+ }
- case _Flags::_Type::__binary_lower_case:
- case _Flags::_Type::__binary_upper_case:
- case _Flags::_Type::__octal:
- case _Flags::_Type::__decimal:
- case _Flags::_Type::__hexadecimal_lower_case:
- case _Flags::_Type::__hexadecimal_upper_case:
- this->__handle_integer();
- break;
+ _LIBCPP_HIDE_FROM_ABI auto format(bool __value, auto& __ctx) const -> decltype(__ctx.out()) {
+ switch (__parser_.__type_) {
+ case __format_spec::__type::__string:
+ return __formatter::__format_bool(__value, __ctx, __parser_.__get_parsed_std_specifications(__ctx));
+
+ case __format_spec::__type::__binary_lower_case:
+ case __format_spec::__type::__binary_upper_case:
+ case __format_spec::__type::__octal:
+ case __format_spec::__type::__decimal:
+ case __format_spec::__type::__hexadecimal_lower_case:
+ case __format_spec::__type::__hexadecimal_upper_case:
+ // Promotes bool to an integral type. This reduces the number of
+ // instantiations of __format_integer reducing code size.
+ return __formatter::__format_integer(
+ static_cast<unsigned>(__value), __ctx, __parser_.__get_parsed_std_specifications(__ctx));
default:
- __throw_format_error(
- "The format-spec type has a type not supported for a bool argument");
+ _LIBCPP_ASSERT(false, "The parse function should have validated the type");
+ __libcpp_unreachable();
}
-
- return __it;
}
-};
-
-template <class _CharT>
-struct _LIBCPP_TEMPLATE_VIS __bool_strings;
-
-template <>
-struct _LIBCPP_TEMPLATE_VIS __bool_strings<char> {
- static constexpr string_view __true{"true"};
- static constexpr string_view __false{"false"};
-};
-
-#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-template <>
-struct _LIBCPP_TEMPLATE_VIS __bool_strings<wchar_t> {
- static constexpr wstring_view __true{L"true"};
- static constexpr wstring_view __false{L"false"};
-};
-#endif
-template <class _CharT>
-using __formatter_bool = __formatter_integral<__parser_bool<_CharT>>;
-
-} //namespace __format_spec
-
-// [format.formatter.spec]/2.3
-// For each charT, for each cv-unqualified arithmetic type ArithmeticT other
-// than char, wchar_t, char8_t, char16_t, or char32_t, a specialization
-
-template <__formatter::__char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<bool, _CharT>
- : public __format_spec::__formatter_bool<_CharT> {
- using _Base = __format_spec::__formatter_bool<_CharT>;
-
- _LIBCPP_HIDE_FROM_ABI auto format(bool __value, auto& __ctx)
- -> decltype(__ctx.out()) {
- if (this->__type != __format_spec::_Flags::_Type::__string)
- return _Base::format(static_cast<unsigned char>(__value), __ctx);
-
- if (this->__width_needs_substitution())
- this->__substitute_width_arg_id(__ctx.arg(this->__width));
-
-#ifndef _LIBCPP_HAS_NO_LOCALIZATION
- if (this->__locale_specific_form) {
- const auto& __np = use_facet<numpunct<_CharT>>(__ctx.locale());
- basic_string<_CharT> __str = __value ? __np.truename() : __np.falsename();
- return __formatter::__write_unicode(
- __ctx.out(), basic_string_view<_CharT>{__str}, this->__width, -1,
- this->__fill, this->__alignment);
- }
-#endif
- basic_string_view<_CharT> __str =
- __value ? __format_spec::__bool_strings<_CharT>::__true
- : __format_spec::__bool_strings<_CharT>::__false;
-
- // The output only uses ASCII so every character is one column.
- unsigned __size = __str.size();
- if (__size >= this->__width)
- return _VSTD::copy(__str.begin(), __str.end(), __ctx.out());
-
- return __formatter::__write(__ctx.out(), __str.begin(), __str.end(), __size,
- this->__width, this->__fill, this->__alignment);
- }
+ __format_spec::__parser<_CharT> __parser_;
};
-#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
-
#endif //_LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__format/formatter_char.h b/libcxx/include/__format/formatter_char.h
index 2131de0778f2..cd54abba348a 100644
--- a/libcxx/include/__format/formatter_char.h
+++ b/libcxx/include/__format/formatter_char.h
@@ -11,91 +11,71 @@
#define _LIBCPP___FORMAT_FORMATTER_CHAR_H
#include <__availability>
+#include <__concepts/same_as.h>
#include <__config>
-#include <__format/format_error.h>
#include <__format/format_fwd.h>
+#include <__format/format_parse_context.h>
#include <__format/formatter.h>
#include <__format/formatter_integral.h>
+#include <__format/formatter_output.h>
#include <__format/parser_std_format_spec.h>
+#include <__type_traits/conditional.h>
+#include <__type_traits/is_signed.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER > 17
-// TODO FMT Remove this once we require compilers with proper C++20 support.
-// If the compiler has no concepts support, the format header will be disabled.
-// Without concepts support enable_if needs to be used and that too much effort
-// to support compilers with partial C++20 support.
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
-
-namespace __format_spec {
-
-template <class _CharT>
-class _LIBCPP_TEMPLATE_VIS __parser_char : public __parser_integral<_CharT> {
+template <__formatter::__char_type _CharT>
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __formatter_char {
public:
- _LIBCPP_HIDE_FROM_ABI constexpr auto parse(auto& __parse_ctx)
- -> decltype(__parse_ctx.begin()) {
- auto __it = __parser_integral<_CharT>::__parse(__parse_ctx);
-
- switch (this->__type) {
- case _Flags::_Type::__default:
- this->__type = _Flags::_Type::__char;
- [[fallthrough]];
- case _Flags::_Type::__char:
- this->__handle_char();
- break;
-
- case _Flags::_Type::__binary_lower_case:
- case _Flags::_Type::__binary_upper_case:
- case _Flags::_Type::__octal:
- case _Flags::_Type::__decimal:
- case _Flags::_Type::__hexadecimal_lower_case:
- case _Flags::_Type::__hexadecimal_upper_case:
- this->__handle_integer();
- break;
-
- default:
- __throw_format_error(
- "The format-spec type has a type not supported for a char argument");
- }
-
- return __it;
+ _LIBCPP_HIDE_FROM_ABI constexpr auto
+ parse(basic_format_parse_context<_CharT>& __parse_ctx) -> decltype(__parse_ctx.begin()) {
+ auto __result = __parser_.__parse(__parse_ctx, __format_spec::__fields_integral);
+ __format_spec::__process_parsed_char(__parser_);
+ return __result;
}
-};
-template <class _CharT>
-using __formatter_char = __formatter_integral<__parser_char<_CharT>>;
+ _LIBCPP_HIDE_FROM_ABI auto format(_CharT __value, auto& __ctx) const -> decltype(__ctx.out()) {
+ if (__parser_.__type_ == __format_spec::__type::__char)
+ return __formatter::__format_char(__value, __ctx.out(), __parser_.__get_parsed_std_specifications(__ctx));
+
+ if constexpr (sizeof(_CharT) <= sizeof(int))
+ // Promotes _CharT to an integral type. This reduces the number of
+ // instantiations of __format_integer reducing code size.
+ return __formatter::__format_integer(
+ static_cast<conditional_t<is_signed_v<_CharT>, int, unsigned>>(__value),
+ __ctx,
+ __parser_.__get_parsed_std_specifications(__ctx));
+ else
+ return __formatter::__format_integer(__value, __ctx, __parser_.__get_parsed_std_specifications(__ctx));
+ }
-} // namespace __format_spec
+ _LIBCPP_HIDE_FROM_ABI auto format(char __value, auto& __ctx) const -> decltype(__ctx.out())
+ requires(same_as<_CharT, wchar_t>)
+ {
+ return format(static_cast<wchar_t>(__value), __ctx);
+ }
-// [format.formatter.spec]/2.1 The specializations
+ __format_spec::__parser<_CharT> __parser_;
+};
template <>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<char, char>
- : public __format_spec::__formatter_char<char> {};
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<char, char> : public __formatter_char<char> {};
-#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
template <>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<char, wchar_t>
- : public __format_spec::__formatter_char<wchar_t> {
- using _Base = __format_spec::__formatter_char<wchar_t>;
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<char, wchar_t> : public __formatter_char<wchar_t> {};
- _LIBCPP_HIDE_FROM_ABI auto format(char __value, auto& __ctx)
- -> decltype(__ctx.out()) {
- return _Base::format(static_cast<wchar_t>(__value), __ctx);
- }
+template <>
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<wchar_t, wchar_t> : public __formatter_char<wchar_t> {
};
-template <>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT
- formatter<wchar_t, wchar_t>
- : public __format_spec::__formatter_char<wchar_t> {};
-#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
-#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
+# endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
#endif //_LIBCPP_STD_VER > 17
diff --git a/libcxx/include/__format/formatter_floating_point.h b/libcxx/include/__format/formatter_floating_point.h
index 2e710b409deb..c9f5689abd8b 100644
--- a/libcxx/include/__format/formatter_floating_point.h
+++ b/libcxx/include/__format/formatter_floating_point.h
@@ -17,16 +17,19 @@
#include <__algorithm/min.h>
#include <__algorithm/rotate.h>
#include <__algorithm/transform.h>
+#include <__assert>
#include <__concepts/arithmetic.h>
+#include <__concepts/same_as.h>
#include <__config>
-#include <__debug>
#include <__format/format_error.h>
#include <__format/format_fwd.h>
#include <__format/format_string.h>
#include <__format/formatter.h>
#include <__format/formatter_integral.h>
#include <__format/parser_std_format_spec.h>
+#include <__memory/allocator.h>
#include <__utility/move.h>
+#include <__utility/unreachable.h>
#include <charconv>
#include <cmath>
@@ -45,12 +48,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER > 17
-// TODO FMT Remove this once we require compilers with proper C++20 support.
-// If the compiler has no concepts support, the format header will be disabled.
-// Without concepts support enable_if needs to be used and that too much effort
-// to support compilers with partial C++20 support.
-# if !defined(_LIBCPP_HAS_NO_CONCEPTS)
-
namespace __format_spec {
template <floating_point _Tp>
@@ -450,7 +447,7 @@ _LIBCPP_HIDE_FROM_ABI _OutIt __format_locale_specific_form(_OutIt __out_it, cons
if (__digits <= __grouping[0])
__grouping.clear();
else
- __grouping = __determine_grouping(__digits, __grouping);
+ __grouping = __formatter::__determine_grouping(__digits, __grouping);
}
size_t __size = __result.__last - __buffer.begin() + // Formatted string
@@ -689,7 +686,7 @@ private:
default:
_LIBCPP_ASSERT(false, "The parser should have validated the type");
- _LIBCPP_UNREACHABLE();
+ __libcpp_unreachable();
}
}
};
@@ -706,8 +703,6 @@ template <__formatter::__char_type _CharT>
struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<long double, _CharT>
: public __format_spec::__formatter_floating_point<_CharT> {};
-# endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
-
#endif //_LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__format/formatter_integer.h b/libcxx/include/__format/formatter_integer.h
index e1f3d4e34897..5d11f8d1d990 100644
--- a/libcxx/include/__format/formatter_integer.h
+++ b/libcxx/include/__format/formatter_integer.h
@@ -11,155 +11,120 @@
#define _LIBCPP___FORMAT_FORMATTER_INTEGER_H
#include <__availability>
+#include <__concepts/arithmetic.h>
#include <__config>
-#include <__format/format_error.h>
+#include <__format/format_error.h> // TODO FMT Remove after adding 128-bit support
#include <__format/format_fwd.h>
+#include <__format/format_parse_context.h>
#include <__format/formatter.h>
#include <__format/formatter_integral.h>
+#include <__format/formatter_output.h>
#include <__format/parser_std_format_spec.h>
-#include <limits>
+#include <limits> // TODO FMT Remove after adding 128-bit support
+#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
-_LIBCPP_PUSH_MACROS
+_LIBCPP_PUSH_MACROS // TODO FMT Remove after adding 128-bit support
#include <__undef_macros>
-_LIBCPP_BEGIN_NAMESPACE_STD
+ _LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER > 17
-// TODO FMT Remove this once we require compilers with proper C++20 support.
-// If the compiler has no concepts support, the format header will be disabled.
-// Without concepts support enable_if needs to be used and that too much effort
-// to support compilers with partial C++20 support.
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
+ template <__formatter::__char_type _CharT>
+ struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __formatter_integer {
-namespace __format_spec {
-
-template <class _CharT>
-class _LIBCPP_TEMPLATE_VIS __parser_integer : public __parser_integral<_CharT> {
public:
- _LIBCPP_HIDE_FROM_ABI constexpr auto parse(auto& __parse_ctx)
- -> decltype(__parse_ctx.begin()) {
- auto __it = __parser_integral<_CharT>::__parse(__parse_ctx);
-
- switch (this->__type) {
- case _Flags::_Type::__default:
- this->__type = _Flags::_Type::__decimal;
- [[fallthrough]];
-
- case _Flags::_Type::__binary_lower_case:
- case _Flags::_Type::__binary_upper_case:
- case _Flags::_Type::__octal:
- case _Flags::_Type::__decimal:
- case _Flags::_Type::__hexadecimal_lower_case:
- case _Flags::_Type::__hexadecimal_upper_case:
- this->__handle_integer();
- break;
-
- case _Flags::_Type::__char:
- this->__handle_char();
- break;
-
- default:
- __throw_format_error("The format-spec type has a type not supported for "
- "an integer argument");
- }
- return __it;
+ _LIBCPP_HIDE_FROM_ABI constexpr auto
+ parse(basic_format_parse_context<_CharT>& __parse_ctx) -> decltype(__parse_ctx.begin()) {
+ auto __result = __parser_.__parse(__parse_ctx, __format_spec::__fields_integral);
+ __format_spec::__process_parsed_integer(__parser_);
+ return __result;
}
-};
-template <class _CharT>
-using __formatter_integer = __formatter_integral<__parser_integer<_CharT>>;
+ template <integral _Tp>
+ _LIBCPP_HIDE_FROM_ABI auto format(_Tp __value, auto& __ctx) const -> decltype(__ctx.out()) {
+ __format_spec::__parsed_specifications<_CharT> __specs = __parser_.__get_parsed_std_specifications(__ctx);
+
+ if (__specs.__std_.__type_ == __format_spec::__type::__char)
+ return __formatter::__format_char(__value, __ctx.out(), __specs);
-} // namespace __format_spec
+ using _Type = __make_32_64_or_128_bit_t<_Tp>;
+ static_assert(!is_same<_Type, void>::value, "unsupported integral type used in __formatter_integer::__format");
+
+ // Reduce the number of instantiation of the integer formatter
+ return __formatter::__format_integer(static_cast<_Type>(__value), __ctx, __specs);
+ }
-// [format.formatter.spec]/2.3
-// For each charT, for each cv-unqualified arithmetic type ArithmeticT other
-// than char, wchar_t, char8_t, char16_t, or char32_t, a specialization
+ __format_spec::__parser<_CharT> __parser_;
+};
// Signed integral types.
template <__formatter::__char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT
- formatter<signed char, _CharT>
- : public __format_spec::__formatter_integer<_CharT> {};
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<signed char, _CharT>
+ : public __formatter_integer<_CharT> {};
template <__formatter::__char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<short, _CharT>
- : public __format_spec::__formatter_integer<_CharT> {};
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<short, _CharT> : public __formatter_integer<_CharT> {
+};
template <__formatter::__char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<int, _CharT>
- : public __format_spec::__formatter_integer<_CharT> {};
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<int, _CharT> : public __formatter_integer<_CharT> {};
template <__formatter::__char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<long, _CharT>
- : public __format_spec::__formatter_integer<_CharT> {};
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<long, _CharT> : public __formatter_integer<_CharT> {};
template <__formatter::__char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT
- formatter<long long, _CharT>
- : public __format_spec::__formatter_integer<_CharT> {};
-#ifndef _LIBCPP_HAS_NO_INT128
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<long long, _CharT>
+ : public __formatter_integer<_CharT> {};
+# ifndef _LIBCPP_HAS_NO_INT128
template <__formatter::__char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT
- formatter<__int128_t, _CharT>
- : public __format_spec::__formatter_integer<_CharT> {
- using _Base = __format_spec::__formatter_integer<_CharT>;
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<__int128_t, _CharT>
+ : public __formatter_integer<_CharT> {
+ using _Base = __formatter_integer<_CharT>;
- _LIBCPP_HIDE_FROM_ABI auto format(__int128_t __value, auto& __ctx)
- -> decltype(__ctx.out()) {
+ _LIBCPP_HIDE_FROM_ABI auto format(__int128_t __value, auto& __ctx) const -> decltype(__ctx.out()) {
// TODO FMT Implement full 128 bit support.
using _To = long long;
- if (__value < numeric_limits<_To>::min() ||
- __value > numeric_limits<_To>::max())
- __throw_format_error("128-bit value is outside of implemented range");
+ if (__value < numeric_limits<_To>::min() || __value > numeric_limits<_To>::max())
+ std::__throw_format_error("128-bit value is outside of implemented range");
return _Base::format(static_cast<_To>(__value), __ctx);
}
};
-#endif
+# endif
// Unsigned integral types.
template <__formatter::__char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT
- formatter<unsigned char, _CharT>
- : public __format_spec::__formatter_integer<_CharT> {};
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<unsigned char, _CharT>
+ : public __formatter_integer<_CharT> {};
template <__formatter::__char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT
- formatter<unsigned short, _CharT>
- : public __format_spec::__formatter_integer<_CharT> {};
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<unsigned short, _CharT>
+ : public __formatter_integer<_CharT> {};
template <__formatter::__char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT
- formatter<unsigned, _CharT>
- : public __format_spec::__formatter_integer<_CharT> {};
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<unsigned, _CharT>
+ : public __formatter_integer<_CharT> {};
template <__formatter::__char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT
- formatter<unsigned long, _CharT>
- : public __format_spec::__formatter_integer<_CharT> {};
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<unsigned long, _CharT>
+ : public __formatter_integer<_CharT> {};
template <__formatter::__char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT
- formatter<unsigned long long, _CharT>
- : public __format_spec::__formatter_integer<_CharT> {};
-#ifndef _LIBCPP_HAS_NO_INT128
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<unsigned long long, _CharT>
+ : public __formatter_integer<_CharT> {};
+# ifndef _LIBCPP_HAS_NO_INT128
template <__formatter::__char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT
- formatter<__uint128_t, _CharT>
- : public __format_spec::__formatter_integer<_CharT> {
- using _Base = __format_spec::__formatter_integer<_CharT>;
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<__uint128_t, _CharT>
+ : public __formatter_integer<_CharT> {
+ using _Base = __formatter_integer<_CharT>;
- _LIBCPP_HIDE_FROM_ABI auto format(__uint128_t __value, auto& __ctx)
- -> decltype(__ctx.out()) {
+ _LIBCPP_HIDE_FROM_ABI auto format(__uint128_t __value, auto& __ctx) const -> decltype(__ctx.out()) {
// TODO FMT Implement full 128 bit support.
using _To = unsigned long long;
- if (__value < numeric_limits<_To>::min() ||
- __value > numeric_limits<_To>::max())
- __throw_format_error("128-bit value is outside of implemented range");
+ if (__value < numeric_limits<_To>::min() || __value > numeric_limits<_To>::max())
+ std::__throw_format_error("128-bit value is outside of implemented range");
return _Base::format(static_cast<_To>(__value), __ctx);
}
};
-#endif
-
-#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
+# endif
#endif //_LIBCPP_STD_VER > 17
diff --git a/libcxx/include/__format/formatter_integral.h b/libcxx/include/__format/formatter_integral.h
index f164ee610974..4ad6de0ec66f 100644
--- a/libcxx/include/__format/formatter_integral.h
+++ b/libcxx/include/__format/formatter_integral.h
@@ -10,27 +10,24 @@
#ifndef _LIBCPP___FORMAT_FORMATTER_INTEGRAL_H
#define _LIBCPP___FORMAT_FORMATTER_INTEGRAL_H
-#include <__algorithm/copy.h>
-#include <__algorithm/copy_n.h>
-#include <__algorithm/fill_n.h>
-#include <__algorithm/transform.h>
+#include <__concepts/arithmetic.h>
+#include <__concepts/same_as.h>
#include <__config>
#include <__format/format_error.h>
-#include <__format/format_fwd.h>
-#include <__format/formatter.h>
+#include <__format/formatter.h> // for __char_type TODO FMT Move the concept?
+#include <__format/formatter_output.h>
#include <__format/parser_std_format_spec.h>
-#include <array>
+#include <__utility/unreachable.h>
#include <charconv>
-#include <concepts>
#include <limits>
#include <string>
#ifndef _LIBCPP_HAS_NO_LOCALIZATION
-#include <locale>
+# include <locale>
#endif
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
@@ -40,97 +37,30 @@ _LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER > 17
-// TODO FMT Remove this once we require compilers with proper C++20 support.
-// If the compiler has no concepts support, the format header will be disabled.
-// Without concepts support enable_if needs to be used and that too much effort
-// to support compilers with partial C++20 support.
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
+namespace __formatter {
-/**
- * Integral formatting classes.
- *
- * There are two types used here:
- * * C++-type, the type as used in C++.
- * * format-type, the output type specified in the std-format-spec.
- *
- * Design of the integral formatters consists of several layers.
- * * @ref __parser_integral The basic std-format-spec parser for all integral
- * classes. This parser does the basic sanity checks. It also contains some
- * helper functions that are nice to have available for all parsers.
- * * A C++-type specific parser. These parsers must derive from
- * @ref __parser_integral. Their task is to validate whether the parsed
- * std-format-spec is valid for the C++-type and selected format-type. After
- * validation they need to make sure all members are properly set. For
- * example, when the alignment hasn't changed it needs to set the proper
- * default alignment for the format-type. The following parsers are available:
- * - @ref __parser_integer
- * - @ref __parser_char
- * - @ref __parser_bool
- * * A general formatter for all integral types @ref __formatter_integral. This
- * formatter can handle all formatting of integers and characters. The class
- * derives from the proper formatter.
- * Note the boolean string format-type isn't supported in this class.
- * * A typedef C++-type group combining the @ref __formatter_integral with a
- * parser:
- * * @ref __formatter_integer
- * * @ref __formatter_char
- * * @ref __formatter_bool
- * * Then every C++-type has its own formatter specializations. They inherit
- * from the C++-type group typedef. Most specializations need nothing else.
- * Others need some additional specializations in this class.
- */
-namespace __format_spec {
-
-/** Wrapper around @ref to_chars, returning the output pointer. */
-template <integral _Tp>
-_LIBCPP_HIDE_FROM_ABI char* __to_buffer(char* __first, char* __last,
- _Tp __value, int __base) {
- // TODO FMT Evaluate code overhead due to not calling the internal function
- // directly. (Should be zero overhead.)
- to_chars_result __r = _VSTD::to_chars(__first, __last, __value, __base);
- _LIBCPP_ASSERT(__r.ec == errc(0), "Internal buffer too small");
- return __r.ptr;
-}
-
-/**
- * Helper to determine the buffer size to output a integer in Base @em x.
- *
- * There are several overloads for the supported bases. The function uses the
- * base as template argument so it can be used in a constant expression.
- */
-template <unsigned_integral _Tp, size_t _Base>
-_LIBCPP_HIDE_FROM_ABI constexpr size_t __buffer_size() noexcept
- requires(_Base == 2) {
- return numeric_limits<_Tp>::digits // The number of binary digits.
- + 2 // Reserve space for the '0[Bb]' prefix.
- + 1; // Reserve space for the sign.
-}
-
-template <unsigned_integral _Tp, size_t _Base>
-_LIBCPP_HIDE_FROM_ABI constexpr size_t __buffer_size() noexcept
- requires(_Base == 8) {
- return numeric_limits<_Tp>::digits // The number of binary digits.
- / 3 // Adjust to octal.
- + 1 // Turn floor to ceil.
- + 1 // Reserve space for the '0' prefix.
- + 1; // Reserve space for the sign.
-}
+//
+// Generic
+//
-template <unsigned_integral _Tp, size_t _Base>
-_LIBCPP_HIDE_FROM_ABI constexpr size_t __buffer_size() noexcept
- requires(_Base == 10) {
- return numeric_limits<_Tp>::digits10 // The floored value.
- + 1 // Turn floor to ceil.
- + 1; // Reserve space for the sign.
-}
+_LIBCPP_HIDE_FROM_ABI inline char* __insert_sign(char* __buf, bool __negative, __format_spec::__sign __sign) {
+ if (__negative)
+ *__buf++ = '-';
+ else
+ switch (__sign) {
+ case __format_spec::__sign::__default:
+ case __format_spec::__sign::__minus:
+ // No sign added.
+ break;
+ case __format_spec::__sign::__plus:
+ *__buf++ = '+';
+ break;
+ case __format_spec::__sign::__space:
+ *__buf++ = ' ';
+ break;
+ }
-template <unsigned_integral _Tp, size_t _Base>
-_LIBCPP_HIDE_FROM_ABI constexpr size_t __buffer_size() noexcept
- requires(_Base == 16) {
- return numeric_limits<_Tp>::digits // The number of binary digits.
- / 4 // Adjust to hexadecimal.
- + 2 // Reserve space for the '0[Xx]' prefix.
- + 1; // Reserve space for the sign.
+ return __buf;
}
/**
@@ -148,8 +78,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr size_t __buffer_size() noexcept
* @note The grouping field of the locale is always a @c std::string,
* regardless whether the @c std::numpunct's type is @c char or @c wchar_t.
*/
-_LIBCPP_HIDE_FROM_ABI inline string
-__determine_grouping(ptrdiff_t __size, const string& __grouping) {
+_LIBCPP_HIDE_FROM_ABI inline string __determine_grouping(ptrdiff_t __size, const string& __grouping) {
_LIBCPP_ASSERT(!__grouping.empty() && __size > __grouping[0],
"The slow grouping formatting is used while there will be no "
"separators written");
@@ -176,283 +105,256 @@ __determine_grouping(ptrdiff_t __size, const string& __grouping) {
}
}
- _LIBCPP_UNREACHABLE();
+ __libcpp_unreachable();
}
-template <class _Parser>
-requires __formatter::__char_type<typename _Parser::char_type>
-class _LIBCPP_TEMPLATE_VIS __formatter_integral : public _Parser {
-public:
- using _CharT = typename _Parser::char_type;
-
- template <integral _Tp>
- _LIBCPP_HIDE_FROM_ABI auto format(_Tp __value, auto& __ctx)
- -> decltype(__ctx.out()) {
- if (this->__width_needs_substitution())
- this->__substitute_width_arg_id(__ctx.arg(this->__width));
-
- if (this->__type == _Flags::_Type::__char)
- return __format_as_char(__value, __ctx);
+//
+// Char
+//
- if constexpr (unsigned_integral<_Tp>)
- return __format_unsigned_integral(__value, false, __ctx);
- else {
- // Depending on the std-format-spec string the sign and the value
- // might not be outputted together:
- // - alternate form may insert a prefix string.
- // - zero-padding may insert additional '0' characters.
- // Therefore the value is processed as a positive unsigned value.
- // The function @ref __insert_sign will a '-' when the value was negative.
- auto __r = __to_unsigned_like(__value);
- bool __negative = __value < 0;
- if (__negative)
- __r = __complement(__r);
-
- return __format_unsigned_integral(__r, __negative, __ctx);
+template <__formatter::__char_type _CharT>
+_LIBCPP_HIDE_FROM_ABI auto __format_char(
+ integral auto __value,
+ output_iterator<const _CharT&> auto __out_it,
+ __format_spec::__parsed_specifications<_CharT> __specs) -> decltype(__out_it) {
+ using _Tp = decltype(__value);
+ if constexpr (!same_as<_CharT, _Tp>) {
+ // cmp_less and cmp_greater can't be used for character types.
+ if constexpr (signed_integral<_CharT> == signed_integral<_Tp>) {
+ if (__value < numeric_limits<_CharT>::min() || __value > numeric_limits<_CharT>::max())
+ std::__throw_format_error("Integral value outside the range of the char type");
+ } else if constexpr (signed_integral<_CharT>) {
+ // _CharT is signed _Tp is unsigned
+ if (__value > static_cast<make_unsigned_t<_CharT>>(numeric_limits<_CharT>::max()))
+ std::__throw_format_error("Integral value outside the range of the char type");
+ } else {
+ // _CharT is unsigned _Tp is signed
+ if (__value < 0 || static_cast<make_unsigned_t<_Tp>>(__value) > numeric_limits<_CharT>::max())
+ std::__throw_format_error("Integral value outside the range of the char type");
}
}
-private:
- /** Generic formatting for format-type c. */
- _LIBCPP_HIDE_FROM_ABI auto __format_as_char(integral auto __value,
- auto& __ctx)
- -> decltype(__ctx.out()) {
- if (this->__alignment == _Flags::_Alignment::__default)
- this->__alignment = _Flags::_Alignment::__right;
-
- using _Tp = decltype(__value);
- if constexpr (!same_as<_CharT, _Tp>) {
- // cmp_less and cmp_greater can't be used for character types.
- if constexpr (signed_integral<_CharT> == signed_integral<_Tp>) {
- if (__value < numeric_limits<_CharT>::min() ||
- __value > numeric_limits<_CharT>::max())
- __throw_format_error(
- "Integral value outside the range of the char type");
- } else if constexpr (signed_integral<_CharT>) {
- // _CharT is signed _Tp is unsigned
- if (__value >
- static_cast<make_unsigned_t<_CharT>>(numeric_limits<_CharT>::max()))
- __throw_format_error(
- "Integral value outside the range of the char type");
- } else {
- // _CharT is unsigned _Tp is signed
- if (__value < 0 || static_cast<make_unsigned_t<_Tp>>(__value) >
- numeric_limits<_CharT>::max())
- __throw_format_error(
- "Integral value outside the range of the char type");
- }
- }
+ const auto __c = static_cast<_CharT>(__value);
+ return __formatter::__write(_VSTD::addressof(__c), _VSTD::addressof(__c) + 1, _VSTD::move(__out_it), __specs);
+}
- const auto __c = static_cast<_CharT>(__value);
- return __write(_VSTD::addressof(__c), _VSTD::addressof(__c) + 1,
- __ctx.out());
- }
+//
+// Integer
+//
- /**
- * Generic formatting for format-type bBdoxX.
- *
- * This small wrapper allocates a buffer with the required size. Then calls
- * the real formatter with the buffer and the prefix for the base.
- */
- _LIBCPP_HIDE_FROM_ABI auto
- __format_unsigned_integral(unsigned_integral auto __value, bool __negative,
- auto& __ctx) -> decltype(__ctx.out()) {
- switch (this->__type) {
- case _Flags::_Type::__binary_lower_case: {
- array<char, __buffer_size<decltype(__value), 2>()> __array;
- return __format_unsigned_integral(__array.begin(), __array.end(), __value,
- __negative, 2, __ctx, "0b");
- }
- case _Flags::_Type::__binary_upper_case: {
- array<char, __buffer_size<decltype(__value), 2>()> __array;
- return __format_unsigned_integral(__array.begin(), __array.end(), __value,
- __negative, 2, __ctx, "0B");
- }
- case _Flags::_Type::__octal: {
- // Octal is special; if __value == 0 there's no prefix.
- array<char, __buffer_size<decltype(__value), 8>()> __array;
- return __format_unsigned_integral(__array.begin(), __array.end(), __value,
- __negative, 8, __ctx,
- __value != 0 ? "0" : nullptr);
- }
- case _Flags::_Type::__decimal: {
- array<char, __buffer_size<decltype(__value), 10>()> __array;
- return __format_unsigned_integral(__array.begin(), __array.end(), __value,
- __negative, 10, __ctx, nullptr);
- }
- case _Flags::_Type::__hexadecimal_lower_case: {
- array<char, __buffer_size<decltype(__value), 16>()> __array;
- return __format_unsigned_integral(__array.begin(), __array.end(), __value,
- __negative, 16, __ctx, "0x");
- }
- case _Flags::_Type::__hexadecimal_upper_case: {
- array<char, __buffer_size<decltype(__value), 16>()> __array;
- return __format_unsigned_integral(__array.begin(), __array.end(), __value,
- __negative, 16, __ctx, "0X");
- }
- default:
- _LIBCPP_ASSERT(false, "The parser should have validated the type");
- _LIBCPP_UNREACHABLE();
- }
- }
+/** Wrapper around @ref to_chars, returning the output pointer. */
+template <integral _Tp>
+_LIBCPP_HIDE_FROM_ABI char* __to_buffer(char* __first, char* __last, _Tp __value, int __base) {
+ // TODO FMT Evaluate code overhead due to not calling the internal function
+ // directly. (Should be zero overhead.)
+ to_chars_result __r = _VSTD::to_chars(__first, __last, __value, __base);
+ _LIBCPP_ASSERT(__r.ec == errc(0), "Internal buffer too small");
+ return __r.ptr;
+}
- template <class _Tp>
- requires(same_as<char, _Tp> || same_as<wchar_t, _Tp>) _LIBCPP_HIDE_FROM_ABI
- auto __write(const _Tp* __first, const _Tp* __last, auto __out_it)
- -> decltype(__out_it) {
+/**
+ * Helper to determine the buffer size to output a integer in Base @em x.
+ *
+ * There are several overloads for the supported bases. The function uses the
+ * base as template argument so it can be used in a constant expression.
+ */
+template <unsigned_integral _Tp, size_t _Base>
+consteval size_t __buffer_size() noexcept
+ requires(_Base == 2)
+{
+ return numeric_limits<_Tp>::digits // The number of binary digits.
+ + 2 // Reserve space for the '0[Bb]' prefix.
+ + 1; // Reserve space for the sign.
+}
- unsigned __size = __last - __first;
- if (this->__type != _Flags::_Type::__hexadecimal_upper_case) [[likely]] {
- if (__size >= this->__width)
- return _VSTD::copy(__first, __last, _VSTD::move(__out_it));
+template <unsigned_integral _Tp, size_t _Base>
+consteval size_t __buffer_size() noexcept
+ requires(_Base == 8)
+{
+ return numeric_limits<_Tp>::digits // The number of binary digits.
+ / 3 // Adjust to octal.
+ + 1 // Turn floor to ceil.
+ + 1 // Reserve space for the '0' prefix.
+ + 1; // Reserve space for the sign.
+}
- return __formatter::__write(_VSTD::move(__out_it), __first, __last,
- __size, this->__width, this->__fill,
- this->__alignment);
- }
+template <unsigned_integral _Tp, size_t _Base>
+consteval size_t __buffer_size() noexcept
+ requires(_Base == 10)
+{
+ return numeric_limits<_Tp>::digits10 // The floored value.
+ + 1 // Turn floor to ceil.
+ + 1; // Reserve space for the sign.
+}
+
+template <unsigned_integral _Tp, size_t _Base>
+consteval size_t __buffer_size() noexcept
+ requires(_Base == 16)
+{
+ return numeric_limits<_Tp>::digits // The number of binary digits.
+ / 4 // Adjust to hexadecimal.
+ + 2 // Reserve space for the '0[Xx]' prefix.
+ + 1; // Reserve space for the sign.
+}
- // this->__type == _Flags::_Type::__hexadecimal_upper_case
- // This means all characters in the range [a-f] need to be changed to their
- // uppercase representation. The transformation is done as transformation
- // in the output routine instead of before. This avoids another pass over
- // the data.
- // TODO FMT See whether it's possible to do this transformation during the
- // conversion. (This probably requires changing std::to_chars' alphabet.)
- if (__size >= this->__width)
- return _VSTD::transform(__first, __last, _VSTD::move(__out_it),
- __hex_to_upper);
-
- return __formatter::__write(_VSTD::move(__out_it), __first, __last, __size,
- __hex_to_upper, this->__width, this->__fill,
- this->__alignment);
+template <unsigned_integral _Tp, class _CharT>
+_LIBCPP_HIDE_FROM_ABI auto __format_integer(
+ _Tp __value,
+ auto& __ctx,
+ __format_spec::__parsed_specifications<_CharT> __specs,
+ bool __negative,
+ char* __begin,
+ char* __end,
+ const char* __prefix,
+ int __base) -> decltype(__ctx.out()) {
+ _LIBCPP_ASSERT(
+ __specs.__alignment_ != __format_spec::__alignment::__default,
+ "the caller should adjust the default to the value required by the type");
+
+ char* __first = __formatter::__insert_sign(__begin, __negative, __specs.__std_.__sign_);
+ if (__specs.__std_.__alternate_form_ && __prefix)
+ while (*__prefix)
+ *__first++ = *__prefix++;
+
+ char* __last = __formatter::__to_buffer(__first, __end, __value, __base);
+
+# ifndef _LIBCPP_HAS_NO_LOCALIZATION
+ if (__specs.__std_.__locale_specific_form_) {
+ const auto& __np = use_facet<numpunct<_CharT>>(__ctx.locale());
+ string __grouping = __np.grouping();
+ ptrdiff_t __size = __last - __first;
+ // Writing the grouped form has more overhead than the normal output
+ // routines. If there will be no separators written the locale-specific
+ // form is identical to the normal routine. Test whether to grouped form
+ // is required.
+ if (!__grouping.empty() && __size > __grouping[0])
+ return __formatter::__write_using_decimal_separators(
+ __ctx.out(),
+ __begin,
+ __first,
+ __last,
+ __formatter::__determine_grouping(__size, __grouping),
+ __np.thousands_sep(),
+ __specs);
+ }
+# endif
+ auto __out_it = __ctx.out();
+ if (__specs.__alignment_ != __format_spec::__alignment::__zero_padding)
+ __first = __begin;
+ else {
+ // __buf contains [sign][prefix]data
+ // ^ location of __first
+ // The zero padding is done like:
+ // - Write [sign][prefix]
+ // - Write data right aligned with '0' as fill character.
+ __out_it = _VSTD::copy(__begin, __first, _VSTD::move(__out_it));
+ __specs.__alignment_ = __format_spec::__alignment::__right;
+ __specs.__fill_ = _CharT('0');
+ int32_t __size = __first - __begin;
+
+ __specs.__width_ -= _VSTD::min(__size, __specs.__width_);
}
- _LIBCPP_HIDE_FROM_ABI auto
- __format_unsigned_integral(char* __begin, char* __end,
- unsigned_integral auto __value, bool __negative,
- int __base, auto& __ctx, const char* __prefix)
- -> decltype(__ctx.out()) {
- char* __first = __insert_sign(__begin, __negative, this->__sign);
- if (this->__alternate_form && __prefix)
- while (*__prefix)
- *__first++ = *__prefix++;
-
- char* __last = __to_buffer(__first, __end, __value, __base);
-#ifndef _LIBCPP_HAS_NO_LOCALIZATION
- if (this->__locale_specific_form) {
- const auto& __np = use_facet<numpunct<_CharT>>(__ctx.locale());
- string __grouping = __np.grouping();
- ptrdiff_t __size = __last - __first;
- // Writing the grouped form has more overhead than the normal output
- // routines. If there will be no separators written the locale-specific
- // form is identical to the normal routine. Test whether to grouped form
- // is required.
- if (!__grouping.empty() && __size > __grouping[0])
- return __format_grouping(__ctx.out(), __begin, __first, __last,
- __determine_grouping(__size, __grouping),
- __np.thousands_sep());
- }
-#endif
- auto __out_it = __ctx.out();
- if (this->__alignment != _Flags::_Alignment::__default)
- __first = __begin;
- else {
- // __buf contains [sign][prefix]data
- // ^ location of __first
- // The zero padding is done like:
- // - Write [sign][prefix]
- // - Write data right aligned with '0' as fill character.
- __out_it = _VSTD::copy(__begin, __first, _VSTD::move(__out_it));
- this->__alignment = _Flags::_Alignment::__right;
- this->__fill = _CharT('0');
- uint32_t __size = __first - __begin;
- this->__width -= _VSTD::min(__size, this->__width);
- }
+ if (__specs.__std_.__type_ != __format_spec::__type::__hexadecimal_upper_case) [[likely]]
+ return __formatter::__write(__first, __last, __ctx.out(), __specs);
+
+ return __formatter::__write_transformed(__first, __last, __ctx.out(), __specs, __formatter::__hex_to_upper);
+}
- return __write(__first, __last, _VSTD::move(__out_it));
+template <unsigned_integral _Tp, class _CharT>
+_LIBCPP_HIDE_FROM_ABI auto __format_integer(
+ _Tp __value, auto& __ctx, __format_spec::__parsed_specifications<_CharT> __specs, bool __negative = false)
+ -> decltype(__ctx.out()) {
+ switch (__specs.__std_.__type_) {
+ case __format_spec::__type::__binary_lower_case: {
+ array<char, __formatter::__buffer_size<decltype(__value), 2>()> __array;
+ return __formatter::__format_integer(__value, __ctx, __specs, __negative, __array.begin(), __array.end(), "0b", 2);
+ }
+ case __format_spec::__type::__binary_upper_case: {
+ array<char, __formatter::__buffer_size<decltype(__value), 2>()> __array;
+ return __formatter::__format_integer(__value, __ctx, __specs, __negative, __array.begin(), __array.end(), "0B", 2);
+ }
+ case __format_spec::__type::__octal: {
+ // Octal is special; if __value == 0 there's no prefix.
+ array<char, __formatter::__buffer_size<decltype(__value), 8>()> __array;
+ return __formatter::__format_integer(
+ __value, __ctx, __specs, __negative, __array.begin(), __array.end(), __value != 0 ? "0" : nullptr, 8);
+ }
+ case __format_spec::__type::__decimal: {
+ array<char, __formatter::__buffer_size<decltype(__value), 10>()> __array;
+ return __formatter::__format_integer(
+ __value, __ctx, __specs, __negative, __array.begin(), __array.end(), nullptr, 10);
+ }
+ case __format_spec::__type::__hexadecimal_lower_case: {
+ array<char, __formatter::__buffer_size<decltype(__value), 16>()> __array;
+ return __formatter::__format_integer(__value, __ctx, __specs, __negative, __array.begin(), __array.end(), "0x", 16);
+ }
+ case __format_spec::__type::__hexadecimal_upper_case: {
+ array<char, __formatter::__buffer_size<decltype(__value), 16>()> __array;
+ return __formatter::__format_integer(__value, __ctx, __specs, __negative, __array.begin(), __array.end(), "0X", 16);
+ }
+ default:
+ _LIBCPP_ASSERT(false, "The parse function should have validated the type");
+ __libcpp_unreachable();
}
+}
-#ifndef _LIBCPP_HAS_NO_LOCALIZATION
- /** Format's the locale-specific form's groupings. */
- template <class _OutIt, class _CharT>
- _LIBCPP_HIDE_FROM_ABI _OutIt
- __format_grouping(_OutIt __out_it, const char* __begin, const char* __first,
- const char* __last, string&& __grouping, _CharT __sep) {
-
- // TODO FMT This function duplicates some functionality of the normal
- // output routines. Evaluate whether these parts can be efficiently
- // combined with the existing routines.
-
- unsigned __size = (__first - __begin) + // [sign][prefix]
- (__last - __first) + // data
- (__grouping.size() - 1); // number of separator characters
-
- __formatter::__padding_size_result __padding = {0, 0};
- if (this->__alignment == _Flags::_Alignment::__default) {
- // Write [sign][prefix].
- __out_it = _VSTD::copy(__begin, __first, _VSTD::move(__out_it));
-
- if (this->__width > __size) {
- // Write zero padding.
- __padding.__before = this->__width - __size;
- __out_it = _VSTD::fill_n(_VSTD::move(__out_it), this->__width - __size,
- _CharT('0'));
- }
- } else {
- if (this->__width > __size) {
- // Determine padding and write padding.
- __padding = __formatter::__padding_size(__size, this->__width,
- this->__alignment);
-
- __out_it = _VSTD::fill_n(_VSTD::move(__out_it), __padding.__before,
- this->__fill);
- }
- // Write [sign][prefix].
- __out_it = _VSTD::copy(__begin, __first, _VSTD::move(__out_it));
- }
+template <signed_integral _Tp, class _CharT>
+_LIBCPP_HIDE_FROM_ABI auto
+__format_integer(_Tp __value, auto& __ctx, __format_spec::__parsed_specifications<_CharT> __specs)
+ -> decltype(__ctx.out()) {
+ // Depending on the std-format-spec string the sign and the value
+ // might not be outputted together:
+ // - alternate form may insert a prefix string.
+ // - zero-padding may insert additional '0' characters.
+ // Therefore the value is processed as a positive unsigned value.
+ // The function @ref __insert_sign will a '-' when the value was negative.
+ auto __r = std::__to_unsigned_like(__value);
+ bool __negative = __value < 0;
+ if (__negative)
+ __r = __complement(__r);
+
+ return __formatter::__format_integer(__r, __ctx, __specs, __negative);
+}
- auto __r = __grouping.rbegin();
- auto __e = __grouping.rend() - 1;
- _LIBCPP_ASSERT(__r != __e, "The slow grouping formatting is used while "
- "there will be no separators written.");
- // The output is divided in small groups of numbers to write:
- // - A group before the first separator.
- // - A separator and a group, repeated for the number of separators.
- // - A group after the last separator.
- // This loop achieves that process by testing the termination condition
- // midway in the loop.
- //
- // TODO FMT This loop evaluates the loop invariant `this->__type !=
- // _Flags::_Type::__hexadecimal_upper_case` for every iteration. (This test
- // happens in the __write call.) Benchmark whether making two loops and
- // hoisting the invariant is worth the effort.
- while (true) {
- if (this->__type == _Flags::_Type::__hexadecimal_upper_case) {
- __last = __first + *__r;
- __out_it = _VSTD::transform(__first, __last, _VSTD::move(__out_it),
- __hex_to_upper);
- __first = __last;
- } else {
- __out_it = _VSTD::copy_n(__first, *__r, _VSTD::move(__out_it));
- __first += *__r;
- }
-
- if (__r == __e)
- break;
-
- ++__r;
- *__out_it++ = __sep;
- }
+//
+// Formatter arithmetic (bool)
+//
- return _VSTD::fill_n(_VSTD::move(__out_it), __padding.__after,
- this->__fill);
- }
-#endif // _LIBCPP_HAS_NO_LOCALIZATION
+template <class _CharT>
+struct _LIBCPP_TEMPLATE_VIS __bool_strings;
+
+template <>
+struct _LIBCPP_TEMPLATE_VIS __bool_strings<char> {
+ static constexpr string_view __true{"true"};
+ static constexpr string_view __false{"false"};
};
-} // namespace __format_spec
+# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+template <>
+struct _LIBCPP_TEMPLATE_VIS __bool_strings<wchar_t> {
+ static constexpr wstring_view __true{L"true"};
+ static constexpr wstring_view __false{L"false"};
+};
+# endif
+
+template <class _CharT>
+_LIBCPP_HIDE_FROM_ABI auto
+__format_bool(bool __value, auto& __ctx, __format_spec::__parsed_specifications<_CharT> __specs)
+ -> decltype(__ctx.out()) {
+# ifndef _LIBCPP_HAS_NO_LOCALIZATION
+ if (__specs.__std_.__locale_specific_form_) {
+ const auto& __np = use_facet<numpunct<_CharT>>(__ctx.locale());
+ basic_string<_CharT> __str = __value ? __np.truename() : __np.falsename();
+ return __formatter::__write_unicode_no_precision(basic_string_view<_CharT>{__str}, __ctx.out(), __specs);
+ }
+# endif
+ basic_string_view<_CharT> __str =
+ __value ? __formatter::__bool_strings<_CharT>::__true : __formatter::__bool_strings<_CharT>::__false;
+ return __formatter::__write(__str.begin(), __str.end(), __ctx.out(), __specs);
+}
-#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
+} // namespace __formatter
#endif //_LIBCPP_STD_VER > 17
diff --git a/libcxx/include/__format/formatter_output.h b/libcxx/include/__format/formatter_output.h
new file mode 100644
index 000000000000..ab016f6f1610
--- /dev/null
+++ b/libcxx/include/__format/formatter_output.h
@@ -0,0 +1,304 @@
+// -*- 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___FORMAT_FORMATTER_OUTPUT_H
+#define _LIBCPP___FORMAT_FORMATTER_OUTPUT_H
+
+#include <__algorithm/copy.h>
+#include <__algorithm/copy_n.h>
+#include <__algorithm/fill_n.h>
+#include <__algorithm/transform.h>
+#include <__config>
+#include <__format/formatter.h>
+#include <__format/parser_std_format_spec.h>
+#include <__utility/move.h>
+#include <__utility/unreachable.h>
+#include <cstddef>
+#include <string>
+#include <string_view>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 17
+
+namespace __formatter {
+
+_LIBCPP_HIDE_FROM_ABI constexpr char __hex_to_upper(char c) {
+ switch (c) {
+ case 'a':
+ return 'A';
+ case 'b':
+ return 'B';
+ case 'c':
+ return 'C';
+ case 'd':
+ return 'D';
+ case 'e':
+ return 'E';
+ case 'f':
+ return 'F';
+ }
+ return c;
+}
+
+// TODO FMT remove _v2 suffix.
+struct _LIBCPP_TYPE_VIS __padding_size_result_v2 {
+ size_t __before_;
+ size_t __after_;
+};
+
+// TODO FMT remove _v2 suffix.
+_LIBCPP_HIDE_FROM_ABI constexpr __padding_size_result_v2 __padding_size_v2(size_t __size, size_t __width,
+ __format_spec::__alignment __align) {
+ _LIBCPP_ASSERT(__width > __size, "don't call this function when no padding is required");
+ _LIBCPP_ASSERT(__align != __format_spec::__alignment::__default,
+ "the caller should adjust the default to the value required by the type");
+ _LIBCPP_ASSERT(__align != __format_spec::__alignment::__zero_padding,
+ "the caller should have handled the zero-padding");
+
+ size_t __fill = __width - __size;
+ switch (__align) {
+ case __format_spec::__alignment::__default:
+ case __format_spec::__alignment::__zero_padding:
+ __libcpp_unreachable();
+
+ case __format_spec::__alignment::__left:
+ return {0, __fill};
+
+ case __format_spec::__alignment::__center: {
+ // The extra padding is divided per [format.string.std]/3
+ // __before = floor(__fill, 2);
+ // __after = ceil(__fill, 2);
+ size_t __before = __fill / 2;
+ size_t __after = __fill - __before;
+ return {__before, __after};
+ }
+ case __format_spec::__alignment::__right:
+ return {__fill, 0};
+ }
+ __libcpp_unreachable();
+}
+
+template <class _OutIt, class _CharT>
+_LIBCPP_HIDE_FROM_ABI _OutIt __write_using_decimal_separators(_OutIt __out_it, const char* __begin, const char* __first,
+ const char* __last, string&& __grouping, _CharT __sep,
+ __format_spec::__parsed_specifications<_CharT> __specs) {
+ _LIBCPP_ASSERT(__specs.__alignment_ != __format_spec::__alignment::__default,
+ "the caller should adjust the default to the value required by the type");
+
+ int __size = (__first - __begin) + // [sign][prefix]
+ (__last - __first) + // data
+ (__grouping.size() - 1); // number of separator characters
+
+ __padding_size_result_v2 __padding = {0, 0};
+ if (__specs.__alignment_ == __format_spec::__alignment::__zero_padding) {
+ // Write [sign][prefix].
+ __out_it = _VSTD::copy(__begin, __first, _VSTD::move(__out_it));
+
+ if (__specs.__width_ > __size) {
+ // Write zero padding.
+ __padding.__before_ = __specs.__width_ - __size;
+ __out_it = _VSTD::fill_n(_VSTD::move(__out_it), __specs.__width_ - __size, _CharT('0'));
+ }
+ } else {
+ if (__specs.__width_ > __size) {
+ // Determine padding and write padding.
+ __padding = __padding_size_v2(__size, __specs.__width_, __specs.__alignment_);
+
+ __out_it = _VSTD::fill_n(_VSTD::move(__out_it), __padding.__before_, __specs.__fill_);
+ }
+ // Write [sign][prefix].
+ __out_it = _VSTD::copy(__begin, __first, _VSTD::move(__out_it));
+ }
+
+ auto __r = __grouping.rbegin();
+ auto __e = __grouping.rend() - 1;
+ _LIBCPP_ASSERT(__r != __e, "The slow grouping formatting is used while "
+ "there will be no separators written.");
+ // The output is divided in small groups of numbers to write:
+ // - A group before the first separator.
+ // - A separator and a group, repeated for the number of separators.
+ // - A group after the last separator.
+ // This loop achieves that process by testing the termination condition
+ // midway in the loop.
+ //
+ // TODO FMT This loop evaluates the loop invariant `__parser.__type !=
+ // _Flags::_Type::__hexadecimal_upper_case` for every iteration. (This test
+ // happens in the __write call.) Benchmark whether making two loops and
+ // hoisting the invariant is worth the effort.
+ while (true) {
+ if (__specs.__std_.__type_ == __format_spec::__type::__hexadecimal_upper_case) {
+ __last = __first + *__r;
+ __out_it = _VSTD::transform(__first, __last, _VSTD::move(__out_it), __hex_to_upper);
+ __first = __last;
+ } else {
+ __out_it = _VSTD::copy_n(__first, *__r, _VSTD::move(__out_it));
+ __first += *__r;
+ }
+
+ if (__r == __e)
+ break;
+
+ ++__r;
+ *__out_it++ = __sep;
+ }
+
+ return _VSTD::fill_n(_VSTD::move(__out_it), __padding.__after_, __specs.__fill_);
+}
+
+/// Writes the input to the output with the required padding.
+///
+/// Since the output column width is specified the function can be used for
+/// ASCII and Unicode output.
+///
+/// \pre [\a __first, \a __last) is a valid range.
+/// \pre \a __size <= \a __width. Using this function when this pre-condition
+/// doesn't hold incurs an unwanted overhead.
+///
+/// \param __first Pointer to the first element to write.
+/// \param __last Pointer beyond the last element to write.
+/// \param __out_it The output iterator to write to.
+/// \param __specs The parsed formatting specifications.
+/// \param __size The (estimated) output column width. When the elements
+/// to be written are ASCII the following condition holds
+/// \a __size == \a __last - \a __first.
+///
+/// \returns An iterator pointing beyond the last element written.
+///
+/// \note The type of the elements in range [\a __first, \a __last) can differ
+/// from the type of \a __specs. Integer output uses \c std::to_chars for its
+/// conversion, which means the [\a __first, \a __last) always contains elements
+/// of the type \c char.
+template <class _CharT, class _ParserCharT>
+_LIBCPP_HIDE_FROM_ABI auto __write(const _CharT* __first, const _CharT* __last,
+ output_iterator<const _CharT&> auto __out_it,
+ __format_spec::__parsed_specifications<_ParserCharT> __specs, ptrdiff_t __size)
+ -> decltype(__out_it) {
+ _LIBCPP_ASSERT(__first <= __last, "Not a valid range");
+
+ if (__size >= __specs.__width_)
+ return _VSTD::copy(__first, __last, _VSTD::move(__out_it));
+
+ __padding_size_result_v2 __padding =
+ __formatter::__padding_size_v2(__size, __specs.__width_, __specs.__std_.__alignment_);
+ __out_it = _VSTD::fill_n(_VSTD::move(__out_it), __padding.__before_, __specs.__fill_);
+ __out_it = _VSTD::copy(__first, __last, _VSTD::move(__out_it));
+ return _VSTD::fill_n(_VSTD::move(__out_it), __padding.__after_, __specs.__fill_);
+}
+
+/// \overload
+/// Calls the function above where \a __size = \a __last - \a __first.
+template <class _CharT, class _ParserCharT>
+_LIBCPP_HIDE_FROM_ABI auto __write(const _CharT* __first, const _CharT* __last,
+ output_iterator<const _CharT&> auto __out_it,
+ __format_spec::__parsed_specifications<_ParserCharT> __specs) -> decltype(__out_it) {
+ return __write(__first, __last, _VSTD::move(__out_it), __specs, __last - __first);
+}
+
+template <class _CharT, class _ParserCharT, class _UnaryOperation>
+_LIBCPP_HIDE_FROM_ABI auto __write_transformed(const _CharT* __first, const _CharT* __last,
+ output_iterator<const _CharT&> auto __out_it,
+ __format_spec::__parsed_specifications<_ParserCharT> __specs,
+ _UnaryOperation __op) -> decltype(__out_it) {
+ _LIBCPP_ASSERT(__first <= __last, "Not a valid range");
+
+ ptrdiff_t __size = __last - __first;
+ if (__size >= __specs.__width_)
+ return _VSTD::transform(__first, __last, _VSTD::move(__out_it), __op);
+
+ __padding_size_result_v2 __padding = __padding_size_v2(__size, __specs.__width_, __specs.__alignment_);
+ __out_it = _VSTD::fill_n(_VSTD::move(__out_it), __padding.__before_, __specs.__fill_);
+ __out_it = _VSTD::transform(__first, __last, _VSTD::move(__out_it), __op);
+ return _VSTD::fill_n(_VSTD::move(__out_it), __padding.__after_, __specs.__fill_);
+}
+
+# ifndef _LIBCPP_HAS_NO_UNICODE
+template <class _CharT>
+_LIBCPP_HIDE_FROM_ABI auto __write_unicode_no_precision(basic_string_view<_CharT> __str,
+ output_iterator<const _CharT&> auto __out_it,
+ __format_spec::__parsed_specifications<_CharT> __specs)
+ -> decltype(__out_it) {
+
+ _LIBCPP_ASSERT(!__specs.__has_precision(), "use __write_unicode");
+ // No padding -> copy the string
+ if (!__specs.__has_width())
+ return _VSTD::copy(__str.begin(), __str.end(), _VSTD::move(__out_it));
+
+ // Non Unicode part larger than width -> copy the string
+ auto __last = __format_spec::__detail::__estimate_column_width_fast(__str.begin(), __str.end());
+ ptrdiff_t __size = __last - __str.begin();
+ if (__size >= __specs.__width_)
+ return _VSTD::copy(__str.begin(), __str.end(), _VSTD::move(__out_it));
+
+ // Is there a non Unicode part?
+ if (__last != __str.end()) {
+ // Non Unicode and Unicode part larger than width -> copy the string
+ __format_spec::__detail::__column_width_result __column_width =
+ __format_spec::__detail::__estimate_column_width(__last, __str.end(), __specs.__width_);
+ __size += __column_width.__width; // Note this new size is used when __size < __specs.__width_
+ if (__size >= __specs.__width_)
+ return _VSTD::copy(__str.begin(), __str.end(), _VSTD::move(__out_it));
+ }
+
+ return __formatter::__write(__str.begin(), __str.end(), _VSTD::move(__out_it), __specs, __size);
+}
+# endif
+
+template <class _CharT>
+_LIBCPP_HIDE_FROM_ABI auto __write_unicode(basic_string_view<_CharT> __str,
+ output_iterator<const _CharT&> auto __out_it,
+ __format_spec::__parsed_specifications<_CharT> __specs)
+ -> decltype(__out_it) {
+# ifndef _LIBCPP_HAS_NO_UNICODE
+ if (!__specs.__has_precision())
+ return __formatter::__write_unicode_no_precision(__str, _VSTD::move(__out_it), __specs);
+
+ // Non unicode part larger than precision -> truncate the output and use the normal write operation.
+ auto __last = __format_spec::__detail::__estimate_column_width_fast(__str.begin(), __str.end());
+ ptrdiff_t __size = __last - __str.begin();
+ if (__size >= __specs.__precision_)
+ return __formatter::__write(__str.begin(), __str.begin() + __specs.__precision_, _VSTD::move(__out_it), __specs,
+ __specs.__precision_);
+
+ // No non Unicode part, implies __size < __specs.__precision_ -> use normal write operation
+ if (__last == __str.end())
+ return __formatter::__write(__str.begin(), __str.end(), _VSTD::move(__out_it), __specs, __str.size());
+
+ __format_spec::__detail::__column_width_result __column_width =
+ __format_spec::__detail::__estimate_column_width(__last, __str.end(), __specs.__precision_ - __size);
+ __size += __column_width.__width;
+ // Truncate the output
+ if (__column_width.__ptr != __str.end())
+ __str.remove_suffix(__str.end() - __column_width.__ptr);
+
+ return __formatter::__write(__str.begin(), __str.end(), _VSTD::move(__out_it), __specs, __size);
+
+# else
+ if (__specs.__has_precision()) {
+ ptrdiff_t __size = __str.size();
+ if (__size > __specs.__precision_)
+ return __formatter::__write(__str.begin(), __str.begin() + __specs.__precision_, _VSTD::move(__out_it), __specs,
+ __specs.__precision_);
+ }
+ return __formatter::__write(__str.begin(), __str.end(), _VSTD::move(__out_it), __specs, __str.size());
+
+# endif
+}
+
+} // namespace __formatter
+
+#endif //_LIBCPP_STD_VER > 17
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___FORMAT_FORMATTER_OUTPUT_H
diff --git a/libcxx/include/__format/formatter_pointer.h b/libcxx/include/__format/formatter_pointer.h
index aa2eb641c6c6..3cd4c9bba960 100644
--- a/libcxx/include/__format/formatter_pointer.h
+++ b/libcxx/include/__format/formatter_pointer.h
@@ -10,17 +10,15 @@
#ifndef _LIBCPP___FORMAT_FORMATTER_POINTER_H
#define _LIBCPP___FORMAT_FORMATTER_POINTER_H
-#include <__algorithm/copy.h>
#include <__availability>
#include <__config>
-#include <__debug>
-#include <__format/format_error.h>
#include <__format/format_fwd.h>
+#include <__format/format_parse_context.h>
#include <__format/formatter.h>
#include <__format/formatter_integral.h>
+#include <__format/formatter_output.h>
#include <__format/parser_std_format_spec.h>
-#include <__iterator/access.h>
-#include <__nullptr>
+#include <cstddef>
#include <cstdint>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -31,41 +29,27 @@ _LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER > 17
-// TODO FMT Remove this once we require compilers with proper C++20 support.
-// If the compiler has no concepts support, the format header will be disabled.
-// Without concepts support enable_if needs to be used and that too much effort
-// to support compilers with partial C++20 support.
-# if !defined(_LIBCPP_HAS_NO_CONCEPTS)
-
-namespace __format_spec {
-
template <__formatter::__char_type _CharT>
-class _LIBCPP_TEMPLATE_VIS __formatter_pointer : public __parser_pointer<_CharT> {
+struct _LIBCPP_TEMPLATE_VIS __formatter_pointer {
public:
- _LIBCPP_HIDE_FROM_ABI auto format(const void* __ptr, auto& __ctx) -> decltype(__ctx.out()) {
- _LIBCPP_ASSERT(this->__alignment != _Flags::_Alignment::__default,
- "The call to parse should have updated the alignment");
- if (this->__width_needs_substitution())
- this->__substitute_width_arg_id(__ctx.arg(this->__width));
+ constexpr __formatter_pointer() { __parser_.__alignment_ = __format_spec::__alignment::__right; }
- // This code looks a lot like the code to format a hexadecimal integral,
- // but that code isn't public. Making that code public requires some
- // refactoring.
- // TODO FMT Remove code duplication.
- char __buffer[2 + 2 * sizeof(uintptr_t)];
- __buffer[0] = '0';
- __buffer[1] = 'x';
- char* __last = __to_buffer(__buffer + 2, _VSTD::end(__buffer), reinterpret_cast<uintptr_t>(__ptr), 16);
-
- unsigned __size = __last - __buffer;
- if (__size >= this->__width)
- return _VSTD::copy(__buffer, __last, __ctx.out());
+ _LIBCPP_HIDE_FROM_ABI constexpr auto
+ parse(basic_format_parse_context<_CharT>& __parse_ctx) -> decltype(__parse_ctx.begin()) {
+ auto __result = __parser_.__parse(__parse_ctx, __format_spec::__fields_pointer);
+ __format_spec::__process_display_type_pointer(__parser_.__type_);
+ return __result;
+ }
- return __formatter::__write(__ctx.out(), __buffer, __last, __size, this->__width, this->__fill, this->__alignment);
+ _LIBCPP_HIDE_FROM_ABI auto format(const void* __ptr, auto& __ctx) const -> decltype(__ctx.out()) {
+ __format_spec::__parsed_specifications<_CharT> __specs = __parser_.__get_parsed_std_specifications(__ctx);
+ __specs.__std_.__alternate_form_ = true;
+ __specs.__std_.__type_ = __format_spec::__type::__hexadecimal_lower_case;
+ return __formatter::__format_integer(reinterpret_cast<uintptr_t>(__ptr), __ctx, __specs);
}
-};
-} // namespace __format_spec
+ __format_spec::__parser<_CharT> __parser_;
+};
// [format.formatter.spec]/2.4
// For each charT, the pointer type specializations template<>
@@ -74,15 +58,13 @@ public:
// - template<> struct formatter<const void*, charT>;
template <__formatter::__char_type _CharT>
struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<nullptr_t, _CharT>
- : public __format_spec::__formatter_pointer<_CharT> {};
+ : public __formatter_pointer<_CharT> {};
template <__formatter::__char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<void*, _CharT>
- : public __format_spec::__formatter_pointer<_CharT> {};
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<void*, _CharT> : public __formatter_pointer<_CharT> {
+};
template <__formatter::__char_type _CharT>
struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<const void*, _CharT>
- : public __format_spec::__formatter_pointer<_CharT> {};
-
-# endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
+ : public __formatter_pointer<_CharT> {};
#endif //_LIBCPP_STD_VER > 17
diff --git a/libcxx/include/__format/formatter_string.h b/libcxx/include/__format/formatter_string.h
index 04950faa4a21..139c05e58c28 100644
--- a/libcxx/include/__format/formatter_string.h
+++ b/libcxx/include/__format/formatter_string.h
@@ -10,68 +10,49 @@
#ifndef _LIBCPP___FORMAT_FORMATTER_STRING_H
#define _LIBCPP___FORMAT_FORMATTER_STRING_H
+#include <__availability>
#include <__config>
-#include <__format/format_error.h>
#include <__format/format_fwd.h>
-#include <__format/format_string.h>
+#include <__format/format_parse_context.h>
#include <__format/formatter.h>
+#include <__format/formatter_output.h>
#include <__format/parser_std_format_spec.h>
+#include <__utility/move.h>
+#include <string>
#include <string_view>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
-_LIBCPP_PUSH_MACROS
-#include <__undef_macros>
-
_LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER > 17
-// TODO FMT Remove this once we require compilers with proper C++20 support.
-// If the compiler has no concepts support, the format header will be disabled.
-// Without concepts support enable_if needs to be used and that too much effort
-// to support compilers with partial C++20 support.
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
-
-namespace __format_spec {
-
template <__formatter::__char_type _CharT>
-class _LIBCPP_TEMPLATE_VIS __formatter_string : public __parser_string<_CharT> {
+struct _LIBCPP_TEMPLATE_VIS __formatter_string {
public:
- _LIBCPP_HIDE_FROM_ABI auto format(basic_string_view<_CharT> __str,
- auto& __ctx) -> decltype(__ctx.out()) {
-
- _LIBCPP_ASSERT(this->__alignment != _Flags::_Alignment::__default,
- "The parser should not use these defaults");
-
- if (this->__width_needs_substitution())
- this->__substitute_width_arg_id(__ctx.arg(this->__width));
-
- if (this->__precision_needs_substitution())
- this->__substitute_precision_arg_id(__ctx.arg(this->__precision));
-
- return __formatter::__write_unicode(
- __ctx.out(), __str, this->__width,
- this->__has_precision_field() ? this->__precision : -1, this->__fill,
- this->__alignment);
+ _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx)
+ -> decltype(__parse_ctx.begin()) {
+ auto __result = __parser_.__parse(__parse_ctx, __format_spec::__fields_string);
+ __format_spec::__process_display_type_string(__parser_.__type_);
+ return __result;
}
-};
-} //namespace __format_spec
+ _LIBCPP_HIDE_FROM_ABI auto format(basic_string_view<_CharT> __str, auto& __ctx) const -> decltype(__ctx.out()) {
+ return __formatter::__write_unicode(__str, __ctx.out(), __parser_.__get_parsed_std_specifications(__ctx));
+ }
-// [format.formatter.spec]/2.2 For each charT, the string type specializations
+ __format_spec::__parser<_CharT> __parser_;
+};
// Formatter const char*.
template <__formatter::__char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT
- formatter<const _CharT*, _CharT>
- : public __format_spec::__formatter_string<_CharT> {
- using _Base = __format_spec::__formatter_string<_CharT>;
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<const _CharT*, _CharT>
+ : public __formatter_string<_CharT> {
+ using _Base = __formatter_string<_CharT>;
- _LIBCPP_HIDE_FROM_ABI auto format(const _CharT* __str, auto& __ctx)
- -> decltype(__ctx.out()) {
+ _LIBCPP_HIDE_FROM_ABI auto format(const _CharT* __str, auto& __ctx) const -> decltype(__ctx.out()) {
_LIBCPP_ASSERT(__str, "The basic_format_arg constructor should have "
"prevented an invalid pointer.");
@@ -86,8 +67,9 @@ struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT
// now these optimizations aren't implemented. Instead the base class
// handles these options.
// TODO FMT Implement these improvements.
- if (this->__has_width_field() || this->__has_precision_field())
- return _Base::format(__str, __ctx);
+ __format_spec::__parsed_specifications<_CharT> __specs = _Base::__parser_.__get_parsed_std_specifications(__ctx);
+ if (__specs.__has_width() || __specs.__has_precision())
+ return __formatter::__write_unicode(basic_string_view<_CharT>{__str}, __ctx.out(), __specs);
// No formatting required, copy the string to the output.
auto __out_it = __ctx.out();
@@ -99,40 +81,46 @@ struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT
// Formatter char*.
template <__formatter::__char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT
- formatter<_CharT*, _CharT> : public formatter<const _CharT*, _CharT> {
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<_CharT*, _CharT>
+ : public formatter<const _CharT*, _CharT> {
using _Base = formatter<const _CharT*, _CharT>;
- _LIBCPP_HIDE_FROM_ABI auto format(_CharT* __str, auto& __ctx)
- -> decltype(__ctx.out()) {
+ _LIBCPP_HIDE_FROM_ABI auto format(_CharT* __str, auto& __ctx) const -> decltype(__ctx.out()) {
return _Base::format(__str, __ctx);
}
};
+// Formatter char[].
+template <__formatter::__char_type _CharT, size_t _Size>
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<_CharT[_Size], _CharT>
+ : public __formatter_string<_CharT> {
+ using _Base = __formatter_string<_CharT>;
+
+ _LIBCPP_HIDE_FROM_ABI auto format(_CharT __str[_Size], auto& __ctx) const -> decltype(__ctx.out()) {
+ return _Base::format(basic_string_view<_CharT>(__str, _Size), __ctx);
+ }
+};
+
// Formatter const char[].
template <__formatter::__char_type _CharT, size_t _Size>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT
- formatter<const _CharT[_Size], _CharT>
- : public __format_spec::__formatter_string<_CharT> {
- using _Base = __format_spec::__formatter_string<_CharT>;
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<const _CharT[_Size], _CharT>
+ : public __formatter_string<_CharT> {
+ using _Base = __formatter_string<_CharT>;
- _LIBCPP_HIDE_FROM_ABI auto format(const _CharT __str[_Size], auto& __ctx)
- -> decltype(__ctx.out()) {
+ _LIBCPP_HIDE_FROM_ABI auto format(const _CharT __str[_Size], auto& __ctx) const -> decltype(__ctx.out()) {
return _Base::format(basic_string_view<_CharT>(__str, _Size), __ctx);
}
};
// Formatter std::string.
template <__formatter::__char_type _CharT, class _Traits, class _Allocator>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT
- formatter<basic_string<_CharT, _Traits, _Allocator>, _CharT>
- : public __format_spec::__formatter_string<_CharT> {
- using _Base = __format_spec::__formatter_string<_CharT>;
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<basic_string<_CharT, _Traits, _Allocator>, _CharT>
+ : public __formatter_string<_CharT> {
+ using _Base = __formatter_string<_CharT>;
- _LIBCPP_HIDE_FROM_ABI auto
- format(const basic_string<_CharT, _Traits, _Allocator>& __str, auto& __ctx)
+ _LIBCPP_HIDE_FROM_ABI auto format(const basic_string<_CharT, _Traits, _Allocator>& __str, auto& __ctx) const
-> decltype(__ctx.out()) {
- // drop _Traits and _Allocator
+ // Drop _Traits and _Allocator to have one std::basic_string formatter.
return _Base::format(basic_string_view<_CharT>(__str.data(), __str.size()), __ctx);
}
};
@@ -140,23 +128,18 @@ struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT
// Formatter std::string_view.
template <__formatter::__char_type _CharT, class _Traits>
struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<basic_string_view<_CharT, _Traits>, _CharT>
- : public __format_spec::__formatter_string<_CharT> {
- using _Base = __format_spec::__formatter_string<_CharT>;
+ : public __formatter_string<_CharT> {
+ using _Base = __formatter_string<_CharT>;
- _LIBCPP_HIDE_FROM_ABI auto
- format(basic_string_view<_CharT, _Traits> __str, auto& __ctx)
+ _LIBCPP_HIDE_FROM_ABI auto format(basic_string_view<_CharT, _Traits> __str, auto& __ctx) const
-> decltype(__ctx.out()) {
- // drop _Traits
+ // Drop _Traits to have one std::basic_string_view formatter.
return _Base::format(basic_string_view<_CharT>(__str.data(), __str.size()), __ctx);
}
};
-#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
-
#endif //_LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
-_LIBCPP_POP_MACROS
-
#endif // _LIBCPP___FORMAT_FORMATTER_STRING_H
diff --git a/libcxx/include/__format/parser_std_format_spec.h b/libcxx/include/__format/parser_std_format_spec.h
index 9d893e9ced27..739bdf457e40 100644
--- a/libcxx/include/__format/parser_std_format_spec.h
+++ b/libcxx/include/__format/parser_std_format_spec.h
@@ -10,12 +10,20 @@
#ifndef _LIBCPP___FORMAT_PARSER_STD_FORMAT_SPEC_H
#define _LIBCPP___FORMAT_PARSER_STD_FORMAT_SPEC_H
+/// \file Contains the std-format-spec parser.
+///
+/// Most of the code can be reused in the chrono-format-spec.
+/// This header has some support for the chrono-format-spec since it doesn't
+/// affect the std-format-spec.
+
#include <__algorithm/find_if.h>
#include <__algorithm/min.h>
+#include <__assert>
#include <__config>
#include <__debug>
#include <__format/format_arg.h>
#include <__format/format_error.h>
+#include <__format/format_parse_context.h>
#include <__format/format_string.h>
#include <__variant/monostate.h>
#include <bit>
@@ -24,7 +32,7 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-# pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
@@ -34,24 +42,19 @@ _LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER > 17
-// TODO FMT Remove this once we require compilers with proper C++20 support.
-// If the compiler has no concepts support, the format header will be disabled.
-// Without concepts support enable_if needs to be used and that too much effort
-// to support compilers with partial C++20 support.
-# if !defined(_LIBCPP_HAS_NO_CONCEPTS)
-
namespace __format_spec {
/**
* Contains the flags for the std-format-spec.
*
- * Some format-options can only be used for specific C++types and may depend on
+ * Some format-options can only be used for specific C++ types and may depend on
* the selected format-type.
* * The C++type filtering can be done using the proper policies for
* @ref __parser_std.
* * The format-type filtering needs to be done post parsing in the parser
* derived from @ref __parser_std.
*/
+_LIBCPP_PACKED_BYTE_FOR_AIX
class _LIBCPP_TYPE_VIS _Flags {
public:
enum class _LIBCPP_ENUM_VIS _Alignment : uint8_t {
@@ -109,6 +112,7 @@ public:
_Type __type{_Type::__default};
};
+_LIBCPP_PACKED_BYTE_FOR_AIX_END
namespace __detail {
template <class _CharT>
@@ -222,7 +226,7 @@ __parse_arg_id(const _CharT* __begin, const _CharT* __end, auto& __parse_ctx) {
template <class _Context>
_LIBCPP_HIDE_FROM_ABI constexpr uint32_t
-__substitute_arg_id(basic_format_arg<_Context> __arg) {
+__substitute_arg_id(basic_format_arg<_Context> _Arg) {
return visit_format_arg(
[](auto __arg) -> uint32_t {
using _Type = decltype(__arg);
@@ -246,7 +250,7 @@ __substitute_arg_id(basic_format_arg<_Context> __arg) {
__throw_format_error("A format-spec arg-id replacement argument "
"isn't an integral type");
},
- __arg);
+ _Arg);
}
class _LIBCPP_TYPE_VIS __parser_width {
@@ -256,6 +260,13 @@ public:
/** Determines whether the value stored is a width or an arg-id. */
uint32_t __width_as_arg : 1 {0};
+ /**
+ * Does the supplied width field contain an arg-id?
+ *
+ * If @c true the formatter needs to call @ref __substitute_width_arg_id.
+ */
+ constexpr bool __width_needs_substitution() const noexcept { return __width_as_arg; }
+
protected:
/**
* Does the supplied std-format-spec contain a width field?
@@ -263,18 +274,7 @@ protected:
* When the field isn't present there's no padding required. This can be used
* to optimize the formatting.
*/
- constexpr bool __has_width_field() const noexcept {
- return __width_as_arg || __width;
- }
-
- /**
- * Does the supplied width field contain an arg-id?
- *
- * If @c true the formatter needs to call @ref __substitute_width_arg_id.
- */
- constexpr bool __width_needs_substitution() const noexcept {
- return __width_as_arg;
- }
+ constexpr bool __has_width_field() const noexcept { return __width_as_arg || __width; }
template <class _CharT>
_LIBCPP_HIDE_FROM_ABI constexpr const _CharT*
@@ -331,6 +331,15 @@ public:
*/
uint32_t __precision_as_arg : 1 {1};
+ /**
+ * Does the supplied precision field contain an arg-id?
+ *
+ * If @c true the formatter needs to call @ref __substitute_precision_arg_id.
+ */
+ constexpr bool __precision_needs_substitution() const noexcept {
+ return __precision_as_arg && __precision != __format::__number_max;
+ }
+
protected:
/**
* Does the supplied std-format-spec contain a precision field?
@@ -344,15 +353,6 @@ protected:
__precision != __format::__number_max; // The arg-id is valid?
}
- /**
- * Does the supplied precision field contain an arg-id?
- *
- * If @c true the formatter needs to call @ref __substitute_precision_arg_id.
- */
- constexpr bool __precision_needs_substitution() const noexcept {
- return __precision_as_arg && __precision != __format::__number_max;
- }
-
template <class _CharT>
_LIBCPP_HIDE_FROM_ABI constexpr const _CharT*
__parse(const _CharT* __begin, const _CharT* __end, auto& __parse_ctx) {
@@ -1041,7 +1041,7 @@ concept __utf16_or_32_character = __utf16_character<_CharT> || __utf32_character
* character.
*/
_LIBCPP_HIDE_FROM_ABI inline constexpr int __column_width_3(uint32_t __c) noexcept {
- _LIBCPP_ASSERT(__c < 0x1'0000,
+ _LIBCPP_ASSERT(__c < 0x10000,
"Use __column_width_4 or __column_width for larger values");
// clang-format off
@@ -1066,7 +1066,7 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr int __column_width_3(uint32_t __c) noexce
* 4-byte UTF-8 character.
*/
_LIBCPP_HIDE_FROM_ABI inline constexpr int __column_width_4(uint32_t __c) noexcept {
- _LIBCPP_ASSERT(__c >= 0x1'0000,
+ _LIBCPP_ASSERT(__c >= 0x10000,
"Use __column_width_3 or __column_width for smaller values");
// clang-format off
@@ -1084,7 +1084,7 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr int __column_width_4(uint32_t __c) noexce
* The general case, accepting all values.
*/
_LIBCPP_HIDE_FROM_ABI inline constexpr int __column_width(uint32_t __c) noexcept {
- if (__c < 0x1'0000)
+ if (__c < 0x10000)
return __column_width_3(__c);
return __column_width_4(__c);
@@ -1244,7 +1244,7 @@ __estimate_column_width(const _CharT* __first, const _CharT* __last,
__c -= 0xd800;
__c <<= 10;
__c += (*(__first + 1) - 0xdc00);
- __c += 0x10'000;
+ __c += 0x10000;
__result += __column_width_4(__c);
if (__result > __maximum)
@@ -1271,7 +1271,7 @@ __estimate_column_width(const _CharT* __first, const _CharT* __last,
size_t __result = 0;
while (__first != __last) {
- wchar_t __c = *__first;
+ uint32_t __c = *__first;
__result += __column_width(__c);
if (__result > __maximum)
@@ -1385,9 +1385,582 @@ __get_string_alignment(const _CharT* __first, const _CharT* __last,
}
#endif // _LIBCPP_HAS_NO_UNICODE
-} // namespace __format_spec
+/// These fields are a filter for which elements to parse.
+///
+/// They default to false so when a new field is added it needs to be opted in
+/// explicitly.
+struct __fields {
+ uint8_t __sign_ : 1 {false};
+ uint8_t __alternate_form_ : 1 {false};
+ uint8_t __zero_padding_ : 1 {false};
+ uint8_t __precision_ : 1 {false};
+ uint8_t __locale_specific_form_ : 1 {false};
+ uint8_t __type_ : 1 {false};
+};
+
+// By not placing this constant in the formatter class it's not duplicated for
+// char and wchar_t.
+inline constexpr __fields __fields_integral{
+ .__sign_ = true,
+ .__alternate_form_ = true,
+ .__zero_padding_ = true,
+ .__locale_specific_form_ = true,
+ .__type_ = true};
+inline constexpr __fields __fields_string{.__precision_ = true, .__type_ = true};
+inline constexpr __fields __fields_pointer{.__type_ = true};
+
+enum class _LIBCPP_ENUM_VIS __alignment : uint8_t {
+ /// No alignment is set in the format string.
+ __default,
+ __left,
+ __center,
+ __right,
+ __zero_padding
+};
+
+enum class _LIBCPP_ENUM_VIS __sign : uint8_t {
+ /// No sign is set in the format string.
+ ///
+ /// The sign isn't allowed for certain format-types. By using this value
+ /// it's possible to detect whether or not the user explicitly set the sign
+ /// flag. For formatting purposes it behaves the same as \ref __minus.
+ __default,
+ __minus,
+ __plus,
+ __space
+};
+
+enum class _LIBCPP_ENUM_VIS __type : uint8_t {
+ __default,
+ __string,
+ __binary_lower_case,
+ __binary_upper_case,
+ __octal,
+ __decimal,
+ __hexadecimal_lower_case,
+ __hexadecimal_upper_case,
+ __pointer,
+ __char,
+ __hexfloat_lower_case,
+ __hexfloat_upper_case,
+ __scientific_lower_case,
+ __scientific_upper_case,
+ __fixed_lower_case,
+ __fixed_upper_case,
+ __general_lower_case,
+ __general_upper_case
+};
+
+struct __std {
+ __alignment __alignment_ : 3;
+ __sign __sign_ : 2;
+ bool __alternate_form_ : 1;
+ bool __locale_specific_form_ : 1;
+ __type __type_;
+};
+
+struct __chrono {
+ __alignment __alignment_ : 3;
+ bool __weekday_name_ : 1;
+ bool __month_name_ : 1;
+};
+
+/// Contains the parsed formatting specifications.
+///
+/// This contains information for both the std-format-spec and the
+/// chrono-format-spec. This results in some unused members for both
+/// specifications. However these unused members don't increase the size
+/// of the structure.
+///
+/// This struct doesn't cross ABI boundaries so its layout doesn't need to be
+/// kept stable.
+template <class _CharT>
+struct __parsed_specifications {
+ union {
+ // The field __alignment_ is the first element in __std_ and __chrono_.
+ // This allows the code to always inspect this value regards which member
+ // of the union is the active member [class.union.general]/2.
+ //
+ // This is needed since the generic output routines handle the alignment of
+ // the output.
+ __alignment __alignment_ : 3;
+ __std __std_;
+ __chrono __chrono_;
+ };
+
+ /// The requested width.
+ ///
+ /// When the format-spec used an arg-id for this field it has already been
+ /// replaced with the value of that arg-id.
+ int32_t __width_;
+
+ /// The requested precision.
+ ///
+ /// When the format-spec used an arg-id for this field it has already been
+ /// replaced with the value of that arg-id.
+ int32_t __precision_;
+
+ _CharT __fill_;
+
+ _LIBCPP_HIDE_FROM_ABI constexpr bool __has_width() const { return __width_ > 0; }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr bool __has_precision() const { return __precision_ >= 0; }
+};
+
+// Validate the struct is small and cheap to copy since the struct is passed by
+// value in formatting functions.
+static_assert(sizeof(__parsed_specifications<char>) == 16);
+static_assert(is_trivially_copyable_v<__parsed_specifications<char>>);
+# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+static_assert(sizeof(__parsed_specifications<wchar_t>) == 16);
+static_assert(is_trivially_copyable_v<__parsed_specifications<wchar_t>>);
+# endif
+
+/// The parser for the std-format-spec.
+///
+/// Note this class is a member of std::formatter specializations. It's
+/// expected developers will create their own formatter specializations that
+/// inherit from the std::formatter specializations. This means this class
+/// must be ABI stable. To aid the stability the unused bits in the class are
+/// set to zero. That way they can be repurposed if a future revision of the
+/// Standards adds new fields to std-format-spec.
+template <class _CharT>
+class _LIBCPP_TEMPLATE_VIS __parser {
+public:
+ _LIBCPP_HIDE_FROM_ABI constexpr auto __parse(basic_format_parse_context<_CharT>& __parse_ctx, __fields __fields)
+ -> decltype(__parse_ctx.begin()) {
+
+ const _CharT* __begin = __parse_ctx.begin();
+ const _CharT* __end = __parse_ctx.end();
+ if (__begin == __end)
+ return __begin;
+
+ if (__parse_fill_align(__begin, __end) && __begin == __end)
+ return __begin;
+
+ if (__fields.__sign_ && __parse_sign(__begin) && __begin == __end)
+ return __begin;
+
+ if (__fields.__alternate_form_ && __parse_alternate_form(__begin) && __begin == __end)
+ return __begin;
+
+ if (__fields.__zero_padding_ && __parse_zero_padding(__begin) && __begin == __end)
+ return __begin;
+
+ if (__parse_width(__begin, __end, __parse_ctx) && __begin == __end)
+ return __begin;
+
+ if (__fields.__precision_ && __parse_precision(__begin, __end, __parse_ctx) && __begin == __end)
+ return __begin;
+
+ if (__fields.__locale_specific_form_ && __parse_locale_specific_form(__begin) && __begin == __end)
+ return __begin;
+
+ if (__fields.__type_) {
+ __parse_type(__begin);
+
+ // When __type_ is false the calling parser is expected to do additional
+ // parsing. In that case that parser should do the end of format string
+ // validation.
+ if (__begin != __end && *__begin != _CharT('}'))
+ __throw_format_error("The format-spec should consume the input or end with a '}'");
+ }
+
+ return __begin;
+ }
+
+ /// \returns the `__parsed_specifications` with the resolved dynamic sizes..
+ _LIBCPP_HIDE_FROM_ABI
+ __parsed_specifications<_CharT> __get_parsed_std_specifications(auto& __ctx) const {
+ return __parsed_specifications<_CharT>{
+ .__std_ =
+ __std{.__alignment_ = __alignment_,
+ .__sign_ = __sign_,
+ .__alternate_form_ = __alternate_form_,
+ .__locale_specific_form_ = __locale_specific_form_,
+ .__type_ = __type_},
+ .__width_{__get_width(__ctx)},
+ .__precision_{__get_precision(__ctx)},
+ .__fill_{__fill_}};
+ }
+
+ __alignment __alignment_ : 3 {__alignment::__default};
+ __sign __sign_ : 2 {__sign::__default};
+ bool __alternate_form_ : 1 {false};
+ bool __locale_specific_form_ : 1 {false};
+ bool __reserved_0_ : 1 {false};
+ __type __type_{__type::__default};
+
+ // These two flags are used for formatting chrono. Since the struct has
+ // padding space left it's added to this structure.
+ bool __weekday_name_ : 1 {false};
+ bool __month_name_ : 1 {false};
+
+ uint8_t __reserved_1_ : 6 {0};
+ uint8_t __reserved_2_ : 6 {0};
+ // These two flags are only used internally and not part of the
+ // __parsed_specifications. Therefore put them at the end.
+ bool __width_as_arg_ : 1 {false};
+ bool __precision_as_arg_ : 1 {false};
+
+ /// The requested width, either the value or the arg-id.
+ int32_t __width_{0};
+
+ /// The requested precision, either the value or the arg-id.
+ int32_t __precision_{-1};
+
+ // LWG 3576 will probably change this to always accept a Unicode code point
+ // To avoid changing the size with that change align the field so when it
+ // becomes 32-bit its alignment will remain the same. That also means the
+ // size will remain the same. (D2572 addresses the solution for LWG 3576.)
+ _CharT __fill_{_CharT(' ')};
+
+private:
+ _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_alignment(_CharT __c) {
+ switch (__c) {
+ case _CharT('<'):
+ __alignment_ = __alignment::__left;
+ return true;
+
+ case _CharT('^'):
+ __alignment_ = __alignment::__center;
+ return true;
+
+ case _CharT('>'):
+ __alignment_ = __alignment::__right;
+ return true;
+ }
+ return false;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_fill_align(const _CharT*& __begin, const _CharT* __end) {
+ _LIBCPP_ASSERT(__begin != __end, "when called with an empty input the function will cause "
+ "undefined behavior by evaluating data not in the input");
+ if (__begin + 1 != __end) {
+ if (__parse_alignment(*(__begin + 1))) {
+ if (*__begin == _CharT('{') || *__begin == _CharT('}'))
+ __throw_format_error("The format-spec fill field contains an invalid character");
+
+ __fill_ = *__begin;
+ __begin += 2;
+ return true;
+ }
+ }
+
+ if (!__parse_alignment(*__begin))
+ return false;
+
+ ++__begin;
+ return true;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_sign(const _CharT*& __begin) {
+ switch (*__begin) {
+ case _CharT('-'):
+ __sign_ = __sign::__minus;
+ break;
+ case _CharT('+'):
+ __sign_ = __sign::__plus;
+ break;
+ case _CharT(' '):
+ __sign_ = __sign::__space;
+ break;
+ default:
+ return false;
+ }
+ ++__begin;
+ return true;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_alternate_form(const _CharT*& __begin) {
+ if (*__begin != _CharT('#'))
+ return false;
+
+ __alternate_form_ = true;
+ ++__begin;
+ return true;
+ }
-# endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
+ _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_zero_padding(const _CharT*& __begin) {
+ if (*__begin != _CharT('0'))
+ return false;
+
+ if (__alignment_ == __alignment::__default)
+ __alignment_ = __alignment::__zero_padding;
+ ++__begin;
+ return true;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_width(const _CharT*& __begin, const _CharT* __end, auto& __parse_ctx) {
+ if (*__begin == _CharT('0'))
+ __throw_format_error("A format-spec width field shouldn't have a leading zero");
+
+ if (*__begin == _CharT('{')) {
+ __format::__parse_number_result __r = __format_spec::__parse_arg_id(++__begin, __end, __parse_ctx);
+ __width_as_arg_ = true;
+ __width_ = __r.__value;
+ __begin = __r.__ptr;
+ return true;
+ }
+
+ if (*__begin < _CharT('0') || *__begin > _CharT('9'))
+ return false;
+
+ __format::__parse_number_result __r = __format::__parse_number(__begin, __end);
+ __width_ = __r.__value;
+ _LIBCPP_ASSERT(__width_ != 0, "A zero value isn't allowed and should be impossible, "
+ "due to validations in this function");
+ __begin = __r.__ptr;
+ return true;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_precision(const _CharT*& __begin, const _CharT* __end,
+ auto& __parse_ctx) {
+ if (*__begin != _CharT('.'))
+ return false;
+
+ ++__begin;
+ if (__begin == __end)
+ __throw_format_error("End of input while parsing format-spec precision");
+
+ if (*__begin == _CharT('{')) {
+ __format::__parse_number_result __arg_id = __format_spec::__parse_arg_id(++__begin, __end, __parse_ctx);
+ __precision_as_arg_ = true;
+ __precision_ = __arg_id.__value;
+ __begin = __arg_id.__ptr;
+ return true;
+ }
+
+ if (*__begin < _CharT('0') || *__begin > _CharT('9'))
+ __throw_format_error("The format-spec precision field doesn't contain a value or arg-id");
+
+ __format::__parse_number_result __r = __format::__parse_number(__begin, __end);
+ __precision_ = __r.__value;
+ __precision_as_arg_ = false;
+ __begin = __r.__ptr;
+ return true;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_locale_specific_form(const _CharT*& __begin) {
+ if (*__begin != _CharT('L'))
+ return false;
+
+ __locale_specific_form_ = true;
+ ++__begin;
+ return true;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr void __parse_type(const _CharT*& __begin) {
+ // Determines the type. It does not validate whether the selected type is
+ // valid. Most formatters have optional fields that are only allowed for
+ // certain types. These parsers need to do validation after the type has
+ // been parsed. So its easier to implement the validation for all types in
+ // the specific parse function.
+ switch (*__begin) {
+ case 'A':
+ __type_ = __type::__hexfloat_upper_case;
+ break;
+ case 'B':
+ __type_ = __type::__binary_upper_case;
+ break;
+ case 'E':
+ __type_ = __type::__scientific_upper_case;
+ break;
+ case 'F':
+ __type_ = __type::__fixed_upper_case;
+ break;
+ case 'G':
+ __type_ = __type::__general_upper_case;
+ break;
+ case 'X':
+ __type_ = __type::__hexadecimal_upper_case;
+ break;
+ case 'a':
+ __type_ = __type::__hexfloat_lower_case;
+ break;
+ case 'b':
+ __type_ = __type::__binary_lower_case;
+ break;
+ case 'c':
+ __type_ = __type::__char;
+ break;
+ case 'd':
+ __type_ = __type::__decimal;
+ break;
+ case 'e':
+ __type_ = __type::__scientific_lower_case;
+ break;
+ case 'f':
+ __type_ = __type::__fixed_lower_case;
+ break;
+ case 'g':
+ __type_ = __type::__general_lower_case;
+ break;
+ case 'o':
+ __type_ = __type::__octal;
+ break;
+ case 'p':
+ __type_ = __type::__pointer;
+ break;
+ case 's':
+ __type_ = __type::__string;
+ break;
+ case 'x':
+ __type_ = __type::__hexadecimal_lower_case;
+ break;
+ default:
+ return;
+ }
+ ++__begin;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ int32_t __get_width(auto& __ctx) const {
+ if (!__width_as_arg_)
+ return __width_;
+
+ int32_t __result = __format_spec::__substitute_arg_id(__ctx.arg(__width_));
+ if (__result == 0)
+ __throw_format_error("A format-spec width field replacement should have a positive value");
+ return __result;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ int32_t __get_precision(auto& __ctx) const {
+ if (!__precision_as_arg_)
+ return __precision_;
+
+ return __format_spec::__substitute_arg_id(__ctx.arg(__precision_));
+ }
+};
+
+// Validates whether the reserved bitfields don't change the size.
+static_assert(sizeof(__parser<char>) == 16);
+# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+static_assert(sizeof(__parser<wchar_t>) == 16);
+# endif
+
+_LIBCPP_HIDE_FROM_ABI constexpr void __process_display_type_string(__format_spec::__type __type) {
+ switch (__type) {
+ case __format_spec::__type::__default:
+ case __format_spec::__type::__string:
+ break;
+
+ default:
+ std::__throw_format_error("The format-spec type has a type not supported for a string argument");
+ }
+}
+
+template <class _CharT>
+_LIBCPP_HIDE_FROM_ABI constexpr void __process_display_type_bool_string(__parser<_CharT>& __parser) {
+ if (__parser.__sign_ != __sign::__default)
+ std::__throw_format_error("A sign field isn't allowed in this format-spec");
+
+ if (__parser.__alternate_form_)
+ std::__throw_format_error("An alternate form field isn't allowed in this format-spec");
+
+ if (__parser.__alignment_ == __alignment::__zero_padding)
+ std::__throw_format_error("A zero-padding field isn't allowed in this format-spec");
+
+ if (__parser.__alignment_ == __alignment::__default)
+ __parser.__alignment_ = __alignment::__left;
+}
+
+template <class _CharT>
+_LIBCPP_HIDE_FROM_ABI constexpr void __process_display_type_char(__parser<_CharT>& __parser) {
+ __format_spec::__process_display_type_bool_string(__parser);
+}
+
+template <class _CharT>
+_LIBCPP_HIDE_FROM_ABI constexpr void __process_display_type_integer(__parser<_CharT>& __parser) {
+ if (__parser.__alignment_ == __alignment::__default)
+ __parser.__alignment_ = __alignment::__right;
+}
+
+template <class _CharT>
+_LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_bool(__parser<_CharT>& __parser) {
+ switch (__parser.__type_) {
+ case __format_spec::__type::__default:
+ __parser.__type_ = __format_spec::__type::__string;
+ [[fallthrough]];
+ case __format_spec::__type::__string:
+ __format_spec::__process_display_type_bool_string(__parser);
+ break;
+
+ case __format_spec::__type::__binary_lower_case:
+ case __format_spec::__type::__binary_upper_case:
+ case __format_spec::__type::__octal:
+ case __format_spec::__type::__decimal:
+ case __format_spec::__type::__hexadecimal_lower_case:
+ case __format_spec::__type::__hexadecimal_upper_case:
+ __process_display_type_integer(__parser);
+ break;
+
+ default:
+ std::__throw_format_error("The format-spec type has a type not supported for a bool argument");
+ }
+}
+
+template <class _CharT>
+_LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_char(__parser<_CharT>& __parser) {
+ switch (__parser.__type_) {
+ case __format_spec::__type::__default:
+ __parser.__type_ = __format_spec::__type::__char;
+ [[fallthrough]];
+ case __format_spec::__type::__char:
+ __format_spec::__process_display_type_char(__parser);
+ break;
+
+ case __format_spec::__type::__binary_lower_case:
+ case __format_spec::__type::__binary_upper_case:
+ case __format_spec::__type::__octal:
+ case __format_spec::__type::__decimal:
+ case __format_spec::__type::__hexadecimal_lower_case:
+ case __format_spec::__type::__hexadecimal_upper_case:
+ __format_spec::__process_display_type_integer(__parser);
+ break;
+
+ default:
+ std::__throw_format_error("The format-spec type has a type not supported for a char argument");
+ }
+}
+
+template <class _CharT>
+_LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_integer(__parser<_CharT>& __parser) {
+ switch (__parser.__type_) {
+ case __format_spec::__type::__default:
+ __parser.__type_ = __format_spec::__type::__decimal;
+ [[fallthrough]];
+ case __format_spec::__type::__binary_lower_case:
+ case __format_spec::__type::__binary_upper_case:
+ case __format_spec::__type::__octal:
+ case __format_spec::__type::__decimal:
+ case __format_spec::__type::__hexadecimal_lower_case:
+ case __format_spec::__type::__hexadecimal_upper_case:
+ __format_spec::__process_display_type_integer(__parser);
+ break;
+
+ case __format_spec::__type::__char:
+ __format_spec::__process_display_type_char(__parser);
+ break;
+
+ default:
+ std::__throw_format_error("The format-spec type has a type not supported for an integer argument");
+ }
+}
+
+_LIBCPP_HIDE_FROM_ABI constexpr void __process_display_type_pointer(__format_spec::__type __type) {
+ switch (__type) {
+ case __format_spec::__type::__default:
+ case __format_spec::__type::__pointer:
+ break;
+
+ default:
+ std::__throw_format_error("The format-spec type has a type not supported for a pointer argument");
+ }
+}
+
+} // namespace __format_spec
#endif //_LIBCPP_STD_VER > 17
diff --git a/libcxx/include/__functional/binary_function.h b/libcxx/include/__functional/binary_function.h
index 8ca7b06662ae..fdedb8b177da 100644
--- a/libcxx/include/__functional/binary_function.h
+++ b/libcxx/include/__functional/binary_function.h
@@ -13,19 +13,42 @@
#include <__config>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
+#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION)
+
template <class _Arg1, class _Arg2, class _Result>
-struct _LIBCPP_TEMPLATE_VIS binary_function
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 binary_function
{
typedef _Arg1 first_argument_type;
typedef _Arg2 second_argument_type;
typedef _Result result_type;
};
+#endif // _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION)
+
+template <class _Arg1, class _Arg2, class _Result> struct __binary_function_keep_layout_base {
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+ using first_argument_type _LIBCPP_DEPRECATED_IN_CXX17 = _Arg1;
+ using second_argument_type _LIBCPP_DEPRECATED_IN_CXX17 = _Arg2;
+ using result_type _LIBCPP_DEPRECATED_IN_CXX17 = _Result;
+#endif
+};
+
+#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION)
+_LIBCPP_DIAGNOSTIC_PUSH
+_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wdeprecated-declarations")
+template <class _Arg1, class _Arg2, class _Result>
+using __binary_function = binary_function<_Arg1, _Arg2, _Result>;
+_LIBCPP_DIAGNOSTIC_POP
+#else
+template <class _Arg1, class _Arg2, class _Result>
+using __binary_function = __binary_function_keep_layout_base<_Arg1, _Arg2, _Result>;
+#endif
+
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___FUNCTIONAL_BINARY_FUNCTION_H
diff --git a/libcxx/include/__functional/binary_negate.h b/libcxx/include/__functional/binary_negate.h
index 4fc3f1ba2875..c4977f4ebe12 100644
--- a/libcxx/include/__functional/binary_negate.h
+++ b/libcxx/include/__functional/binary_negate.h
@@ -14,7 +14,7 @@
#include <__functional/binary_function.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -23,9 +23,9 @@ _LIBCPP_BEGIN_NAMESPACE_STD
template <class _Predicate>
class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 binary_negate
- : public binary_function<typename _Predicate::first_argument_type,
- typename _Predicate::second_argument_type,
- bool>
+ : public __binary_function<typename _Predicate::first_argument_type,
+ typename _Predicate::second_argument_type,
+ bool>
{
_Predicate __pred_;
public:
diff --git a/libcxx/include/__functional/bind.h b/libcxx/include/__functional/bind.h
index 11a51e5957ee..d1cbbb3d916e 100644
--- a/libcxx/include/__functional/bind.h
+++ b/libcxx/include/__functional/bind.h
@@ -18,16 +18,16 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
template<class _Tp>
struct is_bind_expression : _If<
- _IsSame<_Tp, typename __uncvref<_Tp>::type>::value,
+ _IsSame<_Tp, __uncvref_t<_Tp> >::value,
false_type,
- is_bind_expression<typename __uncvref<_Tp>::type>
+ is_bind_expression<__uncvref_t<_Tp> >
> {};
#if _LIBCPP_STD_VER > 14
@@ -37,9 +37,9 @@ inline constexpr size_t is_bind_expression_v = is_bind_expression<_Tp>::value;
template<class _Tp>
struct is_placeholder : _If<
- _IsSame<_Tp, typename __uncvref<_Tp>::type>::value,
+ _IsSame<_Tp, __uncvref_t<_Tp> >::value,
integral_constant<int, 0>,
- is_placeholder<typename __uncvref<_Tp>::type>
+ is_placeholder<__uncvref_t<_Tp> >
> {};
#if _LIBCPP_STD_VER > 14
@@ -264,10 +264,7 @@ __apply_functor(_Fp& __f, _BoundArgs& __bound_args, __tuple_indices<_Indx...>,
}
template<class _Fp, class ..._BoundArgs>
-class __bind
-#if _LIBCPP_STD_VER <= 17 || !defined(_LIBCPP_ABI_NO_BINDER_BASES)
- : public __weak_result_type<typename decay<_Fp>::type>
-#endif
+class __bind : public __weak_result_type<typename decay<_Fp>::type>
{
protected:
typedef typename decay<_Fp>::type _Fd;
diff --git a/libcxx/include/__functional/bind_back.h b/libcxx/include/__functional/bind_back.h
index a0089e1fb090..f0a6e49875a3 100644
--- a/libcxx/include/__functional/bind_back.h
+++ b/libcxx/include/__functional/bind_back.h
@@ -19,7 +19,7 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -31,12 +31,11 @@ struct __bind_back_op;
template <size_t _NBound, size_t ..._Ip>
struct __bind_back_op<_NBound, index_sequence<_Ip...>> {
- template <class _Fn, class _Bound, class ..._Args>
- _LIBCPP_HIDE_FROM_ABI
- constexpr auto operator()(_Fn&& __f, _Bound&& __bound, _Args&& ...__args) const
- noexcept(noexcept(_VSTD::invoke(_VSTD::forward<_Fn>(__f), _VSTD::forward<_Args>(__args)..., _VSTD::get<_Ip>(_VSTD::forward<_Bound>(__bound))...)))
- -> decltype( _VSTD::invoke(_VSTD::forward<_Fn>(__f), _VSTD::forward<_Args>(__args)..., _VSTD::get<_Ip>(_VSTD::forward<_Bound>(__bound))...))
- { return _VSTD::invoke(_VSTD::forward<_Fn>(__f), _VSTD::forward<_Args>(__args)..., _VSTD::get<_Ip>(_VSTD::forward<_Bound>(__bound))...); }
+ template <class _Fn, class _BoundArgs, class... _Args>
+ _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Fn&& __f, _BoundArgs&& __bound_args, _Args&&... __args) const
+ noexcept(noexcept(_VSTD::invoke(_VSTD::forward<_Fn>(__f), _VSTD::forward<_Args>(__args)..., _VSTD::get<_Ip>(_VSTD::forward<_BoundArgs>(__bound_args))...)))
+ -> decltype( _VSTD::invoke(_VSTD::forward<_Fn>(__f), _VSTD::forward<_Args>(__args)..., _VSTD::get<_Ip>(_VSTD::forward<_BoundArgs>(__bound_args))...))
+ { return _VSTD::invoke(_VSTD::forward<_Fn>(__f), _VSTD::forward<_Args>(__args)..., _VSTD::get<_Ip>(_VSTD::forward<_BoundArgs>(__bound_args))...); }
};
template <class _Fn, class _BoundArgs>
diff --git a/libcxx/include/__functional/bind_front.h b/libcxx/include/__functional/bind_front.h
index 31397ec5400d..22fb3a69dc75 100644
--- a/libcxx/include/__functional/bind_front.h
+++ b/libcxx/include/__functional/bind_front.h
@@ -13,11 +13,11 @@
#include <__config>
#include <__functional/invoke.h>
#include <__functional/perfect_forward.h>
+#include <__utility/forward.h>
#include <type_traits>
-#include <utility>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__functional/binder1st.h b/libcxx/include/__functional/binder1st.h
index 5dd8f5cf0155..dea22c70e1f2 100644
--- a/libcxx/include/__functional/binder1st.h
+++ b/libcxx/include/__functional/binder1st.h
@@ -14,7 +14,7 @@
#include <__functional/unary_function.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -23,8 +23,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
template <class __Operation>
class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 binder1st
- : public unary_function<typename __Operation::second_argument_type,
- typename __Operation::result_type>
+ : public __unary_function<typename __Operation::second_argument_type, typename __Operation::result_type>
{
protected:
__Operation op;
diff --git a/libcxx/include/__functional/binder2nd.h b/libcxx/include/__functional/binder2nd.h
index 3ed5f5bf4540..c98a146b6a66 100644
--- a/libcxx/include/__functional/binder2nd.h
+++ b/libcxx/include/__functional/binder2nd.h
@@ -14,7 +14,7 @@
#include <__functional/unary_function.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -23,8 +23,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
template <class __Operation>
class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 binder2nd
- : public unary_function<typename __Operation::first_argument_type,
- typename __Operation::result_type>
+ : public __unary_function<typename __Operation::first_argument_type, typename __Operation::result_type>
{
protected:
__Operation op;
diff --git a/libcxx/include/__functional/boyer_moore_searcher.h b/libcxx/include/__functional/boyer_moore_searcher.h
new file mode 100644
index 000000000000..20e554408ff0
--- /dev/null
+++ b/libcxx/include/__functional/boyer_moore_searcher.h
@@ -0,0 +1,313 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___FUNCTIONAL_BOYER_MOORE_SEARCHER_H
+#define _LIBCPP___FUNCTIONAL_BOYER_MOORE_SEARCHER_H
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#include <__algorithm/fill_n.h>
+#include <__config>
+#include <__functional/hash.h>
+#include <__functional/operations.h>
+#include <__iterator/distance.h>
+#include <__iterator/iterator_traits.h>
+#include <__memory/shared_ptr.h>
+#include <__utility/pair.h>
+#include <array>
+#include <unordered_map>
+#include <vector>
+
+#if _LIBCPP_STD_VER > 14
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Key,
+ class _Value,
+ class _Hash,
+ class _BinaryPredicate,
+ bool /*useArray*/>
+class _BMSkipTable;
+
+// General case for BM data searching; use a map
+template <class _Key,
+ class _Value,
+ class _Hash,
+ class _BinaryPredicate>
+class _BMSkipTable<_Key, _Value, _Hash, _BinaryPredicate, false> {
+private:
+ using value_type = _Value;
+ using key_type = _Key;
+
+ const value_type __default_value_;
+ unordered_map<_Key, _Value, _Hash, _BinaryPredicate> __table_;
+
+public:
+ _LIBCPP_HIDE_FROM_ABI
+ explicit _BMSkipTable(size_t __sz, value_type __default_value, _Hash __hash, _BinaryPredicate __pred)
+ : __default_value_(__default_value),
+ __table_(__sz, __hash, __pred) {}
+
+ _LIBCPP_HIDE_FROM_ABI void insert(const key_type& __key, value_type __val) {
+ __table_[__key] = __val;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI value_type operator[](const key_type& __key) const {
+ auto __it = __table_.find(__key);
+ return __it == __table_.end() ? __default_value_ : __it->second;
+ }
+};
+
+// Special case small numeric values; use an array
+template <class _Key,
+ class _Value,
+ class _Hash,
+ class _BinaryPredicate>
+class _BMSkipTable<_Key, _Value, _Hash, _BinaryPredicate, true> {
+private:
+ using value_type = _Value;
+ using key_type = _Key;
+
+ using unsigned_key_type = make_unsigned_t<key_type>;
+ std::array<value_type, 256> __table_;
+ static_assert(numeric_limits<unsigned_key_type>::max() < 256);
+
+public:
+ _LIBCPP_HIDE_FROM_ABI explicit _BMSkipTable(size_t, value_type __default_value, _Hash, _BinaryPredicate) {
+ std::fill_n(__table_.data(), __table_.size(), __default_value);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI void insert(key_type __key, value_type __val) {
+ __table_[static_cast<unsigned_key_type>(__key)] = __val;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI value_type operator[](key_type __key) const {
+ return __table_[static_cast<unsigned_key_type>(__key)];
+ }
+};
+
+template <class _RandomAccessIterator1,
+ class _Hash = hash<typename iterator_traits<_RandomAccessIterator1>::value_type>,
+ class _BinaryPredicate = equal_to<>>
+class _LIBCPP_TEMPLATE_VIS boyer_moore_searcher {
+private:
+ using difference_type = typename std::iterator_traits<_RandomAccessIterator1>::difference_type;
+ using value_type = typename std::iterator_traits<_RandomAccessIterator1>::value_type;
+ using __skip_table_type = _BMSkipTable<value_type,
+ difference_type,
+ _Hash,
+ _BinaryPredicate,
+ is_integral_v<value_type>
+ && sizeof(value_type) == 1
+ && is_same_v<_Hash, hash<value_type>>
+ && is_same_v<_BinaryPredicate, equal_to<>>>;
+
+public:
+ boyer_moore_searcher(_RandomAccessIterator1 __first,
+ _RandomAccessIterator1 __last,
+ _Hash __hash = _Hash(),
+ _BinaryPredicate __pred = _BinaryPredicate())
+ : __first_(__first),
+ __last_(__last),
+ __pred_(__pred),
+ __pattern_length_(__last - __first),
+ __skip_table_(std::make_shared<__skip_table_type>(__pattern_length_, -1, __hash, __pred_)),
+ __suffix_(std::__allocate_shared_unbounded_array<difference_type[]>(
+ allocator<difference_type>(), __pattern_length_ + 1)) {
+ difference_type __i = 0;
+ while (__first != __last) {
+ __skip_table_->insert(*__first, __i);
+ ++__first;
+ ++__i;
+ }
+ __build_suffix_table(__first_, __last_, __pred_);
+ }
+
+ template <class _RandomAccessIterator2>
+ pair<_RandomAccessIterator2, _RandomAccessIterator2>
+ operator()(_RandomAccessIterator2 __first, _RandomAccessIterator2 __last) const {
+ static_assert(__is_same_uncvref<typename iterator_traits<_RandomAccessIterator1>::value_type,
+ typename iterator_traits<_RandomAccessIterator2>::value_type>::value,
+ "Corpus and Pattern iterators must point to the same type");
+ if (__first == __last)
+ return std::make_pair(__last, __last);
+ if (__first_ == __last_)
+ return std::make_pair(__first, __first);
+
+ if (__pattern_length_ > (__last - __first))
+ return std::make_pair(__last, __last);
+ return __search(__first, __last);
+ }
+
+private:
+ _RandomAccessIterator1 __first_;
+ _RandomAccessIterator1 __last_;
+ _BinaryPredicate __pred_;
+ difference_type __pattern_length_;
+ shared_ptr<__skip_table_type> __skip_table_;
+ shared_ptr<difference_type[]> __suffix_;
+
+ template <class _RandomAccessIterator2>
+ pair<_RandomAccessIterator2, _RandomAccessIterator2>
+ __search(_RandomAccessIterator2 __f, _RandomAccessIterator2 __l) const {
+ _RandomAccessIterator2 __current = __f;
+ const _RandomAccessIterator2 __last = __l - __pattern_length_;
+ const __skip_table_type& __skip_table = *__skip_table_;
+
+ while (__current <= __last) {
+ difference_type __j = __pattern_length_;
+ while (__pred_(__first_[__j - 1], __current[__j - 1])) {
+ --__j;
+ if (__j == 0)
+ return std::make_pair(__current, __current + __pattern_length_);
+ }
+
+ difference_type __k = __skip_table[__current[__j - 1]];
+ difference_type __m = __j - __k - 1;
+ if (__k < __j && __m > __suffix_[__j])
+ __current += __m;
+ else
+ __current += __suffix_[__j];
+ }
+ return std::make_pair(__l, __l);
+ }
+
+ template <class _Iterator, class _Container>
+ void __compute_bm_prefix(_Iterator __first, _Iterator __last, _BinaryPredicate __pred, _Container& __prefix) {
+ const size_t __count = __last - __first;
+
+ __prefix[0] = 0;
+ size_t __k = 0;
+
+ for (size_t __i = 1; __i != __count; ++__i) {
+ while (__k > 0 && !__pred(__first[__k], __first[__i]))
+ __k = __prefix[__k - 1];
+
+ if (__pred(__first[__k], __first[__i]))
+ ++__k;
+ __prefix[__i] = __k;
+ }
+ }
+
+ void __build_suffix_table(_RandomAccessIterator1 __first, _RandomAccessIterator1 __last, _BinaryPredicate __pred) {
+ const size_t __count = __last - __first;
+
+ if (__count == 0)
+ return;
+
+ vector<difference_type> __scratch(__count);
+
+ __compute_bm_prefix(__first, __last, __pred, __scratch);
+ for (size_t __i = 0; __i <= __count; ++__i)
+ __suffix_[__i] = __count - __scratch[__count - 1];
+
+ using _ReverseIter = reverse_iterator<_RandomAccessIterator1>;
+ __compute_bm_prefix(_ReverseIter(__last), _ReverseIter(__first), __pred, __scratch);
+
+ for (size_t __i = 0; __i != __count; ++__i) {
+ const size_t __j = __count - __scratch[__i];
+ const difference_type __k = __i - __scratch[__i] + 1;
+
+ if (__suffix_[__j] > __k)
+ __suffix_[__j] = __k;
+ }
+ }
+};
+
+template <class _RandomAccessIterator1,
+ class _Hash = hash<typename iterator_traits<_RandomAccessIterator1>::value_type>,
+ class _BinaryPredicate = equal_to<>>
+class _LIBCPP_TEMPLATE_VIS boyer_moore_horspool_searcher {
+private:
+ using difference_type = typename iterator_traits<_RandomAccessIterator1>::difference_type;
+ using value_type = typename iterator_traits<_RandomAccessIterator1>::value_type;
+ using __skip_table_type = _BMSkipTable<value_type,
+ difference_type,
+ _Hash,
+ _BinaryPredicate,
+ is_integral_v<value_type>
+ && sizeof(value_type) == 1
+ && is_same_v<_Hash, hash<value_type>>
+ && is_same_v<_BinaryPredicate, equal_to<>>>;
+public:
+ boyer_moore_horspool_searcher(_RandomAccessIterator1 __first,
+ _RandomAccessIterator1 __last,
+ _Hash __hash = _Hash(),
+ _BinaryPredicate __pred = _BinaryPredicate())
+ : __first_(__first),
+ __last_(__last),
+ __pred_(__pred),
+ __pattern_length_(__last - __first),
+ __skip_table_(std::make_shared<__skip_table_type>(__pattern_length_, __pattern_length_, __hash, __pred_)) {
+ if (__first == __last)
+ return;
+ --__last;
+ difference_type __i = 0;
+ while (__first != __last) {
+ __skip_table_->insert(*__first, __pattern_length_ - 1 - __i);
+ ++__first;
+ ++__i;
+ }
+ }
+
+ template <class _RandomAccessIterator2>
+ pair<_RandomAccessIterator2, _RandomAccessIterator2>
+ operator()(_RandomAccessIterator2 __first, _RandomAccessIterator2 __last) const {
+ static_assert(__is_same_uncvref<typename std::iterator_traits<_RandomAccessIterator1>::value_type,
+ typename std::iterator_traits<_RandomAccessIterator2>::value_type>::value,
+ "Corpus and Pattern iterators must point to the same type");
+ if (__first == __last)
+ return std::make_pair(__last, __last);
+ if (__first_ == __last_)
+ return std::make_pair(__first, __first);
+
+ if (__pattern_length_ > __last - __first)
+ return std::make_pair(__last, __last);
+
+ return __search(__first, __last);
+ }
+
+private:
+ _RandomAccessIterator1 __first_;
+ _RandomAccessIterator1 __last_;
+ _BinaryPredicate __pred_;
+ difference_type __pattern_length_;
+ shared_ptr<__skip_table_type> __skip_table_;
+
+ template <class _RandomAccessIterator2>
+ pair<_RandomAccessIterator2, _RandomAccessIterator2>
+ __search(_RandomAccessIterator2 __f, _RandomAccessIterator2 __l) const {
+ _RandomAccessIterator2 __current = __f;
+ const _RandomAccessIterator2 __last = __l - __pattern_length_;
+ const __skip_table_type& __skip_table = *__skip_table_;
+
+ while (__current <= __last) {
+ difference_type __j = __pattern_length_;
+ while (__pred_(__first_[__j - 1], __current[__j - 1])) {
+ --__j;
+ if (__j == 0)
+ return std::make_pair(__current, __current + __pattern_length_);
+ }
+ __current += __skip_table[__current[__pattern_length_ - 1]];
+ }
+ return std::make_pair(__l, __l);
+ }
+};
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP_STD_VER > 14
+
+#endif // _LIBCPP___FUNCTIONAL_BOYER_MOORE_SEARCHER_H
diff --git a/libcxx/include/__functional/compose.h b/libcxx/include/__functional/compose.h
index d9d75875c2a5..25213f28b1f2 100644
--- a/libcxx/include/__functional/compose.h
+++ b/libcxx/include/__functional/compose.h
@@ -17,7 +17,7 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__functional/default_searcher.h b/libcxx/include/__functional/default_searcher.h
index 1acbc1883afc..05fb23d7c3c4 100644
--- a/libcxx/include/__functional/default_searcher.h
+++ b/libcxx/include/__functional/default_searcher.h
@@ -14,10 +14,10 @@
#include <__config>
#include <__functional/operations.h>
#include <__iterator/iterator_traits.h>
-#include <utility>
+#include <__utility/pair.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__functional/function.h b/libcxx/include/__functional/function.h
index 6bb7eb7e8a24..312443b67c3b 100644
--- a/libcxx/include/__functional/function.h
+++ b/libcxx/include/__functional/function.h
@@ -10,8 +10,8 @@
#ifndef _LIBCPP___FUNCTIONAL_FUNCTION_H
#define _LIBCPP___FUNCTIONAL_FUNCTION_H
+#include <__assert>
#include <__config>
-#include <__debug>
#include <__functional/binary_function.h>
#include <__functional/invoke.h>
#include <__functional/unary_function.h>
@@ -20,19 +20,23 @@
#include <__memory/allocator_traits.h>
#include <__memory/compressed_pair.h>
#include <__memory/shared_ptr.h>
+#include <__utility/forward.h>
+#include <__utility/move.h>
+#include <__utility/swap.h>
#include <exception>
#include <memory> // TODO: replace with <__memory/__builtin_new_allocator.h>
#include <type_traits>
-#include <utility>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
// bad_function_call
+_LIBCPP_DIAGNOSTIC_PUSH
+_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wweak-vtables")
class _LIBCPP_EXCEPTION_ABI bad_function_call
: public exception
{
@@ -50,6 +54,7 @@ public:
virtual const char* what() const _NOEXCEPT;
#endif
};
+_LIBCPP_DIAGNOSTIC_POP
_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
void __throw_bad_function_call()
@@ -80,7 +85,7 @@ struct __maybe_derive_from_unary_function
template<class _Rp, class _A1>
struct __maybe_derive_from_unary_function<_Rp(_A1)>
- : public unary_function<_A1, _Rp>
+ : public __unary_function<_A1, _Rp>
{
};
@@ -91,7 +96,7 @@ struct __maybe_derive_from_binary_function
template<class _Rp, class _A1, class _A2>
struct __maybe_derive_from_binary_function<_Rp(_A1, _A2)>
- : public binary_function<_A1, _A2, _Rp>
+ : public __binary_function<_A1, _A2, _Rp>
{
};
@@ -951,10 +956,8 @@ public:
template<class _Rp, class ..._ArgTypes>
class _LIBCPP_TEMPLATE_VIS function<_Rp(_ArgTypes...)>
-#if _LIBCPP_STD_VER <= 17 || !defined(_LIBCPP_ABI_NO_BINDER_BASES)
: public __function::__maybe_derive_from_unary_function<_Rp(_ArgTypes...)>,
public __function::__maybe_derive_from_binary_function<_Rp(_ArgTypes...)>
-#endif
{
#ifndef _LIBCPP_ABI_OPTIMIZED_FUNCTION
typedef __function::__value_func<_Rp(_ArgTypes...)> __func;
@@ -1237,7 +1240,7 @@ void
swap(function<_Rp(_ArgTypes...)>& __x, function<_Rp(_ArgTypes...)>& __y) _NOEXCEPT
{return __x.swap(__y);}
-#else // _LIBCPP_CXX03_LANG
+#elif defined(_LIBCPP_ENABLE_CXX03_FUNCTION)
namespace __function {
@@ -2803,7 +2806,7 @@ void
swap(function<_Fp>& __x, function<_Fp>& __y)
{return __x.swap(__y);}
-#endif
+#endif // _LIBCPP_CXX03_LANG
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__functional/hash.h b/libcxx/include/__functional/hash.h
index de0c161f47ec..8a11931288cf 100644
--- a/libcxx/include/__functional/hash.h
+++ b/libcxx/include/__functional/hash.h
@@ -23,7 +23,7 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -265,18 +265,10 @@ __murmur2_or_cityhash<_Size, 64>::operator()(const void* __key, _Size __len)
template <class _Tp, size_t = sizeof(_Tp) / sizeof(size_t)>
struct __scalar_hash;
-_LIBCPP_SUPPRESS_DEPRECATED_PUSH
template <class _Tp>
struct __scalar_hash<_Tp, 0>
-#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
- : public unary_function<_Tp, size_t>
-#endif
+ : public __unary_function<_Tp, size_t>
{
-_LIBCPP_SUPPRESS_DEPRECATED_POP
-#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
- _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
- _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp argument_type;
-#endif
_LIBCPP_INLINE_VISIBILITY
size_t operator()(_Tp __v) const _NOEXCEPT
{
@@ -291,18 +283,10 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP
}
};
-_LIBCPP_SUPPRESS_DEPRECATED_PUSH
template <class _Tp>
struct __scalar_hash<_Tp, 1>
-#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
- : public unary_function<_Tp, size_t>
-#endif
+ : public __unary_function<_Tp, size_t>
{
-_LIBCPP_SUPPRESS_DEPRECATED_POP
-#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
- _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
- _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp argument_type;
-#endif
_LIBCPP_INLINE_VISIBILITY
size_t operator()(_Tp __v) const _NOEXCEPT
{
@@ -316,18 +300,10 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP
}
};
-_LIBCPP_SUPPRESS_DEPRECATED_PUSH
template <class _Tp>
struct __scalar_hash<_Tp, 2>
-#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
- : public unary_function<_Tp, size_t>
-#endif
+ : public __unary_function<_Tp, size_t>
{
-_LIBCPP_SUPPRESS_DEPRECATED_POP
-#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
- _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
- _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp argument_type;
-#endif
_LIBCPP_INLINE_VISIBILITY
size_t operator()(_Tp __v) const _NOEXCEPT
{
@@ -345,18 +321,10 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP
}
};
-_LIBCPP_SUPPRESS_DEPRECATED_PUSH
template <class _Tp>
struct __scalar_hash<_Tp, 3>
-#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
- : public unary_function<_Tp, size_t>
-#endif
+ : public __unary_function<_Tp, size_t>
{
-_LIBCPP_SUPPRESS_DEPRECATED_POP
-#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
- _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
- _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp argument_type;
-#endif
_LIBCPP_INLINE_VISIBILITY
size_t operator()(_Tp __v) const _NOEXCEPT
{
@@ -375,18 +343,10 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP
}
};
-_LIBCPP_SUPPRESS_DEPRECATED_PUSH
template <class _Tp>
struct __scalar_hash<_Tp, 4>
-#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
- : public unary_function<_Tp, size_t>
-#endif
+ : public __unary_function<_Tp, size_t>
{
-_LIBCPP_SUPPRESS_DEPRECATED_POP
-#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
- _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
- _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp argument_type;
-#endif
_LIBCPP_INLINE_VISIBILITY
size_t operator()(_Tp __v) const _NOEXCEPT
{
@@ -418,18 +378,10 @@ inline size_t __hash_combine(size_t __lhs, size_t __rhs) _NOEXCEPT {
return _HashT()(__p);
}
-_LIBCPP_SUPPRESS_DEPRECATED_PUSH
template<class _Tp>
struct _LIBCPP_TEMPLATE_VIS hash<_Tp*>
-#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
- : public unary_function<_Tp*, size_t>
-#endif
+ : public __unary_function<_Tp*, size_t>
{
-_LIBCPP_SUPPRESS_DEPRECATED_POP
-#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
- _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
- _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp* argument_type;
-#endif
_LIBCPP_INLINE_VISIBILITY
size_t operator()(_Tp* __v) const _NOEXCEPT
{
@@ -443,234 +395,118 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP
}
};
-_LIBCPP_SUPPRESS_DEPRECATED_PUSH
template <>
struct _LIBCPP_TEMPLATE_VIS hash<bool>
-#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
- : public unary_function<bool, size_t>
-#endif
+ : public __unary_function<bool, size_t>
{
-_LIBCPP_SUPPRESS_DEPRECATED_POP
-#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
- _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
- _LIBCPP_DEPRECATED_IN_CXX17 typedef bool argument_type;
-#endif
_LIBCPP_INLINE_VISIBILITY
size_t operator()(bool __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
};
-_LIBCPP_SUPPRESS_DEPRECATED_PUSH
template <>
struct _LIBCPP_TEMPLATE_VIS hash<char>
-#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
- : public unary_function<char, size_t>
-#endif
+ : public __unary_function<char, size_t>
{
-_LIBCPP_SUPPRESS_DEPRECATED_POP
-#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
- _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
- _LIBCPP_DEPRECATED_IN_CXX17 typedef char argument_type;
-#endif
_LIBCPP_INLINE_VISIBILITY
size_t operator()(char __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
};
-_LIBCPP_SUPPRESS_DEPRECATED_PUSH
template <>
struct _LIBCPP_TEMPLATE_VIS hash<signed char>
-#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
- : public unary_function<signed char, size_t>
-#endif
+ : public __unary_function<signed char, size_t>
{
-_LIBCPP_SUPPRESS_DEPRECATED_POP
-#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
- _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
- _LIBCPP_DEPRECATED_IN_CXX17 typedef signed char argument_type;
-#endif
_LIBCPP_INLINE_VISIBILITY
size_t operator()(signed char __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
};
-_LIBCPP_SUPPRESS_DEPRECATED_PUSH
template <>
struct _LIBCPP_TEMPLATE_VIS hash<unsigned char>
-#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
- : public unary_function<unsigned char, size_t>
-#endif
+ : public __unary_function<unsigned char, size_t>
{
-_LIBCPP_SUPPRESS_DEPRECATED_POP
-#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
- _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
- _LIBCPP_DEPRECATED_IN_CXX17 typedef unsigned char argument_type;
-#endif
_LIBCPP_INLINE_VISIBILITY
size_t operator()(unsigned char __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
};
#ifndef _LIBCPP_HAS_NO_CHAR8_T
-_LIBCPP_SUPPRESS_DEPRECATED_PUSH
template <>
struct _LIBCPP_TEMPLATE_VIS hash<char8_t>
-#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
- : public unary_function<char8_t, size_t>
-#endif
+ : public __unary_function<char8_t, size_t>
{
-_LIBCPP_SUPPRESS_DEPRECATED_POP
-#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
- _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
- _LIBCPP_DEPRECATED_IN_CXX17 typedef char8_t argument_type;
-#endif
_LIBCPP_INLINE_VISIBILITY
size_t operator()(char8_t __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
};
#endif // !_LIBCPP_HAS_NO_CHAR8_T
-#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
-
-_LIBCPP_SUPPRESS_DEPRECATED_PUSH
template <>
struct _LIBCPP_TEMPLATE_VIS hash<char16_t>
-#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
- : public unary_function<char16_t, size_t>
-#endif
+ : public __unary_function<char16_t, size_t>
{
-_LIBCPP_SUPPRESS_DEPRECATED_POP
-#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
- _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
- _LIBCPP_DEPRECATED_IN_CXX17 typedef char16_t argument_type;
-#endif
_LIBCPP_INLINE_VISIBILITY
size_t operator()(char16_t __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
};
-_LIBCPP_SUPPRESS_DEPRECATED_PUSH
template <>
struct _LIBCPP_TEMPLATE_VIS hash<char32_t>
-#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
- : public unary_function<char32_t, size_t>
-#endif
+ : public __unary_function<char32_t, size_t>
{
-_LIBCPP_SUPPRESS_DEPRECATED_POP
-#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
- _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
- _LIBCPP_DEPRECATED_IN_CXX17 typedef char32_t argument_type;
-#endif
_LIBCPP_INLINE_VISIBILITY
size_t operator()(char32_t __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
};
-#endif // _LIBCPP_HAS_NO_UNICODE_CHARS
-
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-_LIBCPP_SUPPRESS_DEPRECATED_PUSH
template <>
struct _LIBCPP_TEMPLATE_VIS hash<wchar_t>
-#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
- : public unary_function<wchar_t, size_t>
-#endif
+ : public __unary_function<wchar_t, size_t>
{
-_LIBCPP_SUPPRESS_DEPRECATED_POP
-#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
- _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
- _LIBCPP_DEPRECATED_IN_CXX17 typedef wchar_t argument_type;
-#endif
_LIBCPP_INLINE_VISIBILITY
size_t operator()(wchar_t __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
};
#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
-_LIBCPP_SUPPRESS_DEPRECATED_PUSH
template <>
struct _LIBCPP_TEMPLATE_VIS hash<short>
-#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
- : public unary_function<short, size_t>
-#endif
+ : public __unary_function<short, size_t>
{
-_LIBCPP_SUPPRESS_DEPRECATED_POP
-#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
- _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
- _LIBCPP_DEPRECATED_IN_CXX17 typedef short argument_type;
-#endif
_LIBCPP_INLINE_VISIBILITY
size_t operator()(short __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
};
-_LIBCPP_SUPPRESS_DEPRECATED_PUSH
template <>
struct _LIBCPP_TEMPLATE_VIS hash<unsigned short>
-#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
- : public unary_function<unsigned short, size_t>
-#endif
+ : public __unary_function<unsigned short, size_t>
{
-_LIBCPP_SUPPRESS_DEPRECATED_POP
-#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
- _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
- _LIBCPP_DEPRECATED_IN_CXX17 typedef unsigned short argument_type;
-#endif
_LIBCPP_INLINE_VISIBILITY
size_t operator()(unsigned short __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
};
-_LIBCPP_SUPPRESS_DEPRECATED_PUSH
template <>
struct _LIBCPP_TEMPLATE_VIS hash<int>
-#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
- : public unary_function<int, size_t>
-#endif
+ : public __unary_function<int, size_t>
{
-_LIBCPP_SUPPRESS_DEPRECATED_POP
-#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
- _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
- _LIBCPP_DEPRECATED_IN_CXX17 typedef int argument_type;
-#endif
_LIBCPP_INLINE_VISIBILITY
size_t operator()(int __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
};
-_LIBCPP_SUPPRESS_DEPRECATED_PUSH
template <>
struct _LIBCPP_TEMPLATE_VIS hash<unsigned int>
-#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
- : public unary_function<unsigned int, size_t>
-#endif
+ : public __unary_function<unsigned int, size_t>
{
-_LIBCPP_SUPPRESS_DEPRECATED_POP
-#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
- _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
- _LIBCPP_DEPRECATED_IN_CXX17 typedef unsigned int argument_type;
-#endif
_LIBCPP_INLINE_VISIBILITY
size_t operator()(unsigned int __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
};
-_LIBCPP_SUPPRESS_DEPRECATED_PUSH
template <>
struct _LIBCPP_TEMPLATE_VIS hash<long>
-#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
- : public unary_function<long, size_t>
-#endif
+ : public __unary_function<long, size_t>
{
-_LIBCPP_SUPPRESS_DEPRECATED_POP
-#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
- _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
- _LIBCPP_DEPRECATED_IN_CXX17 typedef long argument_type;
-#endif
_LIBCPP_INLINE_VISIBILITY
size_t operator()(long __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
};
-_LIBCPP_SUPPRESS_DEPRECATED_PUSH
template <>
struct _LIBCPP_TEMPLATE_VIS hash<unsigned long>
-#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
- : public unary_function<unsigned long, size_t>
-#endif
+ : public __unary_function<unsigned long, size_t>
{
-_LIBCPP_SUPPRESS_DEPRECATED_POP
-#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
- _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
- _LIBCPP_DEPRECATED_IN_CXX17 typedef unsigned long argument_type;
-#endif
_LIBCPP_INLINE_VISIBILITY
size_t operator()(unsigned long __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
};
@@ -781,25 +617,15 @@ struct _LIBCPP_TEMPLATE_VIS hash<long double>
}
};
-#if _LIBCPP_STD_VER > 11
-
-_LIBCPP_SUPPRESS_DEPRECATED_PUSH
template <class _Tp, bool = is_enum<_Tp>::value>
struct _LIBCPP_TEMPLATE_VIS __enum_hash
-#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
- : public unary_function<_Tp, size_t>
-#endif
+ : public __unary_function<_Tp, size_t>
{
-_LIBCPP_SUPPRESS_DEPRECATED_POP
-#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
- _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
- _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp argument_type;
-#endif
_LIBCPP_INLINE_VISIBILITY
size_t operator()(_Tp __v) const _NOEXCEPT
{
typedef typename underlying_type<_Tp>::type type;
- return hash<type>{}(static_cast<type>(__v));
+ return hash<type>()(static_cast<type>(__v));
}
};
template <class _Tp>
@@ -813,22 +639,13 @@ template <class _Tp>
struct _LIBCPP_TEMPLATE_VIS hash : public __enum_hash<_Tp>
{
};
-#endif
#if _LIBCPP_STD_VER > 14
-_LIBCPP_SUPPRESS_DEPRECATED_PUSH
template <>
struct _LIBCPP_TEMPLATE_VIS hash<nullptr_t>
-#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
- : public unary_function<nullptr_t, size_t>
-#endif
+ : public __unary_function<nullptr_t, size_t>
{
-_LIBCPP_SUPPRESS_DEPRECATED_POP
-#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
- _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
- _LIBCPP_DEPRECATED_IN_CXX17 typedef nullptr_t argument_type;
-#endif
_LIBCPP_INLINE_VISIBILITY
size_t operator()(nullptr_t) const _NOEXCEPT {
return 662607004ull;
diff --git a/libcxx/include/__functional/identity.h b/libcxx/include/__functional/identity.h
index 6b8346b3b2a7..2fe3acca0899 100644
--- a/libcxx/include/__functional/identity.h
+++ b/libcxx/include/__functional/identity.h
@@ -11,14 +11,23 @@
#define _LIBCPP___FUNCTIONAL_IDENTITY_H
#include <__config>
-#include <utility>
+#include <__utility/forward.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
+struct __identity {
+ template <class _Tp>
+ _LIBCPP_NODISCARD _LIBCPP_CONSTEXPR _Tp&& operator()(_Tp&& __t) const _NOEXCEPT {
+ return std::forward<_Tp>(__t);
+ }
+
+ using is_transparent = void;
+};
+
#if _LIBCPP_STD_VER > 17
struct identity {
diff --git a/libcxx/include/__functional/invoke.h b/libcxx/include/__functional/invoke.h
index 0e167c75d690..7381462ffca5 100644
--- a/libcxx/include/__functional/invoke.h
+++ b/libcxx/include/__functional/invoke.h
@@ -11,79 +11,526 @@
#define _LIBCPP___FUNCTIONAL_INVOKE_H
#include <__config>
-#include <__functional/weak_result_type.h>
+#include <__type_traits/add_lvalue_reference.h>
+#include <__type_traits/apply_cv.h>
+#include <__type_traits/conditional.h>
+#include <__type_traits/decay.h>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/is_base_of.h>
+#include <__type_traits/is_core_convertible.h>
+#include <__type_traits/is_member_function_pointer.h>
+#include <__type_traits/is_member_object_pointer.h>
+#include <__type_traits/is_reference_wrapper.h>
+#include <__type_traits/is_same.h>
+#include <__type_traits/is_void.h>
+#include <__type_traits/remove_cv.h>
+#include <__utility/declval.h>
#include <__utility/forward.h>
-#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
+// TODO: Disentangle the type traits and std::invoke properly
+
_LIBCPP_BEGIN_NAMESPACE_STD
-template <class _Ret, bool = is_void<_Ret>::value>
-struct __invoke_void_return_wrapper
+struct __any
+{
+ __any(...);
+};
+
+struct __nat
{
#ifndef _LIBCPP_CXX03_LANG
- template <class ..._Args>
- static _Ret __call(_Args&&... __args) {
- return _VSTD::__invoke(_VSTD::forward<_Args>(__args)...);
- }
-#else
- template <class _Fn>
- static _Ret __call(_Fn __f) {
- return _VSTD::__invoke(__f);
- }
+ __nat() = delete;
+ __nat(const __nat&) = delete;
+ __nat& operator=(const __nat&) = delete;
+ ~__nat() = delete;
+#endif
+};
- template <class _Fn, class _A0>
- static _Ret __call(_Fn __f, _A0& __a0) {
- return _VSTD::__invoke(__f, __a0);
- }
+template <class _MP, bool _IsMemberFunctionPtr, bool _IsMemberObjectPtr>
+struct __member_pointer_traits_imp
+{
+};
- template <class _Fn, class _A0, class _A1>
- static _Ret __call(_Fn __f, _A0& __a0, _A1& __a1) {
- return _VSTD::__invoke(__f, __a0, __a1);
- }
+template <class _Rp, class _Class, class ..._Param>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...), true, false>
+{
+ typedef _Class _ClassType;
+ typedef _Rp _ReturnType;
+ typedef _Rp (_FnType) (_Param...);
+};
+
+template <class _Rp, class _Class, class ..._Param>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...), true, false>
+{
+ typedef _Class _ClassType;
+ typedef _Rp _ReturnType;
+ typedef _Rp (_FnType) (_Param..., ...);
+};
+
+template <class _Rp, class _Class, class ..._Param>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const, true, false>
+{
+ typedef _Class const _ClassType;
+ typedef _Rp _ReturnType;
+ typedef _Rp (_FnType) (_Param...);
+};
+
+template <class _Rp, class _Class, class ..._Param>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const, true, false>
+{
+ typedef _Class const _ClassType;
+ typedef _Rp _ReturnType;
+ typedef _Rp (_FnType) (_Param..., ...);
+};
+
+template <class _Rp, class _Class, class ..._Param>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) volatile, true, false>
+{
+ typedef _Class volatile _ClassType;
+ typedef _Rp _ReturnType;
+ typedef _Rp (_FnType) (_Param...);
+};
+
+template <class _Rp, class _Class, class ..._Param>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) volatile, true, false>
+{
+ typedef _Class volatile _ClassType;
+ typedef _Rp _ReturnType;
+ typedef _Rp (_FnType) (_Param..., ...);
+};
+
+template <class _Rp, class _Class, class ..._Param>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const volatile, true, false>
+{
+ typedef _Class const volatile _ClassType;
+ typedef _Rp _ReturnType;
+ typedef _Rp (_FnType) (_Param...);
+};
+
+template <class _Rp, class _Class, class ..._Param>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const volatile, true, false>
+{
+ typedef _Class const volatile _ClassType;
+ typedef _Rp _ReturnType;
+ typedef _Rp (_FnType) (_Param..., ...);
+};
+
+template <class _Rp, class _Class, class ..._Param>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) &, true, false>
+{
+ typedef _Class& _ClassType;
+ typedef _Rp _ReturnType;
+ typedef _Rp (_FnType) (_Param...);
+};
+
+template <class _Rp, class _Class, class ..._Param>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) &, true, false>
+{
+ typedef _Class& _ClassType;
+ typedef _Rp _ReturnType;
+ typedef _Rp (_FnType) (_Param..., ...);
+};
+
+template <class _Rp, class _Class, class ..._Param>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const&, true, false>
+{
+ typedef _Class const& _ClassType;
+ typedef _Rp _ReturnType;
+ typedef _Rp (_FnType) (_Param...);
+};
+
+template <class _Rp, class _Class, class ..._Param>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const&, true, false>
+{
+ typedef _Class const& _ClassType;
+ typedef _Rp _ReturnType;
+ typedef _Rp (_FnType) (_Param..., ...);
+};
+
+template <class _Rp, class _Class, class ..._Param>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) volatile&, true, false>
+{
+ typedef _Class volatile& _ClassType;
+ typedef _Rp _ReturnType;
+ typedef _Rp (_FnType) (_Param...);
+};
+
+template <class _Rp, class _Class, class ..._Param>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) volatile&, true, false>
+{
+ typedef _Class volatile& _ClassType;
+ typedef _Rp _ReturnType;
+ typedef _Rp (_FnType) (_Param..., ...);
+};
+
+template <class _Rp, class _Class, class ..._Param>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const volatile&, true, false>
+{
+ typedef _Class const volatile& _ClassType;
+ typedef _Rp _ReturnType;
+ typedef _Rp (_FnType) (_Param...);
+};
+
+template <class _Rp, class _Class, class ..._Param>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const volatile&, true, false>
+{
+ typedef _Class const volatile& _ClassType;
+ typedef _Rp _ReturnType;
+ typedef _Rp (_FnType) (_Param..., ...);
+};
+
+template <class _Rp, class _Class, class ..._Param>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) &&, true, false>
+{
+ typedef _Class&& _ClassType;
+ typedef _Rp _ReturnType;
+ typedef _Rp (_FnType) (_Param...);
+};
+
+template <class _Rp, class _Class, class ..._Param>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) &&, true, false>
+{
+ typedef _Class&& _ClassType;
+ typedef _Rp _ReturnType;
+ typedef _Rp (_FnType) (_Param..., ...);
+};
+
+template <class _Rp, class _Class, class ..._Param>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const&&, true, false>
+{
+ typedef _Class const&& _ClassType;
+ typedef _Rp _ReturnType;
+ typedef _Rp (_FnType) (_Param...);
+};
+
+template <class _Rp, class _Class, class ..._Param>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const&&, true, false>
+{
+ typedef _Class const&& _ClassType;
+ typedef _Rp _ReturnType;
+ typedef _Rp (_FnType) (_Param..., ...);
+};
+
+template <class _Rp, class _Class, class ..._Param>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) volatile&&, true, false>
+{
+ typedef _Class volatile&& _ClassType;
+ typedef _Rp _ReturnType;
+ typedef _Rp (_FnType) (_Param...);
+};
+
+template <class _Rp, class _Class, class ..._Param>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) volatile&&, true, false>
+{
+ typedef _Class volatile&& _ClassType;
+ typedef _Rp _ReturnType;
+ typedef _Rp (_FnType) (_Param..., ...);
+};
+
+template <class _Rp, class _Class, class ..._Param>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const volatile&&, true, false>
+{
+ typedef _Class const volatile&& _ClassType;
+ typedef _Rp _ReturnType;
+ typedef _Rp (_FnType) (_Param...);
+};
+
+template <class _Rp, class _Class, class ..._Param>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const volatile&&, true, false>
+{
+ typedef _Class const volatile&& _ClassType;
+ typedef _Rp _ReturnType;
+ typedef _Rp (_FnType) (_Param..., ...);
+};
+
+template <class _Rp, class _Class>
+struct __member_pointer_traits_imp<_Rp _Class::*, false, true>
+{
+ typedef _Class _ClassType;
+ typedef _Rp _ReturnType;
+};
+
+template <class _MP>
+struct __member_pointer_traits
+ : public __member_pointer_traits_imp<typename remove_cv<_MP>::type,
+ is_member_function_pointer<_MP>::value,
+ is_member_object_pointer<_MP>::value>
+{
+// typedef ... _ClassType;
+// typedef ... _ReturnType;
+// typedef ... _FnType;
+};
+
+template <class _DecayedFp>
+struct __member_pointer_class_type {};
+
+template <class _Ret, class _ClassType>
+struct __member_pointer_class_type<_Ret _ClassType::*> {
+ typedef _ClassType type;
+};
+
+template <class _Fp, class _A0,
+ class _DecayFp = typename decay<_Fp>::type,
+ class _DecayA0 = typename decay<_A0>::type,
+ class _ClassT = typename __member_pointer_class_type<_DecayFp>::type>
+using __enable_if_bullet1 = typename enable_if
+ <
+ is_member_function_pointer<_DecayFp>::value
+ && is_base_of<_ClassT, _DecayA0>::value
+ >::type;
+
+template <class _Fp, class _A0,
+ class _DecayFp = typename decay<_Fp>::type,
+ class _DecayA0 = typename decay<_A0>::type>
+using __enable_if_bullet2 = typename enable_if
+ <
+ is_member_function_pointer<_DecayFp>::value
+ && __is_reference_wrapper<_DecayA0>::value
+ >::type;
+
+template <class _Fp, class _A0,
+ class _DecayFp = typename decay<_Fp>::type,
+ class _DecayA0 = typename decay<_A0>::type,
+ class _ClassT = typename __member_pointer_class_type<_DecayFp>::type>
+using __enable_if_bullet3 = typename enable_if
+ <
+ is_member_function_pointer<_DecayFp>::value
+ && !is_base_of<_ClassT, _DecayA0>::value
+ && !__is_reference_wrapper<_DecayA0>::value
+ >::type;
+
+template <class _Fp, class _A0,
+ class _DecayFp = typename decay<_Fp>::type,
+ class _DecayA0 = typename decay<_A0>::type,
+ class _ClassT = typename __member_pointer_class_type<_DecayFp>::type>
+using __enable_if_bullet4 = typename enable_if
+ <
+ is_member_object_pointer<_DecayFp>::value
+ && is_base_of<_ClassT, _DecayA0>::value
+ >::type;
+
+template <class _Fp, class _A0,
+ class _DecayFp = typename decay<_Fp>::type,
+ class _DecayA0 = typename decay<_A0>::type>
+using __enable_if_bullet5 = typename enable_if
+ <
+ is_member_object_pointer<_DecayFp>::value
+ && __is_reference_wrapper<_DecayA0>::value
+ >::type;
+
+template <class _Fp, class _A0,
+ class _DecayFp = typename decay<_Fp>::type,
+ class _DecayA0 = typename decay<_A0>::type,
+ class _ClassT = typename __member_pointer_class_type<_DecayFp>::type>
+using __enable_if_bullet6 = typename enable_if
+ <
+ is_member_object_pointer<_DecayFp>::value
+ && !is_base_of<_ClassT, _DecayA0>::value
+ && !__is_reference_wrapper<_DecayA0>::value
+ >::type;
+
+// __invoke forward declarations
+
+// fall back - none of the bullets
+
+template <class ..._Args>
+__nat __invoke(__any, _Args&& ...__args);
+
+// bullets 1, 2 and 3
+
+template <class _Fp, class _A0, class ..._Args,
+ class = __enable_if_bullet1<_Fp, _A0> >
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_CONSTEXPR decltype((std::declval<_A0>().*std::declval<_Fp>())(std::declval<_Args>()...))
+__invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args)
+ _NOEXCEPT_(noexcept((static_cast<_A0&&>(__a0).*__f)(static_cast<_Args&&>(__args)...)))
+ { return (static_cast<_A0&&>(__a0).*__f)(static_cast<_Args&&>(__args)...); }
+
+template <class _Fp, class _A0, class ..._Args,
+ class = __enable_if_bullet2<_Fp, _A0> >
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_CONSTEXPR decltype((std::declval<_A0>().get().*std::declval<_Fp>())(std::declval<_Args>()...))
+__invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args)
+ _NOEXCEPT_(noexcept((__a0.get().*__f)(static_cast<_Args&&>(__args)...)))
+ { return (__a0.get().*__f)(static_cast<_Args&&>(__args)...); }
+
+template <class _Fp, class _A0, class ..._Args,
+ class = __enable_if_bullet3<_Fp, _A0> >
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_CONSTEXPR decltype(((*std::declval<_A0>()).*std::declval<_Fp>())(std::declval<_Args>()...))
+__invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args)
+ _NOEXCEPT_(noexcept(((*static_cast<_A0&&>(__a0)).*__f)(static_cast<_Args&&>(__args)...)))
+ { return ((*static_cast<_A0&&>(__a0)).*__f)(static_cast<_Args&&>(__args)...); }
+
+// bullets 4, 5 and 6
+
+template <class _Fp, class _A0,
+ class = __enable_if_bullet4<_Fp, _A0> >
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_CONSTEXPR decltype(std::declval<_A0>().*std::declval<_Fp>())
+__invoke(_Fp&& __f, _A0&& __a0)
+ _NOEXCEPT_(noexcept(static_cast<_A0&&>(__a0).*__f))
+ { return static_cast<_A0&&>(__a0).*__f; }
+
+template <class _Fp, class _A0,
+ class = __enable_if_bullet5<_Fp, _A0> >
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_CONSTEXPR decltype(std::declval<_A0>().get().*std::declval<_Fp>())
+__invoke(_Fp&& __f, _A0&& __a0)
+ _NOEXCEPT_(noexcept(__a0.get().*__f))
+ { return __a0.get().*__f; }
+
+template <class _Fp, class _A0,
+ class = __enable_if_bullet6<_Fp, _A0> >
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_CONSTEXPR decltype((*std::declval<_A0>()).*std::declval<_Fp>())
+__invoke(_Fp&& __f, _A0&& __a0)
+ _NOEXCEPT_(noexcept((*static_cast<_A0&&>(__a0)).*__f))
+ { return (*static_cast<_A0&&>(__a0)).*__f; }
+
+// bullet 7
+
+template <class _Fp, class ..._Args>
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_CONSTEXPR decltype(std::declval<_Fp>()(std::declval<_Args>()...))
+__invoke(_Fp&& __f, _Args&& ...__args)
+ _NOEXCEPT_(noexcept(static_cast<_Fp&&>(__f)(static_cast<_Args&&>(__args)...)))
+ { return static_cast<_Fp&&>(__f)(static_cast<_Args&&>(__args)...); }
+
+// __invokable
+template <class _Ret, class _Fp, class ..._Args>
+struct __invokable_r
+{
+ template <class _XFp, class ..._XArgs>
+ static decltype(std::__invoke(declval<_XFp>(), declval<_XArgs>()...)) __try_call(int);
+ template <class _XFp, class ..._XArgs>
+ static __nat __try_call(...);
+
+ // FIXME: Check that _Ret, _Fp, and _Args... are all complete types, cv void,
+ // or incomplete array types as required by the standard.
+ using _Result = decltype(__try_call<_Fp, _Args...>(0));
+
+ using type = typename conditional<
+ _IsNotSame<_Result, __nat>::value,
+ typename conditional< is_void<_Ret>::value, true_type, __is_core_convertible<_Result, _Ret> >::type,
+ false_type >::type;
+ static const bool value = type::value;
+};
+template <class _Fp, class ..._Args>
+using __invokable = __invokable_r<void, _Fp, _Args...>;
+
+template <bool _IsInvokable, bool _IsCVVoid, class _Ret, class _Fp, class ..._Args>
+struct __nothrow_invokable_r_imp {
+ static const bool value = false;
+};
+
+template <class _Ret, class _Fp, class ..._Args>
+struct __nothrow_invokable_r_imp<true, false, _Ret, _Fp, _Args...>
+{
+ typedef __nothrow_invokable_r_imp _ThisT;
+
+ template <class _Tp>
+ static void __test_noexcept(_Tp) _NOEXCEPT;
+
+ static const bool value = noexcept(_ThisT::__test_noexcept<_Ret>(
+ _VSTD::__invoke(declval<_Fp>(), declval<_Args>()...)));
+};
- template <class _Fn, class _A0, class _A1, class _A2>
- static _Ret __call(_Fn __f, _A0& __a0, _A1& __a1, _A2& __a2){
- return _VSTD::__invoke(__f, __a0, __a1, __a2);
+template <class _Ret, class _Fp, class ..._Args>
+struct __nothrow_invokable_r_imp<true, true, _Ret, _Fp, _Args...>
+{
+ static const bool value = noexcept(
+ _VSTD::__invoke(declval<_Fp>(), declval<_Args>()...));
+};
+
+template <class _Ret, class _Fp, class ..._Args>
+using __nothrow_invokable_r =
+ __nothrow_invokable_r_imp<
+ __invokable_r<_Ret, _Fp, _Args...>::value,
+ is_void<_Ret>::value,
+ _Ret, _Fp, _Args...
+ >;
+
+template <class _Fp, class ..._Args>
+using __nothrow_invokable =
+ __nothrow_invokable_r_imp<
+ __invokable<_Fp, _Args...>::value,
+ true, void, _Fp, _Args...
+ >;
+
+template <class _Fp, class ..._Args>
+struct __invoke_of
+ : public enable_if<
+ __invokable<_Fp, _Args...>::value,
+ typename __invokable_r<void, _Fp, _Args...>::_Result>
+{
+};
+
+template <class _Ret, bool = is_void<_Ret>::value>
+struct __invoke_void_return_wrapper
+{
+ template <class ..._Args>
+ static _Ret __call(_Args&&... __args) {
+ return std::__invoke(std::forward<_Args>(__args)...);
}
-#endif
};
template <class _Ret>
struct __invoke_void_return_wrapper<_Ret, true>
{
-#ifndef _LIBCPP_CXX03_LANG
template <class ..._Args>
static void __call(_Args&&... __args) {
- _VSTD::__invoke(_VSTD::forward<_Args>(__args)...);
- }
-#else
- template <class _Fn>
- static void __call(_Fn __f) {
- _VSTD::__invoke(__f);
+ std::__invoke(std::forward<_Args>(__args)...);
}
+};
- template <class _Fn, class _A0>
- static void __call(_Fn __f, _A0& __a0) {
- _VSTD::__invoke(__f, __a0);
- }
+#if _LIBCPP_STD_VER > 14
- template <class _Fn, class _A0, class _A1>
- static void __call(_Fn __f, _A0& __a0, _A1& __a1) {
- _VSTD::__invoke(__f, __a0, __a1);
- }
+// is_invocable
- template <class _Fn, class _A0, class _A1, class _A2>
- static void __call(_Fn __f, _A0& __a0, _A1& __a1, _A2& __a2) {
- _VSTD::__invoke(__f, __a0, __a1, __a2);
- }
-#endif
+template <class _Fn, class ..._Args>
+struct _LIBCPP_TEMPLATE_VIS is_invocable
+ : integral_constant<bool, __invokable<_Fn, _Args...>::value> {};
+
+template <class _Ret, class _Fn, class ..._Args>
+struct _LIBCPP_TEMPLATE_VIS is_invocable_r
+ : integral_constant<bool, __invokable_r<_Ret, _Fn, _Args...>::value> {};
+
+template <class _Fn, class ..._Args>
+inline constexpr bool is_invocable_v = is_invocable<_Fn, _Args...>::value;
+
+template <class _Ret, class _Fn, class ..._Args>
+inline constexpr bool is_invocable_r_v = is_invocable_r<_Ret, _Fn, _Args...>::value;
+
+// is_nothrow_invocable
+
+template <class _Fn, class ..._Args>
+struct _LIBCPP_TEMPLATE_VIS is_nothrow_invocable
+ : integral_constant<bool, __nothrow_invokable<_Fn, _Args...>::value> {};
+
+template <class _Ret, class _Fn, class ..._Args>
+struct _LIBCPP_TEMPLATE_VIS is_nothrow_invocable_r
+ : integral_constant<bool, __nothrow_invokable_r<_Ret, _Fn, _Args...>::value> {};
+
+template <class _Fn, class ..._Args>
+inline constexpr bool is_nothrow_invocable_v = is_nothrow_invocable<_Fn, _Args...>::value;
+
+template <class _Ret, class _Fn, class ..._Args>
+inline constexpr bool is_nothrow_invocable_r_v = is_nothrow_invocable_r<_Ret, _Fn, _Args...>::value;
+
+template <class _Fn, class... _Args>
+struct _LIBCPP_TEMPLATE_VIS invoke_result
+ : __invoke_of<_Fn, _Args...>
+{
};
-#if _LIBCPP_STD_VER > 14
+template <class _Fn, class... _Args>
+using invoke_result_t = typename invoke_result<_Fn, _Args...>::type;
template <class _Fn, class ..._Args>
_LIBCPP_CONSTEXPR_AFTER_CXX17 invoke_result_t<_Fn, _Args...>
diff --git a/libcxx/include/__functional/is_transparent.h b/libcxx/include/__functional/is_transparent.h
index 4a72aa8e29ee..74326c76c12f 100644
--- a/libcxx/include/__functional/is_transparent.h
+++ b/libcxx/include/__functional/is_transparent.h
@@ -14,7 +14,7 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__functional/mem_fn.h b/libcxx/include/__functional/mem_fn.h
index 0ec84233439c..a5818b3f018c 100644
--- a/libcxx/include/__functional/mem_fn.h
+++ b/libcxx/include/__functional/mem_fn.h
@@ -14,19 +14,17 @@
#include <__functional/binary_function.h>
#include <__functional/invoke.h>
#include <__functional/weak_result_type.h>
-#include <utility>
+#include <__utility/forward.h>
+#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _Tp>
-class __mem_fn
-#if _LIBCPP_STD_VER <= 17 || !defined(_LIBCPP_ABI_NO_BINDER_BASES)
- : public __weak_result_type<_Tp>
-#endif
+class __mem_fn : public __weak_result_type<_Tp>
{
public:
// types
@@ -38,114 +36,14 @@ public:
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
__mem_fn(type __f) _NOEXCEPT : __f_(__f) {}
-#ifndef _LIBCPP_CXX03_LANG
// invoke
template <class... _ArgTypes>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+
typename __invoke_return<type, _ArgTypes...>::type
operator() (_ArgTypes&&... __args) const {
- return _VSTD::__invoke(__f_, _VSTD::forward<_ArgTypes>(__args)...);
- }
-#else
-
- template <class _A0>
- _LIBCPP_INLINE_VISIBILITY
- typename __invoke_return0<type, _A0>::type
- operator() (_A0& __a0) const {
- return _VSTD::__invoke(__f_, __a0);
- }
-
- template <class _A0>
- _LIBCPP_INLINE_VISIBILITY
- typename __invoke_return0<type, _A0 const>::type
- operator() (_A0 const& __a0) const {
- return _VSTD::__invoke(__f_, __a0);
- }
-
- template <class _A0, class _A1>
- _LIBCPP_INLINE_VISIBILITY
- typename __invoke_return1<type, _A0, _A1>::type
- operator() (_A0& __a0, _A1& __a1) const {
- return _VSTD::__invoke(__f_, __a0, __a1);
- }
-
- template <class _A0, class _A1>
- _LIBCPP_INLINE_VISIBILITY
- typename __invoke_return1<type, _A0 const, _A1>::type
- operator() (_A0 const& __a0, _A1& __a1) const {
- return _VSTD::__invoke(__f_, __a0, __a1);
- }
-
- template <class _A0, class _A1>
- _LIBCPP_INLINE_VISIBILITY
- typename __invoke_return1<type, _A0, _A1 const>::type
- operator() (_A0& __a0, _A1 const& __a1) const {
- return _VSTD::__invoke(__f_, __a0, __a1);
- }
-
- template <class _A0, class _A1>
- _LIBCPP_INLINE_VISIBILITY
- typename __invoke_return1<type, _A0 const, _A1 const>::type
- operator() (_A0 const& __a0, _A1 const& __a1) const {
- return _VSTD::__invoke(__f_, __a0, __a1);
- }
-
- template <class _A0, class _A1, class _A2>
- _LIBCPP_INLINE_VISIBILITY
- typename __invoke_return2<type, _A0, _A1, _A2>::type
- operator() (_A0& __a0, _A1& __a1, _A2& __a2) const {
- return _VSTD::__invoke(__f_, __a0, __a1, __a2);
+ return std::__invoke(__f_, std::forward<_ArgTypes>(__args)...);
}
-
- template <class _A0, class _A1, class _A2>
- _LIBCPP_INLINE_VISIBILITY
- typename __invoke_return2<type, _A0 const, _A1, _A2>::type
- operator() (_A0 const& __a0, _A1& __a1, _A2& __a2) const {
- return _VSTD::__invoke(__f_, __a0, __a1, __a2);
- }
-
- template <class _A0, class _A1, class _A2>
- _LIBCPP_INLINE_VISIBILITY
- typename __invoke_return2<type, _A0, _A1 const, _A2>::type
- operator() (_A0& __a0, _A1 const& __a1, _A2& __a2) const {
- return _VSTD::__invoke(__f_, __a0, __a1, __a2);
- }
-
- template <class _A0, class _A1, class _A2>
- _LIBCPP_INLINE_VISIBILITY
- typename __invoke_return2<type, _A0, _A1, _A2 const>::type
- operator() (_A0& __a0, _A1& __a1, _A2 const& __a2) const {
- return _VSTD::__invoke(__f_, __a0, __a1, __a2);
- }
-
- template <class _A0, class _A1, class _A2>
- _LIBCPP_INLINE_VISIBILITY
- typename __invoke_return2<type, _A0 const, _A1 const, _A2>::type
- operator() (_A0 const& __a0, _A1 const& __a1, _A2& __a2) const {
- return _VSTD::__invoke(__f_, __a0, __a1, __a2);
- }
-
- template <class _A0, class _A1, class _A2>
- _LIBCPP_INLINE_VISIBILITY
- typename __invoke_return2<type, _A0 const, _A1, _A2 const>::type
- operator() (_A0 const& __a0, _A1& __a1, _A2 const& __a2) const {
- return _VSTD::__invoke(__f_, __a0, __a1, __a2);
- }
-
- template <class _A0, class _A1, class _A2>
- _LIBCPP_INLINE_VISIBILITY
- typename __invoke_return2<type, _A0, _A1 const, _A2 const>::type
- operator() (_A0& __a0, _A1 const& __a1, _A2 const& __a2) const {
- return _VSTD::__invoke(__f_, __a0, __a1, __a2);
- }
-
- template <class _A0, class _A1, class _A2>
- _LIBCPP_INLINE_VISIBILITY
- typename __invoke_return2<type, _A0 const, _A1 const, _A2 const>::type
- operator() (_A0 const& __a0, _A1 const& __a1, _A2 const& __a2) const {
- return _VSTD::__invoke(__f_, __a0, __a1, __a2);
- }
-#endif
};
template<class _Rp, class _Tp>
diff --git a/libcxx/include/__functional/mem_fun_ref.h b/libcxx/include/__functional/mem_fun_ref.h
index 830936c1b0e5..65aab0696c16 100644
--- a/libcxx/include/__functional/mem_fun_ref.h
+++ b/libcxx/include/__functional/mem_fun_ref.h
@@ -15,7 +15,7 @@
#include <__functional/unary_function.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -24,7 +24,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
template<class _Sp, class _Tp>
class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 mem_fun_t
- : public unary_function<_Tp*, _Sp>
+ : public __unary_function<_Tp*, _Sp>
{
_Sp (_Tp::*__p_)();
public:
@@ -36,7 +36,7 @@ public:
template<class _Sp, class _Tp, class _Ap>
class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 mem_fun1_t
- : public binary_function<_Tp*, _Ap, _Sp>
+ : public __binary_function<_Tp*, _Ap, _Sp>
{
_Sp (_Tp::*__p_)(_Ap);
public:
@@ -60,7 +60,7 @@ mem_fun(_Sp (_Tp::*__f)(_Ap))
template<class _Sp, class _Tp>
class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 mem_fun_ref_t
- : public unary_function<_Tp, _Sp>
+ : public __unary_function<_Tp, _Sp>
{
_Sp (_Tp::*__p_)();
public:
@@ -72,7 +72,7 @@ public:
template<class _Sp, class _Tp, class _Ap>
class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 mem_fun1_ref_t
- : public binary_function<_Tp, _Ap, _Sp>
+ : public __binary_function<_Tp, _Ap, _Sp>
{
_Sp (_Tp::*__p_)(_Ap);
public:
@@ -96,7 +96,7 @@ mem_fun_ref(_Sp (_Tp::*__f)(_Ap))
template <class _Sp, class _Tp>
class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 const_mem_fun_t
- : public unary_function<const _Tp*, _Sp>
+ : public __unary_function<const _Tp*, _Sp>
{
_Sp (_Tp::*__p_)() const;
public:
@@ -108,7 +108,7 @@ public:
template <class _Sp, class _Tp, class _Ap>
class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 const_mem_fun1_t
- : public binary_function<const _Tp*, _Ap, _Sp>
+ : public __binary_function<const _Tp*, _Ap, _Sp>
{
_Sp (_Tp::*__p_)(_Ap) const;
public:
@@ -132,7 +132,7 @@ mem_fun(_Sp (_Tp::*__f)(_Ap) const)
template <class _Sp, class _Tp>
class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 const_mem_fun_ref_t
- : public unary_function<_Tp, _Sp>
+ : public __unary_function<_Tp, _Sp>
{
_Sp (_Tp::*__p_)() const;
public:
@@ -144,7 +144,7 @@ public:
template <class _Sp, class _Tp, class _Ap>
class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 const_mem_fun1_ref_t
- : public binary_function<_Tp, _Ap, _Sp>
+ : public __binary_function<_Tp, _Ap, _Sp>
{
_Sp (_Tp::*__p_)(_Ap) const;
public:
diff --git a/libcxx/include/__functional/not_fn.h b/libcxx/include/__functional/not_fn.h
index 36aab2eb7935..b5c415c25c44 100644
--- a/libcxx/include/__functional/not_fn.h
+++ b/libcxx/include/__functional/not_fn.h
@@ -13,10 +13,11 @@
#include <__config>
#include <__functional/invoke.h>
#include <__functional/perfect_forward.h>
-#include <utility>
+#include <__utility/forward.h>
+#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__functional/operations.h b/libcxx/include/__functional/operations.h
index 0c7c6d4fcfaf..1c73c999db91 100644
--- a/libcxx/include/__functional/operations.h
+++ b/libcxx/include/__functional/operations.h
@@ -16,31 +16,22 @@
#include <__utility/forward.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
// Arithmetic operations
-_LIBCPP_SUPPRESS_DEPRECATED_PUSH
#if _LIBCPP_STD_VER > 11
template <class _Tp = void>
#else
template <class _Tp>
#endif
struct _LIBCPP_TEMPLATE_VIS plus
-#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
- : binary_function<_Tp, _Tp, _Tp>
-#endif
+ : __binary_function<_Tp, _Tp, _Tp>
{
-_LIBCPP_SUPPRESS_DEPRECATED_POP
typedef _Tp __result_type; // used by valarray
-#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
- _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp result_type;
- _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type;
- _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type;
-#endif
_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
_Tp operator()(const _Tp& __x, const _Tp& __y) const
{return __x + __y;}
@@ -60,24 +51,15 @@ struct _LIBCPP_TEMPLATE_VIS plus<void>
};
#endif
-_LIBCPP_SUPPRESS_DEPRECATED_PUSH
#if _LIBCPP_STD_VER > 11
template <class _Tp = void>
#else
template <class _Tp>
#endif
struct _LIBCPP_TEMPLATE_VIS minus
-#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
- : binary_function<_Tp, _Tp, _Tp>
-#endif
+ : __binary_function<_Tp, _Tp, _Tp>
{
-_LIBCPP_SUPPRESS_DEPRECATED_POP
typedef _Tp __result_type; // used by valarray
-#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
- _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp result_type;
- _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type;
- _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type;
-#endif
_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
_Tp operator()(const _Tp& __x, const _Tp& __y) const
{return __x - __y;}
@@ -97,24 +79,15 @@ struct _LIBCPP_TEMPLATE_VIS minus<void>
};
#endif
-_LIBCPP_SUPPRESS_DEPRECATED_PUSH
#if _LIBCPP_STD_VER > 11
template <class _Tp = void>
#else
template <class _Tp>
#endif
struct _LIBCPP_TEMPLATE_VIS multiplies
-#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
- : binary_function<_Tp, _Tp, _Tp>
-#endif
+ : __binary_function<_Tp, _Tp, _Tp>
{
-_LIBCPP_SUPPRESS_DEPRECATED_POP
typedef _Tp __result_type; // used by valarray
-#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
- _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp result_type;
- _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type;
- _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type;
-#endif
_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
_Tp operator()(const _Tp& __x, const _Tp& __y) const
{return __x * __y;}
@@ -134,24 +107,15 @@ struct _LIBCPP_TEMPLATE_VIS multiplies<void>
};
#endif
-_LIBCPP_SUPPRESS_DEPRECATED_PUSH
#if _LIBCPP_STD_VER > 11
template <class _Tp = void>
#else
template <class _Tp>
#endif
struct _LIBCPP_TEMPLATE_VIS divides
-#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
- : binary_function<_Tp, _Tp, _Tp>
-#endif
+ : __binary_function<_Tp, _Tp, _Tp>
{
-_LIBCPP_SUPPRESS_DEPRECATED_POP
typedef _Tp __result_type; // used by valarray
-#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
- _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp result_type;
- _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type;
- _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type;
-#endif
_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
_Tp operator()(const _Tp& __x, const _Tp& __y) const
{return __x / __y;}
@@ -171,24 +135,15 @@ struct _LIBCPP_TEMPLATE_VIS divides<void>
};
#endif
-_LIBCPP_SUPPRESS_DEPRECATED_PUSH
#if _LIBCPP_STD_VER > 11
template <class _Tp = void>
#else
template <class _Tp>
#endif
struct _LIBCPP_TEMPLATE_VIS modulus
-#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
- : binary_function<_Tp, _Tp, _Tp>
-#endif
+ : __binary_function<_Tp, _Tp, _Tp>
{
-_LIBCPP_SUPPRESS_DEPRECATED_POP
typedef _Tp __result_type; // used by valarray
-#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
- _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp result_type;
- _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type;
- _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type;
-#endif
_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
_Tp operator()(const _Tp& __x, const _Tp& __y) const
{return __x % __y;}
@@ -208,23 +163,15 @@ struct _LIBCPP_TEMPLATE_VIS modulus<void>
};
#endif
-_LIBCPP_SUPPRESS_DEPRECATED_PUSH
#if _LIBCPP_STD_VER > 11
template <class _Tp = void>
#else
template <class _Tp>
#endif
struct _LIBCPP_TEMPLATE_VIS negate
-#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
- : unary_function<_Tp, _Tp>
-#endif
+ : __unary_function<_Tp, _Tp>
{
-_LIBCPP_SUPPRESS_DEPRECATED_POP
typedef _Tp __result_type; // used by valarray
-#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
- _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp result_type;
- _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp argument_type;
-#endif
_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
_Tp operator()(const _Tp& __x) const
{return -__x;}
@@ -246,24 +193,15 @@ struct _LIBCPP_TEMPLATE_VIS negate<void>
// Bitwise operations
-_LIBCPP_SUPPRESS_DEPRECATED_PUSH
#if _LIBCPP_STD_VER > 11
template <class _Tp = void>
#else
template <class _Tp>
#endif
struct _LIBCPP_TEMPLATE_VIS bit_and
-#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
- : binary_function<_Tp, _Tp, _Tp>
-#endif
+ : __binary_function<_Tp, _Tp, _Tp>
{
-_LIBCPP_SUPPRESS_DEPRECATED_POP
typedef _Tp __result_type; // used by valarray
-#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
- _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp result_type;
- _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type;
- _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type;
-#endif
_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
_Tp operator()(const _Tp& __x, const _Tp& __y) const
{return __x & __y;}
@@ -284,18 +222,10 @@ struct _LIBCPP_TEMPLATE_VIS bit_and<void>
#endif
#if _LIBCPP_STD_VER > 11
-_LIBCPP_SUPPRESS_DEPRECATED_PUSH
template <class _Tp = void>
struct _LIBCPP_TEMPLATE_VIS bit_not
-#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
- : unary_function<_Tp, _Tp>
-#endif
+ : __unary_function<_Tp, _Tp>
{
-_LIBCPP_SUPPRESS_DEPRECATED_POP
-#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
- _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp result_type;
- _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp argument_type;
-#endif
_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
_Tp operator()(const _Tp& __x) const
{return ~__x;}
@@ -314,24 +244,15 @@ struct _LIBCPP_TEMPLATE_VIS bit_not<void>
};
#endif
-_LIBCPP_SUPPRESS_DEPRECATED_PUSH
#if _LIBCPP_STD_VER > 11
template <class _Tp = void>
#else
template <class _Tp>
#endif
struct _LIBCPP_TEMPLATE_VIS bit_or
-#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
- : binary_function<_Tp, _Tp, _Tp>
-#endif
+ : __binary_function<_Tp, _Tp, _Tp>
{
-_LIBCPP_SUPPRESS_DEPRECATED_POP
typedef _Tp __result_type; // used by valarray
-#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
- _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp result_type;
- _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type;
- _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type;
-#endif
_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
_Tp operator()(const _Tp& __x, const _Tp& __y) const
{return __x | __y;}
@@ -351,24 +272,15 @@ struct _LIBCPP_TEMPLATE_VIS bit_or<void>
};
#endif
-_LIBCPP_SUPPRESS_DEPRECATED_PUSH
#if _LIBCPP_STD_VER > 11
template <class _Tp = void>
#else
template <class _Tp>
#endif
struct _LIBCPP_TEMPLATE_VIS bit_xor
-#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
- : binary_function<_Tp, _Tp, _Tp>
-#endif
+ : __binary_function<_Tp, _Tp, _Tp>
{
-_LIBCPP_SUPPRESS_DEPRECATED_POP
typedef _Tp __result_type; // used by valarray
-#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
- _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp result_type;
- _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type;
- _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type;
-#endif
_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
_Tp operator()(const _Tp& __x, const _Tp& __y) const
{return __x ^ __y;}
@@ -390,24 +302,15 @@ struct _LIBCPP_TEMPLATE_VIS bit_xor<void>
// Comparison operations
-_LIBCPP_SUPPRESS_DEPRECATED_PUSH
#if _LIBCPP_STD_VER > 11
template <class _Tp = void>
#else
template <class _Tp>
#endif
struct _LIBCPP_TEMPLATE_VIS equal_to
-#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
- : binary_function<_Tp, _Tp, bool>
-#endif
+ : __binary_function<_Tp, _Tp, bool>
{
-_LIBCPP_SUPPRESS_DEPRECATED_POP
typedef bool __result_type; // used by valarray
-#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
- _LIBCPP_DEPRECATED_IN_CXX17 typedef bool result_type;
- _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type;
- _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type;
-#endif
_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
bool operator()(const _Tp& __x, const _Tp& __y) const
{return __x == __y;}
@@ -427,24 +330,15 @@ struct _LIBCPP_TEMPLATE_VIS equal_to<void>
};
#endif
-_LIBCPP_SUPPRESS_DEPRECATED_PUSH
#if _LIBCPP_STD_VER > 11
template <class _Tp = void>
#else
template <class _Tp>
#endif
struct _LIBCPP_TEMPLATE_VIS not_equal_to
-#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
- : binary_function<_Tp, _Tp, bool>
-#endif
+ : __binary_function<_Tp, _Tp, bool>
{
-_LIBCPP_SUPPRESS_DEPRECATED_POP
typedef bool __result_type; // used by valarray
-#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
- _LIBCPP_DEPRECATED_IN_CXX17 typedef bool result_type;
- _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type;
- _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type;
-#endif
_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
bool operator()(const _Tp& __x, const _Tp& __y) const
{return __x != __y;}
@@ -464,24 +358,15 @@ struct _LIBCPP_TEMPLATE_VIS not_equal_to<void>
};
#endif
-_LIBCPP_SUPPRESS_DEPRECATED_PUSH
#if _LIBCPP_STD_VER > 11
template <class _Tp = void>
#else
template <class _Tp>
#endif
struct _LIBCPP_TEMPLATE_VIS less
-#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
- : binary_function<_Tp, _Tp, bool>
-#endif
+ : __binary_function<_Tp, _Tp, bool>
{
-_LIBCPP_SUPPRESS_DEPRECATED_POP
typedef bool __result_type; // used by valarray
-#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
- _LIBCPP_DEPRECATED_IN_CXX17 typedef bool result_type;
- _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type;
- _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type;
-#endif
_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
bool operator()(const _Tp& __x, const _Tp& __y) const
{return __x < __y;}
@@ -501,24 +386,15 @@ struct _LIBCPP_TEMPLATE_VIS less<void>
};
#endif
-_LIBCPP_SUPPRESS_DEPRECATED_PUSH
#if _LIBCPP_STD_VER > 11
template <class _Tp = void>
#else
template <class _Tp>
#endif
struct _LIBCPP_TEMPLATE_VIS less_equal
-#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
- : binary_function<_Tp, _Tp, bool>
-#endif
+ : __binary_function<_Tp, _Tp, bool>
{
-_LIBCPP_SUPPRESS_DEPRECATED_POP
typedef bool __result_type; // used by valarray
-#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
- _LIBCPP_DEPRECATED_IN_CXX17 typedef bool result_type;
- _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type;
- _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type;
-#endif
_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
bool operator()(const _Tp& __x, const _Tp& __y) const
{return __x <= __y;}
@@ -538,24 +414,15 @@ struct _LIBCPP_TEMPLATE_VIS less_equal<void>
};
#endif
-_LIBCPP_SUPPRESS_DEPRECATED_PUSH
#if _LIBCPP_STD_VER > 11
template <class _Tp = void>
#else
template <class _Tp>
#endif
struct _LIBCPP_TEMPLATE_VIS greater_equal
-#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
- : binary_function<_Tp, _Tp, bool>
-#endif
+ : __binary_function<_Tp, _Tp, bool>
{
-_LIBCPP_SUPPRESS_DEPRECATED_POP
typedef bool __result_type; // used by valarray
-#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
- _LIBCPP_DEPRECATED_IN_CXX17 typedef bool result_type;
- _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type;
- _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type;
-#endif
_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
bool operator()(const _Tp& __x, const _Tp& __y) const
{return __x >= __y;}
@@ -575,24 +442,15 @@ struct _LIBCPP_TEMPLATE_VIS greater_equal<void>
};
#endif
-_LIBCPP_SUPPRESS_DEPRECATED_PUSH
#if _LIBCPP_STD_VER > 11
template <class _Tp = void>
#else
template <class _Tp>
#endif
struct _LIBCPP_TEMPLATE_VIS greater
-#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
- : binary_function<_Tp, _Tp, bool>
-#endif
+ : __binary_function<_Tp, _Tp, bool>
{
-_LIBCPP_SUPPRESS_DEPRECATED_POP
typedef bool __result_type; // used by valarray
-#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
- _LIBCPP_DEPRECATED_IN_CXX17 typedef bool result_type;
- _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type;
- _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type;
-#endif
_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
bool operator()(const _Tp& __x, const _Tp& __y) const
{return __x > __y;}
@@ -614,24 +472,15 @@ struct _LIBCPP_TEMPLATE_VIS greater<void>
// Logical operations
-_LIBCPP_SUPPRESS_DEPRECATED_PUSH
#if _LIBCPP_STD_VER > 11
template <class _Tp = void>
#else
template <class _Tp>
#endif
struct _LIBCPP_TEMPLATE_VIS logical_and
-#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
- : binary_function<_Tp, _Tp, bool>
-#endif
+ : __binary_function<_Tp, _Tp, bool>
{
-_LIBCPP_SUPPRESS_DEPRECATED_POP
typedef bool __result_type; // used by valarray
-#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
- _LIBCPP_DEPRECATED_IN_CXX17 typedef bool result_type;
- _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type;
- _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type;
-#endif
_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
bool operator()(const _Tp& __x, const _Tp& __y) const
{return __x && __y;}
@@ -651,23 +500,15 @@ struct _LIBCPP_TEMPLATE_VIS logical_and<void>
};
#endif
-_LIBCPP_SUPPRESS_DEPRECATED_PUSH
#if _LIBCPP_STD_VER > 11
template <class _Tp = void>
#else
template <class _Tp>
#endif
struct _LIBCPP_TEMPLATE_VIS logical_not
-#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
- : unary_function<_Tp, bool>
-#endif
+ : __unary_function<_Tp, bool>
{
-_LIBCPP_SUPPRESS_DEPRECATED_POP
typedef bool __result_type; // used by valarray
-#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
- _LIBCPP_DEPRECATED_IN_CXX17 typedef bool result_type;
- _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp argument_type;
-#endif
_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
bool operator()(const _Tp& __x) const
{return !__x;}
@@ -687,24 +528,15 @@ struct _LIBCPP_TEMPLATE_VIS logical_not<void>
};
#endif
-_LIBCPP_SUPPRESS_DEPRECATED_PUSH
#if _LIBCPP_STD_VER > 11
template <class _Tp = void>
#else
template <class _Tp>
#endif
struct _LIBCPP_TEMPLATE_VIS logical_or
-#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
- : binary_function<_Tp, _Tp, bool>
-#endif
+ : __binary_function<_Tp, _Tp, bool>
{
-_LIBCPP_SUPPRESS_DEPRECATED_POP
typedef bool __result_type; // used by valarray
-#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
- _LIBCPP_DEPRECATED_IN_CXX17 typedef bool result_type;
- _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type;
- _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type;
-#endif
_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
bool operator()(const _Tp& __x, const _Tp& __y) const
{return __x || __y;}
diff --git a/libcxx/include/__functional/perfect_forward.h b/libcxx/include/__functional/perfect_forward.h
index 308b304a76dc..9ffea1a8c75d 100644
--- a/libcxx/include/__functional/perfect_forward.h
+++ b/libcxx/include/__functional/perfect_forward.h
@@ -18,70 +18,69 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER > 14
-template <class _Op, class _Indices, class ..._Bound>
+template <class _Op, class _Indices, class... _BoundArgs>
struct __perfect_forward_impl;
-template <class _Op, size_t ..._Idx, class ..._Bound>
-struct __perfect_forward_impl<_Op, index_sequence<_Idx...>, _Bound...> {
+template <class _Op, size_t... _Idx, class... _BoundArgs>
+struct __perfect_forward_impl<_Op, index_sequence<_Idx...>, _BoundArgs...> {
private:
- tuple<_Bound...> __bound_;
+ tuple<_BoundArgs...> __bound_args_;
public:
- template <class ..._BoundArgs, class = enable_if_t<
- is_constructible_v<tuple<_Bound...>, _BoundArgs&&...>
- >>
- explicit constexpr __perfect_forward_impl(_BoundArgs&& ...__bound)
- : __bound_(_VSTD::forward<_BoundArgs>(__bound)...)
- { }
-
- __perfect_forward_impl(__perfect_forward_impl const&) = default;
- __perfect_forward_impl(__perfect_forward_impl&&) = default;
-
- __perfect_forward_impl& operator=(__perfect_forward_impl const&) = default;
- __perfect_forward_impl& operator=(__perfect_forward_impl&&) = default;
-
- template <class ..._Args, class = enable_if_t<is_invocable_v<_Op, _Bound&..., _Args...>>>
- _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Args&&... __args) &
- noexcept(noexcept(_Op()(_VSTD::get<_Idx>(__bound_)..., _VSTD::forward<_Args>(__args)...)))
- -> decltype( _Op()(_VSTD::get<_Idx>(__bound_)..., _VSTD::forward<_Args>(__args)...))
- { return _Op()(_VSTD::get<_Idx>(__bound_)..., _VSTD::forward<_Args>(__args)...); }
-
- template <class ..._Args, class = enable_if_t<!is_invocable_v<_Op, _Bound&..., _Args...>>>
- auto operator()(_Args&&...) & = delete;
-
- template <class ..._Args, class = enable_if_t<is_invocable_v<_Op, _Bound const&..., _Args...>>>
- _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Args&&... __args) const&
- noexcept(noexcept(_Op()(_VSTD::get<_Idx>(__bound_)..., _VSTD::forward<_Args>(__args)...)))
- -> decltype( _Op()(_VSTD::get<_Idx>(__bound_)..., _VSTD::forward<_Args>(__args)...))
- { return _Op()(_VSTD::get<_Idx>(__bound_)..., _VSTD::forward<_Args>(__args)...); }
-
- template <class ..._Args, class = enable_if_t<!is_invocable_v<_Op, _Bound const&..., _Args...>>>
- auto operator()(_Args&&...) const& = delete;
-
- template <class ..._Args, class = enable_if_t<is_invocable_v<_Op, _Bound..., _Args...>>>
- _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Args&&... __args) &&
- noexcept(noexcept(_Op()(_VSTD::get<_Idx>(_VSTD::move(__bound_))..., _VSTD::forward<_Args>(__args)...)))
- -> decltype( _Op()(_VSTD::get<_Idx>(_VSTD::move(__bound_))..., _VSTD::forward<_Args>(__args)...))
- { return _Op()(_VSTD::get<_Idx>(_VSTD::move(__bound_))..., _VSTD::forward<_Args>(__args)...); }
-
- template <class ..._Args, class = enable_if_t<!is_invocable_v<_Op, _Bound..., _Args...>>>
- auto operator()(_Args&&...) && = delete;
-
- template <class ..._Args, class = enable_if_t<is_invocable_v<_Op, _Bound const..., _Args...>>>
- _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Args&&... __args) const&&
- noexcept(noexcept(_Op()(_VSTD::get<_Idx>(_VSTD::move(__bound_))..., _VSTD::forward<_Args>(__args)...)))
- -> decltype( _Op()(_VSTD::get<_Idx>(_VSTD::move(__bound_))..., _VSTD::forward<_Args>(__args)...))
- { return _Op()(_VSTD::get<_Idx>(_VSTD::move(__bound_))..., _VSTD::forward<_Args>(__args)...); }
-
- template <class ..._Args, class = enable_if_t<!is_invocable_v<_Op, _Bound const..., _Args...>>>
- auto operator()(_Args&&...) const&& = delete;
+ template <class... _Args, class = enable_if_t<
+ is_constructible_v<tuple<_BoundArgs...>, _Args&&...>
+ >>
+ explicit constexpr __perfect_forward_impl(_Args&&... __bound_args)
+ : __bound_args_(_VSTD::forward<_Args>(__bound_args)...) {}
+
+ __perfect_forward_impl(__perfect_forward_impl const&) = default;
+ __perfect_forward_impl(__perfect_forward_impl&&) = default;
+
+ __perfect_forward_impl& operator=(__perfect_forward_impl const&) = default;
+ __perfect_forward_impl& operator=(__perfect_forward_impl&&) = default;
+
+ template <class... _Args, class = enable_if_t<is_invocable_v<_Op, _BoundArgs&..., _Args...>>>
+ _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Args&&... __args) &
+ noexcept(noexcept(_Op()(_VSTD::get<_Idx>(__bound_args_)..., _VSTD::forward<_Args>(__args)...)))
+ -> decltype( _Op()(_VSTD::get<_Idx>(__bound_args_)..., _VSTD::forward<_Args>(__args)...))
+ { return _Op()(_VSTD::get<_Idx>(__bound_args_)..., _VSTD::forward<_Args>(__args)...); }
+
+ template <class... _Args, class = enable_if_t<!is_invocable_v<_Op, _BoundArgs&..., _Args...>>>
+ auto operator()(_Args&&...) & = delete;
+
+ template <class... _Args, class = enable_if_t<is_invocable_v<_Op, _BoundArgs const&..., _Args...>>>
+ _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Args&&... __args) const&
+ noexcept(noexcept(_Op()(_VSTD::get<_Idx>(__bound_args_)..., _VSTD::forward<_Args>(__args)...)))
+ -> decltype( _Op()(_VSTD::get<_Idx>(__bound_args_)..., _VSTD::forward<_Args>(__args)...))
+ { return _Op()(_VSTD::get<_Idx>(__bound_args_)..., _VSTD::forward<_Args>(__args)...); }
+
+ template <class... _Args, class = enable_if_t<!is_invocable_v<_Op, _BoundArgs const&..., _Args...>>>
+ auto operator()(_Args&&...) const& = delete;
+
+ template <class... _Args, class = enable_if_t<is_invocable_v<_Op, _BoundArgs..., _Args...>>>
+ _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Args&&... __args) &&
+ noexcept(noexcept(_Op()(_VSTD::get<_Idx>(_VSTD::move(__bound_args_))..., _VSTD::forward<_Args>(__args)...)))
+ -> decltype( _Op()(_VSTD::get<_Idx>(_VSTD::move(__bound_args_))..., _VSTD::forward<_Args>(__args)...))
+ { return _Op()(_VSTD::get<_Idx>(_VSTD::move(__bound_args_))..., _VSTD::forward<_Args>(__args)...); }
+
+ template <class... _Args, class = enable_if_t<!is_invocable_v<_Op, _BoundArgs..., _Args...>>>
+ auto operator()(_Args&&...) && = delete;
+
+ template <class... _Args, class = enable_if_t<is_invocable_v<_Op, _BoundArgs const..., _Args...>>>
+ _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Args&&... __args) const&&
+ noexcept(noexcept(_Op()(_VSTD::get<_Idx>(_VSTD::move(__bound_args_))..., _VSTD::forward<_Args>(__args)...)))
+ -> decltype( _Op()(_VSTD::get<_Idx>(_VSTD::move(__bound_args_))..., _VSTD::forward<_Args>(__args)...))
+ { return _Op()(_VSTD::get<_Idx>(_VSTD::move(__bound_args_))..., _VSTD::forward<_Args>(__args)...); }
+
+ template <class... _Args, class = enable_if_t<!is_invocable_v<_Op, _BoundArgs const..., _Args...>>>
+ auto operator()(_Args&&...) const&& = delete;
};
// __perfect_forward implements a perfect-forwarding call wrapper as explained in [func.require].
diff --git a/libcxx/include/__functional/pointer_to_binary_function.h b/libcxx/include/__functional/pointer_to_binary_function.h
index d4a6c1674aec..b2676c58f885 100644
--- a/libcxx/include/__functional/pointer_to_binary_function.h
+++ b/libcxx/include/__functional/pointer_to_binary_function.h
@@ -14,7 +14,7 @@
#include <__functional/binary_function.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -23,7 +23,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
template <class _Arg1, class _Arg2, class _Result>
class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 pointer_to_binary_function
- : public binary_function<_Arg1, _Arg2, _Result>
+ : public __binary_function<_Arg1, _Arg2, _Result>
{
_Result (*__f_)(_Arg1, _Arg2);
public:
diff --git a/libcxx/include/__functional/pointer_to_unary_function.h b/libcxx/include/__functional/pointer_to_unary_function.h
index 0ac4561cc305..77d07adf20f0 100644
--- a/libcxx/include/__functional/pointer_to_unary_function.h
+++ b/libcxx/include/__functional/pointer_to_unary_function.h
@@ -14,7 +14,7 @@
#include <__functional/unary_function.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -23,7 +23,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
template <class _Arg, class _Result>
class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 pointer_to_unary_function
- : public unary_function<_Arg, _Result>
+ : public __unary_function<_Arg, _Result>
{
_Result (*__f_)(_Arg);
public:
diff --git a/libcxx/include/__functional/ranges_operations.h b/libcxx/include/__functional/ranges_operations.h
index 8b06240e46a7..3f63a86731e0 100644
--- a/libcxx/include/__functional/ranges_operations.h
+++ b/libcxx/include/__functional/ranges_operations.h
@@ -11,16 +11,17 @@
#define _LIBCPP___FUNCTIONAL_RANGES_OPERATIONS_H
#include <__config>
+#include <__utility/forward.h>
#include <concepts>
-#include <utility>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17
+
namespace ranges {
struct equal_to {
@@ -90,7 +91,8 @@ struct greater_equal {
};
} // namespace ranges
-#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
+
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__functional/reference_wrapper.h b/libcxx/include/__functional/reference_wrapper.h
index d04d51568beb..8245e3a04734 100644
--- a/libcxx/include/__functional/reference_wrapper.h
+++ b/libcxx/include/__functional/reference_wrapper.h
@@ -17,16 +17,13 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _Tp>
-class _LIBCPP_TEMPLATE_VIS reference_wrapper
-#if _LIBCPP_STD_VER <= 17 || !defined(_LIBCPP_ABI_NO_BINDER_BASES)
- : public __weak_result_type<_Tp>
-#endif
+class _LIBCPP_TEMPLATE_VIS reference_wrapper : public __weak_result_type<_Tp>
{
public:
// types
@@ -51,120 +48,13 @@ public:
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
type& get() const _NOEXCEPT {return *__f_;}
-#ifndef _LIBCPP_CXX03_LANG
// invoke
template <class... _ArgTypes>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
typename __invoke_of<type&, _ArgTypes...>::type
operator() (_ArgTypes&&... __args) const {
- return _VSTD::__invoke(get(), _VSTD::forward<_ArgTypes>(__args)...);
- }
-#else
-
- _LIBCPP_INLINE_VISIBILITY
- typename __invoke_return<type>::type
- operator() () const {
- return _VSTD::__invoke(get());
- }
-
- template <class _A0>
- _LIBCPP_INLINE_VISIBILITY
- typename __invoke_return0<type, _A0>::type
- operator() (_A0& __a0) const {
- return _VSTD::__invoke(get(), __a0);
- }
-
- template <class _A0>
- _LIBCPP_INLINE_VISIBILITY
- typename __invoke_return0<type, _A0 const>::type
- operator() (_A0 const& __a0) const {
- return _VSTD::__invoke(get(), __a0);
- }
-
- template <class _A0, class _A1>
- _LIBCPP_INLINE_VISIBILITY
- typename __invoke_return1<type, _A0, _A1>::type
- operator() (_A0& __a0, _A1& __a1) const {
- return _VSTD::__invoke(get(), __a0, __a1);
- }
-
- template <class _A0, class _A1>
- _LIBCPP_INLINE_VISIBILITY
- typename __invoke_return1<type, _A0 const, _A1>::type
- operator() (_A0 const& __a0, _A1& __a1) const {
- return _VSTD::__invoke(get(), __a0, __a1);
- }
-
- template <class _A0, class _A1>
- _LIBCPP_INLINE_VISIBILITY
- typename __invoke_return1<type, _A0, _A1 const>::type
- operator() (_A0& __a0, _A1 const& __a1) const {
- return _VSTD::__invoke(get(), __a0, __a1);
- }
-
- template <class _A0, class _A1>
- _LIBCPP_INLINE_VISIBILITY
- typename __invoke_return1<type, _A0 const, _A1 const>::type
- operator() (_A0 const& __a0, _A1 const& __a1) const {
- return _VSTD::__invoke(get(), __a0, __a1);
- }
-
- template <class _A0, class _A1, class _A2>
- _LIBCPP_INLINE_VISIBILITY
- typename __invoke_return2<type, _A0, _A1, _A2>::type
- operator() (_A0& __a0, _A1& __a1, _A2& __a2) const {
- return _VSTD::__invoke(get(), __a0, __a1, __a2);
- }
-
- template <class _A0, class _A1, class _A2>
- _LIBCPP_INLINE_VISIBILITY
- typename __invoke_return2<type, _A0 const, _A1, _A2>::type
- operator() (_A0 const& __a0, _A1& __a1, _A2& __a2) const {
- return _VSTD::__invoke(get(), __a0, __a1, __a2);
- }
-
- template <class _A0, class _A1, class _A2>
- _LIBCPP_INLINE_VISIBILITY
- typename __invoke_return2<type, _A0, _A1 const, _A2>::type
- operator() (_A0& __a0, _A1 const& __a1, _A2& __a2) const {
- return _VSTD::__invoke(get(), __a0, __a1, __a2);
- }
-
- template <class _A0, class _A1, class _A2>
- _LIBCPP_INLINE_VISIBILITY
- typename __invoke_return2<type, _A0, _A1, _A2 const>::type
- operator() (_A0& __a0, _A1& __a1, _A2 const& __a2) const {
- return _VSTD::__invoke(get(), __a0, __a1, __a2);
- }
-
- template <class _A0, class _A1, class _A2>
- _LIBCPP_INLINE_VISIBILITY
- typename __invoke_return2<type, _A0 const, _A1 const, _A2>::type
- operator() (_A0 const& __a0, _A1 const& __a1, _A2& __a2) const {
- return _VSTD::__invoke(get(), __a0, __a1, __a2);
- }
-
- template <class _A0, class _A1, class _A2>
- _LIBCPP_INLINE_VISIBILITY
- typename __invoke_return2<type, _A0 const, _A1, _A2 const>::type
- operator() (_A0 const& __a0, _A1& __a1, _A2 const& __a2) const {
- return _VSTD::__invoke(get(), __a0, __a1, __a2);
- }
-
- template <class _A0, class _A1, class _A2>
- _LIBCPP_INLINE_VISIBILITY
- typename __invoke_return2<type, _A0, _A1 const, _A2 const>::type
- operator() (_A0& __a0, _A1 const& __a1, _A2 const& __a2) const {
- return _VSTD::__invoke(get(), __a0, __a1, __a2);
- }
-
- template <class _A0, class _A1, class _A2>
- _LIBCPP_INLINE_VISIBILITY
- typename __invoke_return2<type, _A0 const, _A1 const, _A2 const>::type
- operator() (_A0 const& __a0, _A1 const& __a1, _A2 const& __a2) const {
- return _VSTD::__invoke(get(), __a0, __a1, __a2);
+ return std::__invoke(get(), std::forward<_ArgTypes>(__args)...);
}
-#endif // _LIBCPP_CXX03_LANG
};
#if _LIBCPP_STD_VER > 14
diff --git a/libcxx/include/__functional/unary_function.h b/libcxx/include/__functional/unary_function.h
index 499f9964676d..f07cac175a99 100644
--- a/libcxx/include/__functional/unary_function.h
+++ b/libcxx/include/__functional/unary_function.h
@@ -12,18 +12,40 @@
#include <__config>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
+#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION)
+
template <class _Arg, class _Result>
-struct _LIBCPP_TEMPLATE_VIS unary_function
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 unary_function
{
typedef _Arg argument_type;
typedef _Result result_type;
};
+#endif // _LIBCPP_STD_VER <= 14
+
+template <class _Arg, class _Result> struct __unary_function_keep_layout_base {
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+ using argument_type _LIBCPP_DEPRECATED_IN_CXX17 = _Arg;
+ using result_type _LIBCPP_DEPRECATED_IN_CXX17 = _Result;
+#endif
+};
+
+#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION)
+_LIBCPP_DIAGNOSTIC_PUSH
+_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wdeprecated-declarations")
+template <class _Arg, class _Result>
+using __unary_function = unary_function<_Arg, _Result>;
+_LIBCPP_DIAGNOSTIC_POP
+#else
+template <class _Arg, class _Result>
+using __unary_function = __unary_function_keep_layout_base<_Arg, _Result>;
+#endif
+
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___FUNCTIONAL_UNARY_FUNCTION_H
diff --git a/libcxx/include/__functional/unary_negate.h b/libcxx/include/__functional/unary_negate.h
index 71257cf40c0d..7f081903fe44 100644
--- a/libcxx/include/__functional/unary_negate.h
+++ b/libcxx/include/__functional/unary_negate.h
@@ -14,7 +14,7 @@
#include <__functional/unary_function.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -23,7 +23,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
template <class _Predicate>
class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 unary_negate
- : public unary_function<typename _Predicate::argument_type, bool>
+ : public __unary_function<typename _Predicate::argument_type, bool>
{
_Predicate __pred_;
public:
diff --git a/libcxx/include/__functional/unwrap_ref.h b/libcxx/include/__functional/unwrap_ref.h
index dc309add90df..f7207934e1b4 100644
--- a/libcxx/include/__functional/unwrap_ref.h
+++ b/libcxx/include/__functional/unwrap_ref.h
@@ -12,7 +12,7 @@
#include <__config>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__functional/weak_result_type.h b/libcxx/include/__functional/weak_result_type.h
index 32b1e0b1c6c4..96d8cf7146b1 100644
--- a/libcxx/include/__functional/weak_result_type.h
+++ b/libcxx/include/__functional/weak_result_type.h
@@ -16,7 +16,7 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -25,11 +25,10 @@ template <class _Tp>
struct __has_result_type
{
private:
- struct __two {char __lx; char __lxx;};
- template <class _Up> static __two __test(...);
- template <class _Up> static char __test(typename _Up::result_type* = 0);
+ template <class _Up> static false_type __test(...);
+ template <class _Up> static true_type __test(typename _Up::result_type* = 0);
public:
- static const bool value = sizeof(__test<_Tp>(0)) == 1;
+ static const bool value = decltype(__test<_Tp>(0))::value;
};
// __weak_result_type
@@ -41,8 +40,9 @@ private:
struct __two {char __lx; char __lxx;};
static __two __test(...);
template <class _Ap, class _Rp>
- static unary_function<_Ap, _Rp>
- __test(const volatile unary_function<_Ap, _Rp>*);
+ static __unary_function<_Ap, _Rp>
+ __test(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;
@@ -55,8 +55,9 @@ private:
struct __two {char __lx; char __lxx;};
static __two __test(...);
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>
+ __test(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;
@@ -89,7 +90,9 @@ struct __weak_result_type_imp // bool is true
: public __maybe_derive_from_unary_function<_Tp>,
public __maybe_derive_from_binary_function<_Tp>
{
- typedef _LIBCPP_NODEBUG typename _Tp::result_type result_type;
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+ using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = typename _Tp::result_type;
+#endif
};
template <class _Tp>
@@ -110,62 +113,68 @@ struct __weak_result_type
template <class _Rp>
struct __weak_result_type<_Rp ()>
{
- typedef _LIBCPP_NODEBUG _Rp result_type;
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+ using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp;
+#endif
};
template <class _Rp>
struct __weak_result_type<_Rp (&)()>
{
- typedef _LIBCPP_NODEBUG _Rp result_type;
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+ using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp;
+#endif
};
template <class _Rp>
struct __weak_result_type<_Rp (*)()>
{
- typedef _LIBCPP_NODEBUG _Rp result_type;
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+ using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp;
+#endif
};
// 1 argument case
template <class _Rp, class _A1>
struct __weak_result_type<_Rp (_A1)>
- : public unary_function<_A1, _Rp>
+ : public __unary_function<_A1, _Rp>
{
};
template <class _Rp, class _A1>
struct __weak_result_type<_Rp (&)(_A1)>
- : public unary_function<_A1, _Rp>
+ : public __unary_function<_A1, _Rp>
{
};
template <class _Rp, class _A1>
struct __weak_result_type<_Rp (*)(_A1)>
- : public unary_function<_A1, _Rp>
+ : public __unary_function<_A1, _Rp>
{
};
template <class _Rp, class _Cp>
struct __weak_result_type<_Rp (_Cp::*)()>
- : public unary_function<_Cp*, _Rp>
+ : public __unary_function<_Cp*, _Rp>
{
};
template <class _Rp, class _Cp>
struct __weak_result_type<_Rp (_Cp::*)() const>
- : public unary_function<const _Cp*, _Rp>
+ : public __unary_function<const _Cp*, _Rp>
{
};
template <class _Rp, class _Cp>
struct __weak_result_type<_Rp (_Cp::*)() volatile>
- : public unary_function<volatile _Cp*, _Rp>
+ : public __unary_function<volatile _Cp*, _Rp>
{
};
template <class _Rp, class _Cp>
struct __weak_result_type<_Rp (_Cp::*)() const volatile>
- : public unary_function<const volatile _Cp*, _Rp>
+ : public __unary_function<const volatile _Cp*, _Rp>
{
};
@@ -173,90 +182,102 @@ struct __weak_result_type<_Rp (_Cp::*)() const volatile>
template <class _Rp, class _A1, class _A2>
struct __weak_result_type<_Rp (_A1, _A2)>
- : public binary_function<_A1, _A2, _Rp>
+ : public __binary_function<_A1, _A2, _Rp>
{
};
template <class _Rp, class _A1, class _A2>
struct __weak_result_type<_Rp (*)(_A1, _A2)>
- : public binary_function<_A1, _A2, _Rp>
+ : public __binary_function<_A1, _A2, _Rp>
{
};
template <class _Rp, class _A1, class _A2>
struct __weak_result_type<_Rp (&)(_A1, _A2)>
- : public binary_function<_A1, _A2, _Rp>
+ : public __binary_function<_A1, _A2, _Rp>
{
};
template <class _Rp, class _Cp, class _A1>
struct __weak_result_type<_Rp (_Cp::*)(_A1)>
- : public binary_function<_Cp*, _A1, _Rp>
+ : public __binary_function<_Cp*, _A1, _Rp>
{
};
template <class _Rp, class _Cp, class _A1>
struct __weak_result_type<_Rp (_Cp::*)(_A1) const>
- : public binary_function<const _Cp*, _A1, _Rp>
+ : public __binary_function<const _Cp*, _A1, _Rp>
{
};
template <class _Rp, class _Cp, class _A1>
struct __weak_result_type<_Rp (_Cp::*)(_A1) volatile>
- : public binary_function<volatile _Cp*, _A1, _Rp>
+ : public __binary_function<volatile _Cp*, _A1, _Rp>
{
};
template <class _Rp, class _Cp, class _A1>
struct __weak_result_type<_Rp (_Cp::*)(_A1) const volatile>
- : public binary_function<const volatile _Cp*, _A1, _Rp>
+ : public __binary_function<const volatile _Cp*, _A1, _Rp>
{
};
-
-#ifndef _LIBCPP_CXX03_LANG
// 3 or more arguments
template <class _Rp, class _A1, class _A2, class _A3, class ..._A4>
struct __weak_result_type<_Rp (_A1, _A2, _A3, _A4...)>
{
- typedef _Rp result_type;
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+ using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp;
+#endif
};
template <class _Rp, class _A1, class _A2, class _A3, class ..._A4>
struct __weak_result_type<_Rp (&)(_A1, _A2, _A3, _A4...)>
{
- typedef _Rp result_type;
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+ using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp;
+#endif
};
template <class _Rp, class _A1, class _A2, class _A3, class ..._A4>
struct __weak_result_type<_Rp (*)(_A1, _A2, _A3, _A4...)>
{
- typedef _Rp result_type;
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+ using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp;
+#endif
};
template <class _Rp, class _Cp, class _A1, class _A2, class ..._A3>
struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...)>
{
- typedef _Rp result_type;
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+ using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp;
+#endif
};
template <class _Rp, class _Cp, class _A1, class _A2, class ..._A3>
struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) const>
{
- typedef _Rp result_type;
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+ using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp;
+#endif
};
template <class _Rp, class _Cp, class _A1, class _A2, class ..._A3>
struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) volatile>
{
- typedef _Rp result_type;
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+ using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp;
+#endif
};
template <class _Rp, class _Cp, class _A1, class _A2, class ..._A3>
struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) const volatile>
{
- typedef _Rp result_type;
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+ using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp;
+#endif
};
template <class _Tp, class ..._Args>
@@ -265,217 +286,6 @@ struct __invoke_return
typedef decltype(_VSTD::__invoke(declval<_Tp>(), declval<_Args>()...)) type;
};
-#else // defined(_LIBCPP_CXX03_LANG)
-
-template <class _Ret, class _T1, bool _IsFunc, bool _IsBase>
-struct __enable_invoke_imp;
-
-template <class _Ret, class _T1>
-struct __enable_invoke_imp<_Ret, _T1, true, true> {
- typedef _Ret _Bullet1;
- typedef _Bullet1 type;
-};
-
-template <class _Ret, class _T1>
-struct __enable_invoke_imp<_Ret, _T1, true, false> {
- typedef _Ret _Bullet2;
- typedef _Bullet2 type;
-};
-
-template <class _Ret, class _T1>
-struct __enable_invoke_imp<_Ret, _T1, false, true> {
- typedef typename add_lvalue_reference<
- typename __apply_cv<_T1, _Ret>::type
- >::type _Bullet3;
- typedef _Bullet3 type;
-};
-
-template <class _Ret, class _T1>
-struct __enable_invoke_imp<_Ret, _T1, false, false> {
- typedef typename add_lvalue_reference<
- typename __apply_cv<decltype(*declval<_T1>()), _Ret>::type
- >::type _Bullet4;
- typedef _Bullet4 type;
-};
-
-template <class _Ret, class _T1>
-struct __enable_invoke_imp<_Ret, _T1*, false, false> {
- typedef typename add_lvalue_reference<
- typename __apply_cv<_T1, _Ret>::type
- >::type _Bullet4;
- typedef _Bullet4 type;
-};
-
-template <class _Fn, class _T1,
- class _Traits = __member_pointer_traits<_Fn>,
- class _Ret = typename _Traits::_ReturnType,
- class _Class = typename _Traits::_ClassType>
-struct __enable_invoke : __enable_invoke_imp<
- _Ret, _T1,
- is_member_function_pointer<_Fn>::value,
- is_base_of<_Class, typename remove_reference<_T1>::type>::value>
-{
-};
-
-__nat __invoke(__any, ...);
-
-// first bullet
-
-template <class _Fn, class _T1>
-inline _LIBCPP_INLINE_VISIBILITY
-typename __enable_invoke<_Fn, _T1>::_Bullet1
-__invoke(_Fn __f, _T1& __t1) {
- return (__t1.*__f)();
-}
-
-template <class _Fn, class _T1, class _A0>
-inline _LIBCPP_INLINE_VISIBILITY
-typename __enable_invoke<_Fn, _T1>::_Bullet1
-__invoke(_Fn __f, _T1& __t1, _A0& __a0) {
- return (__t1.*__f)(__a0);
-}
-
-template <class _Fn, class _T1, class _A0, class _A1>
-inline _LIBCPP_INLINE_VISIBILITY
-typename __enable_invoke<_Fn, _T1>::_Bullet1
-__invoke(_Fn __f, _T1& __t1, _A0& __a0, _A1& __a1) {
- return (__t1.*__f)(__a0, __a1);
-}
-
-template <class _Fn, class _T1, class _A0, class _A1, class _A2>
-inline _LIBCPP_INLINE_VISIBILITY
-typename __enable_invoke<_Fn, _T1>::_Bullet1
-__invoke(_Fn __f, _T1& __t1, _A0& __a0, _A1& __a1, _A2& __a2) {
- return (__t1.*__f)(__a0, __a1, __a2);
-}
-
-template <class _Fn, class _T1>
-inline _LIBCPP_INLINE_VISIBILITY
-typename __enable_invoke<_Fn, _T1>::_Bullet2
-__invoke(_Fn __f, _T1& __t1) {
- return ((*__t1).*__f)();
-}
-
-template <class _Fn, class _T1, class _A0>
-inline _LIBCPP_INLINE_VISIBILITY
-typename __enable_invoke<_Fn, _T1>::_Bullet2
-__invoke(_Fn __f, _T1& __t1, _A0& __a0) {
- return ((*__t1).*__f)(__a0);
-}
-
-template <class _Fn, class _T1, class _A0, class _A1>
-inline _LIBCPP_INLINE_VISIBILITY
-typename __enable_invoke<_Fn, _T1>::_Bullet2
-__invoke(_Fn __f, _T1& __t1, _A0& __a0, _A1& __a1) {
- return ((*__t1).*__f)(__a0, __a1);
-}
-
-template <class _Fn, class _T1, class _A0, class _A1, class _A2>
-inline _LIBCPP_INLINE_VISIBILITY
-typename __enable_invoke<_Fn, _T1>::_Bullet2
-__invoke(_Fn __f, _T1& __t1, _A0& __a0, _A1& __a1, _A2& __a2) {
- return ((*__t1).*__f)(__a0, __a1, __a2);
-}
-
-template <class _Fn, class _T1>
-inline _LIBCPP_INLINE_VISIBILITY
-typename __enable_invoke<_Fn, _T1>::_Bullet3
-__invoke(_Fn __f, _T1& __t1) {
- return __t1.*__f;
-}
-
-template <class _Fn, class _T1>
-inline _LIBCPP_INLINE_VISIBILITY
-typename __enable_invoke<_Fn, _T1>::_Bullet4
-__invoke(_Fn __f, _T1& __t1) {
- return (*__t1).*__f;
-}
-
-// fifth bullet
-
-template <class _Fp>
-inline _LIBCPP_INLINE_VISIBILITY
-decltype(declval<_Fp&>()())
-__invoke(_Fp& __f)
-{
- return __f();
-}
-
-template <class _Fp, class _A0>
-inline _LIBCPP_INLINE_VISIBILITY
-decltype(declval<_Fp&>()(declval<_A0&>()))
-__invoke(_Fp& __f, _A0& __a0)
-{
- return __f(__a0);
-}
-
-template <class _Fp, class _A0, class _A1>
-inline _LIBCPP_INLINE_VISIBILITY
-decltype(declval<_Fp&>()(declval<_A0&>(), declval<_A1&>()))
-__invoke(_Fp& __f, _A0& __a0, _A1& __a1)
-{
- return __f(__a0, __a1);
-}
-
-template <class _Fp, class _A0, class _A1, class _A2>
-inline _LIBCPP_INLINE_VISIBILITY
-decltype(declval<_Fp&>()(declval<_A0&>(), declval<_A1&>(), declval<_A2&>()))
-__invoke(_Fp& __f, _A0& __a0, _A1& __a1, _A2& __a2)
-{
- return __f(__a0, __a1, __a2);
-}
-
-template <class _Fp, bool = __has_result_type<__weak_result_type<_Fp> >::value>
-struct __invoke_return
-{
- typedef typename __weak_result_type<_Fp>::result_type type;
-};
-
-template <class _Fp>
-struct __invoke_return<_Fp, false>
-{
- typedef decltype(_VSTD::__invoke(declval<_Fp&>())) type;
-};
-
-template <class _Tp, class _A0>
-struct __invoke_return0
-{
- typedef decltype(_VSTD::__invoke(declval<_Tp&>(), declval<_A0&>())) type;
-};
-
-template <class _Rp, class _Tp, class _A0>
-struct __invoke_return0<_Rp _Tp::*, _A0>
-{
- typedef typename __enable_invoke<_Rp _Tp::*, _A0>::type type;
-};
-
-template <class _Tp, class _A0, class _A1>
-struct __invoke_return1
-{
- typedef decltype(_VSTD::__invoke(declval<_Tp&>(), declval<_A0&>(),
- declval<_A1&>())) type;
-};
-
-template <class _Rp, class _Class, class _A0, class _A1>
-struct __invoke_return1<_Rp _Class::*, _A0, _A1> {
- typedef typename __enable_invoke<_Rp _Class::*, _A0>::type type;
-};
-
-template <class _Tp, class _A0, class _A1, class _A2>
-struct __invoke_return2
-{
- typedef decltype(_VSTD::__invoke(declval<_Tp&>(), declval<_A0&>(),
- declval<_A1&>(),
- declval<_A2&>())) type;
-};
-
-template <class _Ret, class _Class, class _A0, class _A1, class _A2>
-struct __invoke_return2<_Ret _Class::*, _A0, _A1, _A2> {
- typedef typename __enable_invoke<_Ret _Class::*, _A0>::type type;
-};
-
-#endif // !defined(_LIBCPP_CXX03_LANG)
-
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___FUNCTIONAL_WEAK_RESULT_TYPE_H
diff --git a/libcxx/include/__functional_base b/libcxx/include/__functional_base
deleted file mode 100644
index ccc3f3a58ca5..000000000000
--- a/libcxx/include/__functional_base
+++ /dev/null
@@ -1,32 +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_FUNCTIONAL_BASE
-#define _LIBCPP_FUNCTIONAL_BASE
-
-#include <__config>
-#include <__functional/binary_function.h>
-#include <__functional/invoke.h>
-#include <__functional/operations.h>
-#include <__functional/reference_wrapper.h>
-#include <__functional/unary_function.h>
-#include <__functional/weak_result_type.h>
-#include <__memory/allocator_arg_t.h>
-#include <__memory/uses_allocator.h>
-#include <exception>
-#include <new>
-#include <type_traits>
-#include <typeinfo>
-#include <utility>
-
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
-#endif
-
-#endif // _LIBCPP_FUNCTIONAL_BASE
diff --git a/libcxx/include/__fwd/span.h b/libcxx/include/__fwd/span.h
new file mode 100644
index 000000000000..f38b8cfa0526
--- /dev/null
+++ b/libcxx/include/__fwd/span.h
@@ -0,0 +1,37 @@
+// -*- 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_FWD_SPAN_H
+#define _LIBCPP_FWD_SPAN_H
+
+#include <__config>
+#include <cstddef>
+#include <limits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 17
+
+inline constexpr size_t dynamic_extent = numeric_limits<size_t>::max();
+template <typename _Tp, size_t _Extent = dynamic_extent> class span;
+
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP_FWD_SPAN_H
diff --git a/libcxx/include/__fwd/string_view.h b/libcxx/include/__fwd/string_view.h
new file mode 100644
index 000000000000..e5e77b292a6e
--- /dev/null
+++ b/libcxx/include/__fwd/string_view.h
@@ -0,0 +1,37 @@
+// -*- 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_FWD_STRING_VIEW_H
+#define _LIBCPP_FWD_STRING_VIEW_H
+
+#include <__config>
+#include <iosfwd> // char_traits
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template<class _CharT, class _Traits = char_traits<_CharT> >
+class _LIBCPP_TEMPLATE_VIS basic_string_view;
+
+typedef basic_string_view<char> string_view;
+#ifndef _LIBCPP_HAS_NO_CHAR8_T
+typedef basic_string_view<char8_t> u8string_view;
+#endif
+typedef basic_string_view<char16_t> u16string_view;
+typedef basic_string_view<char32_t> u32string_view;
+#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+typedef basic_string_view<wchar_t> wstring_view;
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_FWD_STRING_VIEW_H
diff --git a/libcxx/include/__hash_table b/libcxx/include/__hash_table
index adc732cffb01..20223014432f 100644
--- a/libcxx/include/__hash_table
+++ b/libcxx/include/__hash_table
@@ -7,22 +7,25 @@
//
//===----------------------------------------------------------------------===//
-#ifndef _LIBCPP__HASH_TABLE
-#define _LIBCPP__HASH_TABLE
+#ifndef _LIBCPP___HASH_TABLE
+#define _LIBCPP___HASH_TABLE
+#include <__algorithm/max.h>
+#include <__algorithm/min.h>
+#include <__assert>
#include <__bits> // __libcpp_clz
#include <__config>
#include <__debug>
-#include <algorithm>
+#include <__functional/hash.h>
+#include <__iterator/iterator_traits.h>
+#include <__utility/swap.h>
#include <cmath>
#include <initializer_list>
-#include <iterator>
#include <memory>
#include <type_traits>
-#include <utility>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
@@ -44,7 +47,7 @@ template <class ..._Args>
struct __is_hash_value_type : false_type {};
template <class _One>
-struct __is_hash_value_type<_One> : __is_hash_value_type_imp<typename __uncvref<_One>::type> {};
+struct __is_hash_value_type<_One> : __is_hash_value_type_imp<__uncvref_t<_One> > {};
_LIBCPP_FUNC_VIS
size_t __next_prime(size_t __n);
@@ -291,7 +294,7 @@ public:
_VSTD::__debug_db_insert_i(this);
}
-#if _LIBCPP_DEBUG_LEVEL == 2
+#ifdef _LIBCPP_ENABLE_DEBUG_MODE
_LIBCPP_INLINE_VISIBILITY
__hash_iterator(const __hash_iterator& __i)
: __node_(__i.__node_)
@@ -315,7 +318,7 @@ public:
}
return *this;
}
-#endif // _LIBCPP_DEBUG_LEVEL == 2
+#endif // _LIBCPP_ENABLE_DEBUG_MODE
_LIBCPP_INLINE_VISIBILITY
reference operator*() const {
@@ -357,19 +360,15 @@ public:
{return !(__x == __y);}
private:
-#if _LIBCPP_DEBUG_LEVEL == 2
_LIBCPP_INLINE_VISIBILITY
- __hash_iterator(__next_pointer __node, const void* __c) _NOEXCEPT
+ explicit __hash_iterator(__next_pointer __node, const void* __c) _NOEXCEPT
: __node_(__node)
{
+ (void)__c;
+#ifdef _LIBCPP_ENABLE_DEBUG_MODE
__get_db()->__insert_ic(this, __c);
- }
-#else
- _LIBCPP_INLINE_VISIBILITY
- __hash_iterator(__next_pointer __node) _NOEXCEPT
- : __node_(__node)
- {}
#endif
+ }
template <class, class, class, class> friend class __hash_table;
template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_const_iterator;
template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_map_iterator;
@@ -405,12 +404,12 @@ public:
__hash_const_iterator(const __non_const_iterator& __x) _NOEXCEPT
: __node_(__x.__node_)
{
-#if _LIBCPP_DEBUG_LEVEL == 2
+#ifdef _LIBCPP_ENABLE_DEBUG_MODE
__get_db()->__iterator_copy(this, _VSTD::addressof(__x));
#endif
}
-#if _LIBCPP_DEBUG_LEVEL == 2
+#ifdef _LIBCPP_ENABLE_DEBUG_MODE
_LIBCPP_INLINE_VISIBILITY
__hash_const_iterator(const __hash_const_iterator& __i)
: __node_(__i.__node_)
@@ -434,7 +433,7 @@ public:
}
return *this;
}
-#endif // _LIBCPP_DEBUG_LEVEL == 2
+#endif // _LIBCPP_ENABLE_DEBUG_MODE
_LIBCPP_INLINE_VISIBILITY
reference operator*() const {
@@ -475,19 +474,15 @@ public:
{return !(__x == __y);}
private:
-#if _LIBCPP_DEBUG_LEVEL == 2
_LIBCPP_INLINE_VISIBILITY
- __hash_const_iterator(__next_pointer __node, const void* __c) _NOEXCEPT
+ explicit __hash_const_iterator(__next_pointer __node, const void* __c) _NOEXCEPT
: __node_(__node)
{
+ (void)__c;
+#ifdef _LIBCPP_ENABLE_DEBUG_MODE
__get_db()->__insert_ic(this, __c);
- }
-#else
- _LIBCPP_INLINE_VISIBILITY
- __hash_const_iterator(__next_pointer __node) _NOEXCEPT
- : __node_(__node)
- {}
#endif
+ }
template <class, class, class, class> friend class __hash_table;
template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator;
template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_map;
@@ -516,7 +511,7 @@ public:
_VSTD::__debug_db_insert_i(this);
}
-#if _LIBCPP_DEBUG_LEVEL == 2
+#ifdef _LIBCPP_ENABLE_DEBUG_MODE
_LIBCPP_INLINE_VISIBILITY
__hash_local_iterator(const __hash_local_iterator& __i)
: __node_(__i.__node_),
@@ -544,7 +539,7 @@ public:
}
return *this;
}
-#endif // _LIBCPP_DEBUG_LEVEL == 2
+#endif // _LIBCPP_ENABLE_DEBUG_MODE
_LIBCPP_INLINE_VISIBILITY
reference operator*() const {
@@ -588,30 +583,20 @@ public:
{return !(__x == __y);}
private:
-#if _LIBCPP_DEBUG_LEVEL == 2
_LIBCPP_INLINE_VISIBILITY
- __hash_local_iterator(__next_pointer __node, size_t __bucket,
- size_t __bucket_count, const void* __c) _NOEXCEPT
+ explicit __hash_local_iterator(__next_pointer __node, size_t __bucket,
+ size_t __bucket_count, const void* __c) _NOEXCEPT
: __node_(__node),
__bucket_(__bucket),
__bucket_count_(__bucket_count)
{
+ (void)__c;
+#ifdef _LIBCPP_ENABLE_DEBUG_MODE
__get_db()->__insert_ic(this, __c);
+#endif
if (__node_ != nullptr)
__node_ = __node_->__next_;
}
-#else
- _LIBCPP_INLINE_VISIBILITY
- __hash_local_iterator(__next_pointer __node, size_t __bucket,
- size_t __bucket_count) _NOEXCEPT
- : __node_(__node),
- __bucket_(__bucket),
- __bucket_count_(__bucket_count)
- {
- if (__node_ != nullptr)
- __node_ = __node_->__next_;
- }
-#endif
template <class, class, class, class> friend class __hash_table;
template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator;
template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_map_iterator;
@@ -654,12 +639,12 @@ public:
__bucket_(__x.__bucket_),
__bucket_count_(__x.__bucket_count_)
{
-#if _LIBCPP_DEBUG_LEVEL == 2
+#ifdef _LIBCPP_ENABLE_DEBUG_MODE
__get_db()->__iterator_copy(this, _VSTD::addressof(__x));
#endif
}
-#if _LIBCPP_DEBUG_LEVEL == 2
+#ifdef _LIBCPP_ENABLE_DEBUG_MODE
_LIBCPP_INLINE_VISIBILITY
__hash_const_local_iterator(const __hash_const_local_iterator& __i)
: __node_(__i.__node_),
@@ -687,7 +672,7 @@ public:
}
return *this;
}
-#endif // _LIBCPP_DEBUG_LEVEL == 2
+#endif // _LIBCPP_ENABLE_DEBUG_MODE
_LIBCPP_INLINE_VISIBILITY
reference operator*() const {
@@ -731,30 +716,20 @@ public:
{return !(__x == __y);}
private:
-#if _LIBCPP_DEBUG_LEVEL == 2
_LIBCPP_INLINE_VISIBILITY
- __hash_const_local_iterator(__next_pointer __node_ptr, size_t __bucket,
- size_t __bucket_count, const void* __c) _NOEXCEPT
+ explicit __hash_const_local_iterator(__next_pointer __node_ptr, size_t __bucket,
+ size_t __bucket_count, const void* __c) _NOEXCEPT
: __node_(__node_ptr),
__bucket_(__bucket),
__bucket_count_(__bucket_count)
{
+ (void)__c;
+#ifdef _LIBCPP_ENABLE_DEBUG_MODE
__get_db()->__insert_ic(this, __c);
+#endif
if (__node_ != nullptr)
__node_ = __node_->__next_;
}
-#else
- _LIBCPP_INLINE_VISIBILITY
- __hash_const_local_iterator(__next_pointer __node_ptr, size_t __bucket,
- size_t __bucket_count) _NOEXCEPT
- : __node_(__node_ptr),
- __bucket_(__bucket),
- __bucket_count_(__bucket_count)
- {
- if (__node_ != nullptr)
- __node_ = __node_->__next_;
- }
-#endif
template <class, class, class, class> friend class __hash_table;
template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator;
};
@@ -1276,11 +1251,7 @@ public:
{
_LIBCPP_ASSERT(__n < bucket_count(),
"unordered container::begin(n) called with n >= bucket_count()");
-#if _LIBCPP_DEBUG_LEVEL == 2
return local_iterator(__bucket_list_[__n], __n, bucket_count(), this);
-#else
- return local_iterator(__bucket_list_[__n], __n, bucket_count());
-#endif
}
_LIBCPP_INLINE_VISIBILITY
@@ -1289,11 +1260,7 @@ public:
{
_LIBCPP_ASSERT(__n < bucket_count(),
"unordered container::end(n) called with n >= bucket_count()");
-#if _LIBCPP_DEBUG_LEVEL == 2
return local_iterator(nullptr, __n, bucket_count(), this);
-#else
- return local_iterator(nullptr, __n, bucket_count());
-#endif
}
_LIBCPP_INLINE_VISIBILITY
@@ -1302,11 +1269,7 @@ public:
{
_LIBCPP_ASSERT(__n < bucket_count(),
"unordered container::cbegin(n) called with n >= bucket_count()");
-#if _LIBCPP_DEBUG_LEVEL == 2
return const_local_iterator(__bucket_list_[__n], __n, bucket_count(), this);
-#else
- return const_local_iterator(__bucket_list_[__n], __n, bucket_count());
-#endif
}
_LIBCPP_INLINE_VISIBILITY
@@ -1315,21 +1278,17 @@ public:
{
_LIBCPP_ASSERT(__n < bucket_count(),
"unordered container::cend(n) called with n >= bucket_count()");
-#if _LIBCPP_DEBUG_LEVEL == 2
return const_local_iterator(nullptr, __n, bucket_count(), this);
-#else
- return const_local_iterator(nullptr, __n, bucket_count());
-#endif
}
-#if _LIBCPP_DEBUG_LEVEL == 2
+#ifdef _LIBCPP_ENABLE_DEBUG_MODE
bool __dereferenceable(const const_iterator* __i) const;
bool __decrementable(const const_iterator* __i) const;
bool __addable(const const_iterator* __i, ptrdiff_t __n) const;
bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const;
-#endif // _LIBCPP_DEBUG_LEVEL == 2
+#endif // _LIBCPP_ENABLE_DEBUG_MODE
private:
void __rehash(size_type __n);
@@ -1509,9 +1468,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::~__hash_table()
#endif
__deallocate_node(__p1_.first().__next_);
-#if _LIBCPP_DEBUG_LEVEL == 2
- __get_db()->__erase_c(this);
-#endif
+ std::__debug_db_erase_c(this);
}
template <class _Tp, class _Hash, class _Equal, class _Alloc>
@@ -1553,7 +1510,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__deallocate_node(__next_pointer __np)
while (__np != nullptr)
{
__next_pointer __next = __np->__next_;
-#if _LIBCPP_DEBUG_LEVEL == 2
+#ifdef _LIBCPP_ENABLE_DEBUG_MODE
__c_node* __c = __get_db()->__find_c_and_lock(this);
for (__i_node** __p = __c->end_; __p != __c->beg_; )
{
@@ -1614,9 +1571,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign(
__u.__p1_.first().__next_ = nullptr;
__u.size() = 0;
}
-#if _LIBCPP_DEBUG_LEVEL == 2
- __get_db()->swap(this, _VSTD::addressof(__u));
-#endif
+ std::__debug_db_swap(this, std::addressof(__u));
}
template <class _Tp, class _Hash, class _Equal, class _Alloc>
@@ -1766,11 +1721,7 @@ inline
typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
__hash_table<_Tp, _Hash, _Equal, _Alloc>::begin() _NOEXCEPT
{
-#if _LIBCPP_DEBUG_LEVEL == 2
return iterator(__p1_.first().__next_, this);
-#else
- return iterator(__p1_.first().__next_);
-#endif
}
template <class _Tp, class _Hash, class _Equal, class _Alloc>
@@ -1778,11 +1729,7 @@ inline
typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
__hash_table<_Tp, _Hash, _Equal, _Alloc>::end() _NOEXCEPT
{
-#if _LIBCPP_DEBUG_LEVEL == 2
return iterator(nullptr, this);
-#else
- return iterator(nullptr);
-#endif
}
template <class _Tp, class _Hash, class _Equal, class _Alloc>
@@ -1790,11 +1737,7 @@ inline
typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator
__hash_table<_Tp, _Hash, _Equal, _Alloc>::begin() const _NOEXCEPT
{
-#if _LIBCPP_DEBUG_LEVEL == 2
return const_iterator(__p1_.first().__next_, this);
-#else
- return const_iterator(__p1_.first().__next_);
-#endif
}
template <class _Tp, class _Hash, class _Equal, class _Alloc>
@@ -1802,11 +1745,7 @@ inline
typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator
__hash_table<_Tp, _Hash, _Equal, _Alloc>::end() const _NOEXCEPT
{
-#if _LIBCPP_DEBUG_LEVEL == 2
return const_iterator(nullptr, this);
-#else
- return const_iterator(nullptr);
-#endif
}
template <class _Tp, class _Hash, class _Equal, class _Alloc>
@@ -1911,11 +1850,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique(__node_pointer __
__existing_node = __nd->__ptr();
__inserted = true;
}
-#if _LIBCPP_DEBUG_LEVEL == 2
return pair<iterator, bool>(iterator(__existing_node, this), __inserted);
-#else
- return pair<iterator, bool>(iterator(__existing_node), __inserted);
-#endif
}
// Prepare the container for an insertion of the value __cp_val with the hash
@@ -2009,11 +1944,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(__node_pointer __c
__next_pointer __pn = __node_insert_multi_prepare(__cp->__hash(), __cp->__value_);
__node_insert_multi_perform(__cp, __pn);
-#if _LIBCPP_DEBUG_LEVEL == 2
return iterator(__cp->__ptr(), this);
-#else
- return iterator(__cp->__ptr());
-#endif
}
template <class _Tp, class _Hash, class _Equal, class _Alloc>
@@ -2042,11 +1973,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(
__cp->__next_ = __np;
__pp->__next_ = static_cast<__next_pointer>(__cp);
++size();
-#if _LIBCPP_DEBUG_LEVEL == 2
return iterator(static_cast<__next_pointer>(__cp), this);
-#else
- return iterator(static_cast<__next_pointer>(__cp));
-#endif
}
return __node_insert_multi(__cp);
}
@@ -2112,11 +2039,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique_key_args(_Key const&
__inserted = true;
}
__done:
-#if _LIBCPP_DEBUG_LEVEL == 2
return pair<iterator, bool>(iterator(__nd, this), __inserted);
-#else
- return pair<iterator, bool>(iterator(__nd), __inserted);
-#endif
}
template <class _Tp, class _Hash, class _Equal, class _Alloc>
@@ -2318,9 +2241,7 @@ template <class _Tp, class _Hash, class _Equal, class _Alloc>
void
__hash_table<_Tp, _Hash, _Equal, _Alloc>::__rehash(size_type __nbc)
{
-#if _LIBCPP_DEBUG_LEVEL == 2
- __get_db()->__invalidate_all(this);
-#endif
+ std::__debug_db_invalidate_all(this);
__pointer_allocator& __npa = __bucket_list_.get_deleter().__alloc();
__bucket_list_.reset(__nbc > 0 ?
__pointer_alloc_traits::allocate(__npa, __nbc) : nullptr);
@@ -2389,11 +2310,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::find(const _Key& __k)
{
if ((__nd->__hash() == __hash)
&& key_eq()(__nd->__upcast()->__value_, __k))
-#if _LIBCPP_DEBUG_LEVEL == 2
return iterator(__nd, this);
-#else
- return iterator(__nd);
-#endif
}
}
}
@@ -2420,11 +2337,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::find(const _Key& __k) const
{
if ((__nd->__hash() == __hash)
&& key_eq()(__nd->__upcast()->__value_, __k))
-#if _LIBCPP_DEBUG_LEVEL == 2
return const_iterator(__nd, this);
-#else
- return const_iterator(__nd);
-#endif
}
}
@@ -2475,13 +2388,9 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::erase(const_iterator __p)
_LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this,
"unordered container erase(iterator) called with an iterator not"
" referring to this container");
- _LIBCPP_DEBUG_ASSERT(__p != end(),
- "unordered container erase(iterator) called with a non-dereferenceable iterator");
-#if _LIBCPP_DEBUG_LEVEL == 2
+ _LIBCPP_ASSERT(__p != end(),
+ "unordered container erase(iterator) called with a non-dereferenceable iterator");
iterator __r(__np, this);
-#else
- iterator __r(__np);
-#endif
++__r;
remove(__p);
return __r;
@@ -2504,11 +2413,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::erase(const_iterator __first,
erase(__p);
}
__next_pointer __np = __last.__node_;
-#if _LIBCPP_DEBUG_LEVEL == 2
return iterator (__np, this);
-#else
- return iterator (__np);
-#endif
}
template <class _Tp, class _Hash, class _Equal, class _Alloc>
@@ -2575,7 +2480,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::remove(const_iterator __p) _NOEXCEPT
__pn->__next_ = __cn->__next_;
__cn->__next_ = nullptr;
--size();
-#if _LIBCPP_DEBUG_LEVEL == 2
+#ifdef _LIBCPP_ENABLE_DEBUG_MODE
__c_node* __c = __get_db()->__find_c_and_lock(this);
for (__i_node** __dp = __c->end_; __dp != __c->beg_; )
{
@@ -2726,9 +2631,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::swap(__hash_table& __u)
if (__u.size() > 0)
__u.__bucket_list_[__constrain_hash(__u.__p1_.first().__next_->__hash(), __u.bucket_count())] =
__u.__p1_.first().__ptr();
-#if _LIBCPP_DEBUG_LEVEL == 2
- __get_db()->swap(this, _VSTD::addressof(__u));
-#endif
+ std::__debug_db_swap(this, std::addressof(__u));
}
template <class _Tp, class _Hash, class _Equal, class _Alloc>
@@ -2760,7 +2663,7 @@ swap(__hash_table<_Tp, _Hash, _Equal, _Alloc>& __x,
__x.swap(__y);
}
-#if _LIBCPP_DEBUG_LEVEL == 2
+#ifdef _LIBCPP_ENABLE_DEBUG_MODE
template <class _Tp, class _Hash, class _Equal, class _Alloc>
bool
@@ -2790,10 +2693,10 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__subscriptable(const const_iterator*,
return false;
}
-#endif // _LIBCPP_DEBUG_LEVEL == 2
+#endif // _LIBCPP_ENABLE_DEBUG_MODE
_LIBCPP_END_NAMESPACE_STD
_LIBCPP_POP_MACROS
-#endif // _LIBCPP__HASH_TABLE
+#endif // _LIBCPP___HASH_TABLE
diff --git a/libcxx/include/__ios/fpos.h b/libcxx/include/__ios/fpos.h
new file mode 100644
index 000000000000..87f0135fc3ea
--- /dev/null
+++ b/libcxx/include/__ios/fpos.h
@@ -0,0 +1,79 @@
+// -*- 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___IOS_FPOS_H
+#define _LIBCPP___IOS_FPOS_H
+
+#include <__config>
+#include <iosfwd>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _StateT>
+class _LIBCPP_TEMPLATE_VIS fpos {
+private:
+ _StateT __st_;
+ streamoff __off_;
+
+public:
+ _LIBCPP_HIDE_FROM_ABI fpos(streamoff __off = streamoff()) : __st_(), __off_(__off) {}
+
+ _LIBCPP_HIDE_FROM_ABI operator streamoff() const { return __off_; }
+
+ _LIBCPP_HIDE_FROM_ABI _StateT state() const { return __st_; }
+ _LIBCPP_HIDE_FROM_ABI void state(_StateT __st) { __st_ = __st; }
+
+ _LIBCPP_HIDE_FROM_ABI fpos& operator+=(streamoff __off) {
+ __off_ += __off;
+ return *this;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI fpos operator+(streamoff __off) const {
+ fpos __t(*this);
+ __t += __off;
+ return __t;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI fpos& operator-=(streamoff __off) {
+ __off_ -= __off;
+ return *this;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI fpos operator-(streamoff __off) const {
+ fpos __t(*this);
+ __t -= __off;
+ return __t;
+ }
+};
+
+template <class _StateT>
+inline _LIBCPP_HIDE_FROM_ABI
+streamoff operator-(const fpos<_StateT>& __x, const fpos<_StateT>& __y) {
+ return streamoff(__x) - streamoff(__y);
+}
+
+template <class _StateT>
+inline _LIBCPP_HIDE_FROM_ABI
+bool operator==(const fpos<_StateT>& __x, const fpos<_StateT>& __y) {
+ return streamoff(__x) == streamoff(__y);
+}
+
+template <class _StateT>
+inline _LIBCPP_HIDE_FROM_ABI
+bool operator!=(const fpos<_StateT>& __x, const fpos<_StateT>& __y) {
+ return streamoff(__x) != streamoff(__y);
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___IOS_FPOS_H
diff --git a/libcxx/include/__iterator/access.h b/libcxx/include/__iterator/access.h
index 5e0d6b35153b..7abd4c5573d6 100644
--- a/libcxx/include/__iterator/access.h
+++ b/libcxx/include/__iterator/access.h
@@ -14,7 +14,7 @@
#include <cstddef>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__iterator/advance.h b/libcxx/include/__iterator/advance.h
index 5b0e97d76be9..4b8b0dc970a1 100644
--- a/libcxx/include/__iterator/advance.h
+++ b/libcxx/include/__iterator/advance.h
@@ -10,19 +10,20 @@
#ifndef _LIBCPP___ITERATOR_ADVANCE_H
#define _LIBCPP___ITERATOR_ADVANCE_H
+#include <__assert>
#include <__config>
-#include <__debug>
#include <__iterator/concepts.h>
#include <__iterator/incrementable_traits.h>
#include <__iterator/iterator_traits.h>
#include <__utility/move.h>
+#include <__utility/unreachable.h>
#include <concepts>
#include <cstdlib>
#include <limits>
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -64,7 +65,7 @@ void advance(_InputIter& __i, _Distance __orig_n) {
_VSTD::__advance(__i, __n, typename iterator_traits<_InputIter>::iterator_category());
}
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
// [range.iter.op.advance]
@@ -116,47 +117,46 @@ public:
}
}
- // Preconditions: Either `assignable_from<I&, S> || sized_sentinel_for<S, I>` is modeled, or [i, bound) denotes a range.
+ // Preconditions: Either `assignable_from<I&, S> || sized_sentinel_for<S, I>` is modeled, or [i, bound_sentinel) denotes a range.
template <input_or_output_iterator _Ip, sentinel_for<_Ip> _Sp>
- _LIBCPP_HIDE_FROM_ABI
- constexpr void operator()(_Ip& __i, _Sp __bound) const {
- // If `I` and `S` model `assignable_from<I&, S>`, equivalent to `i = std::move(bound)`.
+ _LIBCPP_HIDE_FROM_ABI constexpr void operator()(_Ip& __i, _Sp __bound_sentinel) const {
+ // If `I` and `S` model `assignable_from<I&, S>`, equivalent to `i = std::move(bound_sentinel)`.
if constexpr (assignable_from<_Ip&, _Sp>) {
- __i = _VSTD::move(__bound);
+ __i = _VSTD::move(__bound_sentinel);
}
- // Otherwise, if `S` and `I` model `sized_sentinel_for<S, I>`, equivalent to `ranges::advance(i, bound - i)`.
+ // Otherwise, if `S` and `I` model `sized_sentinel_for<S, I>`, equivalent to `ranges::advance(i, bound_sentinel - i)`.
else if constexpr (sized_sentinel_for<_Sp, _Ip>) {
- (*this)(__i, __bound - __i);
+ (*this)(__i, __bound_sentinel - __i);
}
- // Otherwise, while `bool(i != bound)` is true, increments `i`.
+ // Otherwise, while `bool(i != bound_sentinel)` is true, increments `i`.
else {
- while (__i != __bound) {
+ while (__i != __bound_sentinel) {
++__i;
}
}
}
// Preconditions:
- // * If `n > 0`, [i, bound) denotes a range.
- // * If `n == 0`, [i, bound) or [bound, i) denotes a range.
- // * If `n < 0`, [bound, i) denotes a range, `I` models `bidirectional_iterator`, and `I` and `S` model `same_as<I, S>`.
- // Returns: `n - M`, where `M` is the difference between the the ending and starting position.
+ // * If `n > 0`, [i, bound_sentinel) denotes a range.
+ // * If `n == 0`, [i, bound_sentinel) or [bound_sentinel, i) denotes a range.
+ // * If `n < 0`, [bound_sentinel, i) denotes a range, `I` models `bidirectional_iterator`, and `I` and `S` model `same_as<I, S>`.
+ // Returns: `n - M`, where `M` is the difference between the ending and starting position.
template <input_or_output_iterator _Ip, sentinel_for<_Ip> _Sp>
- _LIBCPP_HIDE_FROM_ABI
- constexpr iter_difference_t<_Ip> operator()(_Ip& __i, iter_difference_t<_Ip> __n, _Sp __bound) const {
+ _LIBCPP_HIDE_FROM_ABI constexpr iter_difference_t<_Ip> operator()(_Ip& __i, iter_difference_t<_Ip> __n,
+ _Sp __bound_sentinel) const {
_LIBCPP_ASSERT((__n >= 0) || (bidirectional_iterator<_Ip> && same_as<_Ip, _Sp>),
"If `n < 0`, then `bidirectional_iterator<I> && same_as<I, S>` must be true.");
// If `S` and `I` model `sized_sentinel_for<S, I>`:
if constexpr (sized_sentinel_for<_Sp, _Ip>) {
- // If |n| >= |bound - i|, equivalent to `ranges::advance(i, bound)`.
+ // If |n| >= |bound_sentinel - i|, equivalent to `ranges::advance(i, bound_sentinel)`.
// __magnitude_geq(a, b) returns |a| >= |b|, assuming they have the same sign.
auto __magnitude_geq = [](auto __a, auto __b) {
return __a == 0 ? __b == 0 :
__a > 0 ? __a >= __b :
__a <= __b;
};
- if (const auto __M = __bound - __i; __magnitude_geq(__n, __M)) {
- (*this)(__i, __bound);
+ if (const auto __M = __bound_sentinel - __i; __magnitude_geq(__n, __M)) {
+ (*this)(__i, __bound_sentinel);
return __n - __M;
}
@@ -164,16 +164,16 @@ public:
(*this)(__i, __n);
return 0;
} else {
- // Otherwise, if `n` is non-negative, while `bool(i != bound)` is true, increments `i` but at
+ // Otherwise, if `n` is non-negative, while `bool(i != bound_sentinel)` is true, increments `i` but at
// most `n` times.
- while (__i != __bound && __n > 0) {
+ while (__i != __bound_sentinel && __n > 0) {
++__i;
--__n;
}
- // Otherwise, while `bool(i != bound)` is true, decrements `i` but at most `-n` times.
+ // Otherwise, while `bool(i != bound_sentinel)` is true, decrements `i` but at most `-n` times.
if constexpr (bidirectional_iterator<_Ip> && same_as<_Ip, _Sp>) {
- while (__i != __bound && __n < 0) {
+ while (__i != __bound_sentinel && __n < 0) {
--__i;
++__n;
}
@@ -181,7 +181,7 @@ public:
return __n;
}
- _LIBCPP_UNREACHABLE();
+ __libcpp_unreachable();
}
};
@@ -192,7 +192,7 @@ inline namespace __cpo {
} // namespace __cpo
} // namespace ranges
-#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__iterator/back_insert_iterator.h b/libcxx/include/__iterator/back_insert_iterator.h
index 844babe5c5ed..7bbf5b09e0e5 100644
--- a/libcxx/include/__iterator/back_insert_iterator.h
+++ b/libcxx/include/__iterator/back_insert_iterator.h
@@ -18,7 +18,7 @@
#include <cstddef>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -55,6 +55,8 @@ public:
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 back_insert_iterator& operator*() {return *this;}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 back_insert_iterator& operator++() {return *this;}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 back_insert_iterator operator++(int) {return *this;}
+
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 _Container* __get_container() const { return container; }
};
template <class _Container>
diff --git a/libcxx/include/__iterator/bounded_iter.h b/libcxx/include/__iterator/bounded_iter.h
new file mode 100644
index 000000000000..a395e2b638eb
--- /dev/null
+++ b/libcxx/include/__iterator/bounded_iter.h
@@ -0,0 +1,229 @@
+// -*- 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___ITERATOR_BOUNDED_ITER_H
+#define _LIBCPP___ITERATOR_BOUNDED_ITER_H
+
+#include <__assert>
+#include <__config>
+#include <__iterator/iterator_traits.h>
+#include <__memory/pointer_traits.h>
+#include <__utility/move.h>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+// Iterator wrapper that carries the valid range it is allowed to access.
+//
+// This is a simple iterator wrapper for contiguous iterators that points
+// within a [begin, end) range and carries these bounds with it. The iterator
+// ensures that it is pointing within that [begin, end) range when it is
+// dereferenced.
+//
+// Arithmetic operations are allowed and the bounds of the resulting iterator
+// are not checked. Hence, it is possible to create an iterator pointing outside
+// its range, but it is not possible to dereference it.
+template <class _Iterator, class = __enable_if_t< __is_cpp17_contiguous_iterator<_Iterator>::value > >
+struct __bounded_iter {
+ using value_type = typename iterator_traits<_Iterator>::value_type;
+ using difference_type = typename iterator_traits<_Iterator>::difference_type;
+ using pointer = typename iterator_traits<_Iterator>::pointer;
+ using reference = typename iterator_traits<_Iterator>::reference;
+ using iterator_category = typename iterator_traits<_Iterator>::iterator_category;
+#if _LIBCPP_STD_VER > 17
+ using iterator_concept = contiguous_iterator_tag;
+#endif
+
+ // Create a singular iterator.
+ //
+ // Such an iterator does not point to any object and is conceptually out of bounds, so it is
+ // not dereferenceable. Observing operations like comparison and assignment are valid.
+ _LIBCPP_HIDE_FROM_ABI __bounded_iter() = default;
+
+ _LIBCPP_HIDE_FROM_ABI __bounded_iter(__bounded_iter const&) = default;
+ _LIBCPP_HIDE_FROM_ABI __bounded_iter(__bounded_iter&&) = default;
+
+ template <class _OtherIterator, class = __enable_if_t< is_convertible<_OtherIterator, _Iterator>::value > >
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __bounded_iter(__bounded_iter<_OtherIterator> const& __other) _NOEXCEPT
+ : __current_(__other.__current_),
+ __begin_(__other.__begin_),
+ __end_(__other.__end_) {}
+
+ // Assign a bounded iterator to another one, rebinding the bounds of the iterator as well.
+ _LIBCPP_HIDE_FROM_ABI __bounded_iter& operator=(__bounded_iter const&) = default;
+ _LIBCPP_HIDE_FROM_ABI __bounded_iter& operator=(__bounded_iter&&) = default;
+
+private:
+ // Create an iterator wrapping the given iterator, and whose bounds are described
+ // by the provided [begin, end) range.
+ //
+ // This constructor does not check whether the resulting iterator is within its bounds.
+ // However, it does check that the provided [begin, end) range is a valid range (that
+ // is, begin <= end).
+ //
+ // Since it is non-standard for iterators to have this constructor, __bounded_iter must
+ // be created via `std::__make_bounded_iter`.
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 explicit __bounded_iter(
+ _Iterator __current, _Iterator __begin, _Iterator __end)
+ : __current_(__current), __begin_(__begin), __end_(__end) {
+ _LIBCPP_ASSERT(__begin <= __end, "__bounded_iter(current, begin, end): [begin, end) is not a valid range");
+ }
+
+ template <class _It>
+ friend _LIBCPP_CONSTEXPR __bounded_iter<_It> __make_bounded_iter(_It, _It, _It);
+
+public:
+ // Dereference and indexing operations.
+ //
+ // These operations check that the iterator is dereferenceable, that is within [begin, end).
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 reference operator*() const _NOEXCEPT {
+ _LIBCPP_ASSERT(
+ __in_bounds(__current_), "__bounded_iter::operator*: Attempt to dereference an out-of-range iterator");
+ return *__current_;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 pointer operator->() const _NOEXCEPT {
+ _LIBCPP_ASSERT(
+ __in_bounds(__current_), "__bounded_iter::operator->: Attempt to dereference an out-of-range iterator");
+ return std::__to_address(__current_);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 reference operator[](difference_type __n) const _NOEXCEPT {
+ _LIBCPP_ASSERT(
+ __in_bounds(__current_ + __n), "__bounded_iter::operator[]: Attempt to index an iterator out-of-range");
+ return __current_[__n];
+ }
+
+ // Arithmetic operations.
+ //
+ // These operations do not check that the resulting iterator is within the bounds, since that
+ // would make it impossible to create a past-the-end iterator.
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 __bounded_iter& operator++() _NOEXCEPT {
+ ++__current_;
+ return *this;
+ }
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 __bounded_iter operator++(int) _NOEXCEPT {
+ __bounded_iter __tmp(*this);
+ ++*this;
+ return __tmp;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 __bounded_iter& operator--() _NOEXCEPT {
+ --__current_;
+ return *this;
+ }
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 __bounded_iter operator--(int) _NOEXCEPT {
+ __bounded_iter __tmp(*this);
+ --*this;
+ return __tmp;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 __bounded_iter& operator+=(difference_type __n) _NOEXCEPT {
+ __current_ += __n;
+ return *this;
+ }
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 friend __bounded_iter
+ operator+(__bounded_iter const& __self, difference_type __n) _NOEXCEPT {
+ __bounded_iter __tmp(__self);
+ __tmp += __n;
+ return __tmp;
+ }
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 friend __bounded_iter
+ operator+(difference_type __n, __bounded_iter const& __self) _NOEXCEPT {
+ __bounded_iter __tmp(__self);
+ __tmp += __n;
+ return __tmp;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 __bounded_iter& operator-=(difference_type __n) _NOEXCEPT {
+ __current_ -= __n;
+ return *this;
+ }
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 friend __bounded_iter
+ operator-(__bounded_iter const& __self, difference_type __n) _NOEXCEPT {
+ __bounded_iter __tmp(__self);
+ __tmp -= __n;
+ return __tmp;
+ }
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 friend difference_type
+ operator-(__bounded_iter const& __x, __bounded_iter const& __y) _NOEXCEPT {
+ return __x.__current_ - __y.__current_;
+ }
+
+ // Comparison operations.
+ //
+ // These operations do not check whether the iterators are within their bounds.
+ // The valid range for each iterator is also not considered as part of the comparison,
+ // i.e. two iterators pointing to the same location will be considered equal even
+ // if they have different validity ranges.
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR friend bool
+ operator==(__bounded_iter const& __x, __bounded_iter const& __y) _NOEXCEPT {
+ return __x.__current_ == __y.__current_;
+ }
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR friend bool
+ operator!=(__bounded_iter const& __x, __bounded_iter const& __y) _NOEXCEPT {
+ return __x.__current_ != __y.__current_;
+ }
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR friend bool
+ operator<(__bounded_iter const& __x, __bounded_iter const& __y) _NOEXCEPT {
+ return __x.__current_ < __y.__current_;
+ }
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR friend bool
+ operator>(__bounded_iter const& __x, __bounded_iter const& __y) _NOEXCEPT {
+ return __x.__current_ > __y.__current_;
+ }
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR friend bool
+ operator<=(__bounded_iter const& __x, __bounded_iter const& __y) _NOEXCEPT {
+ return __x.__current_ <= __y.__current_;
+ }
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR friend bool
+ operator>=(__bounded_iter const& __x, __bounded_iter const& __y) _NOEXCEPT {
+ return __x.__current_ >= __y.__current_;
+ }
+
+private:
+ // Return whether the given iterator is in the bounds of this __bounded_iter.
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool __in_bounds(_Iterator const& __iter) const {
+ return __iter >= __begin_ && __iter < __end_;
+ }
+
+ template <class>
+ friend struct pointer_traits;
+ _Iterator __current_; // current iterator
+ _Iterator __begin_, __end_; // valid range represented as [begin, end)
+};
+
+template <class _It>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __bounded_iter<_It> __make_bounded_iter(_It __it, _It __begin, _It __end) {
+ return __bounded_iter<_It>(std::move(__it), std::move(__begin), std::move(__end));
+}
+
+#if _LIBCPP_STD_VER <= 17
+template <class _Iterator>
+struct __is_cpp17_contiguous_iterator<__bounded_iter<_Iterator> > : true_type {};
+#endif
+
+template <class _Iterator>
+struct pointer_traits<__bounded_iter<_Iterator> > {
+ using pointer = __bounded_iter<_Iterator>;
+ using element_type = typename pointer_traits<_Iterator>::element_type;
+ using difference_type = typename pointer_traits<_Iterator>::difference_type;
+
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR static element_type* to_address(pointer __it) _NOEXCEPT {
+ return std::__to_address(__it.__current_);
+ }
+};
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___ITERATOR_BOUNDED_ITER_H
diff --git a/libcxx/include/__iterator/common_iterator.h b/libcxx/include/__iterator/common_iterator.h
index 68309ee08b30..abcc0b675e63 100644
--- a/libcxx/include/__iterator/common_iterator.h
+++ b/libcxx/include/__iterator/common_iterator.h
@@ -10,8 +10,8 @@
#ifndef _LIBCPP___ITERATOR_COMMON_ITERATOR_H
#define _LIBCPP___ITERATOR_COMMON_ITERATOR_H
+#include <__assert>
#include <__config>
-#include <__debug>
#include <__iterator/concepts.h>
#include <__iterator/incrementable_traits.h>
#include <__iterator/iter_move.h>
@@ -22,12 +22,12 @@
#include <variant>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17
template<class _Iter>
concept __can_use_postfix_proxy =
@@ -37,31 +37,18 @@ concept __can_use_postfix_proxy =
template<input_or_output_iterator _Iter, sentinel_for<_Iter> _Sent>
requires (!same_as<_Iter, _Sent> && copyable<_Iter>)
class common_iterator {
- class __proxy {
- friend common_iterator;
-
- iter_value_t<_Iter> __value;
- // We can move __x because the only caller verifies that __x is not a reference.
- constexpr __proxy(iter_reference_t<_Iter>&& __x)
- : __value(_VSTD::move(__x)) {}
-
- public:
+ struct __proxy {
constexpr const iter_value_t<_Iter>* operator->() const noexcept {
- return _VSTD::addressof(__value);
+ return _VSTD::addressof(__value_);
}
+ iter_value_t<_Iter> __value_;
};
- class __postfix_proxy {
- friend common_iterator;
-
- iter_value_t<_Iter> __value;
- constexpr __postfix_proxy(iter_reference_t<_Iter>&& __x)
- : __value(_VSTD::forward<iter_reference_t<_Iter>>(__x)) {}
-
- public:
+ struct __postfix_proxy {
constexpr const iter_value_t<_Iter>& operator*() const noexcept {
- return __value;
+ return __value_;
}
+ iter_value_t<_Iter> __value_;
};
public:
@@ -133,7 +120,7 @@ public:
auto&& __tmp = *_VSTD::__unchecked_get<_Iter>(__hold_);
return _VSTD::addressof(__tmp);
} else {
- return __proxy(*_VSTD::__unchecked_get<_Iter>(__hold_));
+ return __proxy{*_VSTD::__unchecked_get<_Iter>(__hold_)};
}
}
@@ -148,11 +135,11 @@ public:
auto __tmp = *this;
++*this;
return __tmp;
- } else if constexpr (requires (_Iter& __i) { { *__i++ } -> __referenceable; } ||
+ } else if constexpr (requires (_Iter& __i) { { *__i++ } -> __can_reference; } ||
!__can_use_postfix_proxy<_Iter>) {
return _VSTD::__unchecked_get<_Iter>(__hold_)++;
} else {
- __postfix_proxy __p(**this);
+ auto __p = __postfix_proxy{**this};
++*this;
return __p;
}
@@ -276,7 +263,7 @@ struct iterator_traits<common_iterator<_Iter, _Sent>> {
using reference = iter_reference_t<_Iter>;
};
-#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__iterator/concepts.h b/libcxx/include/__iterator/concepts.h
index f6d092c75d48..bd68889333ce 100644
--- a/libcxx/include/__iterator/concepts.h
+++ b/libcxx/include/__iterator/concepts.h
@@ -21,12 +21,12 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17
// [iterator.concept.readable]
template<class _In>
@@ -90,7 +90,7 @@ concept incrementable =
template<class _Ip>
concept input_or_output_iterator =
requires(_Ip __i) {
- { *__i } -> __referenceable;
+ { *__i } -> __can_reference;
} &&
weakly_incrementable<_Ip>;
@@ -254,10 +254,26 @@ concept indirectly_movable_storable =
constructible_from<iter_value_t<_In>, iter_rvalue_reference_t<_In>> &&
assignable_from<iter_value_t<_In>&, iter_rvalue_reference_t<_In>>;
+template<class _In, class _Out>
+concept indirectly_copyable =
+ indirectly_readable<_In> &&
+ indirectly_writable<_Out, iter_reference_t<_In>>;
+
+template<class _In, class _Out>
+concept indirectly_copyable_storable =
+ indirectly_copyable<_In, _Out> &&
+ indirectly_writable<_Out, iter_value_t<_In>&> &&
+ indirectly_writable<_Out, const iter_value_t<_In>&> &&
+ indirectly_writable<_Out, iter_value_t<_In>&&> &&
+ indirectly_writable<_Out, const iter_value_t<_In>&&> &&
+ copyable<iter_value_t<_In>> &&
+ constructible_from<iter_value_t<_In>, iter_reference_t<_In>> &&
+ assignable_from<iter_value_t<_In>&, iter_reference_t<_In>>;
+
// Note: indirectly_swappable is located in iter_swap.h to prevent a dependency cycle
// (both iter_swap and indirectly_swappable require indirectly_readable).
-#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__iterator/counted_iterator.h b/libcxx/include/__iterator/counted_iterator.h
index aaab3ac77777..b0f5c66ecf21 100644
--- a/libcxx/include/__iterator/counted_iterator.h
+++ b/libcxx/include/__iterator/counted_iterator.h
@@ -9,8 +9,8 @@
#ifndef _LIBCPP___ITERATOR_COUNTED_ITERATOR_H
#define _LIBCPP___ITERATOR_COUNTED_ITERATOR_H
+#include <__assert>
#include <__config>
-#include <__debug>
#include <__iterator/concepts.h>
#include <__iterator/default_sentinel.h>
#include <__iterator/incrementable_traits.h>
@@ -25,12 +25,12 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17
template<class>
struct __counted_iterator_concept {};
@@ -65,7 +65,7 @@ class counted_iterator
, public __counted_iterator_value_type<_Iter>
{
public:
- [[no_unique_address]] _Iter __current_ = _Iter();
+ _LIBCPP_NO_UNIQUE_ADDRESS _Iter __current_ = _Iter();
iter_difference_t<_Iter> __count_ = 0;
using iterator_type = _Iter;
@@ -296,7 +296,7 @@ struct iterator_traits<counted_iterator<_Iter>> : iterator_traits<_Iter> {
add_pointer_t<iter_reference_t<_Iter>>, void>;
};
-#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__iterator/data.h b/libcxx/include/__iterator/data.h
index 5e4946cc10b4..88eb752b642e 100644
--- a/libcxx/include/__iterator/data.h
+++ b/libcxx/include/__iterator/data.h
@@ -15,7 +15,7 @@
#include <initializer_list>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__iterator/default_sentinel.h b/libcxx/include/__iterator/default_sentinel.h
index e12a5909ccf7..669032aa9729 100644
--- a/libcxx/include/__iterator/default_sentinel.h
+++ b/libcxx/include/__iterator/default_sentinel.h
@@ -13,17 +13,17 @@
#include <__config>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17
struct default_sentinel_t { };
inline constexpr default_sentinel_t default_sentinel{};
-#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__iterator/distance.h b/libcxx/include/__iterator/distance.h
index faab03492389..8819078958d3 100644
--- a/libcxx/include/__iterator/distance.h
+++ b/libcxx/include/__iterator/distance.h
@@ -20,7 +20,7 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -52,7 +52,7 @@ distance(_InputIter __first, _InputIter __last)
return _VSTD::__distance(__first, __last, typename iterator_traits<_InputIter>::iterator_category());
}
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
// [range.iter.op.distance]
@@ -100,7 +100,7 @@ inline namespace __cpo {
} // namespace __cpo
} // namespace ranges
-#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__iterator/empty.h b/libcxx/include/__iterator/empty.h
index 39cd560a276f..748ca9ecbd59 100644
--- a/libcxx/include/__iterator/empty.h
+++ b/libcxx/include/__iterator/empty.h
@@ -15,7 +15,7 @@
#include <initializer_list>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__iterator/erase_if_container.h b/libcxx/include/__iterator/erase_if_container.h
index 08f6e2248239..d7c71a947a2b 100644
--- a/libcxx/include/__iterator/erase_if_container.h
+++ b/libcxx/include/__iterator/erase_if_container.h
@@ -13,7 +13,7 @@
#include <__config>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__iterator/front_insert_iterator.h b/libcxx/include/__iterator/front_insert_iterator.h
index b229a99f1104..69b2d32d077a 100644
--- a/libcxx/include/__iterator/front_insert_iterator.h
+++ b/libcxx/include/__iterator/front_insert_iterator.h
@@ -18,7 +18,7 @@
#include <cstddef>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__iterator/incrementable_traits.h b/libcxx/include/__iterator/incrementable_traits.h
index 3b68acc9bc51..ef5f5110a30e 100644
--- a/libcxx/include/__iterator/incrementable_traits.h
+++ b/libcxx/include/__iterator/incrementable_traits.h
@@ -15,12 +15,12 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17
// [incrementable.traits]
template<class> struct incrementable_traits {};
@@ -65,7 +65,7 @@ using iter_difference_t = typename conditional_t<__is_primary_template<iterator_
incrementable_traits<remove_cvref_t<_Ip> >,
iterator_traits<remove_cvref_t<_Ip> > >::difference_type;
-#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__iterator/indirectly_comparable.h b/libcxx/include/__iterator/indirectly_comparable.h
index 3bafc56f926f..868190fc48da 100644
--- a/libcxx/include/__iterator/indirectly_comparable.h
+++ b/libcxx/include/__iterator/indirectly_comparable.h
@@ -15,15 +15,19 @@
#include <__iterator/concepts.h>
#include <__iterator/projected.h>
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
_LIBCPP_BEGIN_NAMESPACE_STD
-#ifndef _LIBCPP_HAS_NO_CONCEPTS
+#if _LIBCPP_STD_VER > 17
template <class _I1, class _I2, class _Rp, class _P1 = identity, class _P2 = identity>
concept indirectly_comparable =
indirect_binary_predicate<_Rp, projected<_I1, _P1>, projected<_I2, _P2>>;
-#endif // _LIBCPP_HAS_NO_CONCEPTS
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__iterator/insert_iterator.h b/libcxx/include/__iterator/insert_iterator.h
index 2f18f5f12162..8b313f2a85bb 100644
--- a/libcxx/include/__iterator/insert_iterator.h
+++ b/libcxx/include/__iterator/insert_iterator.h
@@ -19,12 +19,12 @@
#include <cstddef>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
template <class _Container>
using __insert_iterator_iter_t = ranges::iterator_t<_Container>;
#else
diff --git a/libcxx/include/__iterator/istream_iterator.h b/libcxx/include/__iterator/istream_iterator.h
index 979d714edf5d..a056961c10a8 100644
--- a/libcxx/include/__iterator/istream_iterator.h
+++ b/libcxx/include/__iterator/istream_iterator.h
@@ -11,13 +11,15 @@
#define _LIBCPP___ITERATOR_ISTREAM_ITERATOR_H
#include <__config>
+#include <__iterator/default_sentinel.h>
#include <__iterator/iterator.h>
#include <__iterator/iterator_traits.h>
#include <__memory/addressof.h>
+#include <cstddef>
#include <iosfwd> // for forward declarations of char_traits and basic_istream
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -45,6 +47,9 @@ private:
_Tp __value_;
public:
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR istream_iterator() : __in_stream_(nullptr), __value_() {}
+#if _LIBCPP_STD_VER > 17
+ _LIBCPP_HIDE_FROM_ABI constexpr istream_iterator(default_sentinel_t) : istream_iterator() {}
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_INLINE_VISIBILITY istream_iterator(istream_type& __s) : __in_stream_(_VSTD::addressof(__s))
{
if (!(*__in_stream_ >> __value_))
@@ -67,6 +72,12 @@ public:
bool
operator==(const istream_iterator<_Up, _CharU, _TraitsU, _DistanceU>& __x,
const istream_iterator<_Up, _CharU, _TraitsU, _DistanceU>& __y);
+
+#if _LIBCPP_STD_VER > 17
+ friend _LIBCPP_HIDE_FROM_ABI bool operator==(const istream_iterator& __i, default_sentinel_t) {
+ return __i.__in_stream_ == nullptr;
+ }
+#endif // _LIBCPP_STD_VER > 17
};
template <class _Tp, class _CharT, class _Traits, class _Distance>
@@ -78,6 +89,7 @@ operator==(const istream_iterator<_Tp, _CharT, _Traits, _Distance>& __x,
return __x.__in_stream_ == __y.__in_stream_;
}
+#if _LIBCPP_STD_VER <= 17
template <class _Tp, class _CharT, class _Traits, class _Distance>
inline _LIBCPP_INLINE_VISIBILITY
bool
@@ -86,6 +98,7 @@ operator!=(const istream_iterator<_Tp, _CharT, _Traits, _Distance>& __x,
{
return !(__x == __y);
}
+#endif // _LIBCPP_STD_VER <= 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__iterator/istreambuf_iterator.h b/libcxx/include/__iterator/istreambuf_iterator.h
index 0c7676f16908..bc53a6a1c80e 100644
--- a/libcxx/include/__iterator/istreambuf_iterator.h
+++ b/libcxx/include/__iterator/istreambuf_iterator.h
@@ -11,12 +11,13 @@
#define _LIBCPP___ITERATOR_ISTREAMBUF_ITERATOR_H
#include <__config>
+#include <__iterator/default_sentinel.h>
#include <__iterator/iterator.h>
#include <__iterator/iterator_traits.h>
#include <iosfwd> // for forward declaration of basic_streambuf
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -49,7 +50,8 @@ private:
{
char_type __keep_;
streambuf_type* __sbuf_;
- _LIBCPP_INLINE_VISIBILITY __proxy(char_type __c, streambuf_type* __s)
+ _LIBCPP_INLINE_VISIBILITY
+ explicit __proxy(char_type __c, streambuf_type* __s)
: __keep_(__c), __sbuf_(__s) {}
friend class istreambuf_iterator;
public:
@@ -65,6 +67,10 @@ private:
}
public:
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR istreambuf_iterator() _NOEXCEPT : __sbuf_(nullptr) {}
+#if _LIBCPP_STD_VER > 17
+ _LIBCPP_INLINE_VISIBILITY constexpr istreambuf_iterator(default_sentinel_t) noexcept
+ : istreambuf_iterator() {}
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_INLINE_VISIBILITY istreambuf_iterator(istream_type& __s) _NOEXCEPT
: __sbuf_(__s.rdbuf()) {}
_LIBCPP_INLINE_VISIBILITY istreambuf_iterator(streambuf_type* __s) _NOEXCEPT
@@ -86,6 +92,12 @@ public:
_LIBCPP_INLINE_VISIBILITY bool equal(const istreambuf_iterator& __b) const
{return __test_for_eof() == __b.__test_for_eof();}
+
+#if _LIBCPP_STD_VER > 17
+ friend _LIBCPP_HIDE_FROM_ABI bool operator==(const istreambuf_iterator& __i, default_sentinel_t) {
+ return __i.__test_for_eof();
+ }
+#endif // _LIBCPP_STD_VER > 17
};
template <class _CharT, class _Traits>
@@ -94,11 +106,13 @@ bool operator==(const istreambuf_iterator<_CharT,_Traits>& __a,
const istreambuf_iterator<_CharT,_Traits>& __b)
{return __a.equal(__b);}
+#if _LIBCPP_STD_VER <= 17
template <class _CharT, class _Traits>
inline _LIBCPP_INLINE_VISIBILITY
bool operator!=(const istreambuf_iterator<_CharT,_Traits>& __a,
const istreambuf_iterator<_CharT,_Traits>& __b)
{return !__a.equal(__b);}
+#endif // _LIBCPP_STD_VER <= 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__iterator/iter_move.h b/libcxx/include/__iterator/iter_move.h
index dfcf8e6c8308..d8240ab9c2f1 100644
--- a/libcxx/include/__iterator/iter_move.h
+++ b/libcxx/include/__iterator/iter_move.h
@@ -10,20 +10,20 @@
#ifndef _LIBCPP___ITERATOR_ITER_MOVE_H
#define _LIBCPP___ITERATOR_ITER_MOVE_H
+#include <__concepts/class_or_enum.h>
#include <__config>
#include <__iterator/iterator_traits.h>
#include <__utility/forward.h>
-#include <concepts> // __class_or_enum
+#include <__utility/move.h>
#include <type_traits>
-#include <utility>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17
// [iterator.cust.move]
@@ -36,44 +36,50 @@ template <class _Tp>
concept __unqualified_iter_move =
__class_or_enum<remove_cvref_t<_Tp>> &&
requires (_Tp&& __t) {
- iter_move(_VSTD::forward<_Tp>(__t));
+ iter_move(std::forward<_Tp>(__t));
};
-// [iterator.cust.move]/1
-// The name ranges::iter_move denotes a customization point object.
-// The expression ranges::iter_move(E) for a subexpression E is
-// expression-equivalent to:
+template<class _Tp>
+concept __move_deref =
+ !__unqualified_iter_move<_Tp> &&
+ requires (_Tp&& __t) {
+ *__t;
+ requires is_lvalue_reference_v<decltype(*__t)>;
+ };
+
+template<class _Tp>
+concept __just_deref =
+ !__unqualified_iter_move<_Tp> &&
+ !__move_deref<_Tp> &&
+ requires (_Tp&& __t) {
+ *__t;
+ requires (!is_lvalue_reference_v<decltype(*__t)>);
+ };
+
+// [iterator.cust.move]
+
struct __fn {
- // [iterator.cust.move]/1.1
- // iter_move(E), if E has class or enumeration type and iter_move(E) is a
- // well-formed expression when treated as an unevaluated operand, [...]
template<class _Ip>
- requires __class_or_enum<remove_cvref_t<_Ip>> && __unqualified_iter_move<_Ip>
+ requires __unqualified_iter_move<_Ip>
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator()(_Ip&& __i) const
- noexcept(noexcept(iter_move(_VSTD::forward<_Ip>(__i))))
+ noexcept(noexcept(iter_move(std::forward<_Ip>(__i))))
{
- return iter_move(_VSTD::forward<_Ip>(__i));
+ return iter_move(std::forward<_Ip>(__i));
}
- // [iterator.cust.move]/1.2
- // Otherwise, if the expression *E is well-formed:
- // 1.2.1 if *E is an lvalue, std::move(*E);
- // 1.2.2 otherwise, *E.
template<class _Ip>
- requires (!(__class_or_enum<remove_cvref_t<_Ip>> && __unqualified_iter_move<_Ip>)) &&
- requires(_Ip&& __i) { *_VSTD::forward<_Ip>(__i); }
- [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator()(_Ip&& __i) const
- noexcept(noexcept(*_VSTD::forward<_Ip>(__i)))
- {
- if constexpr (is_lvalue_reference_v<decltype(*_VSTD::forward<_Ip>(__i))>) {
- return _VSTD::move(*_VSTD::forward<_Ip>(__i));
- } else {
- return *_VSTD::forward<_Ip>(__i);
- }
- }
+ requires __move_deref<_Ip>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Ip&& __i) const
+ noexcept(noexcept(std::move(*std::forward<_Ip>(__i))))
+ -> decltype( std::move(*std::forward<_Ip>(__i)))
+ { return std::move(*std::forward<_Ip>(__i)); }
- // [iterator.cust.move]/1.3
- // Otherwise, ranges::iter_move(E) is ill-formed.
+ template<class _Ip>
+ requires __just_deref<_Ip>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Ip&& __i) const
+ noexcept(noexcept(*std::forward<_Ip>(__i)))
+ -> decltype( *std::forward<_Ip>(__i))
+ { return *std::forward<_Ip>(__i); }
};
} // namespace __iter_move
@@ -83,10 +89,10 @@ inline namespace __cpo {
} // namespace ranges
template<__dereferenceable _Tp>
- requires requires(_Tp& __t) { { ranges::iter_move(__t) } -> __referenceable; }
+ requires requires(_Tp& __t) { { ranges::iter_move(__t) } -> __can_reference; }
using iter_rvalue_reference_t = decltype(ranges::iter_move(declval<_Tp&>()));
-#endif // !_LIBCPP_HAS_NO_CONCEPTS
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__iterator/iter_swap.h b/libcxx/include/__iterator/iter_swap.h
index 0179546667b7..9e06464c3690 100644
--- a/libcxx/include/__iterator/iter_swap.h
+++ b/libcxx/include/__iterator/iter_swap.h
@@ -14,19 +14,18 @@
#include <__iterator/iter_move.h>
#include <__iterator/iterator_traits.h>
#include <__iterator/readable_traits.h>
-#include <__ranges/access.h>
#include <__utility/forward.h>
#include <__utility/move.h>
#include <concepts>
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17
// [iter.cust.swap]
@@ -100,7 +99,7 @@ concept indirectly_swappable =
ranges::iter_swap(__i2, __i1);
};
-#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__iterator/iterator.h b/libcxx/include/__iterator/iterator.h
index be298ee5228e..b417eeab79bf 100644
--- a/libcxx/include/__iterator/iterator.h
+++ b/libcxx/include/__iterator/iterator.h
@@ -14,7 +14,7 @@
#include <cstddef>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__iterator/iterator_traits.h b/libcxx/include/__iterator/iterator_traits.h
index f2dbb7c700ec..c3a5b7e0dd22 100644
--- a/libcxx/include/__iterator/iterator_traits.h
+++ b/libcxx/include/__iterator/iterator_traits.h
@@ -17,31 +17,31 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17
template <class _Tp>
using __with_reference = _Tp&;
template <class _Tp>
-concept __referenceable = requires {
+concept __can_reference = requires {
typename __with_reference<_Tp>;
};
template <class _Tp>
concept __dereferenceable = requires(_Tp& __t) {
- { *__t } -> __referenceable; // not required to be equality-preserving
+ { *__t } -> __can_reference; // not required to be equality-preserving
};
// [iterator.traits]
template<__dereferenceable _Tp>
using iter_reference_t = decltype(*declval<_Tp&>());
-#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17
template <class _Iter>
struct _LIBCPP_TEMPLATE_VIS iterator_traits;
@@ -105,15 +105,14 @@ template <class _Tp>
struct __has_iterator_typedefs
{
private:
- struct __two {char __lx; char __lxx;};
- template <class _Up> static __two __test(...);
- template <class _Up> static char __test(typename __void_t<typename _Up::iterator_category>::type* = 0,
- typename __void_t<typename _Up::difference_type>::type* = 0,
- typename __void_t<typename _Up::value_type>::type* = 0,
- typename __void_t<typename _Up::reference>::type* = 0,
- typename __void_t<typename _Up::pointer>::type* = 0);
+ template <class _Up> static false_type __test(...);
+ template <class _Up> static true_type __test(typename __void_t<typename _Up::iterator_category>::type* = 0,
+ typename __void_t<typename _Up::difference_type>::type* = 0,
+ typename __void_t<typename _Up::value_type>::type* = 0,
+ typename __void_t<typename _Up::reference>::type* = 0,
+ typename __void_t<typename _Up::pointer>::type* = 0);
public:
- static const bool value = sizeof(__test<_Tp>(0,0,0,0,0)) == 1;
+ static const bool value = decltype(__test<_Tp>(0,0,0,0,0))::value;
};
@@ -121,35 +120,34 @@ template <class _Tp>
struct __has_iterator_category
{
private:
- struct __two {char __lx; char __lxx;};
- template <class _Up> static __two __test(...);
- template <class _Up> static char __test(typename _Up::iterator_category* = nullptr);
+ template <class _Up> static false_type __test(...);
+ template <class _Up> static true_type __test(typename _Up::iterator_category* = nullptr);
public:
- static const bool value = sizeof(__test<_Tp>(nullptr)) == 1;
+ static const bool value = decltype(__test<_Tp>(nullptr))::value;
};
template <class _Tp>
struct __has_iterator_concept
{
private:
- struct __two {char __lx; char __lxx;};
- template <class _Up> static __two __test(...);
- template <class _Up> static char __test(typename _Up::iterator_concept* = nullptr);
+ template <class _Up> static false_type __test(...);
+ template <class _Up> static true_type __test(typename _Up::iterator_concept* = nullptr);
public:
- static const bool value = sizeof(__test<_Tp>(nullptr)) == 1;
+ static const bool value = decltype(__test<_Tp>(nullptr))::value;
};
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17
-// The `cpp17-*-iterator` exposition-only concepts are easily confused with the Cpp17*Iterator tables,
-// so they've been banished to a namespace that makes it obvious they have a niche use-case.
+// The `cpp17-*-iterator` exposition-only concepts have very similar names to the `Cpp17*Iterator` named requirements
+// from `[iterator.cpp17]`. To avoid confusion between the two, the exposition-only concepts have been banished to
+// a "detail" namespace indicating they have a niche use-case.
namespace __iterator_traits_detail {
template<class _Ip>
concept __cpp17_iterator =
requires(_Ip __i) {
- { *__i } -> __referenceable;
+ { *__i } -> __can_reference;
{ ++__i } -> same_as<_Ip&>;
- { *__i++ } -> __referenceable;
+ { *__i++ } -> __can_reference;
} &&
copyable<_Ip>;
@@ -198,7 +196,7 @@ concept __cpp17_random_access_iterator =
{ __i + __n } -> same_as<_Ip>;
{ __n + __i } -> same_as<_Ip>;
{ __i - __n } -> same_as<_Ip>;
- { __i - __i } -> same_as<decltype(__n)>;
+ { __i - __i } -> same_as<decltype(__n)>; // NOLINT(misc-redundant-expression) ; This is llvm.org/PR54114
{ __i[__n] } -> convertible_to<iter_reference_t<_Ip>>;
};
} // namespace __iterator_traits_detail
@@ -362,7 +360,7 @@ struct iterator_traits : __iterator_traits<_Ip> {
using __primary_template = iterator_traits;
};
-#else // !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#else // _LIBCPP_STD_VER > 17
template <class _Iter, bool> struct __iterator_traits {};
@@ -399,10 +397,10 @@ struct _LIBCPP_TEMPLATE_VIS iterator_traits
using __primary_template = iterator_traits;
};
-#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17
template<class _Tp>
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17
requires is_object_v<_Tp>
#endif
struct _LIBCPP_TEMPLATE_VIS iterator_traits<_Tp*>
@@ -468,27 +466,28 @@ template <class _Up>
struct __is_cpp17_contiguous_iterator<_Up*> : true_type {};
+template <class _Iter>
+class __wrap_iter;
+
template <class _Tp>
struct __is_exactly_cpp17_input_iterator
: public integral_constant<bool,
__has_iterator_category_convertible_to<_Tp, input_iterator_tag>::value &&
!__has_iterator_category_convertible_to<_Tp, forward_iterator_tag>::value> {};
-#if _LIBCPP_STD_VER >= 17
template<class _InputIterator>
using __iter_value_type = typename iterator_traits<_InputIterator>::value_type;
template<class _InputIterator>
-using __iter_key_type = remove_const_t<typename iterator_traits<_InputIterator>::value_type::first_type>;
+using __iter_key_type = typename remove_const<typename iterator_traits<_InputIterator>::value_type::first_type>::type;
template<class _InputIterator>
using __iter_mapped_type = typename iterator_traits<_InputIterator>::value_type::second_type;
template<class _InputIterator>
using __iter_to_alloc_type = pair<
- add_const_t<typename iterator_traits<_InputIterator>::value_type::first_type>,
+ typename add_const<typename iterator_traits<_InputIterator>::value_type::first_type>::type,
typename iterator_traits<_InputIterator>::value_type::second_type>;
-#endif // _LIBCPP_STD_VER >= 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__iterator/mergeable.h b/libcxx/include/__iterator/mergeable.h
new file mode 100644
index 000000000000..b9f2d081dc7e
--- /dev/null
+++ b/libcxx/include/__iterator/mergeable.h
@@ -0,0 +1,41 @@
+// -*- 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___ITERATOR_MERGEABLE_H
+#define _LIBCPP___ITERATOR_MERGEABLE_H
+
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/projected.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 17
+
+template <class _Input1, class _Input2, class _Output,
+ class _Comp = ranges::less, class _Proj1 = identity, class _Proj2 = identity>
+concept mergeable =
+ input_iterator<_Input1> &&
+ input_iterator<_Input2> &&
+ weakly_incrementable<_Output> &&
+ indirectly_copyable<_Input1, _Output> &&
+ indirectly_copyable<_Input2, _Output> &&
+ indirect_strict_weak_order<_Comp, projected<_Input1, _Proj1>, projected<_Input2, _Proj2>>;
+
+#endif // _LIBCPP_STD_VER > 17
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___ITERATOR_MERGEABLE_H
diff --git a/libcxx/include/__iterator/move_iterator.h b/libcxx/include/__iterator/move_iterator.h
index 29bac864c275..6be9f216dbb4 100644
--- a/libcxx/include/__iterator/move_iterator.h
+++ b/libcxx/include/__iterator/move_iterator.h
@@ -10,51 +10,131 @@
#ifndef _LIBCPP___ITERATOR_MOVE_ITERATOR_H
#define _LIBCPP___ITERATOR_MOVE_ITERATOR_H
+#include <__compare/compare_three_way_result.h>
+#include <__compare/three_way_comparable.h>
+#include <__concepts/assignable.h>
+#include <__concepts/convertible_to.h>
+#include <__concepts/derived_from.h>
+#include <__concepts/same_as.h>
#include <__config>
+#include <__iterator/concepts.h>
+#include <__iterator/incrementable_traits.h>
+#include <__iterator/iter_move.h>
+#include <__iterator/iter_swap.h>
#include <__iterator/iterator_traits.h>
+#include <__iterator/move_sentinel.h>
+#include <__iterator/readable_traits.h>
#include <__utility/move.h>
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
+#if _LIBCPP_STD_VER > 17
+template<class _Iter, class = void>
+struct __move_iter_category_base {};
+
+template<class _Iter>
+ requires requires { typename iterator_traits<_Iter>::iterator_category; }
+struct __move_iter_category_base<_Iter> {
+ using iterator_category = _If<
+ derived_from<typename iterator_traits<_Iter>::iterator_category, random_access_iterator_tag>,
+ random_access_iterator_tag,
+ typename iterator_traits<_Iter>::iterator_category
+ >;
+};
+
+template<class _Iter, class _Sent>
+concept __move_iter_comparable = requires {
+ { declval<const _Iter&>() == declval<_Sent>() } -> convertible_to<bool>;
+};
+#endif // _LIBCPP_STD_VER > 17
+
template <class _Iter>
class _LIBCPP_TEMPLATE_VIS move_iterator
+#if _LIBCPP_STD_VER > 17
+ : public __move_iter_category_base<_Iter>
+#endif
{
public:
#if _LIBCPP_STD_VER > 17
- typedef input_iterator_tag iterator_concept;
-#endif
-
+ using iterator_type = _Iter;
+ using iterator_concept = input_iterator_tag;
+ // iterator_category is inherited and not always present
+ using value_type = iter_value_t<_Iter>;
+ using difference_type = iter_difference_t<_Iter>;
+ using pointer = _Iter;
+ using reference = iter_rvalue_reference_t<_Iter>;
+#else
typedef _Iter iterator_type;
typedef _If<
__is_cpp17_random_access_iterator<_Iter>::value,
random_access_iterator_tag,
typename iterator_traits<_Iter>::iterator_category
- > iterator_category;
+ > iterator_category;
typedef typename iterator_traits<iterator_type>::value_type value_type;
typedef typename iterator_traits<iterator_type>::difference_type difference_type;
typedef iterator_type pointer;
-#ifndef _LIBCPP_CXX03_LANG
typedef typename iterator_traits<iterator_type>::reference __reference;
typedef typename conditional<
is_reference<__reference>::value,
typename remove_reference<__reference>::type&&,
__reference
>::type reference;
-#else
- typedef typename iterator_traits<iterator_type>::reference reference;
-#endif
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14
- move_iterator() : __current_() {}
+ explicit move_iterator(_Iter __i) : __current_(std::move(__i)) {}
+
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14
+ move_iterator& operator++() { ++__current_; return *this; }
+
+ _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14
+ pointer operator->() const { return __current_; }
+
+#if _LIBCPP_STD_VER > 17
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ move_iterator() requires is_constructible_v<_Iter> : __current_() {}
+
+ template <class _Up>
+ requires (!_IsSame<_Up, _Iter>::value) && convertible_to<const _Up&, _Iter>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ move_iterator(const move_iterator<_Up>& __u) : __current_(__u.base()) {}
+
+ template <class _Up>
+ requires (!_IsSame<_Up, _Iter>::value) &&
+ convertible_to<const _Up&, _Iter> &&
+ assignable_from<_Iter&, const _Up&>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ move_iterator& operator=(const move_iterator<_Up>& __u) {
+ __current_ = __u.base();
+ return *this;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr const _Iter& base() const & noexcept { return __current_; }
+ _LIBCPP_HIDE_FROM_ABI constexpr _Iter base() && { return std::move(__current_); }
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ reference operator*() const { return ranges::iter_move(__current_); }
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ reference operator[](difference_type __n) const { return ranges::iter_move(__current_ + __n); }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ auto operator++(int)
+ requires forward_iterator<_Iter>
+ {
+ move_iterator __tmp(*this); ++__current_; return __tmp;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ void operator++(int) { ++__current_; }
+#else
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14
- explicit move_iterator(_Iter __i) : __current_(_VSTD::move(__i)) {}
+ move_iterator() : __current_() {}
template <class _Up, class = __enable_if_t<
!is_same<_Up, _Iter>::value && is_convertible<const _Up&, _Iter>::value
@@ -79,14 +159,12 @@ public:
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14
reference operator*() const { return static_cast<reference>(*__current_); }
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14
- pointer operator->() const { return __current_; }
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14
reference operator[](difference_type __n) const { return static_cast<reference>(__current_[__n]); }
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14
- move_iterator& operator++() { ++__current_; return *this; }
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14
move_iterator operator++(int) { move_iterator __tmp(*this); ++__current_; return __tmp; }
+#endif // _LIBCPP_STD_VER > 17
+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14
move_iterator& operator--() { --__current_; return *this; }
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14
@@ -100,7 +178,48 @@ public:
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14
move_iterator& operator-=(difference_type __n) { __current_ -= __n; return *this; }
+#if _LIBCPP_STD_VER > 17
+ template<sentinel_for<_Iter> _Sent>
+ friend _LIBCPP_HIDE_FROM_ABI constexpr
+ bool operator==(const move_iterator& __x, const move_sentinel<_Sent>& __y)
+ requires __move_iter_comparable<_Iter, _Sent>
+ {
+ return __x.base() == __y.base();
+ }
+
+ template<sized_sentinel_for<_Iter> _Sent>
+ friend _LIBCPP_HIDE_FROM_ABI constexpr
+ iter_difference_t<_Iter> operator-(const move_sentinel<_Sent>& __x, const move_iterator& __y)
+ {
+ return __x.base() - __y.base();
+ }
+
+ template<sized_sentinel_for<_Iter> _Sent>
+ friend _LIBCPP_HIDE_FROM_ABI constexpr
+ iter_difference_t<_Iter> operator-(const move_iterator& __x, const move_sentinel<_Sent>& __y)
+ {
+ return __x.base() - __y.base();
+ }
+
+ friend _LIBCPP_HIDE_FROM_ABI constexpr
+ iter_rvalue_reference_t<_Iter> iter_move(const move_iterator& __i)
+ noexcept(noexcept(ranges::iter_move(__i.__current_)))
+ {
+ return ranges::iter_move(__i.__current_);
+ }
+
+ template<indirectly_swappable<_Iter> _It2>
+ friend _LIBCPP_HIDE_FROM_ABI constexpr
+ void iter_swap(const move_iterator& __x, const move_iterator<_It2>& __y)
+ noexcept(noexcept(ranges::iter_swap(__x.__current_, __y.__current_)))
+ {
+ return ranges::iter_swap(__x.__current_, __y.__current_);
+ }
+#endif // _LIBCPP_STD_VER > 17
+
private:
+ template<class _It2> friend class move_iterator;
+
_Iter __current_;
};
@@ -111,12 +230,14 @@ bool operator==(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& _
return __x.base() == __y.base();
}
+#if _LIBCPP_STD_VER <= 17
template <class _Iter1, class _Iter2>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14
bool operator!=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
{
return __x.base() != __y.base();
}
+#endif // _LIBCPP_STD_VER <= 17
template <class _Iter1, class _Iter2>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14
@@ -146,6 +267,16 @@ bool operator>=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& _
return __x.base() >= __y.base();
}
+#if _LIBCPP_STD_VER > 17
+template <class _Iter1, three_way_comparable_with<_Iter1> _Iter2>
+inline _LIBCPP_HIDE_FROM_ABI constexpr
+auto operator<=>(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
+ -> compare_three_way_result_t<_Iter1, _Iter2>
+{
+ return __x.base() <=> __y.base();
+}
+#endif // _LIBCPP_STD_VER > 17
+
#ifndef _LIBCPP_CXX03_LANG
template <class _Iter1, class _Iter2>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14
@@ -162,8 +293,17 @@ operator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
{
return __x.base() - __y.base();
}
-#endif
+#endif // !_LIBCPP_CXX03_LANG
+#if _LIBCPP_STD_VER > 17
+template <class _Iter>
+inline _LIBCPP_HIDE_FROM_ABI constexpr
+move_iterator<_Iter> operator+(iter_difference_t<_Iter> __n, const move_iterator<_Iter>& __x)
+ requires requires { { __x.base() + __n } -> same_as<_Iter>; }
+{
+ return __x + __n;
+}
+#else
template <class _Iter>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14
move_iterator<_Iter>
@@ -171,13 +311,14 @@ operator+(typename move_iterator<_Iter>::difference_type __n, const move_iterato
{
return move_iterator<_Iter>(__x.base() + __n);
}
+#endif // _LIBCPP_STD_VER > 17
template <class _Iter>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14
move_iterator<_Iter>
make_move_iterator(_Iter __i)
{
- return move_iterator<_Iter>(_VSTD::move(__i));
+ return move_iterator<_Iter>(std::move(__i));
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__iterator/move_sentinel.h b/libcxx/include/__iterator/move_sentinel.h
new file mode 100644
index 000000000000..5adf877b3490
--- /dev/null
+++ b/libcxx/include/__iterator/move_sentinel.h
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ITERATOR_MOVE_SENTINEL_H
+#define _LIBCPP___ITERATOR_MOVE_SENTINEL_H
+
+#include <__concepts/assignable.h>
+#include <__concepts/convertible_to.h>
+#include <__concepts/semiregular.h>
+#include <__config>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 17
+
+template <semiregular _Sent>
+class _LIBCPP_TEMPLATE_VIS move_sentinel
+{
+public:
+ _LIBCPP_HIDE_FROM_ABI
+ move_sentinel() = default;
+
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ explicit move_sentinel(_Sent __s) : __last_(std::move(__s)) {}
+
+ template <class _S2>
+ requires convertible_to<const _S2&, _Sent>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ move_sentinel(const move_sentinel<_S2>& __s) : __last_(__s.base()) {}
+
+ template <class _S2>
+ requires assignable_from<_Sent&, const _S2&>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ move_sentinel& operator=(const move_sentinel<_S2>& __s)
+ { __last_ = __s.base(); return *this; }
+
+ constexpr _Sent base() const { return __last_; }
+
+private:
+ _Sent __last_ = _Sent();
+};
+
+#endif // _LIBCPP_STD_VER > 17
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___ITERATOR_MOVE_SENTINEL_H
diff --git a/libcxx/include/__iterator/next.h b/libcxx/include/__iterator/next.h
index 8683e2210e95..5363d6d58ecf 100644
--- a/libcxx/include/__iterator/next.h
+++ b/libcxx/include/__iterator/next.h
@@ -10,8 +10,8 @@
#ifndef _LIBCPP___ITERATOR_NEXT_H
#define _LIBCPP___ITERATOR_NEXT_H
+#include <__assert>
#include <__config>
-#include <__debug>
#include <__iterator/advance.h>
#include <__iterator/concepts.h>
#include <__iterator/incrementable_traits.h>
@@ -19,7 +19,7 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -35,7 +35,7 @@ inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
return __x;
}
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
// [range.iter.op.next]
@@ -58,16 +58,14 @@ struct __fn {
}
template <input_or_output_iterator _Ip, sentinel_for<_Ip> _Sp>
- _LIBCPP_HIDE_FROM_ABI
- constexpr _Ip operator()(_Ip __x, _Sp __bound) const {
- ranges::advance(__x, __bound);
+ _LIBCPP_HIDE_FROM_ABI constexpr _Ip operator()(_Ip __x, _Sp __bound_sentinel) const {
+ ranges::advance(__x, __bound_sentinel);
return __x;
}
template <input_or_output_iterator _Ip, sentinel_for<_Ip> _Sp>
- _LIBCPP_HIDE_FROM_ABI
- constexpr _Ip operator()(_Ip __x, iter_difference_t<_Ip> __n, _Sp __bound) const {
- ranges::advance(__x, __n, __bound);
+ _LIBCPP_HIDE_FROM_ABI constexpr _Ip operator()(_Ip __x, iter_difference_t<_Ip> __n, _Sp __bound_sentinel) const {
+ ranges::advance(__x, __n, __bound_sentinel);
return __x;
}
};
@@ -79,7 +77,7 @@ inline namespace __cpo {
} // namespace __cpo
} // namespace ranges
-#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__iterator/ostream_iterator.h b/libcxx/include/__iterator/ostream_iterator.h
index 20a36742ccab..76ae4614939f 100644
--- a/libcxx/include/__iterator/ostream_iterator.h
+++ b/libcxx/include/__iterator/ostream_iterator.h
@@ -14,10 +14,11 @@
#include <__iterator/iterator.h>
#include <__iterator/iterator_traits.h>
#include <__memory/addressof.h>
+#include <cstddef>
#include <iosfwd> // for forward declarations of char_traits and basic_ostream
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__iterator/ostreambuf_iterator.h b/libcxx/include/__iterator/ostreambuf_iterator.h
index 3272f6c99d74..6da7598ed272 100644
--- a/libcxx/include/__iterator/ostreambuf_iterator.h
+++ b/libcxx/include/__iterator/ostreambuf_iterator.h
@@ -13,10 +13,11 @@
#include <__config>
#include <__iterator/iterator.h>
#include <__iterator/iterator_traits.h>
+#include <cstddef>
#include <iosfwd> // for forward declaration of basic_streambuf
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__iterator/permutable.h b/libcxx/include/__iterator/permutable.h
new file mode 100644
index 000000000000..28d193eaae2c
--- /dev/null
+++ b/libcxx/include/__iterator/permutable.h
@@ -0,0 +1,35 @@
+// -*- 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___ITERATOR_PERMUTABLE_H
+#define _LIBCPP___ITERATOR_PERMUTABLE_H
+
+#include <__config>
+#include <__iterator/concepts.h>
+#include <__iterator/iter_swap.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 17
+
+template <class _Iterator>
+concept permutable =
+ forward_iterator<_Iterator> &&
+ indirectly_movable_storable<_Iterator, _Iterator> &&
+ indirectly_swappable<_Iterator, _Iterator>;
+
+#endif // _LIBCPP_STD_VER > 17
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___ITERATOR_PERMUTABLE_H
diff --git a/libcxx/include/__iterator/prev.h b/libcxx/include/__iterator/prev.h
index 5a58dc0e4b43..eb997b91ba20 100644
--- a/libcxx/include/__iterator/prev.h
+++ b/libcxx/include/__iterator/prev.h
@@ -10,8 +10,8 @@
#ifndef _LIBCPP___ITERATOR_PREV_H
#define _LIBCPP___ITERATOR_PREV_H
+#include <__assert>
#include <__config>
-#include <__debug>
#include <__iterator/advance.h>
#include <__iterator/concepts.h>
#include <__iterator/incrementable_traits.h>
@@ -19,7 +19,7 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -34,7 +34,7 @@ inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
return __x;
}
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
// [range.iter.op.prev]
@@ -57,9 +57,8 @@ struct __fn {
}
template <bidirectional_iterator _Ip>
- _LIBCPP_HIDE_FROM_ABI
- constexpr _Ip operator()(_Ip __x, iter_difference_t<_Ip> __n, _Ip __bound) const {
- ranges::advance(__x, -__n, __bound);
+ _LIBCPP_HIDE_FROM_ABI constexpr _Ip operator()(_Ip __x, iter_difference_t<_Ip> __n, _Ip __bound_iter) const {
+ ranges::advance(__x, -__n, __bound_iter);
return __x;
}
};
@@ -71,7 +70,7 @@ inline namespace __cpo {
} // namespace __cpo
} // namespace ranges
-#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__iterator/projected.h b/libcxx/include/__iterator/projected.h
index 30ea3a124b2c..53526bd8e712 100644
--- a/libcxx/include/__iterator/projected.h
+++ b/libcxx/include/__iterator/projected.h
@@ -15,12 +15,12 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17
template<indirectly_readable _It, indirectly_regular_unary_invocable<_It> _Proj>
struct projected {
@@ -33,7 +33,7 @@ struct incrementable_traits<projected<_It, _Proj>> {
using difference_type = iter_difference_t<_It>;
};
-#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__iterator/readable_traits.h b/libcxx/include/__iterator/readable_traits.h
index c0b16bafd784..500b46ac145f 100644
--- a/libcxx/include/__iterator/readable_traits.h
+++ b/libcxx/include/__iterator/readable_traits.h
@@ -15,12 +15,12 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17
// [readable.traits]
template<class> struct __cond_value_type {};
@@ -79,7 +79,7 @@ using iter_value_t = typename conditional_t<__is_primary_template<iterator_trait
indirectly_readable_traits<remove_cvref_t<_Ip> >,
iterator_traits<remove_cvref_t<_Ip> > >::value_type;
-#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__iterator/reverse_access.h b/libcxx/include/__iterator/reverse_access.h
index 643aede01c72..40c266378d36 100644
--- a/libcxx/include/__iterator/reverse_access.h
+++ b/libcxx/include/__iterator/reverse_access.h
@@ -16,13 +16,11 @@
#include <initializer_list>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if !defined(_LIBCPP_CXX03_LANG)
-
#if _LIBCPP_STD_VER > 11
template <class _Tp, size_t _Np>
@@ -95,9 +93,7 @@ auto crend(const _Cp& __c) -> decltype(_VSTD::rend(__c))
return _VSTD::rend(__c);
}
-#endif
-
-#endif // !defined(_LIBCPP_CXX03_LANG)
+#endif // _LIBCPP_STD_VER > 11
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__iterator/reverse_iterator.h b/libcxx/include/__iterator/reverse_iterator.h
index 449eb529aa98..89bda19effef 100644
--- a/libcxx/include/__iterator/reverse_iterator.h
+++ b/libcxx/include/__iterator/reverse_iterator.h
@@ -10,16 +10,25 @@
#ifndef _LIBCPP___ITERATOR_REVERSE_ITERATOR_H
#define _LIBCPP___ITERATOR_REVERSE_ITERATOR_H
+#include <__algorithm/unwrap_iter.h>
#include <__compare/compare_three_way_result.h>
#include <__compare/three_way_comparable.h>
+#include <__concepts/convertible_to.h>
#include <__config>
+#include <__iterator/concepts.h>
+#include <__iterator/incrementable_traits.h>
+#include <__iterator/iter_move.h>
+#include <__iterator/iter_swap.h>
#include <__iterator/iterator.h>
#include <__iterator/iterator_traits.h>
+#include <__iterator/prev.h>
+#include <__iterator/readable_traits.h>
#include <__memory/addressof.h>
+#include <__utility/move.h>
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -41,22 +50,31 @@ private:
_Iter __t; // no longer used as of LWG #2360, not removed due to ABI break
#endif
+#if _LIBCPP_STD_VER > 17
+ static_assert(__is_cpp17_bidirectional_iterator<_Iter>::value || bidirectional_iterator<_Iter>,
+ "reverse_iterator<It> requires It to be a bidirectional iterator.");
+#endif // _LIBCPP_STD_VER > 17
+
protected:
_Iter current;
public:
- typedef _Iter iterator_type;
- typedef typename iterator_traits<_Iter>::difference_type difference_type;
- typedef typename iterator_traits<_Iter>::reference reference;
- typedef typename iterator_traits<_Iter>::pointer pointer;
- typedef _If<__is_cpp17_random_access_iterator<_Iter>::value,
- random_access_iterator_tag,
- typename iterator_traits<_Iter>::iterator_category> iterator_category;
- typedef typename iterator_traits<_Iter>::value_type value_type;
+ using iterator_type = _Iter;
+ using iterator_category = _If<__is_cpp17_random_access_iterator<_Iter>::value,
+ random_access_iterator_tag,
+ typename iterator_traits<_Iter>::iterator_category>;
+ using pointer = typename iterator_traits<_Iter>::pointer;
#if _LIBCPP_STD_VER > 17
- typedef _If<__is_cpp17_random_access_iterator<_Iter>::value,
- random_access_iterator_tag,
- bidirectional_iterator_tag> iterator_concept;
+ using iterator_concept = _If<__is_cpp17_random_access_iterator<_Iter>::value,
+ random_access_iterator_tag,
+ bidirectional_iterator_tag>;
+ using value_type = iter_value_t<_Iter>;
+ using difference_type = iter_difference_t<_Iter>;
+ using reference = iter_reference_t<_Iter>;
+#else
+ using value_type = typename iterator_traits<_Iter>::value_type;
+ using difference_type = typename iterator_traits<_Iter>::difference_type;
+ using reference = typename iterator_traits<_Iter>::reference;
#endif
#ifndef _LIBCPP_ABI_NO_ITERATOR_BASES
@@ -114,32 +132,75 @@ public:
_Iter base() const {return current;}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
reference operator*() const {_Iter __tmp = current; return *--__tmp;}
+
+#if _LIBCPP_STD_VER > 17
+ _LIBCPP_INLINE_VISIBILITY
+ constexpr pointer operator->() const
+ requires is_pointer_v<_Iter> || requires(const _Iter i) { i.operator->(); }
+ {
+ if constexpr (is_pointer_v<_Iter>) {
+ return std::prev(current);
+ } else {
+ return std::prev(current).operator->();
+ }
+ }
+#else
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
- pointer operator->() const {return _VSTD::addressof(operator*());}
+ pointer operator->() const {
+ return std::addressof(operator*());
+ }
+#endif // _LIBCPP_STD_VER > 17
+
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
reverse_iterator& operator++() {--current; return *this;}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
- reverse_iterator operator++(int) {reverse_iterator __tmp(*this); --current; return __tmp;}
+ reverse_iterator operator++(int) {reverse_iterator __tmp(*this); --current; return __tmp;}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
reverse_iterator& operator--() {++current; return *this;}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
- reverse_iterator operator--(int) {reverse_iterator __tmp(*this); ++current; return __tmp;}
+ reverse_iterator operator--(int) {reverse_iterator __tmp(*this); ++current; return __tmp;}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
- reverse_iterator operator+ (difference_type __n) const {return reverse_iterator(current - __n);}
+ reverse_iterator operator+(difference_type __n) const {return reverse_iterator(current - __n);}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
reverse_iterator& operator+=(difference_type __n) {current -= __n; return *this;}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
- reverse_iterator operator- (difference_type __n) const {return reverse_iterator(current + __n);}
+ reverse_iterator operator-(difference_type __n) const {return reverse_iterator(current + __n);}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
reverse_iterator& operator-=(difference_type __n) {current += __n; return *this;}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
- reference operator[](difference_type __n) const {return *(*this + __n);}
+ reference operator[](difference_type __n) const {return *(*this + __n);}
+
+#if _LIBCPP_STD_VER > 17
+ _LIBCPP_HIDE_FROM_ABI friend constexpr
+ iter_rvalue_reference_t<_Iter> iter_move(const reverse_iterator& __i)
+ noexcept(is_nothrow_copy_constructible_v<_Iter> &&
+ noexcept(ranges::iter_move(--declval<_Iter&>()))) {
+ auto __tmp = __i.base();
+ return ranges::iter_move(--__tmp);
+ }
+
+ template <indirectly_swappable<_Iter> _Iter2>
+ _LIBCPP_HIDE_FROM_ABI friend constexpr
+ void iter_swap(const reverse_iterator& __x, const reverse_iterator<_Iter2>& __y)
+ noexcept(is_nothrow_copy_constructible_v<_Iter> &&
+ is_nothrow_copy_constructible_v<_Iter2> &&
+ noexcept(ranges::iter_swap(--declval<_Iter&>(), --declval<_Iter2&>()))) {
+ auto __xtmp = __x.base();
+ auto __ytmp = __y.base();
+ ranges::iter_swap(--__xtmp, --__ytmp);
+ }
+#endif // _LIBCPP_STD_VER > 17
};
template <class _Iter1, class _Iter2>
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
bool
operator==(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
+#if _LIBCPP_STD_VER > 17
+ requires requires {
+ { __x.base() == __y.base() } -> convertible_to<bool>;
+ }
+#endif // _LIBCPP_STD_VER > 17
{
return __x.base() == __y.base();
}
@@ -148,6 +209,11 @@ template <class _Iter1, class _Iter2>
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
bool
operator<(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
+#if _LIBCPP_STD_VER > 17
+ requires requires {
+ { __x.base() > __y.base() } -> convertible_to<bool>;
+ }
+#endif // _LIBCPP_STD_VER > 17
{
return __x.base() > __y.base();
}
@@ -156,6 +222,11 @@ template <class _Iter1, class _Iter2>
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
bool
operator!=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
+#if _LIBCPP_STD_VER > 17
+ requires requires {
+ { __x.base() != __y.base() } -> convertible_to<bool>;
+ }
+#endif // _LIBCPP_STD_VER > 17
{
return __x.base() != __y.base();
}
@@ -164,6 +235,11 @@ template <class _Iter1, class _Iter2>
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
bool
operator>(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
+#if _LIBCPP_STD_VER > 17
+ requires requires {
+ { __x.base() < __y.base() } -> convertible_to<bool>;
+ }
+#endif // _LIBCPP_STD_VER > 17
{
return __x.base() < __y.base();
}
@@ -172,6 +248,11 @@ template <class _Iter1, class _Iter2>
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
bool
operator>=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
+#if _LIBCPP_STD_VER > 17
+ requires requires {
+ { __x.base() <= __y.base() } -> convertible_to<bool>;
+ }
+#endif // _LIBCPP_STD_VER > 17
{
return __x.base() <= __y.base();
}
@@ -180,11 +261,16 @@ template <class _Iter1, class _Iter2>
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
bool
operator<=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
+#if _LIBCPP_STD_VER > 17
+ requires requires {
+ { __x.base() >= __y.base() } -> convertible_to<bool>;
+ }
+#endif // _LIBCPP_STD_VER > 17
{
return __x.base() >= __y.base();
}
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17
template <class _Iter1, three_way_comparable_with<_Iter1> _Iter2>
_LIBCPP_HIDE_FROM_ABI constexpr
compare_three_way_result_t<_Iter1, _Iter2>
@@ -192,7 +278,7 @@ operator<=>(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>&
{
return __y.base() <=> __x.base();
}
-#endif
+#endif // _LIBCPP_STD_VER > 17
#ifndef _LIBCPP_CXX03_LANG
template <class _Iter1, class _Iter2>
@@ -221,6 +307,12 @@ operator+(typename reverse_iterator<_Iter>::difference_type __n, const reverse_i
return reverse_iterator<_Iter>(__x.base() - __n);
}
+#if _LIBCPP_STD_VER > 17
+template <class _Iter1, class _Iter2>
+ requires (!sized_sentinel_for<_Iter1, _Iter2>)
+inline constexpr bool disable_sized_sentinel_for<reverse_iterator<_Iter1>, reverse_iterator<_Iter2>> = true;
+#endif // _LIBCPP_STD_VER > 17
+
#if _LIBCPP_STD_VER > 11
template <class _Iter>
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
@@ -230,6 +322,49 @@ reverse_iterator<_Iter> make_reverse_iterator(_Iter __i)
}
#endif
+template <class _Iter>
+using _ReverseWrapper = reverse_iterator<reverse_iterator<_Iter> >;
+
+template <class _Iter, bool __b>
+struct __unwrap_iter_impl<_ReverseWrapper<_Iter>, __b> {
+ static _LIBCPP_CONSTEXPR decltype(std::__unwrap_iter(std::declval<_Iter>()))
+ __apply(_ReverseWrapper<_Iter> __i) _NOEXCEPT {
+ return std::__unwrap_iter(__i.base().base());
+ }
+};
+
+template <class _OrigIter, class _UnwrappedIter>
+struct __rewrap_iter_impl<_ReverseWrapper<_OrigIter>, _UnwrappedIter> {
+ template <class _Iter>
+ struct _ReverseWrapperCount {
+ static _LIBCPP_CONSTEXPR const size_t value = 1;
+ };
+
+ template <class _Iter>
+ struct _ReverseWrapperCount<_ReverseWrapper<_Iter> > {
+ static _LIBCPP_CONSTEXPR const size_t value = 1 + _ReverseWrapperCount<_Iter>::value;
+ };
+
+ template <size_t _RewrapCount, class _OIter, class _UIter, __enable_if_t<_RewrapCount != 0, int> = 0>
+ _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR _ReverseWrapper<_OIter> __rewrap(_ReverseWrapper<_OIter> __iter1,
+ _UIter __iter2) {
+ return _ReverseWrapper<_OIter>(
+ reverse_iterator<_OIter>(__rewrap<_RewrapCount - 1>(__iter1.base().base(), __iter2)));
+ }
+
+ template <size_t _RewrapCount, class _OIter, class _UIter, __enable_if_t<_RewrapCount == 0, int> = 0>
+ _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR decltype(std::__rewrap_iter(std::declval<_OIter>(),
+ std::declval<_UIter>()))
+ __rewrap(_OIter __iter1, _UIter __iter2) {
+ return std::__rewrap_iter(__iter1, __iter2);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR _ReverseWrapper<_OrigIter> __apply(_ReverseWrapper<_OrigIter> __iter1,
+ _UnwrappedIter __iter2) {
+ return __rewrap<_ReverseWrapperCount<_OrigIter>::value>(__iter1, __iter2);
+ }
+};
+
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___ITERATOR_REVERSE_ITERATOR_H
diff --git a/libcxx/include/__iterator/size.h b/libcxx/include/__iterator/size.h
index 2e6a7d386cb1..e06013496668 100644
--- a/libcxx/include/__iterator/size.h
+++ b/libcxx/include/__iterator/size.h
@@ -15,7 +15,7 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -41,9 +41,14 @@ _NOEXCEPT_(noexcept(static_cast<common_type_t<ptrdiff_t, make_signed_t<decltype(
-> common_type_t<ptrdiff_t, make_signed_t<decltype(__c.size())>>
{ return static_cast<common_type_t<ptrdiff_t, make_signed_t<decltype(__c.size())>>>(__c.size()); }
+// GCC complains about the implicit conversion from ptrdiff_t to size_t in
+// the array bound.
+_LIBCPP_DIAGNOSTIC_PUSH
+_LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wsign-conversion")
template <class _Tp, ptrdiff_t _Sz>
_LIBCPP_INLINE_VISIBILITY
constexpr ptrdiff_t ssize(const _Tp (&)[_Sz]) noexcept { return _Sz; }
+_LIBCPP_DIAGNOSTIC_POP
#endif
#endif // _LIBCPP_STD_VER > 14
diff --git a/libcxx/include/__iterator/sortable.h b/libcxx/include/__iterator/sortable.h
new file mode 100644
index 000000000000..bcf934f87be0
--- /dev/null
+++ b/libcxx/include/__iterator/sortable.h
@@ -0,0 +1,37 @@
+// -*- 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___ITERATOR_SORTABLE_H
+#define _LIBCPP___ITERATOR_SORTABLE_H
+
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/permutable.h>
+#include <__iterator/projected.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 17
+
+template <class _Iter, class _Comp = ranges::less, class _Proj = identity>
+concept sortable =
+ permutable<_Iter> &&
+ indirect_strict_weak_order<_Comp, projected<_Iter, _Proj>>;
+
+#endif // _LIBCPP_STD_VER > 17
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___ITERATOR_SORTABLE_H
diff --git a/libcxx/include/__iterator/unreachable_sentinel.h b/libcxx/include/__iterator/unreachable_sentinel.h
index b200236d8b9d..d77cc99f02f7 100644
--- a/libcxx/include/__iterator/unreachable_sentinel.h
+++ b/libcxx/include/__iterator/unreachable_sentinel.h
@@ -14,12 +14,12 @@
#include <__iterator/concepts.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17
struct unreachable_sentinel_t {
template<weakly_incrementable _Iter>
@@ -31,7 +31,7 @@ struct unreachable_sentinel_t {
inline constexpr unreachable_sentinel_t unreachable_sentinel{};
-#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__iterator/wrap_iter.h b/libcxx/include/__iterator/wrap_iter.h
index d9dbee588896..f780048754c9 100644
--- a/libcxx/include/__iterator/wrap_iter.h
+++ b/libcxx/include/__iterator/wrap_iter.h
@@ -18,7 +18,7 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -50,12 +50,12 @@ public:
typename enable_if<is_convertible<_Up, iterator_type>::value>::type* = nullptr) _NOEXCEPT
: __i(__u.base())
{
-#if _LIBCPP_DEBUG_LEVEL == 2
+#ifdef _LIBCPP_ENABLE_DEBUG_MODE
if (!__libcpp_is_constant_evaluated())
__get_db()->__iterator_copy(this, _VSTD::addressof(__u));
#endif
}
-#if _LIBCPP_DEBUG_LEVEL == 2
+#ifdef _LIBCPP_ENABLE_DEBUG_MODE
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11
__wrap_iter(const __wrap_iter& __x)
: __i(__x.base())
@@ -135,15 +135,15 @@ public:
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 iterator_type base() const _NOEXCEPT {return __i;}
private:
-#if _LIBCPP_DEBUG_LEVEL == 2
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 __wrap_iter(const void* __p, iterator_type __x) : __i(__x)
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11
+ explicit __wrap_iter(const void* __p, iterator_type __x) _NOEXCEPT : __i(__x)
{
+ (void)__p;
+#ifdef _LIBCPP_ENABLE_DEBUG_MODE
if (!__libcpp_is_constant_evaluated())
__get_db()->__insert_ic(this, __p);
- }
-#else
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 __wrap_iter(iterator_type __x) _NOEXCEPT : __i(__x) {}
#endif
+ }
template <class _Up> friend class __wrap_iter;
template <class _CharT, class _Traits, class _Alloc> friend class basic_string;
diff --git a/libcxx/include/__libcpp_version b/libcxx/include/__libcpp_version
deleted file mode 100644
index bfed81939856..000000000000
--- a/libcxx/include/__libcpp_version
+++ /dev/null
@@ -1 +0,0 @@
-14000
diff --git a/libcxx/include/__locale b/libcxx/include/__locale
index 51f35eece712..4450123db194 100644
--- a/libcxx/include/__locale
+++ b/libcxx/include/__locale
@@ -18,24 +18,22 @@
#include <memory>
#include <mutex>
#include <string>
-#include <utility>
#if defined(_LIBCPP_MSVCRT_LIKE)
-# include <cstring>
# include <__support/win32/locale_win32.h>
+# include <cstring>
#elif defined(_AIX) || defined(__MVS__)
# include <__support/ibm/xlocale.h>
#elif defined(__ANDROID__)
# include <__support/android/locale_bionic.h>
#elif defined(__sun__)
-# include <xlocale.h>
# include <__support/solaris/xlocale.h>
+# include <xlocale.h>
#elif defined(_NEWLIB_VERSION)
# include <__support/newlib/xlocale.h>
#elif defined(__OpenBSD__)
# include <__support/openbsd/xlocale.h>
-#elif (defined(__APPLE__) || defined(__FreeBSD__) \
- || defined(__EMSCRIPTEN__) || defined(__IBMCPP__))
+#elif (defined(__APPLE__) || defined(__FreeBSD__) || defined(__IBMCPP__))
# include <xlocale.h>
#elif defined(__Fuchsia__)
# include <__support/fuchsia/xlocale.h>
@@ -47,7 +45,7 @@
#endif
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -339,9 +337,9 @@ collate<_CharT>::do_hash(const char_type* __lo, const char_type* __hi) const
return static_cast<long>(__h);
}
-_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS collate<char>)
+extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS collate<char>;
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS collate<wchar_t>)
+extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS collate<wchar_t>;
#endif
// template <class CharT> class collate_byname;
@@ -454,6 +452,7 @@ public:
static const mask blank = _BLANK;
static const mask __regex_word = 0x4000; // 0x8000 and 0x0100 and 0x00ff are used
# define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT
+# define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_ALPHA
#elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__)
# ifdef __APPLE__
typedef __uint32_t mask;
@@ -1498,15 +1497,15 @@ codecvt_byname<_InternT, _ExternT, _StateT>::~codecvt_byname()
}
_LIBCPP_SUPPRESS_DEPRECATED_POP
-_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char, char, mbstate_t>)
+extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char, char, mbstate_t>;
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<wchar_t, char, mbstate_t>)
+extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<wchar_t, char, mbstate_t>;
#endif
-_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char16_t, char, mbstate_t>) // deprecated in C++20
-_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char32_t, char, mbstate_t>) // deprecated in C++20
+extern template class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char16_t, char, mbstate_t>; // deprecated in C++20
+extern template class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char32_t, char, mbstate_t>; // deprecated in C++20
#ifndef _LIBCPP_HAS_NO_CHAR8_T
-_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char16_t, char8_t, mbstate_t>) // C++20
-_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char32_t, char8_t, mbstate_t>) // C++20
+extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char16_t, char8_t, mbstate_t>; // C++20
+extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char32_t, char8_t, mbstate_t>; // C++20
#endif
template <size_t _Np>
diff --git a/libcxx/include/__mbstate_t.h b/libcxx/include/__mbstate_t.h
index 3489f9cc0e3a..487a6d092c71 100644
--- a/libcxx/include/__mbstate_t.h
+++ b/libcxx/include/__mbstate_t.h
@@ -13,7 +13,7 @@
#include <__config>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
// TODO(ldionne):
diff --git a/libcxx/include/__memory/addressof.h b/libcxx/include/__memory/addressof.h
index c45dedfaec9b..75e3dd0647b2 100644
--- a/libcxx/include/__memory/addressof.h
+++ b/libcxx/include/__memory/addressof.h
@@ -13,7 +13,7 @@
#include <__config>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__memory/allocate_at_least.h b/libcxx/include/__memory/allocate_at_least.h
new file mode 100644
index 000000000000..7ce588a25d1b
--- /dev/null
+++ b/libcxx/include/__memory/allocate_at_least.h
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___MEMORY_ALLOCATE_AT_LEAST_H
+#define _LIBCPP___MEMORY_ALLOCATE_AT_LEAST_H
+
+#include <__config>
+#include <__memory/allocator_traits.h>
+#include <cstddef>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 20
+template <class _Pointer>
+struct allocation_result {
+ _Pointer ptr;
+ size_t count;
+};
+
+template <class _Alloc>
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr
+allocation_result<typename allocator_traits<_Alloc>::pointer> allocate_at_least(_Alloc& __alloc, size_t __n) {
+ if constexpr (requires { __alloc.allocate_at_least(__n); }) {
+ return __alloc.allocate_at_least(__n);
+ } else {
+ return {__alloc.allocate(__n), __n};
+ }
+}
+
+template <class _Alloc>
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr
+auto __allocate_at_least(_Alloc& __alloc, size_t __n) {
+ return std::allocate_at_least(__alloc, __n);
+}
+#else
+template <class _Pointer>
+struct __allocation_result {
+ _Pointer ptr;
+ size_t count;
+};
+
+template <class _Alloc>
+_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
+__allocation_result<typename allocator_traits<_Alloc>::pointer> __allocate_at_least(_Alloc& __alloc, size_t __n) {
+ return {__alloc.allocate(__n), __n};
+}
+
+#endif // _LIBCPP_STD_VER > 20
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___MEMORY_ALLOCATE_AT_LEAST_H
diff --git a/libcxx/include/__memory/allocation_guard.h b/libcxx/include/__memory/allocation_guard.h
index 6412677aaf14..424598cc8158 100644
--- a/libcxx/include/__memory/allocation_guard.h
+++ b/libcxx/include/__memory/allocation_guard.h
@@ -12,11 +12,11 @@
#include <__config>
#include <__memory/allocator_traits.h>
+#include <__utility/move.h>
#include <cstddef>
-#include <utility>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__memory/allocator.h b/libcxx/include/__memory/allocator.h
index 708bd82b02d2..57ce23483df3 100644
--- a/libcxx/include/__memory/allocator.h
+++ b/libcxx/include/__memory/allocator.h
@@ -11,6 +11,7 @@
#define _LIBCPP___MEMORY_ALLOCATOR_H
#include <__config>
+#include <__memory/allocate_at_least.h>
#include <__memory/allocator_traits.h>
#include <__utility/forward.h>
#include <cstddef>
@@ -19,34 +20,40 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _Tp> class allocator;
-#if _LIBCPP_STD_VER <= 17
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_VOID_SPECIALIZATION)
+// These specializations shouldn't be marked _LIBCPP_DEPRECATED_IN_CXX17.
+// Specializing allocator<void> is deprecated, but not using it.
template <>
class _LIBCPP_TEMPLATE_VIS allocator<void>
{
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS)
public:
_LIBCPP_DEPRECATED_IN_CXX17 typedef void* pointer;
_LIBCPP_DEPRECATED_IN_CXX17 typedef const void* const_pointer;
_LIBCPP_DEPRECATED_IN_CXX17 typedef void value_type;
template <class _Up> struct _LIBCPP_DEPRECATED_IN_CXX17 rebind {typedef allocator<_Up> other;};
+#endif
};
template <>
class _LIBCPP_TEMPLATE_VIS allocator<const void>
{
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS)
public:
_LIBCPP_DEPRECATED_IN_CXX17 typedef const void* pointer;
_LIBCPP_DEPRECATED_IN_CXX17 typedef const void* const_pointer;
_LIBCPP_DEPRECATED_IN_CXX17 typedef const void value_type;
template <class _Up> struct _LIBCPP_DEPRECATED_IN_CXX17 rebind {typedef allocator<_Up> other;};
+#endif
};
#endif
@@ -106,6 +113,13 @@ public:
}
}
+#if _LIBCPP_STD_VER > 20
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr
+ allocation_result<_Tp*> allocate_at_least(size_t __n) {
+ return {allocate(__n), __n};
+ }
+#endif
+
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
void deallocate(_Tp* __p, size_t __n) _NOEXCEPT {
if (__libcpp_is_constant_evaluated()) {
@@ -188,6 +202,13 @@ public:
}
}
+#if _LIBCPP_STD_VER > 20
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr
+ allocation_result<const _Tp*> allocate_at_least(size_t __n) {
+ return {allocate(__n), __n};
+ }
+#endif
+
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
void deallocate(const _Tp* __p, size_t __n) {
if (__libcpp_is_constant_evaluated()) {
diff --git a/libcxx/include/__memory/allocator_arg_t.h b/libcxx/include/__memory/allocator_arg_t.h
index f5a116dbbd7e..2d63b1f905e5 100644
--- a/libcxx/include/__memory/allocator_arg_t.h
+++ b/libcxx/include/__memory/allocator_arg_t.h
@@ -16,7 +16,7 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -36,7 +36,7 @@ extern _LIBCPP_EXPORTED_FROM_ABI const allocator_arg_t allocator_arg;
template <class _Tp, class _Alloc, class ..._Args>
struct __uses_alloc_ctor_imp
{
- typedef _LIBCPP_NODEBUG typename __uncvref<_Alloc>::type _RawAlloc;
+ typedef _LIBCPP_NODEBUG __uncvref_t<_Alloc> _RawAlloc;
static const bool __ua = uses_allocator<_Tp, _RawAlloc>::value;
static const bool __ic =
is_constructible<_Tp, allocator_arg_t, _Alloc, _Args...>::value;
diff --git a/libcxx/include/__memory/allocator_traits.h b/libcxx/include/__memory/allocator_traits.h
index f4c8fa02d650..5215556cdf3c 100644
--- a/libcxx/include/__memory/allocator_traits.h
+++ b/libcxx/include/__memory/allocator_traits.h
@@ -18,7 +18,7 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
diff --git a/libcxx/include/__memory/assume_aligned.h b/libcxx/include/__memory/assume_aligned.h
new file mode 100644
index 000000000000..0f12fb11fd86
--- /dev/null
+++ b/libcxx/include/__memory/assume_aligned.h
@@ -0,0 +1,46 @@
+// -*- 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___MEMORY_ASSUME_ALIGNED_H
+#define _LIBCPP___MEMORY_ASSUME_ALIGNED_H
+
+#include <__assert>
+#include <__config>
+#include <cstddef>
+#include <cstdint>
+#include <type_traits> // for is_constant_evaluated()
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 17
+
+template <size_t _Np, class _Tp>
+[[nodiscard]]
+_LIBCPP_HIDE_FROM_ABI
+constexpr _Tp* assume_aligned(_Tp* __ptr) {
+ static_assert(_Np != 0 && (_Np & (_Np - 1)) == 0,
+ "std::assume_aligned<N>(p) requires N to be a power of two");
+
+ if (is_constant_evaluated()) {
+ return __ptr;
+ } else {
+ _LIBCPP_ASSERT(reinterpret_cast<uintptr_t>(__ptr) % _Np == 0, "Alignment assumption is violated");
+ return static_cast<_Tp*>(__builtin_assume_aligned(__ptr, _Np));
+ }
+}
+
+#endif // _LIBCPP_STD_VER > 17
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___MEMORY_ASSUME_ALIGNED_H
diff --git a/libcxx/include/__memory/auto_ptr.h b/libcxx/include/__memory/auto_ptr.h
index 492cbabab8ac..c007b4d21a5d 100644
--- a/libcxx/include/__memory/auto_ptr.h
+++ b/libcxx/include/__memory/auto_ptr.h
@@ -11,12 +11,13 @@
#define _LIBCPP___MEMORY_AUTO_PTR_H
#include <__config>
-#include <__nullptr>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
+#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
+
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _Tp>
@@ -78,4 +79,6 @@ public:
_LIBCPP_END_NAMESPACE_STD
+#endif // _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
+
#endif // _LIBCPP___MEMORY_AUTO_PTR_H
diff --git a/libcxx/include/__memory/compressed_pair.h b/libcxx/include/__memory/compressed_pair.h
index fd6d7109f8eb..89e5820e992a 100644
--- a/libcxx/include/__memory/compressed_pair.h
+++ b/libcxx/include/__memory/compressed_pair.h
@@ -12,12 +12,12 @@
#include <__config>
#include <__utility/forward.h>
+#include <__utility/move.h>
#include <tuple> // needed in c++03 for some constructors
#include <type_traits>
-#include <utility>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -26,40 +26,28 @@ _LIBCPP_BEGIN_NAMESPACE_STD
struct __default_init_tag {};
struct __value_init_tag {};
-template <class _Tp, int _Idx,
- bool _CanBeEmptyBase =
- is_empty<_Tp>::value && !__libcpp_is_final<_Tp>::value>
+template <class _Tp, int _Idx, bool _CanBeEmptyBase = is_empty<_Tp>::value && !__libcpp_is_final<_Tp>::value>
struct __compressed_pair_elem {
- typedef _Tp _ParamT;
- typedef _Tp& reference;
- typedef const _Tp& const_reference;
-
- _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
- __compressed_pair_elem(__default_init_tag) {}
- _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
- __compressed_pair_elem(__value_init_tag) : __value_() {}
-
- template <class _Up, class = typename enable_if<
- !is_same<__compressed_pair_elem, typename decay<_Up>::type>::value
- >::type>
- _LIBCPP_INLINE_VISIBILITY
- _LIBCPP_CONSTEXPR explicit
- __compressed_pair_elem(_Up&& __u)
- : __value_(_VSTD::forward<_Up>(__u))
- {
- }
+ using _ParamT = _Tp;
+ using reference = _Tp&;
+ using const_reference = const _Tp&;
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit __compressed_pair_elem(__default_init_tag) {}
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit __compressed_pair_elem(__value_init_tag) : __value_() {}
+
+ template <class _Up, class = __enable_if_t<!is_same<__compressed_pair_elem, typename decay<_Up>::type>::value> >
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
+ explicit __compressed_pair_elem(_Up&& __u) : __value_(std::forward<_Up>(__u)) {}
#ifndef _LIBCPP_CXX03_LANG
- template <class... _Args, size_t... _Indexes>
- _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
- __compressed_pair_elem(piecewise_construct_t, tuple<_Args...> __args,
- __tuple_indices<_Indexes...>)
- : __value_(_VSTD::forward<_Args>(_VSTD::get<_Indexes>(__args))...) {}
+ template <class... _Args, size_t... _Indices>
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14
+ explicit __compressed_pair_elem(piecewise_construct_t, tuple<_Args...> __args, __tuple_indices<_Indices...>)
+ : __value_(std::forward<_Args>(std::get<_Indices>(__args))...) {}
#endif
- _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 reference __get() _NOEXCEPT { return __value_; }
- _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR const_reference __get() const _NOEXCEPT { return __value_; }
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 reference __get() _NOEXCEPT { return __value_; }
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR const_reference __get() const _NOEXCEPT { return __value_; }
private:
_Tp __value_;
@@ -67,36 +55,28 @@ private:
template <class _Tp, int _Idx>
struct __compressed_pair_elem<_Tp, _Idx, true> : private _Tp {
- typedef _Tp _ParamT;
- typedef _Tp& reference;
- typedef const _Tp& const_reference;
- typedef _Tp __value_type;
-
- _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR __compressed_pair_elem() = default;
- _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
- __compressed_pair_elem(__default_init_tag) {}
- _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
- __compressed_pair_elem(__value_init_tag) : __value_type() {}
-
- template <class _Up, class = typename enable_if<
- !is_same<__compressed_pair_elem, typename decay<_Up>::type>::value
- >::type>
- _LIBCPP_INLINE_VISIBILITY
- _LIBCPP_CONSTEXPR explicit
- __compressed_pair_elem(_Up&& __u)
- : __value_type(_VSTD::forward<_Up>(__u))
- {}
+ using _ParamT = _Tp;
+ using reference = _Tp&;
+ using const_reference = const _Tp&;
+ using __value_type = _Tp;
+
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit __compressed_pair_elem() = default;
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit __compressed_pair_elem(__default_init_tag) {}
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit __compressed_pair_elem(__value_init_tag) : __value_type() {}
+
+ template <class _Up, class = __enable_if_t<!is_same<__compressed_pair_elem, typename decay<_Up>::type>::value> >
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
+ explicit __compressed_pair_elem(_Up&& __u) : __value_type(std::forward<_Up>(__u)) {}
#ifndef _LIBCPP_CXX03_LANG
- template <class... _Args, size_t... _Indexes>
- _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
- __compressed_pair_elem(piecewise_construct_t, tuple<_Args...> __args,
- __tuple_indices<_Indexes...>)
- : __value_type(_VSTD::forward<_Args>(_VSTD::get<_Indexes>(__args))...) {}
+ template <class... _Args, size_t... _Indices>
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14
+ __compressed_pair_elem(piecewise_construct_t, tuple<_Args...> __args, __tuple_indices<_Indices...>)
+ : __value_type(std::forward<_Args>(std::get<_Indices>(__args))...) {}
#endif
- _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 reference __get() _NOEXCEPT { return *this; }
- _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR const_reference __get() const _NOEXCEPT { return *this; }
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 reference __get() _NOEXCEPT { return *this; }
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR const_reference __get() const _NOEXCEPT { return *this; }
};
template <class _T1, class _T2>
@@ -109,72 +89,73 @@ public:
// object and the allocator have the same type).
static_assert((!is_same<_T1, _T2>::value),
"__compressed_pair cannot be instantiated when T1 and T2 are the same type; "
- "The current implementation is NOT ABI-compatible with the previous "
- "implementation for this configuration");
+ "The current implementation is NOT ABI-compatible with the previous implementation for this configuration");
- typedef _LIBCPP_NODEBUG __compressed_pair_elem<_T1, 0> _Base1;
- typedef _LIBCPP_NODEBUG __compressed_pair_elem<_T2, 1> _Base2;
+ using _Base1 _LIBCPP_NODEBUG = __compressed_pair_elem<_T1, 0>;
+ using _Base2 _LIBCPP_NODEBUG = __compressed_pair_elem<_T2, 1>;
- template <bool _Dummy = true,
- class = typename enable_if<
- __dependent_type<is_default_constructible<_T1>, _Dummy>::value &&
- __dependent_type<is_default_constructible<_T2>, _Dummy>::value
- >::type
+ template <bool _Dummy = true,
+ class = __enable_if_t<
+ __dependent_type<is_default_constructible<_T1>, _Dummy>::value &&
+ __dependent_type<is_default_constructible<_T2>, _Dummy>::value
+ >
>
- _LIBCPP_INLINE_VISIBILITY
- _LIBCPP_CONSTEXPR __compressed_pair() : _Base1(__value_init_tag()), _Base2(__value_init_tag()) {}
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
+ explicit __compressed_pair() : _Base1(__value_init_tag()), _Base2(__value_init_tag()) {}
template <class _U1, class _U2>
- _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
- __compressed_pair(_U1&& __t1, _U2&& __t2)
- : _Base1(_VSTD::forward<_U1>(__t1)), _Base2(_VSTD::forward<_U2>(__t2)) {}
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
+ explicit __compressed_pair(_U1&& __t1, _U2&& __t2) : _Base1(std::forward<_U1>(__t1)), _Base2(std::forward<_U2>(__t2)) {}
#ifndef _LIBCPP_CXX03_LANG
template <class... _Args1, class... _Args2>
- _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
- __compressed_pair(piecewise_construct_t __pc, tuple<_Args1...> __first_args,
- tuple<_Args2...> __second_args)
- : _Base1(__pc, _VSTD::move(__first_args),
- typename __make_tuple_indices<sizeof...(_Args1)>::type()),
- _Base2(__pc, _VSTD::move(__second_args),
- typename __make_tuple_indices<sizeof...(_Args2)>::type()) {}
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14
+ explicit __compressed_pair(piecewise_construct_t __pc, tuple<_Args1...> __first_args,
+ tuple<_Args2...> __second_args)
+ : _Base1(__pc, std::move(__first_args), typename __make_tuple_indices<sizeof...(_Args1)>::type()),
+ _Base2(__pc, std::move(__second_args), typename __make_tuple_indices<sizeof...(_Args2)>::type()) {}
#endif
- _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 typename _Base1::reference first() _NOEXCEPT {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11
+ typename _Base1::reference first() _NOEXCEPT {
return static_cast<_Base1&>(*this).__get();
}
- _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR typename _Base1::const_reference first() const _NOEXCEPT {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
+ typename _Base1::const_reference first() const _NOEXCEPT {
return static_cast<_Base1 const&>(*this).__get();
}
- _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 typename _Base2::reference second() _NOEXCEPT {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11
+ typename _Base2::reference second() _NOEXCEPT {
return static_cast<_Base2&>(*this).__get();
}
- _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR typename _Base2::const_reference second() const _NOEXCEPT {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
+ typename _Base2::const_reference second() const _NOEXCEPT {
return static_cast<_Base2 const&>(*this).__get();
}
- _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
- static _Base1* __get_first_base(__compressed_pair* __pair) _NOEXCEPT {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR static
+ _Base1* __get_first_base(__compressed_pair* __pair) _NOEXCEPT {
return static_cast<_Base1*>(__pair);
}
- _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
- static _Base2* __get_second_base(__compressed_pair* __pair) _NOEXCEPT {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR static
+ _Base2* __get_second_base(__compressed_pair* __pair) _NOEXCEPT {
return static_cast<_Base2*>(__pair);
}
- _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 void swap(__compressed_pair& __x)
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11
+ void swap(__compressed_pair& __x)
_NOEXCEPT_(__is_nothrow_swappable<_T1>::value && __is_nothrow_swappable<_T2>::value) {
- using _VSTD::swap;
+ using std::swap;
swap(first(), __x.first());
swap(second(), __x.second());
}
};
template <class _T1, class _T2>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11
void swap(__compressed_pair<_T1, _T2>& __x, __compressed_pair<_T1, _T2>& __y)
_NOEXCEPT_(__is_nothrow_swappable<_T1>::value && __is_nothrow_swappable<_T2>::value) {
__x.swap(__y);
diff --git a/libcxx/include/__memory/concepts.h b/libcxx/include/__memory/concepts.h
index dced563f38b6..88372d277d7f 100644
--- a/libcxx/include/__memory/concepts.h
+++ b/libcxx/include/__memory/concepts.h
@@ -20,12 +20,13 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
namespace ranges {
// [special.mem.concepts]
@@ -59,7 +60,8 @@ concept __nothrow_forward_range =
__nothrow_forward_iterator<iterator_t<_Rp>>;
} // namespace ranges
-#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__memory/construct_at.h b/libcxx/include/__memory/construct_at.h
index 580ce781f482..bfa20a149d51 100644
--- a/libcxx/include/__memory/construct_at.h
+++ b/libcxx/include/__memory/construct_at.h
@@ -10,17 +10,17 @@
#ifndef _LIBCPP___MEMORY_CONSTRUCT_AT_H
#define _LIBCPP___MEMORY_CONSTRUCT_AT_H
+#include <__assert>
#include <__config>
-#include <__debug>
#include <__iterator/access.h>
#include <__memory/addressof.h>
#include <__memory/voidify.h>
#include <__utility/forward.h>
+#include <__utility/move.h>
#include <type_traits>
-#include <utility>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -29,17 +29,23 @@ _LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER > 17
-template<class _Tp, class ..._Args, class = decltype(
- ::new (declval<void*>()) _Tp(declval<_Args>()...)
-)>
-_LIBCPP_HIDE_FROM_ABI
-constexpr _Tp* construct_at(_Tp* __location, _Args&& ...__args) {
- _LIBCPP_ASSERT(__location, "null pointer given to construct_at");
- return ::new (_VSTD::__voidify(*__location)) _Tp(_VSTD::forward<_Args>(__args)...);
+template <class _Tp, class... _Args, class = decltype(::new(declval<void*>()) _Tp(declval<_Args>()...))>
+_LIBCPP_HIDE_FROM_ABI constexpr _Tp* construct_at(_Tp* __location, _Args&&... __args) {
+ _LIBCPP_ASSERT(__location != nullptr, "null pointer given to construct_at");
+ return ::new (_VSTD::__voidify(*__location)) _Tp(_VSTD::forward<_Args>(__args)...);
}
#endif
+template <class _Tp, class... _Args, class = decltype(::new(declval<void*>()) _Tp(declval<_Args>()...))>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Tp* __construct_at(_Tp* __location, _Args&&... __args) {
+#if _LIBCPP_STD_VER > 17
+ return std::construct_at(__location, std::forward<_Args>(__args)...);
+#else
+ return ::new (std::__voidify(*__location)) _Tp(std::forward<_Args>(__args)...);
+#endif
+}
+
// destroy_at
// The internal functions are available regardless of the language version (with the exception of the `__destroy_at`
@@ -52,7 +58,7 @@ _ForwardIterator __destroy(_ForwardIterator, _ForwardIterator);
template <class _Tp, typename enable_if<!is_array<_Tp>::value, int>::type = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
void __destroy_at(_Tp* __loc) {
- _LIBCPP_ASSERT(__loc, "null pointer given to destroy_at");
+ _LIBCPP_ASSERT(__loc != nullptr, "null pointer given to destroy_at");
__loc->~_Tp();
}
@@ -60,7 +66,7 @@ void __destroy_at(_Tp* __loc) {
template <class _Tp, typename enable_if<is_array<_Tp>::value, int>::type = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
void __destroy_at(_Tp* __loc) {
- _LIBCPP_ASSERT(__loc, "null pointer given to destroy_at");
+ _LIBCPP_ASSERT(__loc != nullptr, "null pointer given to destroy_at");
_VSTD::__destroy(_VSTD::begin(*__loc), _VSTD::end(*__loc));
}
#endif
diff --git a/libcxx/include/__memory/pointer_traits.h b/libcxx/include/__memory/pointer_traits.h
index 07bb6d437d7e..2549e4be7df1 100644
--- a/libcxx/include/__memory/pointer_traits.h
+++ b/libcxx/include/__memory/pointer_traits.h
@@ -15,7 +15,7 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -71,13 +71,12 @@ template <class _Tp, class _Up>
struct __has_rebind
{
private:
- struct __two {char __lx; char __lxx;};
- template <class _Xp> static __two __test(...);
+ template <class _Xp> static false_type __test(...);
_LIBCPP_SUPPRESS_DEPRECATED_PUSH
- template <class _Xp> static char __test(typename _Xp::template rebind<_Up>* = 0);
+ template <class _Xp> static true_type __test(typename _Xp::template rebind<_Up>* = 0);
_LIBCPP_SUPPRESS_DEPRECATED_POP
public:
- static const bool value = sizeof(__test<_Tp>(0)) == 1;
+ static const bool value = decltype(__test<_Tp>(0))::value;
};
template <class _Tp, class _Up, bool = __has_rebind<_Tp, _Up>::value>
diff --git a/libcxx/include/__memory/ranges_construct_at.h b/libcxx/include/__memory/ranges_construct_at.h
index b1821c8cc29e..29258023e3f9 100644
--- a/libcxx/include/__memory/ranges_construct_at.h
+++ b/libcxx/include/__memory/ranges_construct_at.h
@@ -24,12 +24,12 @@
#include <__utility/move.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
namespace ranges {
// construct_at
@@ -117,7 +117,7 @@ inline namespace __cpo {
} // namespace ranges
-#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__memory/ranges_uninitialized_algorithms.h b/libcxx/include/__memory/ranges_uninitialized_algorithms.h
index 70d901a5ad03..8072496c24d6 100644
--- a/libcxx/include/__memory/ranges_uninitialized_algorithms.h
+++ b/libcxx/include/__memory/ranges_uninitialized_algorithms.h
@@ -27,12 +27,13 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
namespace ranges {
// uninitialized_default_construct
@@ -309,7 +310,8 @@ inline namespace __cpo {
} // namespace __cpo
} // namespace ranges
-#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__memory/raw_storage_iterator.h b/libcxx/include/__memory/raw_storage_iterator.h
index abe9677cb668..9b6594b8883e 100644
--- a/libcxx/include/__memory/raw_storage_iterator.h
+++ b/libcxx/include/__memory/raw_storage_iterator.h
@@ -11,13 +11,14 @@
#define _LIBCPP___MEMORY_RAW_STORAGE_ITERATOR_H
#include <__config>
+#include <__iterator/iterator.h>
+#include <__iterator/iterator_traits.h>
#include <__memory/addressof.h>
+#include <__utility/move.h>
#include <cstddef>
-#include <iterator>
-#include <utility>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__memory/shared_ptr.h b/libcxx/include/__memory/shared_ptr.h
index 6a4ffc88c866..41a7c7fa7575 100644
--- a/libcxx/include/__memory/shared_ptr.h
+++ b/libcxx/include/__memory/shared_ptr.h
@@ -15,32 +15,33 @@
#include <__functional/binary_function.h>
#include <__functional/operations.h>
#include <__functional/reference_wrapper.h>
-#include <__functional_base>
+#include <__iterator/access.h>
#include <__memory/addressof.h>
#include <__memory/allocation_guard.h>
#include <__memory/allocator.h>
#include <__memory/allocator_traits.h>
+#include <__memory/auto_ptr.h>
#include <__memory/compressed_pair.h>
+#include <__memory/construct_at.h>
#include <__memory/pointer_traits.h>
+#include <__memory/uninitialized_algorithms.h>
#include <__memory/unique_ptr.h>
#include <__utility/forward.h>
+#include <__utility/move.h>
+#include <__utility/swap.h>
#include <cstddef>
#include <cstdlib> // abort
#include <iosfwd>
#include <stdexcept>
#include <type_traits>
#include <typeinfo>
-#include <utility>
#if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER)
# include <atomic>
#endif
-#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
-# include <__memory/auto_ptr.h>
-#endif
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -159,10 +160,9 @@ public:
explicit __shared_count(long __refs = 0) _NOEXCEPT
: __shared_owners_(__refs) {}
-#if defined(_LIBCPP_BUILDING_LIBRARY) && \
- defined(_LIBCPP_DEPRECATED_ABI_LEGACY_LIBRARY_DEFINITIONS_FOR_INLINE_FUNCTIONS)
- void __add_shared() _NOEXCEPT;
- bool __release_shared() _NOEXCEPT;
+#if defined(_LIBCPP_SHARED_PTR_DEFINE_LEGACY_INLINE_FUNCTIONS)
+ void __add_shared() noexcept;
+ bool __release_shared() noexcept;
#else
_LIBCPP_INLINE_VISIBILITY
void __add_shared() _NOEXCEPT {
@@ -197,11 +197,10 @@ protected:
virtual ~__shared_weak_count();
public:
-#if defined(_LIBCPP_BUILDING_LIBRARY) && \
- defined(_LIBCPP_DEPRECATED_ABI_LEGACY_LIBRARY_DEFINITIONS_FOR_INLINE_FUNCTIONS)
- void __add_shared() _NOEXCEPT;
- void __add_weak() _NOEXCEPT;
- void __release_shared() _NOEXCEPT;
+#if defined(_LIBCPP_SHARED_PTR_DEFINE_LEGACY_INLINE_FUNCTIONS)
+ void __add_shared() noexcept;
+ void __add_weak() noexcept;
+ void __release_shared() noexcept;
#else
_LIBCPP_INLINE_VISIBILITY
void __add_shared() _NOEXCEPT {
@@ -457,7 +456,7 @@ public:
explicit shared_ptr(_Yp* __p) : __ptr_(__p) {
unique_ptr<_Yp> __hold(__p);
typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;
- typedef __shared_ptr_pointer<_Yp*, __shared_ptr_default_delete<_Tp, _Yp>, _AllocT > _CntrlBlk;
+ typedef __shared_ptr_pointer<_Yp*, __shared_ptr_default_delete<_Tp, _Yp>, _AllocT> _CntrlBlk;
__cntrl_ = new _CntrlBlk(__p, __shared_ptr_default_delete<_Tp, _Yp>(), _AllocT());
__hold.release();
__enable_weak_this(__p, __p);
@@ -473,7 +472,7 @@ public:
{
#endif // _LIBCPP_NO_EXCEPTIONS
typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;
- typedef __shared_ptr_pointer<_Yp*, _Dp, _AllocT > _CntrlBlk;
+ typedef __shared_ptr_pointer<_Yp*, _Dp, _AllocT> _CntrlBlk;
#ifndef _LIBCPP_CXX03_LANG
__cntrl_ = new _CntrlBlk(__p, _VSTD::move(__d), _AllocT());
#else
@@ -532,7 +531,7 @@ public:
{
#endif // _LIBCPP_NO_EXCEPTIONS
typedef typename __shared_ptr_default_allocator<_Tp>::type _AllocT;
- typedef __shared_ptr_pointer<nullptr_t, _Dp, _AllocT > _CntrlBlk;
+ typedef __shared_ptr_pointer<nullptr_t, _Dp, _AllocT> _CntrlBlk;
#ifndef _LIBCPP_CXX03_LANG
__cntrl_ = new _CntrlBlk(__p, _VSTD::move(__d), _AllocT());
#else
@@ -665,8 +664,8 @@ public:
#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(), __r.get_deleter(), _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();
@@ -689,7 +688,7 @@ public:
typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;
typedef __shared_ptr_pointer<typename unique_ptr<_Yp, _Dp>::pointer,
reference_wrapper<typename remove_reference<_Dp>::type>,
- _AllocT > _CntrlBlk;
+ _AllocT> _CntrlBlk;
__cntrl_ = new _CntrlBlk(__r.get(), _VSTD::ref(__r.get_deleter()), _AllocT());
__enable_weak_this(__r.get(), __r.get());
}
@@ -963,6 +962,220 @@ shared_ptr<_Tp> make_shared(_Args&& ...__args)
return _VSTD::allocate_shared<_Tp>(allocator<_Tp>(), _VSTD::forward<_Args>(__args)...);
}
+#if _LIBCPP_STD_VER > 14
+
+template <size_t _Alignment>
+struct __sp_aligned_storage {
+ alignas(_Alignment) char __storage[_Alignment];
+};
+
+template <class _Tp, class _Alloc>
+struct __unbounded_array_control_block;
+
+template <class _Tp, class _Alloc>
+struct __unbounded_array_control_block<_Tp[], _Alloc> : __shared_weak_count
+{
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ _Tp* __get_data() noexcept { return __data_; }
+
+ _LIBCPP_HIDE_FROM_ABI
+ explicit __unbounded_array_control_block(_Alloc const& __alloc, size_t __count, _Tp const& __arg)
+ : __alloc_(__alloc), __count_(__count)
+ {
+ std::__uninitialized_allocator_fill_n(__alloc_, std::begin(__data_), __count_, __arg);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ explicit __unbounded_array_control_block(_Alloc const& __alloc, size_t __count)
+ : __alloc_(__alloc), __count_(__count)
+ {
+ std::__uninitialized_allocator_value_construct_n(__alloc_, std::begin(__data_), __count_);
+ }
+
+ // Returns the number of bytes required to store a control block followed by the given number
+ // of elements of _Tp, with the whole storage being aligned to a multiple of _Tp's alignment.
+ _LIBCPP_HIDE_FROM_ABI
+ static constexpr size_t __bytes_for(size_t __elements) {
+ // When there's 0 elements, the control block alone is enough since it holds one element.
+ // Otherwise, we allocate one fewer element than requested because the control block already
+ // holds one. Also, we use the bitwise formula below to ensure that we allocate enough bytes
+ // for the whole allocation to be a multiple of _Tp's alignment. That formula is taken from [1].
+ //
+ // [1]: https://en.wikipedia.org/wiki/Data_structure_alignment#Computing_padding
+ size_t __bytes = __elements == 0 ? sizeof(__unbounded_array_control_block)
+ : (__elements - 1) * sizeof(_Tp) + sizeof(__unbounded_array_control_block);
+ constexpr size_t __align = alignof(_Tp);
+ return (__bytes + __align - 1) & ~(__align - 1);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ ~__unbounded_array_control_block() override { } // can't be `= default` because of the sometimes-non-trivial union member __data_
+
+private:
+ void __on_zero_shared() _NOEXCEPT override {
+ __allocator_traits_rebind_t<_Alloc, _Tp> __value_alloc(__alloc_);
+ std::__allocator_destroy_multidimensional(__value_alloc, __data_, __data_ + __count_);
+ }
+
+ void __on_zero_shared_weak() _NOEXCEPT override {
+ using _AlignedStorage = __sp_aligned_storage<alignof(__unbounded_array_control_block)>;
+ using _StorageAlloc = __allocator_traits_rebind_t<_Alloc, _AlignedStorage>;
+ using _PointerTraits = pointer_traits<typename allocator_traits<_StorageAlloc>::pointer>;
+
+ _StorageAlloc __tmp(__alloc_);
+ __alloc_.~_Alloc();
+ size_t __size = __unbounded_array_control_block::__bytes_for(__count_);
+ _AlignedStorage* __storage = reinterpret_cast<_AlignedStorage*>(this);
+ allocator_traits<_StorageAlloc>::deallocate(__tmp, _PointerTraits::pointer_to(*__storage), __size);
+ }
+
+ _LIBCPP_NO_UNIQUE_ADDRESS _Alloc __alloc_;
+ size_t __count_;
+ union {
+ _Tp __data_[1];
+ };
+};
+
+template<class _Array, class _Alloc, class... _Arg>
+_LIBCPP_HIDE_FROM_ABI
+shared_ptr<_Array> __allocate_shared_unbounded_array(const _Alloc& __a, size_t __n, _Arg&& ...__arg)
+{
+ static_assert(__libcpp_is_unbounded_array<_Array>::value);
+ // We compute the number of bytes necessary to hold the control block and the
+ // array elements. Then, we allocate an array of properly-aligned dummy structs
+ // large enough to hold the control block and array. This allows shifting the
+ // burden of aligning memory properly from us to the allocator.
+ using _ControlBlock = __unbounded_array_control_block<_Array, _Alloc>;
+ using _AlignedStorage = __sp_aligned_storage<alignof(_ControlBlock)>;
+ using _StorageAlloc = __allocator_traits_rebind_t<_Alloc, _AlignedStorage>;
+ __allocation_guard<_StorageAlloc> __guard(__a, _ControlBlock::__bytes_for(__n) / sizeof(_AlignedStorage));
+ _ControlBlock* __control_block = reinterpret_cast<_ControlBlock*>(std::addressof(*__guard.__get()));
+ std::__construct_at(__control_block, __a, __n, std::forward<_Arg>(__arg)...);
+ __guard.__release_ptr();
+ return shared_ptr<_Array>::__create_with_control_block(__control_block->__get_data(), __control_block);
+}
+
+template <class _Tp, class _Alloc>
+struct __bounded_array_control_block;
+
+template <class _Tp, size_t _Count, class _Alloc>
+struct __bounded_array_control_block<_Tp[_Count], _Alloc>
+ : __shared_weak_count
+{
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ _Tp* __get_data() noexcept { return __data_; }
+
+ _LIBCPP_HIDE_FROM_ABI
+ explicit __bounded_array_control_block(_Alloc const& __alloc, _Tp const& __arg) : __alloc_(__alloc) {
+ std::__uninitialized_allocator_fill_n(__alloc_, std::addressof(__data_[0]), _Count, __arg);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ explicit __bounded_array_control_block(_Alloc const& __alloc) : __alloc_(__alloc) {
+ std::__uninitialized_allocator_value_construct_n(__alloc_, std::addressof(__data_[0]), _Count);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ ~__bounded_array_control_block() override { } // can't be `= default` because of the sometimes-non-trivial union member __data_
+
+private:
+ void __on_zero_shared() _NOEXCEPT override {
+ __allocator_traits_rebind_t<_Alloc, _Tp> __value_alloc(__alloc_);
+ std::__allocator_destroy_multidimensional(__value_alloc, __data_, __data_ + _Count);
+ }
+
+ void __on_zero_shared_weak() _NOEXCEPT override {
+ using _ControlBlockAlloc = __allocator_traits_rebind_t<_Alloc, __bounded_array_control_block>;
+ using _PointerTraits = pointer_traits<typename allocator_traits<_ControlBlockAlloc>::pointer>;
+
+ _ControlBlockAlloc __tmp(__alloc_);
+ __alloc_.~_Alloc();
+ allocator_traits<_ControlBlockAlloc>::deallocate(__tmp, _PointerTraits::pointer_to(*this), sizeof(*this));
+ }
+
+ _LIBCPP_NO_UNIQUE_ADDRESS _Alloc __alloc_;
+ union {
+ _Tp __data_[_Count];
+ };
+};
+
+template<class _Array, class _Alloc, class... _Arg>
+_LIBCPP_HIDE_FROM_ABI
+shared_ptr<_Array> __allocate_shared_bounded_array(const _Alloc& __a, _Arg&& ...__arg)
+{
+ static_assert(__libcpp_is_bounded_array<_Array>::value);
+ using _ControlBlock = __bounded_array_control_block<_Array, _Alloc>;
+ using _ControlBlockAlloc = __allocator_traits_rebind_t<_Alloc, _ControlBlock>;
+
+ __allocation_guard<_ControlBlockAlloc> __guard(__a, 1);
+ _ControlBlock* __control_block = reinterpret_cast<_ControlBlock*>(std::addressof(*__guard.__get()));
+ std::__construct_at(__control_block, __a, std::forward<_Arg>(__arg)...);
+ __guard.__release_ptr();
+ return shared_ptr<_Array>::__create_with_control_block(__control_block->__get_data(), __control_block);
+}
+
+#endif // _LIBCPP_STD_VER > 14
+
+#if _LIBCPP_STD_VER > 17
+
+template<class _Tp, class _Alloc, class = __enable_if_t<is_bounded_array<_Tp>::value>>
+_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, class = __enable_if_t<is_bounded_array<_Tp>::value>>
+_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, class = __enable_if_t<is_unbounded_array<_Tp>::value>>
+_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, class = __enable_if_t<is_unbounded_array<_Tp>::value>>
+_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 = __enable_if_t<is_bounded_array<_Tp>::value>>
+_LIBCPP_HIDE_FROM_ABI
+shared_ptr<_Tp> make_shared()
+{
+ return std::__allocate_shared_bounded_array<_Tp>(allocator<_Tp>());
+}
+
+template<class _Tp, class = __enable_if_t<is_bounded_array<_Tp>::value>>
+_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, class = __enable_if_t<is_unbounded_array<_Tp>::value>>
+_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, class = __enable_if_t<is_unbounded_array<_Tp>::value>>
+_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);
+}
+
+#endif // _LIBCPP_STD_VER > 17
+
template<class _Tp, class _Up>
inline _LIBCPP_INLINE_VISIBILITY
bool
@@ -1442,19 +1655,10 @@ template <class _Tp> struct owner_less;
#endif
-_LIBCPP_SUPPRESS_DEPRECATED_PUSH
template <class _Tp>
struct _LIBCPP_TEMPLATE_VIS owner_less<shared_ptr<_Tp> >
-#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
- : binary_function<shared_ptr<_Tp>, shared_ptr<_Tp>, bool>
-#endif
+ : __binary_function<shared_ptr<_Tp>, shared_ptr<_Tp>, bool>
{
-_LIBCPP_SUPPRESS_DEPRECATED_POP
-#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
- _LIBCPP_DEPRECATED_IN_CXX17 typedef bool result_type;
- _LIBCPP_DEPRECATED_IN_CXX17 typedef shared_ptr<_Tp> first_argument_type;
- _LIBCPP_DEPRECATED_IN_CXX17 typedef shared_ptr<_Tp> second_argument_type;
-#endif
_LIBCPP_INLINE_VISIBILITY
bool operator()(shared_ptr<_Tp> const& __x, shared_ptr<_Tp> const& __y) const _NOEXCEPT
{return __x.owner_before(__y);}
@@ -1466,19 +1670,10 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP
{return __x.owner_before(__y);}
};
-_LIBCPP_SUPPRESS_DEPRECATED_PUSH
template <class _Tp>
struct _LIBCPP_TEMPLATE_VIS owner_less<weak_ptr<_Tp> >
-#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
- : binary_function<weak_ptr<_Tp>, weak_ptr<_Tp>, bool>
-#endif
+ : __binary_function<weak_ptr<_Tp>, weak_ptr<_Tp>, bool>
{
-_LIBCPP_SUPPRESS_DEPRECATED_POP
-#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
- _LIBCPP_DEPRECATED_IN_CXX17 typedef bool result_type;
- _LIBCPP_DEPRECATED_IN_CXX17 typedef weak_ptr<_Tp> first_argument_type;
- _LIBCPP_DEPRECATED_IN_CXX17 typedef weak_ptr<_Tp> second_argument_type;
-#endif
_LIBCPP_INLINE_VISIBILITY
bool operator()( weak_ptr<_Tp> const& __x, weak_ptr<_Tp> const& __y) const _NOEXCEPT
{return __x.owner_before(__y);}
diff --git a/libcxx/include/__memory/temporary_buffer.h b/libcxx/include/__memory/temporary_buffer.h
index 06aa6c2936fe..9822bd30c826 100644
--- a/libcxx/include/__memory/temporary_buffer.h
+++ b/libcxx/include/__memory/temporary_buffer.h
@@ -11,18 +11,18 @@
#define _LIBCPP___MEMORY_TEMPORARY_BUFFER_H
#include <__config>
+#include <__utility/pair.h>
#include <cstddef>
#include <new>
-#include <utility> // pair
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _Tp>
-_LIBCPP_NODISCARD_EXT _LIBCPP_NO_CFI
+_LIBCPP_NODISCARD_EXT _LIBCPP_NO_CFI _LIBCPP_DEPRECATED_IN_CXX17
pair<_Tp*, ptrdiff_t>
get_temporary_buffer(ptrdiff_t __n) _NOEXCEPT
{
@@ -67,7 +67,7 @@ get_temporary_buffer(ptrdiff_t __n) _NOEXCEPT
}
template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_IN_CXX17
void return_temporary_buffer(_Tp* __p) _NOEXCEPT
{
_VSTD::__libcpp_deallocate_unsized((void*)__p, _LIBCPP_ALIGNOF(_Tp));
@@ -75,8 +75,10 @@ void return_temporary_buffer(_Tp* __p) _NOEXCEPT
struct __return_temporary_buffer
{
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
template <class _Tp>
_LIBCPP_INLINE_VISIBILITY void operator()(_Tp* __p) const {_VSTD::return_temporary_buffer(__p);}
+_LIBCPP_SUPPRESS_DEPRECATED_POP
};
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__memory/uninitialized_algorithms.h b/libcxx/include/__memory/uninitialized_algorithms.h
index 40e7c79a51e0..3a8560f080c6 100644
--- a/libcxx/include/__memory/uninitialized_algorithms.h
+++ b/libcxx/include/__memory/uninitialized_algorithms.h
@@ -11,14 +11,18 @@
#define _LIBCPP___MEMORY_UNINITIALIZED_ALGORITHMS_H
#include <__config>
+#include <__iterator/iterator_traits.h>
#include <__memory/addressof.h>
+#include <__memory/allocator_traits.h>
#include <__memory/construct_at.h>
#include <__memory/voidify.h>
-#include <iterator>
-#include <utility>
+#include <__utility/move.h>
+#include <__utility/pair.h>
+#include <__utility/transaction.h>
+#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -343,6 +347,149 @@ uninitialized_move_n(_InputIterator __ifirst, _Size __n, _ForwardIterator __ofir
__unreachable_sentinel(), __iter_move);
}
+// Destroys every element in the range [first, last) FROM RIGHT TO LEFT using allocator
+// destruction. If elements are themselves C-style arrays, they are recursively destroyed
+// in the same manner.
+//
+// This function assumes that destructors do not throw, and that the allocator is bound to
+// the correct type.
+template<class _Alloc, class _BidirIter, class = __enable_if_t<
+ __is_cpp17_bidirectional_iterator<_BidirIter>::value
+>>
+_LIBCPP_HIDE_FROM_ABI
+constexpr void __allocator_destroy_multidimensional(_Alloc& __alloc, _BidirIter __first, _BidirIter __last) noexcept {
+ using _ValueType = typename iterator_traits<_BidirIter>::value_type;
+ static_assert(is_same_v<typename allocator_traits<_Alloc>::value_type, _ValueType>,
+ "The allocator should already be rebound to the correct type");
+
+ if (__first == __last)
+ return;
+
+ if constexpr (is_array_v<_ValueType>) {
+ static_assert(!__libcpp_is_unbounded_array<_ValueType>::value,
+ "arrays of unbounded arrays don't exist, but if they did we would mess up here");
+
+ using _Element = remove_extent_t<_ValueType>;
+ __allocator_traits_rebind_t<_Alloc, _Element> __elem_alloc(__alloc);
+ do {
+ --__last;
+ decltype(auto) __array = *__last;
+ std::__allocator_destroy_multidimensional(__elem_alloc, __array, __array + extent_v<_ValueType>);
+ } while (__last != __first);
+ } else {
+ do {
+ --__last;
+ allocator_traits<_Alloc>::destroy(__alloc, std::addressof(*__last));
+ } while (__last != __first);
+ }
+}
+
+// Constructs the object at the given location using the allocator's construct method.
+//
+// If the object being constructed is an array, each element of the array is allocator-constructed,
+// recursively. If an exception is thrown during the construction of an array, the initialized
+// elements are destroyed in reverse order of initialization using allocator destruction.
+//
+// This function assumes that the allocator is bound to the correct type.
+template<class _Alloc, class _Tp>
+_LIBCPP_HIDE_FROM_ABI
+constexpr void __allocator_construct_at(_Alloc& __alloc, _Tp* __loc) {
+ static_assert(is_same_v<typename allocator_traits<_Alloc>::value_type, _Tp>,
+ "The allocator should already be rebound to the correct type");
+
+ if constexpr (is_array_v<_Tp>) {
+ using _Element = remove_extent_t<_Tp>;
+ __allocator_traits_rebind_t<_Alloc, _Element> __elem_alloc(__alloc);
+ size_t __i = 0;
+ _Tp& __array = *__loc;
+
+ // If an exception is thrown, destroy what we have constructed so far in reverse order.
+ __transaction __guard([&]() { std::__allocator_destroy_multidimensional(__elem_alloc, __array, __array + __i); });
+ for (; __i != extent_v<_Tp>; ++__i) {
+ std::__allocator_construct_at(__elem_alloc, std::addressof(__array[__i]));
+ }
+ __guard.__complete();
+ } else {
+ allocator_traits<_Alloc>::construct(__alloc, __loc);
+ }
+}
+
+// Constructs the object at the given location using the allocator's construct method, passing along
+// the provided argument.
+//
+// If the object being constructed is an array, the argument is also assumed to be an array. Each
+// each element of the array being constructed is allocator-constructed from the corresponding
+// element of the argument array. If an exception is thrown during the construction of an array,
+// the initialized elements are destroyed in reverse order of initialization using allocator
+// destruction.
+//
+// This function assumes that the allocator is bound to the correct type.
+template<class _Alloc, class _Tp, class _Arg>
+_LIBCPP_HIDE_FROM_ABI
+constexpr void __allocator_construct_at(_Alloc& __alloc, _Tp* __loc, _Arg const& __arg) {
+ static_assert(is_same_v<typename allocator_traits<_Alloc>::value_type, _Tp>,
+ "The allocator should already be rebound to the correct type");
+
+ if constexpr (is_array_v<_Tp>) {
+ static_assert(is_array_v<_Arg>,
+ "Provided non-array initialization argument to __allocator_construct_at when "
+ "trying to construct an array.");
+
+ using _Element = remove_extent_t<_Tp>;
+ __allocator_traits_rebind_t<_Alloc, _Element> __elem_alloc(__alloc);
+ size_t __i = 0;
+ _Tp& __array = *__loc;
+
+ // If an exception is thrown, destroy what we have constructed so far in reverse order.
+ __transaction __guard([&]() { std::__allocator_destroy_multidimensional(__elem_alloc, __array, __array + __i); });
+ for (; __i != extent_v<_Tp>; ++__i) {
+ std::__allocator_construct_at(__elem_alloc, std::addressof(__array[__i]), __arg[__i]);
+ }
+ __guard.__complete();
+ } else {
+ allocator_traits<_Alloc>::construct(__alloc, __loc, __arg);
+ }
+}
+
+// Given a range starting at it and containing n elements, initializes each element in the
+// range from left to right using the construct method of the allocator (rebound to the
+// correct type).
+//
+// If an exception is thrown, the initialized elements are destroyed in reverse order of
+// initialization using allocator_traits destruction. If the elements in the range are C-style
+// arrays, they are initialized element-wise using allocator construction, and recursively so.
+template<class _Alloc, class _BidirIter, class _Tp, class _Size = typename iterator_traits<_BidirIter>::difference_type>
+_LIBCPP_HIDE_FROM_ABI
+constexpr void __uninitialized_allocator_fill_n(_Alloc& __alloc, _BidirIter __it, _Size __n, _Tp const& __value) {
+ using _ValueType = typename iterator_traits<_BidirIter>::value_type;
+ __allocator_traits_rebind_t<_Alloc, _ValueType> __value_alloc(__alloc);
+ _BidirIter __begin = __it;
+
+ // If an exception is thrown, destroy what we have constructed so far in reverse order.
+ __transaction __guard([&]() { std::__allocator_destroy_multidimensional(__value_alloc, __begin, __it); });
+ for (; __n != 0; --__n, ++__it) {
+ std::__allocator_construct_at(__value_alloc, std::addressof(*__it), __value);
+ }
+ __guard.__complete();
+}
+
+// Same as __uninitialized_allocator_fill_n, but doesn't pass any initialization argument
+// to the allocator's construct method, which results in value initialization.
+template<class _Alloc, class _BidirIter, class _Size = typename iterator_traits<_BidirIter>::difference_type>
+_LIBCPP_HIDE_FROM_ABI
+constexpr void __uninitialized_allocator_value_construct_n(_Alloc& __alloc, _BidirIter __it, _Size __n) {
+ using _ValueType = typename iterator_traits<_BidirIter>::value_type;
+ __allocator_traits_rebind_t<_Alloc, _ValueType> __value_alloc(__alloc);
+ _BidirIter __begin = __it;
+
+ // If an exception is thrown, destroy what we have constructed so far in reverse order.
+ __transaction __guard([&]() { std::__allocator_destroy_multidimensional(__value_alloc, __begin, __it); });
+ for (; __n != 0; --__n, ++__it) {
+ std::__allocator_construct_at(__value_alloc, std::addressof(*__it));
+ }
+ __guard.__complete();
+}
+
#endif // _LIBCPP_STD_VER > 14
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__memory/unique_ptr.h b/libcxx/include/__memory/unique_ptr.h
index e892f3287b93..1de64de30b23 100644
--- a/libcxx/include/__memory/unique_ptr.h
+++ b/libcxx/include/__memory/unique_ptr.h
@@ -13,20 +13,16 @@
#include <__config>
#include <__functional/hash.h>
#include <__functional/operations.h>
-#include <__functional_base>
#include <__memory/allocator_traits.h> // __pointer
+#include <__memory/auto_ptr.h>
#include <__memory/compressed_pair.h>
#include <__utility/forward.h>
+#include <__utility/move.h>
#include <cstddef>
#include <type_traits>
-#include <utility>
-
-#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
-# include <__memory/auto_ptr.h>
-#endif
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -47,10 +43,8 @@ struct _LIBCPP_TEMPLATE_VIS default_delete {
0) _NOEXCEPT {}
_LIBCPP_INLINE_VISIBILITY void operator()(_Tp* __ptr) const _NOEXCEPT {
- static_assert(sizeof(_Tp) > 0,
- "default_delete can not delete incomplete type");
- static_assert(!is_void<_Tp>::value,
- "default_delete can not delete incomplete type");
+ static_assert(sizeof(_Tp) >= 0, "cannot delete an incomplete type");
+ static_assert(!is_void<_Tp>::value, "cannot delete an incomplete type");
delete __ptr;
}
};
@@ -78,10 +72,7 @@ public:
_LIBCPP_INLINE_VISIBILITY
typename _EnableIfConvertible<_Up>::type
operator()(_Up* __ptr) const _NOEXCEPT {
- static_assert(sizeof(_Tp) > 0,
- "default_delete can not delete incomplete type");
- static_assert(!is_void<_Tp>::value,
- "default_delete can not delete void type");
+ static_assert(sizeof(_Up) >= 0, "cannot delete an incomplete type");
delete[] __ptr;
}
};
@@ -144,7 +135,7 @@ private:
typename __dependent_type<_DeleterSFINAE, _Dummy>::__bad_rval_ref_type;
template <bool _Dummy, class _Deleter = typename __dependent_type<
- __identity<deleter_type>, _Dummy>::type>
+ __type_identity<deleter_type>, _Dummy>::type>
using _EnableIfDeleterDefaultConstructible _LIBCPP_NODEBUG =
typename enable_if<is_default_constructible<_Deleter>::value &&
!is_pointer<_Deleter>::value>::type;
@@ -264,7 +255,6 @@ public:
unique_ptr& operator=(unique_ptr const&) = delete;
#endif
-
_LIBCPP_INLINE_VISIBILITY
~unique_ptr() { reset(); }
@@ -359,7 +349,7 @@ private:
typename __dependent_type<_DeleterSFINAE, _Dummy>::__bad_rval_ref_type;
template <bool _Dummy, class _Deleter = typename __dependent_type<
- __identity<deleter_type>, _Dummy>::type>
+ __type_identity<deleter_type>, _Dummy>::type>
using _EnableIfDeleterDefaultConstructible _LIBCPP_NODEBUG =
typename enable_if<is_default_constructible<_Deleter>::value &&
!is_pointer<_Deleter>::value>::type;
@@ -486,7 +476,6 @@ public:
unique_ptr(unique_ptr const&) = delete;
unique_ptr& operator=(unique_ptr const&) = delete;
#endif
-
public:
_LIBCPP_INLINE_VISIBILITY
~unique_ptr() { reset(); }
diff --git a/libcxx/include/__memory/uses_allocator.h b/libcxx/include/__memory/uses_allocator.h
index 2e186207408b..4a07a4a52121 100644
--- a/libcxx/include/__memory/uses_allocator.h
+++ b/libcxx/include/__memory/uses_allocator.h
@@ -15,7 +15,7 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -24,11 +24,10 @@ template <class _Tp>
struct __has_allocator_type
{
private:
- struct __two {char __lx; char __lxx;};
- template <class _Up> static __two __test(...);
- template <class _Up> static char __test(typename _Up::allocator_type* = 0);
+ template <class _Up> static false_type __test(...);
+ template <class _Up> static true_type __test(typename _Up::allocator_type* = 0);
public:
- static const bool value = sizeof(__test<_Tp>(0)) == 1;
+ static const bool value = decltype(__test<_Tp>(0))::value;
};
template <class _Tp, class _Alloc, bool = __has_allocator_type<_Tp>::value>
diff --git a/libcxx/include/__mutex_base b/libcxx/include/__mutex_base
index 8d8c8af7070c..da056b6d1423 100644
--- a/libcxx/include/__mutex_base
+++ b/libcxx/include/__mutex_base
@@ -10,15 +10,18 @@
#ifndef _LIBCPP___MUTEX_BASE
#define _LIBCPP___MUTEX_BASE
+#include <__chrono/duration.h>
+#include <__chrono/steady_clock.h>
+#include <__chrono/system_clock.h>
+#include <__chrono/time_point.h>
#include <__config>
#include <__threading_support>
-#include <chrono>
#include <ratio>
#include <system_error>
#include <time.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
diff --git a/libcxx/include/__node_handle b/libcxx/include/__node_handle
index f313409bb682..71309be62f3c 100644
--- a/libcxx/include/__node_handle
+++ b/libcxx/include/__node_handle
@@ -58,13 +58,13 @@ public:
*/
+#include <__assert>
#include <__config>
-#include <__debug>
#include <memory>
#include <optional>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__nullptr b/libcxx/include/__nullptr
deleted file mode 100644
index c6645cd0150e..000000000000
--- a/libcxx/include/__nullptr
+++ /dev/null
@@ -1,61 +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_NULLPTR
-#define _LIBCPP_NULLPTR
-
-#include <__config>
-
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
-#endif
-
-#ifdef _LIBCPP_HAS_NO_NULLPTR
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-struct _LIBCPP_TEMPLATE_VIS nullptr_t
-{
- void* __lx;
-
- struct __nat {int __for_bool_;};
-
- _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR nullptr_t() : __lx(0) {}
- _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR nullptr_t(int __nat::*) : __lx(0) {}
-
- _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR operator int __nat::*() const {return 0;}
-
- template <class _Tp>
- _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
- operator _Tp* () const {return 0;}
-
- template <class _Tp, class _Up>
- _LIBCPP_INLINE_VISIBILITY
- operator _Tp _Up::* () const {return 0;}
-
- friend _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR bool operator==(nullptr_t, nullptr_t) {return true;}
- friend _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR bool operator!=(nullptr_t, nullptr_t) {return false;}
-};
-
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR nullptr_t __get_nullptr_t() {return nullptr_t(0);}
-
-#define nullptr _VSTD::__get_nullptr_t()
-
-_LIBCPP_END_NAMESPACE_STD
-
-#else // _LIBCPP_HAS_NO_NULLPTR
-
-namespace std
-{
- typedef decltype(nullptr) nullptr_t;
-} // namespace std
-
-#endif // _LIBCPP_HAS_NO_NULLPTR
-
-#endif // _LIBCPP_NULLPTR
diff --git a/libcxx/include/__numeric/accumulate.h b/libcxx/include/__numeric/accumulate.h
index fcdad58df141..fa759872ce77 100644
--- a/libcxx/include/__numeric/accumulate.h
+++ b/libcxx/include/__numeric/accumulate.h
@@ -14,7 +14,7 @@
#include <__utility/move.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__numeric/gcd_lcm.h b/libcxx/include/__numeric/gcd_lcm.h
index 34c0e533c928..9a53a001f211 100644
--- a/libcxx/include/__numeric/gcd_lcm.h
+++ b/libcxx/include/__numeric/gcd_lcm.h
@@ -10,8 +10,8 @@
#ifndef _LIBCPP___NUMERIC_GCD_LCM_H
#define _LIBCPP___NUMERIC_GCD_LCM_H
+#include <__assert>
#include <__config>
-#include <__debug>
#include <limits>
#include <type_traits>
diff --git a/libcxx/include/__numeric/inner_product.h b/libcxx/include/__numeric/inner_product.h
index 004acdde6a0c..6fe18bb2b19e 100644
--- a/libcxx/include/__numeric/inner_product.h
+++ b/libcxx/include/__numeric/inner_product.h
@@ -14,7 +14,7 @@
#include <__utility/move.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__random/bernoulli_distribution.h b/libcxx/include/__random/bernoulli_distribution.h
index 60ae5eae7033..e97d53f5a421 100644
--- a/libcxx/include/__random/bernoulli_distribution.h
+++ b/libcxx/include/__random/bernoulli_distribution.h
@@ -10,11 +10,12 @@
#define _LIBCPP___RANDOM_BERNOULLI_DISTRIBUTION_H
#include <__config>
+#include <__random/is_valid.h>
#include <__random/uniform_real_distribution.h>
#include <iosfwd>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
@@ -103,6 +104,7 @@ inline
bernoulli_distribution::result_type
bernoulli_distribution::operator()(_URNG& __g, const param_type& __p)
{
+ static_assert(__libcpp_random_is_valid_urng<_URNG>::value, "");
uniform_real_distribution<double> __gen;
return __gen(__g) < __p.p();
}
diff --git a/libcxx/include/__random/binomial_distribution.h b/libcxx/include/__random/binomial_distribution.h
index 9662de8befd9..d0e8f3034939 100644
--- a/libcxx/include/__random/binomial_distribution.h
+++ b/libcxx/include/__random/binomial_distribution.h
@@ -10,12 +10,13 @@
#define _LIBCPP___RANDOM_BINOMIAL_DISTRIBUTION_H
#include <__config>
+#include <__random/is_valid.h>
#include <__random/uniform_real_distribution.h>
#include <cmath>
#include <iosfwd>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
@@ -26,6 +27,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
template<class _IntType = int>
class _LIBCPP_TEMPLATE_VIS binomial_distribution
{
+ static_assert(__libcpp_random_is_valid_inttype<_IntType>::value, "IntType must be an integer type larger than char");
public:
// types
typedef _IntType result_type;
@@ -146,6 +148,7 @@ template<class _URNG>
_IntType
binomial_distribution<_IntType>::operator()(_URNG& __g, const param_type& __pr)
{
+ static_assert(__libcpp_random_is_valid_urng<_URNG>::value, "");
if (__pr.__t_ == 0 || __pr.__p_ == 0)
return 0;
if (__pr.__p_ == 1)
diff --git a/libcxx/include/__random/cauchy_distribution.h b/libcxx/include/__random/cauchy_distribution.h
index 6661e00bf939..5bc44ee8dd4c 100644
--- a/libcxx/include/__random/cauchy_distribution.h
+++ b/libcxx/include/__random/cauchy_distribution.h
@@ -10,13 +10,14 @@
#define _LIBCPP___RANDOM_CAUCHY_DISTRIBUTION_H
#include <__config>
+#include <__random/is_valid.h>
#include <__random/uniform_real_distribution.h>
#include <cmath>
#include <iosfwd>
#include <limits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
@@ -116,6 +117,7 @@ inline
_RealType
cauchy_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p)
{
+ static_assert(__libcpp_random_is_valid_urng<_URNG>::value, "");
uniform_real_distribution<result_type> __gen;
// purposefully let tan arg get as close to pi/2 as it wants, tan will return a finite
return __p.a() + __p.b() * _VSTD::tan(3.1415926535897932384626433832795 * __gen(__g));
diff --git a/libcxx/include/__random/chi_squared_distribution.h b/libcxx/include/__random/chi_squared_distribution.h
index 2aa0762a520c..b98488c20d28 100644
--- a/libcxx/include/__random/chi_squared_distribution.h
+++ b/libcxx/include/__random/chi_squared_distribution.h
@@ -15,7 +15,7 @@
#include <limits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
diff --git a/libcxx/include/__random/clamp_to_integral.h b/libcxx/include/__random/clamp_to_integral.h
index dd5d2b0186e4..7d44ff9cfcad 100644
--- a/libcxx/include/__random/clamp_to_integral.h
+++ b/libcxx/include/__random/clamp_to_integral.h
@@ -15,7 +15,7 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
diff --git a/libcxx/include/__random/default_random_engine.h b/libcxx/include/__random/default_random_engine.h
index 61c5cf9c7142..89792f4f0d43 100644
--- a/libcxx/include/__random/default_random_engine.h
+++ b/libcxx/include/__random/default_random_engine.h
@@ -13,7 +13,7 @@
#include <__random/linear_congruential_engine.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__random/discard_block_engine.h b/libcxx/include/__random/discard_block_engine.h
index 335715211884..c58d66b58869 100644
--- a/libcxx/include/__random/discard_block_engine.h
+++ b/libcxx/include/__random/discard_block_engine.h
@@ -17,7 +17,7 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
diff --git a/libcxx/include/__random/discrete_distribution.h b/libcxx/include/__random/discrete_distribution.h
index dc9881a92c38..d899e72d87f9 100644
--- a/libcxx/include/__random/discrete_distribution.h
+++ b/libcxx/include/__random/discrete_distribution.h
@@ -11,6 +11,7 @@
#include <__algorithm/upper_bound.h>
#include <__config>
+#include <__random/is_valid.h>
#include <__random/uniform_real_distribution.h>
#include <cstddef>
#include <iosfwd>
@@ -18,7 +19,7 @@
#include <vector>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
@@ -29,6 +30,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
template<class _IntType = int>
class _LIBCPP_TEMPLATE_VIS discrete_distribution
{
+ static_assert(__libcpp_random_is_valid_inttype<_IntType>::value, "IntType must be an integer type larger than char");
public:
// types
typedef _IntType result_type;
@@ -211,6 +213,7 @@ template<class _URNG>
_IntType
discrete_distribution<_IntType>::operator()(_URNG& __g, const param_type& __p)
{
+ static_assert(__libcpp_random_is_valid_urng<_URNG>::value, "");
uniform_real_distribution<double> __gen;
return static_cast<_IntType>(
_VSTD::upper_bound(__p.__p_.begin(), __p.__p_.end(), __gen(__g)) -
diff --git a/libcxx/include/__random/exponential_distribution.h b/libcxx/include/__random/exponential_distribution.h
index 9e555f0c1075..1c9e9e0d9ef1 100644
--- a/libcxx/include/__random/exponential_distribution.h
+++ b/libcxx/include/__random/exponential_distribution.h
@@ -11,13 +11,14 @@
#include <__config>
#include <__random/generate_canonical.h>
+#include <__random/is_valid.h>
#include <__random/uniform_real_distribution.h>
#include <cmath>
#include <iosfwd>
#include <limits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
@@ -109,6 +110,7 @@ template<class _URNG>
_RealType
exponential_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p)
{
+ static_assert(__libcpp_random_is_valid_urng<_URNG>::value, "");
return -_VSTD::log
(
result_type(1) -
diff --git a/libcxx/include/__random/extreme_value_distribution.h b/libcxx/include/__random/extreme_value_distribution.h
index 0e200f91d7ff..ba30aa5b88c3 100644
--- a/libcxx/include/__random/extreme_value_distribution.h
+++ b/libcxx/include/__random/extreme_value_distribution.h
@@ -10,13 +10,14 @@
#define _LIBCPP___RANDOM_EXTREME_VALUE_DISTRIBUTION_H
#include <__config>
+#include <__random/is_valid.h>
#include <__random/uniform_real_distribution.h>
#include <cmath>
#include <iosfwd>
#include <limits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
@@ -116,6 +117,7 @@ template<class _URNG>
_RealType
extreme_value_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p)
{
+ static_assert(__libcpp_random_is_valid_urng<_URNG>::value, "");
return __p.a() - __p.b() *
_VSTD::log(-_VSTD::log(1-uniform_real_distribution<result_type>()(__g)));
}
diff --git a/libcxx/include/__random/fisher_f_distribution.h b/libcxx/include/__random/fisher_f_distribution.h
index bf64d33a645a..60c7f28c0bb0 100644
--- a/libcxx/include/__random/fisher_f_distribution.h
+++ b/libcxx/include/__random/fisher_f_distribution.h
@@ -11,11 +11,12 @@
#include <__config>
#include <__random/gamma_distribution.h>
+#include <__random/is_valid.h>
#include <iosfwd>
#include <limits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
@@ -114,6 +115,7 @@ template<class _URNG>
_RealType
fisher_f_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p)
{
+ static_assert(__libcpp_random_is_valid_urng<_URNG>::value, "");
gamma_distribution<result_type> __gdm(__p.m() * result_type(.5));
gamma_distribution<result_type> __gdn(__p.n() * result_type(.5));
return __p.n() * __gdm(__g) / (__p.m() * __gdn(__g));
diff --git a/libcxx/include/__random/gamma_distribution.h b/libcxx/include/__random/gamma_distribution.h
index 34167e463528..986d79b67aa3 100644
--- a/libcxx/include/__random/gamma_distribution.h
+++ b/libcxx/include/__random/gamma_distribution.h
@@ -11,13 +11,14 @@
#include <__config>
#include <__random/exponential_distribution.h>
+#include <__random/is_valid.h>
#include <__random/uniform_real_distribution.h>
#include <cmath>
#include <iosfwd>
#include <limits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
@@ -117,6 +118,7 @@ template<class _URNG>
_RealType
gamma_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p)
{
+ static_assert(__libcpp_random_is_valid_urng<_URNG>::value, "");
result_type __a = __p.alpha();
uniform_real_distribution<result_type> __gen(0, 1);
exponential_distribution<result_type> __egen;
diff --git a/libcxx/include/__random/generate_canonical.h b/libcxx/include/__random/generate_canonical.h
index 46c3b2980952..84efa7803c94 100644
--- a/libcxx/include/__random/generate_canonical.h
+++ b/libcxx/include/__random/generate_canonical.h
@@ -16,7 +16,7 @@
#include <limits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
diff --git a/libcxx/include/__random/geometric_distribution.h b/libcxx/include/__random/geometric_distribution.h
index 174914eaed2e..8e1be522e0e3 100644
--- a/libcxx/include/__random/geometric_distribution.h
+++ b/libcxx/include/__random/geometric_distribution.h
@@ -10,12 +10,13 @@
#define _LIBCPP___RANDOM_GEOMETRIC_DISTRIBUTION_H
#include <__config>
+#include <__random/is_valid.h>
#include <__random/negative_binomial_distribution.h>
#include <iosfwd>
#include <limits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
@@ -26,6 +27,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
template<class _IntType = int>
class _LIBCPP_TEMPLATE_VIS geometric_distribution
{
+ static_assert(__libcpp_random_is_valid_inttype<_IntType>::value, "IntType must be an integer type larger than char");
public:
// types
typedef _IntType result_type;
diff --git a/libcxx/include/__random/independent_bits_engine.h b/libcxx/include/__random/independent_bits_engine.h
index f0e8c654246b..e80d6eec49cb 100644
--- a/libcxx/include/__random/independent_bits_engine.h
+++ b/libcxx/include/__random/independent_bits_engine.h
@@ -18,7 +18,7 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
diff --git a/libcxx/include/__random/is_seed_sequence.h b/libcxx/include/__random/is_seed_sequence.h
index 46b1d719ddfb..a6832f51c1ee 100644
--- a/libcxx/include/__random/is_seed_sequence.h
+++ b/libcxx/include/__random/is_seed_sequence.h
@@ -13,7 +13,7 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__random/is_valid.h b/libcxx/include/__random/is_valid.h
new file mode 100644
index 000000000000..d41bfa45ea70
--- /dev/null
+++ b/libcxx/include/__random/is_valid.h
@@ -0,0 +1,58 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___RANDOM_IS_VALID_H
+#define _LIBCPP___RANDOM_IS_VALID_H
+
+#include <__config>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+// [rand.req.genl]/1.5:
+// The effect of instantiating a template that has a template type parameter
+// named IntType is undefined unless the corresponding template argument is
+// cv-unqualified and is one of short, int, long, long long, unsigned short,
+// unsigned int, unsigned long, or unsigned long long.
+
+template<class> struct __libcpp_random_is_valid_inttype : false_type {};
+template<> struct __libcpp_random_is_valid_inttype<short> : true_type {};
+template<> struct __libcpp_random_is_valid_inttype<int> : true_type {};
+template<> struct __libcpp_random_is_valid_inttype<long> : true_type {};
+template<> struct __libcpp_random_is_valid_inttype<long long> : true_type {};
+template<> struct __libcpp_random_is_valid_inttype<unsigned short> : true_type {};
+template<> struct __libcpp_random_is_valid_inttype<unsigned int> : true_type {};
+template<> struct __libcpp_random_is_valid_inttype<unsigned long> : true_type {};
+template<> struct __libcpp_random_is_valid_inttype<unsigned long long> : true_type {};
+
+#ifndef _LIBCPP_HAS_NO_INT128
+template<> struct __libcpp_random_is_valid_inttype<__int128_t> : true_type {};
+template<> struct __libcpp_random_is_valid_inttype<__uint128_t> : true_type {};
+#endif // _LIBCPP_HAS_NO_INT128
+
+// [rand.req.urng]/3:
+// A class G meets the uniform random bit generator requirements if G models
+// uniform_random_bit_generator, invoke_result_t<G&> is an unsigned integer type,
+// and G provides a nested typedef-name result_type that denotes the same type
+// as invoke_result_t<G&>.
+// (In particular, reject URNGs with signed result_types; our distributions cannot
+// handle such generator types.)
+
+template<class, class = void> struct __libcpp_random_is_valid_urng : false_type {};
+template<class _Gp> struct __libcpp_random_is_valid_urng<_Gp, __enable_if_t<
+ is_unsigned<typename _Gp::result_type>::value &&
+ _IsSame<decltype(declval<_Gp&>()()), typename _Gp::result_type>::value
+> > : true_type {};
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___RANDOM_IS_VALID_H
diff --git a/libcxx/include/__random/knuth_b.h b/libcxx/include/__random/knuth_b.h
index ade853884dd3..f5b31cb64fa4 100644
--- a/libcxx/include/__random/knuth_b.h
+++ b/libcxx/include/__random/knuth_b.h
@@ -14,7 +14,7 @@
#include <__random/shuffle_order_engine.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__random/linear_congruential_engine.h b/libcxx/include/__random/linear_congruential_engine.h
index 64c9f584114c..42b40813e0ac 100644
--- a/libcxx/include/__random/linear_congruential_engine.h
+++ b/libcxx/include/__random/linear_congruential_engine.h
@@ -16,7 +16,7 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
@@ -218,8 +218,8 @@ private:
static_assert(__m == 0 || __c < __m, "linear_congruential_engine invalid parameters");
static_assert(is_unsigned<_UIntType>::value, "_UIntType must be unsigned type");
public:
- static _LIBCPP_CONSTEXPR const result_type _Min = __c == 0u ? 1u: 0u;
- static _LIBCPP_CONSTEXPR const result_type _Max = __m - 1u;
+ static _LIBCPP_CONSTEXPR const result_type _Min = __c == 0u ? 1u : 0u;
+ static _LIBCPP_CONSTEXPR const result_type _Max = __m - _UIntType(1u);
static_assert(_Min < _Max, "linear_congruential_engine invalid parameters");
// engine characteristics
diff --git a/libcxx/include/__random/log2.h b/libcxx/include/__random/log2.h
index 3d9640c1f787..b077d211cefa 100644
--- a/libcxx/include/__random/log2.h
+++ b/libcxx/include/__random/log2.h
@@ -14,7 +14,7 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__random/lognormal_distribution.h b/libcxx/include/__random/lognormal_distribution.h
index 8fadb5a1e66a..048d7dade9eb 100644
--- a/libcxx/include/__random/lognormal_distribution.h
+++ b/libcxx/include/__random/lognormal_distribution.h
@@ -16,7 +16,7 @@
#include <limits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
diff --git a/libcxx/include/__random/mersenne_twister_engine.h b/libcxx/include/__random/mersenne_twister_engine.h
index 121ffae37ec0..8bceac05dce9 100644
--- a/libcxx/include/__random/mersenne_twister_engine.h
+++ b/libcxx/include/__random/mersenne_twister_engine.h
@@ -20,7 +20,7 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
diff --git a/libcxx/include/__random/negative_binomial_distribution.h b/libcxx/include/__random/negative_binomial_distribution.h
index 7329bac2ff85..72ce88ea74ba 100644
--- a/libcxx/include/__random/negative_binomial_distribution.h
+++ b/libcxx/include/__random/negative_binomial_distribution.h
@@ -12,12 +12,13 @@
#include <__config>
#include <__random/bernoulli_distribution.h>
#include <__random/gamma_distribution.h>
+#include <__random/is_valid.h>
#include <__random/poisson_distribution.h>
#include <iosfwd>
#include <limits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
@@ -28,6 +29,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
template<class _IntType = int>
class _LIBCPP_TEMPLATE_VIS negative_binomial_distribution
{
+ static_assert(__libcpp_random_is_valid_inttype<_IntType>::value, "IntType must be an integer type larger than char");
public:
// types
typedef _IntType result_type;
@@ -116,6 +118,7 @@ template<class _URNG>
_IntType
negative_binomial_distribution<_IntType>::operator()(_URNG& __urng, const param_type& __pr)
{
+ static_assert(__libcpp_random_is_valid_urng<_URNG>::value, "");
result_type __k = __pr.k();
double __p = __pr.p();
if (__k <= 21 * __p)
diff --git a/libcxx/include/__random/normal_distribution.h b/libcxx/include/__random/normal_distribution.h
index b460ffb7ea9d..0431df927200 100644
--- a/libcxx/include/__random/normal_distribution.h
+++ b/libcxx/include/__random/normal_distribution.h
@@ -10,13 +10,14 @@
#define _LIBCPP___RANDOM_NORMAL_DISTRIBUTION_H
#include <__config>
+#include <__random/is_valid.h>
#include <__random/uniform_real_distribution.h>
#include <cmath>
#include <iosfwd>
#include <limits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
@@ -131,6 +132,7 @@ template<class _URNG>
_RealType
normal_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p)
{
+ static_assert(__libcpp_random_is_valid_urng<_URNG>::value, "");
result_type _Up;
if (_V_hot_)
{
diff --git a/libcxx/include/__random/piecewise_constant_distribution.h b/libcxx/include/__random/piecewise_constant_distribution.h
index ece20d1a1d6e..a33ab0720062 100644
--- a/libcxx/include/__random/piecewise_constant_distribution.h
+++ b/libcxx/include/__random/piecewise_constant_distribution.h
@@ -11,13 +11,14 @@
#include <__algorithm/upper_bound.h>
#include <__config>
+#include <__random/is_valid.h>
#include <__random/uniform_real_distribution.h>
#include <iosfwd>
#include <numeric>
#include <vector>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
@@ -284,6 +285,7 @@ template<class _URNG>
_RealType
piecewise_constant_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p)
{
+ static_assert(__libcpp_random_is_valid_urng<_URNG>::value, "");
typedef uniform_real_distribution<result_type> _Gen;
result_type __u = _Gen()(__g);
ptrdiff_t __k = _VSTD::upper_bound(__p.__areas_.begin(), __p.__areas_.end(),
diff --git a/libcxx/include/__random/piecewise_linear_distribution.h b/libcxx/include/__random/piecewise_linear_distribution.h
index b2ba164d0707..e69ce9444072 100644
--- a/libcxx/include/__random/piecewise_linear_distribution.h
+++ b/libcxx/include/__random/piecewise_linear_distribution.h
@@ -11,13 +11,14 @@
#include <__algorithm/upper_bound.h>
#include <__config>
+#include <__random/is_valid.h>
#include <__random/uniform_real_distribution.h>
#include <iosfwd>
#include <numeric>
#include <vector>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
@@ -289,6 +290,7 @@ template<class _URNG>
_RealType
piecewise_linear_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p)
{
+ static_assert(__libcpp_random_is_valid_urng<_URNG>::value, "");
typedef uniform_real_distribution<result_type> _Gen;
result_type __u = _Gen()(__g);
ptrdiff_t __k = _VSTD::upper_bound(__p.__areas_.begin(), __p.__areas_.end(),
diff --git a/libcxx/include/__random/poisson_distribution.h b/libcxx/include/__random/poisson_distribution.h
index d157e8f230ef..7730923ad6ca 100644
--- a/libcxx/include/__random/poisson_distribution.h
+++ b/libcxx/include/__random/poisson_distribution.h
@@ -12,6 +12,7 @@
#include <__config>
#include <__random/clamp_to_integral.h>
#include <__random/exponential_distribution.h>
+#include <__random/is_valid.h>
#include <__random/normal_distribution.h>
#include <__random/uniform_real_distribution.h>
#include <cmath>
@@ -19,7 +20,7 @@
#include <limits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
@@ -30,6 +31,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
template<class _IntType = int>
class _LIBCPP_TEMPLATE_VIS poisson_distribution
{
+ static_assert(__libcpp_random_is_valid_inttype<_IntType>::value, "IntType must be an integer type larger than char");
public:
// types
typedef _IntType result_type;
@@ -157,6 +159,7 @@ template<class _URNG>
_IntType
poisson_distribution<_IntType>::operator()(_URNG& __urng, const param_type& __pr)
{
+ static_assert(__libcpp_random_is_valid_urng<_URNG>::value, "");
double __tx;
uniform_real_distribution<double> __urd;
if (__pr.__mean_ < 10)
diff --git a/libcxx/include/__random/random_device.h b/libcxx/include/__random/random_device.h
index ef11977f9b77..e82b437a3b54 100644
--- a/libcxx/include/__random/random_device.h
+++ b/libcxx/include/__random/random_device.h
@@ -13,7 +13,7 @@
#include <string>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
@@ -28,10 +28,8 @@ class _LIBCPP_TYPE_VIS random_device
#ifdef _LIBCPP_USING_DEV_RANDOM
int __f_;
#elif !defined(_LIBCPP_ABI_NO_RANDOM_DEVICE_COMPATIBILITY_LAYOUT)
-# if defined(__clang__)
-# pragma clang diagnostic push
-# pragma clang diagnostic ignored "-Wunused-private-field"
-# endif
+ _LIBCPP_DIAGNOSTIC_PUSH
+ _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wunused-private-field")
// Apple platforms used to use the `_LIBCPP_USING_DEV_RANDOM` code path, and now
// use `arc4random()` as of this comment. In order to avoid breaking the ABI, we
@@ -42,9 +40,7 @@ class _LIBCPP_TYPE_VIS random_device
// ... vendors can add workarounds here if they switch to a different representation ...
-# if defined(__clang__)
-# pragma clang diagnostic pop
-# endif
+ _LIBCPP_DIAGNOSTIC_POP
#endif
public:
diff --git a/libcxx/include/__random/ranlux.h b/libcxx/include/__random/ranlux.h
index 0b415928df4d..e44cece39dfc 100644
--- a/libcxx/include/__random/ranlux.h
+++ b/libcxx/include/__random/ranlux.h
@@ -15,7 +15,7 @@
#include <cstdint>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__random/seed_seq.h b/libcxx/include/__random/seed_seq.h
index 1a0877995650..330537fa0023 100644
--- a/libcxx/include/__random/seed_seq.h
+++ b/libcxx/include/__random/seed_seq.h
@@ -17,7 +17,7 @@
#include <vector>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
@@ -109,39 +109,63 @@ seed_seq::generate(_RandomAccessIterator __first, _RandomAccessIterator __last)
__first[__q] += __r;
__first[0] = __r;
}
+ // Initialize indexing terms used with if statements as an optimization to
+ // avoid calculating modulo n on every loop iteration for each term.
+ size_t __kmodn = 0; // __k % __n
+ size_t __k1modn = __n - 1; // (__k - 1) % __n
+ size_t __kpmodn = __p % __n; // (__k + __p) % __n
+ size_t __kqmodn = __q % __n; // (__k + __q) % __n
+
for (size_t __k = 1; __k <= __s; ++__k)
{
- const size_t __kmodn = __k % __n;
- const size_t __kpmodn = (__k + __p) % __n;
- result_type __r = 1664525 * _Tp(__first[__kmodn] ^ __first[__kpmodn]
- ^ __first[(__k - 1) % __n]);
- __first[__kpmodn] += __r;
- __r += __kmodn + __v_[__k-1];
- __first[(__k + __q) % __n] += __r;
- __first[__kmodn] = __r;
+ if (++__kmodn == __n)
+ __kmodn = 0;
+ if (++__k1modn == __n)
+ __k1modn = 0;
+ if (++__kpmodn == __n)
+ __kpmodn = 0;
+ if (++__kqmodn == __n)
+ __kqmodn = 0;
+
+ result_type __r = 1664525 * _Tp(__first[__kmodn] ^ __first[__kpmodn] ^ __first[__k1modn]);
+ __first[__kpmodn] += __r;
+ __r += __kmodn + __v_[__k - 1];
+ __first[__kqmodn] += __r;
+ __first[__kmodn] = __r;
}
for (size_t __k = __s + 1; __k < __m; ++__k)
{
- const size_t __kmodn = __k % __n;
- const size_t __kpmodn = (__k + __p) % __n;
- result_type __r = 1664525 * _Tp(__first[__kmodn] ^ __first[__kpmodn]
- ^ __first[(__k - 1) % __n]);
- __first[__kpmodn] += __r;
- __r += __kmodn;
- __first[(__k + __q) % __n] += __r;
- __first[__kmodn] = __r;
+ if (++__kmodn == __n)
+ __kmodn = 0;
+ if (++__k1modn == __n)
+ __k1modn = 0;
+ if (++__kpmodn == __n)
+ __kpmodn = 0;
+ if (++__kqmodn == __n)
+ __kqmodn = 0;
+
+ result_type __r = 1664525 * _Tp(__first[__kmodn] ^ __first[__kpmodn] ^ __first[__k1modn]);
+ __first[__kpmodn] += __r;
+ __r += __kmodn;
+ __first[__kqmodn] += __r;
+ __first[__kmodn] = __r;
}
for (size_t __k = __m; __k < __m + __n; ++__k)
{
- const size_t __kmodn = __k % __n;
- const size_t __kpmodn = (__k + __p) % __n;
- result_type __r = 1566083941 * _Tp(__first[__kmodn] +
- __first[__kpmodn] +
- __first[(__k - 1) % __n]);
- __first[__kpmodn] ^= __r;
- __r -= __kmodn;
- __first[(__k + __q) % __n] ^= __r;
- __first[__kmodn] = __r;
+ if (++__kmodn == __n)
+ __kmodn = 0;
+ if (++__k1modn == __n)
+ __k1modn = 0;
+ if (++__kpmodn == __n)
+ __kpmodn = 0;
+ if (++__kqmodn == __n)
+ __kqmodn = 0;
+
+ result_type __r = 1566083941 * _Tp(__first[__kmodn] + __first[__kpmodn] + __first[__k1modn]);
+ __first[__kpmodn] ^= __r;
+ __r -= __kmodn;
+ __first[__kqmodn] ^= __r;
+ __first[__kmodn] = __r;
}
}
}
diff --git a/libcxx/include/__random/shuffle_order_engine.h b/libcxx/include/__random/shuffle_order_engine.h
index 7a5735dd7933..c2f76f609ae5 100644
--- a/libcxx/include/__random/shuffle_order_engine.h
+++ b/libcxx/include/__random/shuffle_order_engine.h
@@ -18,7 +18,7 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
diff --git a/libcxx/include/__random/student_t_distribution.h b/libcxx/include/__random/student_t_distribution.h
index 0cf911e4cd76..9e95f97cefab 100644
--- a/libcxx/include/__random/student_t_distribution.h
+++ b/libcxx/include/__random/student_t_distribution.h
@@ -11,13 +11,14 @@
#include <__config>
#include <__random/gamma_distribution.h>
+#include <__random/is_valid.h>
#include <__random/normal_distribution.h>
#include <cmath>
#include <iosfwd>
#include <limits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
@@ -111,6 +112,7 @@ template<class _URNG>
_RealType
student_t_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p)
{
+ static_assert(__libcpp_random_is_valid_urng<_URNG>::value, "");
gamma_distribution<result_type> __gd(__p.n() * .5, 2);
return __nd_(__g) * _VSTD::sqrt(__p.n()/__gd(__g));
}
diff --git a/libcxx/include/__random/subtract_with_carry_engine.h b/libcxx/include/__random/subtract_with_carry_engine.h
index 073f84dccff6..fdbe2d2e9be3 100644
--- a/libcxx/include/__random/subtract_with_carry_engine.h
+++ b/libcxx/include/__random/subtract_with_carry_engine.h
@@ -21,7 +21,7 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
diff --git a/libcxx/include/__random/uniform_int_distribution.h b/libcxx/include/__random/uniform_int_distribution.h
index 55b4761637f0..dd0a7e4e4982 100644
--- a/libcxx/include/__random/uniform_int_distribution.h
+++ b/libcxx/include/__random/uniform_int_distribution.h
@@ -11,6 +11,7 @@
#include <__bits>
#include <__config>
+#include <__random/is_valid.h>
#include <__random/log2.h>
#include <bit>
#include <cstddef>
@@ -20,7 +21,7 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
@@ -155,9 +156,10 @@ __independent_bits_engine<_Engine, _UIntType>::__eval(true_type)
return _Sp;
}
-template<class _IntType = int> // __int128_t is also supported as an extension here
+template<class _IntType = int>
class uniform_int_distribution
{
+ static_assert(__libcpp_random_is_valid_inttype<_IntType>::value, "IntType must be an integer type larger than char");
public:
// types
typedef _IntType result_type;
@@ -230,6 +232,7 @@ typename uniform_int_distribution<_IntType>::result_type
uniform_int_distribution<_IntType>::operator()(_URNG& __g, const param_type& __p)
_LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
{
+ static_assert(__libcpp_random_is_valid_urng<_URNG>::value, "");
typedef typename conditional<sizeof(result_type) <= sizeof(uint32_t), uint32_t,
typename make_unsigned<result_type>::type>::type _UIntType;
const _UIntType _Rp = _UIntType(__p.b()) - _UIntType(__p.a()) + _UIntType(1);
diff --git a/libcxx/include/__random/uniform_random_bit_generator.h b/libcxx/include/__random/uniform_random_bit_generator.h
index 7b2f0df868d7..84a30b0ebe16 100644
--- a/libcxx/include/__random/uniform_random_bit_generator.h
+++ b/libcxx/include/__random/uniform_random_bit_generator.h
@@ -16,7 +16,7 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
@@ -24,7 +24,7 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17
// [rand.req.urng]
template<class _Gen>
@@ -36,7 +36,7 @@ concept uniform_random_bit_generator =
requires bool_constant<(_Gen::min() < _Gen::max())>::value;
};
-#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__random/uniform_real_distribution.h b/libcxx/include/__random/uniform_real_distribution.h
index 967e4e26fd0c..7d2ecda732fe 100644
--- a/libcxx/include/__random/uniform_real_distribution.h
+++ b/libcxx/include/__random/uniform_real_distribution.h
@@ -11,12 +11,13 @@
#include <__config>
#include <__random/generate_canonical.h>
+#include <__random/is_valid.h>
#include <iosfwd>
#include <limits>
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
@@ -115,6 +116,7 @@ inline
typename uniform_real_distribution<_RealType>::result_type
uniform_real_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p)
{
+ static_assert(__libcpp_random_is_valid_urng<_URNG>::value, "");
return (__p.b() - __p.a())
* _VSTD::generate_canonical<_RealType, numeric_limits<_RealType>::digits>(__g)
+ __p.a();
diff --git a/libcxx/include/__random/weibull_distribution.h b/libcxx/include/__random/weibull_distribution.h
index 4c5e4e8fff1c..85bae65096cb 100644
--- a/libcxx/include/__random/weibull_distribution.h
+++ b/libcxx/include/__random/weibull_distribution.h
@@ -16,7 +16,7 @@
#include <limits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
diff --git a/libcxx/include/__ranges/access.h b/libcxx/include/__ranges/access.h
index 67c6c57bd81e..0f1cca033a23 100644
--- a/libcxx/include/__ranges/access.h
+++ b/libcxx/include/__ranges/access.h
@@ -14,18 +14,16 @@
#include <__iterator/concepts.h>
#include <__iterator/readable_traits.h>
#include <__ranges/enable_borrowed_range.h>
-#include <__utility/as_const.h>
#include <__utility/auto_cast.h>
-#include <concepts>
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17
namespace ranges {
template <class _Tp>
@@ -59,10 +57,17 @@ namespace __begin {
struct __fn {
template <class _Tp>
- requires is_array_v<remove_cv_t<_Tp>>
- [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp& __t) const noexcept
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp (&__t)[]) const noexcept
+ requires (sizeof(_Tp) >= 0) // Disallow incomplete element types.
{
- return __t;
+ return __t + 0;
+ }
+
+ template <class _Tp, size_t _Np>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp (&__t)[_Np]) const noexcept
+ requires (sizeof(_Tp) >= 0) // Disallow incomplete element types.
+ {
+ return __t + 0;
}
template <class _Tp>
@@ -123,11 +128,10 @@ namespace __end {
{ _LIBCPP_AUTO_CAST(end(__t)) } -> sentinel_for<iterator_t<_Tp>>;
};
- class __fn {
- public:
+ struct __fn {
template <class _Tp, size_t _Np>
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp (&__t)[_Np]) const noexcept
- requires (sizeof(*__t) != 0) // Disallow incomplete element types.
+ requires (sizeof(_Tp) >= 0) // Disallow incomplete element types.
{
return __t + _Np;
}
@@ -213,7 +217,7 @@ inline namespace __cpo {
} // namespace __cpo
} // namespace ranges
-#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__ranges/all.h b/libcxx/include/__ranges/all.h
index b0a58e9bad82..181477419c85 100644
--- a/libcxx/include/__ranges/all.h
+++ b/libcxx/include/__ranges/all.h
@@ -23,12 +23,12 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
namespace ranges::views {
@@ -38,30 +38,31 @@ namespace __all {
requires ranges::view<decay_t<_Tp>>
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI
constexpr auto operator()(_Tp&& __t) const
- noexcept(noexcept(_LIBCPP_AUTO_CAST(_VSTD::forward<_Tp>(__t))))
+ noexcept(noexcept(_LIBCPP_AUTO_CAST(std::forward<_Tp>(__t))))
+ -> decltype(_LIBCPP_AUTO_CAST(std::forward<_Tp>(__t)))
{
- return _LIBCPP_AUTO_CAST(_VSTD::forward<_Tp>(__t));
+ return _LIBCPP_AUTO_CAST(std::forward<_Tp>(__t));
}
template<class _Tp>
requires (!ranges::view<decay_t<_Tp>>) &&
- requires (_Tp&& __t) { ranges::ref_view{_VSTD::forward<_Tp>(__t)}; }
+ requires (_Tp&& __t) { ranges::ref_view{std::forward<_Tp>(__t)}; }
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI
constexpr auto operator()(_Tp&& __t) const
- noexcept(noexcept(ranges::ref_view{_VSTD::forward<_Tp>(__t)}))
+ noexcept(noexcept(ranges::ref_view{std::forward<_Tp>(__t)}))
{
- return ranges::ref_view{_VSTD::forward<_Tp>(__t)};
+ return ranges::ref_view{std::forward<_Tp>(__t)};
}
template<class _Tp>
requires (!ranges::view<decay_t<_Tp>> &&
- !requires (_Tp&& __t) { ranges::ref_view{_VSTD::forward<_Tp>(__t)}; } &&
- requires (_Tp&& __t) { ranges::owning_view{_VSTD::forward<_Tp>(__t)}; })
+ !requires (_Tp&& __t) { ranges::ref_view{std::forward<_Tp>(__t)}; } &&
+ requires (_Tp&& __t) { ranges::owning_view{std::forward<_Tp>(__t)}; })
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI
constexpr auto operator()(_Tp&& __t) const
- noexcept(noexcept(ranges::owning_view{_VSTD::forward<_Tp>(__t)}))
+ noexcept(noexcept(ranges::owning_view{std::forward<_Tp>(__t)}))
{
- return ranges::owning_view{_VSTD::forward<_Tp>(__t)};
+ return ranges::owning_view{std::forward<_Tp>(__t)};
}
};
} // namespace __all
@@ -75,7 +76,7 @@ using all_t = decltype(views::all(declval<_Range>()));
} // namespace ranges::views
-#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__ranges/common_view.h b/libcxx/include/__ranges/common_view.h
index fb8078d65558..61b9b61f26aa 100644
--- a/libcxx/include/__ranges/common_view.h
+++ b/libcxx/include/__ranges/common_view.h
@@ -25,12 +25,12 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
namespace ranges {
@@ -44,13 +44,13 @@ public:
common_view() requires default_initializable<_View> = default;
_LIBCPP_HIDE_FROM_ABI
- constexpr explicit common_view(_View __v) : __base_(_VSTD::move(__v)) { }
+ constexpr explicit common_view(_View __v) : __base_(std::move(__v)) { }
_LIBCPP_HIDE_FROM_ABI
constexpr _View base() const& requires copy_constructible<_View> { return __base_; }
_LIBCPP_HIDE_FROM_ABI
- constexpr _View base() && { return _VSTD::move(__base_); }
+ constexpr _View base() && { return std::move(__base_); }
_LIBCPP_HIDE_FROM_ABI
constexpr auto begin() {
@@ -109,16 +109,16 @@ namespace __common {
requires common_range<_Range>
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI
constexpr auto operator()(_Range&& __range) const
- noexcept(noexcept(views::all(_VSTD::forward<_Range>(__range))))
- -> decltype( views::all(_VSTD::forward<_Range>(__range)))
- { return views::all(_VSTD::forward<_Range>(__range)); }
+ noexcept(noexcept(views::all(std::forward<_Range>(__range))))
+ -> decltype( views::all(std::forward<_Range>(__range)))
+ { return views::all(std::forward<_Range>(__range)); }
template<class _Range>
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI
constexpr auto operator()(_Range&& __range) const
- noexcept(noexcept(common_view{_VSTD::forward<_Range>(__range)}))
- -> decltype( common_view{_VSTD::forward<_Range>(__range)})
- { return common_view{_VSTD::forward<_Range>(__range)}; }
+ noexcept(noexcept(common_view{std::forward<_Range>(__range)}))
+ -> decltype( common_view{std::forward<_Range>(__range)})
+ { return common_view{std::forward<_Range>(__range)}; }
};
} // namespace __common
@@ -128,7 +128,7 @@ inline namespace __cpo {
} // namespace views
} // namespace ranges
-#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__ranges/concepts.h b/libcxx/include/__ranges/concepts.h
index 0590863138ed..87df1d18baf8 100644
--- a/libcxx/include/__ranges/concepts.h
+++ b/libcxx/include/__ranges/concepts.h
@@ -27,21 +27,26 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17
namespace ranges {
+
// [range.range]
+
template <class _Tp>
concept range = requires(_Tp& __t) {
ranges::begin(__t); // sometimes equality-preserving
ranges::end(__t);
};
+ template <class _Tp>
+ concept input_range = range<_Tp> && input_iterator<iterator_t<_Tp>>;
+
template<class _Range>
concept borrowed_range = range<_Range> &&
(is_lvalue_reference_v<_Range> || enable_borrowed_range<remove_cvref_t<_Range>>);
@@ -94,9 +99,6 @@ namespace ranges {
concept output_range = range<_Rp> && output_iterator<iterator_t<_Rp>, _Tp>;
template <class _Tp>
- concept input_range = range<_Tp> && input_iterator<iterator_t<_Tp>>;
-
- template <class _Tp>
concept forward_range = input_range<_Tp> && forward_iterator<iterator_t<_Tp>>;
template <class _Tp>
@@ -133,7 +135,7 @@ namespace ranges {
} // namespace ranges
-#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__ranges/copyable_box.h b/libcxx/include/__ranges/copyable_box.h
index 608db55dbc5f..6012497db5e8 100644
--- a/libcxx/include/__ranges/copyable_box.h
+++ b/libcxx/include/__ranges/copyable_box.h
@@ -19,12 +19,12 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
// __copyable_box allows turning a type that is copy-constructible (but maybe not copy-assignable) into
// a type that is both copy-constructible and copy-assignable. It does that by introducing an empty state
@@ -41,7 +41,7 @@ namespace ranges {
// Primary template - uses std::optional and introduces an empty state in case assignment fails.
template<__copy_constructible_object _Tp>
class __copyable_box {
- [[no_unique_address]] optional<_Tp> __val_;
+ _LIBCPP_NO_UNIQUE_ADDRESS optional<_Tp> __val_;
public:
template<class ..._Args>
@@ -49,7 +49,7 @@ namespace ranges {
_LIBCPP_HIDE_FROM_ABI
constexpr explicit __copyable_box(in_place_t, _Args&& ...__args)
noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
- : __val_(in_place, _VSTD::forward<_Args>(__args)...)
+ : __val_(in_place, std::forward<_Args>(__args)...)
{ }
_LIBCPP_HIDE_FROM_ABI
@@ -65,7 +65,7 @@ namespace ranges {
constexpr __copyable_box& operator=(__copyable_box const& __other)
noexcept(is_nothrow_copy_constructible_v<_Tp>)
{
- if (this != _VSTD::addressof(__other)) {
+ if (this != std::addressof(__other)) {
if (__other.__has_value()) __val_.emplace(*__other);
else __val_.reset();
}
@@ -79,8 +79,8 @@ namespace ranges {
constexpr __copyable_box& operator=(__copyable_box&& __other)
noexcept(is_nothrow_move_constructible_v<_Tp>)
{
- if (this != _VSTD::addressof(__other)) {
- if (__other.__has_value()) __val_.emplace(_VSTD::move(*__other));
+ if (this != std::addressof(__other)) {
+ if (__other.__has_value()) __val_.emplace(std::move(*__other));
else __val_.reset();
}
return *this;
@@ -116,7 +116,7 @@ namespace ranges {
template<__copy_constructible_object _Tp>
requires __doesnt_need_empty_state_for_copy<_Tp> && __doesnt_need_empty_state_for_move<_Tp>
class __copyable_box<_Tp> {
- [[no_unique_address]] _Tp __val_;
+ _LIBCPP_NO_UNIQUE_ADDRESS _Tp __val_;
public:
template<class ..._Args>
@@ -124,7 +124,7 @@ namespace ranges {
_LIBCPP_HIDE_FROM_ABI
constexpr explicit __copyable_box(in_place_t, _Args&& ...__args)
noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
- : __val_(_VSTD::forward<_Args>(__args)...)
+ : __val_(std::forward<_Args>(__args)...)
{ }
_LIBCPP_HIDE_FROM_ABI
@@ -144,9 +144,9 @@ namespace ranges {
_LIBCPP_HIDE_FROM_ABI
constexpr __copyable_box& operator=(__copyable_box const& __other) noexcept {
static_assert(is_nothrow_copy_constructible_v<_Tp>);
- if (this != _VSTD::addressof(__other)) {
- _VSTD::destroy_at(_VSTD::addressof(__val_));
- _VSTD::construct_at(_VSTD::addressof(__val_), __other.__val_);
+ if (this != std::addressof(__other)) {
+ std::destroy_at(std::addressof(__val_));
+ std::construct_at(std::addressof(__val_), __other.__val_);
}
return *this;
}
@@ -154,9 +154,9 @@ namespace ranges {
_LIBCPP_HIDE_FROM_ABI
constexpr __copyable_box& operator=(__copyable_box&& __other) noexcept {
static_assert(is_nothrow_move_constructible_v<_Tp>);
- if (this != _VSTD::addressof(__other)) {
- _VSTD::destroy_at(_VSTD::addressof(__val_));
- _VSTD::construct_at(_VSTD::addressof(__val_), _VSTD::move(__other.__val_));
+ if (this != std::addressof(__other)) {
+ std::destroy_at(std::addressof(__val_));
+ std::construct_at(std::addressof(__val_), std::move(__other.__val_));
}
return *this;
}
@@ -164,14 +164,14 @@ namespace ranges {
_LIBCPP_HIDE_FROM_ABI constexpr _Tp const& operator*() const noexcept { return __val_; }
_LIBCPP_HIDE_FROM_ABI constexpr _Tp& operator*() noexcept { return __val_; }
- _LIBCPP_HIDE_FROM_ABI constexpr const _Tp *operator->() const noexcept { return _VSTD::addressof(__val_); }
- _LIBCPP_HIDE_FROM_ABI constexpr _Tp *operator->() noexcept { return _VSTD::addressof(__val_); }
+ _LIBCPP_HIDE_FROM_ABI constexpr const _Tp *operator->() const noexcept { return std::addressof(__val_); }
+ _LIBCPP_HIDE_FROM_ABI constexpr _Tp *operator->() noexcept { return std::addressof(__val_); }
_LIBCPP_HIDE_FROM_ABI constexpr bool __has_value() const noexcept { return true; }
};
} // namespace ranges
-#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__ranges/counted.h b/libcxx/include/__ranges/counted.h
index 92bcf06be3ad..f45f1e890085 100644
--- a/libcxx/include/__ranges/counted.h
+++ b/libcxx/include/__ranges/counted.h
@@ -24,12 +24,12 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
namespace ranges::views {
@@ -39,9 +39,9 @@ namespace __counted {
template<contiguous_iterator _It>
_LIBCPP_HIDE_FROM_ABI
static constexpr auto __go(_It __it, iter_difference_t<_It> __count)
- noexcept(noexcept(span(_VSTD::to_address(__it), static_cast<size_t>(__count))))
+ noexcept(noexcept(span(std::to_address(__it), static_cast<size_t>(__count))))
// Deliberately omit return-type SFINAE, because to_address is not SFINAE-friendly
- { return span(_VSTD::to_address(__it), static_cast<size_t>(__count)); }
+ { return span(std::to_address(__it), static_cast<size_t>(__count)); }
template<random_access_iterator _It>
_LIBCPP_HIDE_FROM_ABI
@@ -53,17 +53,17 @@ namespace __counted {
template<class _It>
_LIBCPP_HIDE_FROM_ABI
static constexpr auto __go(_It __it, iter_difference_t<_It> __count)
- noexcept(noexcept(subrange(counted_iterator(_VSTD::move(__it), __count), default_sentinel)))
- -> decltype( subrange(counted_iterator(_VSTD::move(__it), __count), default_sentinel))
- { return subrange(counted_iterator(_VSTD::move(__it), __count), default_sentinel); }
+ noexcept(noexcept(subrange(counted_iterator(std::move(__it), __count), default_sentinel)))
+ -> decltype( subrange(counted_iterator(std::move(__it), __count), default_sentinel))
+ { return subrange(counted_iterator(std::move(__it), __count), default_sentinel); }
template<class _It, convertible_to<iter_difference_t<_It>> _Diff>
requires input_or_output_iterator<decay_t<_It>>
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI
constexpr auto operator()(_It&& __it, _Diff&& __count) const
- noexcept(noexcept(__go(_VSTD::forward<_It>(__it), _VSTD::forward<_Diff>(__count))))
- -> decltype( __go(_VSTD::forward<_It>(__it), _VSTD::forward<_Diff>(__count)))
- { return __go(_VSTD::forward<_It>(__it), _VSTD::forward<_Diff>(__count)); }
+ noexcept(noexcept(__go(std::forward<_It>(__it), std::forward<_Diff>(__count))))
+ -> decltype( __go(std::forward<_It>(__it), std::forward<_Diff>(__count)))
+ { return __go(std::forward<_It>(__it), std::forward<_Diff>(__count)); }
};
} // namespace __counted
@@ -74,7 +74,7 @@ inline namespace __cpo {
} // namespace ranges::views
-#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__ranges/dangling.h b/libcxx/include/__ranges/dangling.h
index b6b733a6eaa9..525b5ff0aabe 100644
--- a/libcxx/include/__ranges/dangling.h
+++ b/libcxx/include/__ranges/dangling.h
@@ -16,12 +16,12 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17
namespace ranges {
struct dangling {
@@ -35,7 +35,7 @@ using borrowed_iterator_t = _If<borrowed_range<_Rp>, iterator_t<_Rp>, dangling>;
// borrowed_subrange_t defined in <__ranges/subrange.h>
} // namespace ranges
-#endif // !_LIBCPP_HAS_NO_CONCEPTS
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__ranges/data.h b/libcxx/include/__ranges/data.h
index f97ec8033297..35d1af1e648f 100644
--- a/libcxx/include/__ranges/data.h
+++ b/libcxx/include/__ranges/data.h
@@ -19,12 +19,12 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17
// [range.prim.data]
@@ -60,8 +60,8 @@ namespace __data {
template<__ranges_begin_invocable _Tp>
_LIBCPP_HIDE_FROM_ABI
constexpr auto operator()(_Tp&& __t) const
- noexcept(noexcept(_VSTD::to_address(ranges::begin(__t)))) {
- return _VSTD::to_address(ranges::begin(__t));
+ noexcept(noexcept(std::to_address(ranges::begin(__t)))) {
+ return std::to_address(ranges::begin(__t));
}
};
} // namespace __data
@@ -99,7 +99,7 @@ inline namespace __cpo {
} // namespace __cpo
} // namespace ranges
-#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__ranges/drop_view.h b/libcxx/include/__ranges/drop_view.h
index 1e2bfa40b325..b2a8ee581475 100644
--- a/libcxx/include/__ranges/drop_view.h
+++ b/libcxx/include/__ranges/drop_view.h
@@ -9,29 +9,43 @@
#ifndef _LIBCPP___RANGES_DROP_VIEW_H
#define _LIBCPP___RANGES_DROP_VIEW_H
+#include <__algorithm/min.h>
+#include <__assert>
#include <__config>
-#include <__debug>
+#include <__functional/bind_back.h>
+#include <__fwd/span.h>
+#include <__fwd/string_view.h>
#include <__iterator/concepts.h>
+#include <__iterator/distance.h>
#include <__iterator/iterator_traits.h>
#include <__iterator/next.h>
#include <__ranges/access.h>
#include <__ranges/all.h>
#include <__ranges/concepts.h>
+#include <__ranges/empty_view.h>
#include <__ranges/enable_borrowed_range.h>
+#include <__ranges/iota_view.h>
#include <__ranges/non_propagating_cache.h>
+#include <__ranges/range_adaptor.h>
#include <__ranges/size.h>
+#include <__ranges/subrange.h>
#include <__ranges/view_interface.h>
+#include <__utility/auto_cast.h>
+#include <__utility/forward.h>
#include <__utility/move.h>
#include <concepts>
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
_LIBCPP_BEGIN_NAMESPACE_STD
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
namespace ranges {
template<view _View>
@@ -45,7 +59,7 @@ namespace ranges {
// one can't call begin() on it more than once.
static constexpr bool _UseCache = forward_range<_View> && !(random_access_range<_View> && sized_range<_View>);
using _Cache = _If<_UseCache, __non_propagating_cache<iterator_t<_View>>, __empty_cache>;
- [[no_unique_address]] _Cache __cached_begin_ = _Cache();
+ _LIBCPP_NO_UNIQUE_ADDRESS _Cache __cached_begin_ = _Cache();
range_difference_t<_View> __count_ = 0;
_View __base_ = _View();
@@ -55,13 +69,13 @@ public:
_LIBCPP_HIDE_FROM_ABI
constexpr drop_view(_View __base, range_difference_t<_View> __count)
: __count_(__count)
- , __base_(_VSTD::move(__base))
+ , __base_(std::move(__base))
{
_LIBCPP_ASSERT(__count_ >= 0, "count must be greater than or equal to zero.");
}
_LIBCPP_HIDE_FROM_ABI constexpr _View base() const& requires copy_constructible<_View> { return __base_; }
- _LIBCPP_HIDE_FROM_ABI constexpr _View base() && { return _VSTD::move(__base_); }
+ _LIBCPP_HIDE_FROM_ABI constexpr _View base() && { return std::move(__base_); }
_LIBCPP_HIDE_FROM_ABI
constexpr auto begin()
@@ -113,15 +127,180 @@ public:
{ return __size(*this); }
};
- template<class _Range>
- drop_view(_Range&&, range_difference_t<_Range>) -> drop_view<views::all_t<_Range>>;
+template<class _Range>
+drop_view(_Range&&, range_difference_t<_Range>) -> drop_view<views::all_t<_Range>>;
+
+template<class _Tp>
+inline constexpr bool enable_borrowed_range<drop_view<_Tp>> = enable_borrowed_range<_Tp>;
+
+namespace views {
+namespace __drop {
+
+template <class _Tp>
+inline constexpr bool __is_empty_view = false;
+
+template <class _Tp>
+inline constexpr bool __is_empty_view<empty_view<_Tp>> = true;
+
+template <class _Tp>
+inline constexpr bool __is_passthrough_specialization = false;
+
+template <class _Tp, size_t _Extent>
+inline constexpr bool __is_passthrough_specialization<span<_Tp, _Extent>> = true;
+
+template <class _CharT, class _Traits>
+inline constexpr bool __is_passthrough_specialization<basic_string_view<_CharT, _Traits>> = true;
+
+template <class _Np, class _Bound>
+inline constexpr bool __is_passthrough_specialization<iota_view<_Np, _Bound>> = true;
+
+template <class _Iter, class _Sent, subrange_kind _Kind>
+inline constexpr bool __is_passthrough_specialization<subrange<_Iter, _Sent, _Kind>> =
+ !subrange<_Iter, _Sent, _Kind>::_StoreSize;
+
+template <class _Tp>
+inline constexpr bool __is_subrange_specialization_with_store_size = false;
+
+template <class _Iter, class _Sent, subrange_kind _Kind>
+inline constexpr bool __is_subrange_specialization_with_store_size<subrange<_Iter, _Sent, _Kind>> =
+ subrange<_Iter, _Sent, _Kind>::_StoreSize;
+
+template <class _Tp>
+struct __passthrough_type;
+
+template <class _Tp, size_t _Extent>
+struct __passthrough_type<span<_Tp, _Extent>> {
+ using type = span<_Tp>;
+};
+
+template <class _CharT, class _Traits>
+struct __passthrough_type<basic_string_view<_CharT, _Traits>> {
+ using type = basic_string_view<_CharT, _Traits>;
+};
+
+template <class _Np, class _Bound>
+struct __passthrough_type<iota_view<_Np, _Bound>> {
+ using type = iota_view<_Np, _Bound>;
+};
+
+template <class _Iter, class _Sent, subrange_kind _Kind>
+struct __passthrough_type<subrange<_Iter, _Sent, _Kind>> {
+ using type = subrange<_Iter, _Sent, _Kind>;
+};
+
+template <class _Tp>
+using __passthrough_type_t = typename __passthrough_type<_Tp>::type;
+
+struct __fn {
+ // [range.drop.overview]: the `empty_view` case.
+ template <class _Range, convertible_to<range_difference_t<_Range>> _Np>
+ requires __is_empty_view<remove_cvref_t<_Range>>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI
+ constexpr auto operator()(_Range&& __range, _Np&&) const
+ noexcept(noexcept(_LIBCPP_AUTO_CAST(std::forward<_Range>(__range))))
+ -> decltype( _LIBCPP_AUTO_CAST(std::forward<_Range>(__range)))
+ { return _LIBCPP_AUTO_CAST(std::forward<_Range>(__range)); }
+
+ // [range.drop.overview]: the `span | basic_string_view | iota_view | subrange (StoreSize == false)` case.
+ template <class _Range,
+ convertible_to<range_difference_t<_Range>> _Np,
+ class _RawRange = remove_cvref_t<_Range>,
+ class _Dist = range_difference_t<_Range>>
+ requires (!__is_empty_view<_RawRange> &&
+ random_access_range<_RawRange> &&
+ sized_range<_RawRange> &&
+ __is_passthrough_specialization<_RawRange>)
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI
+ constexpr auto operator()(_Range&& __rng, _Np&& __n) const
+ noexcept(noexcept(__passthrough_type_t<_RawRange>(
+ ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n)),
+ ranges::end(__rng)
+ )))
+ -> decltype( __passthrough_type_t<_RawRange>(
+ // Note: deliberately not forwarding `__rng` to guard against double moves.
+ ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n)),
+ ranges::end(__rng)
+ ))
+ { return __passthrough_type_t<_RawRange>(
+ ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n)),
+ ranges::end(__rng)
+ ); }
+
+ // [range.drop.overview]: the `subrange (StoreSize == true)` case.
+ template <class _Range,
+ convertible_to<range_difference_t<_Range>> _Np,
+ class _RawRange = remove_cvref_t<_Range>,
+ class _Dist = range_difference_t<_Range>>
+ requires (!__is_empty_view<_RawRange> &&
+ random_access_range<_RawRange> &&
+ sized_range<_RawRange> &&
+ __is_subrange_specialization_with_store_size<_RawRange>)
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI
+ constexpr auto operator()(_Range&& __rng, _Np&& __n) const
+ noexcept(noexcept(_RawRange(
+ ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n)),
+ ranges::end(__rng),
+ std::__to_unsigned_like(ranges::distance(__rng) -
+ std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n)))
+ )))
+ -> decltype( _RawRange(
+ // Note: deliberately not forwarding `__rng` to guard against double moves.
+ ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n)),
+ ranges::end(__rng),
+ std::__to_unsigned_like(ranges::distance(__rng) -
+ std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n)))
+ ))
+ {
+ // Introducing local variables avoids calculating `min` and `distance` twice (at the cost of diverging from the
+ // expression used in the `noexcept` clause and the return statement).
+ auto dist = ranges::distance(__rng);
+ auto clamped = std::min<_Dist>(dist, std::forward<_Np>(__n));
+ return _RawRange(
+ ranges::begin(__rng) + clamped,
+ ranges::end(__rng),
+ std::__to_unsigned_like(dist - clamped)
+ );}
+
+ // [range.drop.overview]: the "otherwise" case.
+ template <class _Range, convertible_to<range_difference_t<_Range>> _Np,
+ class _RawRange = remove_cvref_t<_Range>>
+ // Note: without specifically excluding the other cases, GCC sees this overload as ambiguous with the other
+ // overloads.
+ requires (!(__is_empty_view<_RawRange> ||
+ (__is_subrange_specialization_with_store_size<_RawRange> &&
+ sized_range<_RawRange> &&
+ random_access_range<_RawRange>) ||
+ (__is_passthrough_specialization<_RawRange> &&
+ sized_range<_RawRange> &&
+ random_access_range<_RawRange>)
+ ))
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI
+ constexpr auto operator()(_Range&& __range, _Np&& __n) const
+ noexcept(noexcept(drop_view(std::forward<_Range>(__range), std::forward<_Np>(__n))))
+ -> decltype( drop_view(std::forward<_Range>(__range), std::forward<_Np>(__n)))
+ { return drop_view(std::forward<_Range>(__range), std::forward<_Np>(__n)); }
+
+ template <class _Np>
+ requires constructible_from<decay_t<_Np>, _Np>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI
+ constexpr auto operator()(_Np&& __n) const
+ noexcept(is_nothrow_constructible_v<decay_t<_Np>, _Np>)
+ { return __range_adaptor_closure_t(std::__bind_back(*this, std::forward<_Np>(__n))); }
+};
+
+} // namespace __drop
+
+inline namespace __cpo {
+ inline constexpr auto drop = __drop::__fn{};
+} // namespace __cpo
+} // namespace views
- template<class _Tp>
- inline constexpr bool enable_borrowed_range<drop_view<_Tp>> = enable_borrowed_range<_Tp>;
} // namespace ranges
-#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
_LIBCPP_END_NAMESPACE_STD
+_LIBCPP_POP_MACROS
+
#endif // _LIBCPP___RANGES_DROP_VIEW_H
diff --git a/libcxx/include/__ranges/empty.h b/libcxx/include/__ranges/empty.h
index b06a81c98e8f..46c97ca7e329 100644
--- a/libcxx/include/__ranges/empty.h
+++ b/libcxx/include/__ranges/empty.h
@@ -17,12 +17,12 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
// [range.prim.empty]
@@ -75,7 +75,7 @@ inline namespace __cpo {
} // namespace __cpo
} // namespace ranges
-#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__ranges/empty_view.h b/libcxx/include/__ranges/empty_view.h
index e0116b933797..3299fe825ddf 100644
--- a/libcxx/include/__ranges/empty_view.h
+++ b/libcxx/include/__ranges/empty_view.h
@@ -15,12 +15,12 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
namespace ranges {
template<class _Tp>
@@ -36,9 +36,16 @@ namespace ranges {
template<class _Tp>
inline constexpr bool enable_borrowed_range<empty_view<_Tp>> = true;
+
+ namespace views {
+
+ template <class _Tp>
+ inline constexpr empty_view<_Tp> empty{};
+
+ } // namespace views
} // namespace ranges
-#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__ranges/enable_borrowed_range.h b/libcxx/include/__ranges/enable_borrowed_range.h
index 5f5b3f505773..833d266403ca 100644
--- a/libcxx/include/__ranges/enable_borrowed_range.h
+++ b/libcxx/include/__ranges/enable_borrowed_range.h
@@ -17,15 +17,14 @@
#include <__config>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17
-namespace ranges
-{
+namespace ranges {
// [range.range], ranges
@@ -34,7 +33,7 @@ inline constexpr bool enable_borrowed_range = false;
} // namespace ranges
-#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__ranges/enable_view.h b/libcxx/include/__ranges/enable_view.h
index 87d53f3fcc8c..a1e5721404cd 100644
--- a/libcxx/include/__ranges/enable_view.h
+++ b/libcxx/include/__ranges/enable_view.h
@@ -15,12 +15,12 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17
namespace ranges {
@@ -40,7 +40,7 @@ inline constexpr bool enable_view = derived_from<_Tp, view_base> ||
} // namespace ranges
-#endif // !_LIBCPP_HAS_NO_CONCEPTS
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__ranges/filter_view.h b/libcxx/include/__ranges/filter_view.h
new file mode 100644
index 000000000000..b040ea57b779
--- /dev/null
+++ b/libcxx/include/__ranges/filter_view.h
@@ -0,0 +1,259 @@
+// -*- 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___RANGES_FILTER_VIEW_H
+#define _LIBCPP___RANGES_FILTER_VIEW_H
+
+#include <__algorithm/ranges_find_if.h>
+#include <__config>
+#include <__debug>
+#include <__functional/bind_back.h>
+#include <__functional/invoke.h>
+#include <__functional/reference_wrapper.h>
+#include <__iterator/concepts.h>
+#include <__iterator/iter_move.h>
+#include <__iterator/iter_swap.h>
+#include <__iterator/iterator_traits.h>
+#include <__memory/addressof.h>
+#include <__ranges/access.h>
+#include <__ranges/all.h>
+#include <__ranges/concepts.h>
+#include <__ranges/copyable_box.h>
+#include <__ranges/non_propagating_cache.h>
+#include <__ranges/range_adaptor.h>
+#include <__ranges/view_interface.h>
+#include <__utility/forward.h>
+#include <__utility/in_place.h>
+#include <__utility/move.h>
+#include <concepts>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+namespace ranges {
+ template<input_range _View, indirect_unary_predicate<iterator_t<_View>> _Pred>
+ requires view<_View> && is_object_v<_Pred>
+ class filter_view : public view_interface<filter_view<_View, _Pred>> {
+ _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View();
+ _LIBCPP_NO_UNIQUE_ADDRESS __copyable_box<_Pred> __pred_;
+
+ // We cache the result of begin() to allow providing an amortized O(1) begin() whenever
+ // the underlying range is at least a forward_range.
+ static constexpr bool _UseCache = forward_range<_View>;
+ using _Cache = _If<_UseCache, __non_propagating_cache<iterator_t<_View>>, __empty_cache>;
+ _LIBCPP_NO_UNIQUE_ADDRESS _Cache __cached_begin_ = _Cache();
+
+ class __iterator;
+ class __sentinel;
+
+ public:
+ _LIBCPP_HIDE_FROM_ABI
+ filter_view() requires default_initializable<_View> && default_initializable<_Pred> = default;
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr filter_view(_View __base, _Pred __pred)
+ : __base_(std::move(__base)), __pred_(in_place, std::move(__pred))
+ { }
+
+ template<class _Vp = _View>
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr _View base() const& requires copy_constructible<_Vp> { return __base_; }
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr _View base() && { return std::move(__base_); }
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr _Pred const& pred() const { return *__pred_; }
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr __iterator begin() {
+ _LIBCPP_ASSERT(__pred_.__has_value(), "Trying to call begin() on a filter_view that does not have a valid predicate.");
+ if constexpr (_UseCache) {
+ if (!__cached_begin_.__has_value()) {
+ __cached_begin_.__emplace(ranges::find_if(__base_, std::ref(*__pred_)));
+ }
+ return {*this, *__cached_begin_};
+ } else {
+ return {*this, ranges::find_if(__base_, std::ref(*__pred_))};
+ }
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr auto end() {
+ if constexpr (common_range<_View>)
+ return __iterator{*this, ranges::end(__base_)};
+ else
+ return __sentinel{*this};
+ }
+ };
+
+ template<class _Range, class _Pred>
+ filter_view(_Range&&, _Pred) -> filter_view<views::all_t<_Range>, _Pred>;
+
+ template<class _View>
+ struct __filter_iterator_category { };
+
+ template<forward_range _View>
+ struct __filter_iterator_category<_View> {
+ using _Cat = typename iterator_traits<iterator_t<_View>>::iterator_category;
+ using iterator_category =
+ _If<derived_from<_Cat, bidirectional_iterator_tag>, bidirectional_iterator_tag,
+ _If<derived_from<_Cat, forward_iterator_tag>, forward_iterator_tag,
+ /* else */ _Cat
+ >>;
+ };
+
+ template<input_range _View, indirect_unary_predicate<iterator_t<_View>> _Pred>
+ requires view<_View> && is_object_v<_Pred>
+ class filter_view<_View, _Pred>::__iterator : public __filter_iterator_category<_View> {
+ public:
+ _LIBCPP_NO_UNIQUE_ADDRESS iterator_t<_View> __current_ = iterator_t<_View>();
+ _LIBCPP_NO_UNIQUE_ADDRESS filter_view* __parent_ = nullptr;
+
+ using iterator_concept =
+ _If<bidirectional_range<_View>, bidirectional_iterator_tag,
+ _If<forward_range<_View>, forward_iterator_tag,
+ /* else */ input_iterator_tag
+ >>;
+ // using iterator_category = inherited;
+ using value_type = range_value_t<_View>;
+ using difference_type = range_difference_t<_View>;
+
+ _LIBCPP_HIDE_FROM_ABI
+ __iterator() requires default_initializable<iterator_t<_View>> = default;
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr __iterator(filter_view& __parent, iterator_t<_View> __current)
+ : __current_(std::move(__current)), __parent_(std::addressof(__parent))
+ { }
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr iterator_t<_View> const& base() const& noexcept { return __current_; }
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr iterator_t<_View> base() && { return std::move(__current_); }
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr range_reference_t<_View> operator*() const { return *__current_; }
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr iterator_t<_View> operator->() const
+ requires __has_arrow<iterator_t<_View>> && copyable<iterator_t<_View>>
+ {
+ return __current_;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr __iterator& operator++() {
+ __current_ = ranges::find_if(std::move(++__current_), ranges::end(__parent_->__base_),
+ std::ref(*__parent_->__pred_));
+ return *this;
+ }
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr void operator++(int) { ++*this; }
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr __iterator operator++(int) requires forward_range<_View> {
+ auto __tmp = *this;
+ ++*this;
+ return __tmp;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr __iterator& operator--() requires bidirectional_range<_View> {
+ do {
+ --__current_;
+ } while (!std::invoke(*__parent_->__pred_, *__current_));
+ return *this;
+ }
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr __iterator operator--(int) requires bidirectional_range<_View> {
+ auto tmp = *this;
+ --*this;
+ return tmp;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ friend constexpr bool operator==(__iterator const& __x, __iterator const& __y)
+ requires equality_comparable<iterator_t<_View>>
+ {
+ return __x.__current_ == __y.__current_;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ friend constexpr range_rvalue_reference_t<_View> iter_move(__iterator const& __it)
+ noexcept(noexcept(ranges::iter_move(__it.__current_)))
+ {
+ return ranges::iter_move(__it.__current_);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ friend constexpr void iter_swap(__iterator const& __x, __iterator const& __y)
+ noexcept(noexcept(ranges::iter_swap(__x.__current_, __y.__current_)))
+ requires indirectly_swappable<iterator_t<_View>>
+ {
+ return ranges::iter_swap(__x.__current_, __y.__current_);
+ }
+ };
+
+ template<input_range _View, indirect_unary_predicate<iterator_t<_View>> _Pred>
+ requires view<_View> && is_object_v<_Pred>
+ class filter_view<_View, _Pred>::__sentinel {
+ public:
+ sentinel_t<_View> __end_ = sentinel_t<_View>();
+
+ _LIBCPP_HIDE_FROM_ABI
+ __sentinel() = default;
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr explicit __sentinel(filter_view& __parent)
+ : __end_(ranges::end(__parent.__base_))
+ { }
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr sentinel_t<_View> base() const { return __end_; }
+
+ _LIBCPP_HIDE_FROM_ABI
+ friend constexpr bool operator==(__iterator const& __x, __sentinel const& __y) {
+ return __x.__current_ == __y.__end_;
+ }
+ };
+
+namespace views {
+namespace __filter {
+ struct __fn {
+ template<class _Range, class _Pred>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI
+ constexpr auto operator()(_Range&& __range, _Pred&& __pred) const
+ noexcept(noexcept(filter_view(std::forward<_Range>(__range), std::forward<_Pred>(__pred))))
+ -> decltype( filter_view(std::forward<_Range>(__range), std::forward<_Pred>(__pred)))
+ { return filter_view(std::forward<_Range>(__range), std::forward<_Pred>(__pred)); }
+
+ template<class _Pred>
+ requires constructible_from<decay_t<_Pred>, _Pred>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI
+ constexpr auto operator()(_Pred&& __pred) const
+ noexcept(is_nothrow_constructible_v<decay_t<_Pred>, _Pred>)
+ { return __range_adaptor_closure_t(std::__bind_back(*this, std::forward<_Pred>(__pred))); }
+ };
+} // namespace __filter
+
+inline namespace __cpo {
+ inline constexpr auto filter = __filter::__fn{};
+} // namespace __cpo
+} // namespace views
+
+} // namespace ranges
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___RANGES_FILTER_VIEW_H
diff --git a/libcxx/include/__ranges/iota_view.h b/libcxx/include/__ranges/iota_view.h
index 17f6021f7dd4..e1f03bafa03a 100644
--- a/libcxx/include/__ranges/iota_view.h
+++ b/libcxx/include/__ranges/iota_view.h
@@ -9,6 +9,7 @@
#ifndef _LIBCPP___RANGES_IOTA_VIEW_H
#define _LIBCPP___RANGES_IOTA_VIEW_H
+#include <__assert>
#include <__compare/three_way_comparable.h>
#include <__concepts/arithmetic.h>
#include <__concepts/constructible.h>
@@ -20,7 +21,6 @@
#include <__concepts/semiregular.h>
#include <__concepts/totally_ordered.h>
#include <__config>
-#include <__debug>
#include <__functional/ranges_operations.h>
#include <__iterator/concepts.h>
#include <__iterator/incrementable_traits.h>
@@ -34,12 +34,12 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
namespace ranges {
template<class _Int>
@@ -90,9 +90,9 @@ namespace ranges {
using iterator_category = input_iterator_tag;
};
- template<weakly_incrementable _Start, semiregular _Bound = unreachable_sentinel_t>
- requires __weakly_equality_comparable_with<_Start, _Bound> && copyable<_Start>
- class iota_view : public view_interface<iota_view<_Start, _Bound>> {
+ template <weakly_incrementable _Start, semiregular _BoundSentinel = unreachable_sentinel_t>
+ requires __weakly_equality_comparable_with<_Start, _BoundSentinel> && copyable<_Start>
+ class iota_view : public view_interface<iota_view<_Start, _BoundSentinel>> {
struct __iterator : public __iota_iterator_category<_Start> {
friend class iota_view;
@@ -111,7 +111,7 @@ namespace ranges {
__iterator() requires default_initializable<_Start> = default;
_LIBCPP_HIDE_FROM_ABI
- constexpr explicit __iterator(_Start __value) : __value_(_VSTD::move(__value)) {}
+ constexpr explicit __iterator(_Start __value) : __value_(std::move(__value)) {}
_LIBCPP_HIDE_FROM_ABI
constexpr _Start operator*() const noexcept(is_nothrow_copy_constructible_v<_Start>) {
@@ -271,127 +271,127 @@ namespace ranges {
friend class iota_view;
private:
- _Bound __bound_ = _Bound();
+ _BoundSentinel __bound_sentinel_ = _BoundSentinel();
public:
_LIBCPP_HIDE_FROM_ABI
__sentinel() = default;
- constexpr explicit __sentinel(_Bound __bound) : __bound_(_VSTD::move(__bound)) {}
+ constexpr explicit __sentinel(_BoundSentinel __bound_sentinel) : __bound_sentinel_(std::move(__bound_sentinel)) {}
_LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator==(const __iterator& __x, const __sentinel& __y) {
- return __x.__value_ == __y.__bound_;
+ return __x.__value_ == __y.__bound_sentinel_;
}
_LIBCPP_HIDE_FROM_ABI
friend constexpr iter_difference_t<_Start> operator-(const __iterator& __x, const __sentinel& __y)
- requires sized_sentinel_for<_Bound, _Start>
+ requires sized_sentinel_for<_BoundSentinel, _Start>
{
- return __x.__value_ - __y.__bound_;
+ return __x.__value_ - __y.__bound_sentinel_;
}
_LIBCPP_HIDE_FROM_ABI
friend constexpr iter_difference_t<_Start> operator-(const __sentinel& __x, const __iterator& __y)
- requires sized_sentinel_for<_Bound, _Start>
+ requires sized_sentinel_for<_BoundSentinel, _Start>
{
return -(__y - __x);
}
};
_Start __value_ = _Start();
- _Bound __bound_ = _Bound();
+ _BoundSentinel __bound_sentinel_ = _BoundSentinel();
public:
_LIBCPP_HIDE_FROM_ABI
iota_view() requires default_initializable<_Start> = default;
_LIBCPP_HIDE_FROM_ABI
- constexpr explicit iota_view(_Start __value) : __value_(_VSTD::move(__value)) { }
+ constexpr explicit iota_view(_Start __value) : __value_(std::move(__value)) { }
_LIBCPP_HIDE_FROM_ABI
- constexpr iota_view(type_identity_t<_Start> __value, type_identity_t<_Bound> __bound)
- : __value_(_VSTD::move(__value)), __bound_(_VSTD::move(__bound)) {
+ constexpr iota_view(type_identity_t<_Start> __value, type_identity_t<_BoundSentinel> __bound_sentinel)
+ : __value_(std::move(__value)), __bound_sentinel_(std::move(__bound_sentinel)) {
// Validate the precondition if possible.
- if constexpr (totally_ordered_with<_Start, _Bound>) {
- _LIBCPP_ASSERT(ranges::less_equal()(__value_, __bound_),
+ if constexpr (totally_ordered_with<_Start, _BoundSentinel>) {
+ _LIBCPP_ASSERT(ranges::less_equal()(__value_, __bound_sentinel_),
"Precondition violated: value is greater than bound.");
}
}
_LIBCPP_HIDE_FROM_ABI
constexpr iota_view(__iterator __first, __iterator __last)
- requires same_as<_Start, _Bound>
- : iota_view(_VSTD::move(__first.__value_), _VSTD::move(__last.__value_)) {}
+ requires same_as<_Start, _BoundSentinel>
+ : iota_view(std::move(__first.__value_), std::move(__last.__value_)) {}
_LIBCPP_HIDE_FROM_ABI
- constexpr iota_view(__iterator __first, _Bound __last)
- requires same_as<_Bound, unreachable_sentinel_t>
- : iota_view(_VSTD::move(__first.__value_), _VSTD::move(__last)) {}
+ constexpr iota_view(__iterator __first, _BoundSentinel __last)
+ requires same_as<_BoundSentinel, unreachable_sentinel_t>
+ : iota_view(std::move(__first.__value_), std::move(__last)) {}
_LIBCPP_HIDE_FROM_ABI
constexpr iota_view(__iterator __first, __sentinel __last)
- requires (!same_as<_Start, _Bound> && !same_as<_Start, unreachable_sentinel_t>)
- : iota_view(_VSTD::move(__first.__value_), _VSTD::move(__last.__bound_)) {}
+ requires(!same_as<_Start, _BoundSentinel> && !same_as<_Start, unreachable_sentinel_t>)
+ : iota_view(std::move(__first.__value_), std::move(__last.__bound_sentinel_)) {}
_LIBCPP_HIDE_FROM_ABI
constexpr __iterator begin() const { return __iterator{__value_}; }
_LIBCPP_HIDE_FROM_ABI
constexpr auto end() const {
- if constexpr (same_as<_Bound, unreachable_sentinel_t>)
+ if constexpr (same_as<_BoundSentinel, unreachable_sentinel_t>)
return unreachable_sentinel;
else
- return __sentinel{__bound_};
+ return __sentinel{__bound_sentinel_};
}
_LIBCPP_HIDE_FROM_ABI
- constexpr __iterator end() const requires same_as<_Start, _Bound> {
- return __iterator{__bound_};
+ constexpr __iterator end() const
+ requires same_as<_Start, _BoundSentinel>
+ {
+ return __iterator{__bound_sentinel_};
}
_LIBCPP_HIDE_FROM_ABI
constexpr auto size() const
- requires (same_as<_Start, _Bound> && __advanceable<_Start>) ||
- (integral<_Start> && integral<_Bound>) ||
- sized_sentinel_for<_Bound, _Start>
+ requires(same_as<_Start, _BoundSentinel> && __advanceable<_Start>) ||
+ (integral<_Start> && integral<_BoundSentinel>) || sized_sentinel_for<_BoundSentinel, _Start>
{
- if constexpr (__integer_like<_Start> && __integer_like<_Bound>) {
+ if constexpr (__integer_like<_Start> && __integer_like<_BoundSentinel>) {
if (__value_ < 0) {
- if (__bound_ < 0) {
- return _VSTD::__to_unsigned_like(-__value_) - _VSTD::__to_unsigned_like(-__bound_);
+ if (__bound_sentinel_ < 0) {
+ return std::__to_unsigned_like(-__value_) - std::__to_unsigned_like(-__bound_sentinel_);
}
- return _VSTD::__to_unsigned_like(__bound_) + _VSTD::__to_unsigned_like(-__value_);
+ return std::__to_unsigned_like(__bound_sentinel_) + std::__to_unsigned_like(-__value_);
}
- return _VSTD::__to_unsigned_like(__bound_) - _VSTD::__to_unsigned_like(__value_);
+ return std::__to_unsigned_like(__bound_sentinel_) - std::__to_unsigned_like(__value_);
}
- return _VSTD::__to_unsigned_like(__bound_ - __value_);
+ return std::__to_unsigned_like(__bound_sentinel_ - __value_);
}
};
- template<class _Start, class _Bound>
- requires (!__integer_like<_Start> || !__integer_like<_Bound> ||
- (__signed_integer_like<_Start> == __signed_integer_like<_Bound>))
- iota_view(_Start, _Bound) -> iota_view<_Start, _Bound>;
+ template <class _Start, class _BoundSentinel>
+ requires(!__integer_like<_Start> || !__integer_like<_BoundSentinel> ||
+ (__signed_integer_like<_Start> == __signed_integer_like<_BoundSentinel>))
+ iota_view(_Start, _BoundSentinel) -> iota_view<_Start, _BoundSentinel>;
- template<class _Start, class _Bound>
- inline constexpr bool enable_borrowed_range<iota_view<_Start, _Bound>> = true;
+ template <class _Start, class _BoundSentinel>
+ inline constexpr bool enable_borrowed_range<iota_view<_Start, _BoundSentinel>> = true;
-namespace views {
-namespace __iota {
+ namespace views {
+ namespace __iota {
struct __fn {
template<class _Start>
_LIBCPP_HIDE_FROM_ABI
constexpr auto operator()(_Start&& __start) const
- noexcept(noexcept(ranges::iota_view(_VSTD::forward<_Start>(__start))))
- -> decltype( ranges::iota_view(_VSTD::forward<_Start>(__start)))
- { return ranges::iota_view(_VSTD::forward<_Start>(__start)); }
-
- template<class _Start, class _Bound>
- _LIBCPP_HIDE_FROM_ABI
- constexpr auto operator()(_Start&& __start, _Bound&& __bound) const
- noexcept(noexcept(ranges::iota_view(_VSTD::forward<_Start>(__start), _VSTD::forward<_Bound>(__bound))))
- -> decltype( ranges::iota_view(_VSTD::forward<_Start>(__start), _VSTD::forward<_Bound>(__bound)))
- { return ranges::iota_view(_VSTD::forward<_Start>(__start), _VSTD::forward<_Bound>(__bound)); }
+ noexcept(noexcept(ranges::iota_view(std::forward<_Start>(__start))))
+ -> decltype( ranges::iota_view(std::forward<_Start>(__start)))
+ { return ranges::iota_view(std::forward<_Start>(__start)); }
+
+ template <class _Start, class _BoundSentinel>
+ _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Start&& __start, _BoundSentinel&& __bound_sentinel) const
+ noexcept(noexcept(ranges::iota_view(std::forward<_Start>(__start), std::forward<_BoundSentinel>(__bound_sentinel))))
+ -> decltype( ranges::iota_view(std::forward<_Start>(__start), std::forward<_BoundSentinel>(__bound_sentinel)))
+ { return ranges::iota_view(std::forward<_Start>(__start), std::forward<_BoundSentinel>(__bound_sentinel)); }
};
} // namespace __iota
@@ -401,7 +401,7 @@ inline namespace __cpo {
} // namespace views
} // namespace ranges
-#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__ranges/join_view.h b/libcxx/include/__ranges/join_view.h
index 7efbcfdf8788..b6fcce95aeda 100644
--- a/libcxx/include/__ranges/join_view.h
+++ b/libcxx/include/__ranges/join_view.h
@@ -9,28 +9,33 @@
#ifndef _LIBCPP___RANGES_JOIN_VIEW_H
#define _LIBCPP___RANGES_JOIN_VIEW_H
+#include <__concepts/constructible.h>
+#include <__concepts/convertible_to.h>
+#include <__concepts/copyable.h>
+#include <__concepts/derived_from.h>
+#include <__concepts/equality_comparable.h>
#include <__config>
#include <__iterator/concepts.h>
+#include <__iterator/iter_move.h>
+#include <__iterator/iter_swap.h>
#include <__iterator/iterator_traits.h>
#include <__ranges/access.h>
#include <__ranges/all.h>
#include <__ranges/concepts.h>
#include <__ranges/non_propagating_cache.h>
-#include <__ranges/ref_view.h>
-#include <__ranges/subrange.h>
+#include <__ranges/range_adaptor.h>
#include <__ranges/view_interface.h>
-#include <__utility/declval.h>
#include <__utility/forward.h>
#include <optional>
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
namespace ranges {
template<class>
@@ -45,7 +50,8 @@ namespace ranges {
using _InnerC = typename iterator_traits<iterator_t<range_reference_t<_View>>>::iterator_category;
using iterator_category = _If<
- derived_from<_OuterC, bidirectional_iterator_tag> && derived_from<_InnerC, bidirectional_iterator_tag>,
+ derived_from<_OuterC, bidirectional_iterator_tag> && derived_from<_InnerC, bidirectional_iterator_tag> &&
+ common_range<range_reference_t<_View>>,
bidirectional_iterator_tag,
_If<
derived_from<_OuterC, forward_iterator_tag> && derived_from<_InnerC, forward_iterator_tag>,
@@ -67,8 +73,8 @@ namespace ranges {
static constexpr bool _UseCache = !is_reference_v<_InnerRange>;
using _Cache = _If<_UseCache, __non_propagating_cache<remove_cvref_t<_InnerRange>>, __empty_cache>;
- [[no_unique_address]] _Cache __cache_;
- _View __base_ = _View(); // TODO: [[no_unique_address]] makes clang crash! File a bug :)
+ _LIBCPP_NO_UNIQUE_ADDRESS _Cache __cache_;
+ _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View();
public:
_LIBCPP_HIDE_FROM_ABI
@@ -76,13 +82,13 @@ namespace ranges {
_LIBCPP_HIDE_FROM_ABI
constexpr explicit join_view(_View __base)
- : __base_(_VSTD::move(__base)) {}
+ : __base_(std::move(__base)) {}
_LIBCPP_HIDE_FROM_ABI
constexpr _View base() const& requires copy_constructible<_View> { return __base_; }
_LIBCPP_HIDE_FROM_ABI
- constexpr _View base() && { return _VSTD::move(__base_); }
+ constexpr _View base() && { return std::move(__base_); }
_LIBCPP_HIDE_FROM_ABI
constexpr auto begin() {
@@ -152,7 +158,7 @@ namespace ranges {
_LIBCPP_HIDE_FROM_ABI
constexpr __sentinel(__sentinel<!_Const> __s)
requires _Const && convertible_to<sentinel_t<_View>, sentinel_t<_Base>>
- : __end_(_VSTD::move(__s.__end_)) {}
+ : __end_(std::move(__s.__end_)) {}
template<bool _OtherConst>
requires sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>>
@@ -204,7 +210,8 @@ namespace ranges {
public:
using iterator_concept = _If<
- __ref_is_glvalue && bidirectional_range<_Base> && bidirectional_range<range_reference_t<_Base>>,
+ __ref_is_glvalue && bidirectional_range<_Base> && bidirectional_range<range_reference_t<_Base>> &&
+ common_range<range_reference_t<_Base>>,
bidirectional_iterator_tag,
_If<
__ref_is_glvalue && forward_range<_Base> && forward_range<range_reference_t<_Base>>,
@@ -223,8 +230,8 @@ namespace ranges {
_LIBCPP_HIDE_FROM_ABI
constexpr __iterator(_Parent& __parent, _Outer __outer)
- : __outer_(_VSTD::move(__outer))
- , __parent_(_VSTD::addressof(__parent)) {
+ : __outer_(std::move(__outer))
+ , __parent_(std::addressof(__parent)) {
__satisfy();
}
@@ -233,8 +240,8 @@ namespace ranges {
requires _Const &&
convertible_to<iterator_t<_View>, _Outer> &&
convertible_to<iterator_t<_InnerRange>, _Inner>
- : __outer_(_VSTD::move(__i.__outer_))
- , __inner_(_VSTD::move(__i.__inner_))
+ : __outer_(std::move(__i.__outer_))
+ , __inner_(std::move(__i.__inner_))
, __parent_(__i.__parent_) {}
_LIBCPP_HIDE_FROM_ABI
@@ -338,12 +345,25 @@ namespace ranges {
template<class _Range>
explicit join_view(_Range&&) -> join_view<views::all_t<_Range>>;
-
+
+namespace views {
+namespace __join_view {
+struct __fn : __range_adaptor_closure<__fn> {
+ template<class _Range>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI
+ constexpr auto operator()(_Range&& __range) const
+ noexcept(noexcept(join_view<all_t<_Range&&>>(std::forward<_Range>(__range))))
+ -> decltype( join_view<all_t<_Range&&>>(std::forward<_Range>(__range)))
+ { return join_view<all_t<_Range&&>>(std::forward<_Range>(__range)); }
+};
+} // namespace __join_view
+inline namespace __cpo {
+ inline constexpr auto join = __join_view::__fn{};
+} // namespace __cpo
+} // namespace views
} // namespace ranges
-#undef _CONSTEXPR_TERNARY
-
-#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__ranges/lazy_split_view.h b/libcxx/include/__ranges/lazy_split_view.h
new file mode 100644
index 000000000000..e559a76ef7b7
--- /dev/null
+++ b/libcxx/include/__ranges/lazy_split_view.h
@@ -0,0 +1,465 @@
+// -*- 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___RANGES_LAZY_SPLIT_VIEW_H
+#define _LIBCPP___RANGES_LAZY_SPLIT_VIEW_H
+
+#include <__algorithm/in_in_result.h>
+#include <__algorithm/ranges_find.h>
+#include <__algorithm/ranges_mismatch.h>
+#include <__concepts/constructible.h>
+#include <__concepts/convertible_to.h>
+#include <__concepts/derived_from.h>
+#include <__config>
+#include <__functional/bind_back.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/default_sentinel.h>
+#include <__iterator/incrementable_traits.h>
+#include <__iterator/indirectly_comparable.h>
+#include <__iterator/iter_move.h>
+#include <__iterator/iter_swap.h>
+#include <__iterator/iterator_traits.h>
+#include <__memory/addressof.h>
+#include <__ranges/access.h>
+#include <__ranges/all.h>
+#include <__ranges/concepts.h>
+#include <__ranges/non_propagating_cache.h>
+#include <__ranges/range_adaptor.h>
+#include <__ranges/single_view.h>
+#include <__ranges/subrange.h>
+#include <__ranges/view_interface.h>
+#include <__utility/forward.h>
+#include <__utility/move.h>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+namespace ranges {
+
+template <auto> struct __require_constant;
+
+template <class _Range>
+concept __tiny_range =
+ sized_range<_Range> &&
+ requires { typename __require_constant<remove_reference_t<_Range>::size()>; } &&
+ (remove_reference_t<_Range>::size() <= 1);
+
+template <input_range _View, forward_range _Pattern>
+ requires view<_View> && view<_Pattern> &&
+ indirectly_comparable<iterator_t<_View>, iterator_t<_Pattern>, ranges::equal_to> &&
+ (forward_range<_View> || __tiny_range<_Pattern>)
+class lazy_split_view : public view_interface<lazy_split_view<_View, _Pattern>> {
+
+ _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View();
+ _LIBCPP_NO_UNIQUE_ADDRESS _Pattern __pattern_ = _Pattern();
+
+ using _MaybeCurrent = _If<!forward_range<_View>, __non_propagating_cache<iterator_t<_View>>, __empty_cache>;
+ _LIBCPP_NO_UNIQUE_ADDRESS _MaybeCurrent __current_ = _MaybeCurrent();
+
+ template <bool> struct __outer_iterator;
+ template <bool> struct __inner_iterator;
+
+public:
+ _LIBCPP_HIDE_FROM_ABI
+ lazy_split_view()
+ requires default_initializable<_View> && default_initializable<_Pattern> = default;
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr lazy_split_view(_View __base, _Pattern __pattern)
+ : __base_(std::move(__base)), __pattern_(std::move(__pattern)) {}
+
+ template <input_range _Range>
+ requires constructible_from<_View, views::all_t<_Range>> &&
+ constructible_from<_Pattern, single_view<range_value_t<_Range>>>
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr lazy_split_view(_Range&& __r, range_value_t<_Range> __e)
+ : __base_(views::all(std::forward<_Range>(__r)))
+ , __pattern_(views::single(std::move(__e))) {}
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr _View base() const& requires copy_constructible<_View> { return __base_; }
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr _View base() && { return std::move(__base_); }
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr auto begin() {
+ if constexpr (forward_range<_View>) {
+ return __outer_iterator<__simple_view<_View> && __simple_view<_Pattern>>{*this, ranges::begin(__base_)};
+ } else {
+ __current_.__emplace(ranges::begin(__base_));
+ return __outer_iterator<false>{*this};
+ }
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr auto begin() const requires forward_range<_View> && forward_range<const _View> {
+ return __outer_iterator<true>{*this, ranges::begin(__base_)};
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr auto end() requires forward_range<_View> && common_range<_View> {
+ return __outer_iterator<__simple_view<_View> && __simple_view<_Pattern>>{*this, ranges::end(__base_)};
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr auto end() const {
+ if constexpr (forward_range<_View> && forward_range<const _View> && common_range<const _View>) {
+ return __outer_iterator<true>{*this, ranges::end(__base_)};
+ } else {
+ return default_sentinel;
+ }
+ }
+
+private:
+
+ template <class>
+ struct __outer_iterator_category {};
+
+ template <forward_range _Tp>
+ struct __outer_iterator_category<_Tp> {
+ using iterator_category = input_iterator_tag;
+ };
+
+ template <bool _Const>
+ struct __outer_iterator : __outer_iterator_category<__maybe_const<_Const, _View>> {
+ private:
+ template <bool>
+ friend struct __inner_iterator;
+ friend __outer_iterator<true>;
+
+ using _Parent = __maybe_const<_Const, lazy_split_view>;
+ using _Base = __maybe_const<_Const, _View>;
+
+ _Parent* __parent_ = nullptr;
+ using _MaybeCurrent = _If<forward_range<_View>, iterator_t<_Base>, __empty_cache>;
+ _LIBCPP_NO_UNIQUE_ADDRESS _MaybeCurrent __current_ = _MaybeCurrent();
+ bool __trailing_empty_ = false;
+
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI
+ constexpr auto& __current() noexcept {
+ if constexpr (forward_range<_View>) {
+ return __current_;
+ } else {
+ return *__parent_->__current_;
+ }
+ }
+
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI
+ constexpr const auto& __current() const noexcept {
+ if constexpr (forward_range<_View>) {
+ return __current_;
+ } else {
+ return *__parent_->__current_;
+ }
+ }
+
+ // Workaround for the GCC issue that doesn't allow calling `__parent_->__base_` from friend functions (because
+ // `__base_` is private).
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI
+ constexpr auto& __parent_base() const noexcept {
+ return __parent_->__base_;
+ }
+
+ public:
+ // using iterator_category = inherited;
+ using iterator_concept = conditional_t<forward_range<_Base>, forward_iterator_tag, input_iterator_tag>;
+ using difference_type = range_difference_t<_Base>;
+
+ struct value_type : view_interface<value_type> {
+ private:
+ __outer_iterator __i_ = __outer_iterator();
+
+ public:
+ _LIBCPP_HIDE_FROM_ABI
+ value_type() = default;
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr explicit value_type(__outer_iterator __i)
+ : __i_(std::move(__i)) {}
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr __inner_iterator<_Const> begin() const { return __inner_iterator<_Const>{__i_}; }
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr default_sentinel_t end() const noexcept { return default_sentinel; }
+ };
+
+ _LIBCPP_HIDE_FROM_ABI
+ __outer_iterator() = default;
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr explicit __outer_iterator(_Parent& __parent)
+ requires (!forward_range<_Base>)
+ : __parent_(std::addressof(__parent)) {}
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr __outer_iterator(_Parent& __parent, iterator_t<_Base> __current)
+ requires forward_range<_Base>
+ : __parent_(std::addressof(__parent)), __current_(std::move(__current)) {}
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr __outer_iterator(__outer_iterator<!_Const> __i)
+ requires _Const && convertible_to<iterator_t<_View>, iterator_t<_Base>>
+ : __parent_(__i.__parent_), __current_(std::move(__i.__current_)) {}
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr value_type operator*() const { return value_type{*this}; }
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr __outer_iterator& operator++() {
+ const auto __end = ranges::end(__parent_->__base_);
+ if (__current() == __end) {
+ __trailing_empty_ = false;
+ return *this;
+ }
+
+ const auto [__pbegin, __pend] = ranges::subrange{__parent_->__pattern_};
+ if (__pbegin == __pend) {
+ // Empty pattern: split on every element in the input range
+ ++__current();
+
+ } else if constexpr (__tiny_range<_Pattern>) {
+ // One-element pattern: we can use `ranges::find`.
+ __current() = ranges::find(std::move(__current()), __end, *__pbegin);
+ if (__current() != __end) {
+ // Make sure we point to after the separator we just found.
+ ++__current();
+ if (__current() == __end)
+ __trailing_empty_ = true;
+ }
+
+ } else {
+ // General case for n-element pattern.
+ do {
+ const auto [__b, __p] = ranges::mismatch(__current(), __end, __pbegin, __pend);
+ if (__p == __pend) {
+ __current() = __b;
+ if (__current() == __end) {
+ __trailing_empty_ = true;
+ }
+ break; // The pattern matched; skip it.
+ }
+ } while (++__current() != __end);
+ }
+
+ return *this;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr decltype(auto) operator++(int) {
+ if constexpr (forward_range<_Base>) {
+ auto __tmp = *this;
+ ++*this;
+ return __tmp;
+
+ } else {
+ ++*this;
+ }
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ friend constexpr bool operator==(const __outer_iterator& __x, const __outer_iterator& __y)
+ requires forward_range<_Base> {
+ return __x.__current_ == __y.__current_ && __x.__trailing_empty_ == __y.__trailing_empty_;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ friend constexpr bool operator==(const __outer_iterator& __x, default_sentinel_t) {
+ _LIBCPP_ASSERT(__x.__parent_, "Cannot call comparison on a default-constructed iterator.");
+ return __x.__current() == ranges::end(__x.__parent_base()) && !__x.__trailing_empty_;
+ }
+ };
+
+ template <class>
+ struct __inner_iterator_category {};
+
+ template <forward_range _Tp>
+ struct __inner_iterator_category<_Tp> {
+ using iterator_category = _If<
+ derived_from<typename iterator_traits<iterator_t<_Tp>>::iterator_category, forward_iterator_tag>,
+ forward_iterator_tag,
+ typename iterator_traits<iterator_t<_Tp>>::iterator_category
+ >;
+ };
+
+ template <bool _Const>
+ struct __inner_iterator : __inner_iterator_category<__maybe_const<_Const, _View>> {
+ private:
+ using _Base = __maybe_const<_Const, _View>;
+ // Workaround for a GCC issue.
+ static constexpr bool _OuterConst = _Const;
+ __outer_iterator<_Const> __i_ = __outer_iterator<_OuterConst>();
+ bool __incremented_ = false;
+
+ // Note: these private functions are necessary because GCC doesn't allow calls to private members of `__i_` from
+ // free functions that are friends of `inner-iterator`.
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr bool __is_done() const {
+ _LIBCPP_ASSERT(__i_.__parent_, "Cannot call comparison on a default-constructed iterator.");
+
+ auto [__pcur, __pend] = ranges::subrange{__i_.__parent_->__pattern_};
+ auto __end = ranges::end(__i_.__parent_->__base_);
+
+ if constexpr (__tiny_range<_Pattern>) {
+ const auto& __cur = __i_.__current();
+ if (__cur == __end)
+ return true;
+ if (__pcur == __pend)
+ return __incremented_;
+
+ return *__cur == *__pcur;
+
+ } else {
+ auto __cur = __i_.__current();
+ if (__cur == __end)
+ return true;
+ if (__pcur == __pend)
+ return __incremented_;
+
+ do {
+ if (*__cur != *__pcur)
+ return false;
+ if (++__pcur == __pend)
+ return true;
+ } while (++__cur != __end);
+
+ return false;
+ }
+ }
+
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI
+ constexpr auto& __outer_current() noexcept {
+ return __i_.__current();
+ }
+
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI
+ constexpr const auto& __outer_current() const noexcept {
+ return __i_.__current();
+ }
+
+ public:
+ // using iterator_category = inherited;
+ using iterator_concept = typename __outer_iterator<_Const>::iterator_concept;
+ using value_type = range_value_t<_Base>;
+ using difference_type = range_difference_t<_Base>;
+
+ _LIBCPP_HIDE_FROM_ABI
+ __inner_iterator() = default;
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr explicit __inner_iterator(__outer_iterator<_Const> __i)
+ : __i_(std::move(__i)) {}
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr const iterator_t<_Base>& base() const& noexcept { return __i_.__current(); }
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr iterator_t<_Base> base() &&
+ requires forward_range<_View> { return std::move(__i_.__current()); }
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr decltype(auto) operator*() const { return *__i_.__current(); }
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr __inner_iterator& operator++() {
+ __incremented_ = true;
+
+ if constexpr (!forward_range<_Base>) {
+ if constexpr (_Pattern::size() == 0) {
+ return *this;
+ }
+ }
+
+ ++__i_.__current();
+ return *this;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr decltype(auto) operator++(int) {
+ if constexpr (forward_range<_Base>) {
+ auto __tmp = *this;
+ ++*this;
+ return __tmp;
+
+ } else {
+ ++*this;
+ }
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ friend constexpr bool operator==(const __inner_iterator& __x, const __inner_iterator& __y)
+ requires forward_range<_Base> {
+ return __x.__outer_current() == __y.__outer_current();
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ friend constexpr bool operator==(const __inner_iterator& __x, default_sentinel_t) {
+ return __x.__is_done();
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ friend constexpr decltype(auto) iter_move(const __inner_iterator& __i)
+ noexcept(noexcept(ranges::iter_move(__i.__outer_current()))) {
+ return ranges::iter_move(__i.__outer_current());
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ friend constexpr void iter_swap(const __inner_iterator& __x, const __inner_iterator& __y)
+ noexcept(noexcept(ranges::iter_swap(__x.__outer_current(), __y.__outer_current())))
+ requires indirectly_swappable<iterator_t<_Base>> {
+ ranges::iter_swap(__x.__outer_current(), __y.__outer_current());
+ }
+ };
+
+};
+
+template <class _Range, class _Pattern>
+lazy_split_view(_Range&&, _Pattern&&) -> lazy_split_view<views::all_t<_Range>, views::all_t<_Pattern>>;
+
+template <input_range _Range>
+lazy_split_view(_Range&&, range_value_t<_Range>)
+ -> lazy_split_view<views::all_t<_Range>, single_view<range_value_t<_Range>>>;
+
+namespace views {
+namespace __lazy_split_view {
+struct __fn : __range_adaptor_closure<__fn> {
+ template <class _Range, class _Pattern>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI
+ constexpr auto operator()(_Range&& __range, _Pattern&& __pattern) const
+ noexcept(noexcept(lazy_split_view(std::forward<_Range>(__range), std::forward<_Pattern>(__pattern))))
+ -> decltype( lazy_split_view(std::forward<_Range>(__range), std::forward<_Pattern>(__pattern)))
+ { return lazy_split_view(std::forward<_Range>(__range), std::forward<_Pattern>(__pattern)); }
+
+ template <class _Pattern>
+ requires constructible_from<decay_t<_Pattern>, _Pattern>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI
+ constexpr auto operator()(_Pattern&& __pattern) const
+ noexcept(is_nothrow_constructible_v<decay_t<_Pattern>, _Pattern>) {
+ return __range_adaptor_closure_t(std::__bind_back(*this, std::forward<_Pattern>(__pattern)));
+ }
+};
+} // namespace __lazy_split_view
+
+inline namespace __cpo {
+ inline constexpr auto lazy_split = __lazy_split_view::__fn{};
+} // namespace __cpo
+} // namespace views
+
+} // namespace ranges
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___RANGES_LAZY_SPLIT_VIEW_H
diff --git a/libcxx/include/__ranges/non_propagating_cache.h b/libcxx/include/__ranges/non_propagating_cache.h
index d0f447ce7cc5..7255705256d7 100644
--- a/libcxx/include/__ranges/non_propagating_cache.h
+++ b/libcxx/include/__ranges/non_propagating_cache.h
@@ -19,12 +19,12 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
namespace ranges {
// __non_propagating_cache is a helper type that allows storing an optional value in it,
@@ -45,7 +45,7 @@ namespace ranges {
// constructing the contained type from an iterator.
struct __wrapper {
template<class ..._Args>
- constexpr explicit __wrapper(__forward_tag, _Args&& ...__args) : __t_(_VSTD::forward<_Args>(__args)...) { }
+ constexpr explicit __wrapper(__forward_tag, _Args&& ...__args) : __t_(std::forward<_Args>(__args)...) { }
template<class _Fn>
constexpr explicit __wrapper(__from_tag, _Fn const& __f) : __t_(__f()) { }
_Tp __t_;
@@ -70,7 +70,7 @@ namespace ranges {
_LIBCPP_HIDE_FROM_ABI
constexpr __non_propagating_cache& operator=(__non_propagating_cache const& __other) noexcept {
- if (this != _VSTD::addressof(__other)) {
+ if (this != std::addressof(__other)) {
__value_.reset();
}
return *this;
@@ -100,14 +100,14 @@ namespace ranges {
template<class ..._Args>
_LIBCPP_HIDE_FROM_ABI
constexpr _Tp& __emplace(_Args&& ...__args) {
- return __value_.emplace(__forward_tag{}, _VSTD::forward<_Args>(__args)...).__t_;
+ return __value_.emplace(__forward_tag{}, std::forward<_Args>(__args)...).__t_;
}
};
struct __empty_cache { };
} // namespace ranges
-#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__ranges/owning_view.h b/libcxx/include/__ranges/owning_view.h
index 9c038cbd7580..ac1ef08fecc2 100644
--- a/libcxx/include/__ranges/owning_view.h
+++ b/libcxx/include/__ranges/owning_view.h
@@ -23,12 +23,12 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
namespace ranges {
template<range _Rp>
@@ -38,15 +38,15 @@ namespace ranges {
public:
owning_view() requires default_initializable<_Rp> = default;
- _LIBCPP_HIDE_FROM_ABI constexpr owning_view(_Rp&& __r) : __r_(_VSTD::move(__r)) {}
+ _LIBCPP_HIDE_FROM_ABI constexpr owning_view(_Rp&& __r) : __r_(std::move(__r)) {}
owning_view(owning_view&&) = default;
owning_view& operator=(owning_view&&) = default;
_LIBCPP_HIDE_FROM_ABI constexpr _Rp& base() & noexcept { return __r_; }
_LIBCPP_HIDE_FROM_ABI constexpr const _Rp& base() const& noexcept { return __r_; }
- _LIBCPP_HIDE_FROM_ABI constexpr _Rp&& base() && noexcept { return _VSTD::move(__r_); }
- _LIBCPP_HIDE_FROM_ABI constexpr const _Rp&& base() const&& noexcept { return _VSTD::move(__r_); }
+ _LIBCPP_HIDE_FROM_ABI constexpr _Rp&& base() && noexcept { return std::move(__r_); }
+ _LIBCPP_HIDE_FROM_ABI constexpr const _Rp&& base() const&& noexcept { return std::move(__r_); }
_LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_Rp> begin() { return ranges::begin(__r_); }
_LIBCPP_HIDE_FROM_ABI constexpr sentinel_t<_Rp> end() { return ranges::end(__r_); }
@@ -74,7 +74,7 @@ public:
} // namespace ranges
-#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__ranges/range_adaptor.h b/libcxx/include/__ranges/range_adaptor.h
index d037585d2679..b65233b56359 100644
--- a/libcxx/include/__ranges/range_adaptor.h
+++ b/libcxx/include/__ranges/range_adaptor.h
@@ -20,12 +20,12 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
// CRTP base that one can derive from in order to be considered a range adaptor closure
// by the library. When deriving from this class, a pipe operator will be provided to
@@ -39,7 +39,7 @@ struct __range_adaptor_closure;
// i.e. something that can be called via the `x | f` notation.
template <class _Fn>
struct __range_adaptor_closure_t : _Fn, __range_adaptor_closure<__range_adaptor_closure_t<_Fn>> {
- constexpr explicit __range_adaptor_closure_t(_Fn&& __f) : _Fn(_VSTD::move(__f)) { }
+ constexpr explicit __range_adaptor_closure_t(_Fn&& __f) : _Fn(std::move(__f)) { }
};
template <class _Tp>
@@ -53,7 +53,7 @@ struct __range_adaptor_closure {
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI
friend constexpr decltype(auto) operator|(_View&& __view, _Closure&& __closure)
noexcept(is_nothrow_invocable_v<_Closure, _View>)
- { return _VSTD::invoke(_VSTD::forward<_Closure>(__closure), _VSTD::forward<_View>(__view)); }
+ { return std::invoke(std::forward<_Closure>(__closure), std::forward<_View>(__view)); }
template <_RangeAdaptorClosure _Closure, _RangeAdaptorClosure _OtherClosure>
requires same_as<_Tp, remove_cvref_t<_Closure>> &&
@@ -63,10 +63,10 @@ struct __range_adaptor_closure {
friend constexpr auto operator|(_Closure&& __c1, _OtherClosure&& __c2)
noexcept(is_nothrow_constructible_v<decay_t<_Closure>, _Closure> &&
is_nothrow_constructible_v<decay_t<_OtherClosure>, _OtherClosure>)
- { return __range_adaptor_closure_t(_VSTD::__compose(_VSTD::forward<_OtherClosure>(__c2), _VSTD::forward<_Closure>(__c1))); }
+ { return __range_adaptor_closure_t(std::__compose(std::forward<_OtherClosure>(__c2), std::forward<_Closure>(__c1))); }
};
-#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__ranges/rbegin.h b/libcxx/include/__ranges/rbegin.h
new file mode 100644
index 000000000000..9291359fdf3b
--- /dev/null
+++ b/libcxx/include/__ranges/rbegin.h
@@ -0,0 +1,130 @@
+// -*- 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___RANGES_RBEGIN_H
+#define _LIBCPP___RANGES_RBEGIN_H
+
+#include <__concepts/class_or_enum.h>
+#include <__concepts/same_as.h>
+#include <__config>
+#include <__iterator/concepts.h>
+#include <__iterator/readable_traits.h>
+#include <__iterator/reverse_iterator.h>
+#include <__ranges/access.h>
+#include <__utility/auto_cast.h>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+// [ranges.access.rbegin]
+
+namespace ranges {
+namespace __rbegin {
+template <class _Tp>
+concept __member_rbegin =
+ __can_borrow<_Tp> &&
+ __workaround_52970<_Tp> &&
+ requires(_Tp&& __t) {
+ { _LIBCPP_AUTO_CAST(__t.rbegin()) } -> input_or_output_iterator;
+ };
+
+void rbegin(auto&) = delete;
+void rbegin(const auto&) = delete;
+
+template <class _Tp>
+concept __unqualified_rbegin =
+ !__member_rbegin<_Tp> &&
+ __can_borrow<_Tp> &&
+ __class_or_enum<remove_cvref_t<_Tp>> &&
+ requires(_Tp&& __t) {
+ { _LIBCPP_AUTO_CAST(rbegin(__t)) } -> input_or_output_iterator;
+ };
+
+template <class _Tp>
+concept __can_reverse =
+ __can_borrow<_Tp> &&
+ !__member_rbegin<_Tp> &&
+ !__unqualified_rbegin<_Tp> &&
+ requires(_Tp&& __t) {
+ { ranges::begin(__t) } -> same_as<decltype(ranges::end(__t))>;
+ { ranges::begin(__t) } -> bidirectional_iterator;
+ };
+
+struct __fn {
+ template <class _Tp>
+ requires __member_rbegin<_Tp>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
+ noexcept(noexcept(_LIBCPP_AUTO_CAST(__t.rbegin())))
+ {
+ return _LIBCPP_AUTO_CAST(__t.rbegin());
+ }
+
+ template <class _Tp>
+ requires __unqualified_rbegin<_Tp>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
+ noexcept(noexcept(_LIBCPP_AUTO_CAST(rbegin(__t))))
+ {
+ return _LIBCPP_AUTO_CAST(rbegin(__t));
+ }
+
+ template <class _Tp>
+ requires __can_reverse<_Tp>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
+ noexcept(noexcept(ranges::end(__t)))
+ {
+ return std::make_reverse_iterator(ranges::end(__t));
+ }
+
+ void operator()(auto&&) const = delete;
+};
+} // namespace __rbegin
+
+inline namespace __cpo {
+ inline constexpr auto rbegin = __rbegin::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+// [range.access.crbegin]
+
+namespace ranges {
+namespace __crbegin {
+struct __fn {
+ template <class _Tp>
+ requires is_lvalue_reference_v<_Tp&&>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI
+ constexpr auto operator()(_Tp&& __t) const
+ noexcept(noexcept(ranges::rbegin(static_cast<const remove_reference_t<_Tp>&>(__t))))
+ -> decltype( ranges::rbegin(static_cast<const remove_reference_t<_Tp>&>(__t)))
+ { return ranges::rbegin(static_cast<const remove_reference_t<_Tp>&>(__t)); }
+
+ template <class _Tp>
+ requires is_rvalue_reference_v<_Tp&&>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI
+ constexpr auto operator()(_Tp&& __t) const
+ noexcept(noexcept(ranges::rbegin(static_cast<const _Tp&&>(__t))))
+ -> decltype( ranges::rbegin(static_cast<const _Tp&&>(__t)))
+ { return ranges::rbegin(static_cast<const _Tp&&>(__t)); }
+};
+} // namespace __crbegin
+
+inline namespace __cpo {
+ inline constexpr auto crbegin = __crbegin::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___RANGES_RBEGIN_H
diff --git a/libcxx/include/__ranges/ref_view.h b/libcxx/include/__ranges/ref_view.h
index 4d12759e614f..e69c715fb9e4 100644
--- a/libcxx/include/__ranges/ref_view.h
+++ b/libcxx/include/__ranges/ref_view.h
@@ -26,12 +26,12 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
namespace ranges {
template<range _Range>
@@ -48,7 +48,7 @@ public:
convertible_to<_Tp, _Range&> && requires { __fun(declval<_Tp>()); }
_LIBCPP_HIDE_FROM_ABI
constexpr ref_view(_Tp&& __t)
- : __range_(_VSTD::addressof(static_cast<_Range&>(_VSTD::forward<_Tp>(__t))))
+ : __range_(std::addressof(static_cast<_Range&>(std::forward<_Tp>(__t))))
{}
_LIBCPP_HIDE_FROM_ABI constexpr _Range& base() const { return *__range_; }
@@ -79,7 +79,7 @@ public:
inline constexpr bool enable_borrowed_range<ref_view<_Tp>> = true;
} // namespace ranges
-#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__ranges/rend.h b/libcxx/include/__ranges/rend.h
new file mode 100644
index 000000000000..e507b2587277
--- /dev/null
+++ b/libcxx/include/__ranges/rend.h
@@ -0,0 +1,134 @@
+// -*- 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___RANGES_REND_H
+#define _LIBCPP___RANGES_REND_H
+
+#include <__concepts/class_or_enum.h>
+#include <__concepts/same_as.h>
+#include <__config>
+#include <__iterator/concepts.h>
+#include <__iterator/readable_traits.h>
+#include <__iterator/reverse_iterator.h>
+#include <__ranges/access.h>
+#include <__ranges/rbegin.h>
+#include <__utility/auto_cast.h>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+// [range.access.rend]
+
+namespace ranges {
+namespace __rend {
+template <class _Tp>
+concept __member_rend =
+ __can_borrow<_Tp> &&
+ __workaround_52970<_Tp> &&
+ requires(_Tp&& __t) {
+ ranges::rbegin(__t);
+ { _LIBCPP_AUTO_CAST(__t.rend()) } -> sentinel_for<decltype(ranges::rbegin(__t))>;
+ };
+
+void rend(auto&) = delete;
+void rend(const auto&) = delete;
+
+template <class _Tp>
+concept __unqualified_rend =
+ !__member_rend<_Tp> &&
+ __can_borrow<_Tp> &&
+ __class_or_enum<remove_cvref_t<_Tp>> &&
+ requires(_Tp&& __t) {
+ ranges::rbegin(__t);
+ { _LIBCPP_AUTO_CAST(rend(__t)) } -> sentinel_for<decltype(ranges::rbegin(__t))>;
+ };
+
+template <class _Tp>
+concept __can_reverse =
+ __can_borrow<_Tp> &&
+ !__member_rend<_Tp> &&
+ !__unqualified_rend<_Tp> &&
+ requires(_Tp&& __t) {
+ { ranges::begin(__t) } -> same_as<decltype(ranges::end(__t))>;
+ { ranges::begin(__t) } -> bidirectional_iterator;
+ };
+
+class __fn {
+public:
+ template <class _Tp>
+ requires __member_rend<_Tp>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
+ noexcept(noexcept(_LIBCPP_AUTO_CAST(__t.rend())))
+ {
+ return _LIBCPP_AUTO_CAST(__t.rend());
+ }
+
+ template <class _Tp>
+ requires __unqualified_rend<_Tp>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
+ noexcept(noexcept(_LIBCPP_AUTO_CAST(rend(__t))))
+ {
+ return _LIBCPP_AUTO_CAST(rend(__t));
+ }
+
+ template <class _Tp>
+ requires __can_reverse<_Tp>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
+ noexcept(noexcept(ranges::begin(__t)))
+ {
+ return std::make_reverse_iterator(ranges::begin(__t));
+ }
+
+ void operator()(auto&&) const = delete;
+};
+} // namespace __rend
+
+inline namespace __cpo {
+ inline constexpr auto rend = __rend::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+// [range.access.crend]
+
+namespace ranges {
+namespace __crend {
+struct __fn {
+ template <class _Tp>
+ requires is_lvalue_reference_v<_Tp&&>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI
+ constexpr auto operator()(_Tp&& __t) const
+ noexcept(noexcept(ranges::rend(static_cast<const remove_reference_t<_Tp>&>(__t))))
+ -> decltype( ranges::rend(static_cast<const remove_reference_t<_Tp>&>(__t)))
+ { return ranges::rend(static_cast<const remove_reference_t<_Tp>&>(__t)); }
+
+ template <class _Tp>
+ requires is_rvalue_reference_v<_Tp&&>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI
+ constexpr auto operator()(_Tp&& __t) const
+ noexcept(noexcept(ranges::rend(static_cast<const _Tp&&>(__t))))
+ -> decltype( ranges::rend(static_cast<const _Tp&&>(__t)))
+ { return ranges::rend(static_cast<const _Tp&&>(__t)); }
+};
+} // namespace __crend
+
+inline namespace __cpo {
+ inline constexpr auto crend = __crend::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___RANGES_REND_H
diff --git a/libcxx/include/__ranges/reverse_view.h b/libcxx/include/__ranges/reverse_view.h
index 04ac7f29aa7c..b1df8fbc337b 100644
--- a/libcxx/include/__ranges/reverse_view.h
+++ b/libcxx/include/__ranges/reverse_view.h
@@ -28,12 +28,12 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
namespace ranges {
template<view _View>
@@ -43,21 +43,21 @@ namespace ranges {
// amortized O(1) begin() method.
static constexpr bool _UseCache = !random_access_range<_View> && !common_range<_View>;
using _Cache = _If<_UseCache, __non_propagating_cache<reverse_iterator<iterator_t<_View>>>, __empty_cache>;
- [[no_unique_address]] _Cache __cached_begin_ = _Cache();
- [[no_unique_address]] _View __base_ = _View();
+ _LIBCPP_NO_UNIQUE_ADDRESS _Cache __cached_begin_ = _Cache();
+ _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View();
public:
_LIBCPP_HIDE_FROM_ABI
reverse_view() requires default_initializable<_View> = default;
_LIBCPP_HIDE_FROM_ABI
- constexpr explicit reverse_view(_View __view) : __base_(_VSTD::move(__view)) {}
+ constexpr explicit reverse_view(_View __view) : __base_(std::move(__view)) {}
_LIBCPP_HIDE_FROM_ABI
constexpr _View base() const& requires copy_constructible<_View> { return __base_; }
_LIBCPP_HIDE_FROM_ABI
- constexpr _View base() && { return _VSTD::move(__base_); }
+ constexpr _View base() && { return std::move(__base_); }
_LIBCPP_HIDE_FROM_ABI
constexpr reverse_iterator<iterator_t<_View>> begin() {
@@ -65,7 +65,7 @@ namespace ranges {
if (__cached_begin_.__has_value())
return *__cached_begin_;
- auto __tmp = _VSTD::make_reverse_iterator(ranges::next(ranges::begin(__base_), ranges::end(__base_)));
+ auto __tmp = std::make_reverse_iterator(ranges::next(ranges::begin(__base_), ranges::end(__base_)));
if constexpr (_UseCache)
__cached_begin_.__emplace(__tmp);
return __tmp;
@@ -73,22 +73,22 @@ namespace ranges {
_LIBCPP_HIDE_FROM_ABI
constexpr reverse_iterator<iterator_t<_View>> begin() requires common_range<_View> {
- return _VSTD::make_reverse_iterator(ranges::end(__base_));
+ return std::make_reverse_iterator(ranges::end(__base_));
}
_LIBCPP_HIDE_FROM_ABI
constexpr auto begin() const requires common_range<const _View> {
- return _VSTD::make_reverse_iterator(ranges::end(__base_));
+ return std::make_reverse_iterator(ranges::end(__base_));
}
_LIBCPP_HIDE_FROM_ABI
constexpr reverse_iterator<iterator_t<_View>> end() {
- return _VSTD::make_reverse_iterator(ranges::begin(__base_));
+ return std::make_reverse_iterator(ranges::begin(__base_));
}
_LIBCPP_HIDE_FROM_ABI
constexpr auto end() const requires common_range<const _View> {
- return _VSTD::make_reverse_iterator(ranges::begin(__base_));
+ return std::make_reverse_iterator(ranges::begin(__base_));
}
_LIBCPP_HIDE_FROM_ABI
@@ -111,22 +111,22 @@ namespace ranges {
namespace views {
namespace __reverse {
template<class _Tp>
- constexpr bool __is_reverse_view = false;
+ inline constexpr bool __is_reverse_view = false;
template<class _Tp>
- constexpr bool __is_reverse_view<reverse_view<_Tp>> = true;
+ inline constexpr bool __is_reverse_view<reverse_view<_Tp>> = true;
template<class _Tp>
- constexpr bool __is_sized_reverse_subrange = false;
+ inline constexpr bool __is_sized_reverse_subrange = false;
template<class _Iter>
- constexpr bool __is_sized_reverse_subrange<subrange<reverse_iterator<_Iter>, reverse_iterator<_Iter>, subrange_kind::sized>> = true;
+ inline constexpr bool __is_sized_reverse_subrange<subrange<reverse_iterator<_Iter>, reverse_iterator<_Iter>, subrange_kind::sized>> = true;
template<class _Tp>
- constexpr bool __is_unsized_reverse_subrange = false;
+ inline constexpr bool __is_unsized_reverse_subrange = false;
template<class _Iter, subrange_kind _Kind>
- constexpr bool __is_unsized_reverse_subrange<subrange<reverse_iterator<_Iter>, reverse_iterator<_Iter>, _Kind>> = _Kind == subrange_kind::unsized;
+ inline constexpr bool __is_unsized_reverse_subrange<subrange<reverse_iterator<_Iter>, reverse_iterator<_Iter>, _Kind>> = _Kind == subrange_kind::unsized;
template<class _Tp>
struct __unwrapped_reverse_subrange {
@@ -143,9 +143,9 @@ namespace ranges {
requires __is_reverse_view<remove_cvref_t<_Range>>
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI
constexpr auto operator()(_Range&& __range) const
- noexcept(noexcept(_VSTD::forward<_Range>(__range).base()))
- -> decltype( _VSTD::forward<_Range>(__range).base())
- { return _VSTD::forward<_Range>(__range).base(); }
+ noexcept(noexcept(std::forward<_Range>(__range).base()))
+ -> decltype( std::forward<_Range>(__range).base())
+ { return std::forward<_Range>(__range).base(); }
template<class _Range,
class _UnwrappedSubrange = typename __unwrapped_reverse_subrange<remove_cvref_t<_Range>>::type>
@@ -171,9 +171,9 @@ namespace ranges {
!__is_unsized_reverse_subrange<remove_cvref_t<_Range>>)
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI
constexpr auto operator()(_Range&& __range) const
- noexcept(noexcept(reverse_view{_VSTD::forward<_Range>(__range)}))
- -> decltype( reverse_view{_VSTD::forward<_Range>(__range)})
- { return reverse_view{_VSTD::forward<_Range>(__range)}; }
+ noexcept(noexcept(reverse_view{std::forward<_Range>(__range)}))
+ -> decltype( reverse_view{std::forward<_Range>(__range)})
+ { return reverse_view{std::forward<_Range>(__range)}; }
};
} // namespace __reverse
@@ -183,7 +183,7 @@ namespace ranges {
} // namespace views
} // namespace ranges
-#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__ranges/single_view.h b/libcxx/include/__ranges/single_view.h
index c6f0746ea795..98ebe5f3839f 100644
--- a/libcxx/include/__ranges/single_view.h
+++ b/libcxx/include/__ranges/single_view.h
@@ -11,6 +11,7 @@
#include <__config>
#include <__ranges/copyable_box.h>
+#include <__ranges/range_adaptor.h>
#include <__ranges/view_interface.h>
#include <__utility/forward.h>
#include <__utility/in_place.h>
@@ -19,12 +20,12 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
namespace ranges {
template<copy_constructible _Tp>
@@ -40,13 +41,13 @@ namespace ranges {
constexpr explicit single_view(const _Tp& __t) : __value_(in_place, __t) {}
_LIBCPP_HIDE_FROM_ABI
- constexpr explicit single_view(_Tp&& __t) : __value_(in_place, _VSTD::move(__t)) {}
+ constexpr explicit single_view(_Tp&& __t) : __value_(in_place, std::move(__t)) {}
template<class... _Args>
requires constructible_from<_Tp, _Args...>
_LIBCPP_HIDE_FROM_ABI
constexpr explicit single_view(in_place_t, _Args&&... __args)
- : __value_{in_place, _VSTD::forward<_Args>(__args)...} {}
+ : __value_{in_place, std::forward<_Args>(__args)...} {}
_LIBCPP_HIDE_FROM_ABI
constexpr _Tp* begin() noexcept { return data(); }
@@ -70,11 +71,30 @@ namespace ranges {
constexpr const _Tp* data() const noexcept { return __value_.operator->(); }
};
- template<class _Tp>
- single_view(_Tp) -> single_view<_Tp>;
+template<class _Tp>
+single_view(_Tp) -> single_view<_Tp>;
+
+namespace views {
+namespace __single_view {
+
+struct __fn : __range_adaptor_closure<__fn> {
+ template<class _Range>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI
+ constexpr auto operator()(_Range&& __range) const
+ noexcept(noexcept(single_view<decay_t<_Range&&>>(std::forward<_Range>(__range))))
+ -> decltype( single_view<decay_t<_Range&&>>(std::forward<_Range>(__range)))
+ { return single_view<decay_t<_Range&&>>(std::forward<_Range>(__range)); }
+};
+} // namespace __single_view
+
+inline namespace __cpo {
+ inline constexpr auto single = __single_view::__fn{};
+} // namespace __cpo
+
+} // namespace views
} // namespace ranges
-#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__ranges/size.h b/libcxx/include/__ranges/size.h
index e1aaf7eba898..32ca4b854bc3 100644
--- a/libcxx/include/__ranges/size.h
+++ b/libcxx/include/__ranges/size.h
@@ -19,12 +19,12 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17
namespace ranges {
template<class>
@@ -35,68 +35,76 @@ namespace ranges {
namespace ranges {
namespace __size {
- void size(auto&) = delete;
- void size(const auto&) = delete;
-
- template <class _Tp>
- concept __size_enabled = !disable_sized_range<remove_cvref_t<_Tp>>;
-
- template <class _Tp>
- concept __member_size =
- __size_enabled<_Tp> &&
- __workaround_52970<_Tp> &&
- requires(_Tp&& __t) {
- { _LIBCPP_AUTO_CAST(__t.size()) } -> __integer_like;
- };
-
- template <class _Tp>
- concept __unqualified_size =
- __size_enabled<_Tp> &&
- !__member_size<_Tp> &&
- __class_or_enum<remove_cvref_t<_Tp>> &&
- requires(_Tp&& __t) {
- { _LIBCPP_AUTO_CAST(size(__t)) } -> __integer_like;
- };
-
- template <class _Tp>
- concept __difference =
- !__member_size<_Tp> &&
- !__unqualified_size<_Tp> &&
- __class_or_enum<remove_cvref_t<_Tp>> &&
- requires(_Tp&& __t) {
- { ranges::begin(__t) } -> forward_iterator;
- { ranges::end(__t) } -> sized_sentinel_for<decltype(ranges::begin(declval<_Tp>()))>;
- };
-
- struct __fn {
- template <class _Tp, size_t _Sz>
- [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr size_t operator()(_Tp (&&)[_Sz]) const noexcept {
- return _Sz;
- }
-
- template <class _Tp, size_t _Sz>
- [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr size_t operator()(_Tp (&)[_Sz]) const noexcept {
- return _Sz;
- }
-
- template <__member_size _Tp>
- [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __integer_like auto operator()(_Tp&& __t) const
- noexcept(noexcept(_LIBCPP_AUTO_CAST(__t.size()))) {
- return _LIBCPP_AUTO_CAST(__t.size());
- }
-
- template <__unqualified_size _Tp>
- [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __integer_like auto operator()(_Tp&& __t) const
- noexcept(noexcept(_LIBCPP_AUTO_CAST(size(__t)))) {
- return _LIBCPP_AUTO_CAST(size(__t));
- }
-
- template<__difference _Tp>
- [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __integer_like auto operator()(_Tp&& __t) const
- noexcept(noexcept(ranges::end(__t) - ranges::begin(__t))) {
- return _VSTD::__to_unsigned_like(ranges::end(__t) - ranges::begin(__t));
- }
+void size(auto&) = delete;
+void size(const auto&) = delete;
+
+template <class _Tp>
+concept __size_enabled = !disable_sized_range<remove_cvref_t<_Tp>>;
+
+template <class _Tp>
+concept __member_size =
+ __size_enabled<_Tp> &&
+ __workaround_52970<_Tp> &&
+ requires(_Tp&& __t) {
+ { _LIBCPP_AUTO_CAST(__t.size()) } -> __integer_like;
};
+
+template <class _Tp>
+concept __unqualified_size =
+ __size_enabled<_Tp> &&
+ !__member_size<_Tp> &&
+ __class_or_enum<remove_cvref_t<_Tp>> &&
+ requires(_Tp&& __t) {
+ { _LIBCPP_AUTO_CAST(size(__t)) } -> __integer_like;
+ };
+
+template <class _Tp>
+concept __difference =
+ !__member_size<_Tp> &&
+ !__unqualified_size<_Tp> &&
+ __class_or_enum<remove_cvref_t<_Tp>> &&
+ requires(_Tp&& __t) {
+ { ranges::begin(__t) } -> forward_iterator;
+ { ranges::end(__t) } -> sized_sentinel_for<decltype(ranges::begin(declval<_Tp>()))>;
+ };
+
+struct __fn {
+
+ // `[range.prim.size]`: the array case (for rvalues).
+ template <class _Tp, size_t _Sz>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr size_t operator()(_Tp (&&)[_Sz]) const noexcept {
+ return _Sz;
+ }
+
+ // `[range.prim.size]`: the array case (for lvalues).
+ template <class _Tp, size_t _Sz>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr size_t operator()(_Tp (&)[_Sz]) const noexcept {
+ return _Sz;
+ }
+
+ // `[range.prim.size]`: `auto(t.size())` is a valid expression.
+ template <__member_size _Tp>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __integer_like auto operator()(_Tp&& __t) const
+ noexcept(noexcept(_LIBCPP_AUTO_CAST(__t.size()))) {
+ return _LIBCPP_AUTO_CAST(__t.size());
+ }
+
+ // `[range.prim.size]`: `auto(size(t))` is a valid expression.
+ template <__unqualified_size _Tp>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __integer_like auto operator()(_Tp&& __t) const
+ noexcept(noexcept(_LIBCPP_AUTO_CAST(size(__t)))) {
+ return _LIBCPP_AUTO_CAST(size(__t));
+ }
+
+ // [range.prim.size]: the `to-unsigned-like` case.
+ template <__difference _Tp>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
+ noexcept(noexcept(std::__to_unsigned_like(ranges::end(__t) - ranges::begin(__t))))
+ -> decltype( std::__to_unsigned_like(ranges::end(__t) - ranges::begin(__t)))
+ { return std::__to_unsigned_like(ranges::end(__t) - ranges::begin(__t));
+ }
+};
+
} // namespace __size
inline namespace __cpo {
@@ -108,19 +116,18 @@ inline namespace __cpo {
namespace ranges {
namespace __ssize {
- struct __fn {
- template<class _Tp>
- requires requires (_Tp&& __t) { ranges::size(__t); }
- [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr integral auto operator()(_Tp&& __t) const
- noexcept(noexcept(ranges::size(__t)))
- {
- using _Signed = make_signed_t<decltype(ranges::size(__t))>;
- if constexpr (sizeof(ptrdiff_t) > sizeof(_Signed))
- return static_cast<ptrdiff_t>(ranges::size(__t));
- else
- return static_cast<_Signed>(ranges::size(__t));
- }
- };
+struct __fn {
+ template<class _Tp>
+ requires requires (_Tp&& __t) { ranges::size(__t); }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr integral auto operator()(_Tp&& __t) const
+ noexcept(noexcept(ranges::size(__t))) {
+ using _Signed = make_signed_t<decltype(ranges::size(__t))>;
+ if constexpr (sizeof(ptrdiff_t) > sizeof(_Signed))
+ return static_cast<ptrdiff_t>(ranges::size(__t));
+ else
+ return static_cast<_Signed>(ranges::size(__t));
+ }
+};
} // namespace __ssize
inline namespace __cpo {
@@ -128,7 +135,7 @@ inline namespace __cpo {
} // namespace __cpo
} // namespace ranges
-#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__ranges/subrange.h b/libcxx/include/__ranges/subrange.h
index c6977cec3672..7e42da6ce7f9 100644
--- a/libcxx/include/__ranges/subrange.h
+++ b/libcxx/include/__ranges/subrange.h
@@ -9,13 +9,13 @@
#ifndef _LIBCPP___RANGES_SUBRANGE_H
#define _LIBCPP___RANGES_SUBRANGE_H
+#include <__assert>
#include <__concepts/constructible.h>
#include <__concepts/convertible_to.h>
#include <__concepts/copyable.h>
#include <__concepts/derived_from.h>
#include <__concepts/different_from.h>
#include <__config>
-#include <__debug>
#include <__iterator/advance.h>
#include <__iterator/concepts.h>
#include <__iterator/incrementable_traits.h>
@@ -31,12 +31,12 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
namespace ranges {
template<class _From, class _To>
@@ -56,8 +56,8 @@ namespace ranges {
requires derived_from<tuple_size<_Tp>, integral_constant<size_t, 2>>;
typename tuple_element_t<0, remove_const_t<_Tp>>;
typename tuple_element_t<1, remove_const_t<_Tp>>;
- { _VSTD::get<0>(__t) } -> convertible_to<const tuple_element_t<0, _Tp>&>;
- { _VSTD::get<1>(__t) } -> convertible_to<const tuple_element_t<1, _Tp>&>;
+ { std::get<0>(__t) } -> convertible_to<const tuple_element_t<0, _Tp>&>;
+ { std::get<1>(__t) } -> convertible_to<const tuple_element_t<1, _Tp>&>;
};
template<class _Pair, class _Iter, class _Sent>
@@ -77,14 +77,17 @@ namespace ranges {
class _LIBCPP_TEMPLATE_VIS subrange
: public view_interface<subrange<_Iter, _Sent, _Kind>>
{
- private:
+ public:
+ // Note: this is an internal implementation detail that is public only for internal usage.
static constexpr bool _StoreSize = (_Kind == subrange_kind::sized && !sized_sentinel_for<_Sent, _Iter>);
+
+ private:
static constexpr bool _MustProvideSizeAtConstruction = !_StoreSize; // just to improve compiler diagnostics
struct _Empty { constexpr _Empty(auto) noexcept { } };
using _Size = conditional_t<_StoreSize, make_unsigned_t<iter_difference_t<_Iter>>, _Empty>;
- [[no_unique_address]] _Iter __begin_ = _Iter();
- [[no_unique_address]] _Sent __end_ = _Sent();
- [[no_unique_address]] _Size __size_ = 0;
+ _LIBCPP_NO_UNIQUE_ADDRESS _Iter __begin_ = _Iter();
+ _LIBCPP_NO_UNIQUE_ADDRESS _Sent __end_ = _Sent();
+ _LIBCPP_NO_UNIQUE_ADDRESS _Size __size_ = 0;
public:
_LIBCPP_HIDE_FROM_ABI
@@ -93,14 +96,14 @@ namespace ranges {
_LIBCPP_HIDE_FROM_ABI
constexpr subrange(__convertible_to_non_slicing<_Iter> auto __iter, _Sent __sent)
requires _MustProvideSizeAtConstruction
- : __begin_(_VSTD::move(__iter)), __end_(_VSTD::move(__sent))
+ : __begin_(std::move(__iter)), __end_(std::move(__sent))
{ }
_LIBCPP_HIDE_FROM_ABI
constexpr subrange(__convertible_to_non_slicing<_Iter> auto __iter, _Sent __sent,
make_unsigned_t<iter_difference_t<_Iter>> __n)
requires (_Kind == subrange_kind::sized)
- : __begin_(_VSTD::move(__iter)), __end_(_VSTD::move(__sent)), __size_(__n)
+ : __begin_(std::move(__iter)), __end_(std::move(__sent)), __size_(__n)
{
if constexpr (sized_sentinel_for<_Sent, _Iter>)
_LIBCPP_ASSERT((__end_ - __begin_) == static_cast<iter_difference_t<_Iter>>(__n),
@@ -149,7 +152,7 @@ namespace ranges {
}
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Iter begin() requires (!copyable<_Iter>) {
- return _VSTD::move(__begin_);
+ return std::move(__begin_);
}
_LIBCPP_HIDE_FROM_ABI
@@ -168,7 +171,7 @@ namespace ranges {
if constexpr (_StoreSize)
return __size_;
else
- return _VSTD::__to_unsigned_like(__end_ - __begin_);
+ return std::__to_unsigned_like(__end_ - __begin_);
}
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr subrange next(iter_difference_t<_Iter> __n = 1) const&
@@ -181,7 +184,7 @@ namespace ranges {
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr subrange next(iter_difference_t<_Iter> __n = 1) && {
advance(__n);
- return _VSTD::move(*this);
+ return std::move(*this);
}
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr subrange prev(iter_difference_t<_Iter> __n = 1) const
@@ -198,14 +201,14 @@ namespace ranges {
if (__n < 0) {
ranges::advance(__begin_, __n);
if constexpr (_StoreSize)
- __size_ += _VSTD::__to_unsigned_like(-__n);
+ __size_ += std::__to_unsigned_like(-__n);
return *this;
}
}
auto __d = __n - ranges::advance(__begin_, __n, __end_);
if constexpr (_StoreSize)
- __size_ -= _VSTD::__to_unsigned_like(__d);
+ __size_ -= std::__to_unsigned_like(__d);
return *this;
}
};
@@ -282,7 +285,7 @@ struct tuple_element<1, const ranges::subrange<_Ip, _Sp, _Kp>> {
using type = _Sp;
};
-#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__ranges/take_view.h b/libcxx/include/__ranges/take_view.h
index 4d45219020da..11d5c9fc36bc 100644
--- a/libcxx/include/__ranges/take_view.h
+++ b/libcxx/include/__ranges/take_view.h
@@ -10,23 +10,34 @@
#define _LIBCPP___RANGES_TAKE_VIEW_H
#include <__algorithm/min.h>
+#include <__algorithm/ranges_min.h>
#include <__config>
+#include <__functional/bind_back.h>
+#include <__fwd/span.h>
+#include <__fwd/string_view.h>
#include <__iterator/concepts.h>
#include <__iterator/counted_iterator.h>
#include <__iterator/default_sentinel.h>
+#include <__iterator/distance.h>
#include <__iterator/iterator_traits.h>
#include <__ranges/access.h>
#include <__ranges/all.h>
#include <__ranges/concepts.h>
+#include <__ranges/empty_view.h>
#include <__ranges/enable_borrowed_range.h>
+#include <__ranges/iota_view.h>
+#include <__ranges/range_adaptor.h>
#include <__ranges/size.h>
+#include <__ranges/subrange.h>
#include <__ranges/view_interface.h>
+#include <__utility/auto_cast.h>
+#include <__utility/forward.h>
#include <__utility/move.h>
#include <concepts>
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
@@ -34,149 +45,290 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
namespace ranges {
- template<view _View>
- class take_view : public view_interface<take_view<_View>> {
- [[no_unique_address]] _View __base_ = _View();
- range_difference_t<_View> __count_ = 0;
-
- template<bool> class __sentinel;
-
- public:
- _LIBCPP_HIDE_FROM_ABI
- take_view() requires default_initializable<_View> = default;
-
- _LIBCPP_HIDE_FROM_ABI
- constexpr take_view(_View __base, range_difference_t<_View> __count)
- : __base_(_VSTD::move(__base)), __count_(__count) {}
-
- _LIBCPP_HIDE_FROM_ABI
- constexpr _View base() const& requires copy_constructible<_View> { return __base_; }
-
- _LIBCPP_HIDE_FROM_ABI
- constexpr _View base() && { return _VSTD::move(__base_); }
-
- _LIBCPP_HIDE_FROM_ABI
- constexpr auto begin() requires (!__simple_view<_View>) {
- if constexpr (sized_range<_View>) {
- if constexpr (random_access_range<_View>) {
- return ranges::begin(__base_);
- } else {
- using _DifferenceT = range_difference_t<_View>;
- auto __size = size();
- return counted_iterator(ranges::begin(__base_), static_cast<_DifferenceT>(__size));
- }
+
+template<view _View>
+class take_view : public view_interface<take_view<_View>> {
+ _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View();
+ range_difference_t<_View> __count_ = 0;
+
+ template<bool> class __sentinel;
+
+public:
+ _LIBCPP_HIDE_FROM_ABI
+ take_view() requires default_initializable<_View> = default;
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr take_view(_View __base, range_difference_t<_View> __count)
+ : __base_(std::move(__base)), __count_(__count) {}
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr _View base() const& requires copy_constructible<_View> { return __base_; }
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr _View base() && { return std::move(__base_); }
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr auto begin() requires (!__simple_view<_View>) {
+ if constexpr (sized_range<_View>) {
+ if constexpr (random_access_range<_View>) {
+ return ranges::begin(__base_);
} else {
- return counted_iterator(ranges::begin(__base_), __count_);
+ using _DifferenceT = range_difference_t<_View>;
+ auto __size = size();
+ return counted_iterator(ranges::begin(__base_), static_cast<_DifferenceT>(__size));
}
+ } else {
+ return counted_iterator(ranges::begin(__base_), __count_);
}
+ }
- _LIBCPP_HIDE_FROM_ABI
- constexpr auto begin() const requires range<const _View> {
- if constexpr (sized_range<const _View>) {
- if constexpr (random_access_range<const _View>) {
- return ranges::begin(__base_);
- } else {
- using _DifferenceT = range_difference_t<const _View>;
- auto __size = size();
- return counted_iterator(ranges::begin(__base_), static_cast<_DifferenceT>(__size));
- }
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr auto begin() const requires range<const _View> {
+ if constexpr (sized_range<const _View>) {
+ if constexpr (random_access_range<const _View>) {
+ return ranges::begin(__base_);
} else {
- return counted_iterator(ranges::begin(__base_), __count_);
+ using _DifferenceT = range_difference_t<const _View>;
+ auto __size = size();
+ return counted_iterator(ranges::begin(__base_), static_cast<_DifferenceT>(__size));
}
+ } else {
+ return counted_iterator(ranges::begin(__base_), __count_);
}
+ }
- _LIBCPP_HIDE_FROM_ABI
- constexpr auto end() requires (!__simple_view<_View>) {
- if constexpr (sized_range<_View>) {
- if constexpr (random_access_range<_View>) {
- return ranges::begin(__base_) + size();
- } else {
- return default_sentinel;
- }
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr auto end() requires (!__simple_view<_View>) {
+ if constexpr (sized_range<_View>) {
+ if constexpr (random_access_range<_View>) {
+ return ranges::begin(__base_) + size();
} else {
- return __sentinel<false>{ranges::end(__base_)};
+ return default_sentinel;
}
+ } else {
+ return __sentinel<false>{ranges::end(__base_)};
}
+ }
- _LIBCPP_HIDE_FROM_ABI
- constexpr auto end() const requires range<const _View> {
- if constexpr (sized_range<const _View>) {
- if constexpr (random_access_range<const _View>) {
- return ranges::begin(__base_) + size();
- } else {
- return default_sentinel;
- }
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr auto end() const requires range<const _View> {
+ if constexpr (sized_range<const _View>) {
+ if constexpr (random_access_range<const _View>) {
+ return ranges::begin(__base_) + size();
} else {
- return __sentinel<true>{ranges::end(__base_)};
+ return default_sentinel;
}
+ } else {
+ return __sentinel<true>{ranges::end(__base_)};
}
-
-
- _LIBCPP_HIDE_FROM_ABI
- constexpr auto size() requires sized_range<_View> {
- auto __n = ranges::size(__base_);
- // TODO: use ranges::min here.
- return _VSTD::min(__n, static_cast<decltype(__n)>(__count_));
- }
-
- _LIBCPP_HIDE_FROM_ABI
- constexpr auto size() const requires sized_range<const _View> {
- auto __n = ranges::size(__base_);
- // TODO: use ranges::min here.
- return _VSTD::min(__n, static_cast<decltype(__n)>(__count_));
- }
- };
-
- template<view _View>
- template<bool _Const>
- class take_view<_View>::__sentinel {
- using _Base = __maybe_const<_Const, _View>;
- template<bool _OtherConst>
- using _Iter = counted_iterator<iterator_t<__maybe_const<_OtherConst, _View>>>;
- [[no_unique_address]] sentinel_t<_Base> __end_ = sentinel_t<_Base>();
-
- template<bool>
- friend class take_view<_View>::__sentinel;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr auto size() requires sized_range<_View> {
+ auto __n = ranges::size(__base_);
+ return ranges::min(__n, static_cast<decltype(__n)>(__count_));
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr auto size() const requires sized_range<const _View> {
+ auto __n = ranges::size(__base_);
+ return ranges::min(__n, static_cast<decltype(__n)>(__count_));
+ }
+};
+
+template<view _View>
+template<bool _Const>
+class take_view<_View>::__sentinel {
+ using _Base = __maybe_const<_Const, _View>;
+ template<bool _OtherConst>
+ using _Iter = counted_iterator<iterator_t<__maybe_const<_OtherConst, _View>>>;
+ _LIBCPP_NO_UNIQUE_ADDRESS sentinel_t<_Base> __end_ = sentinel_t<_Base>();
+
+ template<bool>
+ friend class take_view<_View>::__sentinel;
public:
- _LIBCPP_HIDE_FROM_ABI
- __sentinel() = default;
-
- _LIBCPP_HIDE_FROM_ABI
- constexpr explicit __sentinel(sentinel_t<_Base> __end) : __end_(_VSTD::move(__end)) {}
-
- _LIBCPP_HIDE_FROM_ABI
- constexpr __sentinel(__sentinel<!_Const> __s)
- requires _Const && convertible_to<sentinel_t<_View>, sentinel_t<_Base>>
- : __end_(_VSTD::move(__s.__end_)) {}
-
- _LIBCPP_HIDE_FROM_ABI
- constexpr sentinel_t<_Base> base() const { return __end_; }
-
- _LIBCPP_HIDE_FROM_ABI
- friend constexpr bool operator==(const _Iter<_Const>& __lhs, const __sentinel& __rhs) {
- return __lhs.count() == 0 || __lhs.base() == __rhs.__end_;
- }
-
- template<bool _OtherConst = !_Const>
- requires sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>>
- _LIBCPP_HIDE_FROM_ABI
- friend constexpr bool operator==(const _Iter<_Const>& __lhs, const __sentinel& __rhs) {
- return __lhs.count() == 0 || __lhs.base() == __rhs.__end_;
- }
- };
-
- template<class _Range>
- take_view(_Range&&, range_difference_t<_Range>) -> take_view<views::all_t<_Range>>;
+ _LIBCPP_HIDE_FROM_ABI
+ __sentinel() = default;
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr explicit __sentinel(sentinel_t<_Base> __end) : __end_(std::move(__end)) {}
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr __sentinel(__sentinel<!_Const> __s)
+ requires _Const && convertible_to<sentinel_t<_View>, sentinel_t<_Base>>
+ : __end_(std::move(__s.__end_)) {}
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr sentinel_t<_Base> base() const { return __end_; }
+
+ _LIBCPP_HIDE_FROM_ABI
+ friend constexpr bool operator==(const _Iter<_Const>& __lhs, const __sentinel& __rhs) {
+ return __lhs.count() == 0 || __lhs.base() == __rhs.__end_;
+ }
+
+ template<bool _OtherConst = !_Const>
+ requires sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>>
+ _LIBCPP_HIDE_FROM_ABI
+ friend constexpr bool operator==(const _Iter<_Const>& __lhs, const __sentinel& __rhs) {
+ return __lhs.count() == 0 || __lhs.base() == __rhs.__end_;
+ }
+};
+
+template<class _Range>
+take_view(_Range&&, range_difference_t<_Range>) -> take_view<views::all_t<_Range>>;
+
+template<class _Tp>
+inline constexpr bool enable_borrowed_range<take_view<_Tp>> = enable_borrowed_range<_Tp>;
+
+namespace views {
+namespace __take {
+
+template <class _Tp>
+inline constexpr bool __is_empty_view = false;
+
+template <class _Tp>
+inline constexpr bool __is_empty_view<empty_view<_Tp>> = true;
+
+template <class _Tp>
+inline constexpr bool __is_passthrough_specialization = false;
+
+template <class _Tp, size_t _Extent>
+inline constexpr bool __is_passthrough_specialization<span<_Tp, _Extent>> = true;
+
+template <class _CharT, class _Traits>
+inline constexpr bool __is_passthrough_specialization<basic_string_view<_CharT, _Traits>> = true;
+
+template <class _Iter, class _Sent, subrange_kind _Kind>
+inline constexpr bool __is_passthrough_specialization<subrange<_Iter, _Sent, _Kind>> = true;
+
+template <class _Tp>
+inline constexpr bool __is_iota_specialization = false;
+
+template <class _Np, class _Bound>
+inline constexpr bool __is_iota_specialization<iota_view<_Np, _Bound>> = true;
+
+template <class _Tp>
+struct __passthrough_type;
+
+template <class _Tp, size_t _Extent>
+struct __passthrough_type<span<_Tp, _Extent>> {
+ using type = span<_Tp>;
+};
+
+template <class _CharT, class _Traits>
+struct __passthrough_type<basic_string_view<_CharT, _Traits>> {
+ using type = basic_string_view<_CharT, _Traits>;
+};
+
+template <class _Iter, class _Sent, subrange_kind _Kind>
+struct __passthrough_type<subrange<_Iter, _Sent, _Kind>> {
+ using type = subrange<_Iter>;
+};
+
+template <class _Tp>
+using __passthrough_type_t = typename __passthrough_type<_Tp>::type;
+
+struct __fn {
+ // [range.take.overview]: the `empty_view` case.
+ template <class _Range, convertible_to<range_difference_t<_Range>> _Np>
+ requires __is_empty_view<remove_cvref_t<_Range>>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI
+ constexpr auto operator()(_Range&& __range, _Np&&) const
+ noexcept(noexcept(_LIBCPP_AUTO_CAST(std::forward<_Range>(__range))))
+ -> decltype( _LIBCPP_AUTO_CAST(std::forward<_Range>(__range)))
+ { return _LIBCPP_AUTO_CAST(std::forward<_Range>(__range)); }
+
+ // [range.take.overview]: the `span | basic_string_view | subrange` case.
+ template <class _Range,
+ convertible_to<range_difference_t<_Range>> _Np,
+ class _RawRange = remove_cvref_t<_Range>,
+ class _Dist = range_difference_t<_Range>>
+ requires (!__is_empty_view<_RawRange> &&
+ random_access_range<_RawRange> &&
+ sized_range<_RawRange> &&
+ __is_passthrough_specialization<_RawRange>)
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI
+ constexpr auto operator()(_Range&& __rng, _Np&& __n) const
+ noexcept(noexcept(__passthrough_type_t<_RawRange>(
+ ranges::begin(__rng),
+ ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n))
+ )))
+ -> decltype( __passthrough_type_t<_RawRange>(
+ // Note: deliberately not forwarding `__rng` to guard against double moves.
+ ranges::begin(__rng),
+ ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n))
+ ))
+ { return __passthrough_type_t<_RawRange>(
+ ranges::begin(__rng),
+ ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n))
+ ); }
+
+ // [range.take.overview]: the `iota_view` case.
+ template <class _Range,
+ convertible_to<range_difference_t<_Range>> _Np,
+ class _RawRange = remove_cvref_t<_Range>,
+ class _Dist = range_difference_t<_Range>>
+ requires (!__is_empty_view<_RawRange> &&
+ random_access_range<_RawRange> &&
+ sized_range<_RawRange> &&
+ __is_iota_specialization<_RawRange>)
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI
+ constexpr auto operator()(_Range&& __rng, _Np&& __n) const
+ noexcept(noexcept(ranges::iota_view(
+ *ranges::begin(__rng),
+ *ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n))
+ )))
+ -> decltype( ranges::iota_view(
+ // Note: deliberately not forwarding `__rng` to guard against double moves.
+ *ranges::begin(__rng),
+ *ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n))
+ ))
+ { return ranges::iota_view(
+ *ranges::begin(__rng),
+ *ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n))
+ ); }
+
+ // [range.take.overview]: the "otherwise" case.
+ template <class _Range, convertible_to<range_difference_t<_Range>> _Np,
+ class _RawRange = remove_cvref_t<_Range>>
+ // Note: without specifically excluding the other cases, GCC sees this overload as ambiguous with the other
+ // overloads.
+ requires (!(__is_empty_view<_RawRange> ||
+ (__is_iota_specialization<_RawRange> &&
+ sized_range<_RawRange> &&
+ random_access_range<_RawRange>) ||
+ (__is_passthrough_specialization<_RawRange> &&
+ sized_range<_RawRange> &&
+ random_access_range<_RawRange>)
+ ))
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI
+ constexpr auto operator()(_Range&& __range, _Np&& __n) const
+ noexcept(noexcept(take_view(std::forward<_Range>(__range), std::forward<_Np>(__n))))
+ -> decltype( take_view(std::forward<_Range>(__range), std::forward<_Np>(__n)))
+ { return take_view(std::forward<_Range>(__range), std::forward<_Np>(__n)); }
+
+ template <class _Np>
+ requires constructible_from<decay_t<_Np>, _Np>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI
+ constexpr auto operator()(_Np&& __n) const
+ noexcept(is_nothrow_constructible_v<decay_t<_Np>, _Np>)
+ { return __range_adaptor_closure_t(std::__bind_back(*this, std::forward<_Np>(__n))); }
+};
+
+} // namespace __take
+
+inline namespace __cpo {
+ inline constexpr auto take = __take::__fn{};
+} // namespace __cpo
+} // namespace views
- template<class _Tp>
- inline constexpr bool enable_borrowed_range<take_view<_Tp>> = enable_borrowed_range<_Tp>;
} // namespace ranges
-#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__ranges/transform_view.h b/libcxx/include/__ranges/transform_view.h
index d39dd4097290..c5a7128c366b 100644
--- a/libcxx/include/__ranges/transform_view.h
+++ b/libcxx/include/__ranges/transform_view.h
@@ -36,12 +36,12 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
namespace ranges {
@@ -53,7 +53,7 @@ template<class _View, class _Fn>
concept __transform_view_constraints =
view<_View> && is_object_v<_Fn> &&
regular_invocable<_Fn&, range_reference_t<_View>> &&
- __referenceable<invoke_result_t<_Fn&, range_reference_t<_View>>>;
+ __can_reference<invoke_result_t<_Fn&, range_reference_t<_View>>>;
template<input_range _View, copy_constructible _Fn>
requires __transform_view_constraints<_View, _Fn>
@@ -61,8 +61,8 @@ class transform_view : public view_interface<transform_view<_View, _Fn>> {
template<bool> class __iterator;
template<bool> class __sentinel;
- [[no_unique_address]] __copyable_box<_Fn> __func_;
- [[no_unique_address]] _View __base_ = _View();
+ _LIBCPP_NO_UNIQUE_ADDRESS __copyable_box<_Fn> __func_;
+ _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View();
public:
_LIBCPP_HIDE_FROM_ABI
@@ -71,12 +71,12 @@ public:
_LIBCPP_HIDE_FROM_ABI
constexpr transform_view(_View __base, _Fn __func)
- : __func_(_VSTD::in_place, _VSTD::move(__func)), __base_(_VSTD::move(__base)) {}
+ : __func_(std::in_place, std::move(__func)), __base_(std::move(__base)) {}
_LIBCPP_HIDE_FROM_ABI
constexpr _View base() const& requires copy_constructible<_View> { return __base_; }
_LIBCPP_HIDE_FROM_ABI
- constexpr _View base() && { return _VSTD::move(__base_); }
+ constexpr _View base() && { return std::move(__base_); }
_LIBCPP_HIDE_FROM_ABI
constexpr __iterator<false> begin() {
@@ -183,7 +183,7 @@ public:
_LIBCPP_HIDE_FROM_ABI
constexpr __iterator(_Parent& __parent, iterator_t<_Base> __current)
- : __parent_(_VSTD::addressof(__parent)), __current_(_VSTD::move(__current)) {}
+ : __parent_(std::addressof(__parent)), __current_(std::move(__current)) {}
// Note: `__i` should always be `__iterator<false>`, but directly using
// `__iterator<false>` is ill-formed when `_Const` is false
@@ -191,7 +191,7 @@ public:
_LIBCPP_HIDE_FROM_ABI
constexpr __iterator(__iterator<!_Const> __i)
requires _Const && convertible_to<iterator_t<_View>, iterator_t<_Base>>
- : __parent_(__i.__parent_), __current_(_VSTD::move(__i.__current_)) {}
+ : __parent_(__i.__parent_), __current_(std::move(__i.__current_)) {}
_LIBCPP_HIDE_FROM_ABI
constexpr const iterator_t<_Base>& base() const& noexcept {
@@ -200,14 +200,14 @@ public:
_LIBCPP_HIDE_FROM_ABI
constexpr iterator_t<_Base> base() && {
- return _VSTD::move(__current_);
+ return std::move(__current_);
}
_LIBCPP_HIDE_FROM_ABI
constexpr decltype(auto) operator*() const
- noexcept(noexcept(_VSTD::invoke(*__parent_->__func_, *__current_)))
+ noexcept(noexcept(std::invoke(*__parent_->__func_, *__current_)))
{
- return _VSTD::invoke(*__parent_->__func_, *__current_);
+ return std::invoke(*__parent_->__func_, *__current_);
}
_LIBCPP_HIDE_FROM_ABI
@@ -263,10 +263,10 @@ public:
_LIBCPP_HIDE_FROM_ABI
constexpr decltype(auto) operator[](difference_type __n) const
- noexcept(noexcept(_VSTD::invoke(*__parent_->__func_, __current_[__n])))
+ noexcept(noexcept(std::invoke(*__parent_->__func_, __current_[__n])))
requires random_access_range<_Base>
{
- return _VSTD::invoke(*__parent_->__func_, __current_[__n]);
+ return std::invoke(*__parent_->__func_, __current_[__n]);
}
_LIBCPP_HIDE_FROM_ABI
@@ -344,7 +344,7 @@ public:
noexcept(noexcept(*__i))
{
if constexpr (is_lvalue_reference_v<decltype(*__i)>)
- return _VSTD::move(*__i);
+ return std::move(*__i);
else
return *__i;
}
@@ -378,7 +378,7 @@ public:
_LIBCPP_HIDE_FROM_ABI
constexpr __sentinel(__sentinel<!_Const> __i)
requires _Const && convertible_to<sentinel_t<_View>, sentinel_t<_Base>>
- : __end_(_VSTD::move(__i.__end_)) {}
+ : __end_(std::move(__i.__end_)) {}
_LIBCPP_HIDE_FROM_ABI
constexpr sentinel_t<_Base> base() const { return __end_; }
@@ -413,16 +413,16 @@ namespace __transform {
template<class _Range, class _Fn>
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI
constexpr auto operator()(_Range&& __range, _Fn&& __f) const
- noexcept(noexcept(transform_view(_VSTD::forward<_Range>(__range), _VSTD::forward<_Fn>(__f))))
- -> decltype( transform_view(_VSTD::forward<_Range>(__range), _VSTD::forward<_Fn>(__f)))
- { return transform_view(_VSTD::forward<_Range>(__range), _VSTD::forward<_Fn>(__f)); }
+ noexcept(noexcept(transform_view(std::forward<_Range>(__range), std::forward<_Fn>(__f))))
+ -> decltype( transform_view(std::forward<_Range>(__range), std::forward<_Fn>(__f)))
+ { return transform_view(std::forward<_Range>(__range), std::forward<_Fn>(__f)); }
template<class _Fn>
requires constructible_from<decay_t<_Fn>, _Fn>
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI
constexpr auto operator()(_Fn&& __f) const
noexcept(is_nothrow_constructible_v<decay_t<_Fn>, _Fn>)
- { return __range_adaptor_closure_t(_VSTD::__bind_back(*this, _VSTD::forward<_Fn>(__f))); }
+ { return __range_adaptor_closure_t(std::__bind_back(*this, std::forward<_Fn>(__f))); }
};
} // namespace __transform
@@ -433,7 +433,7 @@ inline namespace __cpo {
} // namespace ranges
-#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__ranges/view_interface.h b/libcxx/include/__ranges/view_interface.h
index 0a37323df817..4b36e02f7d6b 100644
--- a/libcxx/include/__ranges/view_interface.h
+++ b/libcxx/include/__ranges/view_interface.h
@@ -9,8 +9,10 @@
#ifndef _LIBCPP___RANGES_VIEW_INTERFACE_H
#define _LIBCPP___RANGES_VIEW_INTERFACE_H
+#include <__assert>
+#include <__concepts/derived_from.h>
+#include <__concepts/same_as.h>
#include <__config>
-#include <__debug>
#include <__iterator/concepts.h>
#include <__iterator/iterator_traits.h>
#include <__iterator/prev.h>
@@ -18,25 +20,18 @@
#include <__ranges/access.h>
#include <__ranges/concepts.h>
#include <__ranges/empty.h>
-#include <concepts>
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
namespace ranges {
-template<class _Tp>
-concept __can_empty = requires(_Tp __t) { ranges::empty(__t); };
-
-template<class _Tp>
-void __implicitly_convert_to(type_identity_t<_Tp>) noexcept;
-
template<class _Derived>
requires is_class_v<_Derived> && same_as<_Derived, remove_cv_t<_Derived>>
class view_interface {
@@ -55,7 +50,6 @@ class view_interface {
public:
template<class _D2 = _Derived>
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty()
- noexcept(noexcept(__implicitly_convert_to<bool>(ranges::begin(__derived()) == ranges::end(__derived()))))
requires forward_range<_D2>
{
return ranges::begin(__derived()) == ranges::end(__derived());
@@ -63,7 +57,6 @@ public:
template<class _D2 = _Derived>
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty() const
- noexcept(noexcept(__implicitly_convert_to<bool>(ranges::begin(__derived()) == ranges::end(__derived()))))
requires forward_range<const _D2>
{
return ranges::begin(__derived()) == ranges::end(__derived());
@@ -72,8 +65,7 @@ public:
template<class _D2 = _Derived>
_LIBCPP_HIDE_FROM_ABI
constexpr explicit operator bool()
- noexcept(noexcept(ranges::empty(declval<_D2>())))
- requires __can_empty<_D2>
+ requires requires (_D2& __t) { ranges::empty(__t); }
{
return !ranges::empty(__derived());
}
@@ -81,8 +73,7 @@ public:
template<class _D2 = _Derived>
_LIBCPP_HIDE_FROM_ABI
constexpr explicit operator bool() const
- noexcept(noexcept(ranges::empty(declval<const _D2>())))
- requires __can_empty<const _D2>
+ requires requires (const _D2& __t) { ranges::empty(__t); }
{
return !ranges::empty(__derived());
}
@@ -90,27 +81,23 @@ public:
template<class _D2 = _Derived>
_LIBCPP_HIDE_FROM_ABI
constexpr auto data()
- noexcept(noexcept(_VSTD::to_address(ranges::begin(__derived()))))
requires contiguous_iterator<iterator_t<_D2>>
{
- return _VSTD::to_address(ranges::begin(__derived()));
+ return std::to_address(ranges::begin(__derived()));
}
template<class _D2 = _Derived>
_LIBCPP_HIDE_FROM_ABI
constexpr auto data() const
- noexcept(noexcept(_VSTD::to_address(ranges::begin(__derived()))))
requires range<const _D2> && contiguous_iterator<iterator_t<const _D2>>
{
- return _VSTD::to_address(ranges::begin(__derived()));
+ return std::to_address(ranges::begin(__derived()));
}
template<class _D2 = _Derived>
_LIBCPP_HIDE_FROM_ABI
constexpr auto size()
- noexcept(noexcept(ranges::end(__derived()) - ranges::begin(__derived())))
- requires forward_range<_D2>
- && sized_sentinel_for<sentinel_t<_D2>, iterator_t<_D2>>
+ requires forward_range<_D2> && sized_sentinel_for<sentinel_t<_D2>, iterator_t<_D2>>
{
return ranges::end(__derived()) - ranges::begin(__derived());
}
@@ -118,9 +105,7 @@ public:
template<class _D2 = _Derived>
_LIBCPP_HIDE_FROM_ABI
constexpr auto size() const
- noexcept(noexcept(ranges::end(__derived()) - ranges::begin(__derived())))
- requires forward_range<const _D2>
- && sized_sentinel_for<sentinel_t<const _D2>, iterator_t<const _D2>>
+ requires forward_range<const _D2> && sized_sentinel_for<sentinel_t<const _D2>, iterator_t<const _D2>>
{
return ranges::end(__derived()) - ranges::begin(__derived());
}
@@ -128,7 +113,6 @@ public:
template<class _D2 = _Derived>
_LIBCPP_HIDE_FROM_ABI
constexpr decltype(auto) front()
- noexcept(noexcept(*ranges::begin(__derived())))
requires forward_range<_D2>
{
_LIBCPP_ASSERT(!empty(),
@@ -139,7 +123,6 @@ public:
template<class _D2 = _Derived>
_LIBCPP_HIDE_FROM_ABI
constexpr decltype(auto) front() const
- noexcept(noexcept(*ranges::begin(__derived())))
requires forward_range<const _D2>
{
_LIBCPP_ASSERT(!empty(),
@@ -150,7 +133,6 @@ public:
template<class _D2 = _Derived>
_LIBCPP_HIDE_FROM_ABI
constexpr decltype(auto) back()
- noexcept(noexcept(*ranges::prev(ranges::end(__derived()))))
requires bidirectional_range<_D2> && common_range<_D2>
{
_LIBCPP_ASSERT(!empty(),
@@ -161,7 +143,6 @@ public:
template<class _D2 = _Derived>
_LIBCPP_HIDE_FROM_ABI
constexpr decltype(auto) back() const
- noexcept(noexcept(*ranges::prev(ranges::end(__derived()))))
requires bidirectional_range<const _D2> && common_range<const _D2>
{
_LIBCPP_ASSERT(!empty(),
@@ -172,7 +153,6 @@ public:
template<random_access_range _RARange = _Derived>
_LIBCPP_HIDE_FROM_ABI
constexpr decltype(auto) operator[](range_difference_t<_RARange> __index)
- noexcept(noexcept(ranges::begin(__derived())[__index]))
{
return ranges::begin(__derived())[__index];
}
@@ -180,7 +160,6 @@ public:
template<random_access_range _RARange = const _Derived>
_LIBCPP_HIDE_FROM_ABI
constexpr decltype(auto) operator[](range_difference_t<_RARange> __index) const
- noexcept(noexcept(ranges::begin(__derived())[__index]))
{
return ranges::begin(__derived())[__index];
}
@@ -188,7 +167,7 @@ public:
} // namespace ranges
-#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__ranges/views.h b/libcxx/include/__ranges/views.h
new file mode 100644
index 000000000000..8cc5ba3d2aca
--- /dev/null
+++ b/libcxx/include/__ranges/views.h
@@ -0,0 +1,35 @@
+// -*- 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___RANGES_VIEWS
+#define _LIBCPP___RANGES_VIEWS
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+namespace ranges {
+
+namespace views { }
+
+} // namespace ranges
+
+namespace views = ranges::views;
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___RANGES_VIEWS
diff --git a/libcxx/include/__ranges/zip_view.h b/libcxx/include/__ranges/zip_view.h
new file mode 100644
index 000000000000..560452aa7c69
--- /dev/null
+++ b/libcxx/include/__ranges/zip_view.h
@@ -0,0 +1,511 @@
+// -*- 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___RANGES_ZIP_VIEW_H
+#define _LIBCPP___RANGES_ZIP_VIEW_H
+
+#include <__config>
+
+#include <__algorithm/ranges_min.h>
+#include <__compare/three_way_comparable.h>
+#include <__concepts/convertible_to.h>
+#include <__concepts/equality_comparable.h>
+#include <__functional/invoke.h>
+#include <__functional/operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/incrementable_traits.h>
+#include <__iterator/iter_move.h>
+#include <__iterator/iter_swap.h>
+#include <__iterator/iterator_traits.h>
+#include <__ranges/access.h>
+#include <__ranges/all.h>
+#include <__ranges/concepts.h>
+#include <__ranges/empty_view.h>
+#include <__ranges/enable_borrowed_range.h>
+#include <__ranges/size.h>
+#include <__ranges/view_interface.h>
+#include <__utility/forward.h>
+#include <__utility/integer_sequence.h>
+#include <__utility/move.h>
+#include <tuple>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 20 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+namespace ranges {
+
+template <class... _Ranges>
+concept __zip_is_common = (sizeof...(_Ranges) == 1 && (common_range<_Ranges> && ...)) ||
+ (!(bidirectional_range<_Ranges> && ...) && (common_range<_Ranges> && ...)) ||
+ ((random_access_range<_Ranges> && ...) && (sized_range<_Ranges> && ...));
+
+template <typename _Tp, typename _Up>
+auto __tuple_or_pair_test() -> pair<_Tp, _Up>;
+
+template <typename... _Types>
+ requires(sizeof...(_Types) != 2)
+auto __tuple_or_pair_test() -> tuple<_Types...>;
+
+template <class... _Types>
+using __tuple_or_pair = decltype(__tuple_or_pair_test<_Types...>());
+
+template <class _Fun, class _Tuple>
+_LIBCPP_HIDE_FROM_ABI constexpr auto __tuple_transform(_Fun&& __f, _Tuple&& __tuple) {
+ return std::apply(
+ [&]<class... _Types>(_Types&&... __elements) {
+ return __tuple_or_pair<invoke_result_t<_Fun&, _Types>...>(
+ std::invoke(__f, std::forward<_Types>(__elements))...);
+ },
+ std::forward<_Tuple>(__tuple));
+}
+
+template <class _Fun, class _Tuple>
+_LIBCPP_HIDE_FROM_ABI constexpr void __tuple_for_each(_Fun&& __f, _Tuple&& __tuple) {
+ std::apply(
+ [&]<class... _Types>(_Types&&... __elements) { (std::invoke(__f, std::forward<_Types>(__elements)), ...); },
+ std::forward<_Tuple>(__tuple));
+}
+
+template <class _Fun, class _Tuple1, class _Tuple2, size_t... _Indices>
+_LIBCPP_HIDE_FROM_ABI constexpr __tuple_or_pair<
+ invoke_result_t<_Fun&, typename tuple_element<_Indices, remove_cvref_t<_Tuple1>>::type,
+ typename tuple_element<_Indices, remove_cvref_t<_Tuple2>>::type>...>
+__tuple_zip_transform(_Fun&& __f, _Tuple1&& __tuple1, _Tuple2&& __tuple2, index_sequence<_Indices...>) {
+ return {std::invoke(__f, std::get<_Indices>(std::forward<_Tuple1>(__tuple1)),
+ std::get<_Indices>(std::forward<_Tuple2>(__tuple2)))...};
+}
+
+template <class _Fun, class _Tuple1, class _Tuple2>
+_LIBCPP_HIDE_FROM_ABI constexpr auto __tuple_zip_transform(_Fun&& __f, _Tuple1&& __tuple1, _Tuple2&& __tuple2) {
+ return ranges::__tuple_zip_transform(__f, std::forward<_Tuple1>(__tuple1), std::forward<_Tuple2>(__tuple2),
+ std::make_index_sequence<tuple_size<remove_cvref_t<_Tuple1>>::value>());
+}
+
+template <class _Fun, class _Tuple1, class _Tuple2, size_t... _Indices>
+_LIBCPP_HIDE_FROM_ABI constexpr void __tuple_zip_for_each(_Fun&& __f, _Tuple1&& __tuple1, _Tuple2&& __tuple2,
+ index_sequence<_Indices...>) {
+ (std::invoke(__f, std::get<_Indices>(std::forward<_Tuple1>(__tuple1)),
+ std::get<_Indices>(std::forward<_Tuple2>(__tuple2))),
+ ...);
+}
+
+template <class _Fun, class _Tuple1, class _Tuple2>
+_LIBCPP_HIDE_FROM_ABI constexpr auto __tuple_zip_for_each(_Fun&& __f, _Tuple1&& __tuple1, _Tuple2&& __tuple2) {
+ return ranges::__tuple_zip_for_each(__f, std::forward<_Tuple1>(__tuple1), std::forward<_Tuple2>(__tuple2),
+ std::make_index_sequence<tuple_size<remove_cvref_t<_Tuple1>>::value>());
+}
+
+template <class _Tuple1, class _Tuple2>
+_LIBCPP_HIDE_FROM_ABI constexpr bool __tuple_any_equals(const _Tuple1& __tuple1, const _Tuple2& __tuple2) {
+ const auto __equals = ranges::__tuple_zip_transform(std::equal_to<>(), __tuple1, __tuple2);
+ return std::apply([](auto... __bools) { return (__bools || ...); }, __equals);
+}
+
+// abs in cstdlib is not constexpr
+// TODO : remove __abs once P0533R9 is implemented.
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI constexpr _Tp __abs(_Tp __t) {
+ return __t < 0 ? -__t : __t;
+}
+
+template <input_range... _Views>
+ requires(view<_Views> && ...) && (sizeof...(_Views) > 0)
+class zip_view : public view_interface<zip_view<_Views...>> {
+
+ _LIBCPP_NO_UNIQUE_ADDRESS tuple<_Views...> __views_;
+
+ template <bool>
+ class __iterator;
+
+ template <bool>
+ class __sentinel;
+
+public:
+ _LIBCPP_HIDE_FROM_ABI
+ zip_view() = default;
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr explicit zip_view(_Views... __views) : __views_(std::move(__views)...) {}
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr auto begin()
+ requires(!(__simple_view<_Views> && ...)) {
+ return __iterator<false>(ranges::__tuple_transform(ranges::begin, __views_));
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr auto begin() const
+ requires(range<const _Views> && ...) {
+ return __iterator<true>(ranges::__tuple_transform(ranges::begin, __views_));
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr auto end()
+ requires(!(__simple_view<_Views> && ...)) {
+ if constexpr (!__zip_is_common<_Views...>) {
+ return __sentinel<false>(ranges::__tuple_transform(ranges::end, __views_));
+ } else if constexpr ((random_access_range<_Views> && ...)) {
+ return begin() + iter_difference_t<__iterator<false>>(size());
+ } else {
+ return __iterator<false>(ranges::__tuple_transform(ranges::end, __views_));
+ }
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr auto end() const
+ requires(range<const _Views> && ...) {
+ if constexpr (!__zip_is_common<const _Views...>) {
+ return __sentinel<true>(ranges::__tuple_transform(ranges::end, __views_));
+ } else if constexpr ((random_access_range<const _Views> && ...)) {
+ return begin() + iter_difference_t<__iterator<true>>(size());
+ } else {
+ return __iterator<true>(ranges::__tuple_transform(ranges::end, __views_));
+ }
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr auto size()
+ requires(sized_range<_Views> && ...) {
+ return std::apply(
+ [](auto... __sizes) {
+ using _CT = make_unsigned_t<common_type_t<decltype(__sizes)...>>;
+ return ranges::min({_CT(__sizes)...});
+ },
+ ranges::__tuple_transform(ranges::size, __views_));
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr auto size() const
+ requires(sized_range<const _Views> && ...) {
+ return std::apply(
+ [](auto... __sizes) {
+ using _CT = make_unsigned_t<common_type_t<decltype(__sizes)...>>;
+ return ranges::min({_CT(__sizes)...});
+ },
+ ranges::__tuple_transform(ranges::size, __views_));
+ }
+};
+
+template <class... _Ranges>
+zip_view(_Ranges&&...) -> zip_view<views::all_t<_Ranges>...>;
+
+template <bool _Const, class... _Views>
+concept __zip_all_random_access = (random_access_range<__maybe_const<_Const, _Views>> && ...);
+
+template <bool _Const, class... _Views>
+concept __zip_all_bidirectional = (bidirectional_range<__maybe_const<_Const, _Views>> && ...);
+
+template <bool _Const, class... _Views>
+concept __zip_all_forward = (forward_range<__maybe_const<_Const, _Views>> && ...);
+
+template <bool _Const, class... _Views>
+consteval auto __get_zip_view_iterator_tag() {
+ if constexpr (__zip_all_random_access<_Const, _Views...>) {
+ return random_access_iterator_tag();
+ } else if constexpr (__zip_all_bidirectional<_Const, _Views...>) {
+ return bidirectional_iterator_tag();
+ } else if constexpr (__zip_all_forward<_Const, _Views...>) {
+ return forward_iterator_tag();
+ } else {
+ return input_iterator_tag();
+ }
+}
+
+template <bool _Const, class... _Views>
+struct __zip_view_iterator_category_base {};
+
+template <bool _Const, class... _Views>
+ requires __zip_all_forward<_Const, _Views...>
+struct __zip_view_iterator_category_base<_Const, _Views...> {
+ using iterator_category = input_iterator_tag;
+};
+
+template <input_range... _Views>
+ requires(view<_Views> && ...) && (sizeof...(_Views) > 0)
+template <bool _Const>
+class zip_view<_Views...>::__iterator : public __zip_view_iterator_category_base<_Const, _Views...> {
+
+ __tuple_or_pair<iterator_t<__maybe_const<_Const, _Views>>...> __current_;
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr explicit __iterator(__tuple_or_pair<iterator_t<__maybe_const<_Const, _Views>>...> __current)
+ : __current_(std::move(__current)) {}
+
+ template <bool>
+ friend class zip_view<_Views...>::__iterator;
+
+ template <bool>
+ friend class zip_view<_Views...>::__sentinel;
+
+ friend class zip_view<_Views...>;
+
+public:
+ using iterator_concept = decltype(__get_zip_view_iterator_tag<_Const, _Views...>());
+ using value_type = __tuple_or_pair<range_value_t<__maybe_const<_Const, _Views>>...>;
+ using difference_type = common_type_t<range_difference_t<__maybe_const<_Const, _Views>>...>;
+
+ _LIBCPP_HIDE_FROM_ABI
+ __iterator() = default;
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr __iterator(__iterator<!_Const> __i)
+ requires _Const && (convertible_to<iterator_t<_Views>, iterator_t<__maybe_const<_Const, _Views>>> && ...)
+ : __current_(std::move(__i.__current_)) {}
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr auto operator*() const {
+ return ranges::__tuple_transform([](auto& __i) -> decltype(auto) { return *__i; }, __current_);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr __iterator& operator++() {
+ ranges::__tuple_for_each([](auto& __i) { ++__i; }, __current_);
+ return *this;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr void operator++(int) { ++*this; }
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr __iterator operator++(int)
+ requires __zip_all_forward<_Const, _Views...> {
+ auto __tmp = *this;
+ ++*this;
+ return __tmp;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr __iterator& operator--()
+ requires __zip_all_bidirectional<_Const, _Views...> {
+ ranges::__tuple_for_each([](auto& __i) { --__i; }, __current_);
+ return *this;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr __iterator operator--(int)
+ requires __zip_all_bidirectional<_Const, _Views...> {
+ auto __tmp = *this;
+ --*this;
+ return __tmp;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr __iterator& operator+=(difference_type __x)
+ requires __zip_all_random_access<_Const, _Views...> {
+ ranges::__tuple_for_each([&]<class _Iter>(_Iter& __i) { __i += iter_difference_t<_Iter>(__x); }, __current_);
+ return *this;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr __iterator& operator-=(difference_type __x)
+ requires __zip_all_random_access<_Const, _Views...> {
+ ranges::__tuple_for_each([&]<class _Iter>(_Iter& __i) { __i -= iter_difference_t<_Iter>(__x); }, __current_);
+ return *this;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr auto operator[](difference_type __n) const
+ requires __zip_all_random_access<_Const, _Views...> {
+ return ranges::__tuple_transform(
+ [&]<class _Iter>(_Iter& __i) -> decltype(auto) { return __i[iter_difference_t<_Iter>(__n)]; }, __current_);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ friend constexpr bool operator==(const __iterator& __x, const __iterator& __y)
+ requires(equality_comparable<iterator_t<__maybe_const<_Const, _Views>>> && ...) {
+ if constexpr (__zip_all_bidirectional<_Const, _Views...>) {
+ return __x.__current_ == __y.__current_;
+ } else {
+ return ranges::__tuple_any_equals(__x.__current_, __y.__current_);
+ }
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ friend constexpr bool operator<(const __iterator& __x, const __iterator& __y)
+ requires __zip_all_random_access<_Const, _Views...> {
+ return __x.__current_ < __y.__current_;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ friend constexpr bool operator>(const __iterator& __x, const __iterator& __y)
+ requires __zip_all_random_access<_Const, _Views...> {
+ return __y < __x;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ friend constexpr bool operator<=(const __iterator& __x, const __iterator& __y)
+ requires __zip_all_random_access<_Const, _Views...> {
+ return !(__y < __x);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ friend constexpr bool operator>=(const __iterator& __x, const __iterator& __y)
+ requires __zip_all_random_access<_Const, _Views...> {
+ return !(__x < __y);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ friend constexpr auto operator<=>(const __iterator& __x, const __iterator& __y)
+ requires __zip_all_random_access<_Const, _Views...> &&
+ (three_way_comparable<iterator_t<__maybe_const<_Const, _Views>>> && ...) {
+ return __x.__current_ <=> __y.__current_;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ friend constexpr __iterator operator+(const __iterator& __i, difference_type __n)
+ requires __zip_all_random_access<_Const, _Views...> {
+ auto __r = __i;
+ __r += __n;
+ return __r;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ friend constexpr __iterator operator+(difference_type __n, const __iterator& __i)
+ requires __zip_all_random_access<_Const, _Views...> {
+ return __i + __n;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ friend constexpr __iterator operator-(const __iterator& __i, difference_type __n)
+ requires __zip_all_random_access<_Const, _Views...> {
+ auto __r = __i;
+ __r -= __n;
+ return __r;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ friend constexpr difference_type operator-(const __iterator& __x, const __iterator& __y)
+ requires(sized_sentinel_for<iterator_t<__maybe_const<_Const, _Views>>, iterator_t<__maybe_const<_Const, _Views>>> &&
+ ...) {
+ const auto __diffs = ranges::__tuple_zip_transform(minus<>(), __x.__current_, __y.__current_);
+ return std::apply(
+ [](auto... __ds) {
+ return ranges::min({difference_type(__ds)...},
+ [](auto __a, auto __b) { return ranges::__abs(__a) < ranges::__abs(__b); });
+ },
+ __diffs);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ friend constexpr auto iter_move(const __iterator& __i) noexcept(
+ (noexcept(ranges::iter_move(declval<const iterator_t<__maybe_const<_Const, _Views>>&>())) && ...) &&
+ (is_nothrow_move_constructible_v<range_rvalue_reference_t<__maybe_const<_Const, _Views>>> && ...)) {
+ return ranges::__tuple_transform(ranges::iter_move, __i.__current_);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ friend constexpr void iter_swap(const __iterator& __l, const __iterator& __r) noexcept(
+ (noexcept(ranges::iter_swap(declval<const iterator_t<__maybe_const<_Const, _Views>>&>(),
+ declval<const iterator_t<__maybe_const<_Const, _Views>>&>())) &&
+ ...))
+ requires(indirectly_swappable<iterator_t<__maybe_const<_Const, _Views>>> && ...) {
+ ranges::__tuple_zip_for_each(ranges::iter_swap, __l.__current_, __r.__current_);
+ }
+};
+
+template <input_range... _Views>
+ requires(view<_Views> && ...) && (sizeof...(_Views) > 0)
+template <bool _Const>
+class zip_view<_Views...>::__sentinel {
+
+ __tuple_or_pair<sentinel_t<__maybe_const<_Const, _Views>>...> __end_;
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr explicit __sentinel(__tuple_or_pair<sentinel_t<__maybe_const<_Const, _Views>>...> __end) : __end_(__end) {}
+
+ friend class zip_view<_Views...>;
+
+ // hidden friend cannot access private member of iterator because they are friends of friends
+ template <bool _OtherConst>
+ _LIBCPP_HIDE_FROM_ABI static constexpr decltype(auto)
+ __iter_current(zip_view<_Views...>::__iterator<_OtherConst> const& __it) {
+ return (__it.__current_);
+ }
+
+public:
+ _LIBCPP_HIDE_FROM_ABI
+ __sentinel() = default;
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr __sentinel(__sentinel<!_Const> __i)
+ requires _Const && (convertible_to<sentinel_t<_Views>, sentinel_t<__maybe_const<_Const, _Views>>> && ...)
+ : __end_(std::move(__i.__end_)) {}
+
+ template <bool _OtherConst>
+ requires(sentinel_for<sentinel_t<__maybe_const<_Const, _Views>>, iterator_t<__maybe_const<_OtherConst, _Views>>> &&
+ ...)
+ _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator<_OtherConst>& __x, const __sentinel& __y) {
+ return ranges::__tuple_any_equals(__iter_current(__x), __y.__end_);
+ }
+
+ template <bool _OtherConst>
+ requires(
+ sized_sentinel_for<sentinel_t<__maybe_const<_Const, _Views>>, iterator_t<__maybe_const<_OtherConst, _Views>>> &&
+ ...)
+ _LIBCPP_HIDE_FROM_ABI friend constexpr common_type_t<range_difference_t<__maybe_const<_OtherConst, _Views>>...>
+ operator-(const __iterator<_OtherConst>& __x, const __sentinel& __y) {
+ const auto __diffs = ranges::__tuple_zip_transform(minus<>(), __iter_current(__x), __y.__end_);
+ return std::apply(
+ [](auto... __ds) {
+ using _Diff = common_type_t<range_difference_t<__maybe_const<_OtherConst, _Views>>...>;
+ return ranges::min({_Diff(__ds)...},
+ [](auto __a, auto __b) { return ranges::__abs(__a) < ranges::__abs(__b); });
+ },
+ __diffs);
+ }
+
+ template <bool _OtherConst>
+ requires(
+ sized_sentinel_for<sentinel_t<__maybe_const<_Const, _Views>>, iterator_t<__maybe_const<_OtherConst, _Views>>> &&
+ ...)
+ _LIBCPP_HIDE_FROM_ABI friend constexpr common_type_t<range_difference_t<__maybe_const<_OtherConst, _Views>>...>
+ operator-(const __sentinel& __y, const __iterator<_OtherConst>& __x) {
+ return -(__x - __y);
+ }
+};
+
+template <class... _Views>
+inline constexpr bool enable_borrowed_range<zip_view<_Views...>> = (enable_borrowed_range<_Views> && ...);
+
+namespace views {
+namespace __zip {
+
+struct __fn {
+ _LIBCPP_HIDE_FROM_ABI constexpr auto operator()() const noexcept { return empty_view<tuple<>>{}; }
+
+ template <class... _Ranges>
+ _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Ranges&&... rs) const
+ noexcept(noexcept(zip_view<all_t<_Ranges&&>...>(std::forward<_Ranges>(rs)...)))
+ -> decltype(zip_view<all_t<_Ranges&&>...>(std::forward<_Ranges>(rs)...)) {
+ return zip_view<all_t<_Ranges>...>(std::forward<_Ranges>(rs)...);
+ }
+};
+
+} // namespace __zip
+inline namespace __cpo {
+ inline constexpr auto zip = __zip::__fn{};
+} // namespace __cpo
+} // namespace views
+} // namespace ranges
+
+#endif // _LIBCPP_STD_VER > 20 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___RANGES_ZIP_VIEW_H
diff --git a/libcxx/include/__split_buffer b/libcxx/include/__split_buffer
index 2642cf6fca49..e484e70440c9 100644
--- a/libcxx/include/__split_buffer
+++ b/libcxx/include/__split_buffer
@@ -1,14 +1,30 @@
// -*- C++ -*-
-#ifndef _LIBCPP_SPLIT_BUFFER
-#define _LIBCPP_SPLIT_BUFFER
-
+//===----------------------------------------------------------------------===//
+//
+// 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___SPLIT_BUFFER
+#define _LIBCPP___SPLIT_BUFFER
+
+#include <__algorithm/max.h>
+#include <__algorithm/move.h>
+#include <__algorithm/move_backward.h>
#include <__config>
+#include <__iterator/distance.h>
+#include <__iterator/iterator_traits.h>
+#include <__iterator/move_iterator.h>
+#include <__memory/allocator.h>
+#include <__memory/compressed_pair.h>
#include <__utility/forward.h>
-#include <algorithm>
+#include <memory>
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
@@ -303,7 +319,13 @@ template <class _Tp, class _Allocator>
__split_buffer<_Tp, _Allocator>::__split_buffer(size_type __cap, size_type __start, __alloc_rr& __a)
: __end_cap_(nullptr, __a)
{
- __first_ = __cap != 0 ? __alloc_traits::allocate(__alloc(), __cap) : nullptr;
+ if (__cap == 0) {
+ __first_ = nullptr;
+ } else {
+ auto __allocation = std::__allocate_at_least(__alloc(), __cap);
+ __first_ = __allocation.ptr;
+ __cap = __allocation.count;
+ }
__begin_ = __end_ = __first_ + __start;
__end_cap() = __first_ + __cap;
}
@@ -369,10 +391,10 @@ __split_buffer<_Tp, _Allocator>::__split_buffer(__split_buffer&& __c, const __al
}
else
{
- size_type __cap = __c.size();
- __first_ = __alloc_traits::allocate(__alloc(), __cap);
+ auto __allocation = std::__allocate_at_least(__alloc(), __c.size());
+ __first_ = __allocation.ptr;
__begin_ = __end_ = __first_;
- __end_cap() = __first_ + __cap;
+ __end_cap() = __first_ + __allocation.count;
typedef move_iterator<iterator> _Ip;
__construct_at_end(_Ip(__c.begin()), _Ip(__c.end()));
}
@@ -617,4 +639,4 @@ _LIBCPP_END_NAMESPACE_STD
_LIBCPP_POP_MACROS
-#endif // _LIBCPP_SPLIT_BUFFER
+#endif // _LIBCPP___SPLIT_BUFFER
diff --git a/libcxx/include/__std_stream b/libcxx/include/__std_stream
index 65e90b7894b6..e419e8c03af0 100644
--- a/libcxx/include/__std_stream
+++ b/libcxx/include/__std_stream
@@ -17,7 +17,7 @@
#include <ostream>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
diff --git a/libcxx/include/__string b/libcxx/include/__string/char_traits.h
index 2249d3a8aec5..457a771b94cf 100644
--- a/libcxx/include/__string
+++ b/libcxx/include/__string/char_traits.h
@@ -1,4 +1,3 @@
-// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
@@ -7,157 +6,36 @@
//
//===----------------------------------------------------------------------===//
-#ifndef _LIBCPP___STRING
-#define _LIBCPP___STRING
+#ifndef _LIBCPP___STRING_CHAR_TRAITS_H
+#define _LIBCPP___STRING_CHAR_TRAITS_H
-#include <__algorithm/copy.h>
-#include <__algorithm/copy_backward.h>
#include <__algorithm/copy_n.h>
#include <__algorithm/fill_n.h>
#include <__algorithm/find_end.h>
#include <__algorithm/find_first_of.h>
#include <__algorithm/min.h>
#include <__config>
-#include <__functional/hash.h> // for __murmur2_or_cityhash
+#include <__functional/hash.h>
#include <__iterator/iterator_traits.h>
-#include <cstdint> // for uint_least16_t
-#include <cstdio> // for EOF
-#include <cstring> // for memcpy
-#include <iosfwd> // for streampos & friends
-#include <type_traits> // for __libcpp_is_constant_evaluated
+#include <cstdint>
+#include <cstdio>
+#include <cstring>
+#include <iosfwd>
+#include <type_traits>
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
# include <cwchar> // for wmemcpy
#endif
-#include <__debug>
-
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
#include <__undef_macros>
-
_LIBCPP_BEGIN_NAMESPACE_STD
-// The extern template ABI lists are kept outside of <string> to improve the
-// readability of that header. We maintain 2 ABI lists:
-// - _LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST
-// - _LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST
-// As the name implies, the ABI lists define the V1 (Stable) and unstable ABI.
-//
-// For unstable, we may explicitly remove function that are external in V1,
-// and add (new) external functions to better control inlining and compiler
-// optimization opportunities.
-//
-// For stable, the ABI list should rarely change, except for adding new
-// functions supporting new c++ version / API changes. Typically entries
-// must never be removed from the stable list.
-#define _LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_Func, _CharType) \
- _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, value_type const*, size_type)) \
- _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::rfind(value_type const*, size_type, size_type) const) \
- _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init(value_type const*, size_type, size_type)) \
- _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::basic_string(basic_string const&)) \
- _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, value_type const*)) \
- _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::basic_string(basic_string const&, allocator<_CharType> const&)) \
- _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_last_not_of(value_type const*, size_type, size_type) const) \
- _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::~basic_string()) \
- _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_first_not_of(value_type const*, size_type, size_type) const) \
- _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, size_type, value_type)) \
- _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::operator=(value_type)) \
- _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init(value_type const*, size_type)) \
- _Func(_LIBCPP_FUNC_VIS const _CharType& basic_string<_CharType>::at(size_type) const) \
- _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, value_type const*, size_type)) \
- _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_first_of(value_type const*, size_type, size_type) const) \
- _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, size_type, value_type)) \
- _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::assign(value_type const*, size_type)) \
- _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::reserve(size_type)) \
- _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(value_type const*, size_type)) \
- _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::assign(basic_string const&, size_type, size_type)) \
- _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::copy(value_type*, size_type, size_type) const) \
- _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::basic_string(basic_string const&, size_type, size_type, allocator<_CharType> const&)) \
- _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find(value_type, size_type) const) \
- _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init(size_type, value_type)) \
- _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, value_type const*)) \
- _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_last_of(value_type const*, size_type, size_type) const) \
- _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__grow_by(size_type, size_type, size_type, size_type, size_type, size_type)) \
- _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__grow_by_and_replace(size_type, size_type, size_type, size_type, size_type, size_type, value_type const*)) \
- _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::push_back(value_type)) \
- _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(size_type, value_type)) \
- _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::rfind(value_type, size_type) const) \
- _Func(_LIBCPP_FUNC_VIS const basic_string<_CharType>::size_type basic_string<_CharType>::npos) \
- _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::assign(size_type, value_type)) \
- _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::erase(size_type, size_type)) \
- _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(basic_string const&, size_type, size_type)) \
- _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(value_type const*) const) \
- _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(size_type, size_type, value_type const*) const) \
- _Func(_LIBCPP_FUNC_VIS _CharType& basic_string<_CharType>::at(size_type)) \
- _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::assign(value_type const*)) \
- _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find(value_type const*, size_type, size_type) const) \
- _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(size_type, size_type, basic_string const&, size_type, size_type) const) \
- _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(size_type, size_type, value_type const*, size_type) const) \
- _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::operator=(basic_string const&)) \
- _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(value_type const*)) \
- _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, basic_string const&, size_type, size_type)) \
- _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::iterator basic_string<_CharType>::insert(basic_string::const_iterator, value_type)) \
- _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::resize(size_type, value_type)) \
- _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, basic_string const&, size_type, size_type))
-
-#define _LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_Func, _CharType) \
- _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, value_type const*, size_type)) \
- _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::rfind(value_type const*, size_type, size_type) const) \
- _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init(value_type const*, size_type, size_type)) \
- _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, value_type const*)) \
- _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_last_not_of(value_type const*, size_type, size_type) const) \
- _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::~basic_string()) \
- _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_first_not_of(value_type const*, size_type, size_type) const) \
- _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, size_type, value_type)) \
- _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::operator=(value_type)) \
- _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init(value_type const*, size_type)) \
- _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init_copy_ctor_external(value_type const*, size_type)) \
- _Func(_LIBCPP_FUNC_VIS const _CharType& basic_string<_CharType>::at(size_type) const) \
- _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, value_type const*, size_type)) \
- _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_first_of(value_type const*, size_type, size_type) const) \
- _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, size_type, value_type)) \
- _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::__assign_external(value_type const*, size_type)) \
- _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::__assign_external(value_type const*)) \
- _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::reserve(size_type)) \
- _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(value_type const*, size_type)) \
- _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::assign(basic_string const&, size_type, size_type)) \
- _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::copy(value_type*, size_type, size_type) const) \
- _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::basic_string(basic_string const&, size_type, size_type, allocator<_CharType> const&)) \
- _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find(value_type, size_type) const) \
- _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init(size_type, value_type)) \
- _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, value_type const*)) \
- _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_last_of(value_type const*, size_type, size_type) const) \
- _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__grow_by(size_type, size_type, size_type, size_type, size_type, size_type)) \
- _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__grow_by_and_replace(size_type, size_type, size_type, size_type, size_type, size_type, value_type const*)) \
- _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::__assign_no_alias<false>(value_type const*, size_type)) \
- _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::__assign_no_alias<true>(value_type const*, size_type)) \
- _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::push_back(value_type)) \
- _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(size_type, value_type)) \
- _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::rfind(value_type, size_type) const) \
- _Func(_LIBCPP_FUNC_VIS const basic_string<_CharType>::size_type basic_string<_CharType>::npos) \
- _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::assign(size_type, value_type)) \
- _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__erase_external_with_move(size_type, size_type)) \
- _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(basic_string const&, size_type, size_type)) \
- _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(value_type const*) const) \
- _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(size_type, size_type, value_type const*) const) \
- _Func(_LIBCPP_FUNC_VIS _CharType& basic_string<_CharType>::at(size_type)) \
- _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find(value_type const*, size_type, size_type) const) \
- _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(size_type, size_type, basic_string const&, size_type, size_type) const) \
- _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(size_type, size_type, value_type const*, size_type) const) \
- _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(value_type const*)) \
- _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, basic_string const&, size_type, size_type)) \
- _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::iterator basic_string<_CharType>::insert(basic_string::const_iterator, value_type)) \
- _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::resize(size_type, value_type)) \
- _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, basic_string const&, size_type, size_type))
-
-
-// char_traits
-
template <class _CharT>
struct _LIBCPP_TEMPLATE_VIS char_traits
{
@@ -286,40 +164,25 @@ char_traits<_CharT>::assign(char_type* __s, size_t __n, char_type __a)
return __r;
}
-// constexpr versions of move/copy/assign.
-
template <class _CharT>
static inline _LIBCPP_CONSTEXPR_AFTER_CXX17
-_CharT* __copy_constexpr(_CharT* __dest, const _CharT* __source, size_t __n) _NOEXCEPT
+_CharT* __char_traits_move(_CharT* __dest, const _CharT* __source, size_t __n) _NOEXCEPT
{
- _LIBCPP_ASSERT(__libcpp_is_constant_evaluated(), "__copy_constexpr() should always be constant evaluated");
- _VSTD::copy_n(__source, __n, __dest);
- return __dest;
-}
-
-template <class _CharT>
-static inline _LIBCPP_CONSTEXPR_AFTER_CXX17
-_CharT* __move_constexpr(_CharT* __dest, const _CharT* __source, size_t __n) _NOEXCEPT
-{
- _LIBCPP_ASSERT(__libcpp_is_constant_evaluated(), "__move_constexpr() should always be constant evaluated");
- if (__n == 0)
+#ifdef _LIBCPP_COMPILER_GCC
+ if (__libcpp_is_constant_evaluated()) {
+ if (__n == 0)
+ return __dest;
+ _CharT* __allocation = new _CharT[__n];
+ std::copy_n(__source, __n, __allocation);
+ std::copy_n(static_cast<const _CharT*>(__allocation), __n, __dest);
+ delete[] __allocation;
return __dest;
- _CharT* __allocation = new _CharT[__n];
- _VSTD::__copy_constexpr(__allocation, __source, __n);
- _VSTD::__copy_constexpr(__dest, static_cast<const _CharT*>(__allocation), __n);
- delete[] __allocation;
+ }
+#endif
+ ::__builtin_memmove(__dest, __source, __n * sizeof(_CharT));
return __dest;
}
-template <class _CharT>
-static inline _LIBCPP_CONSTEXPR_AFTER_CXX17
-_CharT* __assign_constexpr(_CharT* __s, size_t __n, _CharT __a) _NOEXCEPT
-{
- _LIBCPP_ASSERT(__libcpp_is_constant_evaluated(), "__assign_constexpr() should always be constant evaluated");
- _VSTD::fill_n(__s, __n, __a);
- return __s;
-}
-
// char_traits<char>
template <>
@@ -357,30 +220,25 @@ struct _LIBCPP_TEMPLATE_VIS char_traits<char>
static _LIBCPP_CONSTEXPR_AFTER_CXX14
const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT;
+
static inline _LIBCPP_CONSTEXPR_AFTER_CXX17
- char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
- {
- return __libcpp_is_constant_evaluated()
- ? _VSTD::__move_constexpr(__s1, __s2, __n)
- : __n == 0 ? __s1 : (char_type*)_VSTD::memmove(__s1, __s2, __n);
- }
+ char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
+ return std::__char_traits_move(__s1, __s2, __n);
+ }
+
static inline _LIBCPP_CONSTEXPR_AFTER_CXX17
- char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
- {
- if (!__libcpp_is_constant_evaluated()) {
- _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
- }
- return __libcpp_is_constant_evaluated()
- ? _VSTD::__copy_constexpr(__s1, __s2, __n)
- : __n == 0 ? __s1 : (char_type*)_VSTD::memcpy(__s1, __s2, __n);
- }
+ char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
+ if (!__libcpp_is_constant_evaluated())
+ _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
+ std::copy_n(__s2, __n, __s1);
+ return __s1;
+ }
+
static inline _LIBCPP_CONSTEXPR_AFTER_CXX17
- char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT
- {
- return __libcpp_is_constant_evaluated()
- ? _VSTD::__assign_constexpr(__s, __n, __a)
- : __n == 0 ? __s : (char_type*)_VSTD::memset(__s, to_int_type(__a), __n);
- }
+ char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT {
+ std::fill_n(__s, __n, __a);
+ return __s;
+ }
static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT
{return eq_int_type(__c, eof()) ? ~eof() : __c;}
@@ -463,30 +321,26 @@ struct _LIBCPP_TEMPLATE_VIS char_traits<wchar_t>
size_t length(const char_type* __s) _NOEXCEPT;
static _LIBCPP_CONSTEXPR_AFTER_CXX14
const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT;
+
static inline _LIBCPP_CONSTEXPR_AFTER_CXX17
- char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
- {
- return __libcpp_is_constant_evaluated()
- ? _VSTD::__move_constexpr(__s1, __s2, __n)
- : __n == 0 ? __s1 : _VSTD::wmemmove(__s1, __s2, __n);
- }
+ char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
+ return std::__char_traits_move(__s1, __s2, __n);
+ }
+
static inline _LIBCPP_CONSTEXPR_AFTER_CXX17
- char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
- {
- if (!__libcpp_is_constant_evaluated()) {
- _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
- }
- return __libcpp_is_constant_evaluated()
- ? _VSTD::__copy_constexpr(__s1, __s2, __n)
- : __n == 0 ? __s1 : _VSTD::wmemcpy(__s1, __s2, __n);
- }
+ char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
+ if (!__libcpp_is_constant_evaluated())
+ _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
+ std::copy_n(__s2, __n, __s1);
+ return __s1;
+ }
+
static inline _LIBCPP_CONSTEXPR_AFTER_CXX17
- char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT
- {
- return __libcpp_is_constant_evaluated()
- ? _VSTD::__assign_constexpr(__s, __n, __a)
- : __n == 0 ? __s : _VSTD::wmemset(__s, __a, __n);
- }
+ char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT {
+ std::fill_n(__s, __n, __a);
+ return __s;
+ }
+
static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT
{return eq_int_type(__c, eof()) ? ~eof() : __c;}
static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
@@ -559,17 +413,6 @@ char_traits<wchar_t>::find(const char_type* __s, size_t __n, const char_type& __
}
#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
-template <class _Traits>
-_LIBCPP_INLINE_VISIBILITY
-_LIBCPP_CONSTEXPR
-inline size_t __char_traits_length_checked(const typename _Traits::char_type* __s) _NOEXCEPT {
-#if _LIBCPP_DEBUG_LEVEL >= 1
- return __s ? _Traits::length(__s) : (_VSTD::__libcpp_debug_function(_VSTD::__libcpp_debug_info(__FILE__, __LINE__, "p == nullptr", "null pointer pass to non-null argument of char_traits<...>::length")), 0);
-#else
- return _Traits::length(__s);
-#endif
-}
-
#ifndef _LIBCPP_HAS_NO_CHAR8_T
template <>
@@ -598,31 +441,23 @@ struct _LIBCPP_TEMPLATE_VIS char_traits<char8_t>
const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT;
static _LIBCPP_CONSTEXPR_AFTER_CXX17
- char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
- {
- return __libcpp_is_constant_evaluated()
- ? _VSTD::__move_constexpr(__s1, __s2, __n)
- : __n == 0 ? __s1 : (char_type*)_VSTD::memmove(__s1, __s2, __n);
- }
+ char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
+ return std::__char_traits_move(__s1, __s2, __n);
+ }
static _LIBCPP_CONSTEXPR_AFTER_CXX17
- char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
- {
- if (!__libcpp_is_constant_evaluated()) {
- _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
- }
- return __libcpp_is_constant_evaluated()
- ? _VSTD::__copy_constexpr(__s1, __s2, __n)
- : __n == 0 ? __s1 : (char_type*)_VSTD::memcpy(__s1, __s2, __n);
- }
+ char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
+ if (!__libcpp_is_constant_evaluated())
+ _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
+ std::copy_n(__s2, __n, __s1);
+ return __s1;
+ }
static _LIBCPP_CONSTEXPR_AFTER_CXX17
- char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT
- {
- return __libcpp_is_constant_evaluated()
- ? _VSTD::__assign_constexpr(__s, __n, __a)
- : __n == 0 ? __s : (char_type*)_VSTD::memset(__s, to_int_type(__a), __n);
- }
+ char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT {
+ std::fill_n(__s, __n, __a);
+ return __s;
+ }
static inline constexpr int_type not_eof(int_type __c) noexcept
{return eq_int_type(__c, eof()) ? ~eof() : __c;}
@@ -679,9 +514,7 @@ char_traits<char8_t>::find(const char_type* __s, size_t __n, const char_type& __
return nullptr;
}
-#endif // #_LIBCPP_HAS_NO_CHAR8_T
-
-#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
+#endif // _LIBCPP_HAS_NO_CHAR8_T
template <>
struct _LIBCPP_TEMPLATE_VIS char_traits<char16_t>
@@ -705,12 +538,25 @@ struct _LIBCPP_TEMPLATE_VIS char_traits<char16_t>
size_t length(const char_type* __s) _NOEXCEPT;
_LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT;
+
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
- static char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
+ static char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
+ return std::__char_traits_move(__s1, __s2, __n);
+ }
+
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
- static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
+ static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
+ if (!__libcpp_is_constant_evaluated())
+ _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
+ std::copy_n(__s2, __n, __s1);
+ return __s1;
+ }
+
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
- static char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT;
+ static char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT {
+ std::fill_n(__s, __n, __a);
+ return __s;
+ }
static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT
{return eq_int_type(__c, eof()) ? ~eof() : __c;}
@@ -761,50 +607,6 @@ char_traits<char16_t>::find(const char_type* __s, size_t __n, const char_type& _
return nullptr;
}
-inline _LIBCPP_CONSTEXPR_AFTER_CXX17
-char16_t*
-char_traits<char16_t>::move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
-{
- if (__n == 0) return __s1;
- char_type* __r = __s1;
- if (__s1 < __s2)
- {
- for (; __n; --__n, ++__s1, ++__s2)
- assign(*__s1, *__s2);
- }
- else if (__s2 < __s1)
- {
- __s1 += __n;
- __s2 += __n;
- for (; __n; --__n)
- assign(*--__s1, *--__s2);
- }
- return __r;
-}
-
-inline _LIBCPP_CONSTEXPR_AFTER_CXX17
-char16_t*
-char_traits<char16_t>::copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
-{
- if (!__libcpp_is_constant_evaluated()) {
- _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
- }
- char_type* __r = __s1;
- for (; __n; --__n, ++__s1, ++__s2)
- assign(*__s1, *__s2);
- return __r;
-}
-
-inline _LIBCPP_CONSTEXPR_AFTER_CXX17
-char16_t*
-char_traits<char16_t>::assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT
-{
- char_type* __r = __s;
- for (; __n; --__n, ++__s)
- assign(*__s, __a);
- return __r;
-}
-
template <>
struct _LIBCPP_TEMPLATE_VIS char_traits<char32_t>
{
@@ -827,12 +629,23 @@ struct _LIBCPP_TEMPLATE_VIS char_traits<char32_t>
size_t length(const char_type* __s) _NOEXCEPT;
_LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT;
+
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
- static char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
+ static char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
+ return std::__char_traits_move(__s1, __s2, __n);
+ }
+
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
- static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
+ static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
+ std::copy_n(__s2, __n, __s1);
+ return __s1;
+ }
+
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
- static char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT;
+ static char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT {
+ std::fill_n(__s, __n, __a);
+ return __s;
+ }
static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT
{return eq_int_type(__c, eof()) ? ~eof() : __c;}
@@ -883,52 +696,6 @@ char_traits<char32_t>::find(const char_type* __s, size_t __n, const char_type& _
return nullptr;
}
-inline _LIBCPP_CONSTEXPR_AFTER_CXX17
-char32_t*
-char_traits<char32_t>::move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
-{
- if (__n == 0) return __s1;
- char_type* __r = __s1;
- if (__s1 < __s2)
- {
- for (; __n; --__n, ++__s1, ++__s2)
- assign(*__s1, *__s2);
- }
- else if (__s2 < __s1)
- {
- __s1 += __n;
- __s2 += __n;
- for (; __n; --__n)
- assign(*--__s1, *--__s2);
- }
- return __r;
-}
-
-inline _LIBCPP_CONSTEXPR_AFTER_CXX17
-char32_t*
-char_traits<char32_t>::copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
-{
- if (!__libcpp_is_constant_evaluated()) {
- _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
- }
- char_type* __r = __s1;
- for (; __n; --__n, ++__s1, ++__s2)
- assign(*__s1, *__s2);
- return __r;
-}
-
-inline _LIBCPP_CONSTEXPR_AFTER_CXX17
-char32_t*
-char_traits<char32_t>::assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT
-{
- char_type* __r = __s;
- for (; __n; --__n, ++__s)
- assign(*__s, __a);
- return __r;
-}
-
-#endif // _LIBCPP_HAS_NO_UNICODE_CHARS
-
// helper fns for basic_string and string_view
// __str_find
@@ -1155,21 +922,8 @@ size_t __do_string_hash(_Ptr __p, _Ptr __e)
return __murmur2_or_cityhash<size_t>()(__p, (__e-__p)*sizeof(value_type));
}
-template <class _CharT, class _Iter, class _Traits=char_traits<_CharT> >
-struct __quoted_output_proxy
-{
- _Iter __first;
- _Iter __last;
- _CharT __delim;
- _CharT __escape;
-
- __quoted_output_proxy(_Iter __f, _Iter __l, _CharT __d, _CharT __e)
- : __first(__f), __last(__l), __delim(__d), __escape(__e) {}
- // This would be a nice place for a string_ref
-};
-
_LIBCPP_END_NAMESPACE_STD
_LIBCPP_POP_MACROS
-#endif // _LIBCPP___STRING
+#endif // _LIBCPP___STRING_CHAR_TRAITS_H
diff --git a/libcxx/include/__string/extern_template_lists.h b/libcxx/include/__string/extern_template_lists.h
new file mode 100644
index 000000000000..edbda7cbd004
--- /dev/null
+++ b/libcxx/include/__string/extern_template_lists.h
@@ -0,0 +1,131 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___STRING_EXTERN_TEMPLATE_LISTS_H
+#define _LIBCPP___STRING_EXTERN_TEMPLATE_LISTS_H
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+// We maintain 2 ABI lists:
+// - _LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST
+// - _LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST
+// As the name implies, the ABI lists define the V1 (Stable) and unstable ABI.
+//
+// For unstable, we may explicitly remove function that are external in V1,
+// and add (new) external functions to better control inlining and compiler
+// optimization opportunities.
+//
+// For stable, the ABI list should rarely change, except for adding new
+// functions supporting new c++ version / API changes. Typically entries
+// must never be removed from the stable list.
+#define _LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_Func, _CharType) \
+ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, value_type const*, size_type)) \
+ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::rfind(value_type const*, size_type, size_type) const) \
+ _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init(value_type const*, size_type, size_type)) \
+ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::basic_string(basic_string const&)) \
+ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, value_type const*)) \
+ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::basic_string(basic_string const&, allocator<_CharType> const&)) \
+ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_last_not_of(value_type const*, size_type, size_type) const) \
+ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::~basic_string()) \
+ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_first_not_of(value_type const*, size_type, size_type) const) \
+ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, size_type, value_type)) \
+ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::operator=(value_type)) \
+ _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init(value_type const*, size_type)) \
+ _Func(_LIBCPP_FUNC_VIS const _CharType& basic_string<_CharType>::at(size_type) const) \
+ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, value_type const*, size_type)) \
+ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_first_of(value_type const*, size_type, size_type) const) \
+ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, size_type, value_type)) \
+ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::assign(value_type const*, size_type)) \
+ _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::reserve(size_type)) \
+ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(value_type const*, size_type)) \
+ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::assign(basic_string const&, size_type, size_type)) \
+ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::copy(value_type*, size_type, size_type) const) \
+ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::basic_string(basic_string const&, size_type, size_type, allocator<_CharType> const&)) \
+ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find(value_type, size_type) const) \
+ _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init(size_type, value_type)) \
+ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, value_type const*)) \
+ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_last_of(value_type const*, size_type, size_type) const) \
+ _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__grow_by(size_type, size_type, size_type, size_type, size_type, size_type)) \
+ _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__grow_by_and_replace(size_type, size_type, size_type, size_type, size_type, size_type, value_type const*)) \
+ _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::push_back(value_type)) \
+ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(size_type, value_type)) \
+ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::rfind(value_type, size_type) const) \
+ _Func(_LIBCPP_FUNC_VIS const basic_string<_CharType>::size_type basic_string<_CharType>::npos) \
+ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::assign(size_type, value_type)) \
+ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::erase(size_type, size_type)) \
+ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(basic_string const&, size_type, size_type)) \
+ _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(value_type const*) const) \
+ _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(size_type, size_type, value_type const*) const) \
+ _Func(_LIBCPP_FUNC_VIS _CharType& basic_string<_CharType>::at(size_type)) \
+ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::assign(value_type const*)) \
+ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find(value_type const*, size_type, size_type) const) \
+ _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(size_type, size_type, basic_string const&, size_type, size_type) const) \
+ _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(size_type, size_type, value_type const*, size_type) const) \
+ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::operator=(basic_string const&)) \
+ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(value_type const*)) \
+ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, basic_string const&, size_type, size_type)) \
+ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::iterator basic_string<_CharType>::insert(basic_string::const_iterator, value_type)) \
+ _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::resize(size_type, value_type)) \
+ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, basic_string const&, size_type, size_type))
+
+#define _LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_Func, _CharType) \
+ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, value_type const*, size_type)) \
+ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::rfind(value_type const*, size_type, size_type) const) \
+ _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init(value_type const*, size_type, size_type)) \
+ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, value_type const*)) \
+ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_last_not_of(value_type const*, size_type, size_type) const) \
+ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::~basic_string()) \
+ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_first_not_of(value_type const*, size_type, size_type) const) \
+ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, size_type, value_type)) \
+ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::operator=(value_type)) \
+ _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init(value_type const*, size_type)) \
+ _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init_copy_ctor_external(value_type const*, size_type)) \
+ _Func(_LIBCPP_FUNC_VIS const _CharType& basic_string<_CharType>::at(size_type) const) \
+ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, value_type const*, size_type)) \
+ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_first_of(value_type const*, size_type, size_type) const) \
+ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, size_type, value_type)) \
+ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::__assign_external(value_type const*, size_type)) \
+ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::__assign_external(value_type const*)) \
+ _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::reserve(size_type)) \
+ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(value_type const*, size_type)) \
+ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::assign(basic_string const&, size_type, size_type)) \
+ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::copy(value_type*, size_type, size_type) const) \
+ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::basic_string(basic_string const&, size_type, size_type, allocator<_CharType> const&)) \
+ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find(value_type, size_type) const) \
+ _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init(size_type, value_type)) \
+ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, value_type const*)) \
+ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_last_of(value_type const*, size_type, size_type) const) \
+ _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__grow_by(size_type, size_type, size_type, size_type, size_type, size_type)) \
+ _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__grow_by_and_replace(size_type, size_type, size_type, size_type, size_type, size_type, value_type const*)) \
+ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::__assign_no_alias<false>(value_type const*, size_type)) \
+ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::__assign_no_alias<true>(value_type const*, size_type)) \
+ _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::push_back(value_type)) \
+ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(size_type, value_type)) \
+ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::rfind(value_type, size_type) const) \
+ _Func(_LIBCPP_FUNC_VIS const basic_string<_CharType>::size_type basic_string<_CharType>::npos) \
+ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::assign(size_type, value_type)) \
+ _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__erase_external_with_move(size_type, size_type)) \
+ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(basic_string const&, size_type, size_type)) \
+ _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(value_type const*) const) \
+ _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(size_type, size_type, value_type const*) const) \
+ _Func(_LIBCPP_FUNC_VIS _CharType& basic_string<_CharType>::at(size_type)) \
+ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find(value_type const*, size_type, size_type) const) \
+ _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(size_type, size_type, basic_string const&, size_type, size_type) const) \
+ _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(size_type, size_type, value_type const*, size_type) const) \
+ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(value_type const*)) \
+ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, basic_string const&, size_type, size_type)) \
+ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::iterator basic_string<_CharType>::insert(basic_string::const_iterator, value_type)) \
+ _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::resize(size_type, value_type)) \
+ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, basic_string const&, size_type, size_type))
+
+
+#endif // _LIBCPP___STRING_EXTERN_TEMPLATE_LISTS_H
diff --git a/libcxx/include/__thread/poll_with_backoff.h b/libcxx/include/__thread/poll_with_backoff.h
index 3149a3862890..0bbafd186657 100644
--- a/libcxx/include/__thread/poll_with_backoff.h
+++ b/libcxx/include/__thread/poll_with_backoff.h
@@ -10,11 +10,15 @@
#define _LIBCPP___THREAD_POLL_WITH_BACKOFF_H
#include <__availability>
+#include <__chrono/duration.h>
+#include <__chrono/high_resolution_clock.h>
+#include <__chrono/steady_clock.h>
+#include <__chrono/time_point.h>
#include <__config>
-#include <chrono>
+#include <__filesystem/file_time_type.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__thread/timed_backoff_policy.h b/libcxx/include/__thread/timed_backoff_policy.h
index d85a34071c6d..28fe75d6fd80 100644
--- a/libcxx/include/__thread/timed_backoff_policy.h
+++ b/libcxx/include/__thread/timed_backoff_policy.h
@@ -13,11 +13,11 @@
#ifndef _LIBCPP_HAS_NO_THREADS
-#include <__threading_support>
-#include <chrono>
+# include <__chrono/duration.h>
+# include <__threading_support>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__threading_support b/libcxx/include/__threading_support
index bf85d5f5d9f0..8f1efb7854b7 100644
--- a/libcxx/include/__threading_support
+++ b/libcxx/include/__threading_support
@@ -7,13 +7,14 @@
//
//===----------------------------------------------------------------------===//
-#ifndef _LIBCPP_THREADING_SUPPORT
-#define _LIBCPP_THREADING_SUPPORT
+#ifndef _LIBCPP___THREADING_SUPPORT
+#define _LIBCPP___THREADING_SUPPORT
#include <__availability>
+#include <__chrono/convert_to_timespec.h>
+#include <__chrono/duration.h>
#include <__config>
#include <__thread/poll_with_backoff.h>
-#include <chrono>
#include <errno.h>
#include <iosfwd>
#include <limits>
@@ -23,7 +24,7 @@
#endif
#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
-#pragma GCC system_header
+# pragma GCC system_header
#endif
#if defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
@@ -254,7 +255,6 @@ int __libcpp_tls_set(__libcpp_tls_key __key, void *__p);
#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
-_LIBCPP_HIDE_FROM_ABI inline
int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m)
{
pthread_mutexattr_t attr;
@@ -279,88 +279,74 @@ int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m)
return 0;
}
-_LIBCPP_HIDE_FROM_ABI inline
int __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m)
{
return pthread_mutex_lock(__m);
}
-_LIBCPP_HIDE_FROM_ABI inline
bool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m)
{
return pthread_mutex_trylock(__m) == 0;
}
-_LIBCPP_HIDE_FROM_ABI inline
int __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m)
{
return pthread_mutex_unlock(__m);
}
-_LIBCPP_HIDE_FROM_ABI inline
int __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m)
{
return pthread_mutex_destroy(__m);
}
-_LIBCPP_HIDE_FROM_ABI inline
int __libcpp_mutex_lock(__libcpp_mutex_t *__m)
{
return pthread_mutex_lock(__m);
}
-_LIBCPP_HIDE_FROM_ABI inline
bool __libcpp_mutex_trylock(__libcpp_mutex_t *__m)
{
return pthread_mutex_trylock(__m) == 0;
}
-_LIBCPP_HIDE_FROM_ABI inline
int __libcpp_mutex_unlock(__libcpp_mutex_t *__m)
{
return pthread_mutex_unlock(__m);
}
-_LIBCPP_HIDE_FROM_ABI inline
int __libcpp_mutex_destroy(__libcpp_mutex_t *__m)
{
return pthread_mutex_destroy(__m);
}
// Condition Variable
-_LIBCPP_HIDE_FROM_ABI inline
int __libcpp_condvar_signal(__libcpp_condvar_t *__cv)
{
return pthread_cond_signal(__cv);
}
-_LIBCPP_HIDE_FROM_ABI inline
int __libcpp_condvar_broadcast(__libcpp_condvar_t *__cv)
{
return pthread_cond_broadcast(__cv);
}
-_LIBCPP_HIDE_FROM_ABI inline
int __libcpp_condvar_wait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m)
{
return pthread_cond_wait(__cv, __m);
}
-_LIBCPP_HIDE_FROM_ABI inline
int __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m,
__libcpp_timespec_t *__ts)
{
return pthread_cond_timedwait(__cv, __m, __ts);
}
-_LIBCPP_HIDE_FROM_ABI inline
int __libcpp_condvar_destroy(__libcpp_condvar_t *__cv)
{
return pthread_cond_destroy(__cv);
}
// Execute once
-_LIBCPP_HIDE_FROM_ABI inline
int __libcpp_execute_once(__libcpp_exec_once_flag *flag,
void (*init_routine)()) {
return pthread_once(flag, init_routine);
@@ -368,40 +354,34 @@ int __libcpp_execute_once(__libcpp_exec_once_flag *flag,
// Thread id
// Returns non-zero if the thread ids are equal, otherwise 0
-_LIBCPP_HIDE_FROM_ABI inline
bool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2)
{
return t1 == t2;
}
// Returns non-zero if t1 < t2, otherwise 0
-_LIBCPP_HIDE_FROM_ABI inline
bool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2)
{
return t1 < t2;
}
// Thread
-_LIBCPP_HIDE_FROM_ABI inline
bool __libcpp_thread_isnull(const __libcpp_thread_t *__t) {
return __libcpp_thread_get_id(__t) == 0;
}
-_LIBCPP_HIDE_FROM_ABI inline
int __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *),
void *__arg)
{
return pthread_create(__t, nullptr, __func, __arg);
}
-_LIBCPP_HIDE_FROM_ABI inline
__libcpp_thread_id __libcpp_thread_get_current_id()
{
const __libcpp_thread_t thread = pthread_self();
return __libcpp_thread_get_id(&thread);
}
-_LIBCPP_HIDE_FROM_ABI inline
__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t)
{
#if defined(__MVS__)
@@ -411,25 +391,21 @@ __libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t)
#endif
}
-_LIBCPP_HIDE_FROM_ABI inline
int __libcpp_thread_join(__libcpp_thread_t *__t)
{
return pthread_join(*__t, nullptr);
}
-_LIBCPP_HIDE_FROM_ABI inline
int __libcpp_thread_detach(__libcpp_thread_t *__t)
{
return pthread_detach(*__t);
}
-_LIBCPP_HIDE_FROM_ABI inline
void __libcpp_thread_yield()
{
sched_yield();
}
-_LIBCPP_HIDE_FROM_ABI inline
void __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns)
{
__libcpp_timespec_t __ts = _VSTD::__convert_to_timespec<__libcpp_timespec_t>(__ns);
@@ -437,19 +413,16 @@ void __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns)
}
// Thread local storage
-_LIBCPP_HIDE_FROM_ABI inline
int __libcpp_tls_create(__libcpp_tls_key *__key, void (*__at_exit)(void *))
{
return pthread_key_create(__key, __at_exit);
}
-_LIBCPP_HIDE_FROM_ABI inline
void *__libcpp_tls_get(__libcpp_tls_key __key)
{
return pthread_getspecific(__key);
}
-_LIBCPP_HIDE_FROM_ABI inline
int __libcpp_tls_set(__libcpp_tls_key __key, void *__p)
{
return pthread_setspecific(__key, __p);
@@ -457,56 +430,47 @@ int __libcpp_tls_set(__libcpp_tls_key __key, void *__p)
#elif defined(_LIBCPP_HAS_THREAD_API_C11)
-_LIBCPP_HIDE_FROM_ABI inline
int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m)
{
return mtx_init(__m, mtx_plain | mtx_recursive) == thrd_success ? 0 : EINVAL;
}
-_LIBCPP_HIDE_FROM_ABI inline
int __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m)
{
return mtx_lock(__m) == thrd_success ? 0 : EINVAL;
}
-_LIBCPP_HIDE_FROM_ABI inline
bool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m)
{
return mtx_trylock(__m) == thrd_success;
}
-_LIBCPP_HIDE_FROM_ABI inline
int __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m)
{
return mtx_unlock(__m) == thrd_success ? 0 : EINVAL;
}
-_LIBCPP_HIDE_FROM_ABI inline
int __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m)
{
mtx_destroy(__m);
return 0;
}
-_LIBCPP_HIDE_FROM_ABI inline
int __libcpp_mutex_lock(__libcpp_mutex_t *__m)
{
return mtx_lock(__m) == thrd_success ? 0 : EINVAL;
}
-_LIBCPP_HIDE_FROM_ABI inline
bool __libcpp_mutex_trylock(__libcpp_mutex_t *__m)
{
return mtx_trylock(__m) == thrd_success;
}
-_LIBCPP_HIDE_FROM_ABI inline
int __libcpp_mutex_unlock(__libcpp_mutex_t *__m)
{
return mtx_unlock(__m) == thrd_success ? 0 : EINVAL;
}
-_LIBCPP_HIDE_FROM_ABI inline
int __libcpp_mutex_destroy(__libcpp_mutex_t *__m)
{
mtx_destroy(__m);
@@ -514,25 +478,21 @@ int __libcpp_mutex_destroy(__libcpp_mutex_t *__m)
}
// Condition Variable
-_LIBCPP_HIDE_FROM_ABI inline
int __libcpp_condvar_signal(__libcpp_condvar_t *__cv)
{
return cnd_signal(__cv) == thrd_success ? 0 : EINVAL;
}
-_LIBCPP_HIDE_FROM_ABI inline
int __libcpp_condvar_broadcast(__libcpp_condvar_t *__cv)
{
return cnd_broadcast(__cv) == thrd_success ? 0 : EINVAL;
}
-_LIBCPP_HIDE_FROM_ABI inline
int __libcpp_condvar_wait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m)
{
return cnd_wait(__cv, __m) == thrd_success ? 0 : EINVAL;
}
-_LIBCPP_HIDE_FROM_ABI inline
int __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m,
timespec *__ts)
{
@@ -540,7 +500,6 @@ int __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m,
return __ec == thrd_timedout ? ETIMEDOUT : __ec;
}
-_LIBCPP_HIDE_FROM_ABI inline
int __libcpp_condvar_destroy(__libcpp_condvar_t *__cv)
{
cnd_destroy(__cv);
@@ -548,7 +507,6 @@ int __libcpp_condvar_destroy(__libcpp_condvar_t *__cv)
}
// Execute once
-_LIBCPP_HIDE_FROM_ABI inline
int __libcpp_execute_once(__libcpp_exec_once_flag *flag,
void (*init_routine)(void)) {
::call_once(flag, init_routine);
@@ -557,26 +515,22 @@ int __libcpp_execute_once(__libcpp_exec_once_flag *flag,
// Thread id
// Returns non-zero if the thread ids are equal, otherwise 0
-_LIBCPP_HIDE_FROM_ABI inline
bool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2)
{
return thrd_equal(t1, t2) != 0;
}
// Returns non-zero if t1 < t2, otherwise 0
-_LIBCPP_HIDE_FROM_ABI inline
bool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2)
{
return t1 < t2;
}
// Thread
-_LIBCPP_HIDE_FROM_ABI inline
bool __libcpp_thread_isnull(const __libcpp_thread_t *__t) {
return __libcpp_thread_get_id(__t) == 0;
}
-_LIBCPP_HIDE_FROM_ABI inline
int __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *),
void *__arg)
{
@@ -584,37 +538,31 @@ int __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *),
return __ec == thrd_nomem ? ENOMEM : __ec;
}
-_LIBCPP_HIDE_FROM_ABI inline
__libcpp_thread_id __libcpp_thread_get_current_id()
{
return thrd_current();
}
-_LIBCPP_HIDE_FROM_ABI inline
__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t)
{
return *__t;
}
-_LIBCPP_HIDE_FROM_ABI inline
int __libcpp_thread_join(__libcpp_thread_t *__t)
{
return thrd_join(*__t, nullptr) == thrd_success ? 0 : EINVAL;
}
-_LIBCPP_HIDE_FROM_ABI inline
int __libcpp_thread_detach(__libcpp_thread_t *__t)
{
return thrd_detach(*__t) == thrd_success ? 0 : EINVAL;
}
-_LIBCPP_HIDE_FROM_ABI inline
void __libcpp_thread_yield()
{
thrd_yield();
}
-_LIBCPP_HIDE_FROM_ABI inline
void __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns)
{
__libcpp_timespec_t __ts = _VSTD::__convert_to_timespec<__libcpp_timespec_t>(__ns);
@@ -622,19 +570,16 @@ void __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns)
}
// Thread local storage
-_LIBCPP_HIDE_FROM_ABI inline
int __libcpp_tls_create(__libcpp_tls_key *__key, void (*__at_exit)(void *))
{
return tss_create(__key, __at_exit) == thrd_success ? 0 : EINVAL;
}
-_LIBCPP_HIDE_FROM_ABI inline
void *__libcpp_tls_get(__libcpp_tls_key __key)
{
return tss_get(__key);
}
-_LIBCPP_HIDE_FROM_ABI inline
int __libcpp_tls_set(__libcpp_tls_key __key, void *__p)
{
return tss_set(__key, __p) == thrd_success ? 0 : EINVAL;
@@ -729,4 +674,4 @@ get_id() _NOEXCEPT
_LIBCPP_END_NAMESPACE_STD
-#endif // _LIBCPP_THREADING_SUPPORT
+#endif // _LIBCPP___THREADING_SUPPORT
diff --git a/libcxx/include/__tree b/libcxx/include/__tree
index f3f2e8d15f5d..e5dd1f4d45ea 100644
--- a/libcxx/include/__tree
+++ b/libcxx/include/__tree
@@ -10,16 +10,21 @@
#ifndef _LIBCPP___TREE
#define _LIBCPP___TREE
+#include <__algorithm/min.h>
+#include <__assert>
#include <__config>
+#include <__debug>
+#include <__iterator/distance.h>
+#include <__iterator/iterator_traits.h>
+#include <__iterator/next.h>
#include <__utility/forward.h>
-#include <algorithm>
-#include <iterator>
+#include <__utility/swap.h>
#include <limits>
#include <memory>
#include <stdexcept>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
@@ -28,12 +33,10 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD
-#if defined(__GNUC__) && !defined(__clang__) // gcc.gnu.org/PR37804
template <class, class, class, class> class _LIBCPP_TEMPLATE_VIS map;
template <class, class, class, class> class _LIBCPP_TEMPLATE_VIS multimap;
template <class, class, class> class _LIBCPP_TEMPLATE_VIS set;
template <class, class, class> class _LIBCPP_TEMPLATE_VIS multiset;
-#endif
template <class _Tp, class _Compare, class _Allocator> class __tree;
template <class _Tp, class _NodePtr, class _DiffType>
@@ -140,35 +143,35 @@ __tree_invariant(_NodePtr __root)
}
// Returns: pointer to the left-most node under __x.
-// Precondition: __x != nullptr.
template <class _NodePtr>
inline _LIBCPP_INLINE_VISIBILITY
_NodePtr
__tree_min(_NodePtr __x) _NOEXCEPT
{
+ _LIBCPP_ASSERT(__x != nullptr, "Root node shouldn't be null");
while (__x->__left_ != nullptr)
__x = __x->__left_;
return __x;
}
// Returns: pointer to the right-most node under __x.
-// Precondition: __x != nullptr.
template <class _NodePtr>
inline _LIBCPP_INLINE_VISIBILITY
_NodePtr
__tree_max(_NodePtr __x) _NOEXCEPT
{
+ _LIBCPP_ASSERT(__x != nullptr, "Root node shouldn't be null");
while (__x->__right_ != nullptr)
__x = __x->__right_;
return __x;
}
// Returns: pointer to the next in-order node after __x.
-// Precondition: __x != nullptr.
template <class _NodePtr>
_NodePtr
__tree_next(_NodePtr __x) _NOEXCEPT
{
+ _LIBCPP_ASSERT(__x != nullptr, "node shouldn't be null");
if (__x->__right_ != nullptr)
return _VSTD::__tree_min(__x->__right_);
while (!_VSTD::__tree_is_left_child(__x))
@@ -181,6 +184,7 @@ inline _LIBCPP_INLINE_VISIBILITY
_EndNodePtr
__tree_next_iter(_NodePtr __x) _NOEXCEPT
{
+ _LIBCPP_ASSERT(__x != nullptr, "node shouldn't be null");
if (__x->__right_ != nullptr)
return static_cast<_EndNodePtr>(_VSTD::__tree_min(__x->__right_));
while (!_VSTD::__tree_is_left_child(__x))
@@ -189,13 +193,13 @@ __tree_next_iter(_NodePtr __x) _NOEXCEPT
}
// Returns: pointer to the previous in-order node before __x.
-// Precondition: __x != nullptr.
// Note: __x may be the end node.
template <class _NodePtr, class _EndNodePtr>
inline _LIBCPP_INLINE_VISIBILITY
_NodePtr
__tree_prev_iter(_EndNodePtr __x) _NOEXCEPT
{
+ _LIBCPP_ASSERT(__x != nullptr, "node shouldn't be null");
if (__x->__left_ != nullptr)
return _VSTD::__tree_max(__x->__left_);
_NodePtr __xx = static_cast<_NodePtr>(__x);
@@ -205,11 +209,11 @@ __tree_prev_iter(_EndNodePtr __x) _NOEXCEPT
}
// Returns: pointer to a node which has no children
-// Precondition: __x != nullptr.
template <class _NodePtr>
_NodePtr
__tree_leaf(_NodePtr __x) _NOEXCEPT
{
+ _LIBCPP_ASSERT(__x != nullptr, "node shouldn't be null");
while (true)
{
if (__x->__left_ != nullptr)
@@ -229,11 +233,12 @@ __tree_leaf(_NodePtr __x) _NOEXCEPT
// Effects: Makes __x->__right_ the subtree root with __x as its left child
// while preserving in-order order.
-// Precondition: __x->__right_ != nullptr
template <class _NodePtr>
void
__tree_left_rotate(_NodePtr __x) _NOEXCEPT
{
+ _LIBCPP_ASSERT(__x != nullptr, "node shouldn't be null");
+ _LIBCPP_ASSERT(__x->__right_ != nullptr, "node should have a right child");
_NodePtr __y = __x->__right_;
__x->__right_ = __y->__left_;
if (__x->__right_ != nullptr)
@@ -249,11 +254,12 @@ __tree_left_rotate(_NodePtr __x) _NOEXCEPT
// Effects: Makes __x->__left_ the subtree root with __x as its right child
// while preserving in-order order.
-// Precondition: __x->__left_ != nullptr
template <class _NodePtr>
void
__tree_right_rotate(_NodePtr __x) _NOEXCEPT
{
+ _LIBCPP_ASSERT(__x != nullptr, "node shouldn't be null");
+ _LIBCPP_ASSERT(__x->__left_ != nullptr, "node should have a left child");
_NodePtr __y = __x->__left_;
__x->__left_ = __y->__right_;
if (__x->__left_ != nullptr)
@@ -268,8 +274,7 @@ __tree_right_rotate(_NodePtr __x) _NOEXCEPT
}
// Effects: Rebalances __root after attaching __x to a leaf.
-// Precondition: __root != nulptr && __x != nullptr.
-// __x has no children.
+// Precondition: __x has no children.
// __x == __root or == a direct or indirect child of __root.
// If __x were to be unlinked from __root (setting __root to
// nullptr if __root == __x), __tree_invariant(__root) == true.
@@ -279,6 +284,8 @@ template <class _NodePtr>
void
__tree_balance_after_insert(_NodePtr __root, _NodePtr __x) _NOEXCEPT
{
+ _LIBCPP_ASSERT(__root != nullptr, "Root of the tree shouldn't be null");
+ _LIBCPP_ASSERT(__x != nullptr, "Can't attach null node to a leaf");
__x->__is_black_ = __x == __root;
while (__x != __root && !__x->__parent_unsafe()->__is_black_)
{
@@ -338,9 +345,7 @@ __tree_balance_after_insert(_NodePtr __root, _NodePtr __x) _NOEXCEPT
}
}
-// Precondition: __root != nullptr && __z != nullptr.
-// __tree_invariant(__root) == true.
-// __z == __root or == a direct or indirect child of __root.
+// Precondition: __z == __root or == a direct or indirect child of __root.
// Effects: unlinks __z from the tree rooted at __root, rebalancing as needed.
// Postcondition: __tree_invariant(end_node->__left_) == true && end_node->__left_
// nor any of its children refer to __z. end_node->__left_
@@ -349,6 +354,9 @@ template <class _NodePtr>
void
__tree_remove(_NodePtr __root, _NodePtr __z) _NOEXCEPT
{
+ _LIBCPP_ASSERT(__root != nullptr, "Root node should not be null");
+ _LIBCPP_ASSERT(__z != nullptr, "The node to remove should not be null");
+ _LIBCPP_DEBUG_ASSERT(__tree_invariant(__root), "The tree invariants should hold");
// __z will be removed from the tree. Client still needs to destruct/deallocate it
// __y is either __z, or if __z has two children, __tree_next(__z).
// __y will have at most one child.
@@ -545,7 +553,7 @@ template <class ..._Args>
struct __is_tree_value_type : false_type {};
template <class _One>
-struct __is_tree_value_type<_One> : __is_tree_value_type_imp<typename __uncvref<_One>::type> {};
+struct __is_tree_value_type<_One> : __is_tree_value_type_imp<__uncvref_t<_One> > {};
template <class _Tp>
struct __tree_key_value_types {
diff --git a/libcxx/include/__tuple b/libcxx/include/__tuple
index e8eb0b3aaf0c..6d13bb24c579 100644
--- a/libcxx/include/__tuple
+++ b/libcxx/include/__tuple
@@ -15,7 +15,7 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
@@ -278,7 +278,7 @@ using __type_pack_element _LIBCPP_NODEBUG = typename decltype(
#endif
template <size_t _Ip, class ..._Types>
-struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, __tuple_types<_Types...>>
+struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, __tuple_types<_Types...> >
{
static_assert(_Ip < sizeof...(_Types), "tuple_element index out of range");
typedef _LIBCPP_NODEBUG __type_pack_element<_Ip, _Types...> type;
@@ -469,8 +469,7 @@ template <class _SizeTrait, size_t _Expected>
struct __tuple_like_with_size_imp<true, _SizeTrait, _Expected>
: integral_constant<bool, _SizeTrait::value == _Expected> {};
-template <class _Tuple, size_t _ExpectedSize,
- class _RawTuple = typename __uncvref<_Tuple>::type>
+template <class _Tuple, size_t _ExpectedSize, class _RawTuple = __uncvref_t<_Tuple> >
using __tuple_like_with_size _LIBCPP_NODEBUG = __tuple_like_with_size_imp<
__tuple_like<_RawTuple>::value,
tuple_size<_RawTuple>, _ExpectedSize
diff --git a/libcxx/include/__type_traits/add_const.h b/libcxx/include/__type_traits/add_const.h
new file mode 100644
index 000000000000..c616a13f8408
--- /dev/null
+++ b/libcxx/include/__type_traits/add_const.h
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_ADD_CONST_H
+#define _LIBCPP___TYPE_TRAITS_ADD_CONST_H
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS add_const {
+ typedef _LIBCPP_NODEBUG const _Tp type;
+};
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp> using add_const_t = typename add_const<_Tp>::type;
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_ADD_CONST_H
diff --git a/libcxx/include/__type_traits/add_cv.h b/libcxx/include/__type_traits/add_cv.h
new file mode 100644
index 000000000000..8a85353f16c0
--- /dev/null
+++ b/libcxx/include/__type_traits/add_cv.h
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_ADD_CV_H
+#define _LIBCPP___TYPE_TRAITS_ADD_CV_H
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS add_cv {
+ typedef _LIBCPP_NODEBUG const volatile _Tp type;
+};
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp> using add_cv_t = typename add_cv<_Tp>::type;
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_ADD_CV_H
diff --git a/libcxx/include/__type_traits/add_lvalue_reference.h b/libcxx/include/__type_traits/add_lvalue_reference.h
new file mode 100644
index 000000000000..0d1ee4185c8c
--- /dev/null
+++ b/libcxx/include/__type_traits/add_lvalue_reference.h
@@ -0,0 +1,33 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_ADD_LVALUE_REFERENCE_H
+#define _LIBCPP___TYPE_TRAITS_ADD_LVALUE_REFERENCE_H
+
+#include <__config>
+#include <__type_traits/is_referenceable.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp, bool = __is_referenceable<_Tp>::value> struct __add_lvalue_reference_impl { typedef _LIBCPP_NODEBUG _Tp type; };
+template <class _Tp > struct __add_lvalue_reference_impl<_Tp, true> { typedef _LIBCPP_NODEBUG _Tp& type; };
+
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS add_lvalue_reference
+{typedef _LIBCPP_NODEBUG typename __add_lvalue_reference_impl<_Tp>::type type;};
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp> using add_lvalue_reference_t = typename add_lvalue_reference<_Tp>::type;
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_ADD_LVALUE_REFERENCE_H
diff --git a/libcxx/include/__type_traits/add_pointer.h b/libcxx/include/__type_traits/add_pointer.h
new file mode 100644
index 000000000000..aea2490c5d0c
--- /dev/null
+++ b/libcxx/include/__type_traits/add_pointer.h
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_ADD_POINTER_H
+#define _LIBCPP___TYPE_TRAITS_ADD_POINTER_H
+
+#include <__config>
+#include <__type_traits/is_referenceable.h>
+#include <__type_traits/is_same.h>
+#include <__type_traits/remove_cv.h>
+#include <__type_traits/remove_reference.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp,
+ bool = __is_referenceable<_Tp>::value ||
+ _IsSame<typename remove_cv<_Tp>::type, void>::value>
+struct __add_pointer_impl
+ {typedef _LIBCPP_NODEBUG typename remove_reference<_Tp>::type* type;};
+template <class _Tp> struct __add_pointer_impl<_Tp, false>
+ {typedef _LIBCPP_NODEBUG _Tp type;};
+
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS add_pointer
+ {typedef _LIBCPP_NODEBUG typename __add_pointer_impl<_Tp>::type type;};
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp> using add_pointer_t = typename add_pointer<_Tp>::type;
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_ADD_POINTER_H
diff --git a/libcxx/include/__type_traits/add_rvalue_reference.h b/libcxx/include/__type_traits/add_rvalue_reference.h
new file mode 100644
index 000000000000..b2a1428095d8
--- /dev/null
+++ b/libcxx/include/__type_traits/add_rvalue_reference.h
@@ -0,0 +1,33 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_ADD_RVALUE_REFERENCE_H
+#define _LIBCPP___TYPE_TRAITS_ADD_RVALUE_REFERENCE_H
+
+#include <__config>
+#include <__type_traits/is_referenceable.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp, bool = __is_referenceable<_Tp>::value> struct __add_rvalue_reference_impl { typedef _LIBCPP_NODEBUG _Tp type; };
+template <class _Tp > struct __add_rvalue_reference_impl<_Tp, true> { typedef _LIBCPP_NODEBUG _Tp&& type; };
+
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS add_rvalue_reference
+{typedef _LIBCPP_NODEBUG typename __add_rvalue_reference_impl<_Tp>::type type;};
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp> using add_rvalue_reference_t = typename add_rvalue_reference<_Tp>::type;
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_ADD_RVALUE_REFERENCE_H
diff --git a/libcxx/include/__type_traits/add_volatile.h b/libcxx/include/__type_traits/add_volatile.h
new file mode 100644
index 000000000000..73b1cb8418fe
--- /dev/null
+++ b/libcxx/include/__type_traits/add_volatile.h
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_ADD_VOLATILE_H
+#define _LIBCPP___TYPE_TRAITS_ADD_VOLATILE_H
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS add_volatile {
+ typedef _LIBCPP_NODEBUG volatile _Tp type;
+};
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp> using add_volatile_t = typename add_volatile<_Tp>::type;
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_ADD_VOLATILE_H
diff --git a/libcxx/include/__type_traits/alignment_of.h b/libcxx/include/__type_traits/alignment_of.h
new file mode 100644
index 000000000000..65c603058ffa
--- /dev/null
+++ b/libcxx/include/__type_traits/alignment_of.h
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_ALIGNMENT_OF_H
+#define _LIBCPP___TYPE_TRAITS_ALIGNMENT_OF_H
+
+#include <__config>
+#include <__type_traits/integral_constant.h>
+#include <cstddef>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS alignment_of
+ : public integral_constant<size_t, _LIBCPP_ALIGNOF(_Tp)> {};
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline constexpr size_t alignment_of_v = alignment_of<_Tp>::value;
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_ALIGNMENT_OF_H
diff --git a/libcxx/include/__type_traits/apply_cv.h b/libcxx/include/__type_traits/apply_cv.h
new file mode 100644
index 000000000000..4a5aab48a723
--- /dev/null
+++ b/libcxx/include/__type_traits/apply_cv.h
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_APPLY_CV_H
+#define _LIBCPP___TYPE_TRAITS_APPLY_CV_H
+
+#include <__config>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/is_const.h>
+#include <__type_traits/is_volatile.h>
+#include <__type_traits/remove_reference.h>
+#include <cstddef>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp, class _Up, bool = is_const<typename remove_reference<_Tp>::type>::value,
+ bool = is_volatile<typename remove_reference<_Tp>::type>::value>
+struct __apply_cv
+{
+ typedef _LIBCPP_NODEBUG _Up type;
+};
+
+template <class _Tp, class _Up>
+struct __apply_cv<_Tp, _Up, true, false>
+{
+ typedef _LIBCPP_NODEBUG const _Up type;
+};
+
+template <class _Tp, class _Up>
+struct __apply_cv<_Tp, _Up, false, true>
+{
+ typedef volatile _Up type;
+};
+
+template <class _Tp, class _Up>
+struct __apply_cv<_Tp, _Up, true, true>
+{
+ typedef const volatile _Up type;
+};
+
+template <class _Tp, class _Up>
+struct __apply_cv<_Tp&, _Up, false, false>
+{
+ typedef _Up& type;
+};
+
+template <class _Tp, class _Up>
+struct __apply_cv<_Tp&, _Up, true, false>
+{
+ typedef const _Up& type;
+};
+
+template <class _Tp, class _Up>
+struct __apply_cv<_Tp&, _Up, false, true>
+{
+ typedef volatile _Up& type;
+};
+
+template <class _Tp, class _Up>
+struct __apply_cv<_Tp&, _Up, true, true>
+{
+ typedef const volatile _Up& type;
+};
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_APPLY_CV_H
diff --git a/libcxx/include/__type_traits/conditional.h b/libcxx/include/__type_traits/conditional.h
new file mode 100644
index 000000000000..4b1a560ddc7c
--- /dev/null
+++ b/libcxx/include/__type_traits/conditional.h
@@ -0,0 +1,53 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_CONDITIONAL_H
+#define _LIBCPP___TYPE_TRAITS_CONDITIONAL_H
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <bool>
+struct _IfImpl;
+
+template <>
+struct _IfImpl<true> {
+ template <class _IfRes, class _ElseRes>
+ using _Select _LIBCPP_NODEBUG = _IfRes;
+};
+
+template <>
+struct _IfImpl<false> {
+ template <class _IfRes, class _ElseRes>
+ using _Select _LIBCPP_NODEBUG = _ElseRes;
+};
+
+template <bool _Cond, class _IfRes, class _ElseRes>
+using _If _LIBCPP_NODEBUG = typename _IfImpl<_Cond>::template _Select<_IfRes, _ElseRes>;
+
+template <bool _Bp, class _If, class _Then>
+ struct _LIBCPP_TEMPLATE_VIS conditional {typedef _If type;};
+template <class _If, class _Then>
+ struct _LIBCPP_TEMPLATE_VIS conditional<false, _If, _Then> {typedef _Then type;};
+
+#if _LIBCPP_STD_VER > 11
+template <bool _Bp, class _IfRes, class _ElseRes>
+using conditional_t = typename conditional<_Bp, _IfRes, _ElseRes>::type;
+#endif
+
+// Helper so we can use "conditional_t" in all language versions.
+template <bool _Bp, class _If, class _Then> using __conditional_t = typename conditional<_Bp, _If, _Then>::type;
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_CONDITIONAL_H
diff --git a/libcxx/include/__type_traits/conjunction.h b/libcxx/include/__type_traits/conjunction.h
new file mode 100644
index 000000000000..45fe5cdca351
--- /dev/null
+++ b/libcxx/include/__type_traits/conjunction.h
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_CONJUNCTION_H
+#define _LIBCPP___TYPE_TRAITS_CONJUNCTION_H
+
+#include <__config>
+#include <__type_traits/conditional.h>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/integral_constant.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 14
+
+template <class _Arg, class... _Args>
+struct __conjunction_impl {
+ using type = conditional_t<!bool(_Arg::value), _Arg, typename __conjunction_impl<_Args...>::type>;
+};
+
+template <class _Arg>
+struct __conjunction_impl<_Arg> {
+ using type = _Arg;
+};
+
+template <class... _Args>
+struct conjunction : __conjunction_impl<true_type, _Args...>::type {};
+
+template<class... _Args>
+inline constexpr bool conjunction_v = conjunction<_Args...>::value;
+
+#endif // _LIBCPP_STD_VER > 14
+
+template <class...>
+using __expand_to_true = true_type;
+
+template <class... _Pred>
+__expand_to_true<__enable_if_t<_Pred::value>...> __and_helper(int);
+
+template <class...>
+false_type __and_helper(...);
+
+template <class... _Pred>
+using _And _LIBCPP_NODEBUG = decltype(__and_helper<_Pred...>(0));
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_CONJUNCTION_H
diff --git a/libcxx/include/__type_traits/decay.h b/libcxx/include/__type_traits/decay.h
new file mode 100644
index 000000000000..d47ad03fe008
--- /dev/null
+++ b/libcxx/include/__type_traits/decay.h
@@ -0,0 +1,65 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_DECAY_H
+#define _LIBCPP___TYPE_TRAITS_DECAY_H
+
+#include <__config>
+#include <__type_traits/add_pointer.h>
+#include <__type_traits/conditional.h>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/is_array.h>
+#include <__type_traits/is_function.h>
+#include <__type_traits/is_referenceable.h>
+#include <__type_traits/remove_cv.h>
+#include <__type_traits/remove_extent.h>
+#include <__type_traits/remove_reference.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Up, bool>
+struct __decay {
+ typedef _LIBCPP_NODEBUG typename remove_cv<_Up>::type type;
+};
+
+template <class _Up>
+struct __decay<_Up, true> {
+public:
+ typedef _LIBCPP_NODEBUG typename conditional
+ <
+ is_array<_Up>::value,
+ typename remove_extent<_Up>::type*,
+ typename conditional
+ <
+ is_function<_Up>::value,
+ typename add_pointer<_Up>::type,
+ typename remove_cv<_Up>::type
+ >::type
+ >::type type;
+};
+
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS decay
+{
+private:
+ typedef _LIBCPP_NODEBUG typename remove_reference<_Tp>::type _Up;
+public:
+ typedef _LIBCPP_NODEBUG typename __decay<_Up, __is_referenceable<_Up>::value>::type type;
+};
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp> using decay_t = typename decay<_Tp>::type;
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_DECAY_H
diff --git a/libcxx/include/__type_traits/disjunction.h b/libcxx/include/__type_traits/disjunction.h
new file mode 100644
index 000000000000..6c6d1a8f21b6
--- /dev/null
+++ b/libcxx/include/__type_traits/disjunction.h
@@ -0,0 +1,53 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_DISJUNCTION_H
+#define _LIBCPP___TYPE_TRAITS_DISJUNCTION_H
+
+#include <__config>
+#include <__type_traits/conditional.h>
+#include <__type_traits/integral_constant.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <bool>
+struct _OrImpl;
+
+template <>
+struct _OrImpl<true> {
+ template <class _Res, class _First, class... _Rest>
+ using _Result _LIBCPP_NODEBUG =
+ typename _OrImpl<!bool(_First::value) && sizeof...(_Rest) != 0>::template _Result<_First, _Rest...>;
+};
+
+template <>
+struct _OrImpl<false> {
+ template <class _Res, class...>
+ using _Result = _Res;
+};
+
+template <class... _Args>
+using _Or _LIBCPP_NODEBUG = typename _OrImpl<sizeof...(_Args) != 0>::template _Result<false_type, _Args...>;
+
+#if _LIBCPP_STD_VER > 14
+
+template <class... _Args>
+struct disjunction : _Or<_Args...> {};
+
+template <class... _Args>
+inline constexpr bool disjunction_v = _Or<_Args...>::value;
+
+#endif // _LIBCPP_STD_VER > 14
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_DISJUNCTION_H
diff --git a/libcxx/include/__type_traits/enable_if.h b/libcxx/include/__type_traits/enable_if.h
new file mode 100644
index 000000000000..c5e8df45ea58
--- /dev/null
+++ b/libcxx/include/__type_traits/enable_if.h
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_ENABLE_IF_H
+#define _LIBCPP___TYPE_TRAITS_ENABLE_IF_H
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <bool, class _Tp = void> struct _LIBCPP_TEMPLATE_VIS enable_if {};
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS enable_if<true, _Tp> {typedef _Tp type;};
+
+template <bool _Bp, class _Tp = void> using __enable_if_t _LIBCPP_NODEBUG = typename enable_if<_Bp, _Tp>::type;
+
+#if _LIBCPP_STD_VER > 11
+template <bool _Bp, class _Tp = void> using enable_if_t = typename enable_if<_Bp, _Tp>::type;
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_ENABLE_IF_H
diff --git a/libcxx/include/__type_traits/extent.h b/libcxx/include/__type_traits/extent.h
new file mode 100644
index 000000000000..935ec4937c0a
--- /dev/null
+++ b/libcxx/include/__type_traits/extent.h
@@ -0,0 +1,55 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_EXTENT_H
+#define _LIBCPP___TYPE_TRAITS_EXTENT_H
+
+#include <__config>
+#include <__type_traits/integral_constant.h>
+#include <cstddef>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if __has_keyword(__array_extent)
+
+template<class _Tp, size_t _Dim = 0>
+struct _LIBCPP_TEMPLATE_VIS extent
+ : integral_constant<size_t, __array_extent(_Tp, _Dim)> { };
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp, unsigned _Ip = 0>
+inline constexpr size_t extent_v = __array_extent(_Tp, _Ip);
+#endif
+
+#else // __has_keyword(__array_extent)
+
+template <class _Tp, unsigned _Ip = 0> struct _LIBCPP_TEMPLATE_VIS extent
+ : public integral_constant<size_t, 0> {};
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS extent<_Tp[], 0>
+ : public integral_constant<size_t, 0> {};
+template <class _Tp, unsigned _Ip> struct _LIBCPP_TEMPLATE_VIS extent<_Tp[], _Ip>
+ : public integral_constant<size_t, extent<_Tp, _Ip-1>::value> {};
+template <class _Tp, size_t _Np> struct _LIBCPP_TEMPLATE_VIS extent<_Tp[_Np], 0>
+ : public integral_constant<size_t, _Np> {};
+template <class _Tp, size_t _Np, unsigned _Ip> struct _LIBCPP_TEMPLATE_VIS extent<_Tp[_Np], _Ip>
+ : public integral_constant<size_t, extent<_Tp, _Ip-1>::value> {};
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp, unsigned _Ip = 0>
+inline constexpr size_t extent_v = extent<_Tp, _Ip>::value;
+#endif
+
+#endif // __has_keyword(__array_extent)
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_EXTENT_H
diff --git a/libcxx/include/__type_traits/has_unique_object_representation.h b/libcxx/include/__type_traits/has_unique_object_representation.h
new file mode 100644
index 000000000000..d6f75c9ce5c9
--- /dev/null
+++ b/libcxx/include/__type_traits/has_unique_object_representation.h
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_HAS_UNIQUE_OBJECT_REPRESENTATION_H
+#define _LIBCPP___TYPE_TRAITS_HAS_UNIQUE_OBJECT_REPRESENTATION_H
+
+#include <__config>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/remove_all_extents.h>
+#include <__type_traits/remove_cv.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 14
+
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS has_unique_object_representations
+ : public integral_constant<bool,
+ __has_unique_object_representations(remove_cv_t<remove_all_extents_t<_Tp>>)> {};
+
+template <class _Tp>
+inline constexpr bool has_unique_object_representations_v = has_unique_object_representations<_Tp>::value;
+
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_HAS_UNIQUE_OBJECT_REPRESENTATION_H
diff --git a/libcxx/include/__type_traits/has_virtual_destructor.h b/libcxx/include/__type_traits/has_virtual_destructor.h
new file mode 100644
index 000000000000..33574373632e
--- /dev/null
+++ b/libcxx/include/__type_traits/has_virtual_destructor.h
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_HAS_VIRTUAL_DESTRUCTOR_H
+#define _LIBCPP___TYPE_TRAITS_HAS_VIRTUAL_DESTRUCTOR_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
+
+#if __has_feature(has_virtual_destructor) || defined(_LIBCPP_COMPILER_GCC)
+
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS has_virtual_destructor
+ : public integral_constant<bool, __has_virtual_destructor(_Tp)> {};
+
+#else
+
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS has_virtual_destructor
+ : public false_type {};
+
+#endif
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline constexpr bool has_virtual_destructor_v = has_virtual_destructor<_Tp>::value;
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_HAS_VIRTUAL_DESTRUCTOR_H
diff --git a/libcxx/include/__type_traits/integral_constant.h b/libcxx/include/__type_traits/integral_constant.h
new file mode 100644
index 000000000000..2449d1a906e8
--- /dev/null
+++ b/libcxx/include/__type_traits/integral_constant.h
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_INTEGRAL_CONSTANT_H
+#define _LIBCPP___TYPE_TRAITS_INTEGRAL_CONSTANT_H
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp, _Tp __v>
+struct _LIBCPP_TEMPLATE_VIS integral_constant
+{
+ static _LIBCPP_CONSTEXPR const _Tp value = __v;
+ typedef _Tp value_type;
+ typedef integral_constant type;
+ _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_CONSTEXPR operator value_type() const _NOEXCEPT {return value;}
+#if _LIBCPP_STD_VER > 11
+ _LIBCPP_INLINE_VISIBILITY
+ constexpr value_type operator ()() const _NOEXCEPT {return value;}
+#endif
+};
+
+template <class _Tp, _Tp __v>
+_LIBCPP_CONSTEXPR const _Tp integral_constant<_Tp, __v>::value;
+
+typedef integral_constant<bool, true> true_type;
+typedef integral_constant<bool, false> false_type;
+
+template <bool _Val>
+using _BoolConstant _LIBCPP_NODEBUG = integral_constant<bool, _Val>;
+
+#if _LIBCPP_STD_VER > 14
+template <bool __b>
+using bool_constant = integral_constant<bool, __b>;
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_INTEGRAL_CONSTANT_H
diff --git a/libcxx/include/__type_traits/is_abstract.h b/libcxx/include/__type_traits/is_abstract.h
new file mode 100644
index 000000000000..c74b3284f75d
--- /dev/null
+++ b/libcxx/include/__type_traits/is_abstract.h
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_ABSTRACT_H
+#define _LIBCPP___TYPE_TRAITS_IS_ABSTRACT_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> struct _LIBCPP_TEMPLATE_VIS is_abstract
+ : public integral_constant<bool, __is_abstract(_Tp)> {};
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline constexpr bool is_abstract_v = __is_abstract(_Tp);
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_ABSTRACT_H
diff --git a/libcxx/include/__type_traits/is_aggregate.h b/libcxx/include/__type_traits/is_aggregate.h
new file mode 100644
index 000000000000..ea9de84f96d0
--- /dev/null
+++ b/libcxx/include/__type_traits/is_aggregate.h
@@ -0,0 +1,33 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_AGGREGATE_H
+#define _LIBCPP___TYPE_TRAITS_IS_AGGREGATE_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
+
+#if _LIBCPP_STD_VER > 14
+
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS
+is_aggregate : public integral_constant<bool, __is_aggregate(_Tp)> {};
+
+template <class _Tp>
+inline constexpr bool is_aggregate_v = __is_aggregate(_Tp);
+
+#endif // _LIBCPP_STD_VER > 14
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_AGGREGATE_H
diff --git a/libcxx/include/__type_traits/is_arithmetic.h b/libcxx/include/__type_traits/is_arithmetic.h
new file mode 100644
index 000000000000..6d631f41c7d4
--- /dev/null
+++ b/libcxx/include/__type_traits/is_arithmetic.h
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_IS_ARITHMETIC_H
+#define _LIBCPP___TYPE_TRAITS_IS_ARITHMETIC_H
+
+#include <__config>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/is_floating_point.h>
+#include <__type_traits/is_integral.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_arithmetic
+ : public integral_constant<bool, is_integral<_Tp>::value ||
+ is_floating_point<_Tp>::value> {};
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline constexpr bool is_arithmetic_v = is_arithmetic<_Tp>::value;
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_ARITHMETIC_H
diff --git a/libcxx/include/__type_traits/is_array.h b/libcxx/include/__type_traits/is_array.h
new file mode 100644
index 000000000000..766d2a203028
--- /dev/null
+++ b/libcxx/include/__type_traits/is_array.h
@@ -0,0 +1,52 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_ARRAY_H
+#define _LIBCPP___TYPE_TRAITS_IS_ARRAY_H
+
+#include <__config>
+#include <__type_traits/integral_constant.h>
+#include <cstddef>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+// TODO: Clang incorrectly reports that __is_array is true for T[0].
+// Re-enable the branch once https://llvm.org/PR54705 is fixed.
+#if __has_keyword(__is_array) && 0
+
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_array : _BoolConstant<__is_array(_Tp)> { };
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline constexpr bool is_array_v = __is_array(_Tp);
+#endif
+
+#else
+
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_array
+ : public false_type {};
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_array<_Tp[]>
+ : public true_type {};
+template <class _Tp, size_t _Np> struct _LIBCPP_TEMPLATE_VIS is_array<_Tp[_Np]>
+ : public true_type {};
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline constexpr bool is_array_v = is_array<_Tp>::value;
+#endif
+
+#endif // __has_keyword(__is_array)
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_ARRAY_H
diff --git a/libcxx/include/__type_traits/is_assignable.h b/libcxx/include/__type_traits/is_assignable.h
new file mode 100644
index 000000000000..edc864cae065
--- /dev/null
+++ b/libcxx/include/__type_traits/is_assignable.h
@@ -0,0 +1,66 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_ASSIGNABLE_H
+#define _LIBCPP___TYPE_TRAITS_IS_ASSIGNABLE_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<typename, typename _Tp> struct __select_2nd { typedef _LIBCPP_NODEBUG _Tp type; };
+
+#if __has_keyword(__is_assignable)
+
+template<class _Tp, class _Up>
+struct _LIBCPP_TEMPLATE_VIS is_assignable : _BoolConstant<__is_assignable(_Tp, _Up)> { };
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp, class _Arg>
+inline constexpr bool is_assignable_v = __is_assignable(_Tp, _Arg);
+#endif
+
+#else // __has_keyword(__is_assignable)
+
+template <class _Tp, class _Arg>
+typename __select_2nd<decltype((declval<_Tp>() = declval<_Arg>())), true_type>::type
+__is_assignable_test(int);
+
+template <class, class>
+false_type __is_assignable_test(...);
+
+
+template <class _Tp, class _Arg, bool = is_void<_Tp>::value || is_void<_Arg>::value>
+struct __is_assignable_imp
+ : public decltype((_VSTD::__is_assignable_test<_Tp, _Arg>(0))) {};
+
+template <class _Tp, class _Arg>
+struct __is_assignable_imp<_Tp, _Arg, true>
+ : public false_type
+{
+};
+
+template <class _Tp, class _Arg>
+struct is_assignable
+ : public __is_assignable_imp<_Tp, _Arg> {};
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp, class _Arg>
+inline constexpr bool is_assignable_v = is_assignable<_Tp, _Arg>::value;
+#endif
+
+#endif // __has_keyword(__is_assignable)
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_ASSIGNABLE_H
diff --git a/libcxx/include/__type_traits/is_base_of.h b/libcxx/include/__type_traits/is_base_of.h
new file mode 100644
index 000000000000..0e6dec0b5ee0
--- /dev/null
+++ b/libcxx/include/__type_traits/is_base_of.h
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_BASE_OF_H
+#define _LIBCPP___TYPE_TRAITS_IS_BASE_OF_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 _Bp, class _Dp>
+struct _LIBCPP_TEMPLATE_VIS is_base_of
+ : public integral_constant<bool, __is_base_of(_Bp, _Dp)> {};
+
+#if _LIBCPP_STD_VER > 14
+template <class _Bp, class _Dp>
+inline constexpr bool is_base_of_v = __is_base_of(_Bp, _Dp);
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_BASE_OF_H
diff --git a/libcxx/include/__type_traits/is_bounded_array.h b/libcxx/include/__type_traits/is_bounded_array.h
new file mode 100644
index 000000000000..27de9dfd3864
--- /dev/null
+++ b/libcxx/include/__type_traits/is_bounded_array.h
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_IS_BOUNDED_ARRAY_H
+#define _LIBCPP___TYPE_TRAITS_IS_BOUNDED_ARRAY_H
+
+#include <__config>
+#include <__type_traits/integral_constant.h>
+#include <cstddef>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class> struct _LIBCPP_TEMPLATE_VIS __libcpp_is_bounded_array : false_type {};
+template <class _Tp, size_t _Np> struct _LIBCPP_TEMPLATE_VIS __libcpp_is_bounded_array<_Tp[_Np]> : true_type {};
+
+#if _LIBCPP_STD_VER > 17
+
+template <class> struct _LIBCPP_TEMPLATE_VIS is_bounded_array : false_type {};
+template <class _Tp, size_t _Np> struct _LIBCPP_TEMPLATE_VIS is_bounded_array<_Tp[_Np]> : true_type {};
+
+template <class _Tp>
+inline constexpr
+bool is_bounded_array_v = is_bounded_array<_Tp>::value;
+
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_BOUNDED_ARRAY_H
diff --git a/libcxx/include/__type_traits/is_callable.h b/libcxx/include/__type_traits/is_callable.h
new file mode 100644
index 000000000000..73f894dce94c
--- /dev/null
+++ b/libcxx/include/__type_traits/is_callable.h
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_CALLABLE_H
+#define _LIBCPP___TYPE_TRAITS_IS_CALLABLE_H
+
+#include <__config>
+#include <__type_traits/integral_constant.h>
+#include <__utility/declval.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template<class _Func, class... _Args, class = decltype(std::declval<_Func>()(std::declval<_Args>()...))>
+true_type __is_callable_helper(int);
+template<class...>
+false_type __is_callable_helper(...);
+
+template<class _Func, class... _Args>
+struct __is_callable : decltype(__is_callable_helper<_Func, _Args...>(0)) {};
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_CALLABLE_H
diff --git a/libcxx/include/__type_traits/is_class.h b/libcxx/include/__type_traits/is_class.h
new file mode 100644
index 000000000000..cddaeae6e8a9
--- /dev/null
+++ b/libcxx/include/__type_traits/is_class.h
@@ -0,0 +1,33 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_CLASS_H
+#define _LIBCPP___TYPE_TRAITS_IS_CLASS_H
+
+#include <__config>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/is_union.h>
+#include <__type_traits/remove_cv.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_class
+ : public integral_constant<bool, __is_class(_Tp)> {};
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline constexpr bool is_class_v = __is_class(_Tp);
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_CLASS_H
diff --git a/libcxx/include/__type_traits/is_compound.h b/libcxx/include/__type_traits/is_compound.h
new file mode 100644
index 000000000000..643edd78229a
--- /dev/null
+++ b/libcxx/include/__type_traits/is_compound.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___TYPE_TRAITS_IS_COMPOUND_H
+#define _LIBCPP___TYPE_TRAITS_IS_COMPOUND_H
+
+#include <__config>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/is_fundamental.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if __has_keyword(__is_compound)
+
+template<class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_compound : _BoolConstant<__is_compound(_Tp)> { };
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline constexpr bool is_compound_v = __is_compound(_Tp);
+#endif
+
+#else // __has_keyword(__is_compound)
+
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_compound
+ : public integral_constant<bool, !is_fundamental<_Tp>::value> {};
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline constexpr bool is_compound_v = is_compound<_Tp>::value;
+#endif
+
+#endif // __has_keyword(__is_compound)
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_COMPOUND_H
diff --git a/libcxx/include/__type_traits/is_const.h b/libcxx/include/__type_traits/is_const.h
new file mode 100644
index 000000000000..5501832f560b
--- /dev/null
+++ b/libcxx/include/__type_traits/is_const.h
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_IS_CONST_H
+#define _LIBCPP___TYPE_TRAITS_IS_CONST_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
+
+#if __has_keyword(__is_const)
+
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_const : _BoolConstant<__is_const(_Tp)> { };
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline constexpr bool is_const_v = __is_const(_Tp);
+#endif
+
+#else
+
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_const : public false_type {};
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_const<_Tp const> : public true_type {};
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline constexpr bool is_const_v = is_const<_Tp>::value;
+#endif
+
+#endif // __has_keyword(__is_const)
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_CONST_H
diff --git a/libcxx/include/__type_traits/is_constant_evaluated.h b/libcxx/include/__type_traits/is_constant_evaluated.h
new file mode 100644
index 000000000000..de5ff6c43f40
--- /dev/null
+++ b/libcxx/include/__type_traits/is_constant_evaluated.h
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_CONSTANT_EVALUATED_H
+#define _LIBCPP___TYPE_TRAITS_IS_CONSTANT_EVALUATED_H
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 17
+_LIBCPP_INLINE_VISIBILITY
+inline constexpr bool is_constant_evaluated() noexcept {
+ return __builtin_is_constant_evaluated();
+}
+#endif
+
+inline _LIBCPP_CONSTEXPR
+bool __libcpp_is_constant_evaluated() _NOEXCEPT { return __builtin_is_constant_evaluated(); }
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_CONSTANT_EVALUATED_H
diff --git a/libcxx/include/__type_traits/is_constructible.h b/libcxx/include/__type_traits/is_constructible.h
new file mode 100644
index 000000000000..9a96c3df13e8
--- /dev/null
+++ b/libcxx/include/__type_traits/is_constructible.h
@@ -0,0 +1,33 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_IS_CONSTRUCTIBLE_H
+#define _LIBCPP___TYPE_IS_CONSTRUCTIBLE_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, class ..._Args>
+struct _LIBCPP_TEMPLATE_VIS is_constructible
+ : public integral_constant<bool, __is_constructible(_Tp, _Args...)>
+{ };
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp, class ..._Args>
+inline constexpr bool is_constructible_v = is_constructible<_Tp, _Args...>::value;
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_IS_CONSTRUCTIBLE_H
diff --git a/libcxx/include/__type_traits/is_convertible.h b/libcxx/include/__type_traits/is_convertible.h
new file mode 100644
index 000000000000..884e808e2ae4
--- /dev/null
+++ b/libcxx/include/__type_traits/is_convertible.h
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_IS_CONVERTIBLE_H
+#define _LIBCPP___TYPE_TRAITS_IS_CONVERTIBLE_H
+
+#include <__config>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/is_array.h>
+#include <__type_traits/is_function.h>
+#include <__type_traits/is_void.h>
+#include <__type_traits/remove_reference.h>
+#include <__utility/declval.h>
+#include <cstddef>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if __has_feature(is_convertible_to) && !defined(_LIBCPP_USE_IS_CONVERTIBLE_FALLBACK)
+
+template <class _T1, class _T2> struct _LIBCPP_TEMPLATE_VIS is_convertible
+ : public integral_constant<bool, __is_convertible_to(_T1, _T2)> {};
+
+#else // __has_feature(is_convertible_to)
+
+namespace __is_convertible_imp
+{
+template <class _Tp> void __test_convert(_Tp);
+
+template <class _From, class _To, class = void>
+struct __is_convertible_test : public false_type {};
+
+template <class _From, class _To>
+struct __is_convertible_test<_From, _To,
+ decltype(__is_convertible_imp::__test_convert<_To>(declval<_From>()))> : public true_type
+{};
+
+template <class _Tp, bool _IsArray = is_array<_Tp>::value,
+ bool _IsFunction = is_function<_Tp>::value,
+ bool _IsVoid = is_void<_Tp>::value>
+ struct __is_array_function_or_void {enum {value = 0};};
+template <class _Tp> struct __is_array_function_or_void<_Tp, true, false, false> {enum {value = 1};};
+template <class _Tp> struct __is_array_function_or_void<_Tp, false, true, false> {enum {value = 2};};
+template <class _Tp> struct __is_array_function_or_void<_Tp, false, false, true> {enum {value = 3};};
+}
+
+template <class _Tp,
+ unsigned = __is_convertible_imp::__is_array_function_or_void<typename remove_reference<_Tp>::type>::value>
+struct __is_convertible_check
+{
+ static const size_t __v = 0;
+};
+
+template <class _Tp>
+struct __is_convertible_check<_Tp, 0>
+{
+ static const size_t __v = sizeof(_Tp);
+};
+
+template <class _T1, class _T2,
+ unsigned _T1_is_array_function_or_void = __is_convertible_imp::__is_array_function_or_void<_T1>::value,
+ unsigned _T2_is_array_function_or_void = __is_convertible_imp::__is_array_function_or_void<_T2>::value>
+struct __is_convertible
+ : public integral_constant<bool,
+ __is_convertible_imp::__is_convertible_test<_T1, _T2>::value
+ >
+{};
+
+template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 0, 1> : public false_type {};
+template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 1, 1> : public false_type {};
+template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 2, 1> : public false_type {};
+template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 3, 1> : public false_type {};
+
+template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 0, 2> : public false_type {};
+template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 1, 2> : public false_type {};
+template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 2, 2> : public false_type {};
+template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 3, 2> : public false_type {};
+
+template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 0, 3> : public false_type {};
+template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 1, 3> : public false_type {};
+template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 2, 3> : public false_type {};
+template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 3, 3> : public true_type {};
+
+template <class _T1, class _T2> struct _LIBCPP_TEMPLATE_VIS is_convertible
+ : public __is_convertible<_T1, _T2>
+{
+ static const size_t __complete_check1 = __is_convertible_check<_T1>::__v;
+ static const size_t __complete_check2 = __is_convertible_check<_T2>::__v;
+};
+
+#endif // __has_feature(is_convertible_to)
+
+#if _LIBCPP_STD_VER > 14
+template <class _From, class _To>
+inline constexpr bool is_convertible_v = is_convertible<_From, _To>::value;
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_CONVERTIBLE_H
diff --git a/libcxx/include/__type_traits/is_copy_assignable.h b/libcxx/include/__type_traits/is_copy_assignable.h
new file mode 100644
index 000000000000..e46b1249459e
--- /dev/null
+++ b/libcxx/include/__type_traits/is_copy_assignable.h
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_IS_COPY_ASSIGNABLE_H
+#define _LIBCPP___TYPE_TRAITS_IS_COPY_ASSIGNABLE_H
+
+#include <__config>
+#include <__type_traits/add_const.h>
+#include <__type_traits/add_lvalue_reference.h>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/is_assignable.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_copy_assignable
+ : public is_assignable<typename add_lvalue_reference<_Tp>::type,
+ typename add_lvalue_reference<typename add_const<_Tp>::type>::type> {};
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline constexpr bool is_copy_assignable_v = is_copy_assignable<_Tp>::value;
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_COPY_ASSIGNABLE_H
diff --git a/libcxx/include/__type_traits/is_copy_constructible.h b/libcxx/include/__type_traits/is_copy_constructible.h
new file mode 100644
index 000000000000..18dc27f2ef75
--- /dev/null
+++ b/libcxx/include/__type_traits/is_copy_constructible.h
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_COPY_CONSTRUCTIBLE_H
+#define _LIBCPP___TYPE_TRAITS_IS_COPY_CONSTRUCTIBLE_H
+
+#include <__config>
+#include <__type_traits/add_const.h>
+#include <__type_traits/add_lvalue_reference.h>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/is_constructible.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_copy_constructible
+ : public is_constructible<_Tp,
+ typename add_lvalue_reference<typename add_const<_Tp>::type>::type> {};
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline constexpr bool is_copy_constructible_v = is_copy_constructible<_Tp>::value;
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_COPY_CONSTRUCTIBLE_H
diff --git a/libcxx/include/__type_traits/is_core_convertible.h b/libcxx/include/__type_traits/is_core_convertible.h
new file mode 100644
index 000000000000..1ce407913052
--- /dev/null
+++ b/libcxx/include/__type_traits/is_core_convertible.h
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_CORE_CONVERTIBLE_H
+#define _LIBCPP___TYPE_TRAITS_IS_CORE_CONVERTIBLE_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
+
+// [conv.general]/3 says "E is convertible to T" whenever "T t=E;" is well-formed.
+// We can't test for that, but we can test implicit convertibility by passing it
+// to a function. Notice that __is_core_convertible<void,void> is false,
+// and __is_core_convertible<immovable-type,immovable-type> is true in C++17 and later.
+
+template <class _Tp, class _Up, class = void>
+struct __is_core_convertible : public false_type {};
+
+template <class _Tp, class _Up>
+struct __is_core_convertible<_Tp, _Up, decltype(
+ static_cast<void(*)(_Up)>(0) ( static_cast<_Tp(*)()>(0)() )
+)> : public true_type {};
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_CORE_CONVERTIBLE_H
diff --git a/libcxx/include/__type_traits/is_default_constructible.h b/libcxx/include/__type_traits/is_default_constructible.h
new file mode 100644
index 000000000000..a6368413d6b4
--- /dev/null
+++ b/libcxx/include/__type_traits/is_default_constructible.h
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_IS_DEFAULT_CONSTRUCTIBLE_H
+#define _LIBCPP___TYPE_TRAITS_IS_DEFAULT_CONSTRUCTIBLE_H
+
+#include <__config>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/is_constructible.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_default_constructible
+ : public is_constructible<_Tp>
+ {};
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline constexpr bool is_default_constructible_v = is_default_constructible<_Tp>::value;
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_DEFAULT_CONSTRUCTIBLE_H
diff --git a/libcxx/include/__type_traits/is_destructible.h b/libcxx/include/__type_traits/is_destructible.h
new file mode 100644
index 000000000000..489451007873
--- /dev/null
+++ b/libcxx/include/__type_traits/is_destructible.h
@@ -0,0 +1,102 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_DESTRUCTIBLE_H
+#define _LIBCPP___TYPE_TRAITS_IS_DESTRUCTIBLE_H
+
+#include <__config>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/is_function.h>
+#include <__type_traits/is_reference.h>
+#include <__type_traits/remove_all_extents.h>
+#include <__utility/declval.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if __has_keyword(__is_destructible)
+
+template<class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_destructible : _BoolConstant<__is_destructible(_Tp)> { };
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline constexpr bool is_destructible_v = __is_destructible(_Tp);
+#endif
+
+#else // __has_keyword(__is_destructible)
+
+// if it's a reference, return true
+// if it's a function, return false
+// if it's void, return false
+// if it's an array of unknown bound, return false
+// Otherwise, return "declval<_Up&>().~_Up()" is well-formed
+// where _Up is remove_all_extents<_Tp>::type
+
+template <class>
+struct __is_destructible_apply { typedef int type; };
+
+template <typename _Tp>
+struct __is_destructor_wellformed {
+ template <typename _Tp1>
+ static true_type __test (
+ typename __is_destructible_apply<decltype(declval<_Tp1&>().~_Tp1())>::type
+ );
+
+ template <typename _Tp1>
+ static false_type __test (...);
+
+ static const bool value = decltype(__test<_Tp>(12))::value;
+};
+
+template <class _Tp, bool>
+struct __destructible_imp;
+
+template <class _Tp>
+struct __destructible_imp<_Tp, false>
+ : public integral_constant<bool,
+ __is_destructor_wellformed<typename remove_all_extents<_Tp>::type>::value> {};
+
+template <class _Tp>
+struct __destructible_imp<_Tp, true>
+ : public true_type {};
+
+template <class _Tp, bool>
+struct __destructible_false;
+
+template <class _Tp>
+struct __destructible_false<_Tp, false> : public __destructible_imp<_Tp, is_reference<_Tp>::value> {};
+
+template <class _Tp>
+struct __destructible_false<_Tp, true> : public false_type {};
+
+template <class _Tp>
+struct is_destructible
+ : public __destructible_false<_Tp, is_function<_Tp>::value> {};
+
+template <class _Tp>
+struct is_destructible<_Tp[]>
+ : public false_type {};
+
+template <>
+struct is_destructible<void>
+ : public false_type {};
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline constexpr bool is_destructible_v = is_destructible<_Tp>::value;
+#endif
+
+#endif // __has_keyword(__is_destructible)
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_DESTRUCTIBLE_H
diff --git a/libcxx/include/__type_traits/is_empty.h b/libcxx/include/__type_traits/is_empty.h
new file mode 100644
index 000000000000..042b4e68074c
--- /dev/null
+++ b/libcxx/include/__type_traits/is_empty.h
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_EMPTY_H
+#define _LIBCPP___TYPE_TRAITS_IS_EMPTY_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>
+struct _LIBCPP_TEMPLATE_VIS is_empty
+ : public integral_constant<bool, __is_empty(_Tp)> {};
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline constexpr bool is_empty_v = __is_empty(_Tp);
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_EMPTY_H
diff --git a/libcxx/include/__type_traits/is_enum.h b/libcxx/include/__type_traits/is_enum.h
new file mode 100644
index 000000000000..bf6921c88c94
--- /dev/null
+++ b/libcxx/include/__type_traits/is_enum.h
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_ENUM_H
+#define _LIBCPP___TYPE_TRAITS_IS_ENUM_H
+
+#include <__config>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/remove_cv.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_enum
+ : public integral_constant<bool, __is_enum(_Tp)> {};
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline constexpr bool is_enum_v = __is_enum(_Tp);
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_ENUM_H
diff --git a/libcxx/include/__type_traits/is_final.h b/libcxx/include/__type_traits/is_final.h
new file mode 100644
index 000000000000..74ced23a14e0
--- /dev/null
+++ b/libcxx/include/__type_traits/is_final.h
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_FINAL_H
+#define _LIBCPP___TYPE_TRAITS_IS_FINAL_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> struct _LIBCPP_TEMPLATE_VIS
+__libcpp_is_final : public integral_constant<bool, __is_final(_Tp)> {};
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS
+is_final : public integral_constant<bool, __is_final(_Tp)> {};
+#endif
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline constexpr bool is_final_v = __is_final(_Tp);
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_FINAL_H
diff --git a/libcxx/include/__type_traits/is_floating_point.h b/libcxx/include/__type_traits/is_floating_point.h
new file mode 100644
index 000000000000..d93e5d99d07b
--- /dev/null
+++ b/libcxx/include/__type_traits/is_floating_point.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___TYPE_TRAITS_IS_FLOATING_POINT_H
+#define _LIBCPP___TYPE_TRAITS_IS_FLOATING_POINT_H
+
+#include <__config>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/remove_cv.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp> struct __libcpp_is_floating_point : public false_type {};
+template <> struct __libcpp_is_floating_point<float> : public true_type {};
+template <> struct __libcpp_is_floating_point<double> : public true_type {};
+template <> struct __libcpp_is_floating_point<long double> : public true_type {};
+
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_floating_point
+ : public __libcpp_is_floating_point<typename remove_cv<_Tp>::type> {};
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline constexpr bool is_floating_point_v = is_floating_point<_Tp>::value;
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_FLOATING_POINT_H
diff --git a/libcxx/include/__type_traits/is_function.h b/libcxx/include/__type_traits/is_function.h
new file mode 100644
index 000000000000..bce980c21b4e
--- /dev/null
+++ b/libcxx/include/__type_traits/is_function.h
@@ -0,0 +1,43 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_FUNCTIONAL_H
+#define _LIBCPP___TYPE_TRAITS_IS_FUNCTIONAL_H
+
+#include <__config>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/is_const.h>
+#include <__type_traits/is_reference.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if __has_keyword(__is_function)
+
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_function : integral_constant<bool, __is_function(_Tp)> {};
+
+#else
+
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_function
+ : public integral_constant<bool, !(is_reference<_Tp>::value || is_const<const _Tp>::value)> {};
+
+#endif // __has_keyword(__is_function)
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline constexpr bool is_function_v = is_function<_Tp>::value;
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_FUNCTIONAL_H
diff --git a/libcxx/include/__type_traits/is_fundamental.h b/libcxx/include/__type_traits/is_fundamental.h
new file mode 100644
index 000000000000..aaa7063eef9b
--- /dev/null
+++ b/libcxx/include/__type_traits/is_fundamental.h
@@ -0,0 +1,49 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_FUNDAMENTAL_H
+#define _LIBCPP___TYPE_TRAITS_IS_FUNDAMENTAL_H
+
+#include <__config>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/is_null_pointer.h>
+#include <__type_traits/is_void.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if __has_keyword(__is_fundamental)
+
+template<class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_fundamental : _BoolConstant<__is_fundamental(_Tp)> { };
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline constexpr bool is_fundamental_v = __is_fundamental(_Tp);
+#endif
+
+#else // __has_keyword(__is_fundamental)
+
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_fundamental
+ : public integral_constant<bool, is_void<_Tp>::value ||
+ __is_nullptr_t<_Tp>::value ||
+ is_arithmetic<_Tp>::value> {};
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline constexpr bool is_fundamental_v = is_fundamental<_Tp>::value;
+#endif
+
+#endif // __has_keyword(__is_fundamental)
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_FUNDAMENTAL_H
diff --git a/libcxx/include/__type_traits/is_integral.h b/libcxx/include/__type_traits/is_integral.h
new file mode 100644
index 000000000000..09378735d94e
--- /dev/null
+++ b/libcxx/include/__type_traits/is_integral.h
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_IS_INTEGRAL_H
+#define _LIBCPP___TYPE_TRAITS_IS_INTEGRAL_H
+
+#include <__config>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/remove_cv.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp> struct __libcpp_is_integral { enum { value = 0 }; };
+template <> struct __libcpp_is_integral<bool> { enum { value = 1 }; };
+template <> struct __libcpp_is_integral<char> { enum { value = 1 }; };
+template <> struct __libcpp_is_integral<signed char> { enum { value = 1 }; };
+template <> struct __libcpp_is_integral<unsigned char> { enum { value = 1 }; };
+#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+template <> struct __libcpp_is_integral<wchar_t> { enum { value = 1 }; };
+#endif
+#ifndef _LIBCPP_HAS_NO_CHAR8_T
+template <> struct __libcpp_is_integral<char8_t> { enum { value = 1 }; };
+#endif
+template <> struct __libcpp_is_integral<char16_t> { enum { value = 1 }; };
+template <> struct __libcpp_is_integral<char32_t> { enum { value = 1 }; };
+template <> struct __libcpp_is_integral<short> { enum { value = 1 }; };
+template <> struct __libcpp_is_integral<unsigned short> { enum { value = 1 }; };
+template <> struct __libcpp_is_integral<int> { enum { value = 1 }; };
+template <> struct __libcpp_is_integral<unsigned int> { enum { value = 1 }; };
+template <> struct __libcpp_is_integral<long> { enum { value = 1 }; };
+template <> struct __libcpp_is_integral<unsigned long> { enum { value = 1 }; };
+template <> struct __libcpp_is_integral<long long> { enum { value = 1 }; };
+template <> struct __libcpp_is_integral<unsigned long long> { enum { value = 1 }; };
+#ifndef _LIBCPP_HAS_NO_INT128
+template <> struct __libcpp_is_integral<__int128_t> { enum { value = 1 }; };
+template <> struct __libcpp_is_integral<__uint128_t> { enum { value = 1 }; };
+#endif
+
+#if __has_keyword(__is_integral)
+
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_integral : _BoolConstant<__is_integral(_Tp)> { };
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline constexpr bool is_integral_v = __is_integral(_Tp);
+#endif
+
+#else
+
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_integral
+ : public _BoolConstant<__libcpp_is_integral<typename remove_cv<_Tp>::type>::value> {};
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline constexpr bool is_integral_v = is_integral<_Tp>::value;
+#endif
+
+#endif // __has_keyword(__is_integral)
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_INTEGRAL_H
diff --git a/libcxx/include/__type_traits/is_literal_type.h b/libcxx/include/__type_traits/is_literal_type.h
new file mode 100644
index 000000000000..df525ecee208
--- /dev/null
+++ b/libcxx/include/__type_traits/is_literal_type.h
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_IS_LITERAL_TYPE
+#define _LIBCPP___TYPE_TRAITS_IS_LITERAL_TYPE
+
+#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
+
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS)
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 is_literal_type
+ : public integral_constant<bool, __is_literal_type(_Tp)>
+ {};
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+_LIBCPP_DEPRECATED_IN_CXX17 inline constexpr bool is_literal_type_v = is_literal_type<_Tp>::value;
+#endif // _LIBCPP_STD_VER > 14
+#endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS)
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_LITERAL_TYPE
diff --git a/libcxx/include/__type_traits/is_member_function_pointer.h b/libcxx/include/__type_traits/is_member_function_pointer.h
new file mode 100644
index 000000000000..f18f3ebc5a3a
--- /dev/null
+++ b/libcxx/include/__type_traits/is_member_function_pointer.h
@@ -0,0 +1,64 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_MEMBER_FUNCTION_POINTER_H
+#define _LIBCPP___TYPE_TRAITS_IS_MEMBER_FUNCTION_POINTER_H
+
+#include <__config>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/is_function.h>
+#include <__type_traits/remove_cv.h>
+#include <cstddef>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp> struct __libcpp_is_member_pointer {
+ enum {
+ __is_member = false,
+ __is_func = false,
+ __is_obj = false
+ };
+};
+template <class _Tp, class _Up> struct __libcpp_is_member_pointer<_Tp _Up::*> {
+ enum {
+ __is_member = true,
+ __is_func = is_function<_Tp>::value,
+ __is_obj = !__is_func,
+ };
+};
+
+#if __has_keyword(__is_member_function_pointer)
+
+template<class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_member_function_pointer
+ : _BoolConstant<__is_member_function_pointer(_Tp)> { };
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline constexpr bool is_member_function_pointer_v = __is_member_function_pointer(_Tp);
+#endif
+
+#else // __has_keyword(__is_member_function_pointer)
+
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_member_function_pointer
+ : public _BoolConstant< __libcpp_is_member_pointer<typename remove_cv<_Tp>::type>::__is_func > {};
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline constexpr bool is_member_function_pointer_v = is_member_function_pointer<_Tp>::value;
+#endif
+
+#endif // __has_keyword(__is_member_function_pointer)
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_MEMBER_FUNCTION_POINTER_H
diff --git a/libcxx/include/__type_traits/is_member_object_pointer.h b/libcxx/include/__type_traits/is_member_object_pointer.h
new file mode 100644
index 000000000000..41f81d529388
--- /dev/null
+++ b/libcxx/include/__type_traits/is_member_object_pointer.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___TYPE_TRAITS_IS_MEMBER_OBJECT_POINTER_H
+#define _LIBCPP___TYPE_TRAITS_IS_MEMBER_OBJECT_POINTER_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
+
+#if __has_keyword(__is_member_object_pointer)
+
+template<class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_member_object_pointer
+ : _BoolConstant<__is_member_object_pointer(_Tp)> { };
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline constexpr bool is_member_object_pointer_v = __is_member_object_pointer(_Tp);
+#endif
+
+#else // __has_keyword(__is_member_object_pointer)
+
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_member_object_pointer
+ : public _BoolConstant< __libcpp_is_member_pointer<typename remove_cv<_Tp>::type>::__is_obj > {};
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline constexpr bool is_member_object_pointer_v = is_member_object_pointer<_Tp>::value;
+#endif
+
+#endif // __has_keyword(__is_member_object_pointer)
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_MEMBER_FUNCTION_POINTER_H
diff --git a/libcxx/include/__type_traits/is_member_pointer.h b/libcxx/include/__type_traits/is_member_pointer.h
new file mode 100644
index 000000000000..76595dfdab7f
--- /dev/null
+++ b/libcxx/include/__type_traits/is_member_pointer.h
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_IS_MEMBER_POINTER_H
+#define _LIBCPP___TYPE_TRAITS_IS_MEMBER_POINTER_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
+
+#if __has_keyword(__is_member_pointer)
+
+template<class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_member_pointer : _BoolConstant<__is_member_pointer(_Tp)> { };
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline constexpr bool is_member_pointer_v = __is_member_pointer(_Tp);
+#endif
+
+#else // __has_keyword(__is_member_pointer)
+
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_member_pointer
+ : public _BoolConstant< __libcpp_is_member_pointer<typename remove_cv<_Tp>::type>::__is_member > {};
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline constexpr bool is_member_pointer_v = is_member_pointer<_Tp>::value;
+#endif
+
+#endif // __has_keyword(__is_member_pointer)
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_MEMBER_POINTER_H
diff --git a/libcxx/include/__type_traits/is_move_assignable.h b/libcxx/include/__type_traits/is_move_assignable.h
new file mode 100644
index 000000000000..1e8aa23bea37
--- /dev/null
+++ b/libcxx/include/__type_traits/is_move_assignable.h
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_MOVE_ASSIGNABLE_H
+#define _LIBCPP___TYPE_TRAITS_IS_MOVE_ASSIGNABLE_H
+
+#include <__config>
+#include <__type_traits/add_const.h>
+#include <__type_traits/add_lvalue_reference.h>
+#include <__type_traits/add_rvalue_reference.h>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/is_assignable.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_move_assignable
+ : public is_assignable<typename add_lvalue_reference<_Tp>::type,
+ typename add_rvalue_reference<_Tp>::type> {};
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline constexpr bool is_move_assignable_v = is_move_assignable<_Tp>::value;
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_MOVE_ASSIGNABLE_H
diff --git a/libcxx/include/__type_traits/is_move_constructible.h b/libcxx/include/__type_traits/is_move_constructible.h
new file mode 100644
index 000000000000..228cee7efffa
--- /dev/null
+++ b/libcxx/include/__type_traits/is_move_constructible.h
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_IS_MOVE_CONSTRUCTIBLE_H
+#define _LIBCPP___TYPE_TRAITS_IS_MOVE_CONSTRUCTIBLE_H
+
+#include <__config>
+#include <__type_traits/add_rvalue_reference.h>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/is_constructible.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_move_constructible
+ : public is_constructible<_Tp, typename add_rvalue_reference<_Tp>::type>
+ {};
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline constexpr bool is_move_constructible_v = is_move_constructible<_Tp>::value;
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_MOVE_CONSTRUCTIBLE_H
diff --git a/libcxx/include/__type_traits/is_nothrow_assignable.h b/libcxx/include/__type_traits/is_nothrow_assignable.h
new file mode 100644
index 000000000000..18e0e70a561d
--- /dev/null
+++ b/libcxx/include/__type_traits/is_nothrow_assignable.h
@@ -0,0 +1,59 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_NOTHROW_ASSIGNABLE_H
+#define _LIBCPP___TYPE_TRAITS_IS_NOTHROW_ASSIGNABLE_H
+
+#include <__config>
+#include <__type_traits/add_const.h>
+#include <__type_traits/integral_constant.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if __has_keyword(__is_nothrow_assignable)
+
+template <class _Tp, class _Arg>
+struct _LIBCPP_TEMPLATE_VIS is_nothrow_assignable
+ : public integral_constant<bool, __is_nothrow_assignable(_Tp, _Arg)> {};
+
+#else
+
+template <bool, class _Tp, class _Arg> struct __libcpp_is_nothrow_assignable;
+
+template <class _Tp, class _Arg>
+struct __libcpp_is_nothrow_assignable<false, _Tp, _Arg>
+ : public false_type
+{
+};
+
+template <class _Tp, class _Arg>
+struct __libcpp_is_nothrow_assignable<true, _Tp, _Arg>
+ : public integral_constant<bool, noexcept(declval<_Tp>() = declval<_Arg>()) >
+{
+};
+
+template <class _Tp, class _Arg>
+struct _LIBCPP_TEMPLATE_VIS is_nothrow_assignable
+ : public __libcpp_is_nothrow_assignable<is_assignable<_Tp, _Arg>::value, _Tp, _Arg>
+{
+};
+
+#endif // _LIBCPP_HAS_NO_NOEXCEPT
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp, class _Arg>
+inline constexpr bool is_nothrow_assignable_v = is_nothrow_assignable<_Tp, _Arg>::value;
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_NOTHROW_ASSIGNABLE_H
diff --git a/libcxx/include/__type_traits/is_nothrow_constructible.h b/libcxx/include/__type_traits/is_nothrow_constructible.h
new file mode 100644
index 000000000000..1f25d61baa63
--- /dev/null
+++ b/libcxx/include/__type_traits/is_nothrow_constructible.h
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_IS_NOTHROW_CONSTRUCTIBLE_H
+#define _LIBCPP___TYPE_TRAITS_IS_NOTHROW_CONSTRUCTIBLE_H
+
+#include <__config>
+#include <__type_traits/integral_constant.h>
+#include <__utility/declval.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if __has_keyword(__is_nothrow_constructible)
+
+template <class _Tp, class... _Args>
+struct _LIBCPP_TEMPLATE_VIS is_nothrow_constructible
+ : public integral_constant<bool, __is_nothrow_constructible(_Tp, _Args...)> {};
+
+#else
+
+template <bool, bool, class _Tp, class... _Args> struct __libcpp_is_nothrow_constructible;
+
+template <class _Tp, class... _Args>
+struct __libcpp_is_nothrow_constructible</*is constructible*/true, /*is reference*/false, _Tp, _Args...>
+ : public integral_constant<bool, noexcept(_Tp(declval<_Args>()...))>
+{
+};
+
+template <class _Tp>
+void __implicit_conversion_to(_Tp) noexcept { }
+
+template <class _Tp, class _Arg>
+struct __libcpp_is_nothrow_constructible</*is constructible*/true, /*is reference*/true, _Tp, _Arg>
+ : public integral_constant<bool, noexcept(_VSTD::__implicit_conversion_to<_Tp>(declval<_Arg>()))>
+{
+};
+
+template <class _Tp, bool _IsReference, class... _Args>
+struct __libcpp_is_nothrow_constructible</*is constructible*/false, _IsReference, _Tp, _Args...>
+ : public false_type
+{
+};
+
+template <class _Tp, class... _Args>
+struct _LIBCPP_TEMPLATE_VIS is_nothrow_constructible
+ : __libcpp_is_nothrow_constructible<is_constructible<_Tp, _Args...>::value, is_reference<_Tp>::value, _Tp, _Args...>
+{
+};
+
+template <class _Tp, size_t _Ns>
+struct _LIBCPP_TEMPLATE_VIS is_nothrow_constructible<_Tp[_Ns]>
+ : __libcpp_is_nothrow_constructible<is_constructible<_Tp>::value, is_reference<_Tp>::value, _Tp>
+{
+};
+
+#endif // _LIBCPP_HAS_NO_NOEXCEPT
+
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp, class ..._Args>
+inline constexpr bool is_nothrow_constructible_v = is_nothrow_constructible<_Tp, _Args...>::value;
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_NOTHROW_CONSTRUCTIBLE_H
diff --git a/libcxx/include/__type_traits/is_nothrow_copy_assignable.h b/libcxx/include/__type_traits/is_nothrow_copy_assignable.h
new file mode 100644
index 000000000000..8c4b8fd1628b
--- /dev/null
+++ b/libcxx/include/__type_traits/is_nothrow_copy_assignable.h
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_IS_NOTHROW_COPY_ASSIGNABLE_H
+#define _LIBCPP___TYPE_TRAITS_IS_NOTHROW_COPY_ASSIGNABLE_H
+
+#include <__config>
+#include <__type_traits/add_const.h>
+#include <__type_traits/add_lvalue_reference.h>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/is_nothrow_assignable.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_nothrow_copy_assignable
+ : public is_nothrow_assignable<typename add_lvalue_reference<_Tp>::type,
+ typename add_lvalue_reference<typename add_const<_Tp>::type>::type> {};
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline constexpr bool is_nothrow_copy_assignable_v = is_nothrow_copy_assignable<_Tp>::value;
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_NOTHROW_COPY_ASSIGNABLE_H
diff --git a/libcxx/include/__type_traits/is_nothrow_copy_constructible.h b/libcxx/include/__type_traits/is_nothrow_copy_constructible.h
new file mode 100644
index 000000000000..966df860e4b8
--- /dev/null
+++ b/libcxx/include/__type_traits/is_nothrow_copy_constructible.h
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_IS_NOTHROW_COPY_CONSTRUCTIBLE_H
+#define _LIBCPP___TYPE_TRAITS_IS_NOTHROW_COPY_CONSTRUCTIBLE_H
+
+#include <__config>
+#include <__type_traits/add_const.h>
+#include <__type_traits/add_lvalue_reference.h>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/is_nothrow_constructible.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_nothrow_copy_constructible
+ : public is_nothrow_constructible<_Tp,
+ typename add_lvalue_reference<typename add_const<_Tp>::type>::type> {};
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline constexpr bool is_nothrow_copy_constructible_v = is_nothrow_copy_constructible<_Tp>::value;
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_NOTHROW_COPY_CONSTRUCTIBLE_H
diff --git a/libcxx/include/__type_traits/is_nothrow_default_constructible.h b/libcxx/include/__type_traits/is_nothrow_default_constructible.h
new file mode 100644
index 000000000000..addf359ec3d6
--- /dev/null
+++ b/libcxx/include/__type_traits/is_nothrow_default_constructible.h
@@ -0,0 +1,33 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_NOTHROW_DEFAULT_CONSTRUCTIBLE_H
+#define _LIBCPP___TYPE_TRAITS_IS_NOTHROW_DEFAULT_CONSTRUCTIBLE_H
+
+#include <__config>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/is_nothrow_constructible.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_nothrow_default_constructible
+ : public is_nothrow_constructible<_Tp>
+ {};
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline constexpr bool is_nothrow_default_constructible_v = is_nothrow_default_constructible<_Tp>::value;
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_NOTHROW_DEFAULT_CONSTRUCTIBLE_H
diff --git a/libcxx/include/__type_traits/is_nothrow_destructible.h b/libcxx/include/__type_traits/is_nothrow_destructible.h
new file mode 100644
index 000000000000..4763ae84086a
--- /dev/null
+++ b/libcxx/include/__type_traits/is_nothrow_destructible.h
@@ -0,0 +1,90 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_NOTHROW_DESTRUCTIBLE_H
+#define _LIBCPP___TYPE_TRAITS_IS_NOTHROW_DESTRUCTIBLE_H
+
+#include <__config>
+#include <__type_traits/add_const.h>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/is_destructible.h>
+#include <__type_traits/is_reference.h>
+#include <__type_traits/is_scalar.h>
+#include <__type_traits/remove_all_extents.h>
+#include <__utility/declval.h>
+#include <cstddef>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if !defined(_LIBCPP_CXX03_LANG)
+
+template <bool, class _Tp> struct __libcpp_is_nothrow_destructible;
+
+template <class _Tp>
+struct __libcpp_is_nothrow_destructible<false, _Tp>
+ : public false_type
+{
+};
+
+template <class _Tp>
+struct __libcpp_is_nothrow_destructible<true, _Tp>
+ : public integral_constant<bool, noexcept(declval<_Tp>().~_Tp()) >
+{
+};
+
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_nothrow_destructible
+ : public __libcpp_is_nothrow_destructible<is_destructible<_Tp>::value, _Tp>
+{
+};
+
+template <class _Tp, size_t _Ns>
+struct _LIBCPP_TEMPLATE_VIS is_nothrow_destructible<_Tp[_Ns]>
+ : public is_nothrow_destructible<_Tp>
+{
+};
+
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_nothrow_destructible<_Tp&>
+ : public true_type
+{
+};
+
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_nothrow_destructible<_Tp&&>
+ : public true_type
+{
+};
+
+#else
+
+template <class _Tp> struct __libcpp_nothrow_destructor
+ : public integral_constant<bool, is_scalar<_Tp>::value ||
+ is_reference<_Tp>::value> {};
+
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_nothrow_destructible
+ : public __libcpp_nothrow_destructor<typename remove_all_extents<_Tp>::type> {};
+
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_nothrow_destructible<_Tp[]>
+ : public false_type {};
+
+#endif
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline constexpr bool is_nothrow_destructible_v = is_nothrow_destructible<_Tp>::value;
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_NOTHROW_DESTRUCTIBLE_H
diff --git a/libcxx/include/__type_traits/is_nothrow_move_assignable.h b/libcxx/include/__type_traits/is_nothrow_move_assignable.h
new file mode 100644
index 000000000000..44cea1f9cd56
--- /dev/null
+++ b/libcxx/include/__type_traits/is_nothrow_move_assignable.h
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_NOTHROW_MOVE_ASSIGNABLE_H
+#define _LIBCPP___TYPE_TRAITS_IS_NOTHROW_MOVE_ASSIGNABLE_H
+
+#include <__config>
+#include <__type_traits/add_lvalue_reference.h>
+#include <__type_traits/add_rvalue_reference.h>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/is_nothrow_assignable.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_nothrow_move_assignable
+ : public is_nothrow_assignable<typename add_lvalue_reference<_Tp>::type,
+ typename add_rvalue_reference<_Tp>::type>
+ {};
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline constexpr bool is_nothrow_move_assignable_v = is_nothrow_move_assignable<_Tp>::value;
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_NOTHROW_MOVE_ASSIGNABLE_H
diff --git a/libcxx/include/__type_traits/is_nothrow_move_constructible.h b/libcxx/include/__type_traits/is_nothrow_move_constructible.h
new file mode 100644
index 000000000000..e3b1171a4826
--- /dev/null
+++ b/libcxx/include/__type_traits/is_nothrow_move_constructible.h
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_IS_NOTHROW_MOVE_CONSTRUCTIBLE_H
+#define _LIBCPP___TYPE_TRAITS_IS_NOTHROW_MOVE_CONSTRUCTIBLE_H
+
+#include <__config>
+#include <__type_traits/add_rvalue_reference.h>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/is_nothrow_constructible.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_nothrow_move_constructible
+ : public is_nothrow_constructible<_Tp, typename add_rvalue_reference<_Tp>::type>
+ {};
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline constexpr bool is_nothrow_move_constructible_v = is_nothrow_move_constructible<_Tp>::value;
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_NOTHROW_MOVE_CONSTRUCTIBLE_H
diff --git a/libcxx/include/__type_traits/is_null_pointer.h b/libcxx/include/__type_traits/is_null_pointer.h
new file mode 100644
index 000000000000..f81cb9aadb2f
--- /dev/null
+++ b/libcxx/include/__type_traits/is_null_pointer.h
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_NULL_POINTER_H
+#define _LIBCPP___TYPE_TRAITS_IS_NULL_POINTER_H
+
+#include <__config>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/remove_cv.h>
+#include <cstddef>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp> struct __is_nullptr_t_impl : public false_type {};
+template <> struct __is_nullptr_t_impl<nullptr_t> : public true_type {};
+
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS __is_nullptr_t
+ : public __is_nullptr_t_impl<typename remove_cv<_Tp>::type> {};
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_null_pointer
+ : public __is_nullptr_t_impl<typename remove_cv<_Tp>::type> {};
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline constexpr bool is_null_pointer_v = is_null_pointer<_Tp>::value;
+#endif
+#endif // _LIBCPP_STD_VER > 11
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_NULL_POINTER_H
diff --git a/libcxx/include/__type_traits/is_object.h b/libcxx/include/__type_traits/is_object.h
new file mode 100644
index 000000000000..0d8339d19492
--- /dev/null
+++ b/libcxx/include/__type_traits/is_object.h
@@ -0,0 +1,52 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_OBJECT_H
+#define _LIBCPP___TYPE_TRAITS_IS_OBJECT_H
+
+#include <__config>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/is_array.h>
+#include <__type_traits/is_class.h>
+#include <__type_traits/is_scalar.h>
+#include <__type_traits/is_union.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if __has_keyword(__is_object)
+
+template<class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_object : _BoolConstant<__is_object(_Tp)> { };
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline constexpr bool is_object_v = __is_object(_Tp);
+#endif
+
+#else // __has_keyword(__is_object)
+
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_object
+ : public integral_constant<bool, is_scalar<_Tp>::value ||
+ is_array<_Tp>::value ||
+ is_union<_Tp>::value ||
+ is_class<_Tp>::value > {};
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline constexpr bool is_object_v = is_object<_Tp>::value;
+#endif
+
+#endif // __has_keyword(__is_object)
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_OBJECT_H
diff --git a/libcxx/include/__type_traits/is_pod.h b/libcxx/include/__type_traits/is_pod.h
new file mode 100644
index 000000000000..4317182f8964
--- /dev/null
+++ b/libcxx/include/__type_traits/is_pod.h
@@ -0,0 +1,43 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_POD_H
+#define _LIBCPP___TYPE_TRAITS_IS_POD_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
+
+#if __has_feature(is_pod) || defined(_LIBCPP_COMPILER_GCC)
+
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_pod
+ : public integral_constant<bool, __is_pod(_Tp)> {};
+
+#else
+
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_pod
+ : public integral_constant<bool, is_trivially_default_constructible<_Tp>::value &&
+ is_trivially_copy_constructible<_Tp>::value &&
+ is_trivially_copy_assignable<_Tp>::value &&
+ is_trivially_destructible<_Tp>::value> {};
+
+#endif
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline constexpr bool is_pod_v = is_pod<_Tp>::value;
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_POD_H
diff --git a/libcxx/include/__type_traits/is_pointer.h b/libcxx/include/__type_traits/is_pointer.h
new file mode 100644
index 000000000000..2139b03282e7
--- /dev/null
+++ b/libcxx/include/__type_traits/is_pointer.h
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_IS_POINTER_H
+#define _LIBCPP___TYPE_TRAITS_IS_POINTER_H
+
+#include <__config>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/remove_cv.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if __has_keyword(__is_pointer)
+
+template<class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_pointer : _BoolConstant<__is_pointer(_Tp)> { };
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline constexpr bool is_pointer_v = __is_pointer(_Tp);
+#endif
+
+#else // __has_keyword(__is_pointer)
+
+template <class _Tp> struct __libcpp_is_pointer : public false_type {};
+template <class _Tp> struct __libcpp_is_pointer<_Tp*> : public true_type {};
+
+template <class _Tp> struct __libcpp_remove_objc_qualifiers { typedef _Tp type; };
+#if defined(_LIBCPP_HAS_OBJC_ARC)
+template <class _Tp> struct __libcpp_remove_objc_qualifiers<_Tp __strong> { typedef _Tp type; };
+template <class _Tp> struct __libcpp_remove_objc_qualifiers<_Tp __weak> { typedef _Tp type; };
+template <class _Tp> struct __libcpp_remove_objc_qualifiers<_Tp __autoreleasing> { typedef _Tp type; };
+template <class _Tp> struct __libcpp_remove_objc_qualifiers<_Tp __unsafe_unretained> { typedef _Tp type; };
+#endif
+
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_pointer
+ : public __libcpp_is_pointer<typename __libcpp_remove_objc_qualifiers<typename remove_cv<_Tp>::type>::type> {};
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline constexpr bool is_pointer_v = is_pointer<_Tp>::value;
+#endif
+
+#endif // __has_keyword(__is_pointer)
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_POINTER_H
diff --git a/libcxx/include/__type_traits/is_polymorphic.h b/libcxx/include/__type_traits/is_polymorphic.h
new file mode 100644
index 000000000000..96da48abeeec
--- /dev/null
+++ b/libcxx/include/__type_traits/is_polymorphic.h
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_POLYMORPHIC_H
+#define _LIBCPP___TYPE_TRAITS_IS_POLYMORPHIC_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>
+struct _LIBCPP_TEMPLATE_VIS is_polymorphic
+ : public integral_constant<bool, __is_polymorphic(_Tp)> {};
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline constexpr bool is_polymorphic_v = __is_polymorphic(_Tp);
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_POLYMORPHIC_H
diff --git a/libcxx/include/__type_traits/is_reference.h b/libcxx/include/__type_traits/is_reference.h
new file mode 100644
index 000000000000..8aa55c13ff83
--- /dev/null
+++ b/libcxx/include/__type_traits/is_reference.h
@@ -0,0 +1,70 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_REFERENCE_H
+#define _LIBCPP___TYPE_TRAITS_IS_REFERENCE_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
+
+#if __has_keyword(__is_lvalue_reference) && \
+ __has_keyword(__is_rvalue_reference) && \
+ __has_keyword(__is_reference)
+
+template<class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_lvalue_reference : _BoolConstant<__is_lvalue_reference(_Tp)> { };
+
+template<class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_rvalue_reference : _BoolConstant<__is_rvalue_reference(_Tp)> { };
+
+template<class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_reference : _BoolConstant<__is_reference(_Tp)> { };
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline constexpr bool is_reference_v = __is_reference(_Tp);
+template <class _Tp>
+inline constexpr bool is_lvalue_reference_v = __is_lvalue_reference(_Tp);
+template <class _Tp>
+inline constexpr bool is_rvalue_reference_v = __is_rvalue_reference(_Tp);
+#endif
+
+#else // __has_keyword(__is_lvalue_reference) && etc...
+
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_lvalue_reference : public false_type {};
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_lvalue_reference<_Tp&> : public true_type {};
+
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_rvalue_reference : public false_type {};
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_rvalue_reference<_Tp&&> : public true_type {};
+
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_reference : public false_type {};
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_reference<_Tp&> : public true_type {};
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_reference<_Tp&&> : public true_type {};
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline constexpr bool is_reference_v = is_reference<_Tp>::value;
+
+template <class _Tp>
+inline constexpr bool is_lvalue_reference_v = is_lvalue_reference<_Tp>::value;
+
+template <class _Tp>
+inline constexpr bool is_rvalue_reference_v = is_rvalue_reference<_Tp>::value;
+#endif
+
+#endif // __has_keyword(__is_lvalue_reference) && etc...
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_REFERENCE_H
diff --git a/libcxx/include/__type_traits/is_reference_wrapper.h b/libcxx/include/__type_traits/is_reference_wrapper.h
new file mode 100644
index 000000000000..cd391bb07e78
--- /dev/null
+++ b/libcxx/include/__type_traits/is_reference_wrapper.h
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_REFERENCE_WRAPPER_H
+#define _LIBCPP___TYPE_TRAITS_IS_REFERENCE_WRAPPER_H
+
+#include <__config>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/remove_cv.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp> class _LIBCPP_TEMPLATE_VIS reference_wrapper;
+
+template <class _Tp> struct __is_reference_wrapper_impl : public false_type {};
+template <class _Tp> struct __is_reference_wrapper_impl<reference_wrapper<_Tp> > : public true_type {};
+template <class _Tp> struct __is_reference_wrapper
+ : public __is_reference_wrapper_impl<typename remove_cv<_Tp>::type> {};
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_ENABLE_IF_H
diff --git a/libcxx/include/__type_traits/is_referenceable.h b/libcxx/include/__type_traits/is_referenceable.h
new file mode 100644
index 000000000000..b97631cc39dd
--- /dev/null
+++ b/libcxx/include/__type_traits/is_referenceable.h
@@ -0,0 +1,33 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_REFERENCEABLE_H
+#define _LIBCPP___TYPE_TRAITS_IS_REFERENCEABLE_H
+
+#include <__config>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/is_same.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+struct __is_referenceable_impl {
+ template <class _Tp> static _Tp& __test(int);
+ template <class _Tp> static false_type __test(...);
+};
+
+template <class _Tp>
+struct __is_referenceable : integral_constant<bool,
+ _IsNotSame<decltype(__is_referenceable_impl::__test<_Tp>(0)), false_type>::value> {};
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_REFERENCEABLE_H
diff --git a/libcxx/include/__type_traits/is_same.h b/libcxx/include/__type_traits/is_same.h
new file mode 100644
index 000000000000..6fa0afbc18ca
--- /dev/null
+++ b/libcxx/include/__type_traits/is_same.h
@@ -0,0 +1,44 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_SAME_H
+#define _LIBCPP___TYPE_TRAITS_IS_SAME_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, class _Up>
+struct _LIBCPP_TEMPLATE_VIS is_same : _BoolConstant<__is_same(_Tp, _Up)> { };
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp, class _Up>
+inline constexpr bool is_same_v = __is_same(_Tp, _Up);
+#endif
+
+// _IsSame<T,U> has the same effect as is_same<T,U> but instantiates fewer types:
+// is_same<A,B> and is_same<C,D> are guaranteed to be different types, but
+// _IsSame<A,B> and _IsSame<C,D> are the same type (namely, false_type).
+// Neither GCC nor Clang can mangle the __is_same builtin, so _IsSame
+// mustn't be directly used anywhere that contributes to name-mangling
+// (such as in a dependent return type).
+
+template <class _Tp, class _Up>
+using _IsSame = _BoolConstant<__is_same(_Tp, _Up)>;
+
+template <class _Tp, class _Up>
+using _IsNotSame = _BoolConstant<!__is_same(_Tp, _Up)>;
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_SAME_H
diff --git a/libcxx/include/__type_traits/is_scalar.h b/libcxx/include/__type_traits/is_scalar.h
new file mode 100644
index 000000000000..0ca34c7cf79b
--- /dev/null
+++ b/libcxx/include/__type_traits/is_scalar.h
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_IS_SCALAR_H
+#define _LIBCPP___TYPE_TRAITS_IS_SCALAR_H
+
+#include <__config>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/is_arithmetic.h>
+#include <__type_traits/is_enum.h>
+#include <__type_traits/is_member_pointer.h>
+#include <__type_traits/is_pointer.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if __has_keyword(__is_scalar)
+
+template<class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_scalar : _BoolConstant<__is_scalar(_Tp)> { };
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline constexpr bool is_scalar_v = __is_scalar(_Tp);
+#endif
+
+#else // __has_keyword(__is_scalar)
+
+template <class _Tp> struct __is_block : false_type {};
+#if defined(_LIBCPP_HAS_EXTENSION_BLOCKS)
+template <class _Rp, class ..._Args> struct __is_block<_Rp (^)(_Args...)> : true_type {};
+#endif
+
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_scalar
+ : public integral_constant<bool, is_arithmetic<_Tp>::value ||
+ is_member_pointer<_Tp>::value ||
+ is_pointer<_Tp>::value ||
+ __is_nullptr_t<_Tp>::value ||
+ __is_block<_Tp>::value ||
+ is_enum<_Tp>::value > {};
+
+template <> struct _LIBCPP_TEMPLATE_VIS is_scalar<nullptr_t> : public true_type {};
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline constexpr bool is_scalar_v = is_scalar<_Tp>::value;
+#endif
+
+#endif // __has_keyword(__is_scalar)
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_SCALAR_H
diff --git a/libcxx/include/__type_traits/is_scoped_enum.h b/libcxx/include/__type_traits/is_scoped_enum.h
new file mode 100644
index 000000000000..85a412813304
--- /dev/null
+++ b/libcxx/include/__type_traits/is_scoped_enum.h
@@ -0,0 +1,42 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_SCOPED_ENUM_H
+#define _LIBCPP___TYPE_TRAITS_IS_SCOPED_ENUM_H
+
+#include <__config>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/is_convertible.h>
+#include <__type_traits/is_enum.h>
+#include <__type_traits/underlying_type.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 20
+template <class _Tp, bool = is_enum_v<_Tp> >
+struct __is_scoped_enum_helper : false_type {};
+
+template <class _Tp>
+struct __is_scoped_enum_helper<_Tp, true>
+ : public bool_constant<!is_convertible_v<_Tp, underlying_type_t<_Tp> > > {};
+
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_scoped_enum
+ : public __is_scoped_enum_helper<_Tp> {};
+
+template <class _Tp>
+inline constexpr bool is_scoped_enum_v = is_scoped_enum<_Tp>::value;
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_SCOPED_ENUM_H
diff --git a/libcxx/include/__type_traits/is_signed.h b/libcxx/include/__type_traits/is_signed.h
new file mode 100644
index 000000000000..241d6f551a4b
--- /dev/null
+++ b/libcxx/include/__type_traits/is_signed.h
@@ -0,0 +1,55 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_SIGNED_H
+#define _LIBCPP___TYPE_TRAITS_IS_SIGNED_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
+
+#if __has_keyword(__is_signed)
+
+template<class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_signed : _BoolConstant<__is_signed(_Tp)> { };
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline constexpr bool is_signed_v = __is_signed(_Tp);
+#endif
+
+#else // __has_keyword(__is_signed)
+
+template <class _Tp, bool = is_integral<_Tp>::value>
+struct __libcpp_is_signed_impl : public _BoolConstant<(_Tp(-1) < _Tp(0))> {};
+
+template <class _Tp>
+struct __libcpp_is_signed_impl<_Tp, false> : public true_type {}; // floating point
+
+template <class _Tp, bool = is_arithmetic<_Tp>::value>
+struct __libcpp_is_signed : public __libcpp_is_signed_impl<_Tp> {};
+
+template <class _Tp> struct __libcpp_is_signed<_Tp, false> : public false_type {};
+
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_signed : public __libcpp_is_signed<_Tp> {};
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline constexpr bool is_signed_v = is_signed<_Tp>::value;
+#endif
+
+#endif // __has_keyword(__is_signed)
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_SIGNED_H
diff --git a/libcxx/include/__type_traits/is_standard_layout.h b/libcxx/include/__type_traits/is_standard_layout.h
new file mode 100644
index 000000000000..375d08721e90
--- /dev/null
+++ b/libcxx/include/__type_traits/is_standard_layout.h
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_STANDARD_LAYOUT_H
+#define _LIBCPP___TYPE_TRAITS_IS_STANDARD_LAYOUT_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> struct _LIBCPP_TEMPLATE_VIS is_standard_layout
+#if __has_feature(is_standard_layout) || defined(_LIBCPP_COMPILER_GCC)
+ : public integral_constant<bool, __is_standard_layout(_Tp)>
+#else
+ : integral_constant<bool, is_scalar<typename remove_all_extents<_Tp>::type>::value>
+#endif
+ {};
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline constexpr bool is_standard_layout_v = is_standard_layout<_Tp>::value;
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_STANDARD_LAYOUT_H
diff --git a/libcxx/include/__type_traits/is_trivial.h b/libcxx/include/__type_traits/is_trivial.h
new file mode 100644
index 000000000000..011963c3d0e6
--- /dev/null
+++ b/libcxx/include/__type_traits/is_trivial.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___TYPE_TRAITS_IS_TRIVIAL_H
+#define _LIBCPP___TYPE_TRAITS_IS_TRIVIAL_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> struct _LIBCPP_TEMPLATE_VIS is_trivial
+#if __has_feature(is_trivial) || defined(_LIBCPP_COMPILER_GCC)
+ : public integral_constant<bool, __is_trivial(_Tp)>
+#else
+ : integral_constant<bool, is_trivially_copyable<_Tp>::value &&
+ is_trivially_default_constructible<_Tp>::value>
+#endif
+ {};
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline constexpr bool is_trivial_v = is_trivial<_Tp>::value;
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_TRIVIAL_H
diff --git a/libcxx/include/__type_traits/is_trivially_assignable.h b/libcxx/include/__type_traits/is_trivially_assignable.h
new file mode 100644
index 000000000000..01540f959efe
--- /dev/null
+++ b/libcxx/include/__type_traits/is_trivially_assignable.h
@@ -0,0 +1,33 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_TRIVIALLY_ASSIGNABLE_H
+#define _LIBCPP___TYPE_TRAITS_IS_TRIVIALLY_ASSIGNABLE_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, class _Arg>
+struct is_trivially_assignable
+ : integral_constant<bool, __is_trivially_assignable(_Tp, _Arg)>
+{ };
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp, class _Arg>
+inline constexpr bool is_trivially_assignable_v = is_trivially_assignable<_Tp, _Arg>::value;
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_TRIVIALLY_ASSIGNABLE_H
diff --git a/libcxx/include/__type_traits/is_trivially_constructible.h b/libcxx/include/__type_traits/is_trivially_constructible.h
new file mode 100644
index 000000000000..92ea58005f84
--- /dev/null
+++ b/libcxx/include/__type_traits/is_trivially_constructible.h
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_IS_TRIVIALLY_CONSTRUCTIBLE_H
+#define _LIBCPP___TYPE_TRAITS_IS_TRIVIALLY_CONSTRUCTIBLE_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, class... _Args>
+struct _LIBCPP_TEMPLATE_VIS is_trivially_constructible
+ : integral_constant<bool, __is_trivially_constructible(_Tp, _Args...)>
+{
+};
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp, class... _Args>
+inline constexpr bool is_trivially_constructible_v = is_trivially_constructible<_Tp, _Args...>::value;
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_TRIVIALLY_CONSTRUCTIBLE_H
diff --git a/libcxx/include/__type_traits/is_trivially_copy_assignable.h b/libcxx/include/__type_traits/is_trivially_copy_assignable.h
new file mode 100644
index 000000000000..066d763884b0
--- /dev/null
+++ b/libcxx/include/__type_traits/is_trivially_copy_assignable.h
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_IS_TRIVIALLY_COPY_ASSIGNABLE_H
+#define _LIBCPP___TYPE_TRAITS_IS_TRIVIALLY_COPY_ASSIGNABLE_H
+
+#include <__config>
+#include <__type_traits/add_const.h>
+#include <__type_traits/add_lvalue_reference.h>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/is_trivially_assignable.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_trivially_copy_assignable
+ : public is_trivially_assignable<typename add_lvalue_reference<_Tp>::type,
+ typename add_lvalue_reference<typename add_const<_Tp>::type>::type> {};
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline constexpr bool is_trivially_copy_assignable_v = is_trivially_copy_assignable<_Tp>::value;
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_TRIVIALLY_COPY_ASSIGNABLE_H
diff --git a/libcxx/include/__type_traits/is_trivially_copy_constructible.h b/libcxx/include/__type_traits/is_trivially_copy_constructible.h
new file mode 100644
index 000000000000..e0c054d775d6
--- /dev/null
+++ b/libcxx/include/__type_traits/is_trivially_copy_constructible.h
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_IS_TRIVIALLY_COPY_CONSTRUCTIBLE_H
+#define _LIBCPP___TYPE_TRAITS_IS_TRIVIALLY_COPY_CONSTRUCTIBLE_H
+
+#include <__config>
+#include <__type_traits/add_lvalue_reference.h>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/is_trivially_constructible.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_trivially_copy_constructible
+ : public is_trivially_constructible<_Tp, typename add_lvalue_reference<const _Tp>::type>
+ {};
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline constexpr bool is_trivially_copy_constructible_v = is_trivially_copy_constructible<_Tp>::value;
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_TRIVIALLY_COPY_CONSTRUCTIBLE_H
diff --git a/libcxx/include/__type_traits/is_trivially_copyable.h b/libcxx/include/__type_traits/is_trivially_copyable.h
new file mode 100644
index 000000000000..3b7665217292
--- /dev/null
+++ b/libcxx/include/__type_traits/is_trivially_copyable.h
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_TRIVIALLY_COPYABLE_H
+#define _LIBCPP___TYPE_TRAITS_IS_TRIVIALLY_COPYABLE_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> struct _LIBCPP_TEMPLATE_VIS is_trivially_copyable
+ : public integral_constant<bool, __is_trivially_copyable(_Tp)>
+ {};
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline constexpr bool is_trivially_copyable_v = is_trivially_copyable<_Tp>::value;
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_TRIVIALLY_COPYABLE_H
diff --git a/libcxx/include/__type_traits/is_trivially_default_constructible.h b/libcxx/include/__type_traits/is_trivially_default_constructible.h
new file mode 100644
index 000000000000..822fa9c910c9
--- /dev/null
+++ b/libcxx/include/__type_traits/is_trivially_default_constructible.h
@@ -0,0 +1,33 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_TRIVIALLY_DEFAULT_CONSTRUCTIBLE_H
+#define _LIBCPP___TYPE_TRAITS_IS_TRIVIALLY_DEFAULT_CONSTRUCTIBLE_H
+
+#include <__config>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/is_trivially_constructible.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_trivially_default_constructible
+ : public is_trivially_constructible<_Tp>
+ {};
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline constexpr bool is_trivially_default_constructible_v = is_trivially_default_constructible<_Tp>::value;
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_TRIVIALLY_DEFAULT_CONSTRUCTIBLE_H
diff --git a/libcxx/include/__type_traits/is_trivially_destructible.h b/libcxx/include/__type_traits/is_trivially_destructible.h
new file mode 100644
index 000000000000..81181cdf841d
--- /dev/null
+++ b/libcxx/include/__type_traits/is_trivially_destructible.h
@@ -0,0 +1,52 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_TRIVIALLY_DESTRUCTIBLE_H
+#define _LIBCPP___TYPE_TRAITS_IS_TRIVIALLY_DESTRUCTIBLE_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
+
+#if __has_keyword(__is_trivially_destructible)
+
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_trivially_destructible
+ : public integral_constant<bool, __is_trivially_destructible(_Tp)> {};
+
+#elif __has_feature(has_trivial_destructor) || defined(_LIBCPP_COMPILER_GCC)
+
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_trivially_destructible
+ : public integral_constant<bool, is_destructible<_Tp>::value && __has_trivial_destructor(_Tp)> {};
+
+#else
+
+template <class _Tp> struct __libcpp_trivial_destructor
+ : public integral_constant<bool, is_scalar<_Tp>::value ||
+ is_reference<_Tp>::value> {};
+
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_trivially_destructible
+ : public __libcpp_trivial_destructor<typename remove_all_extents<_Tp>::type> {};
+
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_trivially_destructible<_Tp[]>
+ : public false_type {};
+
+#endif
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline constexpr bool is_trivially_destructible_v = is_trivially_destructible<_Tp>::value;
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_TRIVIALLY_DESTRUCTIBLE_H
diff --git a/libcxx/include/__type_traits/is_trivially_move_assignable.h b/libcxx/include/__type_traits/is_trivially_move_assignable.h
new file mode 100644
index 000000000000..fc033a40dea8
--- /dev/null
+++ b/libcxx/include/__type_traits/is_trivially_move_assignable.h
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_TRIVIALLY_MOVE_ASSIGNABLE_H
+#define _LIBCPP___TYPE_TRAITS_IS_TRIVIALLY_MOVE_ASSIGNABLE_H
+
+#include <__config>
+#include <__type_traits/add_lvalue_reference.h>
+#include <__type_traits/add_rvalue_reference.h>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/is_trivially_assignable.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_trivially_move_assignable
+ : public is_trivially_assignable<typename add_lvalue_reference<_Tp>::type,
+ typename add_rvalue_reference<_Tp>::type>
+ {};
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline constexpr bool is_trivially_move_assignable_v = is_trivially_move_assignable<_Tp>::value;
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_TRIVIALLY_MOVE_ASSIGNABLE_H
diff --git a/libcxx/include/__type_traits/is_trivially_move_constructible.h b/libcxx/include/__type_traits/is_trivially_move_constructible.h
new file mode 100644
index 000000000000..be005cc26406
--- /dev/null
+++ b/libcxx/include/__type_traits/is_trivially_move_constructible.h
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_IS_TRIVIALLY_MOVE_CONSTRUCTIBLE_H
+#define _LIBCPP___TYPE_TRAITS_IS_TRIVIALLY_MOVE_CONSTRUCTIBLE_H
+
+#include <__config>
+#include <__type_traits/add_rvalue_reference.h>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/is_trivially_constructible.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_trivially_move_constructible
+ : public is_trivially_constructible<_Tp, typename add_rvalue_reference<_Tp>::type>
+ {};
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline constexpr bool is_trivially_move_constructible_v = is_trivially_move_constructible<_Tp>::value;
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_TRIVIALLY_MOVE_CONSTRUCTIBLE_H
diff --git a/libcxx/include/__type_traits/is_unbounded_array.h b/libcxx/include/__type_traits/is_unbounded_array.h
new file mode 100644
index 000000000000..11a12607e1e0
--- /dev/null
+++ b/libcxx/include/__type_traits/is_unbounded_array.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___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> struct _LIBCPP_TEMPLATE_VIS __libcpp_is_unbounded_array : false_type {};
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS __libcpp_is_unbounded_array<_Tp[]> : true_type {};
+
+#if _LIBCPP_STD_VER > 17
+
+template <class> struct _LIBCPP_TEMPLATE_VIS is_unbounded_array : false_type {};
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_unbounded_array<_Tp[]> : true_type {};
+
+template <class _Tp>
+inline constexpr
+bool is_unbounded_array_v = is_unbounded_array<_Tp>::value;
+
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_UNBOUNDED_ARRAY_H
diff --git a/libcxx/include/__type_traits/is_union.h b/libcxx/include/__type_traits/is_union.h
new file mode 100644
index 000000000000..3e8cffe034d4
--- /dev/null
+++ b/libcxx/include/__type_traits/is_union.h
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_UNION_H
+#define _LIBCPP___TYPE_TRAITS_IS_UNION_H
+
+#include <__config>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/remove_cv.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_union
+ : public integral_constant<bool, __is_union(_Tp)> {};
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline constexpr bool is_union_v = __is_union(_Tp);
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_UNION_H
diff --git a/libcxx/include/__type_traits/is_unsigned.h b/libcxx/include/__type_traits/is_unsigned.h
new file mode 100644
index 000000000000..bb279fdb729d
--- /dev/null
+++ b/libcxx/include/__type_traits/is_unsigned.h
@@ -0,0 +1,58 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_UNSIGNED_H
+#define _LIBCPP___TYPE_TRAITS_IS_UNSIGNED_H
+
+#include <__config>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/is_arithmetic.h>
+#include <__type_traits/is_integral.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+// Before AppleClang 14, __is_unsigned returned true for enums with signed underlying type.
+#if __has_keyword(__is_unsigned) && !(defined(_LIBCPP_APPLE_CLANG_VER) && _LIBCPP_APPLE_CLANG_VER < 1400)
+
+template<class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_unsigned : _BoolConstant<__is_unsigned(_Tp)> { };
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline constexpr bool is_unsigned_v = __is_unsigned(_Tp);
+#endif
+
+#else // __has_keyword(__is_unsigned)
+
+template <class _Tp, bool = is_integral<_Tp>::value>
+struct __libcpp_is_unsigned_impl : public _BoolConstant<(_Tp(0) < _Tp(-1))> {};
+
+template <class _Tp>
+struct __libcpp_is_unsigned_impl<_Tp, false> : public false_type {}; // floating point
+
+template <class _Tp, bool = is_arithmetic<_Tp>::value>
+struct __libcpp_is_unsigned : public __libcpp_is_unsigned_impl<_Tp> {};
+
+template <class _Tp> struct __libcpp_is_unsigned<_Tp, false> : public false_type {};
+
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_unsigned : public __libcpp_is_unsigned<_Tp> {};
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline constexpr bool is_unsigned_v = is_unsigned<_Tp>::value;
+#endif
+
+#endif // __has_keyword(__is_unsigned)
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_UNSIGNED_H
diff --git a/libcxx/include/__type_traits/is_void.h b/libcxx/include/__type_traits/is_void.h
new file mode 100644
index 000000000000..29e68cc529df
--- /dev/null
+++ b/libcxx/include/__type_traits/is_void.h
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_IS_VOID_H
+#define _LIBCPP___TYPE_TRAITS_IS_VOID_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
+
+#if __has_keyword(__is_void)
+
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_void : _BoolConstant<__is_void(_Tp)> { };
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline constexpr bool is_void_v = __is_void(_Tp);
+#endif
+
+#else
+
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_void
+ : public is_same<typename remove_cv<_Tp>::type, void> {};
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline constexpr bool is_void_v = is_void<_Tp>::value;
+#endif
+
+#endif // __has_keyword(__is_void)
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_VOID_H
diff --git a/libcxx/include/__type_traits/is_volatile.h b/libcxx/include/__type_traits/is_volatile.h
new file mode 100644
index 000000000000..372703e7ced6
--- /dev/null
+++ b/libcxx/include/__type_traits/is_volatile.h
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_IS_VOLATILE_H
+#define _LIBCPP___TYPE_TRAITS_IS_VOLATILE_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
+
+#if __has_keyword(__is_volatile)
+
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_volatile : _BoolConstant<__is_volatile(_Tp)> { };
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline constexpr bool is_volatile_v = __is_volatile(_Tp);
+#endif
+
+#else
+
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_volatile : public false_type {};
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_volatile<_Tp volatile> : public true_type {};
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline constexpr bool is_volatile_v = is_volatile<_Tp>::value;
+#endif
+
+#endif // __has_keyword(__is_volatile)
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_VOLATILE_H
diff --git a/libcxx/include/__type_traits/negation.h b/libcxx/include/__type_traits/negation.h
new file mode 100644
index 000000000000..92f205fb838e
--- /dev/null
+++ b/libcxx/include/__type_traits/negation.h
@@ -0,0 +1,33 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_NEGATION_H
+#define _LIBCPP___TYPE_TRAITS_NEGATION_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 _Pred>
+struct _Not : _BoolConstant<!_Pred::value> {};
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+struct negation : _Not<_Tp> {};
+template<class _Tp>
+inline constexpr bool negation_v = negation<_Tp>::value;
+#endif // _LIBCPP_STD_VER > 14
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_NEGATION_H
diff --git a/libcxx/include/__type_traits/rank.h b/libcxx/include/__type_traits/rank.h
new file mode 100644
index 000000000000..193d3fd129a1
--- /dev/null
+++ b/libcxx/include/__type_traits/rank.h
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_RANK_H
+#define _LIBCPP___TYPE_TRAITS_RANK_H
+
+#include <__config>
+#include <__type_traits/integral_constant.h>
+#include <cstddef>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS rank
+ : public integral_constant<size_t, 0> {};
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS rank<_Tp[]>
+ : public integral_constant<size_t, rank<_Tp>::value + 1> {};
+template <class _Tp, size_t _Np> struct _LIBCPP_TEMPLATE_VIS rank<_Tp[_Np]>
+ : public integral_constant<size_t, rank<_Tp>::value + 1> {};
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+inline constexpr size_t rank_v = rank<_Tp>::value;
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_RANK_H
diff --git a/libcxx/include/__type_traits/remove_all_extents.h b/libcxx/include/__type_traits/remove_all_extents.h
new file mode 100644
index 000000000000..075e3acabb44
--- /dev/null
+++ b/libcxx/include/__type_traits/remove_all_extents.h
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_REMOVE_ALL_EXTENTS_H
+#define _LIBCPP___TYPE_TRAITS_REMOVE_ALL_EXTENTS_H
+
+#include <__config>
+#include <cstddef>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_all_extents
+ {typedef _Tp type;};
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_all_extents<_Tp[]>
+ {typedef typename remove_all_extents<_Tp>::type type;};
+template <class _Tp, size_t _Np> struct _LIBCPP_TEMPLATE_VIS remove_all_extents<_Tp[_Np]>
+ {typedef typename remove_all_extents<_Tp>::type type;};
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp> using remove_all_extents_t = typename remove_all_extents<_Tp>::type;
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_REMOVE_ALL_EXTENTS_H
diff --git a/libcxx/include/__type_traits/remove_const.h b/libcxx/include/__type_traits/remove_const.h
new file mode 100644
index 000000000000..8efc893e965a
--- /dev/null
+++ b/libcxx/include/__type_traits/remove_const.h
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_REMOVE_CONST_H
+#define _LIBCPP___TYPE_TRAITS_REMOVE_CONST_H
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_const {typedef _Tp type;};
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_const<const _Tp> {typedef _Tp type;};
+#if _LIBCPP_STD_VER > 11
+template <class _Tp> using remove_const_t = typename remove_const<_Tp>::type;
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_REMOVE_CONST_H
diff --git a/libcxx/include/__type_traits/remove_cv.h b/libcxx/include/__type_traits/remove_cv.h
new file mode 100644
index 000000000000..ce1e4e45c6d1
--- /dev/null
+++ b/libcxx/include/__type_traits/remove_cv.h
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_REMOVE_CV_H
+#define _LIBCPP___TYPE_TRAITS_REMOVE_CV_H
+
+#include <__config>
+#include <__type_traits/remove_const.h>
+#include <__type_traits/remove_volatile.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_cv
+{typedef typename remove_volatile<typename remove_const<_Tp>::type>::type type;};
+#if _LIBCPP_STD_VER > 11
+template <class _Tp> using remove_cv_t = typename remove_cv<_Tp>::type;
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_REMOVE_CV_H
diff --git a/libcxx/include/__type_traits/remove_extent.h b/libcxx/include/__type_traits/remove_extent.h
new file mode 100644
index 000000000000..e353de361616
--- /dev/null
+++ b/libcxx/include/__type_traits/remove_extent.h
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_REMOVE_EXTENT_H
+#define _LIBCPP___TYPE_TRAITS_REMOVE_EXTENT_H
+
+#include <__config>
+#include <cstddef>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_extent
+ {typedef _Tp type;};
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_extent<_Tp[]>
+ {typedef _Tp type;};
+template <class _Tp, size_t _Np> struct _LIBCPP_TEMPLATE_VIS remove_extent<_Tp[_Np]>
+ {typedef _Tp type;};
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp> using remove_extent_t = typename remove_extent<_Tp>::type;
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_REMOVE_EXTENT_H
diff --git a/libcxx/include/__type_traits/remove_pointer.h b/libcxx/include/__type_traits/remove_pointer.h
new file mode 100644
index 000000000000..50cde3829470
--- /dev/null
+++ b/libcxx/include/__type_traits/remove_pointer.h
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_REMOVE_POINTER_H
+#define _LIBCPP___TYPE_TRAITS_REMOVE_POINTER_H
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_pointer {typedef _LIBCPP_NODEBUG _Tp type;};
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_pointer<_Tp*> {typedef _LIBCPP_NODEBUG _Tp type;};
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_pointer<_Tp* const> {typedef _LIBCPP_NODEBUG _Tp type;};
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_pointer<_Tp* volatile> {typedef _LIBCPP_NODEBUG _Tp type;};
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_pointer<_Tp* const volatile> {typedef _LIBCPP_NODEBUG _Tp type;};
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp> using remove_pointer_t = typename remove_pointer<_Tp>::type;
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_REMOVE_POINTER_H
diff --git a/libcxx/include/__type_traits/remove_reference.h b/libcxx/include/__type_traits/remove_reference.h
new file mode 100644
index 000000000000..a69e48dc584b
--- /dev/null
+++ b/libcxx/include/__type_traits/remove_reference.h
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_REMOVE_REFERENCE_H
+#define _LIBCPP___TYPE_TRAITS_REMOVE_REFERENCE_H
+
+#include <__config>
+#include <cstddef>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_reference {typedef _LIBCPP_NODEBUG _Tp type;};
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_reference<_Tp&> {typedef _LIBCPP_NODEBUG _Tp type;};
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_reference<_Tp&&> {typedef _LIBCPP_NODEBUG _Tp type;};
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp> using remove_reference_t = typename remove_reference<_Tp>::type;
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_REMOVE_REFERENCE_H
diff --git a/libcxx/include/__type_traits/remove_volatile.h b/libcxx/include/__type_traits/remove_volatile.h
new file mode 100644
index 000000000000..79f64c46a27d
--- /dev/null
+++ b/libcxx/include/__type_traits/remove_volatile.h
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_REMOVE_VOLATILE_H
+#define _LIBCPP___TYPE_TRAITS_REMOVE_VOLATILE_H
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_volatile {typedef _Tp type;};
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_volatile<volatile _Tp> {typedef _Tp type;};
+#if _LIBCPP_STD_VER > 11
+template <class _Tp> using remove_volatile_t = typename remove_volatile<_Tp>::type;
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_REMOVE_VOLATILE_H
diff --git a/libcxx/include/__type_traits/type_identity.h b/libcxx/include/__type_traits/type_identity.h
new file mode 100644
index 000000000000..42e52b16725b
--- /dev/null
+++ b/libcxx/include/__type_traits/type_identity.h
@@ -0,0 +1,33 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_TYPE_IDENTITY_H
+#define _LIBCPP___TYPE_TRAITS_TYPE_IDENTITY_H
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp>
+struct __type_identity { typedef _Tp type; };
+
+template <class _Tp>
+using __type_identity_t _LIBCPP_NODEBUG = typename __type_identity<_Tp>::type;
+
+#if _LIBCPP_STD_VER > 17
+template<class _Tp> struct type_identity { typedef _Tp type; };
+template<class _Tp> using type_identity_t = typename type_identity<_Tp>::type;
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_TYPE_IDENTITY_H
diff --git a/libcxx/include/__type_traits/underlying_type.h b/libcxx/include/__type_traits/underlying_type.h
new file mode 100644
index 000000000000..1c8db6432371
--- /dev/null
+++ b/libcxx/include/__type_traits/underlying_type.h
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_UNDERLYING_TYPE_H
+#define _LIBCPP___TYPE_TRAITS_UNDERLYING_TYPE_H
+
+#include <__config>
+#include <__type_traits/is_enum.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp, bool = is_enum<_Tp>::value> struct __underlying_type_impl;
+
+template <class _Tp>
+struct __underlying_type_impl<_Tp, false> {};
+
+template <class _Tp>
+struct __underlying_type_impl<_Tp, true>
+{
+ typedef __underlying_type(_Tp) type;
+};
+
+template <class _Tp>
+struct underlying_type : __underlying_type_impl<_Tp, is_enum<_Tp>::value> {};
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp> using underlying_type_t = typename underlying_type<_Tp>::type;
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_UNDERLYING_TYPE_H
diff --git a/libcxx/include/__type_traits/void_t.h b/libcxx/include/__type_traits/void_t.h
new file mode 100644
index 000000000000..a71ab5e4b07f
--- /dev/null
+++ b/libcxx/include/__type_traits/void_t.h
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_VOID_T_H
+#define _LIBCPP___TYPE_TRAITS_VOID_T_H
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 14
+template <class...> using void_t = void;
+#endif
+
+template <class>
+struct __void_t { typedef void type; };
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_VOID_T_H
diff --git a/libcxx/include/__undef_macros b/libcxx/include/__undef_macros
index 40b2b64d0a6f..3bacbbacb502 100644
--- a/libcxx/include/__undef_macros
+++ b/libcxx/include/__undef_macros
@@ -7,27 +7,10 @@
//
//===----------------------------------------------------------------------===//
-
#ifdef min
-#if !defined(_LIBCPP_DISABLE_MACRO_CONFLICT_WARNINGS)
-#if defined(_LIBCPP_WARNING)
-_LIBCPP_WARNING("macro min is incompatible with C++. Try #define NOMINMAX "
- "before any Windows header. #undefing min")
-#else
-#warning: macro min is incompatible with C++. #undefing min
-#endif
-#endif
-#undef min
+# undef min
#endif
#ifdef max
-#if !defined(_LIBCPP_DISABLE_MACRO_CONFLICT_WARNINGS)
-#if defined(_LIBCPP_WARNING)
-_LIBCPP_WARNING("macro max is incompatible with C++. Try #define NOMINMAX "
- "before any Windows header. #undefing max")
-#else
-#warning: macro max is incompatible with C++. #undefing max
-#endif
-#endif
-#undef max
+# undef max
#endif
diff --git a/libcxx/include/__utility/as_const.h b/libcxx/include/__utility/as_const.h
index 52da739875e3..be7dd8c7cf23 100644
--- a/libcxx/include/__utility/as_const.h
+++ b/libcxx/include/__utility/as_const.h
@@ -15,7 +15,7 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__utility/auto_cast.h b/libcxx/include/__utility/auto_cast.h
index 5c368e077508..e9079443959f 100644
--- a/libcxx/include/__utility/auto_cast.h
+++ b/libcxx/include/__utility/auto_cast.h
@@ -14,7 +14,7 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
#define _LIBCPP_AUTO_CAST(expr) static_cast<typename decay<decltype((expr))>::type>(expr)
diff --git a/libcxx/include/__utility/cmp.h b/libcxx/include/__utility/cmp.h
index 4fc96b054f4d..3cfd98106705 100644
--- a/libcxx/include/__utility/cmp.h
+++ b/libcxx/include/__utility/cmp.h
@@ -16,7 +16,7 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
@@ -24,19 +24,16 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17
template<class _Tp, class... _Up>
struct _IsSameAsAny : _Or<_IsSame<_Tp, _Up>...> {};
template<class _Tp>
concept __is_safe_integral_cmp = is_integral_v<_Tp> &&
- !_IsSameAsAny<_Tp, bool, char
+ !_IsSameAsAny<_Tp, bool, char, char16_t, char32_t
#ifndef _LIBCPP_HAS_NO_CHAR8_T
, char8_t
#endif
-#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
- , char16_t, char32_t
-#endif
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
, wchar_t
#endif
@@ -101,7 +98,7 @@ bool in_range(_Up __u) noexcept
return _VSTD::cmp_less_equal(__u, numeric_limits<_Tp>::max()) &&
_VSTD::cmp_greater_equal(__u, numeric_limits<_Tp>::min());
}
-#endif
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__utility/declval.h b/libcxx/include/__utility/declval.h
index 6a9dcd9a1949..97fd1eba91c6 100644
--- a/libcxx/include/__utility/declval.h
+++ b/libcxx/include/__utility/declval.h
@@ -12,7 +12,7 @@
#include <__config>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__utility/exchange.h b/libcxx/include/__utility/exchange.h
index f9c92c622f54..d9b3c151755f 100644
--- a/libcxx/include/__utility/exchange.h
+++ b/libcxx/include/__utility/exchange.h
@@ -15,7 +15,7 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__utility/forward.h b/libcxx/include/__utility/forward.h
index 7629a87d74ff..03ca16d9f955 100644
--- a/libcxx/include/__utility/forward.h
+++ b/libcxx/include/__utility/forward.h
@@ -11,10 +11,11 @@
#define _LIBCPP___UTILITY_FORWARD_H
#include <__config>
-#include <type_traits>
+#include <__type_traits/is_reference.h>
+#include <__type_traits/remove_reference.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__utility/in_place.h b/libcxx/include/__utility/in_place.h
index 846b4a6d4dfb..7a4973fa0407 100644
--- a/libcxx/include/__utility/in_place.h
+++ b/libcxx/include/__utility/in_place.h
@@ -13,7 +13,7 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__utility/integer_sequence.h b/libcxx/include/__utility/integer_sequence.h
index 738ac6c02b05..633f1333e247 100644
--- a/libcxx/include/__utility/integer_sequence.h
+++ b/libcxx/include/__utility/integer_sequence.h
@@ -13,7 +13,7 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__utility/move.h b/libcxx/include/__utility/move.h
index 75d715dc66da..da0d986093d6 100644
--- a/libcxx/include/__utility/move.h
+++ b/libcxx/include/__utility/move.h
@@ -14,7 +14,7 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -26,15 +26,10 @@ move(_Tp&& __t) _NOEXCEPT {
return static_cast<_Up&&>(__t);
}
-#ifndef _LIBCPP_CXX03_LANG
template <class _Tp>
using __move_if_noexcept_result_t =
typename conditional<!is_nothrow_move_constructible<_Tp>::value && is_copy_constructible<_Tp>::value, const _Tp&,
_Tp&&>::type;
-#else // _LIBCPP_CXX03_LANG
-template <class _Tp>
-using __move_if_noexcept_result_t = const _Tp&;
-#endif
template <class _Tp>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 __move_if_noexcept_result_t<_Tp>
diff --git a/libcxx/include/__utility/pair.h b/libcxx/include/__utility/pair.h
index f1114696884a..97635c2e61b5 100644
--- a/libcxx/include/__utility/pair.h
+++ b/libcxx/include/__utility/pair.h
@@ -21,7 +21,7 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -315,7 +315,7 @@ private:
#endif
};
-#if _LIBCPP_STD_VER >= 17
+#if _LIBCPP_STD_VER > 14
template<class _T1, class _T2>
pair(_T1, _T2) -> pair<_T1, _T2>;
#endif
@@ -330,7 +330,7 @@ operator==(const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y)
return __x.first == __y.first && __x.second == __y.second;
}
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17
template <class _T1, class _T2>
_LIBCPP_HIDE_FROM_ABI constexpr
@@ -345,7 +345,7 @@ operator<=>(const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y)
return _VSTD::__synth_three_way(__x.second, __y.second);
}
-#else // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#else // _LIBCPP_STD_VER > 17
template <class _T1, class _T2>
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
@@ -387,7 +387,23 @@ operator<=(const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y)
return !(__y < __x);
}
-#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17
+
+#if _LIBCPP_STD_VER > 20
+template <class _T1, class _T2, class _U1, class _U2, template<class> class _TQual, template<class> class _UQual>
+ requires requires { typename pair<common_reference_t<_TQual<_T1>, _UQual<_U1>>,
+ common_reference_t<_TQual<_T2>, _UQual<_U2>>>; }
+struct basic_common_reference<pair<_T1, _T2>, pair<_U1, _U2>, _TQual, _UQual> {
+ using type = pair<common_reference_t<_TQual<_T1>, _UQual<_U1>>,
+ common_reference_t<_TQual<_T2>, _UQual<_U2>>>;
+};
+
+template <class _T1, class _T2, class _U1, class _U2>
+ requires requires { typename pair<common_type_t<_T1, _U1>, common_type_t<_T2, _U2>>; }
+struct common_type<pair<_T1, _T2>, pair<_U1, _U2>> {
+ using type = pair<common_type_t<_T1, _U1>, common_type_t<_T2, _U2>>;
+};
+#endif // _LIBCPP_STD_VER > 20
template <class _T1, class _T2>
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
diff --git a/libcxx/include/__utility/piecewise_construct.h b/libcxx/include/__utility/piecewise_construct.h
index 4dc44b38fe99..3cc86fef2a0f 100644
--- a/libcxx/include/__utility/piecewise_construct.h
+++ b/libcxx/include/__utility/piecewise_construct.h
@@ -12,7 +12,7 @@
#include <__config>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__utility/priority_tag.h b/libcxx/include/__utility/priority_tag.h
index 45d9e5ec4c8f..e51ba6bfcc05 100644
--- a/libcxx/include/__utility/priority_tag.h
+++ b/libcxx/include/__utility/priority_tag.h
@@ -13,7 +13,7 @@
#include <cstddef>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__utility/rel_ops.h b/libcxx/include/__utility/rel_ops.h
index d59e96d72dc1..2577e94e91f6 100644
--- a/libcxx/include/__utility/rel_ops.h
+++ b/libcxx/include/__utility/rel_ops.h
@@ -15,7 +15,7 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__utility/swap.h b/libcxx/include/__utility/swap.h
index 20ec1419fc97..f9e7f36678ba 100644
--- a/libcxx/include/__utility/swap.h
+++ b/libcxx/include/__utility/swap.h
@@ -16,7 +16,7 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__utility/to_underlying.h b/libcxx/include/__utility/to_underlying.h
index 54f99108a38c..3428406e8d3a 100644
--- a/libcxx/include/__utility/to_underlying.h
+++ b/libcxx/include/__utility/to_underlying.h
@@ -14,7 +14,7 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__utility/transaction.h b/libcxx/include/__utility/transaction.h
index 5bc3a500fdc5..87e51c0b198e 100644
--- a/libcxx/include/__utility/transaction.h
+++ b/libcxx/include/__utility/transaction.h
@@ -15,7 +15,7 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/__utility/unreachable.h b/libcxx/include/__utility/unreachable.h
new file mode 100644
index 000000000000..485edb227c92
--- /dev/null
+++ b/libcxx/include/__utility/unreachable.h
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___UTILITY_UNREACHABLE_H
+#define _LIBCPP___UTILITY_UNREACHABLE_H
+
+#include <__config>
+#include <cstdlib>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+_LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI inline void __libcpp_unreachable()
+{
+#if __has_builtin(__builtin_unreachable)
+ __builtin_unreachable();
+#else
+ std::abort();
+#endif
+}
+
+#if _LIBCPP_STD_VER > 20
+
+[[noreturn]] _LIBCPP_HIDE_FROM_ABI inline void unreachable() { __libcpp_unreachable(); }
+
+#endif // _LIBCPP_STD_VER > 20
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif
diff --git a/libcxx/include/__variant/monostate.h b/libcxx/include/__variant/monostate.h
index d575847340ac..b389c3b56b36 100644
--- a/libcxx/include/__variant/monostate.h
+++ b/libcxx/include/__variant/monostate.h
@@ -15,7 +15,7 @@
#include <cstddef>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/algorithm b/libcxx/include/algorithm
index e5f1030be201..0154dbc39c08 100644
--- a/libcxx/include/algorithm
+++ b/libcxx/include/algorithm
@@ -19,14 +19,483 @@ namespace std
{
namespace ranges {
+
+ // [algorithms.results], algorithm result types
+ template <class I, class F>
+ struct in_fun_result; // since C++20
+
template <class I1, class I2>
- struct in_in_result; // since C++20
+ struct in_in_result; // since C++20
+
+ template <class I, class O>
+ struct in_out_result; // since C++20
template <class I1, class I2, class O>
- struct in_in_out_result; // since C++20
+ struct in_in_out_result; // since C++20
+
+ template <class I, class O1, class O2>
+ struct in_out_out_result; // since C++20
+
+ template <class I1, class I2>
+ struct min_max_result; // since C++20
+
+ template <class I>
+ struct in_found_result; // since C++20
+
+ template<forward_iterator I, sentinel_for<I> S, class Proj = identity,
+ indirect_strict_weak_order<projected<I, Proj>> Comp = ranges::less> // since C++20
+ constexpr I min_element(I first, S last, Comp comp = {}, Proj proj = {});
+
+ template<forward_range R, class Proj = identity,
+ indirect_strict_weak_order<projected<iterator_t<R>, Proj>> Comp = ranges::less> // since C++20
+ constexpr borrowed_iterator_t<R> min_element(R&& r, Comp comp = {}, Proj proj = {});
+
+ template<forward_iterator I, sentinel_for<I> S, class Proj = identity,
+ indirect_strict_weak_order<projected<I, Proj>> Comp = ranges::less>
+ constexpr I ranges::max_element(I first, S last, Comp comp = {}, Proj proj = {}); // since C++20
+
+ template<forward_range R, class Proj = identity,
+ indirect_strict_weak_order<projected<iterator_t<R>, Proj>> Comp = ranges::less>
+ constexpr borrowed_iterator_t<R> ranges::max_element(R&& r, Comp comp = {}, Proj proj = {}); // since C++20
+
+ template<class I1, class I2>
+ using mismatch_result = in_in_result<I1, I2>;
+
+ template <input_iterator I1, sentinel_for<_I1> S1, input_iterator I2, sentinel_for<_I2> S2,
+ class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity>
+ requires indirectly_comparable<I1, I2, Pred, Proj1, Proj2>
+ constexpr mismatch_result<_I1, _I2>
+ mismatch()(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}) // since C++20
+
+ template <input_range R1, input_range R2,
+ class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity>
+ requires indirectly_comparable<iterator_t<R1>, iterator_t<R2>, Pred, Proj1, Proj2>
+ constexpr mismatch_result<borrowed_iterator_t<R1>, borrowed_iterator_t<R2>>
+ mismatch(R1&& r1, R2&& r2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}) // since C++20
+
+ requires indirect_binary_predicate<ranges::equal_to, projected<I, Proj>, const T*>
+ constexpr I find(I first, S last, const T& value, Proj proj = {}); // since C++20
+
+ template<input_range R, class T, class Proj = identity>
+ requires indirect_binary_predicate<ranges::equal_to, projected<iterator_t<R>, Proj>, const T*>
+ constexpr borrowed_iterator_t<R>
+ find(R&& r, const T& value, Proj proj = {}); // since C++20
+
+ template<input_iterator I, sentinel_for<I> S, class Proj = identity,
+ indirect_unary_predicate<projected<I, Proj>> Pred>
+ constexpr I find_if(I first, S last, Pred pred, Proj proj = {}); // since C++20
+
+ template<input_range R, class Proj = identity,
+ indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>
+ constexpr borrowed_iterator_t<R>
+ find_if(R&& r, Pred pred, Proj proj = {}); // since C++20
+
+ template<input_iterator I, sentinel_for<I> S, class Proj = identity,
+ indirect_unary_predicate<projected<I, Proj>> Pred>
+ constexpr I find_if_not(I first, S last, Pred pred, Proj proj = {}); // since C++20
+
+ template<input_range R, class Proj = identity,
+ indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>
+ constexpr borrowed_iterator_t<R>
+ find_if_not(R&& r, Pred pred, Proj proj = {}); // since C++20
+
+ template<class T, class Proj = identity,
+ indirect_strict_weak_order<projected<const T*, Proj>> Comp = ranges::less>
+ constexpr const T& min(const T& a, const T& b, Comp comp = {}, Proj proj = {}); // since C++20
+
+ template<copyable T, class Proj = identity,
+ indirect_strict_weak_order<projected<const T*, Proj>> Comp = ranges::less>
+ constexpr T min(initializer_list<T> r, Comp comp = {}, Proj proj = {}); // since C++20
+
+ template<input_range R, class Proj = identity,
+ indirect_strict_weak_order<projected<iterator_t<R>, Proj>> Comp = ranges::less>
+ requires indirectly_copyable_storable<iterator_t<R>, range_value_t<R>*>
+ constexpr range_value_t<R>
+ min(R&& r, Comp comp = {}, Proj proj = {}); // since C++20
+
+ template<class T, class Proj = identity,
+ indirect_strict_weak_order<projected<const T*, Proj>> Comp = ranges::less>
+ constexpr const T& max(const T& a, const T& b, Comp comp = {}, Proj proj = {}); // since C++20
+
+ template<copyable T, class Proj = identity,
+ indirect_strict_weak_order<projected<const T*, Proj>> Comp = ranges::less>
+ constexpr T max(initializer_list<T> r, Comp comp = {}, Proj proj = {}); // since C++20
+
+ template<input_range R, class Proj = identity,
+ indirect_strict_weak_order<projected<iterator_t<R>, Proj>> Comp = ranges::less>
+ requires indirectly_copyable_storable<iterator_t<R>, range_value_t<R>*>
+ constexpr range_value_t<R>
+ max(R&& r, Comp comp = {}, Proj proj = {}); // since C++20
+
+ template<class I, class O>
+ using unary_transform_result = in_out_result<I, O>; // since C++20
+
+ template<class I1, class I2, class O>
+ using binary_transform_result = in_in_out_result<I1, I2, O>; // since C++20
+
+ template<input_iterator I, sentinel_for<I> S, weakly_incrementable O,
+ copy_constructible F, class Proj = identity>
+ requires indirectly_writable<O, indirect_result_t<F&, projected<I, Proj>>>
+ constexpr ranges::unary_transform_result<I, O>
+ transform(I first1, S last1, O result, F op, Proj proj = {}); // since C++20
+
+ template<input_range R, weakly_incrementable O, copy_constructible F,
+ class Proj = identity>
+ requires indirectly_writable<O, indirect_result_t<F&, projected<iterator_t<R>, Proj>>>
+ constexpr ranges::unary_transform_result<borrowed_iterator_t<R>, O>
+ transform(R&& r, O result, F op, Proj proj = {}); // since C++20
+
+ template<input_iterator I1, sentinel_for<I1> S1, input_iterator I2, sentinel_for<I2> S2,
+ weakly_incrementable O, copy_constructible F, class Proj1 = identity,
+ class Proj2 = identity>
+ requires indirectly_writable<O, indirect_result_t<F&, projected<I1, Proj1>,
+ projected<I2, Proj2>>>
+ constexpr ranges::binary_transform_result<I1, I2, O>
+ transform(I1 first1, S1 last1, I2 first2, S2 last2, O result,
+ F binary_op, Proj1 proj1 = {}, Proj2 proj2 = {}); // since C++20
+
+ template<input_range R1, input_range R2, weakly_incrementable O,
+ copy_constructible F, class Proj1 = identity, class Proj2 = identity>
+ requires indirectly_writable<O, indirect_result_t<F&, projected<iterator_t<R1>, Proj1>,
+ projected<iterator_t<R2>, Proj2>>>
+ constexpr ranges::binary_transform_result<borrowed_iterator_t<R1>, borrowed_iterator_t<R2>, O>
+ transform(R1&& r1, R2&& r2, O result,
+ F binary_op, Proj1 proj1 = {}, Proj2 proj2 = {}); // since C++20
+
+ template<input_iterator I, sentinel_for<I> S, class T, class Proj = identity>
+ requires indirect_binary_predicate<ranges::equal_to, projected<I, Proj>, const T*>
+ constexpr iter_difference_t<I>
+ count(I first, S last, const T& value, Proj proj = {}); // since C++20
+
+ template<input_range R, class T, class Proj = identity>
+ requires indirect_binary_predicate<ranges::equal_to, projected<iterator_t<R>, Proj>, const T*>
+ constexpr range_difference_t<R>
+ count(R&& r, const T& value, Proj proj = {}); // since C++20
+
+ template<input_iterator I, sentinel_for<I> S, class Proj = identity,
+ indirect_unary_predicate<projected<I, Proj>> Pred>
+ constexpr iter_difference_t<I>
+ count_if(I first, S last, Pred pred, Proj proj = {}); // since C++20
+
+ template<input_range R, class Proj = identity,
+ indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>
+ constexpr range_difference_t<R>
+ count_if(R&& r, Pred pred, Proj proj = {}); // since C++20
+
+ template<class T>
+ using minmax_result = min_max_result<T>;
+
+ template<class T, class Proj = identity,
+ indirect_strict_weak_order<projected<const T*, Proj>> Comp = ranges::less>
+ constexpr ranges::minmax_result<const T&>
+ minmax(const T& a, const T& b, Comp comp = {}, Proj proj = {}); // since C++20
+
+ template<copyable T, class Proj = identity,
+ indirect_strict_weak_order<projected<const T*, Proj>> Comp = ranges::less>
+ constexpr ranges::minmax_result<T>
+ minmax(initializer_list<T> r, Comp comp = {}, Proj proj = {}); // since C++20
+
+ template<input_range R, class Proj = identity,
+ indirect_strict_weak_order<projected<iterator_t<R>, Proj>> Comp = ranges::less>
+ requires indirectly_copyable_storable<iterator_t<R>, range_value_t<R>*>
+ constexpr ranges::minmax_result<range_value_t<R>>
+ minmax(R&& r, Comp comp = {}, Proj proj = {}); // since C++20
+
+ template<class I>
+ using minmax_element_result = min_max_result<I>;
+
+ template<forward_iterator I, sentinel_for<I> S, class Proj = identity,
+ indirect_strict_weak_order<projected<I, Proj>> Comp = ranges::less>
+ constexpr ranges::minmax_element_result<I>
+ minmax_element(I first, S last, Comp comp = {}, Proj proj = {}); // since C++20
+
+ template<forward_range R, class Proj = identity,
+ indirect_strict_weak_order<projected<iterator_t<R>, Proj>> Comp = ranges::less>
+ constexpr ranges::minmax_element_result<borrowed_iterator_t<R>>
+ minmax_element(R&& r, Comp comp = {}, Proj proj = {}); // since C++20
+
+ template<class I, class O>
+ using copy_result = in_out_result<I, O>; // since C++20
+
+ template<class I, class O>
+ using copy_n_result = in_out_result<I, O>; // since C++20
+
+ template<class I, class O>
+ using copy_if_result = in_out_result<I, O>; // since C++20
+
+ template<class I1, class I2>
+ using copy_backward_result = in_out_result<I1, I2>; // since C++20
+
+ template<input_iterator I, sentinel_for<I> S, weakly_incrementable O>
+ requires indirectly_copyable<I, O>
+ constexpr ranges::copy_result<I, O> ranges::copy(I first, S last, O result); // since C++20
+
+ template<input_range R, weakly_incrementable O>
+ requires indirectly_copyable<iterator_t<R>, O>
+ constexpr ranges::copy_result<borrowed_iterator_t<R>, O> ranges::copy(R&& r, O result); // since C++20
+
+ template<input_iterator I, weakly_incrementable O>
+ requires indirectly_copyable<I, O>
+ constexpr ranges::copy_n_result<I, O>
+ ranges::copy_n(I first, iter_difference_t<I> n, O result); // since C++20
+
+ template<input_iterator I, sentinel_for<I> S, weakly_incrementable O, class Proj = identity,
+ indirect_unary_predicate<projected<I, Proj>> Pred>
+ requires indirectly_copyable<I, O>
+ constexpr ranges::copy_if_result<I, O>
+ ranges::copy_if(I first, S last, O result, Pred pred, Proj proj = {}); // since C++20
+
+ template<input_range R, weakly_incrementable O, class Proj = identity,
+ indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>
+ requires indirectly_copyable<iterator_t<R>, O>
+ constexpr ranges::copy_if_result<borrowed_iterator_t<R>, O>
+ ranges::copy_if(R&& r, O result, Pred pred, Proj proj = {}); // since C++20
+
+ template<bidirectional_iterator I1, sentinel_for<I1> S1, bidirectional_iterator I2>
+ requires indirectly_copyable<I1, I2>
+ constexpr ranges::copy_backward_result<I1, I2>
+ ranges::copy_backward(I1 first, S1 last, I2 result); // since C++20
+
+ template<bidirectional_range R, bidirectional_iterator I>
+ requires indirectly_copyable<iterator_t<R>, I>
+ constexpr ranges::copy_backward_result<borrowed_iterator_t<R>, I>
+ ranges::copy_backward(R&& r, I result); // since C++20
+
+ template<class I, class F>
+ using for_each_result = in_fun_result<I, F>; // since C++20
+
+ template<input_iterator I, sentinel_for<I> S, class Proj = identity,
+ indirectly_unary_invocable<projected<I, Proj>> Fun>
+ constexpr ranges::for_each_result<I, Fun>
+ ranges::for_each(I first, S last, Fun f, Proj proj = {}); // since C++20
+
+ template<input_range R, class Proj = identity,
+ indirectly_unary_invocable<projected<iterator_t<R>, Proj>> Fun>
+ constexpr ranges::for_each_result<borrowed_iterator_t<R>, Fun>
+ ranges::for_each(R&& r, Fun f, Proj proj = {}); // since C++20
+
+ template<input_iterator I, class Proj = identity,
+ indirectly_unary_invocable<projected<I, Proj>> Fun>
+ constexpr ranges::for_each_n_result<I, Fun>
+ ranges::for_each_n(I first, iter_difference_t<I> n, Fun f, Proj proj = {}); // since C++20
+
+ template<input_iterator I, sentinel_for<I> S, class Proj = identity,
+ indirect_unary_predicate<projected<I, Proj>> Pred>
+ constexpr bool ranges::is_partitioned(I first, S last, Pred pred, Proj proj = {}); // since C++20
+
+ template<input_range R, class Proj = identity,
+ indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>
+ constexpr bool ranges::is_partitioned(R&& r, Pred pred, Proj proj = {}); // since C++20
+
+ template<bidirectional_iterator I, sentinel_for<I> S>
+ requires permutable<I>
+ constexpr I ranges::reverse(I first, S last); // since C++20
+
+ template<bidirectional_range R>
+ requires permutable<iterator_t<R>>
+ constexpr borrowed_iterator_t<R> ranges::reverse(R&& r); // since C++20
+
+ template<random_access_iterator I, sentinel_for<I> S, class Comp = ranges::less,
+ class Proj = identity>
+ requires sortable<I, Comp, Proj>
+ constexpr I
+ ranges::sort(I first, S last, Comp comp = {}, Proj proj = {}); // since C++20
+
+ template<random_access_range R, class Comp = ranges::less, class Proj = identity>
+ requires sortable<iterator_t<R>, Comp, Proj>
+ constexpr borrowed_iterator_t<R>
+ ranges::sort(R&& r, Comp comp = {}, Proj proj = {}); // since C++20
+
+ template<random_access_iterator I, sentinel_for<I> S, class Comp = ranges::less,
+ class Proj = identity>
+ requires sortable<I, Comp, Proj>
+ I ranges::stable_sort(I first, S last, Comp comp = {}, Proj proj = {}); // since C++20
+
+ template<random_access_range R, class Comp = ranges::less, class Proj = identity>
+ requires sortable<iterator_t<R>, Comp, Proj>
+ borrowed_iterator_t<R>
+ ranges::stable_sort(R&& r, Comp comp = {}, Proj proj = {}); // since C++20
+
+ template<class T, output_iterator<const T&> O, sentinel_for<O> S>
+ constexpr O ranges::fill(O first, S last, const T& value); // since C++20
+
+ template<class T, output_range<const T&> R>
+ constexpr borrowed_iterator_t<R> ranges::fill(R&& r, const T& value); // since C++20
+
+ template<class T, output_iterator<const T&> O>
+ constexpr O ranges::fill_n(O first, iter_difference_t<O> n, const T& value); // since C++20
+
+ template<input_iterator I1, sentinel_for<I1> S1, input_iterator I2, sentinel_for<I2> S2,
+ class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity>
+ requires indirectly_comparable<I1, I2, Pred, Proj1, Proj2>
+ constexpr bool ranges::equal(I1 first1, S1 last1, I2 first2, S2 last2,
+ Pred pred = {},
+ Proj1 proj1 = {}, Proj2 proj2 = {}); // since C++20
+
+ template<input_range R1, input_range R2, class Pred = ranges::equal_to,
+ class Proj1 = identity, class Proj2 = identity>
+ requires indirectly_comparable<iterator_t<R1>, iterator_t<R2>, Pred, Proj1, Proj2>
+ constexpr bool ranges::equal(R1&& r1, R2&& r2, Pred pred = {},
+ Proj1 proj1 = {}, Proj2 proj2 = {}); // since C++20
+
+ template<input_iterator I, sentinel_for<I> S, class Proj = identity,
+ indirect_unary_predicate<projected<I, Proj>> Pred>
+ constexpr bool ranges::all_of(I first, S last, Pred pred, Proj proj = {}); // since C++20
+
+ template<input_range R, class Proj = identity,
+ indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>
+ constexpr bool ranges::all_of(R&& r, Pred pred, Proj proj = {}); // since C++20
+
+ template<input_iterator I, sentinel_for<I> S, class Proj = identity,
+ indirect_unary_predicate<projected<I, Proj>> Pred>
+ constexpr bool ranges::any_of(I first, S last, Pred pred, Proj proj = {}); // since C++20
+
+ template<input_range R, class Proj = identity,
+ indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>
+ constexpr bool ranges::any_of(R&& r, Pred pred, Proj proj = {}); // since C++20
+
+ template<input_iterator I, sentinel_for<I> S, class Proj = identity,
+ indirect_unary_predicate<projected<I, Proj>> Pred>
+ constexpr bool ranges::none_of(I first, S last, Pred pred, Proj proj = {}); // since C++20
+
+ template<input_range R, class Proj = identity,
+ indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>
+ constexpr bool ranges::none_of(R&& r, Pred pred, Proj proj = {}); // since C++20
+
+ template<forward_iterator I, sentinel_for<I> S, class Proj = identity,
+ indirect_strict_weak_order<projected<I, Proj>> Comp = ranges::less>
+ constexpr bool ranges::is_sorted(I first, S last, Comp comp = {}, Proj proj = {}); // since C++20
+
+ template<forward_range R, class Proj = identity,
+ indirect_strict_weak_order<projected<iterator_t<R>, Proj>> Comp = ranges::less>
+ constexpr bool ranges::is_sorted(R&& r, Comp comp = {}, Proj proj = {}); // since C++20
+
+ template<forward_iterator I, sentinel_for<I> S, class Proj = identity,
+ indirect_strict_weak_order<projected<I, Proj>> Comp = ranges::less>
+ constexpr I ranges::is_sorted_until(I first, S last, Comp comp = {}, Proj proj = {}); // since C++20
+
+ template<forward_range R, class Proj = identity,
+ indirect_strict_weak_order<projected<iterator_t<R>, Proj>> Comp = ranges::less>
+ constexpr borrowed_iterator_t<R>
+ ranges::is_sorted_until(R&& r, Comp comp = {}, Proj proj = {}); // since C++20
+
+ template<forward_iterator I, sentinel_for<I> S, class T, class Proj = identity,
+ indirect_strict_weak_order<const T*, projected<I, Proj>> Comp = ranges::less>
+ constexpr I upper_bound(I first, S last, const T& value, Comp comp = {}, Proj proj = {}); // since C++20
+
+ template<forward_range R, class T, class Proj = identity,
+ indirect_strict_weak_order<const T*, projected<iterator_t<R>, Proj>> Comp =
+ ranges::less>
+ constexpr borrowed_iterator_t<R>
+ upper_bound(R&& r, const T& value, Comp comp = {}, Proj proj = {}); // since C++20
+
+ template<forward_iterator I, sentinel_for<I> S, class T, class Proj = identity,
+ indirect_strict_weak_order<const T*, projected<I, Proj>> Comp = ranges::less>
+ constexpr I lower_bound(I first, S last, const T& value, Comp comp = {},
+ Proj proj = {}); // since C++20
+ template<forward_range R, class T, class Proj = identity,
+ indirect_strict_weak_order<const T*, projected<iterator_t<R>, Proj>> Comp =
+ ranges::less>
+ constexpr borrowed_iterator_t<R>
+ lower_bound(R&& r, const T& value, Comp comp = {}, Proj proj = {}); // since C++20
+
+ template<forward_iterator I, sentinel_for<I> S, class T, class Proj = identity,
+ indirect_strict_weak_order<const T*, projected<I, Proj>> Comp = ranges::less>
+ constexpr bool binary_search(I first, S last, const T& value, Comp comp = {},
+ Proj proj = {}); // since C++20
+
+ template<forward_range R, class T, class Proj = identity,
+ indirect_strict_weak_order<const T*, projected<iterator_t<R>, Proj>> Comp =
+ ranges::less>
+ constexpr bool binary_search(R&& r, const T& value, Comp comp = {},
+ Proj proj = {}); // since C++20
+ template<input_iterator I1, sentinel_for<I1> S1, forward_iterator I2, sentinel_for<I2> S2,
+ class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity>
+ requires indirectly_comparable<I1, I2, Pred, Proj1, Proj2>
+ constexpr I1 ranges::find_first_of(I1 first1, S1 last1, I2 first2, S2 last2,
+ Pred pred = {},
+ Proj1 proj1 = {}, Proj2 proj2 = {}); // since C++20
+
+ template<input_range R1, forward_range R2,
+ class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity>
+ requires indirectly_comparable<iterator_t<R1>, iterator_t<R2>, Pred, Proj1, Proj2>
+ constexpr borrowed_iterator_t<R1>
+ ranges::find_first_of(R1&& r1, R2&& r2,
+ Pred pred = {},
+ Proj1 proj1 = {}, Proj2 proj2 = {}); // since C++20
+
+ template<forward_iterator I, sentinel_for<I> S, class Proj = identity,
+ indirect_binary_predicate<projected<I, Proj>,
+ projected<I, Proj>> Pred = ranges::equal_to>
+ constexpr I ranges::adjacent_find(I first, S last, Pred pred = {}, Proj proj = {}); // since C+20
+
+ template<forward_range R, class Proj = identity,
+ indirect_binary_predicate<projected<iterator_t<R>, Proj>,
+ projected<iterator_t<R>, Proj>> Pred = ranges::equal_to>
+ constexpr borrowed_iterator_t<R> ranges::adjacent_find(R&& r, Pred pred = {}, Proj proj = {}); // since C++20
+
+ template<input_iterator I, sentinel_for<I> S, class T1, class T2, class Proj = identity>
+ requires indirectly_writable<I, const T2&> &&
+ indirect_binary_predicate<ranges::equal_to, projected<I, Proj>, const T1*>
+ constexpr I
+ ranges::replace(I first, S last, const T1& old_value, const T2& new_value, Proj proj = {}); // since C++20
+
+ template<input_range R, class T1, class T2, class Proj = identity>
+ requires indirectly_writable<iterator_t<R>, const T2&> &&
+ indirect_binary_predicate<ranges::equal_to, projected<iterator_t<R>, Proj>, const T1*>
+ constexpr borrowed_iterator_t<R>
+ ranges::replace(R&& r, const T1& old_value, const T2& new_value, Proj proj = {}); // since C++20
+
+ template<input_iterator I, sentinel_for<I> S, class T, class Proj = identity,
+ indirect_unary_predicate<projected<I, Proj>> Pred>
+ requires indirectly_writable<I, const T&>
+ constexpr I ranges::replace_if(I first, S last, Pred pred, const T& new_value, Proj proj = {}); // since C++20
+
+ template<input_range R, class T, class Proj = identity,
+ indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>
+ requires indirectly_writable<iterator_t<R>, const T&>
+ constexpr borrowed_iterator_t<R>
+ ranges::replace_if(R&& r, Pred pred, const T& new_value, Proj proj = {}); // since C++20
+
+ template<input_iterator I1, sentinel_for<I1> S1, input_iterator I2, sentinel_for<I2> S2,
+ class Proj1 = identity, class Proj2 = identity,
+ indirect_strict_weak_order<projected<I1, Proj1>,
+ projected<I2, Proj2>> Comp = ranges::less>
+ constexpr bool
+ ranges::lexicographical_compare(I1 first1, S1 last1, I2 first2, S2 last2,
+ Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); // since C++20
+
+ template<input_range R1, input_range R2, class Proj1 = identity,
+ class Proj2 = identity,
+ indirect_strict_weak_order<projected<iterator_t<R1>, Proj1>,
+ projected<iterator_t<R2>, Proj2>> Comp = ranges::less>
+ constexpr bool
+ ranges::lexicographical_compare(R1&& r1, R2&& r2, Comp comp = {},
+ Proj1 proj1 = {}, Proj2 proj2 = {}); // since C++20
+
+ template<bidirectional_iterator I1, sentinel_for<I1> S1, bidirectional_iterator I2>
+ requires indirectly_movable<I1, I2>
+ constexpr ranges::move_backward_result<I1, I2>
+ ranges::move_backward(I1 first, S1 last, I2 result); // since C++20
+
+ template<bidirectional_range R, bidirectional_iterator I>
+ requires indirectly_movable<iterator_t<R>, I>
+ constexpr ranges::move_backward_result<borrowed_iterator_t<R>, I>
+ ranges::move_backward(R&& r, I result); // since C++20
+
+ template<input_iterator I, sentinel_for<I> S, weakly_incrementable O>
+ requires indirectly_movable<I, O>
+ constexpr ranges::move_result<I, O>
+ ranges::move(I first, S last, O result); // since C++20
+
+ template<input_range R, weakly_incrementable O>
+ requires indirectly_movable<iterator_t<R>, O>
+ constexpr ranges::move_result<borrowed_iterator_t<R>, O>
+ ranges::move(R&& r, O result); // since C++20
+
+
}
-template <class InputIterator, class Predicate>
constexpr bool // constexpr in C++20
all_of(InputIterator first, InputIterator last, Predicate pred);
@@ -192,10 +661,35 @@ template <class BidirectionalIterator1, class BidirectionalIterator2>
copy_backward(BidirectionalIterator1 first, BidirectionalIterator1 last,
BidirectionalIterator2 result);
+// [alg.move], move
+template<class InputIterator, class OutputIterator>
+ constexpr OutputIterator move(InputIterator first, InputIterator last,
+ OutputIterator result);
+
+template<class BidirectionalIterator1, class BidirectionalIterator2>
+ constexpr BidirectionalIterator2
+ move_backward(BidirectionalIterator1 first, BidirectionalIterator1 last,
+ BidirectionalIterator2 result);
+
template <class ForwardIterator1, class ForwardIterator2>
constexpr ForwardIterator2 // constexpr in C++20
swap_ranges(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2);
+namespace ranges {
+ template<class I1, class I2>
+ using swap_ranges_result = in_in_result<I1, I2>;
+
+template<input_iterator I1, sentinel_for<I1> S1, input_iterator I2, sentinel_for<I2> S2>
+ requires indirectly_swappable<I1, I2>
+ constexpr ranges::swap_ranges_result<I1, I2>
+ swap_ranges(I1 first1, S1 last1, I2 first2, S2 last2);
+
+template<input_range R1, input_range R2>
+ requires indirectly_swappable<iterator_t<R1>, iterator_t<R2>>
+ constexpr ranges::swap_ranges_result<borrowed_iterator_t<R1>, borrowed_iterator_t<R2>>
+ swap_ranges(R1&& r1, R2&& r2);
+}
+
template <class ForwardIterator1, class ForwardIterator2>
constexpr void // constexpr in C++20
iter_swap(ForwardIterator1 a, ForwardIterator2 b);
@@ -648,28 +1142,18 @@ template <class BidirectionalIterator>
template <class BidirectionalIterator, class Compare>
constexpr bool // constexpr in C++20
prev_permutation(BidirectionalIterator first, BidirectionalIterator last, Compare comp);
-
-namespace ranges {
-// [algorithms.results], algorithm result types
-template<class InputIterator, class OutputIterator>
- struct in_out_result;
-}
-
} // std
*/
-#include <__bits> // __libcpp_clz
+#include <__assert> // all public C++ headers provide the assertion handler
+#include <__bits>
#include <__config>
#include <__debug>
#include <cstddef>
#include <cstring>
-#include <functional>
-#include <initializer_list>
-#include <iterator>
#include <memory>
#include <type_traits>
-#include <utility> // swap_ranges
#include <version>
#include <__algorithm/adjacent_find.h>
@@ -699,8 +1183,11 @@ template<class InputIterator, class OutputIterator>
#include <__algorithm/generate.h>
#include <__algorithm/generate_n.h>
#include <__algorithm/half_positive.h>
+#include <__algorithm/in_found_result.h>
+#include <__algorithm/in_fun_result.h>
#include <__algorithm/in_in_out_result.h>
#include <__algorithm/in_in_result.h>
+#include <__algorithm/in_out_out_result.h>
#include <__algorithm/in_out_result.h>
#include <__algorithm/includes.h>
#include <__algorithm/inplace_merge.h>
@@ -719,6 +1206,7 @@ template<class InputIterator, class OutputIterator>
#include <__algorithm/merge.h>
#include <__algorithm/min.h>
#include <__algorithm/min_element.h>
+#include <__algorithm/min_max_result.h>
#include <__algorithm/minmax.h>
#include <__algorithm/minmax_element.h>
#include <__algorithm/mismatch.h>
@@ -735,6 +1223,48 @@ template<class InputIterator, class OutputIterator>
#include <__algorithm/pop_heap.h>
#include <__algorithm/prev_permutation.h>
#include <__algorithm/push_heap.h>
+#include <__algorithm/ranges_adjacent_find.h>
+#include <__algorithm/ranges_all_of.h>
+#include <__algorithm/ranges_any_of.h>
+#include <__algorithm/ranges_binary_search.h>
+#include <__algorithm/ranges_copy.h>
+#include <__algorithm/ranges_copy_backward.h>
+#include <__algorithm/ranges_copy_if.h>
+#include <__algorithm/ranges_copy_n.h>
+#include <__algorithm/ranges_count.h>
+#include <__algorithm/ranges_count_if.h>
+#include <__algorithm/ranges_equal.h>
+#include <__algorithm/ranges_fill.h>
+#include <__algorithm/ranges_fill_n.h>
+#include <__algorithm/ranges_find.h>
+#include <__algorithm/ranges_find_first_of.h>
+#include <__algorithm/ranges_find_if.h>
+#include <__algorithm/ranges_find_if_not.h>
+#include <__algorithm/ranges_for_each.h>
+#include <__algorithm/ranges_for_each_n.h>
+#include <__algorithm/ranges_is_partitioned.h>
+#include <__algorithm/ranges_is_sorted.h>
+#include <__algorithm/ranges_is_sorted_until.h>
+#include <__algorithm/ranges_lexicographical_compare.h>
+#include <__algorithm/ranges_lower_bound.h>
+#include <__algorithm/ranges_max.h>
+#include <__algorithm/ranges_max_element.h>
+#include <__algorithm/ranges_min.h>
+#include <__algorithm/ranges_min_element.h>
+#include <__algorithm/ranges_minmax.h>
+#include <__algorithm/ranges_minmax_element.h>
+#include <__algorithm/ranges_mismatch.h>
+#include <__algorithm/ranges_move.h>
+#include <__algorithm/ranges_move_backward.h>
+#include <__algorithm/ranges_none_of.h>
+#include <__algorithm/ranges_replace.h>
+#include <__algorithm/ranges_replace_if.h>
+#include <__algorithm/ranges_reverse.h>
+#include <__algorithm/ranges_sort.h>
+#include <__algorithm/ranges_stable_sort.h>
+#include <__algorithm/ranges_swap_ranges.h>
+#include <__algorithm/ranges_transform.h>
+#include <__algorithm/ranges_upper_bound.h>
#include <__algorithm/remove.h>
#include <__algorithm/remove_copy.h>
#include <__algorithm/remove_copy_if.h>
@@ -769,8 +1299,17 @@ template<class InputIterator, class OutputIterator>
#include <__algorithm/unwrap_iter.h>
#include <__algorithm/upper_bound.h>
+#ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES
+# include <chrono>
+# include <iterator>
+# include <utility>
+#endif
+
+// standard-mandated includes
+#include <initializer_list>
+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
#if defined(_LIBCPP_HAS_PARALLEL_ALGORITHMS) && _LIBCPP_STD_VER >= 17
diff --git a/libcxx/include/any b/libcxx/include/any
index c5b7af2953b9..7e12034b45a7 100644
--- a/libcxx/include/any
+++ b/libcxx/include/any
@@ -80,17 +80,26 @@ namespace std {
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__availability>
#include <__config>
#include <__utility/forward.h>
+#include <__utility/in_place.h>
+#include <__utility/move.h>
+#include <__utility/unreachable.h>
#include <cstdlib>
+#include <initializer_list>
#include <memory>
#include <type_traits>
#include <typeinfo>
#include <version>
+#ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES
+# include <chrono>
+#endif
+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
namespace std {
@@ -364,6 +373,7 @@ namespace __any_imp
case _Action::_TypeInfo:
return __type_info();
}
+ __libcpp_unreachable();
}
template <class ..._Args>
@@ -447,6 +457,7 @@ namespace __any_imp
case _Action::_TypeInfo:
return __type_info();
}
+ __libcpp_unreachable();
}
template <class ..._Args>
@@ -658,6 +669,7 @@ _RetType __pointer_or_func_cast(void*, /*IsFunction*/true_type) noexcept {
}
template <class _ValueType>
+_LIBCPP_HIDE_FROM_ABI
add_pointer_t<_ValueType>
any_cast(any * __any) _NOEXCEPT
{
diff --git a/libcxx/include/array b/libcxx/include/array
index 06884eab4a80..e96c3d813339 100644
--- a/libcxx/include/array
+++ b/libcxx/include/array
@@ -108,19 +108,42 @@ template <size_t I, class T, size_t N> const T&& get(const array<T, N>&&) noexce
*/
+#include <__algorithm/equal.h>
+#include <__algorithm/fill_n.h>
+#include <__algorithm/lexicographical_compare.h>
+#include <__algorithm/swap_ranges.h>
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
-#include <__debug>
+#include <__iterator/reverse_iterator.h>
#include <__tuple>
-#include <algorithm>
-#include <cstdlib> // for _LIBCPP_UNREACHABLE
-#include <iterator>
+#include <__utility/integer_sequence.h>
+#include <__utility/move.h>
+#include <__utility/unreachable.h>
#include <stdexcept>
#include <type_traits>
-#include <utility>
#include <version>
+#ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES
+# include <algorithm>
+# include <iterator>
+# include <utility>
+#endif
+
+// standard-mandated includes
+
+// [iterator.range]
+#include <__iterator/access.h>
+#include <__iterator/data.h>
+#include <__iterator/empty.h>
+#include <__iterator/reverse_access.h>
+#include <__iterator/size.h>
+
+// [array.syn]
+#include <compare>
+#include <initializer_list>
+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -309,54 +332,54 @@ struct _LIBCPP_TEMPLATE_VIS array<_Tp, 0>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
reference operator[](size_type) _NOEXCEPT {
_LIBCPP_ASSERT(false, "cannot call array<T, 0>::operator[] on a zero-sized array");
- _LIBCPP_UNREACHABLE();
+ __libcpp_unreachable();
}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
const_reference operator[](size_type) const _NOEXCEPT {
_LIBCPP_ASSERT(false, "cannot call array<T, 0>::operator[] on a zero-sized array");
- _LIBCPP_UNREACHABLE();
+ __libcpp_unreachable();
}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
reference at(size_type) {
__throw_out_of_range("array<T, 0>::at");
- _LIBCPP_UNREACHABLE();
+ __libcpp_unreachable();
}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
const_reference at(size_type) const {
__throw_out_of_range("array<T, 0>::at");
- _LIBCPP_UNREACHABLE();
+ __libcpp_unreachable();
}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
reference front() _NOEXCEPT {
_LIBCPP_ASSERT(false, "cannot call array<T, 0>::front() on a zero-sized array");
- _LIBCPP_UNREACHABLE();
+ __libcpp_unreachable();
}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
const_reference front() const _NOEXCEPT {
_LIBCPP_ASSERT(false, "cannot call array<T, 0>::front() on a zero-sized array");
- _LIBCPP_UNREACHABLE();
+ __libcpp_unreachable();
}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
reference back() _NOEXCEPT {
_LIBCPP_ASSERT(false, "cannot call array<T, 0>::back() on a zero-sized array");
- _LIBCPP_UNREACHABLE();
+ __libcpp_unreachable();
}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
const_reference back() const _NOEXCEPT {
_LIBCPP_ASSERT(false, "cannot call array<T, 0>::back() on a zero-sized array");
- _LIBCPP_UNREACHABLE();
+ __libcpp_unreachable();
}
};
-#if _LIBCPP_STD_VER >= 17
+#if _LIBCPP_STD_VER > 14
template<class _Tp, class... _Args,
class = enable_if_t<__all<_IsSame<_Tp, _Args>::value...>::value>
>
diff --git a/libcxx/include/atomic b/libcxx/include/atomic
index bd49367a3246..0c6d3079c96a 100644
--- a/libcxx/include/atomic
+++ b/libcxx/include/atomic
@@ -518,7 +518,9 @@ template <class T>
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__availability>
+#include <__chrono/duration.h>
#include <__config>
#include <__thread/poll_with_backoff.h>
#include <__thread/timed_backoff_policy.h>
@@ -532,15 +534,19 @@ template <class T>
# include <__threading_support>
#endif
+#ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES
+# include <chrono>
+#endif
+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
#ifdef _LIBCPP_HAS_NO_ATOMIC_HEADER
# error <atomic> is not implemented
#endif
#ifdef kill_dependency
-# error C++ standard library is incompatible with <stdatomic.h>
+# error <atomic> is incompatible with <stdatomic.h> before C++23. Please compile with -std=c++23.
#endif
#define _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) \
@@ -1449,11 +1455,11 @@ struct __cxx_atomic_impl : public _Base {
: _Base(value) {}
};
-#ifdef __linux__
+#if defined(__linux__) || (defined(_AIX) && !defined(__64BIT__))
using __cxx_contention_t = int32_t;
#else
using __cxx_contention_t = int64_t;
-#endif //__linux__
+#endif // __linux__ || (_AIX && !__64BIT__)
using __cxx_atomic_contention_t = __cxx_atomic_impl<__cxx_contention_t>;
@@ -1651,13 +1657,7 @@ struct __atomic_base // false
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
__atomic_base(_Tp __d) _NOEXCEPT : __a_(__d) {}
-#ifndef _LIBCPP_CXX03_LANG
__atomic_base(const __atomic_base&) = delete;
-#else
-private:
- _LIBCPP_INLINE_VISIBILITY
- __atomic_base(const __atomic_base&);
-#endif
};
#if defined(__cpp_lib_atomic_is_always_lock_free)
@@ -2439,19 +2439,10 @@ typedef struct atomic_flag
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
atomic_flag(bool __b) _NOEXCEPT : __a_(__b) {} // EXTENSION
-#ifndef _LIBCPP_CXX03_LANG
atomic_flag(const atomic_flag&) = delete;
atomic_flag& operator=(const atomic_flag&) = delete;
atomic_flag& operator=(const atomic_flag&) volatile = delete;
-#else
-private:
- _LIBCPP_INLINE_VISIBILITY
- atomic_flag(const atomic_flag&);
- _LIBCPP_INLINE_VISIBILITY
- atomic_flag& operator=(const atomic_flag&);
- _LIBCPP_INLINE_VISIBILITY
- atomic_flag& operator=(const atomic_flag&) volatile;
-#endif
+
} atomic_flag;
diff --git a/libcxx/include/barrier b/libcxx/include/barrier
index c7af46271745..9d91d255df9a 100644
--- a/libcxx/include/barrier
+++ b/libcxx/include/barrier
@@ -45,20 +45,20 @@ namespace std
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__availability>
#include <__config>
#include <__thread/timed_backoff_policy.h>
#include <atomic>
-#ifndef _LIBCPP_HAS_NO_TREE_BARRIER
-# include <memory>
-#endif
+#include <limits>
+#include <memory>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
#ifdef _LIBCPP_HAS_NO_THREADS
-# error <barrier> is not supported on this single threaded system
+# error "<barrier> is not supported since libc++ has been configured without support for threads."
#endif
_LIBCPP_PUSH_MACROS
@@ -108,12 +108,12 @@ void __destroy_barrier_algorithm_base(__barrier_algorithm_base* __barrier);
template<class _CompletionF>
class __barrier_base {
- ptrdiff_t __expected;
+ ptrdiff_t __expected_;
unique_ptr<__barrier_algorithm_base,
- void (*)(__barrier_algorithm_base*)> __base;
- __atomic_base<ptrdiff_t> __expected_adjustment;
- _CompletionF __completion;
- __atomic_base<__barrier_phase_t> __phase;
+ void (*)(__barrier_algorithm_base*)> __base_;
+ __atomic_base<ptrdiff_t> __expected_adjustment_;
+ _CompletionF __completion_;
+ __atomic_base<__barrier_phase_t> __phase_;
public:
using arrival_token = __barrier_phase_t;
@@ -124,22 +124,22 @@ public:
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
__barrier_base(ptrdiff_t __expected, _CompletionF __completion = _CompletionF())
- : __expected(__expected), __base(__construct_barrier_algorithm_base(this->__expected),
- &__destroy_barrier_algorithm_base),
- __expected_adjustment(0), __completion(move(__completion)), __phase(0)
+ : __expected_(__expected), __base_(__construct_barrier_algorithm_base(this->__expected_),
+ &__destroy_barrier_algorithm_base),
+ __expected_adjustment_(0), __completion_(std::move(__completion)), __phase_(0)
{
}
[[nodiscard]] _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
arrival_token arrive(ptrdiff_t update)
{
- auto const __old_phase = __phase.load(memory_order_relaxed);
+ auto const __old_phase = __phase_.load(memory_order_relaxed);
for(; update; --update)
- if(__arrive_barrier_algorithm_base(__base.get(), __old_phase)) {
- __completion();
- __expected += __expected_adjustment.load(memory_order_relaxed);
- __expected_adjustment.store(0, memory_order_relaxed);
- __phase.store(__old_phase + 2, memory_order_release);
- __phase.notify_all();
+ if(__arrive_barrier_algorithm_base(__base_.get(), __old_phase)) {
+ __completion_();
+ __expected_ += __expected_adjustment_.load(memory_order_relaxed);
+ __expected_adjustment_.store(0, memory_order_relaxed);
+ __phase_.store(__old_phase + 2, memory_order_release);
+ __phase_.notify_all();
}
return __old_phase;
}
@@ -147,14 +147,14 @@ public:
void wait(arrival_token&& __old_phase) const
{
auto const __test_fn = [this, __old_phase]() -> bool {
- return __phase.load(memory_order_acquire) != __old_phase;
+ return __phase_.load(memory_order_acquire) != __old_phase;
};
__libcpp_thread_poll_with_backoff(__test_fn, __libcpp_timed_backoff_policy());
}
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
void arrive_and_drop()
{
- __expected_adjustment.fetch_sub(1, memory_order_relaxed);
+ __expected_adjustment_.fetch_sub(1, memory_order_relaxed);
(void)arrive(1);
}
};
@@ -190,7 +190,7 @@ public:
_LIBCPP_INLINE_VISIBILITY
__barrier_base(ptrdiff_t __expected, _CompletionF __completion = _CompletionF())
- : __expected(__expected), __arrived(__expected), __completion(move(__completion)), __phase(false)
+ : __expected(__expected), __arrived(__expected), __completion(std::move(__completion)), __phase(false)
{
}
[[nodiscard]] _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
@@ -278,7 +278,7 @@ public:
}
};
-#endif //_LIBCPP_HAS_NO_TREE_BARRIER
+#endif // !_LIBCPP_HAS_NO_TREE_BARRIER
template<class _CompletionF = __empty_completion>
class barrier {
diff --git a/libcxx/include/bit b/libcxx/include/bit
index 57a13768c493..fe1bcadc818a 100644
--- a/libcxx/include/bit
+++ b/libcxx/include/bit
@@ -30,7 +30,7 @@ namespace std {
template <class T>
constexpr T bit_floor(T x) noexcept; // C++20
template <class T>
- constexpr T bit_width(T x) noexcept; // C++20
+ constexpr int bit_width(T x) noexcept; // C++20
// [bit.rotate], rotating
template<class T>
@@ -61,24 +61,29 @@ namespace std {
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__bit/bit_cast.h>
#include <__bit/byteswap.h>
#include <__bits> // __libcpp_clz
+#include <__concepts/arithmetic.h>
#include <__config>
-#include <__debug>
#include <limits>
#include <type_traits>
#include <version>
+#ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES
+# include <iosfwd>
+#endif
+
#if defined(__IBMCPP__)
-#include "__support/ibm/support.h"
+# include "__support/ibm/support.h"
#endif
#if defined(_LIBCPP_COMPILER_MSVC)
-#include <intrin.h>
+# include <intrin.h>
#endif
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
@@ -87,18 +92,7 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD
template<class _Tp>
-_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
-_Tp __rotl(_Tp __t, unsigned int __cnt) _NOEXCEPT
-{
- static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__rotl requires an unsigned integer type");
- const unsigned int __dig = numeric_limits<_Tp>::digits;
- if ((__cnt % __dig) == 0)
- return __t;
- return (__t << (__cnt % __dig)) | (__t >> (__dig - (__cnt % __dig)));
-}
-
-template<class _Tp>
-_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11
_Tp __rotr(_Tp __t, unsigned int __cnt) _NOEXCEPT
{
static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__rotr requires an unsigned integer type");
@@ -109,34 +103,7 @@ _Tp __rotr(_Tp __t, unsigned int __cnt) _NOEXCEPT
}
template<class _Tp>
-_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
-int __countr_zero(_Tp __t) _NOEXCEPT
-{
- static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__countr_zero requires an unsigned integer type");
- if (__t == 0)
- return numeric_limits<_Tp>::digits;
-
- if (sizeof(_Tp) <= sizeof(unsigned int))
- return __libcpp_ctz(static_cast<unsigned int>(__t));
- else if (sizeof(_Tp) <= sizeof(unsigned long))
- return __libcpp_ctz(static_cast<unsigned long>(__t));
- else if (sizeof(_Tp) <= sizeof(unsigned long long))
- return __libcpp_ctz(static_cast<unsigned long long>(__t));
- else
- {
- int __ret = 0;
- const unsigned int __ulldigits = numeric_limits<unsigned long long>::digits;
- while (static_cast<unsigned long long>(__t) == 0uLL)
- {
- __ret += __ulldigits;
- __t >>= __ulldigits;
- }
- return __ret + __libcpp_ctz(static_cast<unsigned long long>(__t));
- }
-}
-
-template<class _Tp>
-_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11
int __countl_zero(_Tp __t) _NOEXCEPT
{
static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__countl_zero requires an unsigned integer type");
@@ -144,13 +111,13 @@ int __countl_zero(_Tp __t) _NOEXCEPT
return numeric_limits<_Tp>::digits;
if (sizeof(_Tp) <= sizeof(unsigned int))
- return __libcpp_clz(static_cast<unsigned int>(__t))
+ return std::__libcpp_clz(static_cast<unsigned int>(__t))
- (numeric_limits<unsigned int>::digits - numeric_limits<_Tp>::digits);
else if (sizeof(_Tp) <= sizeof(unsigned long))
- return __libcpp_clz(static_cast<unsigned long>(__t))
+ return std::__libcpp_clz(static_cast<unsigned long>(__t))
- (numeric_limits<unsigned long>::digits - numeric_limits<_Tp>::digits);
else if (sizeof(_Tp) <= sizeof(unsigned long long))
- return __libcpp_clz(static_cast<unsigned long long>(__t))
+ return std::__libcpp_clz(static_cast<unsigned long long>(__t))
- (numeric_limits<unsigned long long>::digits - numeric_limits<_Tp>::digits);
else
{
@@ -158,8 +125,8 @@ int __countl_zero(_Tp __t) _NOEXCEPT
int __iter = 0;
const unsigned int __ulldigits = numeric_limits<unsigned long long>::digits;
while (true) {
- __t = __rotr(__t, __ulldigits);
- if ((__iter = __countl_zero(static_cast<unsigned long long>(__t))) != __ulldigits)
+ __t = std::__rotr(__t, __ulldigits);
+ if ((__iter = std::__countl_zero(static_cast<unsigned long long>(__t))) != __ulldigits)
break;
__ret += __iter;
}
@@ -167,178 +134,123 @@ int __countl_zero(_Tp __t) _NOEXCEPT
}
}
-template<class _Tp>
-_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
-int __countl_one(_Tp __t) _NOEXCEPT
-{
- static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__countl_one requires an unsigned integer type");
- return __t != numeric_limits<_Tp>::max()
- ? __countl_zero(static_cast<_Tp>(~__t))
- : numeric_limits<_Tp>::digits;
-}
-
-template<class _Tp>
-_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
-int __countr_one(_Tp __t) _NOEXCEPT
-{
- static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__countr_one requires an unsigned integer type");
- return __t != numeric_limits<_Tp>::max()
- ? __countr_zero(static_cast<_Tp>(~__t))
- : numeric_limits<_Tp>::digits;
-}
-
-template<class _Tp>
-_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
-int __popcount(_Tp __t) _NOEXCEPT
-{
- static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__popcount requires an unsigned integer type");
- if (sizeof(_Tp) <= sizeof(unsigned int))
- return __libcpp_popcount(static_cast<unsigned int>(__t));
- else if (sizeof(_Tp) <= sizeof(unsigned long))
- return __libcpp_popcount(static_cast<unsigned long>(__t));
- else if (sizeof(_Tp) <= sizeof(unsigned long long))
- return __libcpp_popcount(static_cast<unsigned long long>(__t));
- else
- {
- int __ret = 0;
- while (__t != 0)
- {
- __ret += __libcpp_popcount(static_cast<unsigned long long>(__t));
- __t >>= numeric_limits<unsigned long long>::digits;
- }
- return __ret;
- }
-}
-
-// integral log base 2
-template<class _Tp>
-_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
-unsigned __bit_log2(_Tp __t) _NOEXCEPT
-{
- static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__bit_log2 requires an unsigned integer type");
- return numeric_limits<_Tp>::digits - 1 - __countl_zero(__t);
-}
-
-template <class _Tp>
-_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
-bool __has_single_bit(_Tp __t) _NOEXCEPT
-{
- static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__has_single_bit requires an unsigned integer type");
- return __t != 0 && (((__t & (__t - 1)) == 0));
-}
-
#if _LIBCPP_STD_VER > 17
-template<class _Tp>
-_LIBCPP_INLINE_VISIBILITY constexpr
-enable_if_t<__libcpp_is_unsigned_integer<_Tp>::value, _Tp>
-rotl(_Tp __t, unsigned int __cnt) noexcept
-{
- return __rotl(__t, __cnt);
+template <__libcpp_unsigned_integer _Tp>
+_LIBCPP_HIDE_FROM_ABI constexpr _Tp rotl(_Tp __t, unsigned int __cnt) noexcept {
+ const unsigned int __dig = numeric_limits<_Tp>::digits;
+ if ((__cnt % __dig) == 0)
+ return __t;
+ return (__t << (__cnt % __dig)) | (__t >> (__dig - (__cnt % __dig)));
}
-template<class _Tp>
-_LIBCPP_INLINE_VISIBILITY constexpr
-enable_if_t<__libcpp_is_unsigned_integer<_Tp>::value, _Tp>
-rotr(_Tp __t, unsigned int __cnt) noexcept
-{
- return __rotr(__t, __cnt);
+template <__libcpp_unsigned_integer _Tp>
+_LIBCPP_HIDE_FROM_ABI constexpr _Tp rotr(_Tp __t, unsigned int __cnt) noexcept {
+ return std::__rotr(__t, __cnt);
}
-template<class _Tp>
-_LIBCPP_INLINE_VISIBILITY constexpr
-enable_if_t<__libcpp_is_unsigned_integer<_Tp>::value, int>
-countl_zero(_Tp __t) noexcept
-{
- return __countl_zero(__t);
+template <__libcpp_unsigned_integer _Tp>
+_LIBCPP_HIDE_FROM_ABI constexpr int countl_zero(_Tp __t) noexcept {
+ return std::__countl_zero(__t);
}
-template<class _Tp>
-_LIBCPP_INLINE_VISIBILITY constexpr
-enable_if_t<__libcpp_is_unsigned_integer<_Tp>::value, int>
-countl_one(_Tp __t) noexcept
-{
- return __countl_one(__t);
+template <__libcpp_unsigned_integer _Tp>
+_LIBCPP_HIDE_FROM_ABI constexpr int countl_one(_Tp __t) noexcept {
+ return __t != numeric_limits<_Tp>::max() ? std::countl_zero(static_cast<_Tp>(~__t)) : numeric_limits<_Tp>::digits;
}
-template<class _Tp>
-_LIBCPP_INLINE_VISIBILITY constexpr
-enable_if_t<__libcpp_is_unsigned_integer<_Tp>::value, int>
-countr_zero(_Tp __t) noexcept
-{
- return __countr_zero(__t);
+template <__libcpp_unsigned_integer _Tp>
+_LIBCPP_HIDE_FROM_ABI constexpr int countr_zero(_Tp __t) noexcept {
+ if (__t == 0)
+ return numeric_limits<_Tp>::digits;
+
+ if (sizeof(_Tp) <= sizeof(unsigned int))
+ return std::__libcpp_ctz(static_cast<unsigned int>(__t));
+ else if (sizeof(_Tp) <= sizeof(unsigned long))
+ return std::__libcpp_ctz(static_cast<unsigned long>(__t));
+ else if (sizeof(_Tp) <= sizeof(unsigned long long))
+ return std::__libcpp_ctz(static_cast<unsigned long long>(__t));
+ else {
+ int __ret = 0;
+ const unsigned int __ulldigits = numeric_limits<unsigned long long>::digits;
+ while (static_cast<unsigned long long>(__t) == 0uLL) {
+ __ret += __ulldigits;
+ __t >>= __ulldigits;
+ }
+ return __ret + std::__libcpp_ctz(static_cast<unsigned long long>(__t));
+ }
}
-template<class _Tp>
-_LIBCPP_INLINE_VISIBILITY constexpr
-enable_if_t<__libcpp_is_unsigned_integer<_Tp>::value, int>
-countr_one(_Tp __t) noexcept
-{
- return __countr_one(__t);
+template <__libcpp_unsigned_integer _Tp>
+_LIBCPP_HIDE_FROM_ABI constexpr int countr_one(_Tp __t) noexcept {
+ return __t != numeric_limits<_Tp>::max() ? std::countr_zero(static_cast<_Tp>(~__t)) : numeric_limits<_Tp>::digits;
}
-template<class _Tp>
-_LIBCPP_INLINE_VISIBILITY constexpr
-enable_if_t<__libcpp_is_unsigned_integer<_Tp>::value, int>
-popcount(_Tp __t) noexcept
-{
- return __popcount(__t);
+template <__libcpp_unsigned_integer _Tp>
+_LIBCPP_HIDE_FROM_ABI constexpr int popcount(_Tp __t) noexcept {
+ if (sizeof(_Tp) <= sizeof(unsigned int))
+ return std::__libcpp_popcount(static_cast<unsigned int>(__t));
+ else if (sizeof(_Tp) <= sizeof(unsigned long))
+ return std::__libcpp_popcount(static_cast<unsigned long>(__t));
+ else if (sizeof(_Tp) <= sizeof(unsigned long long))
+ return std::__libcpp_popcount(static_cast<unsigned long long>(__t));
+ else {
+ int __ret = 0;
+ while (__t != 0) {
+ __ret += std::__libcpp_popcount(static_cast<unsigned long long>(__t));
+ __t >>= numeric_limits<unsigned long long>::digits;
+ }
+ return __ret;
+ }
}
-template <class _Tp>
-_LIBCPP_INLINE_VISIBILITY constexpr
-enable_if_t<__libcpp_is_unsigned_integer<_Tp>::value, bool>
-has_single_bit(_Tp __t) noexcept
-{
- return __has_single_bit(__t);
+template <__libcpp_unsigned_integer _Tp>
+_LIBCPP_HIDE_FROM_ABI constexpr bool has_single_bit(_Tp __t) noexcept {
+ return __t != 0 && (((__t & (__t - 1)) == 0));
}
-template <class _Tp>
-_LIBCPP_INLINE_VISIBILITY constexpr
-enable_if_t<__libcpp_is_unsigned_integer<_Tp>::value, _Tp>
-bit_floor(_Tp __t) noexcept
-{
- return __t == 0 ? 0 : _Tp{1} << __bit_log2(__t);
+// integral log base 2
+template <__libcpp_unsigned_integer _Tp>
+_LIBCPP_HIDE_FROM_ABI constexpr _Tp __bit_log2(_Tp __t) noexcept {
+ return numeric_limits<_Tp>::digits - 1 - std::countl_zero(__t);
}
-template <class _Tp>
-_LIBCPP_INLINE_VISIBILITY constexpr
-enable_if_t<__libcpp_is_unsigned_integer<_Tp>::value, _Tp>
-bit_ceil(_Tp __t) noexcept
-{
- if (__t < 2) return 1;
- const unsigned __n = numeric_limits<_Tp>::digits - countl_zero((_Tp)(__t - 1u));
- _LIBCPP_ASSERT(__n != numeric_limits<_Tp>::digits, "Bad input to bit_ceil");
+template <__libcpp_unsigned_integer _Tp>
+_LIBCPP_HIDE_FROM_ABI constexpr _Tp bit_floor(_Tp __t) noexcept {
+ return __t == 0 ? 0 : _Tp{1} << std::__bit_log2(__t);
+}
- if constexpr (sizeof(_Tp) >= sizeof(unsigned))
- return _Tp{1} << __n;
- else
- {
- const unsigned __extra = numeric_limits<unsigned>::digits - numeric_limits<_Tp>::digits;
- const unsigned __retVal = 1u << (__n + __extra);
- return (_Tp) (__retVal >> __extra);
- }
+template <__libcpp_unsigned_integer _Tp>
+_LIBCPP_HIDE_FROM_ABI constexpr _Tp bit_ceil(_Tp __t) noexcept {
+ if (__t < 2)
+ return 1;
+ const unsigned __n = numeric_limits<_Tp>::digits - std::countl_zero((_Tp)(__t - 1u));
+ _LIBCPP_ASSERT(__n != numeric_limits<_Tp>::digits, "Bad input to bit_ceil");
+
+ if constexpr (sizeof(_Tp) >= sizeof(unsigned))
+ return _Tp{1} << __n;
+ else {
+ const unsigned __extra = numeric_limits<unsigned>::digits - numeric_limits<_Tp>::digits;
+ const unsigned __retVal = 1u << (__n + __extra);
+ return (_Tp)(__retVal >> __extra);
+ }
}
-template <class _Tp>
-_LIBCPP_INLINE_VISIBILITY constexpr
-enable_if_t<__libcpp_is_unsigned_integer<_Tp>::value, _Tp>
-bit_width(_Tp __t) noexcept
-{
- return __t == 0 ? 0 : __bit_log2(__t) + 1;
+template <__libcpp_unsigned_integer _Tp>
+_LIBCPP_HIDE_FROM_ABI constexpr int bit_width(_Tp __t) noexcept {
+ return __t == 0 ? 0 : std::__bit_log2(__t) + 1;
}
-enum class endian
-{
- little = 0xDEAD,
- big = 0xFACE,
-#if defined(_LIBCPP_LITTLE_ENDIAN)
- native = little
-#elif defined(_LIBCPP_BIG_ENDIAN)
- native = big
-#else
- native = 0xCAFE
-#endif
+enum class endian {
+ little = 0xDEAD,
+ big = 0xFACE,
+# if defined(_LIBCPP_LITTLE_ENDIAN)
+ native = little
+# elif defined(_LIBCPP_BIG_ENDIAN)
+ native = big
+# else
+ native = 0xCAFE
+# endif
};
#endif // _LIBCPP_STD_VER > 17
diff --git a/libcxx/include/bitset b/libcxx/include/bitset
index a5b93f90d40f..0f997cef8316 100644
--- a/libcxx/include/bitset
+++ b/libcxx/include/bitset
@@ -112,18 +112,23 @@ template <size_t N> struct hash<std::bitset<N>>;
*/
+#include <__algorithm/fill.h>
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__bit_reference>
#include <__config>
-#include <__functional_base>
+#include <__functional/hash.h>
+#include <__functional/unary_function.h>
#include <climits>
#include <cstddef>
-#include <iosfwd>
#include <stdexcept>
-#include <string>
#include <version>
+// standard-mandated includes
+#include <iosfwd>
+#include <string>
+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
@@ -713,9 +718,12 @@ public:
bitset& flip(size_t __pos);
// element access:
- _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
- const_reference operator[](size_t __p) const {return base::__make_ref(__p);}
- _LIBCPP_INLINE_VISIBILITY reference operator[](size_t __p) {return base::__make_ref(__p);}
+#ifdef _LIBCPP_ABI_BITSET_VECTOR_BOOL_CONST_SUBSCRIPT_RETURN_BOOL
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool operator[](size_t __p) const {return base::__make_ref(__p);}
+#else
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR const_reference operator[](size_t __p) const {return base::__make_ref(__p);}
+#endif
+ _LIBCPP_HIDE_FROM_ABI reference operator[](size_t __p) {return base::__make_ref(__p);}
_LIBCPP_INLINE_VISIBILITY
unsigned long to_ulong() const;
_LIBCPP_INLINE_VISIBILITY
@@ -946,7 +954,7 @@ basic_string<_CharT, _Traits, _Allocator>
bitset<_Size>::to_string(_CharT __zero, _CharT __one) const
{
basic_string<_CharT, _Traits, _Allocator> __r(_Size, __zero);
- for (size_t __i = 0; __i < _Size; ++__i)
+ for (size_t __i = 0; __i != _Size; ++__i)
{
if ((*this)[__i])
__r[_Size - 1 - __i] = __one;
@@ -1082,7 +1090,7 @@ operator^(const bitset<_Size>& __x, const bitset<_Size>& __y) _NOEXCEPT
template <size_t _Size>
struct _LIBCPP_TEMPLATE_VIS hash<bitset<_Size> >
- : public unary_function<bitset<_Size>, size_t>
+ : public __unary_function<bitset<_Size>, size_t>
{
_LIBCPP_INLINE_VISIBILITY
size_t operator()(const bitset<_Size>& __bs) const _NOEXCEPT
diff --git a/libcxx/include/cassert b/libcxx/include/cassert
index ebd5a56bb046..28fc0b10e9f4 100644
--- a/libcxx/include/cassert
+++ b/libcxx/include/cassert
@@ -16,9 +16,10 @@ Macros:
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
#include <assert.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
diff --git a/libcxx/include/ccomplex b/libcxx/include/ccomplex
index 3402fc9a3915..cf05c7a91081 100644
--- a/libcxx/include/ccomplex
+++ b/libcxx/include/ccomplex
@@ -17,12 +17,11 @@
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <complex>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
-// hh 080623 Created
-
#endif // _LIBCPP_CCOMPLEX
diff --git a/libcxx/include/cctype b/libcxx/include/cctype
index 4235cd6acc8c..248f8d98000f 100644
--- a/libcxx/include/cctype
+++ b/libcxx/include/cctype
@@ -34,11 +34,12 @@ int toupper(int c);
} // std
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
#include <ctype.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/cerrno b/libcxx/include/cerrno
index 486588e31fc4..e9eacd35effe 100644
--- a/libcxx/include/cerrno
+++ b/libcxx/include/cerrno
@@ -22,11 +22,12 @@ Macros:
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
#include <errno.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
#endif // _LIBCPP_CERRNO
diff --git a/libcxx/include/cfenv b/libcxx/include/cfenv
index 94ab79377c85..e42b46680d15 100644
--- a/libcxx/include/cfenv
+++ b/libcxx/include/cfenv
@@ -52,11 +52,12 @@ int feupdateenv(const fenv_t* envp);
} // std
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
#include <fenv.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/cfloat b/libcxx/include/cfloat
index 76374083407a..36a7c51cdda5 100644
--- a/libcxx/include/cfloat
+++ b/libcxx/include/cfloat
@@ -69,11 +69,12 @@ Macros:
LDBL_TRUE_MIN // C11
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
#include <float.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
#endif // _LIBCPP_CFLOAT
diff --git a/libcxx/include/charconv b/libcxx/include/charconv
index 06634fe7bc39..6a63e5fe9057 100644
--- a/libcxx/include/charconv
+++ b/libcxx/include/charconv
@@ -77,24 +77,31 @@ namespace std {
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__availability>
#include <__bits>
#include <__charconv/chars_format.h>
#include <__charconv/from_chars_result.h>
+#include <__charconv/tables.h>
+#include <__charconv/to_chars_base_10.h>
#include <__charconv/to_chars_result.h>
#include <__config>
+#include <__debug>
#include <__errc>
+#include <__utility/unreachable.h>
#include <cmath> // for log2f
#include <cstdint>
-#include <cstdlib> // for _LIBCPP_UNREACHABLE
+#include <cstdlib>
#include <cstring>
#include <limits>
#include <type_traits>
-#include <__debug>
+#ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES
+# include <iosfwd>
+#endif
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
@@ -102,11 +109,6 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD
-namespace __itoa {
-_LIBCPP_AVAILABILITY_TO_CHARS _LIBCPP_FUNC_VIS char* __u64toa(uint64_t __value, char* __buffer) _NOEXCEPT;
-_LIBCPP_AVAILABILITY_TO_CHARS _LIBCPP_FUNC_VIS char* __u32toa(uint32_t __value, char* __buffer) _NOEXCEPT;
-} // namespace __itoa
-
#ifndef _LIBCPP_CXX03_LANG
to_chars_result to_chars(char*, char*, bool, int = 10) = delete;
@@ -115,54 +117,24 @@ from_chars_result from_chars(const char*, const char*, bool, int = 10) = delete;
namespace __itoa
{
-static _LIBCPP_CONSTEXPR uint64_t __pow10_64[] = {
- UINT64_C(0),
- UINT64_C(10),
- UINT64_C(100),
- UINT64_C(1000),
- UINT64_C(10000),
- UINT64_C(100000),
- UINT64_C(1000000),
- UINT64_C(10000000),
- UINT64_C(100000000),
- UINT64_C(1000000000),
- UINT64_C(10000000000),
- UINT64_C(100000000000),
- UINT64_C(1000000000000),
- UINT64_C(10000000000000),
- UINT64_C(100000000000000),
- UINT64_C(1000000000000000),
- UINT64_C(10000000000000000),
- UINT64_C(100000000000000000),
- UINT64_C(1000000000000000000),
- UINT64_C(10000000000000000000),
-};
-
-static _LIBCPP_CONSTEXPR uint32_t __pow10_32[] = {
- UINT32_C(0), UINT32_C(10), UINT32_C(100),
- UINT32_C(1000), UINT32_C(10000), UINT32_C(100000),
- UINT32_C(1000000), UINT32_C(10000000), UINT32_C(100000000),
- UINT32_C(1000000000),
-};
template <typename _Tp, typename = void>
struct _LIBCPP_HIDDEN __traits_base
{
using type = uint64_t;
- static _LIBCPP_INLINE_VISIBILITY int __width(_Tp __v)
+ static _LIBCPP_HIDE_FROM_ABI int __width(_Tp __v)
{
- auto __t = (64 - _VSTD::__libcpp_clz(static_cast<type>(__v | 1))) * 1233 >> 12;
- return __t - (__v < __pow10_64[__t]) + 1;
+ auto __t = (64 - std::__libcpp_clz(static_cast<type>(__v | 1))) * 1233 >> 12;
+ return __t - (__v < __table<>::__pow10_64[__t]) + 1;
}
- _LIBCPP_AVAILABILITY_TO_CHARS
- static _LIBCPP_INLINE_VISIBILITY char* __convert(_Tp __v, char* __p)
+ static _LIBCPP_HIDE_FROM_ABI char* __convert(char* __p, _Tp __v)
{
- return __u64toa(__v, __p);
+ return __itoa::__base_10_u64(__p, __v);
}
- static _LIBCPP_INLINE_VISIBILITY decltype(__pow10_64)& __pow() { return __pow10_64; }
+ static _LIBCPP_HIDE_FROM_ABI decltype(__table<>::__pow10_64)& __pow() { return __table<>::__pow10_64; }
};
template <typename _Tp>
@@ -171,23 +143,22 @@ struct _LIBCPP_HIDDEN
{
using type = uint32_t;
- static _LIBCPP_INLINE_VISIBILITY int __width(_Tp __v)
+ static _LIBCPP_HIDE_FROM_ABI int __width(_Tp __v)
{
- auto __t = (32 - _VSTD::__libcpp_clz(static_cast<type>(__v | 1))) * 1233 >> 12;
- return __t - (__v < __pow10_32[__t]) + 1;
+ auto __t = (32 - std::__libcpp_clz(static_cast<type>(__v | 1))) * 1233 >> 12;
+ return __t - (__v < __table<>::__pow10_32[__t]) + 1;
}
- _LIBCPP_AVAILABILITY_TO_CHARS
- static _LIBCPP_INLINE_VISIBILITY char* __convert(_Tp __v, char* __p)
+ static _LIBCPP_HIDE_FROM_ABI char* __convert(char* __p, _Tp __v)
{
- return __u32toa(__v, __p);
+ return __itoa::__base_10_u32(__p, __v);
}
- static _LIBCPP_INLINE_VISIBILITY decltype(__pow10_32)& __pow() { return __pow10_32; }
+ static _LIBCPP_HIDE_FROM_ABI decltype(__table<>::__pow10_32)& __pow() { return __table<>::__pow10_32; }
};
template <typename _Tp>
-inline _LIBCPP_INLINE_VISIBILITY bool
+inline _LIBCPP_HIDE_FROM_ABI bool
__mul_overflowed(unsigned char __a, _Tp __b, unsigned char& __r)
{
auto __c = __a * __b;
@@ -196,7 +167,7 @@ __mul_overflowed(unsigned char __a, _Tp __b, unsigned char& __r)
}
template <typename _Tp>
-inline _LIBCPP_INLINE_VISIBILITY bool
+inline _LIBCPP_HIDE_FROM_ABI bool
__mul_overflowed(unsigned short __a, _Tp __b, unsigned short& __r)
{
auto __c = __a * __b;
@@ -205,7 +176,7 @@ __mul_overflowed(unsigned short __a, _Tp __b, unsigned short& __r)
}
template <typename _Tp>
-inline _LIBCPP_INLINE_VISIBILITY bool
+inline _LIBCPP_HIDE_FROM_ABI bool
__mul_overflowed(_Tp __a, _Tp __b, _Tp& __r)
{
static_assert(is_unsigned<_Tp>::value, "");
@@ -219,7 +190,7 @@ __mul_overflowed(_Tp __a, _Tp __b, _Tp& __r)
}
template <typename _Tp, typename _Up>
-inline _LIBCPP_INLINE_VISIBILITY bool
+inline _LIBCPP_HIDE_FROM_ABI bool
__mul_overflowed(_Tp __a, _Up __b, _Tp& __r)
{
return __mul_overflowed(__a, static_cast<_Tp>(__b), __r);
@@ -228,12 +199,12 @@ __mul_overflowed(_Tp __a, _Up __b, _Tp& __r)
template <typename _Tp>
struct _LIBCPP_HIDDEN __traits : __traits_base<_Tp>
{
- static _LIBCPP_CONSTEXPR int digits = numeric_limits<_Tp>::digits10 + 1;
+ static constexpr int digits = numeric_limits<_Tp>::digits10 + 1;
using __traits_base<_Tp>::__pow;
using typename __traits_base<_Tp>::type;
// precondition: at least one non-zero character available
- static _LIBCPP_INLINE_VISIBILITY char const*
+ static _LIBCPP_HIDE_FROM_ABI char const*
__read(char const* __p, char const* __ep, type& __a, type& __b)
{
type __cprod[digits];
@@ -254,7 +225,7 @@ struct _LIBCPP_HIDDEN __traits : __traits_base<_Tp>
}
template <typename _It1, typename _It2, class _Up>
- static _LIBCPP_INLINE_VISIBILITY _Up
+ static _LIBCPP_HIDE_FROM_ABI _Up
__inner_product(_It1 __first1, _It1 __last1, _It2 __first2, _Up __init)
{
for (; __first1 < __last1; ++__first1, ++__first2)
@@ -266,7 +237,7 @@ struct _LIBCPP_HIDDEN __traits : __traits_base<_Tp>
} // namespace __itoa
template <typename _Tp>
-inline _LIBCPP_INLINE_VISIBILITY _Tp
+inline _LIBCPP_HIDE_FROM_ABI _Tp
__complement(_Tp __x)
{
static_assert(is_unsigned<_Tp>::value, "cast to unsigned first");
@@ -274,8 +245,7 @@ __complement(_Tp __x)
}
template <typename _Tp>
-_LIBCPP_AVAILABILITY_TO_CHARS
-inline _LIBCPP_INLINE_VISIBILITY to_chars_result
+inline _LIBCPP_HIDE_FROM_ABI to_chars_result
__to_chars_itoa(char* __first, char* __last, _Tp __value, true_type)
{
auto __x = __to_unsigned_like(__value);
@@ -289,22 +259,20 @@ __to_chars_itoa(char* __first, char* __last, _Tp __value, true_type)
}
template <typename _Tp>
-_LIBCPP_AVAILABILITY_TO_CHARS
-inline _LIBCPP_INLINE_VISIBILITY to_chars_result
+inline _LIBCPP_HIDE_FROM_ABI to_chars_result
__to_chars_itoa(char* __first, char* __last, _Tp __value, false_type)
{
using __tx = __itoa::__traits<_Tp>;
auto __diff = __last - __first;
if (__tx::digits <= __diff || __tx::__width(__value) <= __diff)
- return {__tx::__convert(__value, __first), errc(0)};
+ return {__tx::__convert(__first, __value), errc(0)};
else
return {__last, errc::value_too_large};
}
template <typename _Tp>
-_LIBCPP_AVAILABILITY_TO_CHARS
-inline _LIBCPP_INLINE_VISIBILITY to_chars_result
+inline _LIBCPP_HIDE_FROM_ABI to_chars_result
__to_chars_integral(char* __first, char* __last, _Tp __value, int __base,
true_type)
{
@@ -318,8 +286,151 @@ __to_chars_integral(char* __first, char* __last, _Tp __value, int __base,
return __to_chars_integral(__first, __last, __x, __base, false_type());
}
+namespace __itoa {
+
+template <unsigned _Base>
+struct _LIBCPP_HIDDEN __integral;
+
+template <>
+struct _LIBCPP_HIDDEN __integral<2> {
+ template <typename _Tp>
+ _LIBCPP_HIDE_FROM_ABI static constexpr int __width(_Tp __value) noexcept {
+ // If value == 0 still need one digit. If the value != this has no
+ // effect since the code scans for the most significant bit set. (Note
+ // that __libcpp_clz doesn't work for 0.)
+ return numeric_limits<_Tp>::digits - std::__libcpp_clz(__value | 1);
+ }
+
+ template <typename _Tp>
+ _LIBCPP_HIDE_FROM_ABI static to_chars_result __to_chars(char* __first, char* __last, _Tp __value) {
+ ptrdiff_t __cap = __last - __first;
+ int __n = __width(__value);
+ if (__n > __cap)
+ return {__last, errc::value_too_large};
+
+ __last = __first + __n;
+ char* __p = __last;
+ const unsigned __divisor = 16;
+ while (__value > __divisor) {
+ unsigned __c = __value % __divisor;
+ __value /= __divisor;
+ __p -= 4;
+ std::memcpy(__p, &__table<>::__base_2_lut[4 * __c], 4);
+ }
+ do {
+ unsigned __c = __value % 2;
+ __value /= 2;
+ *--__p = "01"[__c];
+ } while (__value != 0);
+ return {__last, errc(0)};
+ }
+};
+
+template <>
+struct _LIBCPP_HIDDEN __integral<8> {
+ template <typename _Tp>
+ _LIBCPP_HIDE_FROM_ABI static constexpr int __width(_Tp __value) noexcept {
+ // If value == 0 still need one digit. If the value != this has no
+ // effect since the code scans for the most significat bit set. (Note
+ // that __libcpp_clz doesn't work for 0.)
+ return ((numeric_limits<_Tp>::digits - std::__libcpp_clz(__value | 1)) + 2) / 3;
+ }
+
+ template <typename _Tp>
+ _LIBCPP_HIDE_FROM_ABI static to_chars_result __to_chars(char* __first, char* __last, _Tp __value) {
+ ptrdiff_t __cap = __last - __first;
+ int __n = __width(__value);
+ if (__n > __cap)
+ return {__last, errc::value_too_large};
+
+ __last = __first + __n;
+ char* __p = __last;
+ unsigned __divisor = 64;
+ while (__value > __divisor) {
+ unsigned __c = __value % __divisor;
+ __value /= __divisor;
+ __p -= 2;
+ std::memcpy(__p, &__table<>::__base_8_lut[2 * __c], 2);
+ }
+ do {
+ unsigned __c = __value % 8;
+ __value /= 8;
+ *--__p = "01234567"[__c];
+ } while (__value != 0);
+ return {__last, errc(0)};
+ }
+
+};
+
+template <>
+struct _LIBCPP_HIDDEN __integral<16> {
+ template <typename _Tp>
+ _LIBCPP_HIDE_FROM_ABI static constexpr int __width(_Tp __value) noexcept {
+ // If value == 0 still need one digit. If the value != this has no
+ // effect since the code scans for the most significat bit set. (Note
+ // that __libcpp_clz doesn't work for 0.)
+ return (numeric_limits<_Tp>::digits - std::__libcpp_clz(__value | 1) + 3) / 4;
+ }
+
+ template <typename _Tp>
+ _LIBCPP_HIDE_FROM_ABI static to_chars_result __to_chars(char* __first, char* __last, _Tp __value) {
+ ptrdiff_t __cap = __last - __first;
+ int __n = __width(__value);
+ if (__n > __cap)
+ return {__last, errc::value_too_large};
+
+ __last = __first + __n;
+ char* __p = __last;
+ unsigned __divisor = 256;
+ while (__value > __divisor) {
+ unsigned __c = __value % __divisor;
+ __value /= __divisor;
+ __p -= 2;
+ std::memcpy(__p, &__table<>::__base_16_lut[2 * __c], 2);
+ }
+ if (__first != __last)
+ do {
+ unsigned __c = __value % 16;
+ __value /= 16;
+ *--__p = "0123456789abcdef"[__c];
+ } while (__value != 0);
+ return {__last, errc(0)};
+ }
+};
+
+} // namespace __itoa
+
+template <unsigned _Base, typename _Tp,
+ typename enable_if<(sizeof(_Tp) >= sizeof(unsigned)), int>::type = 0>
+_LIBCPP_HIDE_FROM_ABI int
+__to_chars_integral_width(_Tp __value) {
+ return __itoa::__integral<_Base>::__width(__value);
+}
+
+template <unsigned _Base, typename _Tp,
+ typename enable_if<(sizeof(_Tp) < sizeof(unsigned)), int>::type = 0>
+_LIBCPP_HIDE_FROM_ABI int
+__to_chars_integral_width(_Tp __value) {
+ return std::__to_chars_integral_width<_Base>(static_cast<unsigned>(__value));
+}
+
+template <unsigned _Base, typename _Tp,
+ typename enable_if<(sizeof(_Tp) >= sizeof(unsigned)), int>::type = 0>
+_LIBCPP_HIDE_FROM_ABI to_chars_result
+__to_chars_integral(char* __first, char* __last, _Tp __value) {
+ return __itoa::__integral<_Base>::__to_chars(__first, __last, __value);
+}
+
+template <unsigned _Base, typename _Tp,
+ typename enable_if<(sizeof(_Tp) < sizeof(unsigned)), int>::type = 0>
+_LIBCPP_HIDE_FROM_ABI to_chars_result
+__to_chars_integral(char* __first, char* __last, _Tp __value) {
+ return std::__to_chars_integral<_Base>(__first, __last, static_cast<unsigned>(__value));
+}
+
template <typename _Tp>
-_LIBCPP_AVAILABILITY_TO_CHARS _LIBCPP_INLINE_VISIBILITY int __to_chars_integral_width(_Tp __value, unsigned __base) {
+_LIBCPP_HIDE_FROM_ABI int
+__to_chars_integral_width(_Tp __value, unsigned __base) {
_LIBCPP_ASSERT(__value >= 0, "The function requires a non-negative value.");
unsigned __base_2 = __base * __base;
@@ -341,18 +452,26 @@ _LIBCPP_AVAILABILITY_TO_CHARS _LIBCPP_INLINE_VISIBILITY int __to_chars_integral_
__r += 4;
}
- _LIBCPP_UNREACHABLE();
+ __libcpp_unreachable();
}
template <typename _Tp>
-_LIBCPP_AVAILABILITY_TO_CHARS
-inline _LIBCPP_INLINE_VISIBILITY to_chars_result
+inline _LIBCPP_HIDE_FROM_ABI to_chars_result
__to_chars_integral(char* __first, char* __last, _Tp __value, int __base,
false_type)
{
- if (__base == 10)
+ if (__base == 10) [[likely]]
return __to_chars_itoa(__first, __last, __value, false_type());
+ switch (__base) {
+ case 2:
+ return __to_chars_integral<2>(__first, __last, __value);
+ case 8:
+ return __to_chars_integral<8>(__first, __last, __value);
+ case 16:
+ return __to_chars_integral<16>(__first, __last, __value);
+ }
+
ptrdiff_t __cap = __last - __first;
int __n = __to_chars_integral_width(__value, __base);
if (__n > __cap)
@@ -369,25 +488,28 @@ __to_chars_integral(char* __first, char* __last, _Tp __value, int __base,
}
template <typename _Tp, typename enable_if<is_integral<_Tp>::value, int>::type = 0>
-_LIBCPP_AVAILABILITY_TO_CHARS
-inline _LIBCPP_INLINE_VISIBILITY to_chars_result
+inline _LIBCPP_HIDE_FROM_ABI to_chars_result
to_chars(char* __first, char* __last, _Tp __value)
{
- return __to_chars_itoa(__first, __last, __value, is_signed<_Tp>());
+ using _Type = __make_32_64_or_128_bit_t<_Tp>;
+ static_assert(!is_same<_Type, void>::value, "unsupported integral type used in to_chars");
+ static_assert(sizeof(_Tp) <= sizeof(int64_t), "128-bit integral support isn't available yet in to_chars");
+ return std::__to_chars_itoa(__first, __last, static_cast<_Type>(__value), is_signed<_Tp>());
}
template <typename _Tp, typename enable_if<is_integral<_Tp>::value, int>::type = 0>
-_LIBCPP_AVAILABILITY_TO_CHARS
-inline _LIBCPP_INLINE_VISIBILITY to_chars_result
+inline _LIBCPP_HIDE_FROM_ABI to_chars_result
to_chars(char* __first, char* __last, _Tp __value, int __base)
{
- _LIBCPP_ASSERT(2 <= __base && __base <= 36, "base not in [2, 36]");
- return __to_chars_integral(__first, __last, __value, __base,
- is_signed<_Tp>());
+ _LIBCPP_ASSERT(2 <= __base && __base <= 36, "base not in [2, 36]");
+
+ using _Type = __make_32_64_or_128_bit_t<_Tp>;
+ static_assert(sizeof(_Tp) <= sizeof(int64_t), "128-bit integral support isn't available yet in to_chars");
+ return std::__to_chars_integral(__first, __last, static_cast<_Type>(__value), __base, is_signed<_Tp>());
}
template <typename _It, typename _Tp, typename _Fn, typename... _Ts>
-inline _LIBCPP_INLINE_VISIBILITY from_chars_result
+inline _LIBCPP_HIDE_FROM_ABI from_chars_result
__sign_combinator(_It __first, _It __last, _Tp& __value, _Fn __f, _Ts... __args)
{
using __tl = numeric_limits<_Tp>;
@@ -410,13 +532,13 @@ __sign_combinator(_It __first, _It __last, _Tp& __value, _Fn __f, _Ts... __args)
if (__x <= __complement(__to_unsigned_like(__tl::min())))
{
__x = __complement(__x);
- _VSTD::memcpy(&__value, &__x, sizeof(__x));
+ std::memcpy(&__value, &__x, sizeof(__x));
return __r;
}
}
else
{
- if (__x <= __tl::max())
+ if (__x <= __to_unsigned_like(__tl::max()))
{
__value = __x;
return __r;
@@ -427,7 +549,7 @@ __sign_combinator(_It __first, _It __last, _Tp& __value, _Fn __f, _Ts... __args)
}
template <typename _Tp>
-inline _LIBCPP_INLINE_VISIBILITY bool
+inline _LIBCPP_HIDE_FROM_ABI bool
__in_pattern(_Tp __c)
{
return '0' <= __c && __c <= '9';
@@ -438,11 +560,11 @@ struct _LIBCPP_HIDDEN __in_pattern_result
bool __ok;
int __val;
- explicit _LIBCPP_INLINE_VISIBILITY operator bool() const { return __ok; }
+ explicit _LIBCPP_HIDE_FROM_ABI operator bool() const { return __ok; }
};
template <typename _Tp>
-inline _LIBCPP_INLINE_VISIBILITY __in_pattern_result
+inline _LIBCPP_HIDE_FROM_ABI __in_pattern_result
__in_pattern(_Tp __c, int __base)
{
if (__base <= 10)
@@ -456,15 +578,15 @@ __in_pattern(_Tp __c, int __base)
}
template <typename _It, typename _Tp, typename _Fn, typename... _Ts>
-inline _LIBCPP_INLINE_VISIBILITY from_chars_result
+inline _LIBCPP_HIDE_FROM_ABI from_chars_result
__subject_seq_combinator(_It __first, _It __last, _Tp& __value, _Fn __f,
_Ts... __args)
{
- auto __find_non_zero = [](_It __first, _It __last) {
- for (; __first != __last; ++__first)
- if (*__first != '0')
+ auto __find_non_zero = [](_It __firstit, _It __lastit) {
+ for (; __firstit != __lastit; ++__firstit)
+ if (*__firstit != '0')
break;
- return __first;
+ return __firstit;
};
auto __p = __find_non_zero(__first, __last);
@@ -493,7 +615,7 @@ __subject_seq_combinator(_It __first, _It __last, _Tp& __value, _Fn __f,
}
template <typename _Tp, typename enable_if<is_unsigned<_Tp>::value, int>::type = 0>
-inline _LIBCPP_INLINE_VISIBILITY from_chars_result
+inline _LIBCPP_HIDE_FROM_ABI from_chars_result
__from_chars_atoi(const char* __first, const char* __last, _Tp& __value)
{
using __tx = __itoa::__traits<_Tp>;
@@ -501,16 +623,16 @@ __from_chars_atoi(const char* __first, const char* __last, _Tp& __value)
return __subject_seq_combinator(
__first, __last, __value,
- [](const char* __first, const char* __last,
- _Tp& __value) -> from_chars_result {
+ [](const char* _First, const char* _Last,
+ _Tp& __val) -> from_chars_result {
__output_type __a, __b;
- auto __p = __tx::__read(__first, __last, __a, __b);
- if (__p == __last || !__in_pattern(*__p))
+ auto __p = __tx::__read(_First, _Last, __a, __b);
+ if (__p == _Last || !__in_pattern(*__p))
{
__output_type __m = numeric_limits<_Tp>::max();
if (__m >= __a && __m - __a >= __b)
{
- __value = __a + __b;
+ __val = __a + __b;
return {__p, {}};
}
}
@@ -519,7 +641,7 @@ __from_chars_atoi(const char* __first, const char* __last, _Tp& __value)
}
template <typename _Tp, typename enable_if<is_signed<_Tp>::value, int>::type = 0>
-inline _LIBCPP_INLINE_VISIBILITY from_chars_result
+inline _LIBCPP_HIDE_FROM_ABI from_chars_result
__from_chars_atoi(const char* __first, const char* __last, _Tp& __value)
{
using __t = decltype(__to_unsigned_like(__value));
@@ -527,7 +649,7 @@ __from_chars_atoi(const char* __first, const char* __last, _Tp& __value)
}
template <typename _Tp, typename enable_if<is_unsigned<_Tp>::value, int>::type = 0>
-inline _LIBCPP_INLINE_VISIBILITY from_chars_result
+inline _LIBCPP_HIDE_FROM_ABI from_chars_result
__from_chars_integral(const char* __first, const char* __last, _Tp& __value,
int __base)
{
@@ -536,21 +658,21 @@ __from_chars_integral(const char* __first, const char* __last, _Tp& __value,
return __subject_seq_combinator(
__first, __last, __value,
- [](const char* __p, const char* __lastx, _Tp& __value,
- int __base) -> from_chars_result {
+ [](const char* __p, const char* __lastp, _Tp& __val,
+ int _Base) -> from_chars_result {
using __tl = numeric_limits<_Tp>;
- auto __digits = __tl::digits / log2f(float(__base));
- _Tp __a = __in_pattern(*__p++, __base).__val, __b = 0;
+ auto __digits = __tl::digits / log2f(float(_Base));
+ _Tp __a = __in_pattern(*__p++, _Base).__val, __b = 0;
- for (int __i = 1; __p != __lastx; ++__i, ++__p)
+ for (int __i = 1; __p != __lastp; ++__i, ++__p)
{
- if (auto __c = __in_pattern(*__p, __base))
+ if (auto __c = __in_pattern(*__p, _Base))
{
if (__i < __digits - 1)
- __a = __a * __base + __c.__val;
+ __a = __a * _Base + __c.__val;
else
{
- if (!__itoa::__mul_overflowed(__a, __base, __a))
+ if (!__itoa::__mul_overflowed(__a, _Base, __a))
++__p;
__b = __c.__val;
break;
@@ -560,11 +682,11 @@ __from_chars_integral(const char* __first, const char* __last, _Tp& __value,
break;
}
- if (__p == __lastx || !__in_pattern(*__p, __base))
+ if (__p == __lastp || !__in_pattern(*__p, _Base))
{
if (__tl::max() - __a >= __b)
{
- __value = __a + __b;
+ __val = __a + __b;
return {__p, {}};
}
}
@@ -574,7 +696,7 @@ __from_chars_integral(const char* __first, const char* __last, _Tp& __value,
}
template <typename _Tp, typename enable_if<is_signed<_Tp>::value, int>::type = 0>
-inline _LIBCPP_INLINE_VISIBILITY from_chars_result
+inline _LIBCPP_HIDE_FROM_ABI from_chars_result
__from_chars_integral(const char* __first, const char* __last, _Tp& __value,
int __base)
{
@@ -584,14 +706,14 @@ __from_chars_integral(const char* __first, const char* __last, _Tp& __value,
}
template <typename _Tp, typename enable_if<is_integral<_Tp>::value, int>::type = 0>
-inline _LIBCPP_INLINE_VISIBILITY from_chars_result
+inline _LIBCPP_HIDE_FROM_ABI from_chars_result
from_chars(const char* __first, const char* __last, _Tp& __value)
{
return __from_chars_atoi(__first, __last, __value);
}
template <typename _Tp, typename enable_if<is_integral<_Tp>::value, int>::type = 0>
-inline _LIBCPP_INLINE_VISIBILITY from_chars_result
+inline _LIBCPP_HIDE_FROM_ABI from_chars_result
from_chars(const char* __first, const char* __last, _Tp& __value, int __base)
{
_LIBCPP_ASSERT(2 <= __base && __base <= 36, "base not in [2, 36]");
diff --git a/libcxx/include/chrono b/libcxx/include/chrono
index eada2b8520e3..9185d74c09c4 100644
--- a/libcxx/include/chrono
+++ b/libcxx/include/chrono
@@ -694,20 +694,32 @@ constexpr chrono::year operator ""y(unsigned lo
} // std
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__chrono/calendar.h>
#include <__chrono/convert_to_timespec.h>
+#include <__chrono/day.h>
#include <__chrono/duration.h>
#include <__chrono/file_clock.h>
+#include <__chrono/hh_mm_ss.h>
#include <__chrono/high_resolution_clock.h>
+#include <__chrono/literals.h>
+#include <__chrono/month.h>
+#include <__chrono/month_weekday.h>
+#include <__chrono/monthday.h>
#include <__chrono/steady_clock.h>
#include <__chrono/system_clock.h>
#include <__chrono/time_point.h>
+#include <__chrono/weekday.h>
+#include <__chrono/year.h>
+#include <__chrono/year_month.h>
+#include <__chrono/year_month_day.h>
+#include <__chrono/year_month_weekday.h>
#include <__config>
#include <compare>
#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
#endif // _LIBCPP_CHRONO
diff --git a/libcxx/include/cinttypes b/libcxx/include/cinttypes
index 07d54a3b626a..a4cfe961cc55 100644
--- a/libcxx/include/cinttypes
+++ b/libcxx/include/cinttypes
@@ -234,12 +234,13 @@ uintmax_t wcstoumax(const wchar_t* restrict nptr, wchar_t** restrict endptr, int
} // std
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
#include <cstdint>
#include <inttypes.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/ciso646 b/libcxx/include/ciso646
index b2538d06a8dc..e0cd722495ed 100644
--- a/libcxx/include/ciso646
+++ b/libcxx/include/ciso646
@@ -15,10 +15,11 @@
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
#endif // _LIBCPP_CISO646
diff --git a/libcxx/include/climits b/libcxx/include/climits
index 2040e1ad02a4..16800a652f6d 100644
--- a/libcxx/include/climits
+++ b/libcxx/include/climits
@@ -37,11 +37,12 @@ Macros:
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
#include <limits.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
#endif // _LIBCPP_CLIMITS
diff --git a/libcxx/include/clocale b/libcxx/include/clocale
index ed8c7d240633..892604207532 100644
--- a/libcxx/include/clocale
+++ b/libcxx/include/clocale
@@ -34,11 +34,12 @@ lconv* localeconv();
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
#include <locale.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/cmath b/libcxx/include/cmath
index 8bd55542ed92..2d22151684e0 100644
--- a/libcxx/include/cmath
+++ b/libcxx/include/cmath
@@ -304,13 +304,14 @@ constexpr long double lerp(long double a, long double b, long double t) noexcept
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
#include <math.h>
#include <type_traits>
#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
diff --git a/libcxx/include/codecvt b/libcxx/include/codecvt
index 74839d199686..3e5110a008e4 100644
--- a/libcxx/include/codecvt
+++ b/libcxx/include/codecvt
@@ -54,17 +54,18 @@ class codecvt_utf8_utf16
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
#include <__locale>
#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
-enum codecvt_mode
+enum _LIBCPP_DEPRECATED_IN_CXX17 codecvt_mode
{
consume_header = 4,
generate_header = 2,
@@ -81,17 +82,21 @@ class _LIBCPP_TYPE_VIS __codecvt_utf8<wchar_t>
: public codecvt<wchar_t, char, mbstate_t>
{
unsigned long _Maxcode_;
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
codecvt_mode _Mode_;
+_LIBCPP_SUPPRESS_DEPRECATED_POP
public:
typedef wchar_t intern_type;
typedef char extern_type;
typedef mbstate_t state_type;
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
_LIBCPP_INLINE_VISIBILITY
explicit __codecvt_utf8(size_t __refs, unsigned long _Maxcode,
codecvt_mode _Mode)
: codecvt<wchar_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode),
_Mode_(_Mode) {}
+_LIBCPP_SUPPRESS_DEPRECATED_POP
protected:
virtual result
do_out(state_type& __st,
@@ -188,9 +193,10 @@ protected:
virtual int do_max_length() const _NOEXCEPT;
};
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
template <class _Elem, unsigned long _Maxcode = 0x10ffff,
codecvt_mode _Mode = (codecvt_mode)0>
-class _LIBCPP_TEMPLATE_VIS codecvt_utf8
+class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 codecvt_utf8
: public __codecvt_utf8<_Elem>
{
public:
@@ -201,6 +207,7 @@ public:
_LIBCPP_INLINE_VISIBILITY
~codecvt_utf8() {}
};
+_LIBCPP_SUPPRESS_DEPRECATED_POP
// codecvt_utf16
@@ -212,17 +219,21 @@ class _LIBCPP_TYPE_VIS __codecvt_utf16<wchar_t, false>
: public codecvt<wchar_t, char, mbstate_t>
{
unsigned long _Maxcode_;
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
codecvt_mode _Mode_;
+_LIBCPP_SUPPRESS_DEPRECATED_POP
public:
typedef wchar_t intern_type;
typedef char extern_type;
typedef mbstate_t state_type;
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
_LIBCPP_INLINE_VISIBILITY
explicit __codecvt_utf16(size_t __refs, unsigned long _Maxcode,
codecvt_mode _Mode)
: codecvt<wchar_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode),
_Mode_(_Mode) {}
+_LIBCPP_SUPPRESS_DEPRECATED_POP
protected:
virtual result
do_out(state_type& __st,
@@ -247,17 +258,21 @@ class _LIBCPP_TYPE_VIS __codecvt_utf16<wchar_t, true>
: public codecvt<wchar_t, char, mbstate_t>
{
unsigned long _Maxcode_;
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
codecvt_mode _Mode_;
+_LIBCPP_SUPPRESS_DEPRECATED_POP
public:
typedef wchar_t intern_type;
typedef char extern_type;
typedef mbstate_t state_type;
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
_LIBCPP_INLINE_VISIBILITY
explicit __codecvt_utf16(size_t __refs, unsigned long _Maxcode,
codecvt_mode _Mode)
: codecvt<wchar_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode),
_Mode_(_Mode) {}
+_LIBCPP_SUPPRESS_DEPRECATED_POP
protected:
virtual result
do_out(state_type& __st,
@@ -430,9 +445,10 @@ protected:
virtual int do_max_length() const _NOEXCEPT;
};
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
template <class _Elem, unsigned long _Maxcode = 0x10ffff,
codecvt_mode _Mode = (codecvt_mode)0>
-class _LIBCPP_TEMPLATE_VIS codecvt_utf16
+class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 codecvt_utf16
: public __codecvt_utf16<_Elem, _Mode & little_endian>
{
public:
@@ -443,6 +459,7 @@ public:
_LIBCPP_INLINE_VISIBILITY
~codecvt_utf16() {}
};
+_LIBCPP_SUPPRESS_DEPRECATED_POP
// codecvt_utf8_utf16
@@ -454,17 +471,21 @@ class _LIBCPP_TYPE_VIS __codecvt_utf8_utf16<wchar_t>
: public codecvt<wchar_t, char, mbstate_t>
{
unsigned long _Maxcode_;
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
codecvt_mode _Mode_;
+_LIBCPP_SUPPRESS_DEPRECATED_POP
public:
typedef wchar_t intern_type;
typedef char extern_type;
typedef mbstate_t state_type;
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
_LIBCPP_INLINE_VISIBILITY
explicit __codecvt_utf8_utf16(size_t __refs, unsigned long _Maxcode,
codecvt_mode _Mode)
: codecvt<wchar_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode),
_Mode_(_Mode) {}
+_LIBCPP_SUPPRESS_DEPRECATED_POP
protected:
virtual result
do_out(state_type& __st,
@@ -561,9 +582,10 @@ protected:
virtual int do_max_length() const _NOEXCEPT;
};
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
template <class _Elem, unsigned long _Maxcode = 0x10ffff,
codecvt_mode _Mode = (codecvt_mode)0>
-class _LIBCPP_TEMPLATE_VIS codecvt_utf8_utf16
+class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 codecvt_utf8_utf16
: public __codecvt_utf8_utf16<_Elem>
{
public:
@@ -574,6 +596,7 @@ public:
_LIBCPP_INLINE_VISIBILITY
~codecvt_utf8_utf16() {}
};
+_LIBCPP_SUPPRESS_DEPRECATED_POP
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/compare b/libcxx/include/compare
index 287e61690bbb..6aa1abefd3ef 100644
--- a/libcxx/include/compare
+++ b/libcxx/include/compare
@@ -140,6 +140,7 @@ namespace std {
}
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__compare/common_comparison_category.h>
#include <__compare/compare_partial_order_fallback.h>
#include <__compare/compare_strong_order_fallback.h>
@@ -156,7 +157,7 @@ namespace std {
#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
#endif // _LIBCPP_COMPARE
diff --git a/libcxx/include/complex b/libcxx/include/complex
index 2dc58c010495..87a4e5872497 100644
--- a/libcxx/include/complex
+++ b/libcxx/include/complex
@@ -231,6 +231,7 @@ template<class T> complex<T> tanh (const complex<T>&);
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
#include <cmath>
#include <iosfwd>
@@ -243,7 +244,7 @@ template<class T> complex<T> tanh (const complex<T>&);
#endif
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/complex.h b/libcxx/include/complex.h
index d44a5dd15796..a2814669c7d4 100644
--- a/libcxx/include/complex.h
+++ b/libcxx/include/complex.h
@@ -20,7 +20,7 @@
#include <__config>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
#ifdef __cplusplus
diff --git a/libcxx/include/concepts b/libcxx/include/concepts
index bfa27ddca0d4..301256ca7ef7 100644
--- a/libcxx/include/concepts
+++ b/libcxx/include/concepts
@@ -129,6 +129,7 @@ namespace std {
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__concepts/arithmetic.h>
#include <__concepts/assignable.h>
#include <__concepts/boolean_testable.h>
@@ -155,7 +156,7 @@ namespace std {
#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
#endif // _LIBCPP_CONCEPTS
diff --git a/libcxx/include/condition_variable b/libcxx/include/condition_variable
index ecec3ea8c017..dfcb7160565b 100644
--- a/libcxx/include/condition_variable
+++ b/libcxx/include/condition_variable
@@ -106,13 +106,14 @@ public:
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
#include <__mutex_base>
#include <memory>
#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
#ifndef _LIBCPP_HAS_NO_THREADS
diff --git a/libcxx/include/coroutine b/libcxx/include/coroutine
index 6e83fe285bc7..6582f5554ed0 100644
--- a/libcxx/include/coroutine
+++ b/libcxx/include/coroutine
@@ -38,6 +38,7 @@ struct suspend_always;
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
#include <__coroutine/coroutine_handle.h>
#include <__coroutine/coroutine_traits.h>
@@ -45,8 +46,15 @@ struct suspend_always;
#include <__coroutine/trivial_awaitables.h>
#include <version>
+#ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES
+# include <iosfwd>
+#endif
+
+// standard-mandated includes
+#include <compare>
+
#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
-#pragma GCC system_header
+# pragma GCC system_header
#endif
#endif // _LIBCPP_COROUTINE
diff --git a/libcxx/include/csetjmp b/libcxx/include/csetjmp
index f7afe6168751..4f40bcbf61e9 100644
--- a/libcxx/include/csetjmp
+++ b/libcxx/include/csetjmp
@@ -30,11 +30,12 @@ void longjmp(jmp_buf env, int val);
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
#include <setjmp.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/csignal b/libcxx/include/csignal
index e2c71a987692..c1b58f818b62 100644
--- a/libcxx/include/csignal
+++ b/libcxx/include/csignal
@@ -39,11 +39,15 @@ int raise(int sig);
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
-#include <signal.h>
+
+#if __has_include(<signal.h>)
+# include <signal.h>
+#endif
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/cstdarg b/libcxx/include/cstdarg
index 17fa5a550525..f36ade202b7a 100644
--- a/libcxx/include/cstdarg
+++ b/libcxx/include/cstdarg
@@ -31,11 +31,12 @@ Types:
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
#include <stdarg.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/cstdbool b/libcxx/include/cstdbool
index b7bdb9a555b6..ce608033a22c 100644
--- a/libcxx/include/cstdbool
+++ b/libcxx/include/cstdbool
@@ -19,10 +19,11 @@ Macros:
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
#undef __bool_true_false_are_defined
diff --git a/libcxx/include/cstddef b/libcxx/include/cstddef
index e77629e1ea0c..8daba076d7db 100644
--- a/libcxx/include/cstddef
+++ b/libcxx/include/cstddef
@@ -33,19 +33,21 @@ Types:
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/is_integral.h>
+#include <stddef.h>
#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
-// Don't include our own <stddef.h>; we don't want to declare ::nullptr_t.
-#include_next <stddef.h>
-#include <__nullptr>
-
_LIBCPP_BEGIN_NAMESPACE_STD
+using ::nullptr_t;
using ::ptrdiff_t _LIBCPP_USING_IF_EXISTS;
using ::size_t _LIBCPP_USING_IF_EXISTS;
@@ -53,34 +55,6 @@ using ::size_t _LIBCPP_USING_IF_EXISTS;
using ::max_align_t _LIBCPP_USING_IF_EXISTS;
#endif
-template <class _Tp> struct __libcpp_is_integral { enum { value = 0 }; };
-template <> struct __libcpp_is_integral<bool> { enum { value = 1 }; };
-template <> struct __libcpp_is_integral<char> { enum { value = 1 }; };
-template <> struct __libcpp_is_integral<signed char> { enum { value = 1 }; };
-template <> struct __libcpp_is_integral<unsigned char> { enum { value = 1 }; };
-#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-template <> struct __libcpp_is_integral<wchar_t> { enum { value = 1 }; };
-#endif
-#ifndef _LIBCPP_HAS_NO_CHAR8_T
-template <> struct __libcpp_is_integral<char8_t> { enum { value = 1 }; };
-#endif
-#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
-template <> struct __libcpp_is_integral<char16_t> { enum { value = 1 }; };
-template <> struct __libcpp_is_integral<char32_t> { enum { value = 1 }; };
-#endif
-template <> struct __libcpp_is_integral<short> { enum { value = 1 }; };
-template <> struct __libcpp_is_integral<unsigned short> { enum { value = 1 }; };
-template <> struct __libcpp_is_integral<int> { enum { value = 1 }; };
-template <> struct __libcpp_is_integral<unsigned int> { enum { value = 1 }; };
-template <> struct __libcpp_is_integral<long> { enum { value = 1 }; };
-template <> struct __libcpp_is_integral<unsigned long> { enum { value = 1 }; };
-template <> struct __libcpp_is_integral<long long> { enum { value = 1 }; };
-template <> struct __libcpp_is_integral<unsigned long long> { enum { value = 1 }; };
-#ifndef _LIBCPP_HAS_NO_INT128
-template <> struct __libcpp_is_integral<__int128_t> { enum { value = 1 }; };
-template <> struct __libcpp_is_integral<__uint128_t> { enum { value = 1 }; };
-#endif
-
_LIBCPP_END_NAMESPACE_STD
#if _LIBCPP_STD_VER > 14
@@ -88,11 +62,6 @@ namespace std // purposefully not versioned
{
enum class byte : unsigned char {};
-
-template <bool> struct __enable_if_integral_imp {};
-template <> struct __enable_if_integral_imp<true> { using type = byte; };
-template <class _Tp> using _EnableByteOverload = typename __enable_if_integral_imp<__libcpp_is_integral<_Tp>::value>::type;
-
constexpr byte operator| (byte __lhs, byte __rhs) noexcept
{
return static_cast<byte>(
@@ -133,6 +102,10 @@ constexpr byte operator~ (byte __b) noexcept
~static_cast<unsigned int>(__b)
));
}
+
+template <class _Tp>
+using _EnableByteOverload = __enable_if_t<is_integral<_Tp>::value, byte>;
+
template <class _Integer>
constexpr _EnableByteOverload<_Integer> &
operator<<=(byte& __lhs, _Integer __shift) noexcept
diff --git a/libcxx/include/cstdint b/libcxx/include/cstdint
index 8fbdd6e523fd..83cda947b497 100644
--- a/libcxx/include/cstdint
+++ b/libcxx/include/cstdint
@@ -140,11 +140,12 @@ Types:
} // std
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
#include <stdint.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/cstdio b/libcxx/include/cstdio
index 492439f675c6..d191086a85da 100644
--- a/libcxx/include/cstdio
+++ b/libcxx/include/cstdio
@@ -95,11 +95,12 @@ void perror(const char* s);
} // std
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
#include <stdio.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/cstdlib b/libcxx/include/cstdlib
index 219c68c6d371..457c31f625d8 100644
--- a/libcxx/include/cstdlib
+++ b/libcxx/include/cstdlib
@@ -81,17 +81,12 @@ void *aligned_alloc(size_t alignment, size_t size); // C11
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
#include <stdlib.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
-#endif
-
-#ifdef __GNUC__
-#define _LIBCPP_UNREACHABLE() __builtin_unreachable()
-#else
-#define _LIBCPP_UNREACHABLE() _VSTD::abort()
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -121,10 +116,8 @@ using ::abort _LIBCPP_USING_IF_EXISTS;
using ::atexit _LIBCPP_USING_IF_EXISTS;
using ::exit _LIBCPP_USING_IF_EXISTS;
using ::_Exit _LIBCPP_USING_IF_EXISTS;
-#ifndef _LIBCPP_WINDOWS_STORE_APP
using ::getenv _LIBCPP_USING_IF_EXISTS;
using ::system _LIBCPP_USING_IF_EXISTS;
-#endif
using ::bsearch _LIBCPP_USING_IF_EXISTS;
using ::qsort _LIBCPP_USING_IF_EXISTS;
using ::abs _LIBCPP_USING_IF_EXISTS;
@@ -138,11 +131,11 @@ using ::mbtowc _LIBCPP_USING_IF_EXISTS;
using ::wctomb _LIBCPP_USING_IF_EXISTS;
using ::mbstowcs _LIBCPP_USING_IF_EXISTS;
using ::wcstombs _LIBCPP_USING_IF_EXISTS;
-#if !defined(_LIBCPP_CXX03_LANG) && defined(_LIBCPP_HAS_QUICK_EXIT)
+#if !defined(_LIBCPP_CXX03_LANG)
using ::at_quick_exit _LIBCPP_USING_IF_EXISTS;
using ::quick_exit _LIBCPP_USING_IF_EXISTS;
#endif
-#if _LIBCPP_STD_VER > 14 && defined(_LIBCPP_HAS_ALIGNED_ALLOC)
+#if _LIBCPP_STD_VER > 14
using ::aligned_alloc _LIBCPP_USING_IF_EXISTS;
#endif
diff --git a/libcxx/include/cstring b/libcxx/include/cstring
index 91036f575a32..37c92e149b8f 100644
--- a/libcxx/include/cstring
+++ b/libcxx/include/cstring
@@ -56,11 +56,12 @@ size_t strlen(const char* s);
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
#include <string.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/ctgmath b/libcxx/include/ctgmath
index 108e948800de..bfcf2f98d470 100644
--- a/libcxx/include/ctgmath
+++ b/libcxx/include/ctgmath
@@ -18,11 +18,12 @@
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <ccomplex>
#include <cmath>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
#endif // _LIBCPP_CTGMATH
diff --git a/libcxx/include/ctime b/libcxx/include/ctime
index 779187d0ef51..0c6e4dfd6f98 100644
--- a/libcxx/include/ctime
+++ b/libcxx/include/ctime
@@ -45,25 +45,12 @@ int timespec_get( struct timespec *ts, int base); // C++17
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
#include <time.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
-#endif
-
-// FIXME:
-// Apple SDKs don't define ::timespec_get unconditionally in C++ mode. This
-// should be fixed in future SDKs, but for the time being we need to avoid
-// trying to use that declaration when the SDK doesn't provide it. Note that
-// we're detecting this here instead of in <__config> because we can't include
-// system headers from <__config>, since it leads to circular module dependencies.
-// This is also meant to be a very temporary workaround until the SDKs are fixed.
-#if defined(__APPLE__) && !__has_attribute(using_if_exists)
-# include <sys/cdefs.h>
-# if defined(_LIBCPP_HAS_TIMESPEC_GET) && (__DARWIN_C_LEVEL < __DARWIN_C_FULL)
-# define _LIBCPP_HAS_TIMESPEC_GET_NOT_ACTUALLY_PROVIDED
-# endif
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -72,7 +59,7 @@ using ::clock_t _LIBCPP_USING_IF_EXISTS;
using ::size_t _LIBCPP_USING_IF_EXISTS;
using ::time_t _LIBCPP_USING_IF_EXISTS;
using ::tm _LIBCPP_USING_IF_EXISTS;
-#if _LIBCPP_STD_VER > 14 && defined(_LIBCPP_HAS_TIMESPEC_GET)
+#if _LIBCPP_STD_VER > 14
using ::timespec _LIBCPP_USING_IF_EXISTS;
#endif
using ::clock _LIBCPP_USING_IF_EXISTS;
@@ -84,7 +71,7 @@ using ::ctime _LIBCPP_USING_IF_EXISTS;
using ::gmtime _LIBCPP_USING_IF_EXISTS;
using ::localtime _LIBCPP_USING_IF_EXISTS;
using ::strftime _LIBCPP_USING_IF_EXISTS;
-#if _LIBCPP_STD_VER > 14 && defined(_LIBCPP_HAS_TIMESPEC_GET) && !defined(_LIBCPP_HAS_TIMESPEC_GET_NOT_ACTUALLY_PROVIDED)
+#if _LIBCPP_STD_VER > 14
using ::timespec_get _LIBCPP_USING_IF_EXISTS;
#endif
diff --git a/libcxx/include/ctype.h b/libcxx/include/ctype.h
index 308d6e457c13..ba0925069c64 100644
--- a/libcxx/include/ctype.h
+++ b/libcxx/include/ctype.h
@@ -32,7 +32,7 @@ int toupper(int c);
#include <__config>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
#include_next <ctype.h>
diff --git a/libcxx/include/cuchar b/libcxx/include/cuchar
new file mode 100644
index 000000000000..a4ed585d1aeb
--- /dev/null
+++ b/libcxx/include/cuchar
@@ -0,0 +1,61 @@
+// -*- 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_CUCHAR
+#define _LIBCPP_CUCHAR
+
+/*
+ cuchar synopsis // since C++11
+
+Macros:
+
+ __STDC_UTF_16__
+ __STDC_UTF_32__
+
+namespace std {
+
+Types:
+
+ mbstate_t
+ size_t
+
+size_t mbrtoc16(char16_t* pc16, const char* s, size_t n, mbstate_t* ps);
+size_t c16rtomb(char* s, char16_t c16, mbstate_t* ps);
+size_t mbrtoc32(char32_t* pc32, const char* s, size_t n, mbstate_t* ps);
+size_t c32rtomb(char* s, char32_t c32, mbstate_t* ps);
+
+} // std
+
+*/
+
+#include <__assert> // all public C++ headers provide the assertion handler
+#include <__config>
+#include <uchar.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if !defined(_LIBCPP_CXX03_LANG)
+
+using ::mbstate_t _LIBCPP_USING_IF_EXISTS;
+using ::size_t _LIBCPP_USING_IF_EXISTS;
+
+using ::mbrtoc16 _LIBCPP_USING_IF_EXISTS;
+using ::c16rtomb _LIBCPP_USING_IF_EXISTS;
+using ::mbrtoc32 _LIBCPP_USING_IF_EXISTS;
+using ::c32rtomb _LIBCPP_USING_IF_EXISTS;
+
+#endif // _LIBCPP_CXX03_LANG
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_CUCHAR
diff --git a/libcxx/include/cwchar b/libcxx/include/cwchar
index e07f2df98450..5c69ab2a7bb1 100644
--- a/libcxx/include/cwchar
+++ b/libcxx/include/cwchar
@@ -102,12 +102,13 @@ size_t wcsrtombs(char* restrict dst, const wchar_t** restrict src, size_t len,
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
#include <cwctype>
#include <wchar.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/cwctype b/libcxx/include/cwctype
index b3ef1ae905ad..429b00c2446d 100644
--- a/libcxx/include/cwctype
+++ b/libcxx/include/cwctype
@@ -49,12 +49,13 @@ wctrans_t wctrans(const char* property);
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
#include <cctype>
#include <wctype.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/deque b/libcxx/include/deque
index e45d780e274f..d8f48f07954c 100644
--- a/libcxx/include/deque
+++ b/libcxx/include/deque
@@ -160,22 +160,52 @@ template <class T, class Allocator, class Predicate>
*/
+#include <__algorithm/copy.h>
+#include <__algorithm/copy_backward.h>
+#include <__algorithm/equal.h>
+#include <__algorithm/fill_n.h>
+#include <__algorithm/lexicographical_compare.h>
+#include <__algorithm/min.h>
+#include <__algorithm/remove.h>
+#include <__algorithm/remove_if.h>
+#include <__algorithm/unwrap_iter.h>
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
-#include <__debug>
+#include <__format/enable_insertable.h>
#include <__iterator/iterator_traits.h>
+#include <__iterator/next.h>
+#include <__iterator/prev.h>
+#include <__iterator/reverse_iterator.h>
#include <__split_buffer>
#include <__utility/forward.h>
-#include <algorithm>
-#include <compare>
-#include <initializer_list>
-#include <iterator>
+#include <__utility/move.h>
+#include <__utility/swap.h>
#include <limits>
#include <stdexcept>
#include <type_traits>
#include <version>
+#ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES
+# include <algorithm>
+# include <functional>
+# include <iterator>
+#endif
+
+// standard-mandated includes
+
+// [iterator.range]
+#include <__iterator/access.h>
+#include <__iterator/data.h>
+#include <__iterator/empty.h>
+#include <__iterator/reverse_access.h>
+#include <__iterator/size.h>
+
+// [deque.syn]
+#include <compare>
+#include <initializer_list>
+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
@@ -442,7 +472,7 @@ public:
{return !(__x < __y);}
private:
- _LIBCPP_INLINE_VISIBILITY __deque_iterator(__map_iterator __m, pointer __p) _NOEXCEPT
+ _LIBCPP_INLINE_VISIBILITY explicit __deque_iterator(__map_iterator __m, pointer __p) _NOEXCEPT
: __m_iter_(__m), __ptr_(__p) {}
template <class _Tp, class _Ap> friend class __deque_base;
@@ -1304,7 +1334,7 @@ public:
deque(_InputIter __f, _InputIter __l, const allocator_type& __a,
typename enable_if<__is_cpp17_input_iterator<_InputIter>::value>::type* = 0);
deque(const deque& __c);
- deque(const deque& __c, const __identity_t<allocator_type>& __a);
+ deque(const deque& __c, const __type_identity_t<allocator_type>& __a);
deque& operator=(const deque& __c);
@@ -1318,7 +1348,7 @@ public:
_LIBCPP_INLINE_VISIBILITY
deque(deque&& __c) _NOEXCEPT_(is_nothrow_move_constructible<__base>::value);
_LIBCPP_INLINE_VISIBILITY
- deque(deque&& __c, const __identity_t<allocator_type>& __a);
+ deque(deque&& __c, const __type_identity_t<allocator_type>& __a);
_LIBCPP_INLINE_VISIBILITY
deque& operator=(deque&& __c)
_NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value &&
@@ -1640,7 +1670,7 @@ deque<_Tp, _Allocator>::deque(const deque& __c)
}
template <class _Tp, class _Allocator>
-deque<_Tp, _Allocator>::deque(const deque& __c, const __identity_t<allocator_type>& __a)
+deque<_Tp, _Allocator>::deque(const deque& __c, const __type_identity_t<allocator_type>& __a)
: __base(__a)
{
__append(__c.begin(), __c.end());
@@ -1683,7 +1713,7 @@ deque<_Tp, _Allocator>::deque(deque&& __c)
template <class _Tp, class _Allocator>
inline
-deque<_Tp, _Allocator>::deque(deque&& __c, const __identity_t<allocator_type>& __a)
+deque<_Tp, _Allocator>::deque(deque&& __c, const __type_identity_t<allocator_type>& __a)
: __base(_VSTD::move(__c), __a)
{
if (__a != __c.__alloc())
@@ -3019,8 +3049,15 @@ erase_if(deque<_Tp, _Allocator>& __c, _Predicate __pred) {
__c.erase(_VSTD::remove_if(__c.begin(), __c.end(), __pred), __c.end());
return __old_size - __c.size();
}
+
+template <>
+inline constexpr bool __format::__enable_insertable<std::deque<char>> = true;
+#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+template <>
+inline constexpr bool __format::__enable_insertable<std::deque<wchar_t>> = true;
#endif
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/errno.h b/libcxx/include/errno.h
index a0bbec46bdf9..ea0559f0f5d1 100644
--- a/libcxx/include/errno.h
+++ b/libcxx/include/errno.h
@@ -25,7 +25,7 @@ Macros:
#include <__config>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
#include_next <errno.h>
diff --git a/libcxx/include/exception b/libcxx/include/exception
index 886daac4439a..412e02af3822 100644
--- a/libcxx/include/exception
+++ b/libcxx/include/exception
@@ -76,6 +76,7 @@ template <class E> void rethrow_if_nested(const E& e);
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__availability>
#include <__config>
#include <__memory/addressof.h>
@@ -89,7 +90,7 @@ template <class E> void rethrow_if_nested(const E& e);
#endif
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
namespace std // purposefully not using versioning namespace
@@ -189,15 +190,11 @@ make_exception_ptr(_Ep __e) _NOEXCEPT
class _LIBCPP_TYPE_VIS exception_ptr
{
-#if defined(__clang__)
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wunused-private-field"
-#endif
+_LIBCPP_DIAGNOSTIC_PUSH
+_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wunused-private-field")
void* __ptr1_;
void* __ptr2_;
-#if defined(__clang__)
-#pragma clang diagnostic pop
-#endif
+_LIBCPP_DIAGNOSTIC_POP
public:
exception_ptr() _NOEXCEPT;
exception_ptr(nullptr_t) _NOEXCEPT;
@@ -304,10 +301,10 @@ throw_with_nested(_Tp&& __t)
}
template <class _From, class _To>
-struct __can_dynamic_cast : public _LIBCPP_BOOL_CONSTANT(
+struct __can_dynamic_cast : _BoolConstant<
is_polymorphic<_From>::value &&
(!is_base_of<_To, _From>::value ||
- is_convertible<const _From*, const _To*>::value)) {};
+ is_convertible<const _From*, const _To*>::value)> {};
template <class _Ep>
inline _LIBCPP_INLINE_VISIBILITY
diff --git a/libcxx/include/execution b/libcxx/include/execution
index 417b11b103a2..040297038637 100644
--- a/libcxx/include/execution
+++ b/libcxx/include/execution
@@ -10,6 +10,7 @@
#ifndef _LIBCPP_EXECUTION
#define _LIBCPP_EXECUTION
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
#include <version>
@@ -18,7 +19,7 @@
#endif
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
#endif // _LIBCPP_EXECUTION
diff --git a/libcxx/include/experimental/__config b/libcxx/include/experimental/__config
index c7a7d68118a2..a71b348c0490 100644
--- a/libcxx/include/experimental/__config
+++ b/libcxx/include/experimental/__config
@@ -13,7 +13,7 @@
#include <__config>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
#define _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL namespace std { namespace experimental {
@@ -32,19 +32,6 @@
#define _LIBCPP_END_NAMESPACE_LFTS_PMR _LIBCPP_END_NAMESPACE_LFTS }
#define _VSTD_LFTS_PMR _VSTD_LFTS::pmr
-#if defined(_LIBCPP_NO_EXPERIMENTAL_DEPRECATION_WARNING_FILESYSTEM)
-# define _LIBCPP_DEPRECATED_EXPERIMENTAL_FILESYSTEM /* nothing */
-#else
-# define _LIBCPP_DEPRECATED_EXPERIMENTAL_FILESYSTEM __attribute__((deprecated("std::experimental::filesystem has now been deprecated in favor of C++17's std::filesystem. Please stop using it and start using std::filesystem. This experimental version will be removed in LLVM 11. You can remove this warning by defining the _LIBCPP_NO_EXPERIMENTAL_DEPRECATION_WARNING_FILESYSTEM macro.")))
-#endif
-
-#define _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_FILESYSTEM \
- _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL namespace filesystem _LIBCPP_DEPRECATED_EXPERIMENTAL_FILESYSTEM { \
- inline namespace v1 {
-
-#define _LIBCPP_END_NAMESPACE_EXPERIMENTAL_FILESYSTEM \
- } } _LIBCPP_END_NAMESPACE_EXPERIMENTAL
-
#if !defined(__cpp_coroutines) || __cpp_coroutines < 201703L
#define _LIBCPP_HAS_NO_EXPERIMENTAL_COROUTINES
#endif
diff --git a/libcxx/include/experimental/__memory b/libcxx/include/experimental/__memory
index 33027793895d..749cf4c0c657 100644
--- a/libcxx/include/experimental/__memory
+++ b/libcxx/include/experimental/__memory
@@ -10,7 +10,6 @@
#ifndef _LIBCPP_EXPERIMENTAL___MEMORY
#define _LIBCPP_EXPERIMENTAL___MEMORY
-#include <__functional_base>
#include <__memory/allocator_arg_t.h>
#include <__memory/uses_allocator.h>
#include <experimental/__config>
@@ -18,7 +17,7 @@
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_LFTS
diff --git a/libcxx/include/experimental/algorithm b/libcxx/include/experimental/algorithm
index a7fa18ff5dde..e0ca3c73be6b 100644
--- a/libcxx/include/experimental/algorithm
+++ b/libcxx/include/experimental/algorithm
@@ -31,13 +31,14 @@ ForwardIterator search(ForwardIterator first, ForwardIterator last,
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__debug>
#include <algorithm>
#include <experimental/__config>
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_LFTS
diff --git a/libcxx/include/experimental/coroutine b/libcxx/include/experimental/coroutine
index 4b53e4b62b40..111073bb6d67 100644
--- a/libcxx/include/experimental/coroutine
+++ b/libcxx/include/experimental/coroutine
@@ -45,24 +45,17 @@ template <class P> struct hash<coroutine_handle<P>>;
*/
-#include <__debug>
+#include <__assert> // all public C++ headers provide the assertion handler
+#include <__functional/hash.h>
+#include <__functional/operations.h>
#include <cstddef>
#include <experimental/__config>
-#include <functional>
#include <memory> // for hash<T*>
#include <new>
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
-#endif
-
-#ifdef _LIBCPP_HAS_NO_EXPERIMENTAL_COROUTINES
-# if defined(_LIBCPP_WARNING)
- _LIBCPP_WARNING("<experimental/coroutine> cannot be used with this compiler")
-# else
-# warning <experimental/coroutine> cannot be used with this compiler
-# endif
+# pragma GCC system_header
#endif
#ifndef _LIBCPP_HAS_NO_EXPERIMENTAL_COROUTINES
diff --git a/libcxx/include/experimental/deque b/libcxx/include/experimental/deque
index 41c25d95b9a0..3e3f9098a8fd 100644
--- a/libcxx/include/experimental/deque
+++ b/libcxx/include/experimental/deque
@@ -9,6 +9,7 @@
#ifndef _LIBCPP_EXPERIMENTAL_DEQUE
#define _LIBCPP_EXPERIMENTAL_DEQUE
+
/*
experimental/deque synopsis
@@ -28,12 +29,13 @@ namespace pmr {
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <deque>
#include <experimental/__config>
#include <experimental/memory_resource>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_LFTS_PMR
diff --git a/libcxx/include/experimental/filesystem b/libcxx/include/experimental/filesystem
deleted file mode 100644
index 45d80b66a874..000000000000
--- a/libcxx/include/experimental/filesystem
+++ /dev/null
@@ -1,256 +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_EXPERIMENTAL_FILESYSTEM
-#define _LIBCPP_EXPERIMENTAL_FILESYSTEM
-/*
- filesystem synopsis
-
- namespace std { namespace experimental { namespace filesystem { inline namespace v1 {
-
- class path;
-
- void swap(path& lhs, path& rhs) noexcept;
- size_t hash_value(const path& p) noexcept;
-
- bool operator==(const path& lhs, const path& rhs) noexcept;
- bool operator!=(const path& lhs, const path& rhs) noexcept;
- bool operator< (const path& lhs, const path& rhs) noexcept;
- bool operator<=(const path& lhs, const path& rhs) noexcept;
- bool operator> (const path& lhs, const path& rhs) noexcept;
- bool operator>=(const path& lhs, const path& rhs) noexcept;
-
- path operator/ (const path& lhs, const path& rhs);
-
- // fs.path.io operators are friends of path.
- template <class charT, class traits>
- friend basic_ostream<charT, traits>&
- operator<<(basic_ostream<charT, traits>& os, const path& p);
-
- template <class charT, class traits>
- friend basic_istream<charT, traits>&
- operator>>(basic_istream<charT, traits>& is, path& p);
-
- template <class Source>
- path u8path(const Source& source);
- template <class InputIterator>
- path u8path(InputIterator first, InputIterator last);
-
- class filesystem_error;
- class directory_entry;
-
- class directory_iterator;
-
- // enable directory_iterator range-based for statements
- directory_iterator begin(directory_iterator iter) noexcept;
- directory_iterator end(const directory_iterator&) noexcept;
-
- class recursive_directory_iterator;
-
- // enable recursive_directory_iterator range-based for statements
- recursive_directory_iterator begin(recursive_directory_iterator iter) noexcept;
- recursive_directory_iterator end(const recursive_directory_iterator&) noexcept;
-
- class file_status;
-
- struct space_info
- {
- uintmax_t capacity;
- uintmax_t free;
- uintmax_t available;
- };
-
- enum class file_type;
- enum class perms;
- enum class perm_options;
- enum class copy_options;
- enum class directory_options;
-
- typedef chrono::time_point<trivial-clock> file_time_type;
-
- // operational functions
-
- path absolute(const path& p);
- path absolute(const path& p, error_code &ec);
-
- path canonical(const path& p);
- path canonical(const path& p, error_code& ec);
-
- void copy(const path& from, const path& to);
- void copy(const path& from, const path& to, error_code& ec);
- void copy(const path& from, const path& to, copy_options options);
- void copy(const path& from, const path& to, copy_options options,
- error_code& ec);
-
- bool copy_file(const path& from, const path& to);
- bool copy_file(const path& from, const path& to, error_code& ec);
- bool copy_file(const path& from, const path& to, copy_options option);
- bool copy_file(const path& from, const path& to, copy_options option,
- error_code& ec);
-
- void copy_symlink(const path& existing_symlink, const path& new_symlink);
- void copy_symlink(const path& existing_symlink, const path& new_symlink,
- error_code& ec) noexcept;
-
- bool create_directories(const path& p);
- bool create_directories(const path& p, error_code& ec);
-
- bool create_directory(const path& p);
- bool create_directory(const path& p, error_code& ec) noexcept;
-
- bool create_directory(const path& p, const path& attributes);
- bool create_directory(const path& p, const path& attributes,
- error_code& ec) noexcept;
-
- void create_directory_symlink(const path& to, const path& new_symlink);
- void create_directory_symlink(const path& to, const path& new_symlink,
- error_code& ec) noexcept;
-
- void create_hard_link(const path& to, const path& new_hard_link);
- void create_hard_link(const path& to, const path& new_hard_link,
- error_code& ec) noexcept;
-
- void create_symlink(const path& to, const path& new_symlink);
- void create_symlink(const path& to, const path& new_symlink,
- error_code& ec) noexcept;
-
- path current_path();
- path current_path(error_code& ec);
- void current_path(const path& p);
- void current_path(const path& p, error_code& ec) noexcept;
-
- bool exists(file_status s) noexcept;
- bool exists(const path& p);
- bool exists(const path& p, error_code& ec) noexcept;
-
- bool equivalent(const path& p1, const path& p2);
- bool equivalent(const path& p1, const path& p2, error_code& ec) noexcept;
-
- uintmax_t file_size(const path& p);
- uintmax_t file_size(const path& p, error_code& ec) noexcept;
-
- uintmax_t hard_link_count(const path& p);
- uintmax_t hard_link_count(const path& p, error_code& ec) noexcept;
-
- bool is_block_file(file_status s) noexcept;
- bool is_block_file(const path& p);
- bool is_block_file(const path& p, error_code& ec) noexcept;
-
- bool is_character_file(file_status s) noexcept;
- bool is_character_file(const path& p);
- bool is_character_file(const path& p, error_code& ec) noexcept;
-
- bool is_directory(file_status s) noexcept;
- bool is_directory(const path& p);
- bool is_directory(const path& p, error_code& ec) noexcept;
-
- bool is_empty(const path& p);
- bool is_empty(const path& p, error_code& ec) noexcept;
-
- bool is_fifo(file_status s) noexcept;
- bool is_fifo(const path& p);
- bool is_fifo(const path& p, error_code& ec) noexcept;
-
- bool is_other(file_status s) noexcept;
- bool is_other(const path& p);
- bool is_other(const path& p, error_code& ec) noexcept;
-
- bool is_regular_file(file_status s) noexcept;
- bool is_regular_file(const path& p);
- bool is_regular_file(const path& p, error_code& ec) noexcept;
-
- bool is_socket(file_status s) noexcept;
- bool is_socket(const path& p);
- bool is_socket(const path& p, error_code& ec) noexcept;
-
- bool is_symlink(file_status s) noexcept;
- bool is_symlink(const path& p);
- bool is_symlink(const path& p, error_code& ec) noexcept;
-
- file_time_type last_write_time(const path& p);
- file_time_type last_write_time(const path& p, error_code& ec) noexcept;
- void last_write_time(const path& p, file_time_type new_time);
- void last_write_time(const path& p, file_time_type new_time,
- error_code& ec) noexcept;
-
- void permissions(const path& p, perms prms,
- perm_options opts=perm_options::replace);
- void permissions(const path& p, perms prms, error_code& ec) noexcept;
- void permissions(const path& p, perms prms, perm_options opts,
- error_code& ec);
-
- path proximate(const path& p, error_code& ec);
- path proximate(const path& p, const path& base = current_path());
- path proximate(const path& p, const path& base, error_code &ec);
-
- path read_symlink(const path& p);
- path read_symlink(const path& p, error_code& ec);
-
- path relative(const path& p, error_code& ec);
- path relative(const path& p, const path& base=current_path());
- path relative(const path& p, const path& base, error_code& ec);
-
- bool remove(const path& p);
- bool remove(const path& p, error_code& ec) noexcept;
-
- uintmax_t remove_all(const path& p);
- uintmax_t remove_all(const path& p, error_code& ec);
-
- void rename(const path& from, const path& to);
- void rename(const path& from, const path& to, error_code& ec) noexcept;
-
- void resize_file(const path& p, uintmax_t size);
- void resize_file(const path& p, uintmax_t size, error_code& ec) noexcept;
-
- space_info space(const path& p);
- space_info space(const path& p, error_code& ec) noexcept;
-
- file_status status(const path& p);
- file_status status(const path& p, error_code& ec) noexcept;
-
- bool status_known(file_status s) noexcept;
-
- file_status symlink_status(const path& p);
- file_status symlink_status(const path& p, error_code& ec) noexcept;
-
- path temp_directory_path();
- path temp_directory_path(error_code& ec);
-
- path weakly_canonical(path const& p);
- path weakly_canonical(path const& p, error_code& ec);
-
-
-} } } } // namespaces std::experimental::filesystem::v1
-
-*/
-
-#include <experimental/__config>
-#include <filesystem>
-
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
-#endif
-
-_LIBCPP_PUSH_MACROS
-#include <__undef_macros>
-
-#ifndef _LIBCPP_CXX03_LANG
-
-#define __cpp_lib_experimental_filesystem 201406
-
-_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_FILESYSTEM
-
-using namespace _VSTD_FS;
-
-_LIBCPP_END_NAMESPACE_EXPERIMENTAL_FILESYSTEM
-
-#endif // !_LIBCPP_CXX03_LANG
-
-_LIBCPP_POP_MACROS
-
-#endif // _LIBCPP_EXPERIMENTAL_FILESYSTEM
diff --git a/libcxx/include/experimental/forward_list b/libcxx/include/experimental/forward_list
index 590bef0283a2..4b102c554704 100644
--- a/libcxx/include/experimental/forward_list
+++ b/libcxx/include/experimental/forward_list
@@ -9,6 +9,7 @@
#ifndef _LIBCPP_EXPERIMENTAL_FORWARD_LIST
#define _LIBCPP_EXPERIMENTAL_FORWARD_LIST
+
/*
experimental/forward_list synopsis
@@ -28,12 +29,13 @@ namespace pmr {
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <experimental/__config>
#include <experimental/memory_resource>
#include <forward_list>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_LFTS_PMR
diff --git a/libcxx/include/experimental/functional b/libcxx/include/experimental/functional
index 8977c6354355..04f195d3cf24 100644
--- a/libcxx/include/experimental/functional
+++ b/libcxx/include/experimental/functional
@@ -18,29 +18,6 @@
namespace std {
namespace experimental {
inline namespace fundamentals_v1 {
-
- // See C++14 20.9.9, Function object binders
- template <class T> constexpr bool is_bind_expression_v
- = is_bind_expression<T>::value;
- template <class T> constexpr int is_placeholder_v
- = is_placeholder<T>::value;
-
- // 4.2, Class template function
- template<class> class function; // undefined
- template<class R, class... ArgTypes> class function<R(ArgTypes...)>;
-
- template<class R, class... ArgTypes>
- void swap(function<R(ArgTypes...)>&, function<R(ArgTypes...)>&);
-
- template<class R, class... ArgTypes>
- bool operator==(const function<R(ArgTypes...)>&, nullptr_t) noexcept;
- template<class R, class... ArgTypes>
- bool operator==(nullptr_t, const function<R(ArgTypes...)>&) noexcept;
- template<class R, class... ArgTypes>
- bool operator!=(const function<R(ArgTypes...)>&, nullptr_t) noexcept;
- template<class R, class... ArgTypes>
- bool operator!=(nullptr_t, const function<R(ArgTypes...)>&) noexcept;
-
// 4.3, Searchers
template<class ForwardIterator, class BinaryPredicate = equal_to<>>
class default_searcher;
@@ -79,16 +56,13 @@ inline namespace fundamentals_v1 {
} // namespace fundamentals_v1
} // namespace experimental
- template<class R, class... ArgTypes, class Alloc>
- struct uses_allocator<experimental::function<R(ArgTypes...)>, Alloc>;
-
} // namespace std
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__debug>
#include <__memory/uses_allocator.h>
-#include <algorithm>
#include <array>
#include <experimental/__config>
#include <functional>
@@ -97,7 +71,7 @@ inline namespace fundamentals_v1 {
#include <vector>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
@@ -105,10 +79,20 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_LFTS
+#ifdef _LIBCPP_NO_EXPERIMENTAL_DEPRECATION_WARNING_SEARCHERS
+# define _LIBCPP_DEPRECATED_DEFAULT_SEARCHER
+# define _LIBCPP_DEPRECATED_BOYER_MOORE_SEARCHER
+# define _LIBCPP_DEPRECATED_BOYER_MOORE_HORSPOOL_SEARCHER
+#else
+# define _LIBCPP_DEPRECATED_DEFAULT_SEARCHER _LIBCPP_DEPRECATED_("std::exprerimental::default_searcher will be removed in LLVM 17. Use std::default_searcher instead")
+# define _LIBCPP_DEPRECATED_BOYER_MOORE_SEARCHER _LIBCPP_DEPRECATED_("std::exprerimental::boyer_moore_searcher will be removed in LLVM 17. Use std::boyer_moore_searcher instead")
+# define _LIBCPP_DEPRECATED_BOYER_MOORE_HORSPOOL_SEARCHER _LIBCPP_DEPRECATED_("std::exprerimental::boyer_moore_horspool_searcher will be removed in LLVM 17. Use std::boyer_moore_horspool_searcher instead")
+#endif
+
#if _LIBCPP_STD_VER > 11
// default searcher
template<class _ForwardIterator, class _BinaryPredicate = equal_to<>>
-class _LIBCPP_TEMPLATE_VIS default_searcher {
+class _LIBCPP_DEPRECATED_DEFAULT_SEARCHER _LIBCPP_TEMPLATE_VIS default_searcher {
public:
_LIBCPP_INLINE_VISIBILITY
default_searcher(_ForwardIterator __f, _ForwardIterator __l,
@@ -132,7 +116,7 @@ private:
};
template<class _ForwardIterator, class _BinaryPredicate = equal_to<>>
-_LIBCPP_INLINE_VISIBILITY
+_LIBCPP_DEPRECATED_DEFAULT_SEARCHER _LIBCPP_INLINE_VISIBILITY
default_searcher<_ForwardIterator, _BinaryPredicate>
make_default_searcher( _ForwardIterator __f, _ForwardIterator __l, _BinaryPredicate __p = _BinaryPredicate ())
{
@@ -144,7 +128,6 @@ template<class _Key, class _Value, class _Hash, class _BinaryPredicate, bool /*u
// General case for BM data searching; use a map
template<class _Key, typename _Value, class _Hash, class _BinaryPredicate>
class _BMSkipTable<_Key, _Value, _Hash, _BinaryPredicate, false> {
-public: // TODO private:
typedef _Value value_type;
typedef _Key key_type;
@@ -179,7 +162,7 @@ private:
typedef _Key key_type;
typedef typename make_unsigned<key_type>::type unsigned_key_type;
- typedef std::array<value_type, numeric_limits<unsigned_key_type>::max()> skip_map;
+ typedef std::array<value_type, 256> skip_map;
skip_map __table;
public:
@@ -206,7 +189,7 @@ public:
template <class _RandomAccessIterator1,
class _Hash = hash<typename iterator_traits<_RandomAccessIterator1>::value_type>,
class _BinaryPredicate = equal_to<>>
-class _LIBCPP_TEMPLATE_VIS boyer_moore_searcher {
+class _LIBCPP_DEPRECATED_BOYER_MOORE_SEARCHER _LIBCPP_TEMPLATE_VIS boyer_moore_searcher {
private:
typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type difference_type;
typedef typename std::iterator_traits<_RandomAccessIterator1>::value_type value_type;
@@ -236,11 +219,9 @@ public:
pair<_RandomAccessIterator2, _RandomAccessIterator2>
operator ()(_RandomAccessIterator2 __f, _RandomAccessIterator2 __l) const
{
- static_assert ( std::is_same<
- typename std::__uncvref<typename std::iterator_traits<_RandomAccessIterator1>::value_type>::type,
- typename std::__uncvref<typename std::iterator_traits<_RandomAccessIterator2>::value_type>::type
- >::value,
- "Corpus and Pattern iterators must point to the same type" );
+ static_assert(__is_same_uncvref<typename iterator_traits<_RandomAccessIterator1>::value_type,
+ typename iterator_traits<_RandomAccessIterator2>::value_type>::value,
+ "Corpus and Pattern iterators must point to the same type");
if (__f == __l ) return make_pair(__l, __l); // empty corpus
if (__first_ == __last_) return make_pair(__f, __f); // empty pattern
@@ -253,7 +234,7 @@ public:
return this->__search(__f, __l);
}
-public: // TODO private:
+private:
_RandomAccessIterator1 __first_;
_RandomAccessIterator1 __last_;
_BinaryPredicate __pred_;
@@ -320,7 +301,7 @@ public: // TODO private:
vector<difference_type> & __suffix = *__suffix_.get();
if (__count > 0)
{
- vector<value_type> __scratch(__count);
+ vector<difference_type> __scratch(__count);
__compute_bm_prefix(__f, __l, __pred, __scratch);
for ( size_t __i = 0; __i <= __count; __i++ )
@@ -345,7 +326,7 @@ public: // TODO private:
template<class _RandomAccessIterator,
class _Hash = hash<typename iterator_traits<_RandomAccessIterator>::value_type>,
class _BinaryPredicate = equal_to<>>
-_LIBCPP_INLINE_VISIBILITY
+_LIBCPP_DEPRECATED_BOYER_MOORE_SEARCHER _LIBCPP_INLINE_VISIBILITY
boyer_moore_searcher<_RandomAccessIterator, _Hash, _BinaryPredicate>
make_boyer_moore_searcher( _RandomAccessIterator __f, _RandomAccessIterator __l,
_Hash __hf = _Hash(), _BinaryPredicate __p = _BinaryPredicate ())
@@ -357,7 +338,7 @@ make_boyer_moore_searcher( _RandomAccessIterator __f, _RandomAccessIterator __l,
template <class _RandomAccessIterator1,
class _Hash = hash<typename iterator_traits<_RandomAccessIterator1>::value_type>,
class _BinaryPredicate = equal_to<>>
-class _LIBCPP_TEMPLATE_VIS boyer_moore_horspool_searcher {
+class _LIBCPP_DEPRECATED_BOYER_MOORE_HORSPOOL_SEARCHER _LIBCPP_TEMPLATE_VIS boyer_moore_horspool_searcher {
private:
typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type difference_type;
typedef typename std::iterator_traits<_RandomAccessIterator1>::value_type value_type;
@@ -388,11 +369,9 @@ public:
pair<_RandomAccessIterator2, _RandomAccessIterator2>
operator ()(_RandomAccessIterator2 __f, _RandomAccessIterator2 __l) const
{
- static_assert ( std::is_same<
- typename std::__uncvref<typename std::iterator_traits<_RandomAccessIterator1>::value_type>::type,
- typename std::__uncvref<typename std::iterator_traits<_RandomAccessIterator2>::value_type>::type
- >::value,
- "Corpus and Pattern iterators must point to the same type" );
+ static_assert(__is_same_uncvref<typename std::iterator_traits<_RandomAccessIterator1>::value_type,
+ typename std::iterator_traits<_RandomAccessIterator2>::value_type>::value,
+ "Corpus and Pattern iterators must point to the same type");
if (__f == __l ) return make_pair(__l, __l); // empty corpus
if (__first_ == __last_) return make_pair(__f, __f); // empty pattern
@@ -440,7 +419,7 @@ private:
template<class _RandomAccessIterator,
class _Hash = hash<typename iterator_traits<_RandomAccessIterator>::value_type>,
class _BinaryPredicate = equal_to<>>
-_LIBCPP_INLINE_VISIBILITY
+_LIBCPP_DEPRECATED_BOYER_MOORE_HORSPOOL_SEARCHER _LIBCPP_INLINE_VISIBILITY
boyer_moore_horspool_searcher<_RandomAccessIterator, _Hash, _BinaryPredicate>
make_boyer_moore_horspool_searcher( _RandomAccessIterator __f, _RandomAccessIterator __l,
_Hash __hf = _Hash(), _BinaryPredicate __p = _BinaryPredicate ())
diff --git a/libcxx/include/experimental/iterator b/libcxx/include/experimental/iterator
index ab1f54e35eb9..a92bca6a20fa 100644
--- a/libcxx/include/experimental/iterator
+++ b/libcxx/include/experimental/iterator
@@ -52,14 +52,16 @@ namespace std {
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__memory/addressof.h>
#include <__utility/forward.h>
#include <__utility/move.h>
#include <experimental/__config>
+#include <iosfwd> // char_traits
#include <iterator>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
#if _LIBCPP_STD_VER > 11
diff --git a/libcxx/include/experimental/list b/libcxx/include/experimental/list
index be43e60f49ad..c8480575977e 100644
--- a/libcxx/include/experimental/list
+++ b/libcxx/include/experimental/list
@@ -9,6 +9,7 @@
#ifndef _LIBCPP_EXPERIMENTAL_LIST
#define _LIBCPP_EXPERIMENTAL_LIST
+
/*
experimental/list synopsis
@@ -28,12 +29,13 @@ namespace pmr {
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <experimental/__config>
#include <experimental/memory_resource>
#include <list>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_LFTS_PMR
diff --git a/libcxx/include/experimental/map b/libcxx/include/experimental/map
index 704626eed674..3dee7f703aeb 100644
--- a/libcxx/include/experimental/map
+++ b/libcxx/include/experimental/map
@@ -9,6 +9,7 @@
#ifndef _LIBCPP_EXPERIMENTAL_MAP
#define _LIBCPP_EXPERIMENTAL_MAP
+
/*
experimental/map synopsis
@@ -33,12 +34,13 @@ namespace pmr {
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <experimental/__config>
#include <experimental/memory_resource>
#include <map>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_LFTS_PMR
diff --git a/libcxx/include/experimental/memory_resource b/libcxx/include/experimental/memory_resource
index 47bb8c58c8de..f7b19aafd40f 100644
--- a/libcxx/include/experimental/memory_resource
+++ b/libcxx/include/experimental/memory_resource
@@ -64,8 +64,9 @@ namespace pmr {
*/
-#include <__debug>
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__tuple>
+#include <__utility/move.h>
#include <cstddef>
#include <cstdlib>
#include <experimental/__config>
@@ -75,10 +76,9 @@ namespace pmr {
#include <new>
#include <stdexcept>
#include <type_traits>
-#include <utility>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
diff --git a/libcxx/include/experimental/propagate_const b/libcxx/include/experimental/propagate_const
index deb4ba98a7fa..432635668e4e 100644
--- a/libcxx/include/experimental/propagate_const
+++ b/libcxx/include/experimental/propagate_const
@@ -9,6 +9,7 @@
#ifndef _LIBCPP_EXPERIMENTAL_PROPAGATE_CONST
#define _LIBCPP_EXPERIMENTAL_PROPAGATE_CONST
+
/*
propagate_const synopsis
@@ -106,13 +107,16 @@
*/
+#include <__assert> // all public C++ headers provide the assertion handler
+#include <__functional/operations.h>
+#include <__utility/forward.h>
+#include <__utility/move.h>
+#include <__utility/swap.h>
#include <experimental/__config>
-#include <functional>
#include <type_traits>
-#include <utility>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
#if _LIBCPP_STD_VER > 11
diff --git a/libcxx/include/experimental/regex b/libcxx/include/experimental/regex
index 5bb3dccf9387..4dc2bbae4510 100644
--- a/libcxx/include/experimental/regex
+++ b/libcxx/include/experimental/regex
@@ -9,6 +9,7 @@
#ifndef _LIBCPP_EXPERIMENTAL_REGEX
#define _LIBCPP_EXPERIMENTAL_REGEX
+
/*
experimental/regex synopsis
@@ -35,13 +36,14 @@ namespace pmr {
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <experimental/__config>
#include <experimental/memory_resource>
#include <experimental/string>
#include <regex>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_LFTS_PMR
diff --git a/libcxx/include/experimental/set b/libcxx/include/experimental/set
index 12b2ac23b81a..e2e75e35448b 100644
--- a/libcxx/include/experimental/set
+++ b/libcxx/include/experimental/set
@@ -9,6 +9,7 @@
#ifndef _LIBCPP_EXPERIMENTAL_SET
#define _LIBCPP_EXPERIMENTAL_SET
+
/*
experimental/set synopsis
@@ -33,12 +34,13 @@ namespace pmr {
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <experimental/__config>
#include <experimental/memory_resource>
#include <set>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_LFTS_PMR
diff --git a/libcxx/include/experimental/simd b/libcxx/include/experimental/simd
index 475155512d76..9b55cc009986 100644
--- a/libcxx/include/experimental/simd
+++ b/libcxx/include/experimental/simd
@@ -649,14 +649,20 @@ public:
*/
-#include <algorithm>
+#include <__assert> // all public C++ headers provide the assertion handler
+#include <__functional/operations.h>
#include <array>
#include <cstddef>
#include <experimental/__config>
-#include <functional>
+#include <tuple>
+
+#ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES
+# include <algorithm>
+# include <functional>
+#endif
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
@@ -1471,6 +1477,7 @@ public:
simd operator+() const;
simd operator-() const;
+#if 0
// binary operators [simd.binary]
friend simd operator+(const simd&, const simd&);
friend simd operator-(const simd&, const simd&);
@@ -1507,6 +1514,7 @@ public:
friend mask_type operator<=(const simd&, const simd&);
friend mask_type operator>(const simd&, const simd&);
friend mask_type operator<(const simd&, const simd&);
+#endif
};
// [simd.mask.class]
@@ -1546,6 +1554,7 @@ public:
// unary operators [simd.mask.unary]
simd_mask operator!() const noexcept;
+#if 0
// simd_mask binary operators [simd.mask.binary]
friend simd_mask operator&&(const simd_mask&, const simd_mask&) noexcept;
friend simd_mask operator||(const simd_mask&, const simd_mask&) noexcept;
@@ -1561,6 +1570,7 @@ public:
// simd_mask compares [simd.mask.comparison]
friend simd_mask operator==(const simd_mask&, const simd_mask&) noexcept;
friend simd_mask operator!=(const simd_mask&, const simd_mask&) noexcept;
+#endif
};
#endif // _LIBCPP_STD_VER >= 17
diff --git a/libcxx/include/experimental/string b/libcxx/include/experimental/string
index 1643e84c5a0c..c795d685d735 100644
--- a/libcxx/include/experimental/string
+++ b/libcxx/include/experimental/string
@@ -9,6 +9,7 @@
#ifndef _LIBCPP_EXPERIMENTAL_STRING
#define _LIBCPP_EXPERIMENTAL_STRING
+
/*
experimental/string synopsis
@@ -37,12 +38,13 @@ namespace pmr {
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <experimental/__config>
#include <experimental/memory_resource>
#include <string>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_LFTS_PMR
diff --git a/libcxx/include/experimental/type_traits b/libcxx/include/experimental/type_traits
index 408e62d5cb86..dd4c53963640 100644
--- a/libcxx/include/experimental/type_traits
+++ b/libcxx/include/experimental/type_traits
@@ -68,6 +68,7 @@ inline namespace fundamentals_v1 {
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <experimental/__config>
#if _LIBCPP_STD_VER > 11
@@ -76,7 +77,7 @@ inline namespace fundamentals_v1 {
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_LFTS
diff --git a/libcxx/include/experimental/unordered_map b/libcxx/include/experimental/unordered_map
index 80905e68ef36..636d31bdc557 100644
--- a/libcxx/include/experimental/unordered_map
+++ b/libcxx/include/experimental/unordered_map
@@ -9,6 +9,7 @@
#ifndef _LIBCPP_EXPERIMENTAL_UNORDERED_MAP
#define _LIBCPP_EXPERIMENTAL_UNORDERED_MAP
+
/*
experimental/unordered_map synopsis
@@ -39,12 +40,21 @@ namespace pmr {
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <experimental/__config>
#include <experimental/memory_resource>
#include <unordered_map>
+#ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES
+# include <algorithm>
+# include <array>
+# include <bit>
+# include <functional>
+# include <vector>
+#endif
+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_LFTS_PMR
diff --git a/libcxx/include/experimental/unordered_set b/libcxx/include/experimental/unordered_set
index f09b0bd57d9f..509f3ec1044e 100644
--- a/libcxx/include/experimental/unordered_set
+++ b/libcxx/include/experimental/unordered_set
@@ -9,6 +9,7 @@
#ifndef _LIBCPP_EXPERIMENTAL_UNORDERED_SET
#define _LIBCPP_EXPERIMENTAL_UNORDERED_SET
+
/*
experimental/unordered_set synopsis
@@ -33,12 +34,13 @@ namespace pmr {
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <experimental/__config>
#include <experimental/memory_resource>
#include <unordered_set>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_LFTS_PMR
diff --git a/libcxx/include/experimental/utility b/libcxx/include/experimental/utility
index 6d819da9bb1d..576b8be46357 100644
--- a/libcxx/include/experimental/utility
+++ b/libcxx/include/experimental/utility
@@ -30,11 +30,12 @@ inline namespace fundamentals_v1 {
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <experimental/__config>
#include <utility>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_LFTS
diff --git a/libcxx/include/experimental/vector b/libcxx/include/experimental/vector
index 4d31d1ccd85b..97c51c830c4a 100644
--- a/libcxx/include/experimental/vector
+++ b/libcxx/include/experimental/vector
@@ -9,6 +9,7 @@
#ifndef _LIBCPP_EXPERIMENTAL_VECTOR
#define _LIBCPP_EXPERIMENTAL_VECTOR
+
/*
experimental/vector synopsis
@@ -28,12 +29,13 @@ namespace pmr {
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <experimental/__config>
#include <experimental/memory_resource>
#include <vector>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_LFTS_PMR
diff --git a/libcxx/include/ext/__hash b/libcxx/include/ext/__hash
index f6e7a486f6b6..0e6c2cc05b52 100644
--- a/libcxx/include/ext/__hash
+++ b/libcxx/include/ext/__hash
@@ -10,9 +10,9 @@
#ifndef _LIBCPP_EXT_HASH
#define _LIBCPP_EXT_HASH
-#pragma GCC system_header
+# pragma GCC system_header
-#include <__string>
+#include <__config>
#include <cstring>
#include <string>
@@ -21,7 +21,7 @@ namespace __gnu_cxx {
template <typename _Tp> struct _LIBCPP_TEMPLATE_VIS hash { };
template <> struct _LIBCPP_TEMPLATE_VIS hash<const char*>
- : public std::unary_function<const char*, size_t>
+ : public std::__unary_function<const char*, size_t>
{
_LIBCPP_INLINE_VISIBILITY
size_t operator()(const char *__c) const _NOEXCEPT
@@ -31,7 +31,7 @@ template <> struct _LIBCPP_TEMPLATE_VIS hash<const char*>
};
template <> struct _LIBCPP_TEMPLATE_VIS hash<char *>
- : public std::unary_function<char*, size_t>
+ : public std::__unary_function<char*, size_t>
{
_LIBCPP_INLINE_VISIBILITY
size_t operator()(char *__c) const _NOEXCEPT
@@ -41,7 +41,7 @@ template <> struct _LIBCPP_TEMPLATE_VIS hash<char *>
};
template <> struct _LIBCPP_TEMPLATE_VIS hash<char>
- : public std::unary_function<char, size_t>
+ : public std::__unary_function<char, size_t>
{
_LIBCPP_INLINE_VISIBILITY
size_t operator()(char __c) const _NOEXCEPT
@@ -51,7 +51,7 @@ template <> struct _LIBCPP_TEMPLATE_VIS hash<char>
};
template <> struct _LIBCPP_TEMPLATE_VIS hash<signed char>
- : public std::unary_function<signed char, size_t>
+ : public std::__unary_function<signed char, size_t>
{
_LIBCPP_INLINE_VISIBILITY
size_t operator()(signed char __c) const _NOEXCEPT
@@ -61,7 +61,7 @@ template <> struct _LIBCPP_TEMPLATE_VIS hash<signed char>
};
template <> struct _LIBCPP_TEMPLATE_VIS hash<unsigned char>
- : public std::unary_function<unsigned char, size_t>
+ : public std::__unary_function<unsigned char, size_t>
{
_LIBCPP_INLINE_VISIBILITY
size_t operator()(unsigned char __c) const _NOEXCEPT
@@ -71,7 +71,7 @@ template <> struct _LIBCPP_TEMPLATE_VIS hash<unsigned char>
};
template <> struct _LIBCPP_TEMPLATE_VIS hash<short>
- : public std::unary_function<short, size_t>
+ : public std::__unary_function<short, size_t>
{
_LIBCPP_INLINE_VISIBILITY
size_t operator()(short __c) const _NOEXCEPT
@@ -81,7 +81,7 @@ template <> struct _LIBCPP_TEMPLATE_VIS hash<short>
};
template <> struct _LIBCPP_TEMPLATE_VIS hash<unsigned short>
- : public std::unary_function<unsigned short, size_t>
+ : public std::__unary_function<unsigned short, size_t>
{
_LIBCPP_INLINE_VISIBILITY
size_t operator()(unsigned short __c) const _NOEXCEPT
@@ -91,7 +91,7 @@ template <> struct _LIBCPP_TEMPLATE_VIS hash<unsigned short>
};
template <> struct _LIBCPP_TEMPLATE_VIS hash<int>
- : public std::unary_function<int, size_t>
+ : public std::__unary_function<int, size_t>
{
_LIBCPP_INLINE_VISIBILITY
size_t operator()(int __c) const _NOEXCEPT
@@ -101,7 +101,7 @@ template <> struct _LIBCPP_TEMPLATE_VIS hash<int>
};
template <> struct _LIBCPP_TEMPLATE_VIS hash<unsigned int>
- : public std::unary_function<unsigned int, size_t>
+ : public std::__unary_function<unsigned int, size_t>
{
_LIBCPP_INLINE_VISIBILITY
size_t operator()(unsigned int __c) const _NOEXCEPT
@@ -111,7 +111,7 @@ template <> struct _LIBCPP_TEMPLATE_VIS hash<unsigned int>
};
template <> struct _LIBCPP_TEMPLATE_VIS hash<long>
- : public std::unary_function<long, size_t>
+ : public std::__unary_function<long, size_t>
{
_LIBCPP_INLINE_VISIBILITY
size_t operator()(long __c) const _NOEXCEPT
@@ -121,7 +121,7 @@ template <> struct _LIBCPP_TEMPLATE_VIS hash<long>
};
template <> struct _LIBCPP_TEMPLATE_VIS hash<unsigned long>
- : public std::unary_function<unsigned long, size_t>
+ : public std::__unary_function<unsigned long, size_t>
{
_LIBCPP_INLINE_VISIBILITY
size_t operator()(unsigned long __c) const _NOEXCEPT
diff --git a/libcxx/include/ext/hash_map b/libcxx/include/ext/hash_map
index a52c6a4066f7..8afe12f6319b 100644
--- a/libcxx/include/ext/hash_map
+++ b/libcxx/include/ext/hash_map
@@ -201,13 +201,19 @@ template <class Key, class T, class Hash, class Pred, class Alloc>
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
#include <__hash_table>
+#include <algorithm>
#include <ext/__hash>
#include <functional>
#include <stdexcept>
#include <type_traits>
+#ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES
+# include <iterator>
+#endif
+
#if defined(__DEPRECATED) && __DEPRECATED
#if defined(_LIBCPP_WARNING)
_LIBCPP_WARNING("Use of the header <ext/hash_map> is deprecated. Migrate to <unordered_map>")
@@ -217,7 +223,7 @@ template <class Key, class T, class Hash, class Pred, class Alloc>
#endif
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
namespace __gnu_cxx {
diff --git a/libcxx/include/ext/hash_set b/libcxx/include/ext/hash_set
index bca008d172a2..433c13f80bb2 100644
--- a/libcxx/include/ext/hash_set
+++ b/libcxx/include/ext/hash_set
@@ -192,11 +192,17 @@ template <class Value, class Hash, class Pred, class Alloc>
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
#include <__hash_table>
+#include <algorithm>
#include <ext/__hash>
#include <functional>
+#ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES
+# include <iterator>
+#endif
+
#if defined(__DEPRECATED) && __DEPRECATED
#if defined(_LIBCPP_WARNING)
_LIBCPP_WARNING("Use of the header <ext/hash_set> is deprecated. Migrate to <unordered_set>")
@@ -206,7 +212,7 @@ template <class Value, class Hash, class Pred, class Alloc>
#endif
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
namespace __gnu_cxx {
diff --git a/libcxx/include/fenv.h b/libcxx/include/fenv.h
index b3ce2378219f..a9ba6800245b 100644
--- a/libcxx/include/fenv.h
+++ b/libcxx/include/fenv.h
@@ -53,7 +53,7 @@ int feupdateenv(const fenv_t* envp);
#include <__config>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
#include_next <fenv.h>
diff --git a/libcxx/include/filesystem b/libcxx/include/filesystem
index 74f596599a1e..87de8861ea42 100644
--- a/libcxx/include/filesystem
+++ b/libcxx/include/filesystem
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
#ifndef _LIBCPP_FILESYSTEM
#define _LIBCPP_FILESYSTEM
+
/*
filesystem synopsis
@@ -238,6 +239,7 @@ inline constexpr bool std::ranges::enable_view<std::filesystem::recursive_direct
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
#include <__filesystem/copy_options.h>
#include <__filesystem/directory_entry.h>
@@ -255,15 +257,17 @@ inline constexpr bool std::ranges::enable_view<std::filesystem::recursive_direct
#include <__filesystem/recursive_directory_iterator.h>
#include <__filesystem/space_info.h>
#include <__filesystem/u8path.h>
-#include <compare>
#include <version>
+// standard-mandated includes
+#include <compare>
+
#if defined(_LIBCPP_HAS_NO_FILESYSTEM_LIBRARY)
-# error "The Filesystem library is not supported since libc++ has been configured with LIBCXX_ENABLE_FILESYSTEM disabled"
+# error "The <filesystem> library is not supported since libc++ has been configured without support for a filesystem."
#endif
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
#endif // _LIBCPP_FILESYSTEM
diff --git a/libcxx/include/float.h b/libcxx/include/float.h
index e3b4f9f3442b..606081251dfb 100644
--- a/libcxx/include/float.h
+++ b/libcxx/include/float.h
@@ -73,7 +73,7 @@ Macros:
#include <__config>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
#include_next <float.h>
diff --git a/libcxx/include/format b/libcxx/include/format
index 4cf146ead17a..bf51edd91ece 100644
--- a/libcxx/include/format
+++ b/libcxx/include/format
@@ -23,15 +23,26 @@ namespace std {
using format_args = basic_format_args<format_context>;
using wformat_args = basic_format_args<wformat_context>;
+ // [format.fmt.string], class template basic-format-string
+ template<class charT, class... Args>
+ struct basic-format-string; // exposition only
+
+ template<class... Args>
+ using format-string = // exposition only
+ basic-format-string<char, type_identity_t<Args>...>;
+ template<class... Args>
+ using wformat-string = // exposition only
+ basic-format-string<wchar_t, type_identity_t<Args>...>;
+
// [format.functions], formatting functions
template<class... Args>
- string format(string_view fmt, const Args&... args);
+ string format(format-string<Args...> fmt, const Args&... args);
template<class... Args>
- wstring format(wstring_view fmt, const Args&... args);
+ wstring format(wformat-string<Args...> fmt, const Args&... args);
template<class... Args>
- string format(const locale& loc, string_view fmt, const Args&... args);
+ string format(const locale& loc, format-string<Args...> fmt, const Args&... args);
template<class... Args>
- wstring format(const locale& loc, wstring_view fmt, const Args&... args);
+ wstring format(const locale& loc, wformat-string<Args...> fmt, const Args&... args);
string vformat(string_view fmt, format_args args);
wstring vformat(wstring_view fmt, wformat_args args);
@@ -39,13 +50,13 @@ namespace std {
wstring vformat(const locale& loc, wstring_view fmt, wformat_args args);
template<class Out, class... Args>
- Out format_to(Out out, string_view fmt, const Args&... args);
+ Out format_to(Out out, format-string<Args...> fmt, const Args&... args);
template<class Out, class... Args>
- Out format_to(Out out, wstring_view fmt, const Args&... args);
+ Out format_to(Out out, wformat-string<Args...> fmt, const Args&... args);
template<class Out, class... Args>
- Out format_to(Out out, const locale& loc, string_view fmt, const Args&... args);
+ Out format_to(Out out, const locale& loc, format-string<Args...> fmt, const Args&... args);
template<class Out, class... Args>
- Out format_to(Out out, const locale& loc, wstring_view fmt, const Args&... args);
+ Out format_to(Out out, const locale& loc, wformat-string<Args...> fmt, const Args&... args);
template<class Out>
Out vformat_to(Out out, string_view fmt, format_args args);
@@ -64,27 +75,27 @@ namespace std {
};
template<class Out, class... Args>
format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n,
- string_view fmt, const Args&... args);
+ format-string<Args...> fmt, const Args&... args);
template<class Out, class... Args>
format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n,
- wstring_view fmt, const Args&... args);
+ wformat-string<Args...> fmt, const Args&... args);
template<class Out, class... Args>
format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n,
- const locale& loc, string_view fmt,
+ const locale& loc, format-string<Args...> fmt,
const Args&... args);
template<class Out, class... Args>
format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n,
- const locale& loc, wstring_view fmt,
+ const locale& loc, wformat-string<Args...> fmt,
const Args&... args);
template<class... Args>
- size_t formatted_size(string_view fmt, const Args&... args);
+ size_t formatted_size(format-string<Args...> fmt, const Args&... args);
template<class... Args>
- size_t formatted_size(wstring_view fmt, const Args&... args);
+ size_t formatted_size(wformat-string<Args...> fmt, const Args&... args);
template<class... Args>
- size_t formatted_size(const locale& loc, string_view fmt, const Args&... args);
+ size_t formatted_size(const locale& loc, format-string<Args...> fmt, const Args&... args);
template<class... Args>
- size_t formatted_size(const locale& loc, wstring_view fmt, const Args&... args);
+ size_t formatted_size(const locale& loc, wformat-string<Args...> fmt, const Args&... args);
// [format.formatter], formatter
template<class T, class charT = char> struct formatter;
@@ -117,14 +128,20 @@ namespace std {
*/
+#include <__assert> // all public C++ headers provide the assertion handler
// Make sure all feature-test macros are available.
#include <version>
// Enable the contents of the header only when libc++ was built with LIBCXX_ENABLE_INCOMPLETE_FEATURES.
#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)
+#include <__algorithm/clamp.h>
#include <__config>
#include <__debug>
+#include <__format/buffer.h>
+#include <__format/concepts.h>
+#include <__format/enable_insertable.h>
#include <__format/format_arg.h>
+#include <__format/format_arg_store.h>
#include <__format/format_args.h>
#include <__format/format_context.h>
#include <__format/format_error.h>
@@ -140,6 +157,8 @@ namespace std {
#include <__format/formatter_pointer.h>
#include <__format/formatter_string.h>
#include <__format/parser_std_format_spec.h>
+#include <__iterator/back_insert_iterator.h>
+#include <__iterator/incrementable_traits.h>
#include <__variant/monostate.h>
#include <array>
#include <concepts>
@@ -152,22 +171,13 @@ namespace std {
#endif
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
-_LIBCPP_PUSH_MACROS
-#include <__undef_macros>
-
_LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER > 17
-// TODO FMT Remove this once we require compilers with proper C++20 support.
-// If the compiler has no concepts support, the format header will be disabled.
-// Without concepts support enable_if needs to be used and that too much effort
-// to support compilers with partial C++20 support.
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
-
// TODO FMT Move the implementation in this file to its own granular headers.
// TODO FMT Evaluate which templates should be external templates. This
@@ -180,30 +190,198 @@ using format_args = basic_format_args<format_context>;
using wformat_args = basic_format_args<wformat_context>;
#endif
+// TODO FMT This helper wrapper can probably be removed after P2418 has been
+// implemented.
template <class _Context, class... _Args>
-struct _LIBCPP_TEMPLATE_VIS __format_arg_store {
- // TODO FMT Use a built-in array.
- array<basic_format_arg<_Context>, sizeof...(_Args)> __args;
-};
+_LIBCPP_HIDE_FROM_ABI __format_arg_store<_Context, _Args...>
+__make_format_args(_Args&&... __args) {
+ return _VSTD::__format_arg_store<_Context, _Args...>(
+ _VSTD::forward<_Args>(__args)...);
+}
+// TODO FMT After P2418 specify the return type instead of using auto.
template <class _Context = format_context, class... _Args>
-_LIBCPP_HIDE_FROM_ABI __format_arg_store<_Context, _Args...>
-make_format_args(const _Args&... __args) {
- return {basic_format_arg<_Context>(__args)...};
+_LIBCPP_HIDE_FROM_ABI auto make_format_args(const _Args&... __args) {
+ return _VSTD::__make_format_args<_Context>(__args...);
}
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+// TODO FMT After P2418 specify the return type instead of using auto.
template <class... _Args>
-_LIBCPP_HIDE_FROM_ABI __format_arg_store<wformat_context, _Args...>
-make_wformat_args(const _Args&... __args) {
+_LIBCPP_HIDE_FROM_ABI auto make_wformat_args(const _Args&... __args) {
return _VSTD::make_format_args<wformat_context>(__args...);
}
#endif
namespace __format {
+/// Helper class parse and handle argument.
+///
+/// When parsing a handle which is not enabled the code is ill-formed.
+/// This helper uses the parser of the appropriate formatter for the stored type.
+template <class _CharT>
+class _LIBCPP_TEMPLATE_VIS __compile_time_handle {
+public:
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr void __parse(basic_format_parse_context<_CharT>& __parse_ctx) const { __parse_(__parse_ctx); }
+
+ template <class _Tp>
+ _LIBCPP_HIDE_FROM_ABI constexpr void __enable() {
+ __parse_ = [](basic_format_parse_context<_CharT>& __parse_ctx) {
+ formatter<_Tp, _CharT> __f;
+ __parse_ctx.advance_to(__f.parse(__parse_ctx));
+ };
+ }
+
+ // Before calling __parse the proper handler needs to be set with __enable.
+ // The default handler isn't a core constant expression.
+ _LIBCPP_HIDE_FROM_ABI constexpr __compile_time_handle()
+ : __parse_([](basic_format_parse_context<_CharT>&) { __throw_format_error("Not a handle"); }) {}
+
+private:
+ void (*__parse_)(basic_format_parse_context<_CharT>&);
+};
+
+// Dummy format_context only providing the parts used during constant
+// validation of the basic-format-string.
+template <class _CharT>
+struct _LIBCPP_TEMPLATE_VIS __compile_time_basic_format_context {
+public:
+ using char_type = _CharT;
+
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit __compile_time_basic_format_context(
+ const __arg_t* __args, const __compile_time_handle<_CharT>* __handles, size_t __size)
+ : __args_(__args), __handles_(__handles), __size_(__size) {}
+
+ // During the compile-time validation nothing needs to be written.
+ // Therefore all operations of this iterator are a NOP.
+ struct iterator {
+ _LIBCPP_HIDE_FROM_ABI constexpr iterator& operator=(_CharT) { return *this; }
+ _LIBCPP_HIDE_FROM_ABI constexpr iterator& operator*() { return *this; }
+ _LIBCPP_HIDE_FROM_ABI constexpr iterator operator++(int) { return *this; }
+ };
+
+ _LIBCPP_HIDE_FROM_ABI constexpr __arg_t arg(size_t __id) const {
+ if (__id >= __size_)
+ __throw_format_error("Argument index out of bounds");
+ return __args_[__id];
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr const __compile_time_handle<_CharT>& __handle(size_t __id) const {
+ if (__id >= __size_)
+ __throw_format_error("Argument index out of bounds");
+ return __handles_[__id];
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr iterator out() { return {}; }
+ _LIBCPP_HIDE_FROM_ABI constexpr void advance_to(iterator) {}
+
+private:
+ const __arg_t* __args_;
+ const __compile_time_handle<_CharT>* __handles_;
+ size_t __size_;
+};
+
+_LIBCPP_HIDE_FROM_ABI
+constexpr void __compile_time_validate_integral(__arg_t __type) {
+ switch (__type) {
+ case __arg_t::__int:
+ case __arg_t::__long_long:
+ case __arg_t::__i128:
+ case __arg_t::__unsigned:
+ case __arg_t::__unsigned_long_long:
+ case __arg_t::__u128:
+ return;
+
+ default:
+ __throw_format_error("Argument isn't an integral type");
+ }
+}
+
+// _HasPrecision does the formatter have a precision?
+template <class _CharT, class _Tp, bool _HasPrecision = false>
+_LIBCPP_HIDE_FROM_ABI constexpr void
+__compile_time_validate_argument(basic_format_parse_context<_CharT>& __parse_ctx,
+ __compile_time_basic_format_context<_CharT>& __ctx) {
+ formatter<_Tp, _CharT> __formatter;
+ __parse_ctx.advance_to(__formatter.parse(__parse_ctx));
+ // [format.string.std]/7
+ // ... If the corresponding formatting argument is not of integral type, or
+ // its value is negative for precision or non-positive for width, an
+ // exception of type format_error is thrown.
+ //
+ // Validate whether the arguments are integrals.
+ if constexpr (requires(formatter<_Tp, _CharT> __f) { __f.__width_needs_substitution(); }) {
+ // TODO FMT Remove this when parser v1 has been phased out.
+ if (__formatter.__width_needs_substitution())
+ __format::__compile_time_validate_integral(__ctx.arg(__formatter.__width));
+
+ if constexpr (_HasPrecision)
+ if (__formatter.__precision_needs_substitution())
+ __format::__compile_time_validate_integral(__ctx.arg(__formatter.__precision));
+ } else {
+ if (__formatter.__parser_.__width_as_arg_)
+ __format::__compile_time_validate_integral(__ctx.arg(__formatter.__parser_.__width_));
+
+ if constexpr (_HasPrecision)
+ if (__formatter.__parser_.__precision_as_arg_)
+ __format::__compile_time_validate_integral(__ctx.arg(__formatter.__parser_.__precision_));
+ }
+}
+
+template <class _CharT>
+_LIBCPP_HIDE_FROM_ABI constexpr void __compile_time_visit_format_arg(basic_format_parse_context<_CharT>& __parse_ctx,
+ __compile_time_basic_format_context<_CharT>& __ctx,
+ __arg_t __type) {
+ switch (__type) {
+ case __arg_t::__none:
+ __throw_format_error("Invalid argument");
+ case __arg_t::__boolean:
+ return __format::__compile_time_validate_argument<_CharT, bool>(__parse_ctx, __ctx);
+ case __arg_t::__char_type:
+ return __format::__compile_time_validate_argument<_CharT, _CharT>(__parse_ctx, __ctx);
+ case __arg_t::__int:
+ return __format::__compile_time_validate_argument<_CharT, int>(__parse_ctx, __ctx);
+ case __arg_t::__long_long:
+ return __format::__compile_time_validate_argument<_CharT, long long>(__parse_ctx, __ctx);
+ case __arg_t::__i128:
+# ifndef _LIBCPP_HAS_NO_INT128
+ return __format::__compile_time_validate_argument<_CharT, __int128_t>(__parse_ctx, __ctx);
+# else
+ __throw_format_error("Invalid argument");
+# endif
+ return;
+ case __arg_t::__unsigned:
+ return __format::__compile_time_validate_argument<_CharT, unsigned>(__parse_ctx, __ctx);
+ case __arg_t::__unsigned_long_long:
+ return __format::__compile_time_validate_argument<_CharT, unsigned long long>(__parse_ctx, __ctx);
+ case __arg_t::__u128:
+# ifndef _LIBCPP_HAS_NO_INT128
+ return __format::__compile_time_validate_argument<_CharT, __uint128_t>(__parse_ctx, __ctx);
+# else
+ __throw_format_error("Invalid argument");
+# endif
+ return;
+ case __arg_t::__float:
+ return __format::__compile_time_validate_argument<_CharT, float, true>(__parse_ctx, __ctx);
+ case __arg_t::__double:
+ return __format::__compile_time_validate_argument<_CharT, double, true>(__parse_ctx, __ctx);
+ case __arg_t::__long_double:
+ return __format::__compile_time_validate_argument<_CharT, long double, true>(__parse_ctx, __ctx);
+ case __arg_t::__const_char_type_ptr:
+ return __format::__compile_time_validate_argument<_CharT, const _CharT*, true>(__parse_ctx, __ctx);
+ case __arg_t::__string_view:
+ return __format::__compile_time_validate_argument<_CharT, basic_string_view<_CharT>, true>(__parse_ctx, __ctx);
+ case __arg_t::__ptr:
+ return __format::__compile_time_validate_argument<_CharT, const void*>(__parse_ctx, __ctx);
+ case __arg_t::__handle:
+ __throw_format_error("Handle should use __compile_time_validate_handle_argument");
+ }
+ __throw_format_error("Invalid argument");
+}
+
template <class _CharT, class _ParseCtx, class _Ctx>
-_LIBCPP_HIDE_FROM_ABI const _CharT*
+_LIBCPP_HIDE_FROM_ABI constexpr const _CharT*
__handle_replacement_field(const _CharT* __begin, const _CharT* __end,
_ParseCtx& __parse_ctx, _Ctx& __ctx) {
__format::__parse_number_result __r =
@@ -223,19 +401,26 @@ __handle_replacement_field(const _CharT* __begin, const _CharT* __end,
"The replacement field arg-id should terminate at a ':' or '}'");
}
- _VSTD::visit_format_arg(
- [&](auto __arg) {
- if constexpr (same_as<decltype(__arg), monostate>)
- __throw_format_error("Argument index out of bounds");
- else if constexpr (same_as<decltype(__arg), typename basic_format_arg<_Ctx>::handle>)
- __arg.format(__parse_ctx, __ctx);
- else {
- formatter<decltype(__arg), _CharT> __formatter;
- __parse_ctx.advance_to(__formatter.parse(__parse_ctx));
- __ctx.advance_to(__formatter.format(__arg, __ctx));
- }
- },
- __ctx.arg(__r.__value));
+ if constexpr (same_as<_Ctx, __compile_time_basic_format_context<_CharT>>) {
+ __arg_t __type = __ctx.arg(__r.__value);
+ if (__type == __arg_t::__handle)
+ __ctx.__handle(__r.__value).__parse(__parse_ctx);
+ else
+ __format::__compile_time_visit_format_arg(__parse_ctx, __ctx, __type);
+ } else
+ _VSTD::visit_format_arg(
+ [&](auto __arg) {
+ if constexpr (same_as<decltype(__arg), monostate>)
+ __throw_format_error("Argument index out of bounds");
+ else if constexpr (same_as<decltype(__arg), typename basic_format_arg<_Ctx>::handle>)
+ __arg.format(__parse_ctx, __ctx);
+ else {
+ formatter<decltype(__arg), _CharT> __formatter;
+ __parse_ctx.advance_to(__formatter.parse(__parse_ctx));
+ __ctx.advance_to(__formatter.format(__arg, __ctx));
+ }
+ },
+ __ctx.arg(__r.__value));
__begin = __parse_ctx.begin();
if (__begin == __end || *__begin != _CharT('}'))
@@ -245,7 +430,7 @@ __handle_replacement_field(const _CharT* __begin, const _CharT* __end,
}
template <class _ParseCtx, class _Ctx>
-_LIBCPP_HIDE_FROM_ABI typename _Ctx::iterator
+_LIBCPP_HIDE_FROM_ABI constexpr typename _Ctx::iterator
__vformat_to(_ParseCtx&& __parse_ctx, _Ctx&& __ctx) {
using _CharT = typename _ParseCtx::char_type;
static_assert(same_as<typename _Ctx::char_type, _CharT>);
@@ -290,6 +475,56 @@ __vformat_to(_ParseCtx&& __parse_ctx, _Ctx&& __ctx) {
} // namespace __format
+template <class _CharT, class... _Args>
+struct _LIBCPP_TEMPLATE_VIS __basic_format_string {
+ basic_string_view<_CharT> __str_;
+
+ template <class _Tp>
+ requires convertible_to<const _Tp&, basic_string_view<_CharT>>
+ consteval __basic_format_string(const _Tp& __str) : __str_{__str} {
+ __format::__vformat_to(basic_format_parse_context<_CharT>{__str_, sizeof...(_Args)},
+ _Context{__types_.data(), __handles_.data(), sizeof...(_Args)});
+ }
+
+private:
+ using _Context = __format::__compile_time_basic_format_context<_CharT>;
+
+ static constexpr array<__format::__arg_t, sizeof...(_Args)> __types_{
+ __format::__determine_arg_t<_Context, remove_cvref_t<_Args>>()...};
+
+ // TODO FMT remove this work-around when the AIX ICE has been resolved.
+# if defined(_AIX) && defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER < 1400
+ template <class _Tp>
+ static constexpr __format::__compile_time_handle<_CharT> __get_handle() {
+ __format::__compile_time_handle<_CharT> __handle;
+ if (__format::__determine_arg_t<_Context, _Tp>() == __format::__arg_t::__handle)
+ __handle.template __enable<_Tp>();
+
+ return __handle;
+ }
+
+ static constexpr array<__format::__compile_time_handle<_CharT>, sizeof...(_Args)> __handles_{
+ __get_handle<_Args>()...};
+# else
+ static constexpr array<__format::__compile_time_handle<_CharT>, sizeof...(_Args)> __handles_{[] {
+ using _Tp = remove_cvref_t<_Args>;
+ __format::__compile_time_handle<_CharT> __handle;
+ if (__format::__determine_arg_t<_Context, _Tp>() == __format::__arg_t::__handle)
+ __handle.template __enable<_Tp>();
+
+ return __handle;
+ }()...};
+# endif
+};
+
+template <class... _Args>
+using __format_string_t = __basic_format_string<char, type_identity_t<_Args>...>;
+
+#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+template <class... _Args>
+using __wformat_string_t = __basic_format_string<wchar_t, type_identity_t<_Args>...>;
+#endif
+
template <class _OutIt, class _CharT, class _FormatOutIt>
requires(output_iterator<_OutIt, const _CharT&>) _LIBCPP_HIDE_FROM_ABI _OutIt
__vformat_to(
@@ -300,14 +535,18 @@ requires(output_iterator<_OutIt, const _CharT&>) _LIBCPP_HIDE_FROM_ABI _OutIt
basic_format_parse_context{__fmt, __args.__size()},
_VSTD::__format_context_create(_VSTD::move(__out_it), __args));
else {
- basic_string<_CharT> __str;
+ __format::__format_buffer<_OutIt, _CharT> __buffer{_VSTD::move(__out_it)};
_VSTD::__format::__vformat_to(
basic_format_parse_context{__fmt, __args.__size()},
- _VSTD::__format_context_create(_VSTD::back_inserter(__str), __args));
- return _VSTD::copy_n(__str.begin(), __str.size(), _VSTD::move(__out_it));
+ _VSTD::__format_context_create(__buffer.make_output_iterator(),
+ __args));
+ return _VSTD::move(__buffer).out();
}
}
+// The function is _LIBCPP_ALWAYS_INLINE since the compiler is bad at inlining
+// https://reviews.llvm.org/D110499#inline-1180704
+// TODO FMT Evaluate whether we want to file a Clang bug report regarding this.
template <output_iterator<const char&> _OutIt>
_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt
vformat_to(_OutIt __out_it, string_view __fmt, format_args __args) {
@@ -324,16 +563,16 @@ vformat_to(_OutIt __out_it, wstring_view __fmt, wformat_args __args) {
template <output_iterator<const char&> _OutIt, class... _Args>
_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt
-format_to(_OutIt __out_it, string_view __fmt, const _Args&... __args) {
- return _VSTD::vformat_to(_VSTD::move(__out_it), __fmt,
+format_to(_OutIt __out_it, __format_string_t<_Args...> __fmt, const _Args&... __args) {
+ return _VSTD::vformat_to(_VSTD::move(__out_it), __fmt.__str_,
_VSTD::make_format_args(__args...));
}
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
template <output_iterator<const wchar_t&> _OutIt, class... _Args>
_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt
-format_to(_OutIt __out_it, wstring_view __fmt, const _Args&... __args) {
- return _VSTD::vformat_to(_VSTD::move(__out_it), __fmt,
+format_to(_OutIt __out_it, __wformat_string_t<_Args...> __fmt, const _Args&... __args) {
+ return _VSTD::vformat_to(_VSTD::move(__out_it), __fmt.__str_,
_VSTD::make_wformat_args(__args...));
}
#endif
@@ -355,60 +594,63 @@ vformat(wstring_view __fmt, wformat_args __args) {
#endif
template <class... _Args>
-_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string
-format(string_view __fmt, const _Args&... __args) {
- return _VSTD::vformat(__fmt, _VSTD::make_format_args(__args...));
+_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string format(__format_string_t<_Args...> __fmt,
+ const _Args&... __args) {
+ return _VSTD::vformat(__fmt.__str_, _VSTD::make_format_args(__args...));
}
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
template <class... _Args>
_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring
-format(wstring_view __fmt, const _Args&... __args) {
- return _VSTD::vformat(__fmt, _VSTD::make_wformat_args(__args...));
+format(__wformat_string_t<_Args...> __fmt, const _Args&... __args) {
+ return _VSTD::vformat(__fmt.__str_, _VSTD::make_wformat_args(__args...));
}
#endif
+template <class _Context, class _OutIt, class _CharT>
+_LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt> __vformat_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n,
+ basic_string_view<_CharT> __fmt,
+ basic_format_args<_Context> __args) {
+ __format::__format_to_n_buffer<_OutIt, _CharT> __buffer{_VSTD::move(__out_it), __n};
+ _VSTD::__format::__vformat_to(basic_format_parse_context{__fmt, __args.__size()},
+ _VSTD::__format_context_create(__buffer.make_output_iterator(), __args));
+ return _VSTD::move(__buffer).result();
+}
+
template <output_iterator<const char&> _OutIt, class... _Args>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt>
-format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, string_view __fmt,
- const _Args&... __args) {
- // TODO FMT Improve PoC: using std::string is inefficient.
- string __str = _VSTD::vformat(__fmt, _VSTD::make_format_args(__args...));
- iter_difference_t<_OutIt> __s = __str.size();
- iter_difference_t<_OutIt> __m =
- _VSTD::clamp(__n, iter_difference_t<_OutIt>(0), __s);
- __out_it = _VSTD::copy_n(__str.begin(), __m, _VSTD::move(__out_it));
- return {_VSTD::move(__out_it), __s};
+_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt>
+format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, __format_string_t<_Args...> __fmt, const _Args&... __args) {
+ return _VSTD::__vformat_to_n<format_context>(_VSTD::move(__out_it), __n, __fmt.__str_, _VSTD::make_format_args(__args...));
}
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
template <output_iterator<const wchar_t&> _OutIt, class... _Args>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt>
-format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, wstring_view __fmt,
+format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, __wformat_string_t<_Args...> __fmt,
const _Args&... __args) {
- // TODO FMT Improve PoC: using std::string is inefficient.
- wstring __str = _VSTD::vformat(__fmt, _VSTD::make_wformat_args(__args...));
- iter_difference_t<_OutIt> __s = __str.size();
- iter_difference_t<_OutIt> __m =
- _VSTD::clamp(__n, iter_difference_t<_OutIt>(0), __s);
- __out_it = _VSTD::copy_n(__str.begin(), __m, _VSTD::move(__out_it));
- return {_VSTD::move(__out_it), __s};
+ return _VSTD::__vformat_to_n<wformat_context>(_VSTD::move(__out_it), __n, __fmt.__str_, _VSTD::make_wformat_args(__args...));
}
#endif
+template <class _CharT>
+_LIBCPP_HIDE_FROM_ABI size_t __vformatted_size(basic_string_view<_CharT> __fmt, auto __args) {
+ __format::__formatted_size_buffer<_CharT> __buffer;
+ _VSTD::__format::__vformat_to(basic_format_parse_context{__fmt, __args.__size()},
+ _VSTD::__format_context_create(__buffer.make_output_iterator(), __args));
+ return _VSTD::move(__buffer).result();
+}
+
template <class... _Args>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t
-formatted_size(string_view __fmt, const _Args&... __args) {
- // TODO FMT Improve PoC: using std::string is inefficient.
- return _VSTD::vformat(__fmt, _VSTD::make_format_args(__args...)).size();
+_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t
+formatted_size(__format_string_t<_Args...> __fmt, const _Args&... __args) {
+ return _VSTD::__vformatted_size(__fmt.__str_, basic_format_args{_VSTD::make_format_args(__args...)});
}
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
template <class... _Args>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t
-formatted_size(wstring_view __fmt, const _Args&... __args) {
- // TODO FMT Improve PoC: using std::string is inefficient.
- return _VSTD::vformat(__fmt, _VSTD::make_wformat_args(__args...)).size();
+_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t
+formatted_size(__wformat_string_t<_Args...> __fmt, const _Args&... __args) {
+ return _VSTD::__vformatted_size(__fmt.__str_, basic_format_args{_VSTD::make_wformat_args(__args...)});
}
#endif
@@ -425,12 +667,12 @@ requires(output_iterator<_OutIt, const _CharT&>) _LIBCPP_HIDE_FROM_ABI _OutIt
_VSTD::__format_context_create(_VSTD::move(__out_it), __args,
_VSTD::move(__loc)));
else {
- basic_string<_CharT> __str;
+ __format::__format_buffer<_OutIt, _CharT> __buffer{_VSTD::move(__out_it)};
_VSTD::__format::__vformat_to(
basic_format_parse_context{__fmt, __args.__size()},
- _VSTD::__format_context_create(_VSTD::back_inserter(__str), __args,
- _VSTD::move(__loc)));
- return _VSTD::copy_n(__str.begin(), __str.size(), _VSTD::move(__out_it));
+ _VSTD::__format_context_create(__buffer.make_output_iterator(),
+ __args, _VSTD::move(__loc)));
+ return _VSTD::move(__buffer).out();
}
}
@@ -451,17 +693,17 @@ _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt v
#endif
template <output_iterator<const char&> _OutIt, class... _Args>
-_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt format_to(
- _OutIt __out_it, locale __loc, string_view __fmt, const _Args&... __args) {
- return _VSTD::vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt,
+_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt
+format_to(_OutIt __out_it, locale __loc, __format_string_t<_Args...> __fmt, const _Args&... __args) {
+ return _VSTD::vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt.__str_,
_VSTD::make_format_args(__args...));
}
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
template <output_iterator<const wchar_t&> _OutIt, class... _Args>
-_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt format_to(
- _OutIt __out_it, locale __loc, wstring_view __fmt, const _Args&... __args) {
- return _VSTD::vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt,
+_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt
+format_to(_OutIt __out_it, locale __loc, __wformat_string_t<_Args...> __fmt, const _Args&... __args) {
+ return _VSTD::vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt.__str_,
_VSTD::make_wformat_args(__args...));
}
#endif
@@ -485,80 +727,80 @@ vformat(locale __loc, wstring_view __fmt, wformat_args __args) {
#endif
template <class... _Args>
-_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string
-format(locale __loc, string_view __fmt, const _Args&... __args) {
- return _VSTD::vformat(_VSTD::move(__loc), __fmt,
+_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string format(locale __loc,
+ __format_string_t<_Args...> __fmt,
+ const _Args&... __args) {
+ return _VSTD::vformat(_VSTD::move(__loc), __fmt.__str_,
_VSTD::make_format_args(__args...));
}
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
template <class... _Args>
_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring
-format(locale __loc, wstring_view __fmt, const _Args&... __args) {
- return _VSTD::vformat(_VSTD::move(__loc), __fmt,
+format(locale __loc, __wformat_string_t<_Args...> __fmt, const _Args&... __args) {
+ return _VSTD::vformat(_VSTD::move(__loc), __fmt.__str_,
_VSTD::make_wformat_args(__args...));
}
#endif
+template <class _Context, class _OutIt, class _CharT>
+_LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt> __vformat_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n,
+ locale __loc, basic_string_view<_CharT> __fmt,
+ basic_format_args<_Context> __args) {
+ __format::__format_to_n_buffer<_OutIt, _CharT> __buffer{_VSTD::move(__out_it), __n};
+ _VSTD::__format::__vformat_to(
+ basic_format_parse_context{__fmt, __args.__size()},
+ _VSTD::__format_context_create(__buffer.make_output_iterator(), __args, _VSTD::move(__loc)));
+ return _VSTD::move(__buffer).result();
+}
+
template <output_iterator<const char&> _OutIt, class... _Args>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt>
-format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, locale __loc,
- string_view __fmt, const _Args&... __args) {
- // TODO FMT Improve PoC: using std::string is inefficient.
- string __str = _VSTD::vformat(_VSTD::move(__loc), __fmt,
- _VSTD::make_format_args(__args...));
- iter_difference_t<_OutIt> __s = __str.size();
- iter_difference_t<_OutIt> __m =
- _VSTD::clamp(__n, iter_difference_t<_OutIt>(0), __s);
- __out_it = _VSTD::copy_n(__str.begin(), __m, _VSTD::move(__out_it));
- return {_VSTD::move(__out_it), __s};
+_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt>
+format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, locale __loc, __format_string_t<_Args...> __fmt,
+ const _Args&... __args) {
+ return _VSTD::__vformat_to_n<format_context>(_VSTD::move(__out_it), __n, _VSTD::move(__loc), __fmt.__str_,
+ _VSTD::make_format_args(__args...));
}
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
template <output_iterator<const wchar_t&> _OutIt, class... _Args>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt>
-format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, locale __loc,
- wstring_view __fmt, const _Args&... __args) {
- // TODO FMT Improve PoC: using std::string is inefficient.
- wstring __str = _VSTD::vformat(_VSTD::move(__loc), __fmt,
- _VSTD::make_wformat_args(__args...));
- iter_difference_t<_OutIt> __s = __str.size();
- iter_difference_t<_OutIt> __m =
- _VSTD::clamp(__n, iter_difference_t<_OutIt>(0), __s);
- __out_it = _VSTD::copy_n(__str.begin(), __m, _VSTD::move(__out_it));
- return {_VSTD::move(__out_it), __s};
+_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt>
+format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, locale __loc, __wformat_string_t<_Args...> __fmt,
+ const _Args&... __args) {
+ return _VSTD::__vformat_to_n<wformat_context>(_VSTD::move(__out_it), __n, _VSTD::move(__loc), __fmt.__str_,
+ _VSTD::make_wformat_args(__args...));
}
#endif
+template <class _CharT>
+_LIBCPP_HIDE_FROM_ABI size_t __vformatted_size(locale __loc, basic_string_view<_CharT> __fmt, auto __args) {
+ __format::__formatted_size_buffer<_CharT> __buffer;
+ _VSTD::__format::__vformat_to(
+ basic_format_parse_context{__fmt, __args.__size()},
+ _VSTD::__format_context_create(__buffer.make_output_iterator(), __args, _VSTD::move(__loc)));
+ return _VSTD::move(__buffer).result();
+}
+
template <class... _Args>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t
-formatted_size(locale __loc, string_view __fmt, const _Args&... __args) {
- // TODO FMT Improve PoC: using std::string is inefficient.
- return _VSTD::vformat(_VSTD::move(__loc), __fmt,
- _VSTD::make_format_args(__args...))
- .size();
+_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t
+formatted_size(locale __loc, __format_string_t<_Args...> __fmt, const _Args&... __args) {
+ return _VSTD::__vformatted_size(_VSTD::move(__loc), __fmt.__str_, basic_format_args{_VSTD::make_format_args(__args...)});
}
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
template <class... _Args>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t
-formatted_size(locale __loc, wstring_view __fmt, const _Args&... __args) {
- // TODO FMT Improve PoC: using std::string is inefficient.
- return _VSTD::vformat(_VSTD::move(__loc), __fmt,
- _VSTD::make_wformat_args(__args...))
- .size();
+_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t
+formatted_size(locale __loc, __wformat_string_t<_Args...> __fmt, const _Args&... __args) {
+ return _VSTD::__vformatted_size(_VSTD::move(__loc), __fmt.__str_, basic_format_args{_VSTD::make_wformat_args(__args...)});
}
#endif
#endif // _LIBCPP_HAS_NO_LOCALIZATION
-#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
#endif //_LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
-_LIBCPP_POP_MACROS
-
#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)
#endif // _LIBCPP_FORMAT
diff --git a/libcxx/include/forward_list b/libcxx/include/forward_list
index 34168e88746e..6a7272027351 100644
--- a/libcxx/include/forward_list
+++ b/libcxx/include/forward_list
@@ -179,18 +179,42 @@ template <class T, class Allocator, class Predicate>
*/
+#include <__algorithm/comp.h>
+#include <__algorithm/lexicographical_compare.h>
+#include <__algorithm/min.h>
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
+#include <__iterator/distance.h>
+#include <__iterator/iterator_traits.h>
+#include <__iterator/move_iterator.h>
+#include <__iterator/next.h>
#include <__utility/forward.h>
-#include <algorithm>
-#include <initializer_list>
-#include <iterator>
#include <limits>
#include <memory>
#include <type_traits>
#include <version>
+#ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES
+# include <algorithm>
+# include <functional>
+# include <iterator>
+#endif
+
+// standard-mandated includes
+
+// [iterator.range]
+#include <__iterator/access.h>
+#include <__iterator/data.h>
+#include <__iterator/empty.h>
+#include <__iterator/reverse_access.h>
+#include <__iterator/size.h>
+
+// [forward.list.syn]
+#include <compare>
+#include <initializer_list>
+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
@@ -689,7 +713,7 @@ public:
__is_cpp17_input_iterator<_InputIterator>::value
>::type* = nullptr);
forward_list(const forward_list& __x);
- forward_list(const forward_list& __x, const __identity_t<allocator_type>& __a);
+ forward_list(const forward_list& __x, const __type_identity_t<allocator_type>& __a);
forward_list& operator=(const forward_list& __x);
@@ -698,7 +722,7 @@ public:
forward_list(forward_list&& __x)
_NOEXCEPT_(is_nothrow_move_constructible<base>::value)
: base(_VSTD::move(__x)) {}
- forward_list(forward_list&& __x, const __identity_t<allocator_type>& __a);
+ forward_list(forward_list&& __x, const __type_identity_t<allocator_type>& __a);
forward_list(initializer_list<value_type> __il);
forward_list(initializer_list<value_type> __il, const allocator_type& __a);
@@ -981,7 +1005,7 @@ forward_list<_Tp, _Alloc>::forward_list(const forward_list& __x)
template <class _Tp, class _Alloc>
forward_list<_Tp, _Alloc>::forward_list(const forward_list& __x,
- const __identity_t<allocator_type>& __a)
+ const __type_identity_t<allocator_type>& __a)
: base(__a)
{
insert_after(cbefore_begin(), __x.begin(), __x.end());
@@ -1002,7 +1026,7 @@ forward_list<_Tp, _Alloc>::operator=(const forward_list& __x)
#ifndef _LIBCPP_CXX03_LANG
template <class _Tp, class _Alloc>
forward_list<_Tp, _Alloc>::forward_list(forward_list&& __x,
- const __identity_t<allocator_type>& __a)
+ const __type_identity_t<allocator_type>& __a)
: base(_VSTD::move(__x), __a)
{
if (base::__alloc() != __x.__alloc())
diff --git a/libcxx/include/fstream b/libcxx/include/fstream
index fc0a9204ed60..ffa75b14eb15 100644
--- a/libcxx/include/fstream
+++ b/libcxx/include/fstream
@@ -179,12 +179,17 @@ typedef basic_fstream<wchar_t> wfstream;
*/
+#include <__algorithm/max.h>
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__availability>
#include <__config>
-#include <__debug>
#include <__locale>
+#include <__utility/move.h>
+#include <__utility/swap.h>
+#include <__utility/unreachable.h>
#include <cstdio>
#include <cstdlib>
+#include <cstring>
#include <istream>
#include <ostream>
#include <version>
@@ -194,7 +199,7 @@ typedef basic_fstream<wchar_t> wfstream;
#endif
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
@@ -414,25 +419,38 @@ basic_filebuf<_CharT, _Traits>::swap(basic_filebuf& __rhs)
basic_streambuf<char_type, traits_type>::swap(__rhs);
if (__extbuf_ != __extbuf_min_ && __rhs.__extbuf_ != __rhs.__extbuf_min_)
{
- _VSTD::swap(__extbuf_, __rhs.__extbuf_);
- _VSTD::swap(__extbufnext_, __rhs.__extbufnext_);
- _VSTD::swap(__extbufend_, __rhs.__extbufend_);
+ // Neither *this nor __rhs uses the small buffer, so we can simply swap the pointers.
+ std::swap(__extbuf_, __rhs.__extbuf_);
+ std::swap(__extbufnext_, __rhs.__extbufnext_);
+ std::swap(__extbufend_, __rhs.__extbufend_);
}
else
{
- ptrdiff_t __ln = __extbufnext_ - __extbuf_;
- ptrdiff_t __le = __extbufend_ - __extbuf_;
- ptrdiff_t __rn = __rhs.__extbufnext_ - __rhs.__extbuf_;
- ptrdiff_t __re = __rhs.__extbufend_ - __rhs.__extbuf_;
+ ptrdiff_t __ln = __extbufnext_ ? __extbufnext_ - __extbuf_ : 0;
+ ptrdiff_t __le = __extbufend_ ? __extbufend_ - __extbuf_ : 0;
+ ptrdiff_t __rn = __rhs.__extbufnext_ ? __rhs.__extbufnext_ - __rhs.__extbuf_ : 0;
+ ptrdiff_t __re = __rhs.__extbufend_ ? __rhs.__extbufend_ - __rhs.__extbuf_ : 0;
if (__extbuf_ == __extbuf_min_ && __rhs.__extbuf_ != __rhs.__extbuf_min_)
{
+ // *this uses the small buffer, but __rhs doesn't.
__extbuf_ = __rhs.__extbuf_;
__rhs.__extbuf_ = __rhs.__extbuf_min_;
+ std::memmove(__rhs.__extbuf_min_, __extbuf_min_, sizeof(__extbuf_min_));
}
else if (__extbuf_ != __extbuf_min_ && __rhs.__extbuf_ == __rhs.__extbuf_min_)
{
+ // *this doesn't use the small buffer, but __rhs does.
__rhs.__extbuf_ = __extbuf_;
__extbuf_ = __extbuf_min_;
+ std::memmove(__extbuf_min_, __rhs.__extbuf_min_, sizeof(__extbuf_min_));
+ }
+ else
+ {
+ // Both *this and __rhs use the small buffer.
+ char __tmp[sizeof(__extbuf_min_)];
+ std::memmove(__tmp, __extbuf_min_, sizeof(__extbuf_min_));
+ std::memmove(__extbuf_min_, __rhs.__extbuf_min_, sizeof(__extbuf_min_));
+ std::memmove(__rhs.__extbuf_min_, __tmp, sizeof(__extbuf_min_));
}
__extbufnext_ = __extbuf_ + __rn;
__extbufend_ = __extbuf_ + __re;
@@ -538,7 +556,7 @@ const char* basic_filebuf<_CharT, _Traits>::__make_mdstring(
default:
return nullptr;
}
- _LIBCPP_UNREACHABLE();
+ __libcpp_unreachable();
}
template <class _CharT, class _Traits>
@@ -1716,9 +1734,9 @@ basic_fstream<_CharT, _Traits>::close()
}
#if defined(_LIBCPP_ABI_ENABLE_ADDITIONAL_IOSTREAM_EXPLICIT_INSTANTIATIONS_1)
-_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ifstream<char>)
-_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ofstream<char>)
-_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_filebuf<char>)
+extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ifstream<char>;
+extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ofstream<char>;
+extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_filebuf<char>;
#endif
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/functional b/libcxx/include/functional
index 3a24b975881c..de02059f642a 100644
--- a/libcxx/include/functional
+++ b/libcxx/include/functional
@@ -482,6 +482,16 @@ template <> struct hash<long double>;
template<class T> struct hash<T*>;
template <> struct hash<nullptr_t>; // C++17
+namespace ranges {
+ // [range.cmp], concept-constrained comparisons
+ struct equal_to;
+ struct not_equal_to;
+ struct greater;
+ struct less;
+ struct greater_equal;
+ struct less_equal;
+}
+
} // std
POLICY: For non-variadic implementations, the number of arguments is limited
@@ -491,6 +501,7 @@ POLICY: For non-variadic implementations, the number of arguments is limited
*/
#include <__algorithm/search.h>
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__compare/compare_three_way.h>
#include <__config>
#include <__debug>
@@ -501,6 +512,7 @@ POLICY: For non-variadic implementations, the number of arguments is limited
#include <__functional/bind_front.h>
#include <__functional/binder1st.h>
#include <__functional/binder2nd.h>
+#include <__functional/boyer_moore_searcher.h>
#include <__functional/compose.h>
#include <__functional/default_searcher.h>
#include <__functional/function.h>
@@ -525,11 +537,14 @@ POLICY: For non-variadic implementations, the number of arguments is limited
#include <tuple>
#include <type_traits>
#include <typeinfo>
-#include <utility>
#include <version>
+#ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES
+# include <utility>
+#endif
+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
#endif // _LIBCPP_FUNCTIONAL
diff --git a/libcxx/include/future b/libcxx/include/future
index e35eedf35641..f4a5b43eef08 100644
--- a/libcxx/include/future
+++ b/libcxx/include/future
@@ -361,14 +361,16 @@ template <class R, class Alloc> struct uses_allocator<packaged_task<R>, Alloc>;
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__availability>
+#include <__chrono/duration.h>
+#include <__chrono/time_point.h>
#include <__config>
-#include <__debug>
#include <__memory/allocator_arg_t.h>
#include <__memory/uses_allocator.h>
#include <__utility/auto_cast.h>
#include <__utility/forward.h>
-#include <chrono>
+#include <__utility/move.h>
#include <exception>
#include <memory>
#include <mutex>
@@ -376,13 +378,17 @@ template <class R, class Alloc> struct uses_allocator<packaged_task<R>, Alloc>;
#include <thread>
#include <version>
+#ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES
+# include <chrono>
+#endif
+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
#ifdef _LIBCPP_HAS_NO_THREADS
-#error <future> is not supported on this single threaded system
-#else // !_LIBCPP_HAS_NO_THREADS
+# error "<future> is not supported since libc++ has been configured without support for threads."
+#endif
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -399,7 +405,7 @@ _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_errc)
template <>
struct _LIBCPP_TEMPLATE_VIS is_error_code_enum<future_errc> : public true_type {};
-#ifdef _LIBCPP_HAS_NO_STRONG_ENUMS
+#ifdef _LIBCPP_CXX03_LANG
template <>
struct _LIBCPP_TEMPLATE_VIS is_error_code_enum<future_errc::__lx> : public true_type { };
#endif
@@ -413,7 +419,7 @@ _LIBCPP_DECLARE_STRONG_ENUM(launch)
};
_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(launch)
-#ifndef _LIBCPP_HAS_NO_STRONG_ENUMS
+#ifndef _LIBCPP_CXX03_LANG
typedef underlying_type<launch>::type __launch_underlying_type;
@@ -473,7 +479,7 @@ operator^=(launch& __x, launch __y)
__x = __x ^ __y; return __x;
}
-#endif // !_LIBCPP_HAS_NO_STRONG_ENUMS
+#endif // !_LIBCPP_CXX03_LANG
//enum class future_status
_LIBCPP_DECLARE_STRONG_ENUM(future_status)
@@ -1885,25 +1891,11 @@ public:
_LIBCPP_INLINE_VISIBILITY
packaged_task() _NOEXCEPT : __p_(nullptr) {}
template <class _Fp,
- class = typename enable_if
- <
- !is_same<
- typename __uncvref<_Fp>::type,
- packaged_task
- >::value
- >::type
- >
+ class = __enable_if_t<!is_same<__uncvref_t<_Fp>, packaged_task>::value> >
_LIBCPP_INLINE_VISIBILITY
explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
template <class _Fp, class _Allocator,
- class = typename enable_if
- <
- !is_same<
- typename __uncvref<_Fp>::type,
- packaged_task
- >::value
- >::type
- >
+ class = __enable_if_t<!is_same<__uncvref_t<_Fp>, packaged_task>::value> >
_LIBCPP_INLINE_VISIBILITY
packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
: __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
@@ -2014,25 +2006,11 @@ public:
_LIBCPP_INLINE_VISIBILITY
packaged_task() _NOEXCEPT : __p_(nullptr) {}
template <class _Fp,
- class = typename enable_if
- <
- !is_same<
- typename __uncvref<_Fp>::type,
- packaged_task
- >::value
- >::type
- >
+ class = __enable_if_t<!is_same<__uncvref_t<_Fp>, packaged_task>::value> >
_LIBCPP_INLINE_VISIBILITY
explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
template <class _Fp, class _Allocator,
- class = typename enable_if
- <
- !is_same<
- typename __uncvref<_Fp>::type,
- packaged_task
- >::value
- >::type
- >
+ class = __enable_if_t<!is_same<__uncvref_t<_Fp>, packaged_task>::value> >
_LIBCPP_INLINE_VISIBILITY
packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
: __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
@@ -2458,6 +2436,4 @@ future<void>::share() _NOEXCEPT
_LIBCPP_END_NAMESPACE_STD
-#endif // !_LIBCPP_HAS_NO_THREADS
-
#endif // _LIBCPP_FUTURE
diff --git a/libcxx/include/initializer_list b/libcxx/include/initializer_list
index fefaf8cf8b6f..02a8ec57fab3 100644
--- a/libcxx/include/initializer_list
+++ b/libcxx/include/initializer_list
@@ -42,11 +42,12 @@ template<class E> const E* end(initializer_list<E> il) noexcept; // constexpr in
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
#include <cstddef>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
namespace std // purposefully not versioned
diff --git a/libcxx/include/inttypes.h b/libcxx/include/inttypes.h
index 69508140763c..e0fd71f9b65d 100644
--- a/libcxx/include/inttypes.h
+++ b/libcxx/include/inttypes.h
@@ -238,7 +238,7 @@ uintmax_t wcstoumax(const wchar_t* restrict nptr, wchar_t** restrict endptr, int
#include <__config>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
/* C99 stdlib (e.g. glibc < 2.18) does not provide format macros needed
diff --git a/libcxx/include/iomanip b/libcxx/include/iomanip
index ba434b983b1c..ed8334519ae8 100644
--- a/libcxx/include/iomanip
+++ b/libcxx/include/iomanip
@@ -42,13 +42,13 @@ template <class charT, class traits, class Allocator>
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
-#include <__string>
#include <istream>
#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -513,16 +513,17 @@ put_time(const tm* __tm, const _CharT* __fmt)
return __iom_t10<_CharT>(__tm, __fmt);
}
-template <class _CharT, class _Traits, class _ForwardIterator>
-basic_ostream<_CharT, _Traits> &
-__quoted_output ( basic_ostream<_CharT, _Traits> &__os,
- _ForwardIterator __first, _ForwardIterator __last, _CharT __delim, _CharT __escape )
+#if _LIBCPP_STD_VER >= 11
+
+template <class _CharT, class _Traits>
+_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
+__quoted_output(basic_ostream<_CharT, _Traits>& __os,
+ const _CharT *__first, const _CharT *__last, _CharT __delim, _CharT __escape)
{
basic_string<_CharT, _Traits> __str;
__str.push_back(__delim);
- for ( ; __first != __last; ++ __first )
- {
- if (_Traits::eq (*__first, __escape) || _Traits::eq (*__first, __delim))
+ for (; __first != __last; ++__first) {
+ if (_Traits::eq(*__first, __escape) || _Traits::eq(*__first, __delim))
__str.push_back(__escape);
__str.push_back(*__first);
}
@@ -531,139 +532,131 @@ __quoted_output ( basic_ostream<_CharT, _Traits> &__os,
}
template <class _CharT, class _Traits, class _String>
-basic_istream<_CharT, _Traits> &
-__quoted_input ( basic_istream<_CharT, _Traits> &__is, _String & __string, _CharT __delim, _CharT __escape )
+_LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
+__quoted_input(basic_istream<_CharT, _Traits>& __is, _String& __string, _CharT __delim, _CharT __escape)
{
- __string.clear ();
+ __string.clear();
_CharT __c;
__is >> __c;
- if ( __is.fail ())
+ if (__is.fail())
return __is;
- if (!_Traits::eq (__c, __delim)) // no delimiter, read the whole string
- {
- __is.unget ();
+ if (!_Traits::eq(__c, __delim)) {
+ // no delimiter, read the whole string
+ __is.unget();
__is >> __string;
return __is;
}
- __save_flags<_CharT, _Traits> sf(__is);
- noskipws (__is);
- while (true)
- {
+ __save_flags<_CharT, _Traits> __sf(__is);
+ std::noskipws(__is);
+ while (true) {
__is >> __c;
- if ( __is.fail ())
+ if (__is.fail())
break;
- if (_Traits::eq (__c, __escape))
- {
+ if (_Traits::eq(__c, __escape)) {
__is >> __c;
- if ( __is.fail ())
+ if (__is.fail())
break;
- }
- else if (_Traits::eq (__c, __delim))
+ } else if (_Traits::eq(__c, __delim))
break;
- __string.push_back ( __c );
- }
+ __string.push_back(__c);
+ }
return __is;
}
-
-template <class _CharT, class _Traits, class _Iter>
-basic_ostream<_CharT, _Traits>& operator<<(
- basic_ostream<_CharT, _Traits>& __os,
- const __quoted_output_proxy<_CharT, _Iter, _Traits> & __proxy)
+template <class _CharT, class _Traits>
+struct _LIBCPP_HIDDEN __quoted_output_proxy
{
- return __quoted_output (__os, __proxy.__first, __proxy.__last, __proxy.__delim, __proxy.__escape);
-}
+ const _CharT *__first_;
+ const _CharT *__last_;
+ _CharT __delim_;
+ _CharT __escape_;
-template <class _CharT, class _Traits, class _Allocator>
-struct __quoted_proxy
-{
- basic_string<_CharT, _Traits, _Allocator> &__string;
- _CharT __delim;
- _CharT __escape;
+ _LIBCPP_HIDE_FROM_ABI
+ explicit __quoted_output_proxy(const _CharT *__f, const _CharT *__l, _CharT __d, _CharT __e)
+ : __first_(__f), __last_(__l), __delim_(__d), __escape_(__e) {}
- __quoted_proxy(basic_string<_CharT, _Traits, _Allocator> &__s, _CharT __d, _CharT __e)
- : __string(__s), __delim(__d), __escape(__e) {}
+ template<class _T2, __enable_if_t<_IsSame<_Traits, void>::value || _IsSame<_Traits, _T2>::value>* = nullptr>
+ friend _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _T2>&
+ operator<<(basic_ostream<_CharT, _T2>& __os, const __quoted_output_proxy& __p) {
+ return std::__quoted_output(__os, __p.__first_, __p.__last_, __p.__delim_, __p.__escape_);
+ }
};
template <class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY
-basic_ostream<_CharT, _Traits>& operator<<(
- basic_ostream<_CharT, _Traits>& __os,
- const __quoted_proxy<_CharT, _Traits, _Allocator> & __proxy)
+struct _LIBCPP_HIDDEN __quoted_proxy
{
- return __quoted_output (__os, __proxy.__string.cbegin (), __proxy.__string.cend (), __proxy.__delim, __proxy.__escape);
-}
-
-// extractor for non-const basic_string& proxies
-template <class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY
-basic_istream<_CharT, _Traits>& operator>>(
- basic_istream<_CharT, _Traits>& __is,
- const __quoted_proxy<_CharT, _Traits, _Allocator> & __proxy)
-{
- return __quoted_input ( __is, __proxy.__string, __proxy.__delim, __proxy.__escape );
-}
+ basic_string<_CharT, _Traits, _Allocator>& __string_;
+ _CharT __delim_;
+ _CharT __escape_;
+ _LIBCPP_HIDE_FROM_ABI
+ explicit __quoted_proxy(basic_string<_CharT, _Traits, _Allocator>& __s, _CharT __d, _CharT __e)
+ : __string_(__s), __delim_(__d), __escape_(__e) {}
-template <class _CharT>
-_LIBCPP_INLINE_VISIBILITY
-__quoted_output_proxy<_CharT, const _CharT *>
-quoted ( const _CharT *__s, _CharT __delim = _CharT('"'), _CharT __escape =_CharT('\\'))
-{
- const _CharT *__end = __s;
- while ( *__end ) ++__end;
- return __quoted_output_proxy<_CharT, const _CharT *> ( __s, __end, __delim, __escape );
-}
+ friend _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
+ operator<<(basic_ostream<_CharT, _Traits>& __os, const __quoted_proxy& __p) {
+ return std::__quoted_output(__os, __p.__string_.data(), __p.__string_.data() + __p.__string_.size(), __p.__delim_, __p.__escape_);
+ }
+ friend _LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
+ operator>>(basic_istream<_CharT, _Traits>& __is, const __quoted_proxy& __p) {
+ return std::__quoted_input(__is, __p.__string_, __p.__delim_, __p.__escape_);
+ }
+};
template <class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY
-__quoted_output_proxy<_CharT, typename basic_string <_CharT, _Traits, _Allocator>::const_iterator>
-__quoted ( const basic_string <_CharT, _Traits, _Allocator> &__s, _CharT __delim = _CharT('"'), _CharT __escape=_CharT('\\'))
+_LIBCPP_HIDE_FROM_ABI
+__quoted_output_proxy<_CharT, _Traits>
+__quoted(const basic_string<_CharT, _Traits, _Allocator>& __s, _CharT __delim = _CharT('"'), _CharT __escape = _CharT('\\'))
{
- return __quoted_output_proxy<_CharT,
- typename basic_string <_CharT, _Traits, _Allocator>::const_iterator>
- ( __s.cbegin(), __s.cend (), __delim, __escape );
+ return __quoted_output_proxy<_CharT, _Traits>(__s.data(), __s.data() + __s.size(), __delim, __escape);
}
template <class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY
+_LIBCPP_HIDE_FROM_ABI
__quoted_proxy<_CharT, _Traits, _Allocator>
-__quoted ( basic_string <_CharT, _Traits, _Allocator> &__s, _CharT __delim = _CharT('"'), _CharT __escape=_CharT('\\'))
+__quoted(basic_string<_CharT, _Traits, _Allocator>& __s, _CharT __delim = _CharT('"'), _CharT __escape = _CharT('\\'))
{
- return __quoted_proxy<_CharT, _Traits, _Allocator>( __s, __delim, __escape );
+ return __quoted_proxy<_CharT, _Traits, _Allocator>(__s, __delim, __escape);
}
+#endif // _LIBCPP_STD_VER >= 11
#if _LIBCPP_STD_VER > 11
+template <class _CharT>
+_LIBCPP_HIDE_FROM_ABI
+auto quoted(const _CharT *__s, _CharT __delim = _CharT('"'), _CharT __escape = _CharT('\\'))
+{
+ const _CharT *__end = __s;
+ while (*__end) ++__end;
+ return __quoted_output_proxy<_CharT, void>(__s, __end, __delim, __escape);
+}
+
template <class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY
-__quoted_output_proxy<_CharT, typename basic_string <_CharT, _Traits, _Allocator>::const_iterator>
-quoted ( const basic_string <_CharT, _Traits, _Allocator> &__s, _CharT __delim = _CharT('"'), _CharT __escape=_CharT('\\'))
+_LIBCPP_HIDE_FROM_ABI
+auto quoted(const basic_string<_CharT, _Traits, _Allocator>& __s, _CharT __delim = _CharT('"'), _CharT __escape = _CharT('\\'))
{
- return __quoted(__s, __delim, __escape);
+ return __quoted_output_proxy<_CharT, _Traits>(__s.data(), __s.data() + __s.size(), __delim, __escape);
}
template <class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY
-__quoted_proxy<_CharT, _Traits, _Allocator>
-quoted ( basic_string <_CharT, _Traits, _Allocator> &__s, _CharT __delim = _CharT('"'), _CharT __escape=_CharT('\\'))
+_LIBCPP_HIDE_FROM_ABI
+auto quoted(basic_string<_CharT, _Traits, _Allocator>& __s, _CharT __delim = _CharT('"'), _CharT __escape = _CharT('\\'))
{
- return __quoted(__s, __delim, __escape);
+ return __quoted_proxy<_CharT, _Traits, _Allocator>(__s, __delim, __escape);
}
template <class _CharT, class _Traits>
-__quoted_output_proxy<_CharT, const _CharT *, _Traits>
-quoted (basic_string_view <_CharT, _Traits> __sv,
- _CharT __delim = _CharT('"'), _CharT __escape=_CharT('\\'))
+_LIBCPP_HIDE_FROM_ABI
+auto quoted(basic_string_view<_CharT, _Traits> __sv, _CharT __delim = _CharT('"'), _CharT __escape = _CharT('\\'))
{
- return __quoted_output_proxy<_CharT, const _CharT *, _Traits>
- ( __sv.data(), __sv.data() + __sv.size(), __delim, __escape );
+ return __quoted_output_proxy<_CharT, _Traits>(__sv.data(), __sv.data() + __sv.size(), __delim, __escape);
}
-#endif
+
+#endif // _LIBCPP_STD_VER > 11
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/ios b/libcxx/include/ios
index 74c3c63bd347..7140e00b406a 100644
--- a/libcxx/include/ios
+++ b/libcxx/include/ios
@@ -211,17 +211,27 @@ storage-class-specifier const error_category& iostream_category() noexcept;
*/
#include <__config>
+
+#if defined(_LIBCPP_HAS_NO_LOCALIZATION)
+# error "The iostreams library is not supported since libc++ has been configured without support for localization."
+#endif
+
+#include <__assert> // all public C++ headers provide the assertion handler
+#include <__ios/fpos.h>
#include <__locale>
-#include <iosfwd>
+#include <__utility/swap.h>
#include <system_error>
#include <version>
+// standard-mandated includes
+#include <iosfwd>
+
#if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER)
#include <atomic> // for __xindex_
#endif
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -402,7 +412,7 @@ _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(io_errc)
template <>
struct _LIBCPP_TEMPLATE_VIS is_error_code_enum<io_errc> : public true_type { };
-#ifdef _LIBCPP_HAS_NO_STRONG_ENUMS
+#ifdef _LIBCPP_CXX03_LANG
template <>
struct _LIBCPP_TEMPLATE_VIS is_error_code_enum<io_errc::__lx> : public true_type { };
#endif
@@ -780,6 +790,8 @@ inline _LIBCPP_INLINE_VISIBILITY
_CharT
basic_ios<_CharT, _Traits>::fill(char_type __ch)
{
+ if (traits_type::eq_int_type(traits_type::eof(), __fill_))
+ __fill_ = widen(' ');
char_type __r = __fill_;
__fill_ = __ch;
return __r;
diff --git a/libcxx/include/iosfwd b/libcxx/include/iosfwd
index c2ba8ee9e652..9cd9450e62e9 100644
--- a/libcxx/include/iosfwd
+++ b/libcxx/include/iosfwd
@@ -94,12 +94,13 @@ using u32streampos = fpos<char_traits<char32_t>::state_type>;
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
#include <__mbstate_t.h>
#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -231,10 +232,8 @@ typedef fpos<mbstate_t> wstreampos;
#ifndef _LIBCPP_HAS_NO_CHAR8_T
typedef fpos<mbstate_t> u8streampos;
#endif
-#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
typedef fpos<mbstate_t> u16streampos;
typedef fpos<mbstate_t> u32streampos;
-#endif
#if defined(_NEWLIB_VERSION)
// On newlib, off_t is 'long int'
diff --git a/libcxx/include/iostream b/libcxx/include/iostream
index 793f08ab1330..13d4ac3cadae 100644
--- a/libcxx/include/iostream
+++ b/libcxx/include/iostream
@@ -33,15 +33,18 @@ extern wostream wclog;
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
+#include <version>
+
+// standard-mandated includes
#include <ios>
#include <istream>
#include <ostream>
#include <streambuf>
-#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/istream b/libcxx/include/istream
index de49d49e4564..7af5dfa474cd 100644
--- a/libcxx/include/istream
+++ b/libcxx/include/istream
@@ -158,13 +158,15 @@ template <class Stream, class T>
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
+#include <__iterator/istreambuf_iterator.h>
#include <__utility/forward.h>
#include <ostream>
#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
@@ -1592,7 +1594,7 @@ operator>>(basic_istream<_CharT, _Traits>& __is, bitset<_Size>& __x)
size_t __c = 0;
_CharT __zero = __ct.widen('0');
_CharT __one = __ct.widen('1');
- while (__c < _Size)
+ while (__c != _Size)
{
typename _Traits::int_type __i = __is.rdbuf()->sgetc();
if (_Traits::eq_int_type(__i, _Traits::eof()))
@@ -1627,11 +1629,11 @@ operator>>(basic_istream<_CharT, _Traits>& __is, bitset<_Size>& __x)
return __is;
}
-_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_istream<char>)
+extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_istream<char>;
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_istream<wchar_t>)
+extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_istream<wchar_t>;
#endif
-_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_iostream<char>)
+extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_iostream<char>;
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/iterator b/libcxx/include/iterator
index 29097a9aa8bf..225ae815363c 100644
--- a/libcxx/include/iterator
+++ b/libcxx/include/iterator
@@ -136,6 +136,13 @@ template<class In, class Out>
template<class In, class Out>
concept indirectly_movable_storable = see below; // since C++20
+// [alg.req.ind.copy], concept indirectly_copyable
+template<class In, class Out>
+ concept indirectly_copyable = see below; // since C++20
+
+template<class In, class Out>
+ concept indirectly_copyable_storable = see below; // since C++20
+
// [alg.req.ind.swap], concept indirectly_swappable
template<class I1, class I2 = I1>
concept indirectly_swappable = see below; // since C++20
@@ -145,6 +152,19 @@ template<class I1, class I2, class R, class P1 = identity,
concept indirectly_comparable =
indirect_binary_predicate<R, projected<I1, P1>, projected<I2, P2>>; // since C++20
+// [alg.req.permutable], concept permutable
+template<class I>
+ concept permutable = see below; // since C++20
+
+ // [alg.req.mergeable], concept mergeable
+template<class I1, class I2, class Out,
+ class R = ranges::less, class P1 = identity, class P2 = identity>
+ concept mergeable = see below; // since C++20
+
+// [alg.req.sortable], concept sortable
+template<class I, class R = ranges::less, class P = identity>
+ concept sortable = see below; // since C++20
+
template<input_or_output_iterator I, sentinel_for<I> S>
requires (!same_as<I, S> && copyable<I>)
class common_iterator; // since C++20
@@ -165,6 +185,7 @@ struct output_iterator_tag {};
struct forward_iterator_tag : public input_iterator_tag {};
struct bidirectional_iterator_tag : public forward_iterator_tag {};
struct random_access_iterator_tag : public bidirectional_iterator_tag {};
+struct contiguous_iterator_tag : public random_access_iterator_tag {};
// 27.4.3, iterator operations
template <class InputIterator, class Distance> // constexpr in C++17
@@ -204,10 +225,17 @@ class reverse_iterator
protected:
Iterator current;
public:
- typedef Iterator iterator_type;
- typedef typename iterator_traits<Iterator>::difference_type difference_type;
- typedef typename iterator_traits<Iterator>::reference reference;
- typedef typename iterator_traits<Iterator>::pointer pointer;
+ using iterator_type = Iterator;
+ using iterator_concept = see below; // since C++20
+ using iterator_category = typename iterator_traits<Iterator>::iterator_category; // since C++17, until C++20
+ using iterator_category = see below; // since C++20
+ using value_type = typename iterator_traits<Iterator>::value_type; // since C++17, until C++20
+ using value_type = iter_value_t<Iterator>; // since C++20
+ using difference_type = typename iterator_traits<Iterator>::difference_type; // until C++20
+ using difference_type = iter_difference_t<Iterator>; // since C++20
+ using pointer = typename iterator_traits<Iterator>::pointer;
+ using reference = typename iterator_traits<Iterator>::reference; // until C++20
+ using reference = iter_reference_t<Iterator>; // since C++20
constexpr reverse_iterator();
constexpr explicit reverse_iterator(Iterator x);
@@ -215,7 +243,8 @@ public:
template <class U> constexpr reverse_iterator& operator=(const reverse_iterator<U>& u);
constexpr Iterator base() const;
constexpr reference operator*() const;
- constexpr pointer operator->() const;
+ constexpr pointer operator->() const; // until C++20
+ constexpr pointer operator->() const requires see below; // since C++20
constexpr reverse_iterator& operator++();
constexpr reverse_iterator operator++(int);
constexpr reverse_iterator& operator--();
@@ -224,7 +253,14 @@ public:
constexpr reverse_iterator& operator+=(difference_type n);
constexpr reverse_iterator operator- (difference_type n) const;
constexpr reverse_iterator& operator-=(difference_type n);
- constexpr reference operator[](difference_type n) const;
+ constexpr unspecified operator[](difference_type n) const;
+
+ friend constexpr iter_rvalue_reference_t<Iterator>
+ iter_move(const reverse_iterator& i) noexcept(see below);
+ template<indirectly_swappable<Iterator> Iterator2>
+ friend constexpr void
+ iter_swap(const reverse_iterator& x,
+ const reverse_iterator<Iterator2>& y) noexcept(see below);
};
template <class Iterator1, class Iterator2>
@@ -233,11 +269,11 @@ operator==(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator
template <class Iterator1, class Iterator2>
constexpr bool // constexpr in C++17
-operator<(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
+operator!=(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
template <class Iterator1, class Iterator2>
constexpr bool // constexpr in C++17
-operator!=(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
+operator<(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
template <class Iterator1, class Iterator2>
constexpr bool // constexpr in C++17
@@ -245,11 +281,16 @@ operator>(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2
template <class Iterator1, class Iterator2>
constexpr bool // constexpr in C++17
-operator>=(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
+operator<=(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
template <class Iterator1, class Iterator2>
constexpr bool // constexpr in C++17
-operator<=(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
+operator>=(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
+
+template<class Iterator1, three_way_comparable_with<Iterator1> Iterator2>
+ constexpr compare_three_way_result_t<Iterator1, Iterator2>
+ operator<=>(const reverse_iterator<Iterator1>& x,
+ const reverse_iterator<Iterator2>& y);
template <class Iterator1, class Iterator2>
constexpr auto
@@ -264,6 +305,11 @@ operator+(typename reverse_iterator<Iterator>::difference_type n,
template <class Iterator>
constexpr reverse_iterator<Iterator> make_reverse_iterator(Iterator i); // C++14, constexpr in C++17
+template<class Iterator1, class Iterator2>
+ requires (!sized_sentinel_for<Iterator1, Iterator2>)
+ inline constexpr bool disable_sized_sentinel_for<reverse_iterator<Iterator1>,
+ reverse_iterator<Iterator2>> = true;
+
template <class Container>
class back_insert_iterator
: public iterator<output_iterator_tag, void, void, void, void> // until C++17
@@ -332,18 +378,21 @@ public:
insert_iterator& operator++(int); // constexpr in C++20
};
-template <class Container, class Iterator>
-insert_iterator<Container> inserter(Container& x, Iterator i); // constexpr in C++20
+template <class Container>
+insert_iterator<Container> inserter(Container& x, typename Container::iterator i); // until C++20
+template <class Container>
+constexpr insert_iterator<Container> inserter(Container& x, ranges::iterator_t<Container> i); // since C++20
template <class Iterator>
class move_iterator {
public:
- typedef Iterator iterator_type;
- typedef typename iterator_traits<Iterator>::difference_type difference_type;
- typedef Iterator pointer;
- typedef typename iterator_traits<Iterator>::value_type value_type;
- typedef typename iterator_traits<Iterator>::iterator_category iterator_category;
- typedef value_type&& reference;
+ using iterator_type = Iterator;
+ using iterator_concept = input_iterator_tag; // From C++20
+ using iterator_category = see below; // not always present starting from C++20
+ using value_type = iter_value_t<Iterator>; // Until C++20, iterator_traits<Iterator>::value_type
+ using difference_type = iter_difference_t<Iterator>; // Until C++20, iterator_traits<Iterator>::difference_type;
+ using pointer = Iterator;
+ using reference = iter_rvalue_reference_t<Iterator>; // Until C++20, value_type&&
constexpr move_iterator(); // all the constexprs are in C++17
constexpr explicit move_iterator(Iterator i);
@@ -351,18 +400,40 @@ public:
constexpr move_iterator(const move_iterator<U>& u);
template <class U>
constexpr move_iterator& operator=(const move_iterator<U>& u);
- constexpr iterator_type base() const;
+
+ constexpr iterator_type base() const; // Until C++20
+ constexpr const Iterator& base() const & noexcept; // From C++20
+ constexpr Iterator base() &&; // From C++20
+
constexpr reference operator*() const;
- constexpr pointer operator->() const;
+ constexpr pointer operator->() const; // Deprecated in C++20
constexpr move_iterator& operator++();
- constexpr move_iterator operator++(int);
+ constexpr auto operator++(int); // Return type was move_iterator until C++20
constexpr move_iterator& operator--();
constexpr move_iterator operator--(int);
constexpr move_iterator operator+(difference_type n) const;
constexpr move_iterator& operator+=(difference_type n);
constexpr move_iterator operator-(difference_type n) const;
constexpr move_iterator& operator-=(difference_type n);
- constexpr unspecified operator[](difference_type n) const;
+ constexpr reference operator[](difference_type n) const; // Return type unspecified until C++20
+
+ template<sentinel_for<Iterator> S>
+ friend constexpr bool
+ operator==(const move_iterator& x, const move_sentinel<S>& y); // Since C++20
+ template<sized_sentinel_for<Iterator> S>
+ friend constexpr iter_difference_t<Iterator>
+ operator-(const move_sentinel<S>& x, const move_iterator& y); // Since C++20
+ template<sized_sentinel_for<Iterator> S>
+ friend constexpr iter_difference_t<Iterator>
+ operator-(const move_iterator& x, const move_sentinel<S>& y); // Since C++20
+ friend constexpr iter_rvalue_reference_t<Iterator>
+ iter_move(const move_iterator& i)
+ noexcept(noexcept(ranges::iter_move(i.current))); // Since C++20
+ template<indirectly_swappable<Iterator> Iterator2>
+ friend constexpr void
+ iter_swap(const move_iterator& x, const move_iterator<Iterator2>& y)
+ noexcept(noexcept(ranges::iter_swap(x.current, y.current))); // Since C++20
+
private:
Iterator current; // exposition only
};
@@ -404,6 +475,23 @@ constexpr move_iterator<Iterator> operator+( // constexpr in C++17
template <class Iterator> // constexpr in C++17
constexpr move_iterator<Iterator> make_move_iterator(const Iterator& i);
+template<semiregular S>
+class move_sentinel {
+public:
+ constexpr move_sentinel();
+ constexpr explicit move_sentinel(S s);
+ template<class S2>
+ requires convertible_to<const S2&, S>
+ constexpr move_sentinel(const move_sentinel<S2>& s);
+ template<class S2>
+ requires assignable_from<S&, const S2&>
+ constexpr move_sentinel& operator=(const move_sentinel<S2>& s);
+
+ constexpr S base() const;
+private:
+ S last; // exposition only
+};
+
// [default.sentinel], default sentinel
struct default_sentinel_t;
inline constexpr default_sentinel_t default_sentinel{};
@@ -434,7 +522,8 @@ public:
typedef traits traits_type;
typedef basic_istream<charT, traits> istream_type;
- constexpr istream_iterator();
+ istream_iterator(); // constexpr since C++11
+ constexpr istream_iterator(default_sentinel_t); // since C++20
istream_iterator(istream_type& s);
istream_iterator(const istream_iterator& x);
~istream_iterator();
@@ -443,6 +532,7 @@ public:
const T* operator->() const;
istream_iterator& operator++();
istream_iterator operator++(int);
+ friend bool operator==(const istream_iterator& i, default_sentinel_t); // since C++20
};
template <class T, class charT, class traits, class Distance>
@@ -450,7 +540,7 @@ bool operator==(const istream_iterator<T,charT,traits,Distance>& x,
const istream_iterator<T,charT,traits,Distance>& y);
template <class T, class charT, class traits, class Distance>
bool operator!=(const istream_iterator<T,charT,traits,Distance>& x,
- const istream_iterator<T,charT,traits,Distance>& y);
+ const istream_iterator<T,charT,traits,Distance>& y); // until C++20
template <class T, class charT = char, class traits = char_traits<charT> >
class ostream_iterator
@@ -496,7 +586,8 @@ public:
typedef basic_streambuf<charT, traits> streambuf_type;
typedef basic_istream<charT, traits> istream_type;
- istreambuf_iterator() noexcept;
+ istreambuf_iterator() noexcept; // constexpr since C++11
+ constexpr istreambuf_iterator(default_sentinel_t) noexcept; // since C++20
istreambuf_iterator(istream_type& s) noexcept;
istreambuf_iterator(streambuf_type* s) noexcept;
istreambuf_iterator(a-private-type) noexcept;
@@ -507,6 +598,7 @@ public:
a-private-type operator++(int);
bool equal(const istreambuf_iterator& b) const;
+ friend bool operator==(const istreambuf_iterator& i, default_sentinel_t s); // since C++20
};
template <class charT, class traits>
@@ -514,7 +606,7 @@ bool operator==(const istreambuf_iterator<charT,traits>& a,
const istreambuf_iterator<charT,traits>& b);
template <class charT, class traits>
bool operator!=(const istreambuf_iterator<charT,traits>& a,
- const istreambuf_iterator<charT,traits>& b);
+ const istreambuf_iterator<charT,traits>& b); // until C++20
template <class charT, class traits = char_traits<charT> >
class ostreambuf_iterator
@@ -582,12 +674,13 @@ template <class E> constexpr const E* data(initializer_list<E> il) noexcept;
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
#include <__debug>
-#include <__functional_base>
#include <__iterator/access.h>
#include <__iterator/advance.h>
#include <__iterator/back_insert_iterator.h>
+#include <__iterator/bounded_iter.h>
#include <__iterator/common_iterator.h>
#include <__iterator/concepts.h>
#include <__iterator/counted_iterator.h>
@@ -606,21 +699,24 @@ template <class E> constexpr const E* data(initializer_list<E> il) noexcept;
#include <__iterator/iter_swap.h>
#include <__iterator/iterator.h>
#include <__iterator/iterator_traits.h>
+#include <__iterator/mergeable.h>
#include <__iterator/move_iterator.h>
+#include <__iterator/move_sentinel.h>
#include <__iterator/next.h>
#include <__iterator/ostream_iterator.h>
#include <__iterator/ostreambuf_iterator.h>
+#include <__iterator/permutable.h>
#include <__iterator/prev.h>
#include <__iterator/projected.h>
#include <__iterator/readable_traits.h>
#include <__iterator/reverse_access.h>
#include <__iterator/reverse_iterator.h>
#include <__iterator/size.h>
+#include <__iterator/sortable.h>
#include <__iterator/unreachable_sentinel.h>
#include <__iterator/wrap_iter.h>
#include <__memory/addressof.h>
#include <__memory/pointer_traits.h>
-#include <__utility/forward.h>
#include <compare>
#include <concepts> // Mandated by the Standard.
#include <cstddef>
@@ -628,8 +724,15 @@ template <class E> constexpr const E* data(initializer_list<E> il) noexcept;
#include <type_traits>
#include <version>
+#ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES
+# include <exception>
+# include <new>
+# include <typeinfo>
+# include <utility>
+#endif
+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
#endif // _LIBCPP_ITERATOR
diff --git a/libcxx/include/latch b/libcxx/include/latch
index 2cc9222baadc..85936750b4c1 100644
--- a/libcxx/include/latch
+++ b/libcxx/include/latch
@@ -40,17 +40,19 @@ namespace std
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__availability>
#include <__config>
#include <atomic>
+#include <limits>
#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
#ifdef _LIBCPP_HAS_NO_THREADS
-# error <latch> is not supported on this single threaded system
+# error "<latch> is not supported since libc++ has been configured without support for threads."
#endif
_LIBCPP_PUSH_MACROS
@@ -91,10 +93,9 @@ public:
inline _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
void wait() const
{
- auto const __test_fn = [=]() -> bool {
+ __cxx_atomic_wait(&__a.__a_, [&]() -> bool {
return try_wait();
- };
- __cxx_atomic_wait(&__a.__a_, __test_fn);
+ });
}
inline _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
void arrive_and_wait(ptrdiff_t __update = 1)
diff --git a/libcxx/include/limits b/libcxx/include/limits
index 245c84eea883..35e4d85734de 100644
--- a/libcxx/include/limits
+++ b/libcxx/include/limits
@@ -101,6 +101,8 @@ template<> class numeric_limits<cv long double>;
} // std
*/
+
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
#include <type_traits>
@@ -113,7 +115,7 @@ template<> class numeric_limits<cv long double>;
#endif // __IBMCPP__
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
@@ -339,7 +341,11 @@ protected:
static _LIBCPP_CONSTEXPR const bool is_modulo = false;
static _LIBCPP_CONSTEXPR const bool traps = false;
+#if (defined(__arm__) || defined(__aarch64__))
+ static _LIBCPP_CONSTEXPR const bool tinyness_before = true;
+#else
static _LIBCPP_CONSTEXPR const bool tinyness_before = false;
+#endif
static _LIBCPP_CONSTEXPR const float_round_style round_style = round_to_nearest;
};
@@ -385,7 +391,11 @@ protected:
static _LIBCPP_CONSTEXPR const bool is_modulo = false;
static _LIBCPP_CONSTEXPR const bool traps = false;
+#if (defined(__arm__) || defined(__aarch64__))
+ static _LIBCPP_CONSTEXPR const bool tinyness_before = true;
+#else
static _LIBCPP_CONSTEXPR const bool tinyness_before = false;
+#endif
static _LIBCPP_CONSTEXPR const float_round_style round_style = round_to_nearest;
};
@@ -435,7 +445,11 @@ protected:
static _LIBCPP_CONSTEXPR const bool is_modulo = false;
static _LIBCPP_CONSTEXPR const bool traps = false;
+#if (defined(__arm__) || defined(__aarch64__))
+ static _LIBCPP_CONSTEXPR const bool tinyness_before = true;
+#else
static _LIBCPP_CONSTEXPR const bool tinyness_before = false;
+#endif
static _LIBCPP_CONSTEXPR const float_round_style round_style = round_to_nearest;
};
diff --git a/libcxx/include/limits.h b/libcxx/include/limits.h
index 026bcfe0fc42..3e1e85a8a0b4 100644
--- a/libcxx/include/limits.h
+++ b/libcxx/include/limits.h
@@ -40,7 +40,7 @@ Macros:
#include <__config>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
#ifndef __GNUC__
diff --git a/libcxx/include/list b/libcxx/include/list
index 258fe2cee727..d75b15c060be 100644
--- a/libcxx/include/list
+++ b/libcxx/include/list
@@ -180,19 +180,49 @@ template <class T, class Allocator, class Predicate>
*/
+#include <__algorithm/comp.h>
+#include <__algorithm/equal.h>
+#include <__algorithm/lexicographical_compare.h>
+#include <__algorithm/min.h>
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
#include <__debug>
+#include <__format/enable_insertable.h>
+#include <__iterator/distance.h>
+#include <__iterator/iterator_traits.h>
+#include <__iterator/move_iterator.h>
+#include <__iterator/next.h>
+#include <__iterator/prev.h>
+#include <__iterator/reverse_iterator.h>
#include <__utility/forward.h>
-#include <algorithm>
-#include <initializer_list>
-#include <iterator>
+#include <__utility/move.h>
+#include <__utility/swap.h>
#include <limits>
#include <memory>
#include <type_traits>
#include <version>
+#ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES
+# include <algorithm>
+# include <functional>
+# include <iterator>
+#endif
+
+// standard-mandated includes
+
+// [iterator.range]
+#include <__iterator/access.h>
+#include <__iterator/data.h>
+#include <__iterator/empty.h>
+#include <__iterator/reverse_access.h>
+#include <__iterator/size.h>
+
+// [list.syn]
+#include <compare>
+#include <initializer_list>
+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
@@ -292,19 +322,15 @@ class _LIBCPP_TEMPLATE_VIS __list_iterator
__link_pointer __ptr_;
-#if _LIBCPP_DEBUG_LEVEL == 2
_LIBCPP_INLINE_VISIBILITY
explicit __list_iterator(__link_pointer __p, const void* __c) _NOEXCEPT
: __ptr_(__p)
{
+ (void)__c;
+#ifdef _LIBCPP_ENABLE_DEBUG_MODE
__get_db()->__insert_ic(this, __c);
- }
-#else
- _LIBCPP_INLINE_VISIBILITY
- explicit __list_iterator(__link_pointer __p) _NOEXCEPT : __ptr_(__p) {}
#endif
-
-
+ }
template<class, class> friend class list;
template<class, class> friend class __list_imp;
@@ -322,7 +348,7 @@ public:
_VSTD::__debug_db_insert_i(this);
}
-#if _LIBCPP_DEBUG_LEVEL == 2
+#ifdef _LIBCPP_ENABLE_DEBUG_MODE
_LIBCPP_INLINE_VISIBILITY
__list_iterator(const __list_iterator& __p)
@@ -348,7 +374,7 @@ public:
return *this;
}
-#endif // _LIBCPP_DEBUG_LEVEL == 2
+#endif // _LIBCPP_ENABLE_DEBUG_MODE
_LIBCPP_INLINE_VISIBILITY
reference operator*() const
@@ -405,17 +431,15 @@ class _LIBCPP_TEMPLATE_VIS __list_const_iterator
__link_pointer __ptr_;
-#if _LIBCPP_DEBUG_LEVEL == 2
_LIBCPP_INLINE_VISIBILITY
explicit __list_const_iterator(__link_pointer __p, const void* __c) _NOEXCEPT
: __ptr_(__p)
{
+ (void)__c;
+#ifdef _LIBCPP_ENABLE_DEBUG_MODE
__get_db()->__insert_ic(this, __c);
- }
-#else
- _LIBCPP_INLINE_VISIBILITY
- explicit __list_const_iterator(__link_pointer __p) _NOEXCEPT : __ptr_(__p) {}
#endif
+ }
template<class, class> friend class list;
template<class, class> friend class __list_imp;
@@ -435,12 +459,12 @@ public:
__list_const_iterator(const __list_iterator<_Tp, _VoidPtr>& __p) _NOEXCEPT
: __ptr_(__p.__ptr_)
{
-#if _LIBCPP_DEBUG_LEVEL == 2
+#ifdef _LIBCPP_ENABLE_DEBUG_MODE
__get_db()->__iterator_copy(this, _VSTD::addressof(__p));
#endif
}
-#if _LIBCPP_DEBUG_LEVEL == 2
+#ifdef _LIBCPP_ENABLE_DEBUG_MODE
_LIBCPP_INLINE_VISIBILITY
__list_const_iterator(const __list_const_iterator& __p)
@@ -466,7 +490,7 @@ public:
return *this;
}
-#endif // _LIBCPP_DEBUG_LEVEL == 2
+#endif // _LIBCPP_ENABLE_DEBUG_MODE
_LIBCPP_INLINE_VISIBILITY
reference operator*() const
{
@@ -593,38 +617,22 @@ protected:
_LIBCPP_INLINE_VISIBILITY
iterator begin() _NOEXCEPT
{
-#if _LIBCPP_DEBUG_LEVEL == 2
return iterator(__end_.__next_, this);
-#else
- return iterator(__end_.__next_);
-#endif
}
_LIBCPP_INLINE_VISIBILITY
const_iterator begin() const _NOEXCEPT
{
-#if _LIBCPP_DEBUG_LEVEL == 2
return const_iterator(__end_.__next_, this);
-#else
- return const_iterator(__end_.__next_);
-#endif
}
_LIBCPP_INLINE_VISIBILITY
iterator end() _NOEXCEPT
{
-#if _LIBCPP_DEBUG_LEVEL == 2
return iterator(__end_as_link(), this);
-#else
- return iterator(__end_as_link());
-#endif
}
_LIBCPP_INLINE_VISIBILITY
const_iterator end() const _NOEXCEPT
{
-#if _LIBCPP_DEBUG_LEVEL == 2
return const_iterator(__end_as_link(), this);
-#else
- return const_iterator(__end_as_link());
-#endif
}
void swap(__list_imp& __c)
@@ -672,13 +680,6 @@ private:
void __move_assign_alloc(__list_imp&, false_type)
_NOEXCEPT
{}
-
- _LIBCPP_INLINE_VISIBILITY
- void __invalidate_all_iterators() {
-#if _LIBCPP_DEBUG_LEVEL == 2
- __get_db()->__invalidate_all(this);
-#endif
- }
};
// Unlink nodes [__f, __l]
@@ -720,9 +721,7 @@ inline __list_imp<_Tp, _Alloc>::__list_imp(__node_allocator&& __a) _NOEXCEPT
template <class _Tp, class _Alloc>
__list_imp<_Tp, _Alloc>::~__list_imp() {
clear();
-#if _LIBCPP_DEBUG_LEVEL == 2
- __get_db()->__erase_c(this);
-#endif
+ std::__debug_db_erase_c(this);
}
template <class _Tp, class _Alloc>
@@ -743,7 +742,7 @@ __list_imp<_Tp, _Alloc>::clear() _NOEXCEPT
__node_alloc_traits::destroy(__na, _VSTD::addressof(__np->__value_));
__node_alloc_traits::deallocate(__na, __np, 1);
}
- __invalidate_all_iterators();
+ std::__debug_db_invalidate_all(this);
}
}
@@ -774,7 +773,7 @@ __list_imp<_Tp, _Alloc>::swap(__list_imp& __c)
else
__c.__end_.__prev_->__next_ = __c.__end_.__next_->__prev_ = __c.__end_as_link();
-#if _LIBCPP_DEBUG_LEVEL == 2
+#ifdef _LIBCPP_ENABLE_DEBUG_MODE
__libcpp_db* __db = __get_db();
__c_node* __cn1 = __db->__find_c_and_lock(this);
__c_node* __cn2 = __db->__find_c(_VSTD::addressof(__c));
@@ -877,7 +876,7 @@ public:
typename enable_if<__is_cpp17_input_iterator<_InpIter>::value>::type* = 0);
list(const list& __c);
- list(const list& __c, const __identity_t<allocator_type>& __a);
+ list(const list& __c, const __type_identity_t<allocator_type>& __a);
_LIBCPP_INLINE_VISIBILITY
list& operator=(const list& __c);
#ifndef _LIBCPP_CXX03_LANG
@@ -888,7 +887,7 @@ public:
list(list&& __c)
_NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value);
_LIBCPP_INLINE_VISIBILITY
- list(list&& __c, const __identity_t<allocator_type>& __a);
+ list(list&& __c, const __type_identity_t<allocator_type>& __a);
_LIBCPP_INLINE_VISIBILITY
list& operator=(list&& __c)
_NOEXCEPT_(
@@ -1099,14 +1098,14 @@ public:
return __hold_pointer(__p, __node_destructor(__na, 1));
}
-#if _LIBCPP_DEBUG_LEVEL == 2
+#ifdef _LIBCPP_ENABLE_DEBUG_MODE
bool __dereferenceable(const const_iterator* __i) const;
bool __decrementable(const const_iterator* __i) const;
bool __addable(const const_iterator* __i, ptrdiff_t __n) const;
bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const;
-#endif // _LIBCPP_DEBUG_LEVEL == 2
+#endif // _LIBCPP_ENABLE_DEBUG_MODE
private:
_LIBCPP_INLINE_VISIBILITY
@@ -1249,7 +1248,7 @@ list<_Tp, _Alloc>::list(const list& __c)
}
template <class _Tp, class _Alloc>
-list<_Tp, _Alloc>::list(const list& __c, const __identity_t<allocator_type>& __a)
+list<_Tp, _Alloc>::list(const list& __c, const __type_identity_t<allocator_type>& __a)
: base(__a)
{
_VSTD::__debug_db_insert_c(this);
@@ -1288,7 +1287,7 @@ inline list<_Tp, _Alloc>::list(list&& __c)
template <class _Tp, class _Alloc>
inline
-list<_Tp, _Alloc>::list(list&& __c, const __identity_t<allocator_type>& __a)
+list<_Tp, _Alloc>::list(list&& __c, const __type_identity_t<allocator_type>& __a)
: base(__a)
{
_VSTD::__debug_db_insert_c(this);
@@ -1366,9 +1365,7 @@ list<_Tp, _Alloc>::assign(_InpIter __f, _InpIter __l,
insert(__e, __f, __l);
else
erase(__i, __e);
-#if _LIBCPP_DEBUG_LEVEL == 2
- __get_db()->__invalidate_all(this);
-#endif
+ std::__debug_db_invalidate_all(this);
}
template <class _Tp, class _Alloc>
@@ -1383,9 +1380,7 @@ list<_Tp, _Alloc>::assign(size_type __n, const value_type& __x)
insert(__e, __n, __x);
else
erase(__i, __e);
-#if _LIBCPP_DEBUG_LEVEL == 2
- __get_db()->__invalidate_all(this);
-#endif
+ std::__debug_db_invalidate_all(this);
}
template <class _Tp, class _Alloc>
@@ -1407,11 +1402,7 @@ list<_Tp, _Alloc>::insert(const_iterator __p, const value_type& __x)
__node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x);
__link_nodes(__p.__ptr_, __hold->__as_link(), __hold->__as_link());
++base::__sz();
-#if _LIBCPP_DEBUG_LEVEL == 2
return iterator(__hold.release()->__as_link(), this);
-#else
- return iterator(__hold.release()->__as_link());
-#endif
}
template <class _Tp, class _Alloc>
@@ -1420,11 +1411,7 @@ list<_Tp, _Alloc>::insert(const_iterator __p, size_type __n, const value_type& _
{
_LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this,
"list::insert(iterator, n, x) called with an iterator not referring to this list");
-#if _LIBCPP_DEBUG_LEVEL == 2
iterator __r(__p.__ptr_, this);
-#else
- iterator __r(__p.__ptr_);
-#endif
if (__n > 0)
{
size_type __ds = 0;
@@ -1432,11 +1419,7 @@ list<_Tp, _Alloc>::insert(const_iterator __p, size_type __n, const value_type& _
__hold_pointer __hold = __allocate_node(__na);
__node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x);
++__ds;
-#if _LIBCPP_DEBUG_LEVEL == 2
__r = iterator(__hold->__as_link(), this);
-#else
- __r = iterator(__hold->__as_link());
-#endif
__hold.release();
iterator __e = __r;
#ifndef _LIBCPP_NO_EXCEPTIONS
@@ -1462,11 +1445,7 @@ list<_Tp, _Alloc>::insert(const_iterator __p, size_type __n, const value_type& _
__node_alloc_traits::deallocate(__na, __e.__ptr_->__as_node(), 1);
if (__prev == 0)
break;
-#if _LIBCPP_DEBUG_LEVEL == 2
__e = iterator(__prev, this);
-#else
- __e = iterator(__prev);
-#endif
}
throw;
}
@@ -1485,11 +1464,7 @@ list<_Tp, _Alloc>::insert(const_iterator __p, _InpIter __f, _InpIter __l,
{
_LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this,
"list::insert(iterator, range) called with an iterator not referring to this list");
-#if _LIBCPP_DEBUG_LEVEL == 2
iterator __r(__p.__ptr_, this);
-#else
- iterator __r(__p.__ptr_);
-#endif
if (__f != __l)
{
size_type __ds = 0;
@@ -1497,11 +1472,7 @@ list<_Tp, _Alloc>::insert(const_iterator __p, _InpIter __f, _InpIter __l,
__hold_pointer __hold = __allocate_node(__na);
__node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), *__f);
++__ds;
-#if _LIBCPP_DEBUG_LEVEL == 2
__r = iterator(__hold.get()->__as_link(), this);
-#else
- __r = iterator(__hold.get()->__as_link());
-#endif
__hold.release();
iterator __e = __r;
#ifndef _LIBCPP_NO_EXCEPTIONS
@@ -1527,11 +1498,7 @@ list<_Tp, _Alloc>::insert(const_iterator __p, _InpIter __f, _InpIter __l,
__node_alloc_traits::deallocate(__na, __e.__ptr_->__as_node(), 1);
if (__prev == 0)
break;
-#if _LIBCPP_DEBUG_LEVEL == 2
__e = iterator(__prev, this);
-#else
- __e = iterator(__prev);
-#endif
}
throw;
}
@@ -1650,11 +1617,7 @@ list<_Tp, _Alloc>::emplace(const_iterator __p, _Args&&... __args)
__link_nodes(__p.__ptr_, __nl, __nl);
++base::__sz();
__hold.release();
-#if _LIBCPP_DEBUG_LEVEL == 2
return iterator(__nl, this);
-#else
- return iterator(__nl);
-#endif
}
template <class _Tp, class _Alloc>
@@ -1670,11 +1633,7 @@ list<_Tp, _Alloc>::insert(const_iterator __p, value_type&& __x)
__link_nodes(__p.__ptr_, __nl, __nl);
++base::__sz();
__hold.release();
-#if _LIBCPP_DEBUG_LEVEL == 2
return iterator(__nl, this);
-#else
- return iterator(__nl);
-#endif
}
#endif // _LIBCPP_CXX03_LANG
@@ -1688,7 +1647,7 @@ list<_Tp, _Alloc>::pop_front()
__link_pointer __n = base::__end_.__next_;
base::__unlink_nodes(__n, __n);
--base::__sz();
-#if _LIBCPP_DEBUG_LEVEL == 2
+#ifdef _LIBCPP_ENABLE_DEBUG_MODE
__c_node* __c = __get_db()->__find_c_and_lock(this);
for (__i_node** __p = __c->end_; __p != __c->beg_; )
{
@@ -1717,7 +1676,7 @@ list<_Tp, _Alloc>::pop_back()
__link_pointer __n = base::__end_.__prev_;
base::__unlink_nodes(__n, __n);
--base::__sz();
-#if _LIBCPP_DEBUG_LEVEL == 2
+#ifdef _LIBCPP_ENABLE_DEBUG_MODE
__c_node* __c = __get_db()->__find_c_and_lock(this);
for (__i_node** __p = __c->end_; __p != __c->beg_; )
{
@@ -1750,7 +1709,7 @@ list<_Tp, _Alloc>::erase(const_iterator __p)
__link_pointer __r = __n->__next_;
base::__unlink_nodes(__n, __n);
--base::__sz();
-#if _LIBCPP_DEBUG_LEVEL == 2
+#ifdef _LIBCPP_ENABLE_DEBUG_MODE
__c_node* __c = __get_db()->__find_c_and_lock(this);
for (__i_node** __ip = __c->end_; __ip != __c->beg_; )
{
@@ -1768,11 +1727,7 @@ list<_Tp, _Alloc>::erase(const_iterator __p)
__node_pointer __np = __n->__as_node();
__node_alloc_traits::destroy(__na, _VSTD::addressof(__np->__value_));
__node_alloc_traits::deallocate(__na, __np, 1);
-#if _LIBCPP_DEBUG_LEVEL == 2
return iterator(__r, this);
-#else
- return iterator(__r);
-#endif
}
template <class _Tp, class _Alloc>
@@ -1792,7 +1747,7 @@ list<_Tp, _Alloc>::erase(const_iterator __f, const_iterator __l)
__link_pointer __n = __f.__ptr_;
++__f;
--base::__sz();
-#if _LIBCPP_DEBUG_LEVEL == 2
+#ifdef _LIBCPP_ENABLE_DEBUG_MODE
__c_node* __c = __get_db()->__find_c_and_lock(this);
for (__i_node** __p = __c->end_; __p != __c->beg_; )
{
@@ -1812,11 +1767,7 @@ list<_Tp, _Alloc>::erase(const_iterator __f, const_iterator __l)
__node_alloc_traits::deallocate(__na, __np, 1);
}
}
-#if _LIBCPP_DEBUG_LEVEL == 2
return iterator(__l.__ptr_, this);
-#else
- return iterator(__l.__ptr_);
-#endif
}
template <class _Tp, class _Alloc>
@@ -1833,11 +1784,7 @@ list<_Tp, _Alloc>::resize(size_type __n)
__hold_pointer __hold = __allocate_node(__na);
__node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_));
++__ds;
-#if _LIBCPP_DEBUG_LEVEL == 2
iterator __r = iterator(__hold.release()->__as_link(), this);
-#else
- iterator __r = iterator(__hold.release()->__as_link());
-#endif
iterator __e = __r;
#ifndef _LIBCPP_NO_EXCEPTIONS
try
@@ -1862,11 +1809,7 @@ list<_Tp, _Alloc>::resize(size_type __n)
__node_alloc_traits::deallocate(__na, __e.__ptr_->__as_node(), 1);
if (__prev == 0)
break;
-#if _LIBCPP_DEBUG_LEVEL == 2
__e = iterator(__prev, this);
-#else
- __e = iterator(__prev);
-#endif
}
throw;
}
@@ -1891,11 +1834,7 @@ list<_Tp, _Alloc>::resize(size_type __n, const value_type& __x)
__node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x);
++__ds;
__link_pointer __nl = __hold.release()->__as_link();
-#if _LIBCPP_DEBUG_LEVEL == 2
iterator __r = iterator(__nl, this);
-#else
- iterator __r = iterator(__nl);
-#endif
iterator __e = __r;
#ifndef _LIBCPP_NO_EXCEPTIONS
try
@@ -1920,11 +1859,7 @@ list<_Tp, _Alloc>::resize(size_type __n, const value_type& __x)
__node_alloc_traits::deallocate(__na, __e.__ptr_->__as_node(), 1);
if (__prev == 0)
break;
-#if _LIBCPP_DEBUG_LEVEL == 2
__e = iterator(__prev, this);
-#else
- __e = iterator(__prev);
-#endif
}
throw;
}
@@ -1950,7 +1885,7 @@ list<_Tp, _Alloc>::splice(const_iterator __p, list& __c)
__link_nodes(__p.__ptr_, __f, __l);
base::__sz() += __c.__sz();
__c.__sz() = 0;
-#if _LIBCPP_DEBUG_LEVEL == 2
+#ifdef _LIBCPP_ENABLE_DEBUG_MODE
if (_VSTD::addressof(__c) != this) {
__libcpp_db* __db = __get_db();
__c_node* __cn1 = __db->__find_c_and_lock(this);
@@ -1991,7 +1926,7 @@ list<_Tp, _Alloc>::splice(const_iterator __p, list& __c, const_iterator __i)
__link_nodes(__p.__ptr_, __f, __f);
--__c.__sz();
++base::__sz();
-#if _LIBCPP_DEBUG_LEVEL == 2
+#ifdef _LIBCPP_ENABLE_DEBUG_MODE
if (_VSTD::addressof(__c) != this) {
__libcpp_db* __db = __get_db();
__c_node* __cn1 = __db->__find_c_and_lock(this);
@@ -2014,6 +1949,17 @@ list<_Tp, _Alloc>::splice(const_iterator __p, list& __c, const_iterator __i)
}
}
+template <class _Iterator>
+_LIBCPP_HIDE_FROM_ABI
+bool __iterator_in_range(_Iterator __first, _Iterator __last, _Iterator __it) {
+ for (_Iterator __p = __first; __p != __last; ++__p) {
+ if (__p == __it) {
+ return true;
+ }
+ }
+ return false;
+}
+
template <class _Tp, class _Alloc>
void
list<_Tp, _Alloc>::splice(const_iterator __p, list& __c, const_iterator __f, const_iterator __l)
@@ -2024,16 +1970,10 @@ list<_Tp, _Alloc>::splice(const_iterator __p, list& __c, const_iterator __f, con
"list::splice(iterator, list, iterator, iterator) called with second iterator not referring to the list argument");
_LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__l)) == _VSTD::addressof(__c),
"list::splice(iterator, list, iterator, iterator) called with third iterator not referring to the list argument");
+ _LIBCPP_DEBUG_ASSERT(this != std::addressof(__c) || !std::__iterator_in_range(__f, __l, __p),
+ "list::splice(iterator, list, iterator, iterator)"
+ " called with the first iterator within the range of the second and third iterators");
-#if _LIBCPP_DEBUG_LEVEL == 2
- if (this == _VSTD::addressof(__c))
- {
- for (const_iterator __i = __f; __i != __l; ++__i)
- _LIBCPP_DEBUG_ASSERT(__i != __p,
- "list::splice(iterator, list, iterator, iterator)"
- " called with the first iterator within the range of the second and third iterators");
- }
-#endif
if (__f != __l)
{
__link_pointer __first = __f.__ptr_;
@@ -2047,7 +1987,7 @@ list<_Tp, _Alloc>::splice(const_iterator __p, list& __c, const_iterator __f, con
}
base::__unlink_nodes(__first, __last);
__link_nodes(__p.__ptr_, __first, __last);
-#if _LIBCPP_DEBUG_LEVEL == 2
+#ifdef _LIBCPP_ENABLE_DEBUG_MODE
if (_VSTD::addressof(__c) != this) {
__libcpp_db* __db = __get_db();
__c_node* __cn1 = __db->__find_c_and_lock(this);
@@ -2184,7 +2124,7 @@ list<_Tp, _Alloc>::merge(list& __c, _Comp __comp)
++__f1;
}
splice(__e1, __c);
-#if _LIBCPP_DEBUG_LEVEL == 2
+#ifdef _LIBCPP_ENABLE_DEBUG_MODE
__libcpp_db* __db = __get_db();
__c_node* __cn1 = __db->__find_c_and_lock(this);
__c_node* __cn2 = __db->__find_c(_VSTD::addressof(__c));
@@ -2308,7 +2248,7 @@ list<_Tp, _Alloc>::__invariants() const
return size() == _VSTD::distance(begin(), end());
}
-#if _LIBCPP_DEBUG_LEVEL == 2
+#ifdef _LIBCPP_ENABLE_DEBUG_MODE
template <class _Tp, class _Alloc>
bool
@@ -2338,7 +2278,7 @@ list<_Tp, _Alloc>::__subscriptable(const const_iterator*, ptrdiff_t) const
return false;
}
-#endif // _LIBCPP_DEBUG_LEVEL == 2
+#endif // _LIBCPP_ENABLE_DEBUG_MODE
template <class _Tp, class _Alloc>
inline _LIBCPP_INLINE_VISIBILITY
@@ -2409,8 +2349,16 @@ inline _LIBCPP_INLINE_VISIBILITY typename list<_Tp, _Allocator>::size_type
erase(list<_Tp, _Allocator>& __c, const _Up& __v) {
return _VSTD::erase_if(__c, [&](auto& __elem) { return __elem == __v; });
}
+
+template <>
+inline constexpr bool __format::__enable_insertable<std::list<char>> = true;
+#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+template <>
+inline constexpr bool __format::__enable_insertable<std::list<wchar_t>> = true;
#endif
+#endif // _LIBCPP_STD_VER > 17
+
_LIBCPP_END_NAMESPACE_STD
_LIBCPP_POP_MACROS
diff --git a/libcxx/include/locale b/libcxx/include/locale
index 7c2d2361f751..b01c66d0430f 100644
--- a/libcxx/include/locale
+++ b/libcxx/include/locale
@@ -187,26 +187,37 @@ template <class charT> class messages_byname;
*/
+#include <__algorithm/copy.h>
+#include <__algorithm/equal.h>
+#include <__algorithm/find.h>
+#include <__algorithm/max.h>
+#include <__algorithm/reverse.h>
+#include <__algorithm/unwrap_iter.h>
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
#include <__debug>
+#include <__iterator/access.h>
+#include <__iterator/back_insert_iterator.h>
+#include <__iterator/istreambuf_iterator.h>
+#include <__iterator/ostreambuf_iterator.h>
#include <__locale>
-#include <algorithm>
-#ifndef __APPLE__
-# include <cstdarg>
-#endif
+#include <cstdarg> // TODO: Remove this include
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <ios>
-#include <iterator>
#include <limits>
#include <memory>
#include <streambuf>
#include <version>
+#ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES
+# include <iterator>
+#endif
+
#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)
+# if !defined(__BIONIC__) && !defined(_NEWLIB_VERSION) && !defined(__EMSCRIPTEN__)
# define _LIBCPP_HAS_CATOPEN 1
# include <nl_types.h>
# endif
@@ -219,7 +230,7 @@ template <class charT> class messages_byname;
#endif
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
@@ -572,9 +583,9 @@ __num_get<_CharT>::__stage2_float_loop(_CharT __ct, bool& __in_units, char& __ex
return 0;
}
-_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(struct _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __num_get<char>)
+extern template struct _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __num_get<char>;
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(struct _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __num_get<wchar_t>)
+extern template struct _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __num_get<wchar_t>;
#endif
template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
@@ -1112,9 +1123,9 @@ num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
return __b;
}
-_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS num_get<char>)
+extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS num_get<char>;
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS num_get<wchar_t>)
+extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS num_get<wchar_t>;
#endif
struct _LIBCPP_TYPE_VIS __num_put_base
@@ -1264,9 +1275,9 @@ __num_put<_CharT>::__widen_and_group_float(char* __nb, char* __np, char* __ne,
__op = __ob + (__np - __nb);
}
-_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(struct _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __num_put<char>)
+extern template struct _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __num_put<char>;
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(struct _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __num_put<wchar_t>)
+extern template struct _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __num_put<wchar_t>;
#endif
template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >
@@ -1456,7 +1467,7 @@ num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
return do_put(__s, __iob, __fl, (unsigned long)__v);
const numpunct<char_type>& __np = use_facet<numpunct<char_type> >(__iob.getloc());
typedef typename numpunct<char_type>::string_type string_type;
-#if _LIBCPP_DEBUG_LEVEL == 2
+#ifdef _LIBCPP_ENABLE_DEBUG_MODE
string_type __tmp(__v ? __np.truename() : __np.falsename());
string_type __nm = _VSTD::move(__tmp);
#else
@@ -1486,10 +1497,11 @@ num_put<_CharT, _OutputIterator>::__do_put_integral(iter_type __s, ios_base& __i
+ ((numeric_limits<_Unsigned>::digits % 3) != 0) // round up
+ 2; // base prefix + terminating null character
char __nar[__nbuf];
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wformat-nonliteral"
+ _LIBCPP_DIAGNOSTIC_PUSH
+ _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wformat-nonliteral")
+ _LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wformat-nonliteral")
int __nc = __libcpp_snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
-#pragma clang diagnostic pop
+ _LIBCPP_DIAGNOSTIC_POP
char* __ne = __nar + __nc;
char* __np = this->__identify_padding(__nar, __ne, __iob);
// Stage 2 - Widen __nar while adding thousands separators
@@ -1549,8 +1561,9 @@ num_put<_CharT, _OutputIterator>::__do_put_floating_point(iter_type __s, ios_bas
char __nar[__nbuf];
char* __nb = __nar;
int __nc;
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wformat-nonliteral"
+ _LIBCPP_DIAGNOSTIC_PUSH
+ _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wformat-nonliteral")
+ _LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wformat-nonliteral")
if (__specify_precision)
__nc = __libcpp_snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt,
(int)__iob.precision(), __v);
@@ -1567,7 +1580,7 @@ num_put<_CharT, _OutputIterator>::__do_put_floating_point(iter_type __s, ios_bas
__throw_bad_alloc();
__nbh.reset(__nb);
}
-#pragma clang diagnostic pop
+ _LIBCPP_DIAGNOSTIC_POP
char* __ne = __nb + __nc;
char* __np = this->__identify_padding(__nb, __ne, __iob);
// Stage 2 - Widen __nar while adding thousands separators
@@ -1633,9 +1646,9 @@ num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);
}
-_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS num_put<char>)
+extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS num_put<char>;
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS num_put<wchar_t>)
+extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS num_put<wchar_t>;
#endif
template <class _CharT, class _InputIterator>
@@ -1918,7 +1931,7 @@ time_get<_CharT, _InputIterator>::__get_month(int& __m,
const ctype<char_type>& __ct) const
{
int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2) - 1;
- if (!(__err & ios_base::failbit) && __t <= 11)
+ if (!(__err & ios_base::failbit) && 0 <= __t && __t <= 11)
__m = __t;
else
__err |= ios_base::failbit;
@@ -2323,9 +2336,9 @@ time_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
return __b;
}
-_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_get<char>)
+extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_get<char>;
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_get<wchar_t>)
+extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_get<wchar_t>;
#endif
class _LIBCPP_TYPE_VIS __time_get
@@ -2425,9 +2438,9 @@ private:
virtual const string_type& __X() const {return this->__X_;}
};
-_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_get_byname<char>)
+extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_get_byname<char>;
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_get_byname<wchar_t>)
+extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_get_byname<wchar_t>;
#endif
class _LIBCPP_TYPE_VIS __time_put
@@ -2540,9 +2553,9 @@ time_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base&,
return _VSTD::copy(__nb, __ne, __s);
}
-_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_put<char>)
+extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_put<char>;
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_put<wchar_t>)
+extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_put<wchar_t>;
#endif
template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >
@@ -2563,9 +2576,9 @@ protected:
~time_put_byname() {}
};
-_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_put_byname<char>)
+extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_put_byname<char>;
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_put_byname<wchar_t>)
+extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_put_byname<wchar_t>;
#endif
// money_base
@@ -2632,11 +2645,11 @@ template <class _CharT, bool _International>
const bool
moneypunct<_CharT, _International>::intl;
-_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct<char, false>)
-_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct<char, true>)
+extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct<char, false>;
+extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct<char, true>;
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct<wchar_t, false>)
-_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct<wchar_t, true>)
+extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct<wchar_t, false>;
+extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct<wchar_t, true>;
#endif
// moneypunct_byname
@@ -2688,14 +2701,14 @@ private:
template<> _LIBCPP_FUNC_VIS void moneypunct_byname<char, false>::init(const char*);
template<> _LIBCPP_FUNC_VIS void moneypunct_byname<char, true>::init(const char*);
-_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct_byname<char, false>)
-_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct_byname<char, true>)
+extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct_byname<char, false>;
+extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct_byname<char, true>;
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
template<> _LIBCPP_FUNC_VIS void moneypunct_byname<wchar_t, false>::init(const char*);
template<> _LIBCPP_FUNC_VIS void moneypunct_byname<wchar_t, true>::init(const char*);
-_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct_byname<wchar_t, false>)
-_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct_byname<wchar_t, true>)
+extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct_byname<wchar_t, false>;
+extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct_byname<wchar_t, true>;
#endif
// money_get
@@ -2752,9 +2765,9 @@ __money_get<_CharT>::__gather_info(bool __intl, const locale& __loc,
}
}
-_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __money_get<char>)
+extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __money_get<char>;
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __money_get<wchar_t>)
+extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __money_get<wchar_t>;
#endif
template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
@@ -3121,9 +3134,9 @@ money_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
return __b;
}
-_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS money_get<char>)
+extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS money_get<char>;
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS money_get<wchar_t>)
+extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS money_get<wchar_t>;
#endif
// money_put
@@ -3214,9 +3227,9 @@ __money_put<_CharT>::__format(char_type* __mb, char_type*& __mi, char_type*& __m
int __fd)
{
__me = __mb;
- for (unsigned __p = 0; __p < 4; ++__p)
+ for (char __p : __pat.field)
{
- switch (__pat.field[__p])
+ switch (__p)
{
case money_base::none:
__mi = __me;
@@ -3298,9 +3311,9 @@ __money_put<_CharT>::__format(char_type* __mb, char_type*& __mi, char_type*& __m
__mi = __mb;
}
-_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __money_put<char>)
+extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __money_put<char>;
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __money_put<wchar_t>)
+extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __money_put<wchar_t>;
#endif
template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >
@@ -3453,9 +3466,9 @@ money_put<_CharT, _OutputIterator>::do_put(iter_type __s, bool __intl,
return __pad_and_output(__s, __mb, __mi, __me, __iob, __fl);
}
-_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS money_put<char>)
+extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS money_put<char>;
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS money_put<wchar_t>)
+extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS money_put<wchar_t>;
#endif
// messages
@@ -3571,9 +3584,9 @@ messages<_CharT>::do_close(catalog __c) const
#endif // _LIBCPP_HAS_CATOPEN
}
-_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS messages<char>)
+extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS messages<char>;
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS messages<wchar_t>)
+extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS messages<wchar_t>;
#endif
template <class _CharT>
@@ -3597,15 +3610,15 @@ protected:
~messages_byname() {}
};
-_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS messages_byname<char>)
+extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS messages_byname<char>;
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS messages_byname<wchar_t>)
+extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS messages_byname<wchar_t>;
#endif
template<class _Codecvt, class _Elem = wchar_t,
class _Wide_alloc = allocator<_Elem>,
class _Byte_alloc = allocator<char> >
-class _LIBCPP_TEMPLATE_VIS wstring_convert
+class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 wstring_convert
{
public:
typedef basic_string<char, char_traits<char>, _Byte_alloc> byte_string;
@@ -3672,6 +3685,7 @@ public:
state_type state() const {return __cvtstate_;}
};
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
inline
wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
@@ -3679,6 +3693,7 @@ wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
: __cvtptr_(__pcvt), __cvtstate_(), __cvtcount_(0)
{
}
+_LIBCPP_SUPPRESS_DEPRECATED_POP
template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
inline
@@ -3713,6 +3728,7 @@ wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
#endif // _LIBCPP_CXX03_LANG
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::~wstring_convert()
{
@@ -3724,6 +3740,7 @@ typename wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::wide_string
wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
from_bytes(const char* __frm, const char* __frm_end)
{
+_LIBCPP_SUPPRESS_DEPRECATED_POP
__cvtcount_ = 0;
if (__cvtptr_ != nullptr)
{
@@ -3870,7 +3887,7 @@ wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
}
template <class _Codecvt, class _Elem = wchar_t, class _Tr = char_traits<_Elem> >
-class _LIBCPP_TEMPLATE_VIS wbuffer_convert
+class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 wbuffer_convert
: public basic_streambuf<_Elem, _Tr>
{
public:
@@ -3947,6 +3964,7 @@ private:
wbuffer_convert* __close();
};
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
template <class _Codecvt, class _Elem, class _Tr>
wbuffer_convert<_Codecvt, _Elem, _Tr>::
wbuffer_convert(streambuf* __bytebuf, _Codecvt* __pcvt, state_type __state)
@@ -3982,6 +4000,7 @@ template <class _Codecvt, class _Elem, class _Tr>
typename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type
wbuffer_convert<_Codecvt, _Elem, _Tr>::underflow()
{
+_LIBCPP_SUPPRESS_DEPRECATED_POP
if (__cv_ == 0 || __bufptr_ == 0)
return traits_type::eof();
bool __initial = __read_mode();
@@ -4046,10 +4065,12 @@ wbuffer_convert<_Codecvt, _Elem, _Tr>::underflow()
return __c;
}
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
template <class _Codecvt, class _Elem, class _Tr>
typename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type
wbuffer_convert<_Codecvt, _Elem, _Tr>::pbackfail(int_type __c)
{
+_LIBCPP_SUPPRESS_DEPRECATED_POP
if (__cv_ != 0 && __bufptr_ != 0 && this->eback() < this->gptr())
{
if (traits_type::eq_int_type(__c, traits_type::eof()))
@@ -4067,10 +4088,12 @@ wbuffer_convert<_Codecvt, _Elem, _Tr>::pbackfail(int_type __c)
return traits_type::eof();
}
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
template <class _Codecvt, class _Elem, class _Tr>
typename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type
wbuffer_convert<_Codecvt, _Elem, _Tr>::overflow(int_type __c)
{
+_LIBCPP_SUPPRESS_DEPRECATED_POP
if (__cv_ == 0 || __bufptr_ == 0)
return traits_type::eof();
__write_mode();
@@ -4129,10 +4152,12 @@ wbuffer_convert<_Codecvt, _Elem, _Tr>::overflow(int_type __c)
return traits_type::not_eof(__c);
}
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
template <class _Codecvt, class _Elem, class _Tr>
basic_streambuf<_Elem, _Tr>*
wbuffer_convert<_Codecvt, _Elem, _Tr>::setbuf(char_type* __s, streamsize __n)
{
+_LIBCPP_SUPPRESS_DEPRECATED_POP
this->setg(0, 0, 0);
this->setp(0, 0);
if (__owns_eb_)
@@ -4182,6 +4207,7 @@ wbuffer_convert<_Codecvt, _Elem, _Tr>::setbuf(char_type* __s, streamsize __n)
return this;
}
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
template <class _Codecvt, class _Elem, class _Tr>
typename wbuffer_convert<_Codecvt, _Elem, _Tr>::pos_type
wbuffer_convert<_Codecvt, _Elem, _Tr>::seekoff(off_type __off, ios_base::seekdir __way,
@@ -4213,6 +4239,7 @@ template <class _Codecvt, class _Elem, class _Tr>
int
wbuffer_convert<_Codecvt, _Elem, _Tr>::sync()
{
+_LIBCPP_SUPPRESS_DEPRECATED_POP
if (__cv_ == 0 || __bufptr_ == 0)
return 0;
if (__cm_ & ios_base::out)
@@ -4281,6 +4308,7 @@ wbuffer_convert<_Codecvt, _Elem, _Tr>::sync()
return 0;
}
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
template <class _Codecvt, class _Elem, class _Tr>
bool
wbuffer_convert<_Codecvt, _Elem, _Tr>::__read_mode()
@@ -4335,6 +4363,8 @@ wbuffer_convert<_Codecvt, _Elem, _Tr>::__close()
return __rt;
}
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+
_LIBCPP_END_NAMESPACE_STD
_LIBCPP_POP_MACROS
diff --git a/libcxx/include/locale.h b/libcxx/include/locale.h
index 215e46d9ccd7..17c0a705a009 100644
--- a/libcxx/include/locale.h
+++ b/libcxx/include/locale.h
@@ -36,11 +36,11 @@ Functions:
#include <__config>
#if defined(_LIBCPP_HAS_NO_LOCALIZATION)
-# error "The Localization library is not supported since libc++ has been configured with LIBCXX_ENABLE_LOCALIZATION disabled"
+# error "<locale.h> is not supported since libc++ has been configured without support for localization."
#endif
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-# pragma GCC system_header
+# pragma GCC system_header
#endif
#include_next <locale.h>
diff --git a/libcxx/include/map b/libcxx/include/map
index 7654a8fc2847..106ed5259ed9 100644
--- a/libcxx/include/map
+++ b/libcxx/include/map
@@ -528,24 +528,45 @@ erase_if(multimap<Key, T, Compare, Allocator>& c, Predicate pred); // C++20
*/
+#include <__algorithm/equal.h>
+#include <__algorithm/lexicographical_compare.h>
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
-#include <__debug>
+#include <__functional/binary_function.h>
#include <__functional/is_transparent.h>
+#include <__functional/operations.h>
+#include <__iterator/erase_if_container.h>
#include <__iterator/iterator_traits.h>
+#include <__iterator/reverse_iterator.h>
#include <__node_handle>
#include <__tree>
#include <__utility/forward.h>
-#include <compare>
-#include <functional>
-#include <initializer_list>
-#include <iterator> // __libcpp_erase_if_container
+#include <__utility/swap.h>
#include <memory>
#include <type_traits>
-#include <utility>
#include <version>
+#ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES
+# include <functional>
+# include <iterator>
+# include <utility>
+#endif
+
+// standard-mandated includes
+
+// [iterator.range]
+#include <__iterator/access.h>
+#include <__iterator/data.h>
+#include <__iterator/empty.h>
+#include <__iterator/reverse_access.h>
+#include <__iterator/size.h>
+
+// [associative.map.syn]
+#include <compare>
+#include <initializer_list>
+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -956,32 +977,23 @@ public:
typedef _Key key_type;
typedef _Tp mapped_type;
typedef pair<const key_type, mapped_type> value_type;
- typedef __identity_t<_Compare> key_compare;
- typedef __identity_t<_Allocator> allocator_type;
+ typedef __type_identity_t<_Compare> key_compare;
+ typedef __type_identity_t<_Allocator> allocator_type;
typedef value_type& reference;
typedef const value_type& const_reference;
static_assert((is_same<typename allocator_type::value_type, value_type>::value),
"Allocator::value_type must be same type as value_type");
-_LIBCPP_SUPPRESS_DEPRECATED_PUSH
class _LIBCPP_TEMPLATE_VIS value_compare
-#if defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
- : public binary_function<value_type, value_type, bool>
-#endif
+ : public __binary_function<value_type, value_type, bool>
{
-_LIBCPP_SUPPRESS_DEPRECATED_POP
friend class map;
protected:
key_compare comp;
_LIBCPP_INLINE_VISIBILITY value_compare(key_compare c) : comp(c) {}
public:
-#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
- _LIBCPP_DEPRECATED_IN_CXX17 typedef bool result_type;
- _LIBCPP_DEPRECATED_IN_CXX17 typedef value_type first_argument_type;
- _LIBCPP_DEPRECATED_IN_CXX17 typedef value_type second_argument_type;
-#endif
_LIBCPP_INLINE_VISIBILITY
bool operator()(const value_type& __x, const value_type& __y) const
{return comp(__x.first, __y.first);}
@@ -1741,21 +1753,17 @@ public:
typedef _Key key_type;
typedef _Tp mapped_type;
typedef pair<const key_type, mapped_type> value_type;
- typedef __identity_t<_Compare> key_compare;
- typedef __identity_t<_Allocator> allocator_type;
+ typedef __type_identity_t<_Compare> key_compare;
+ typedef __type_identity_t<_Allocator> allocator_type;
typedef value_type& reference;
typedef const value_type& const_reference;
static_assert((is_same<typename allocator_type::value_type, value_type>::value),
"Allocator::value_type must be same type as value_type");
-_LIBCPP_SUPPRESS_DEPRECATED_PUSH
class _LIBCPP_TEMPLATE_VIS value_compare
-#if defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
- : public binary_function<value_type, value_type, bool>
-#endif
+ : public __binary_function<value_type, value_type, bool>
{
-_LIBCPP_SUPPRESS_DEPRECATED_POP
friend class multimap;
protected:
key_compare comp;
@@ -1763,11 +1771,6 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP
_LIBCPP_INLINE_VISIBILITY
value_compare(key_compare c) : comp(c) {}
public:
-#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
- _LIBCPP_DEPRECATED_IN_CXX17 typedef bool result_type;
- _LIBCPP_DEPRECATED_IN_CXX17 typedef value_type first_argument_type;
- _LIBCPP_DEPRECATED_IN_CXX17 typedef value_type second_argument_type;
-#endif
_LIBCPP_INLINE_VISIBILITY
bool operator()(const value_type& __x, const value_type& __y) const
{return comp(__x.first, __y.first);}
diff --git a/libcxx/include/math.h b/libcxx/include/math.h
index e59ac6be11bf..7d553e728d0f 100644
--- a/libcxx/include/math.h
+++ b/libcxx/include/math.h
@@ -294,7 +294,7 @@ long double truncl(long double x);
#include <__config>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
#include_next <math.h>
@@ -788,10 +788,10 @@ isunordered(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
// acos
-#if !(defined(_AIX) || defined(__sun__))
+# if !defined(__sun__)
inline _LIBCPP_INLINE_VISIBILITY float acos(float __lcpp_x) _NOEXCEPT {return ::acosf(__lcpp_x);}
inline _LIBCPP_INLINE_VISIBILITY long double acos(long double __lcpp_x) _NOEXCEPT {return ::acosl(__lcpp_x);}
-#endif
+# endif
template <class _A1>
inline _LIBCPP_INLINE_VISIBILITY
@@ -800,10 +800,10 @@ acos(_A1 __lcpp_x) _NOEXCEPT {return ::acos((double)__lcpp_x);}
// asin
-#if !(defined(_AIX) || defined(__sun__))
+# if !defined(__sun__)
inline _LIBCPP_INLINE_VISIBILITY float asin(float __lcpp_x) _NOEXCEPT {return ::asinf(__lcpp_x);}
inline _LIBCPP_INLINE_VISIBILITY long double asin(long double __lcpp_x) _NOEXCEPT {return ::asinl(__lcpp_x);}
-#endif
+# endif
template <class _A1>
inline _LIBCPP_INLINE_VISIBILITY
@@ -812,10 +812,10 @@ asin(_A1 __lcpp_x) _NOEXCEPT {return ::asin((double)__lcpp_x);}
// atan
-#if !(defined(_AIX) || defined(__sun__))
+# if !defined(__sun__)
inline _LIBCPP_INLINE_VISIBILITY float atan(float __lcpp_x) _NOEXCEPT {return ::atanf(__lcpp_x);}
inline _LIBCPP_INLINE_VISIBILITY long double atan(long double __lcpp_x) _NOEXCEPT {return ::atanl(__lcpp_x);}
-#endif
+# endif
template <class _A1>
inline _LIBCPP_INLINE_VISIBILITY
@@ -824,10 +824,10 @@ atan(_A1 __lcpp_x) _NOEXCEPT {return ::atan((double)__lcpp_x);}
// atan2
-#if !(defined(_AIX) || defined(__sun__))
+# if !defined(__sun__)
inline _LIBCPP_INLINE_VISIBILITY float atan2(float __lcpp_y, float __lcpp_x) _NOEXCEPT {return ::atan2f(__lcpp_y, __lcpp_x);}
inline _LIBCPP_INLINE_VISIBILITY long double atan2(long double __lcpp_y, long double __lcpp_x) _NOEXCEPT {return ::atan2l(__lcpp_y, __lcpp_x);}
-#endif
+# endif
template <class _A1, class _A2>
inline _LIBCPP_INLINE_VISIBILITY
@@ -847,10 +847,10 @@ atan2(_A1 __lcpp_y, _A2 __lcpp_x) _NOEXCEPT
// ceil
-#if !(defined(_AIX) || defined(__sun__))
+# if !defined(__sun__)
inline _LIBCPP_INLINE_VISIBILITY float ceil(float __lcpp_x) _NOEXCEPT {return ::ceilf(__lcpp_x);}
inline _LIBCPP_INLINE_VISIBILITY long double ceil(long double __lcpp_x) _NOEXCEPT {return ::ceill(__lcpp_x);}
-#endif
+# endif
template <class _A1>
inline _LIBCPP_INLINE_VISIBILITY
@@ -859,10 +859,10 @@ ceil(_A1 __lcpp_x) _NOEXCEPT {return ::ceil((double)__lcpp_x);}
// cos
-#if !(defined(_AIX) || defined(__sun__))
+# if !defined(__sun__)
inline _LIBCPP_INLINE_VISIBILITY float cos(float __lcpp_x) _NOEXCEPT {return ::cosf(__lcpp_x);}
inline _LIBCPP_INLINE_VISIBILITY long double cos(long double __lcpp_x) _NOEXCEPT {return ::cosl(__lcpp_x);}
-#endif
+# endif
template <class _A1>
inline _LIBCPP_INLINE_VISIBILITY
@@ -871,10 +871,10 @@ cos(_A1 __lcpp_x) _NOEXCEPT {return ::cos((double)__lcpp_x);}
// cosh
-#if !(defined(_AIX) || defined(__sun__))
+# if !defined(__sun__)
inline _LIBCPP_INLINE_VISIBILITY float cosh(float __lcpp_x) _NOEXCEPT {return ::coshf(__lcpp_x);}
inline _LIBCPP_INLINE_VISIBILITY long double cosh(long double __lcpp_x) _NOEXCEPT {return ::coshl(__lcpp_x);}
-#endif
+# endif
template <class _A1>
inline _LIBCPP_INLINE_VISIBILITY
@@ -883,10 +883,10 @@ cosh(_A1 __lcpp_x) _NOEXCEPT {return ::cosh((double)__lcpp_x);}
// exp
-#if !(defined(_AIX) || defined(__sun__))
+# if !defined(__sun__)
inline _LIBCPP_INLINE_VISIBILITY float exp(float __lcpp_x) _NOEXCEPT {return ::expf(__lcpp_x);}
inline _LIBCPP_INLINE_VISIBILITY long double exp(long double __lcpp_x) _NOEXCEPT {return ::expl(__lcpp_x);}
-#endif
+# endif
template <class _A1>
inline _LIBCPP_INLINE_VISIBILITY
@@ -895,10 +895,10 @@ exp(_A1 __lcpp_x) _NOEXCEPT {return ::exp((double)__lcpp_x);}
// fabs
-#if !(defined(_AIX) || defined(__sun__))
+# if !defined(__sun__)
inline _LIBCPP_INLINE_VISIBILITY float fabs(float __lcpp_x) _NOEXCEPT {return ::fabsf(__lcpp_x);}
inline _LIBCPP_INLINE_VISIBILITY long double fabs(long double __lcpp_x) _NOEXCEPT {return ::fabsl(__lcpp_x);}
-#endif
+# endif
template <class _A1>
inline _LIBCPP_INLINE_VISIBILITY
@@ -907,10 +907,10 @@ fabs(_A1 __lcpp_x) _NOEXCEPT {return ::fabs((double)__lcpp_x);}
// floor
-#if !(defined(_AIX) || defined(__sun__))
+# if !defined(__sun__)
inline _LIBCPP_INLINE_VISIBILITY float floor(float __lcpp_x) _NOEXCEPT {return ::floorf(__lcpp_x);}
inline _LIBCPP_INLINE_VISIBILITY long double floor(long double __lcpp_x) _NOEXCEPT {return ::floorl(__lcpp_x);}
-#endif
+# endif
template <class _A1>
inline _LIBCPP_INLINE_VISIBILITY
@@ -919,10 +919,10 @@ floor(_A1 __lcpp_x) _NOEXCEPT {return ::floor((double)__lcpp_x);}
// fmod
-#if !(defined(_AIX) || defined(__sun__))
+# if !defined(__sun__)
inline _LIBCPP_INLINE_VISIBILITY float fmod(float __lcpp_x, float __lcpp_y) _NOEXCEPT {return ::fmodf(__lcpp_x, __lcpp_y);}
inline _LIBCPP_INLINE_VISIBILITY long double fmod(long double __lcpp_x, long double __lcpp_y) _NOEXCEPT {return ::fmodl(__lcpp_x, __lcpp_y);}
-#endif
+# endif
template <class _A1, class _A2>
inline _LIBCPP_INLINE_VISIBILITY
@@ -942,10 +942,10 @@ fmod(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
// frexp
-#if !(defined(_AIX) || defined(__sun__))
+# if !defined(__sun__)
inline _LIBCPP_INLINE_VISIBILITY float frexp(float __lcpp_x, int* __lcpp_e) _NOEXCEPT {return ::frexpf(__lcpp_x, __lcpp_e);}
inline _LIBCPP_INLINE_VISIBILITY long double frexp(long double __lcpp_x, int* __lcpp_e) _NOEXCEPT {return ::frexpl(__lcpp_x, __lcpp_e);}
-#endif
+# endif
template <class _A1>
inline _LIBCPP_INLINE_VISIBILITY
@@ -954,10 +954,10 @@ frexp(_A1 __lcpp_x, int* __lcpp_e) _NOEXCEPT {return ::frexp((double)__lcpp_x, _
// ldexp
-#if !(defined(_AIX) || defined(__sun__))
+# if !defined(__sun__)
inline _LIBCPP_INLINE_VISIBILITY float ldexp(float __lcpp_x, int __lcpp_e) _NOEXCEPT {return ::ldexpf(__lcpp_x, __lcpp_e);}
inline _LIBCPP_INLINE_VISIBILITY long double ldexp(long double __lcpp_x, int __lcpp_e) _NOEXCEPT {return ::ldexpl(__lcpp_x, __lcpp_e);}
-#endif
+# endif
template <class _A1>
inline _LIBCPP_INLINE_VISIBILITY
@@ -966,10 +966,10 @@ ldexp(_A1 __lcpp_x, int __lcpp_e) _NOEXCEPT {return ::ldexp((double)__lcpp_x, __
// log
-#if !(defined(_AIX) || defined(__sun__))
+# if !defined(__sun__)
inline _LIBCPP_INLINE_VISIBILITY float log(float __lcpp_x) _NOEXCEPT {return ::logf(__lcpp_x);}
inline _LIBCPP_INLINE_VISIBILITY long double log(long double __lcpp_x) _NOEXCEPT {return ::logl(__lcpp_x);}
-#endif
+# endif
template <class _A1>
inline _LIBCPP_INLINE_VISIBILITY
@@ -978,10 +978,10 @@ log(_A1 __lcpp_x) _NOEXCEPT {return ::log((double)__lcpp_x);}
// log10
-#if !(defined(_AIX) || defined(__sun__))
+# if !defined(__sun__)
inline _LIBCPP_INLINE_VISIBILITY float log10(float __lcpp_x) _NOEXCEPT {return ::log10f(__lcpp_x);}
inline _LIBCPP_INLINE_VISIBILITY long double log10(long double __lcpp_x) _NOEXCEPT {return ::log10l(__lcpp_x);}
-#endif
+# endif
template <class _A1>
inline _LIBCPP_INLINE_VISIBILITY
@@ -990,17 +990,17 @@ log10(_A1 __lcpp_x) _NOEXCEPT {return ::log10((double)__lcpp_x);}
// modf
-#if !(defined(_AIX) || defined(__sun__))
+# if !defined(__sun__)
inline _LIBCPP_INLINE_VISIBILITY float modf(float __lcpp_x, float* __lcpp_y) _NOEXCEPT {return ::modff(__lcpp_x, __lcpp_y);}
inline _LIBCPP_INLINE_VISIBILITY long double modf(long double __lcpp_x, long double* __lcpp_y) _NOEXCEPT {return ::modfl(__lcpp_x, __lcpp_y);}
-#endif
+# endif
// pow
-#if !(defined(_AIX) || defined(__sun__))
+# if !defined(__sun__)
inline _LIBCPP_INLINE_VISIBILITY float pow(float __lcpp_x, float __lcpp_y) _NOEXCEPT {return ::powf(__lcpp_x, __lcpp_y);}
inline _LIBCPP_INLINE_VISIBILITY long double pow(long double __lcpp_x, long double __lcpp_y) _NOEXCEPT {return ::powl(__lcpp_x, __lcpp_y);}
-#endif
+# endif
template <class _A1, class _A2>
inline _LIBCPP_INLINE_VISIBILITY
@@ -1020,7 +1020,7 @@ pow(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
// sin
-#if !(defined(_AIX) || defined(__sun__))
+# if !defined(__sun__)
inline _LIBCPP_INLINE_VISIBILITY float sin(float __lcpp_x) _NOEXCEPT {return ::sinf(__lcpp_x);}
inline _LIBCPP_INLINE_VISIBILITY long double sin(long double __lcpp_x) _NOEXCEPT {return ::sinl(__lcpp_x);}
#endif
@@ -1032,10 +1032,10 @@ sin(_A1 __lcpp_x) _NOEXCEPT {return ::sin((double)__lcpp_x);}
// sinh
-#if !(defined(_AIX) || defined(__sun__))
+# if !defined(__sun__)
inline _LIBCPP_INLINE_VISIBILITY float sinh(float __lcpp_x) _NOEXCEPT {return ::sinhf(__lcpp_x);}
inline _LIBCPP_INLINE_VISIBILITY long double sinh(long double __lcpp_x) _NOEXCEPT {return ::sinhl(__lcpp_x);}
-#endif
+# endif
template <class _A1>
inline _LIBCPP_INLINE_VISIBILITY
@@ -1044,10 +1044,10 @@ sinh(_A1 __lcpp_x) _NOEXCEPT {return ::sinh((double)__lcpp_x);}
// sqrt
-#if !(defined(_AIX) || defined(__sun__))
+# if !defined(__sun__)
inline _LIBCPP_INLINE_VISIBILITY float sqrt(float __lcpp_x) _NOEXCEPT {return ::sqrtf(__lcpp_x);}
inline _LIBCPP_INLINE_VISIBILITY long double sqrt(long double __lcpp_x) _NOEXCEPT {return ::sqrtl(__lcpp_x);}
-#endif
+# endif
template <class _A1>
inline _LIBCPP_INLINE_VISIBILITY
@@ -1056,10 +1056,10 @@ sqrt(_A1 __lcpp_x) _NOEXCEPT {return ::sqrt((double)__lcpp_x);}
// tan
-#if !(defined(_AIX) || defined(__sun__))
+# if !defined(__sun__)
inline _LIBCPP_INLINE_VISIBILITY float tan(float __lcpp_x) _NOEXCEPT {return ::tanf(__lcpp_x);}
inline _LIBCPP_INLINE_VISIBILITY long double tan(long double __lcpp_x) _NOEXCEPT {return ::tanl(__lcpp_x);}
-#endif
+# endif
template <class _A1>
inline _LIBCPP_INLINE_VISIBILITY
@@ -1068,10 +1068,10 @@ tan(_A1 __lcpp_x) _NOEXCEPT {return ::tan((double)__lcpp_x);}
// tanh
-#if !(defined(_AIX) || defined(__sun__))
+# if !defined(__sun__)
inline _LIBCPP_INLINE_VISIBILITY float tanh(float __lcpp_x) _NOEXCEPT {return ::tanhf(__lcpp_x);}
inline _LIBCPP_INLINE_VISIBILITY long double tanh(long double __lcpp_x) _NOEXCEPT {return ::tanhl(__lcpp_x);}
-#endif
+# endif
template <class _A1>
inline _LIBCPP_INLINE_VISIBILITY
diff --git a/libcxx/include/memory b/libcxx/include/memory
index db59936707e4..299746022274 100644
--- a/libcxx/include/memory
+++ b/libcxx/include/memory
@@ -98,6 +98,16 @@ struct allocator_traits
static allocator_type select_on_container_copy_construction(const allocator_type& a); // constexpr in C++20
};
+template<class Pointer>
+struct allocation_result {
+ Pointer ptr;
+ size_t count;
+}; // since C++23
+
+template<class Allocator>
+[[nodiscard]] constexpr allocation_result<typename allocator_traits<Allocator>::pointer>
+ allocate_at_least(Allocator& a, size_t n); // since C++23
+
template <>
class allocator<void> // removed in C++20
{
@@ -661,9 +671,29 @@ template<class E, class T, class Y>
template<class D, class T> D* get_deleter(shared_ptr<T> const& p) noexcept;
template<class T, class... Args>
- shared_ptr<T> make_shared(Args&&... args);
+ shared_ptr<T> make_shared(Args&&... args); // T is not an array
template<class T, class A, class... Args>
- shared_ptr<T> allocate_shared(const A& a, Args&&... args);
+ shared_ptr<T> allocate_shared(const A& a, Args&&... args); // T is not an array
+
+template<class T>
+ shared_ptr<T> make_shared(size_t N); // T is U[] (since C++20)
+template<class T, class A>
+ shared_ptr<T> allocate_shared(const A& a, size_t N); // T is U[] (since C++20)
+
+template<class T>
+ shared_ptr<T> make_shared(); // T is U[N] (since C++20)
+template<class T, class A>
+ shared_ptr<T> allocate_shared(const A& a); // T is U[N] (since C++20)
+
+template<class T>
+ shared_ptr<T> make_shared(size_t N, const remove_extent_t<T>& u); // T is U[] (since C++20)
+template<class T, class A>
+ shared_ptr<T> allocate_shared(const A& a, size_t N, const remove_extent_t<T>& u); // T is U[] (since C++20)
+
+template<class T> shared_ptr<T>
+ make_shared(const remove_extent_t<T>& u); // T is U[N] (since C++20)
+template<class T, class A>
+ shared_ptr<T> allocate_shared(const A& a, const remove_extent_t<T>& u); // T is U[N] (since C++20)
template<class T>
class weak_ptr
@@ -798,19 +828,26 @@ template <class T> struct hash<shared_ptr<T> >;
template <class T, class Alloc>
inline constexpr bool uses_allocator_v = uses_allocator<T, Alloc>::value;
+// [ptr.align]
void* align(size_t alignment, size_t size, void*& ptr, size_t& space);
+template<size_t N, class T>
+[[nodiscard]] constexpr T* assume_aligned(T* ptr); // since C++20
+
} // std
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
-#include <__functional_base>
#include <__memory/addressof.h>
+#include <__memory/allocate_at_least.h>
#include <__memory/allocation_guard.h>
#include <__memory/allocator.h>
#include <__memory/allocator_arg_t.h>
#include <__memory/allocator_traits.h>
+#include <__memory/assume_aligned.h>
+#include <__memory/auto_ptr.h>
#include <__memory/compressed_pair.h>
#include <__memory/concepts.h>
#include <__memory/construct_at.h>
@@ -823,26 +860,27 @@ void* align(size_t alignment, size_t size, void*& ptr, size_t& space);
#include <__memory/uninitialized_algorithms.h>
#include <__memory/unique_ptr.h>
#include <__memory/uses_allocator.h>
-#include <compare>
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <iosfwd>
-#include <iterator>
#include <new>
#include <stdexcept>
#include <tuple>
#include <type_traits>
#include <typeinfo>
-#include <utility>
#include <version>
-#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
-# include <__memory/auto_ptr.h>
+#ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES
+# include <iterator>
+# include <utility>
#endif
+// standard-mandated includes
+#include <compare>
+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -1092,7 +1130,6 @@ struct __builtin_new_allocator {
}
};
-
_LIBCPP_END_NAMESPACE_STD
#if defined(_LIBCPP_HAS_PARALLEL_ALGORITHMS) && _LIBCPP_STD_VER >= 17
diff --git a/libcxx/include/module.modulemap b/libcxx/include/module.modulemap.in
index 84abf01bf5d7..3e191dc0f86d 100644
--- a/libcxx/include/module.modulemap
+++ b/libcxx/include/module.modulemap.in
@@ -2,7 +2,8 @@
// since __config may be included from C headers which may create an
// include cycle.
module std_config [system] [extern_c] {
- header "__config"
+ header "__config"
+ export *
}
module std [system] {
@@ -37,6 +38,7 @@ module std [system] {
// <iso646.h> provided by compiler.
// <limits.h> provided by compiler or C library.
module locale_h {
+ @requires_LIBCXX_ENABLE_LOCALIZATION@
header "locale.h"
export *
}
@@ -48,6 +50,12 @@ module std [system] {
header "setjmp.h"
export *
}
+ module stdatomic_h {
+ @requires_LIBCXX_ENABLE_THREADS@
+ requires cplusplus23
+ header "stdatomic.h"
+ export *
+ }
// FIXME: <stdalign.h> is missing.
// <signal.h> provided by C library.
// <stdarg.h> provided by compiler.
@@ -78,14 +86,19 @@ module std [system] {
header "string.h"
export *
}
- // FIXME: <uchar.h> is missing.
+ module uchar_h {
+ header "uchar.h"
+ export *
+ }
// <time.h> provided by C library.
module wchar_h {
+ @requires_LIBCXX_ENABLE_WIDE_CHARACTERS@
// <wchar.h>'s __need_* macros require textual inclusion.
textual header "wchar.h"
export *
}
module wctype_h {
+ @requires_LIBCXX_ENABLE_WIDE_CHARACTERS@
header "wctype.h"
export *
}
@@ -146,6 +159,7 @@ module std [system] {
export *
}
module clocale {
+ @requires_LIBCXX_ENABLE_LOCALIZATION@
header "clocale"
export *
}
@@ -201,13 +215,18 @@ module std [system] {
header "ctime"
export *
}
- // FIXME: <cuchar> is missing.
+ module cuchar {
+ header "cuchar"
+ export *
+ }
module cwchar {
+ @requires_LIBCXX_ENABLE_WIDE_CHARACTERS@
header "cwchar"
export depr.stdio_h
export *
}
module cwctype {
+ @requires_LIBCXX_ENABLE_WIDE_CHARACTERS@
header "cwctype"
export *
}
@@ -219,102 +238,150 @@ module std [system] {
export *
module __algorithm {
- module adjacent_find { private header "__algorithm/adjacent_find.h" }
- module all_of { private header "__algorithm/all_of.h" }
- module any_of { private header "__algorithm/any_of.h" }
- module binary_search { private header "__algorithm/binary_search.h" }
- module clamp { private header "__algorithm/clamp.h" }
- module comp { private header "__algorithm/comp.h" }
- module comp_ref_type { private header "__algorithm/comp_ref_type.h" }
- module copy { private header "__algorithm/copy.h" }
- module copy_backward { private header "__algorithm/copy_backward.h" }
- module copy_if { private header "__algorithm/copy_if.h" }
- module copy_n { private header "__algorithm/copy_n.h" }
- module count { private header "__algorithm/count.h" }
- module count_if { private header "__algorithm/count_if.h" }
- module equal { private header "__algorithm/equal.h" }
- module equal_range { private header "__algorithm/equal_range.h" }
- module fill { private header "__algorithm/fill.h" }
- module fill_n { private header "__algorithm/fill_n.h" }
- module find { private header "__algorithm/find.h" }
- module find_end { private header "__algorithm/find_end.h" }
- module find_first_of { private header "__algorithm/find_first_of.h" }
- module find_if { private header "__algorithm/find_if.h" }
- module find_if_not { private header "__algorithm/find_if_not.h" }
- module for_each { private header "__algorithm/for_each.h" }
- module for_each_n { private header "__algorithm/for_each_n.h" }
- module generate { private header "__algorithm/generate.h" }
- module generate_n { private header "__algorithm/generate_n.h" }
- module half_positive { private header "__algorithm/half_positive.h" }
- module in_in_out_result { private header "__algorithm/in_in_out_result.h" }
- module in_in_result { private header "__algorithm/in_in_result.h" }
- module in_out_result { private header "__algorithm/in_out_result.h" }
- module includes { private header "__algorithm/includes.h" }
- module inplace_merge { private header "__algorithm/inplace_merge.h" }
- module is_heap { private header "__algorithm/is_heap.h" }
- module is_heap_until { private header "__algorithm/is_heap_until.h" }
- module is_partitioned { private header "__algorithm/is_partitioned.h" }
- module is_permutation { private header "__algorithm/is_permutation.h" }
- module is_sorted { private header "__algorithm/is_sorted.h" }
- module is_sorted_until { private header "__algorithm/is_sorted_until.h" }
- module iter_swap { private header "__algorithm/iter_swap.h" }
- module lexicographical_compare { private header "__algorithm/lexicographical_compare.h" }
- module lower_bound { private header "__algorithm/lower_bound.h" }
- module make_heap { private header "__algorithm/make_heap.h" }
- module max { private header "__algorithm/max.h" }
- module max_element { private header "__algorithm/max_element.h" }
- module merge { private header "__algorithm/merge.h" }
- module min { private header "__algorithm/min.h" }
- module min_element { private header "__algorithm/min_element.h" }
- module minmax { private header "__algorithm/minmax.h" }
- module minmax_element { private header "__algorithm/minmax_element.h" }
- module mismatch { private header "__algorithm/mismatch.h" }
- module move { private header "__algorithm/move.h" }
- module move_backward { private header "__algorithm/move_backward.h" }
- module next_permutation { private header "__algorithm/next_permutation.h" }
- module none_of { private header "__algorithm/none_of.h" }
- module nth_element { private header "__algorithm/nth_element.h" }
- module partial_sort { private header "__algorithm/partial_sort.h" }
- module partial_sort_copy { private header "__algorithm/partial_sort_copy.h" }
- module partition { private header "__algorithm/partition.h" }
- module partition_copy { private header "__algorithm/partition_copy.h" }
- module partition_point { private header "__algorithm/partition_point.h" }
- module pop_heap { private header "__algorithm/pop_heap.h" }
- module prev_permutation { private header "__algorithm/prev_permutation.h" }
- module push_heap { private header "__algorithm/push_heap.h" }
- module remove { private header "__algorithm/remove.h" }
- module remove_copy { private header "__algorithm/remove_copy.h" }
- module remove_copy_if { private header "__algorithm/remove_copy_if.h" }
- module remove_if { private header "__algorithm/remove_if.h" }
- module replace { private header "__algorithm/replace.h" }
- module replace_copy { private header "__algorithm/replace_copy.h" }
- module replace_copy_if { private header "__algorithm/replace_copy_if.h" }
- module replace_if { private header "__algorithm/replace_if.h" }
- module reverse { private header "__algorithm/reverse.h" }
- module reverse_copy { private header "__algorithm/reverse_copy.h" }
- module rotate { private header "__algorithm/rotate.h" }
- module rotate_copy { private header "__algorithm/rotate_copy.h" }
- module sample { private header "__algorithm/sample.h" }
- module search { private header "__algorithm/search.h" }
- module search_n { private header "__algorithm/search_n.h" }
- module set_difference { private header "__algorithm/set_difference.h" }
- module set_intersection { private header "__algorithm/set_intersection.h" }
- module set_symmetric_difference { private header "__algorithm/set_symmetric_difference.h" }
- module set_union { private header "__algorithm/set_union.h" }
- module shift_left { private header "__algorithm/shift_left.h" }
- module shift_right { private header "__algorithm/shift_right.h" }
- module shuffle { private header "__algorithm/shuffle.h" }
- module sift_down { private header "__algorithm/sift_down.h" }
- module sort { private header "__algorithm/sort.h" }
- module sort_heap { private header "__algorithm/sort_heap.h" }
- module stable_partition { private header "__algorithm/stable_partition.h" }
- module stable_sort { private header "__algorithm/stable_sort.h" }
- module swap_ranges { private header "__algorithm/swap_ranges.h" }
- module transform { private header "__algorithm/transform.h" }
- module unique { private header "__algorithm/unique.h" }
- module unique_copy { private header "__algorithm/unique_copy.h" }
- module unwrap_iter { private header "__algorithm/unwrap_iter.h" }
- module upper_bound { private header "__algorithm/upper_bound.h" }
+ module adjacent_find { private header "__algorithm/adjacent_find.h" }
+ module all_of { private header "__algorithm/all_of.h" }
+ module any_of { private header "__algorithm/any_of.h" }
+ module binary_search { private header "__algorithm/binary_search.h" }
+ module clamp { private header "__algorithm/clamp.h" }
+ module comp { private header "__algorithm/comp.h" }
+ module comp_ref_type { private header "__algorithm/comp_ref_type.h" }
+ module copy { private header "__algorithm/copy.h" }
+ module copy_backward { private header "__algorithm/copy_backward.h" }
+ module copy_if { private header "__algorithm/copy_if.h" }
+ module copy_n { private header "__algorithm/copy_n.h" }
+ module count { private header "__algorithm/count.h" }
+ module count_if { private header "__algorithm/count_if.h" }
+ module equal { private header "__algorithm/equal.h" }
+ module equal_range { private header "__algorithm/equal_range.h" }
+ module fill { private header "__algorithm/fill.h" }
+ module fill_n { private header "__algorithm/fill_n.h" }
+ module find { private header "__algorithm/find.h" }
+ module find_end { private header "__algorithm/find_end.h" }
+ module find_first_of { private header "__algorithm/find_first_of.h" }
+ module find_if { private header "__algorithm/find_if.h" }
+ module find_if_not { private header "__algorithm/find_if_not.h" }
+ module for_each { private header "__algorithm/for_each.h" }
+ module for_each_n { private header "__algorithm/for_each_n.h" }
+ module generate { private header "__algorithm/generate.h" }
+ module generate_n { private header "__algorithm/generate_n.h" }
+ module half_positive { private header "__algorithm/half_positive.h" }
+ module in_found_result { private header "__algorithm/in_found_result.h" }
+ module in_fun_result { private header "__algorithm/in_fun_result.h" }
+ module in_in_out_result { private header "__algorithm/in_in_out_result.h" }
+ module in_in_result { private header "__algorithm/in_in_result.h" }
+ module in_out_out_result { private header "__algorithm/in_out_out_result.h" }
+ module in_out_result { private header "__algorithm/in_out_result.h" }
+ module includes { private header "__algorithm/includes.h" }
+ module inplace_merge { private header "__algorithm/inplace_merge.h" }
+ module is_heap { private header "__algorithm/is_heap.h" }
+ module is_heap_until { private header "__algorithm/is_heap_until.h" }
+ module is_partitioned { private header "__algorithm/is_partitioned.h" }
+ module is_permutation { private header "__algorithm/is_permutation.h" }
+ module is_sorted { private header "__algorithm/is_sorted.h" }
+ module is_sorted_until { private header "__algorithm/is_sorted_until.h" }
+ module iter_swap { private header "__algorithm/iter_swap.h" }
+ module iterator_operations { private header "__algorithm/iterator_operations.h" }
+ module lexicographical_compare { private header "__algorithm/lexicographical_compare.h" }
+ module lower_bound { private header "__algorithm/lower_bound.h" }
+ module make_heap { private header "__algorithm/make_heap.h" }
+ module make_projected { private header "__algorithm/make_projected.h" }
+ module max { private header "__algorithm/max.h" }
+ module max_element { private header "__algorithm/max_element.h" }
+ module merge { private header "__algorithm/merge.h" }
+ module min { private header "__algorithm/min.h" }
+ module min_element { private header "__algorithm/min_element.h" }
+ module min_max_result { private header "__algorithm/min_max_result.h" }
+ module minmax { private header "__algorithm/minmax.h" }
+ module minmax_element { private header "__algorithm/minmax_element.h" }
+ module mismatch { private header "__algorithm/mismatch.h" }
+ module move { private header "__algorithm/move.h" }
+ module move_backward { private header "__algorithm/move_backward.h" }
+ module next_permutation { private header "__algorithm/next_permutation.h" }
+ module none_of { private header "__algorithm/none_of.h" }
+ module nth_element { private header "__algorithm/nth_element.h" }
+ module partial_sort { private header "__algorithm/partial_sort.h" }
+ module partial_sort_copy { private header "__algorithm/partial_sort_copy.h" }
+ module partition { private header "__algorithm/partition.h" }
+ module partition_copy { private header "__algorithm/partition_copy.h" }
+ module partition_point { private header "__algorithm/partition_point.h" }
+ module pop_heap { private header "__algorithm/pop_heap.h" }
+ module prev_permutation { private header "__algorithm/prev_permutation.h" }
+ module push_heap { private header "__algorithm/push_heap.h" }
+ module ranges_adjacent_find { private header "__algorithm/ranges_adjacent_find.h" }
+ module ranges_all_of { private header "__algorithm/ranges_all_of.h" }
+ module ranges_any_of { private header "__algorithm/ranges_any_of.h" }
+ module ranges_binary_search { private header "__algorithm/ranges_binary_search.h" }
+ module ranges_copy { private header "__algorithm/ranges_copy.h" }
+ module ranges_copy_backward { private header "__algorithm/ranges_copy_backward.h" }
+ module ranges_copy_if { private header "__algorithm/ranges_copy_if.h" }
+ module ranges_copy_n { private header "__algorithm/ranges_copy_n.h" }
+ module ranges_count { private header "__algorithm/ranges_count.h" }
+ module ranges_count_if { private header "__algorithm/ranges_count_if.h" }
+ module ranges_equal { private header "__algorithm/ranges_equal.h" }
+ module ranges_fill { private header "__algorithm/ranges_fill.h" }
+ module ranges_fill_n { private header "__algorithm/ranges_fill_n.h" }
+ module ranges_find { private header "__algorithm/ranges_find.h" }
+ module ranges_find_first_of { private header "__algorithm/ranges_find_first_of.h" }
+ module ranges_find_if { private header "__algorithm/ranges_find_if.h" }
+ module ranges_find_if_not { private header "__algorithm/ranges_find_if_not.h" }
+ module ranges_for_each { private header "__algorithm/ranges_for_each.h" }
+ module ranges_for_each_n { private header "__algorithm/ranges_for_each_n.h" }
+ module ranges_is_partitioned { private header "__algorithm/ranges_is_partitioned.h" }
+ module ranges_is_sorted { private header "__algorithm/ranges_is_sorted.h" }
+ module ranges_is_sorted_until { private header "__algorithm/ranges_is_sorted_until.h" }
+ module ranges_lexicographical_compare { private header "__algorithm/ranges_lexicographical_compare.h" }
+ module ranges_lower_bound { private header "__algorithm/ranges_lower_bound.h" }
+ module ranges_max { private header "__algorithm/ranges_max.h" }
+ module ranges_max_element { private header "__algorithm/ranges_max_element.h" }
+ module ranges_min { private header "__algorithm/ranges_min.h" }
+ module ranges_min_element { private header "__algorithm/ranges_min_element.h" }
+ module ranges_minmax { private header "__algorithm/ranges_minmax.h" }
+ module ranges_minmax_element { private header "__algorithm/ranges_minmax_element.h" }
+ module ranges_mismatch { private header "__algorithm/ranges_mismatch.h" }
+ module ranges_move { private header "__algorithm/ranges_move.h" }
+ module ranges_move_backward { private header "__algorithm/ranges_move_backward.h" }
+ module ranges_none_of { private header "__algorithm/ranges_none_of.h" }
+ module ranges_replace { private header "__algorithm/ranges_replace.h" }
+ module ranges_replace_if { private header "__algorithm/ranges_replace_if.h" }
+ module ranges_reverse { private header "__algorithm/ranges_reverse.h" }
+ module ranges_sort { private header "__algorithm/ranges_sort.h" }
+ module ranges_stable_sort { private header "__algorithm/ranges_stable_sort.h" }
+ module ranges_swap_ranges { private header "__algorithm/ranges_swap_ranges.h" }
+ module ranges_transform { private header "__algorithm/ranges_transform.h" }
+ module ranges_upper_bound { private header "__algorithm/ranges_upper_bound.h" }
+ module remove { private header "__algorithm/remove.h" }
+ module remove_copy { private header "__algorithm/remove_copy.h" }
+ module remove_copy_if { private header "__algorithm/remove_copy_if.h" }
+ module remove_if { private header "__algorithm/remove_if.h" }
+ module replace { private header "__algorithm/replace.h" }
+ module replace_copy { private header "__algorithm/replace_copy.h" }
+ module replace_copy_if { private header "__algorithm/replace_copy_if.h" }
+ module replace_if { private header "__algorithm/replace_if.h" }
+ module reverse { private header "__algorithm/reverse.h" }
+ module reverse_copy { private header "__algorithm/reverse_copy.h" }
+ module rotate { private header "__algorithm/rotate.h" }
+ module rotate_copy { private header "__algorithm/rotate_copy.h" }
+ module sample { private header "__algorithm/sample.h" }
+ module search { private header "__algorithm/search.h" }
+ module search_n { private header "__algorithm/search_n.h" }
+ module set_difference { private header "__algorithm/set_difference.h" }
+ module set_intersection { private header "__algorithm/set_intersection.h" }
+ module set_symmetric_difference { private header "__algorithm/set_symmetric_difference.h" }
+ module set_union { private header "__algorithm/set_union.h" }
+ module shift_left { private header "__algorithm/shift_left.h" }
+ module shift_right { private header "__algorithm/shift_right.h" }
+ module shuffle { private header "__algorithm/shuffle.h" }
+ module sift_down { private header "__algorithm/sift_down.h" }
+ module sort { private header "__algorithm/sort.h" }
+ module sort_heap { private header "__algorithm/sort_heap.h" }
+ module stable_partition { private header "__algorithm/stable_partition.h" }
+ module stable_sort { private header "__algorithm/stable_sort.h" }
+ module swap_ranges { private header "__algorithm/swap_ranges.h" }
+ module transform { private header "__algorithm/transform.h" }
+ module unique { private header "__algorithm/unique.h" }
+ module unique_copy { private header "__algorithm/unique_copy.h" }
+ module unwrap_iter { private header "__algorithm/unwrap_iter.h" }
+ module upper_bound { private header "__algorithm/upper_bound.h" }
}
}
module any {
@@ -331,7 +398,7 @@ module std [system] {
export *
}
module barrier {
- requires cplusplus14
+ @requires_LIBCXX_ENABLE_THREADS@
header "barrier"
export *
}
@@ -358,6 +425,8 @@ module std [system] {
module __charconv {
module chars_format { private header "__charconv/chars_format.h" }
module from_chars_result { private header "__charconv/from_chars_result.h" }
+ module tables { private header "__charconv/tables.h" }
+ module to_chars_base_10 { private header "__charconv/to_chars_base_10.h" }
module to_chars_result { private header "__charconv/to_chars_result.h" }
}
@@ -369,15 +438,31 @@ module std [system] {
module __chrono {
module calendar { private header "__chrono/calendar.h" }
module convert_to_timespec { private header "__chrono/convert_to_timespec.h" }
+ module day { private header "__chrono/day.h" }
module duration { private header "__chrono/duration.h" }
module file_clock { private header "__chrono/file_clock.h" }
- module high_resolution_clock { private header "__chrono/high_resolution_clock.h" }
+ module hh_mm_ss { private header "__chrono/hh_mm_ss.h" }
+ module high_resolution_clock {
+ private header "__chrono/high_resolution_clock.h"
+ export steady_clock
+ export system_clock
+ }
+ module literals { private header "__chrono/literals.h" }
+ module month { private header "__chrono/month.h" }
+ module month_weekday { private header "__chrono/month_weekday.h" }
+ module monthday { private header "__chrono/monthday.h" }
module steady_clock { private header "__chrono/steady_clock.h" }
module system_clock { private header "__chrono/system_clock.h" }
module time_point { private header "__chrono/time_point.h" }
+ module weekday { private header "__chrono/weekday.h" }
+ module year { private header "__chrono/year.h" }
+ module year_month { private header "__chrono/year_month.h" }
+ module year_month_day { private header "__chrono/year_month_day.h" }
+ module year_month_weekday { private header "__chrono/year_month_weekday.h" }
}
}
module codecvt {
+ @requires_LIBCXX_ENABLE_LOCALIZATION@
header "codecvt"
export *
}
@@ -465,6 +550,7 @@ module std [system] {
export *
}
module filesystem {
+ @requires_LIBCXX_ENABLE_FILESYSTEM@
header "filesystem"
export *
@@ -492,7 +578,11 @@ module std [system] {
export *
module __format {
+ module buffer { private header "__format/buffer.h" }
+ module concepts { private header "__format/concepts.h" }
+ module enable_insertable { private header "__format/enable_insertable.h" }
module format_arg { private header "__format/format_arg.h" }
+ module format_arg_store { private header "__format/format_arg_store.h" }
module format_args { private header "__format/format_args.h" }
module format_context {
private header "__format/format_context.h"
@@ -510,6 +600,7 @@ module std [system] {
module formatter_floating_point { private header "__format/formatter_floating_point.h" }
module formatter_integer { private header "__format/formatter_integer.h" }
module formatter_integral { private header "__format/formatter_integral.h" }
+ module formatter_output { private header "__format/formatter_output.h" }
module formatter_pointer { private header "__format/formatter_pointer.h" }
module formatter_string { private header "__format/formatter_string.h" }
module parser_std_format_spec { private header "__format/parser_std_format_spec.h" }
@@ -521,6 +612,7 @@ module std [system] {
export *
}
module fstream {
+ @requires_LIBCXX_ENABLE_LOCALIZATION@
header "fstream"
export *
}
@@ -536,6 +628,7 @@ module std [system] {
module bind_front { private header "__functional/bind_front.h" }
module binder1st { private header "__functional/binder1st.h" }
module binder2nd { private header "__functional/binder2nd.h" }
+ module boyer_moore_searcher { private header "__functional/boyer_moore_searcher.h" }
module compose { private header "__functional/compose.h" }
module default_searcher { private header "__functional/default_searcher.h" }
module function { private header "__functional/function.h" }
@@ -559,6 +652,7 @@ module std [system] {
}
}
module future {
+ @requires_LIBCXX_ENABLE_THREADS@
header "future"
export *
}
@@ -567,19 +661,26 @@ module std [system] {
export *
}
module iomanip {
+ @requires_LIBCXX_ENABLE_LOCALIZATION@
header "iomanip"
export *
}
module ios {
+ @requires_LIBCXX_ENABLE_LOCALIZATION@
header "ios"
export iosfwd
export *
+
+ module __ios {
+ module fpos { private header "__ios/fpos.h" }
+ }
}
module iosfwd {
header "iosfwd"
export *
}
module iostream {
+ @requires_LIBCXX_ENABLE_LOCALIZATION@
header "iostream"
export ios
export streambuf
@@ -588,6 +689,7 @@ module std [system] {
export *
}
module istream {
+ @requires_LIBCXX_ENABLE_LOCALIZATION@
header "istream"
// FIXME: should re-export ios, streambuf?
export *
@@ -600,6 +702,7 @@ module std [system] {
module access { private header "__iterator/access.h" }
module advance { private header "__iterator/advance.h" }
module back_insert_iterator { private header "__iterator/back_insert_iterator.h" }
+ module bounded_iter { private header "__iterator/bounded_iter.h" }
module common_iterator { private header "__iterator/common_iterator.h" }
module concepts { private header "__iterator/concepts.h" }
module counted_iterator { private header "__iterator/counted_iterator.h" }
@@ -618,22 +721,29 @@ module std [system] {
module iter_swap { private header "__iterator/iter_swap.h" }
module iterator { private header "__iterator/iterator.h" }
module iterator_traits { private header "__iterator/iterator_traits.h" }
+ module mergeable { private header "__iterator/mergeable.h" }
module move_iterator { private header "__iterator/move_iterator.h" }
+ module move_sentinel { private header "__iterator/move_sentinel.h" }
module next { private header "__iterator/next.h" }
module ostream_iterator { private header "__iterator/ostream_iterator.h" }
- module ostreambuf_iterator { private header "__iterator/ostreambuf_iterator.h" }
+ module ostreambuf_iterator {
+ private header "__iterator/ostreambuf_iterator.h"
+ export iosfwd
+ }
+ module permutable { private header "__iterator/permutable.h" }
module prev { private header "__iterator/prev.h" }
module projected { private header "__iterator/projected.h" }
module readable_traits { private header "__iterator/readable_traits.h" }
module reverse_access { private header "__iterator/reverse_access.h" }
module reverse_iterator { private header "__iterator/reverse_iterator.h" }
module size { private header "__iterator/size.h" }
+ module sortable { private header "__iterator/sortable.h" }
module unreachable_sentinel { private header "__iterator/unreachable_sentinel.h" }
module wrap_iter { private header "__iterator/wrap_iter.h" }
}
}
module latch {
- requires cplusplus14
+ @requires_LIBCXX_ENABLE_THREADS@
header "latch"
export *
}
@@ -647,6 +757,7 @@ module std [system] {
export *
}
module locale {
+ @requires_LIBCXX_ENABLE_LOCALIZATION@
header "locale"
export *
}
@@ -661,10 +772,12 @@ module std [system] {
module __memory {
module addressof { private header "__memory/addressof.h" }
+ module allocate_at_least { private header "__memory/allocate_at_least.h" }
module allocation_guard { private header "__memory/allocation_guard.h" }
module allocator { private header "__memory/allocator.h" }
module allocator_arg_t { private header "__memory/allocator_arg_t.h" }
module allocator_traits { private header "__memory/allocator_traits.h" }
+ module assume_aligned { private header "__memory/assume_aligned.h" }
module auto_ptr { private header "__memory/auto_ptr.h" }
module compressed_pair { private header "__memory/compressed_pair.h" }
module concepts { private header "__memory/concepts.h" }
@@ -682,6 +795,7 @@ module std [system] {
}
}
module mutex {
+ @requires_LIBCXX_ENABLE_THREADS@
header "mutex"
export *
}
@@ -718,6 +832,7 @@ module std [system] {
export *
}
module ostream {
+ @requires_LIBCXX_ENABLE_LOCALIZATION@
header "ostream"
// FIXME: should re-export ios, streambuf?
export *
@@ -749,6 +864,7 @@ module std [system] {
module geometric_distribution { private header "__random/geometric_distribution.h" }
module independent_bits_engine { private header "__random/independent_bits_engine.h" }
module is_seed_sequence { private header "__random/is_seed_sequence.h" }
+ module is_valid { private header "__random/is_valid.h" }
module knuth_b { private header "__random/knuth_b.h" }
module linear_congruential_engine { private header "__random/linear_congruential_engine.h" }
module log2 { private header "__random/log2.h" }
@@ -799,12 +915,16 @@ module std [system] {
module empty_view { private header "__ranges/empty_view.h" }
module enable_borrowed_range { private header "__ranges/enable_borrowed_range.h" }
module enable_view { private header "__ranges/enable_view.h" }
+ module filter_view { private header "__ranges/filter_view.h" }
module iota_view { private header "__ranges/iota_view.h" }
module join_view { private header "__ranges/join_view.h" }
+ module lazy_split_view { private header "__ranges/lazy_split_view.h" }
module non_propagating_cache { private header "__ranges/non_propagating_cache.h" }
module owning_view { private header "__ranges/owning_view.h" }
module range_adaptor { private header "__ranges/range_adaptor.h" }
+ module rbegin { private header "__ranges/rbegin.h" }
module ref_view { private header "__ranges/ref_view.h" }
+ module rend { private header "__ranges/rend.h" }
module reverse_view { private header "__ranges/reverse_view.h" }
module single_view { private header "__ranges/single_view.h" }
module size { private header "__ranges/size.h" }
@@ -816,6 +936,8 @@ module std [system] {
export functional.__functional.perfect_forward
}
module view_interface { private header "__ranges/view_interface.h" }
+ module views { private header "__ranges/views.h" }
+ module zip_view { private header "__ranges/zip_view.h" }
}
}
module ratio {
@@ -823,6 +945,7 @@ module std [system] {
export *
}
module regex {
+ @requires_LIBCXX_ENABLE_LOCALIZATION@
header "regex"
export initializer_list
export *
@@ -832,7 +955,7 @@ module std [system] {
export *
}
module semaphore {
- requires cplusplus14
+ @requires_LIBCXX_ENABLE_THREADS@
header "semaphore"
export *
}
@@ -842,6 +965,7 @@ module std [system] {
export *
}
module shared_mutex {
+ @requires_LIBCXX_ENABLE_THREADS@
header "shared_mutex"
export version
}
@@ -849,8 +973,10 @@ module std [system] {
header "span"
export ranges.__ranges.enable_borrowed_range
export version
+ module span_fwd { private header "__fwd/span.h" }
}
module sstream {
+ @requires_LIBCXX_ENABLE_LOCALIZATION@
header "sstream"
// FIXME: should re-export istream, ostream, ios, streambuf, string?
export *
@@ -865,6 +991,7 @@ module std [system] {
export *
}
module streambuf {
+ @requires_LIBCXX_ENABLE_LOCALIZATION@
header "streambuf"
export *
}
@@ -872,16 +999,20 @@ module std [system] {
header "string"
export initializer_list
export string_view
- export __string
+ module __string {
+ module char_traits { private header "__string/char_traits.h" }
+ module extern_template_lists { private header "__string/extern_template_lists.h" }
+ }
export *
}
module string_view {
header "string_view"
export initializer_list
- export __string
export *
+ module string_view_fwd { private header "__fwd/string_view.h" }
}
module strstream {
+ @requires_LIBCXX_ENABLE_LOCALIZATION@
header "strstream"
export *
}
@@ -890,6 +1021,7 @@ module std [system] {
export *
}
module thread {
+ @requires_LIBCXX_ENABLE_THREADS@
header "thread"
export *
@@ -906,6 +1038,104 @@ module std [system] {
header "type_traits"
export functional.__functional.unwrap_ref
export *
+
+ module add_const { private header "__type_traits/add_const.h" }
+ module add_cv { private header "__type_traits/add_cv.h" }
+ module add_lvalue_reference { private header "__type_traits/add_lvalue_reference.h" }
+ module add_pointer { private header "__type_traits/add_pointer.h" }
+ module add_rvalue_reference { private header "__type_traits/add_rvalue_reference.h" }
+ module add_volatile { private header "__type_traits/add_volatile.h" }
+ module alignment_of { private header "__type_traits/alignment_of.h" }
+ module apply_cv { private header "__type_traits/apply_cv.h" }
+ module conditional { private header "__type_traits/conditional.h" }
+ module conjunction { private header "__type_traits/conjunction.h" }
+ module decay { private header "__type_traits/decay.h" }
+ module disjunction { private header "__type_traits/disjunction.h" }
+ module enable_if { private header "__type_traits/enable_if.h" }
+ module extent { private header "__type_traits/extent.h" }
+ module has_unique_object_representation { private header "__type_traits/has_unique_object_representation.h" }
+ module has_virtual_destructor { private header "__type_traits/has_virtual_destructor.h" }
+ module integral_constant { private header "__type_traits/integral_constant.h" }
+ module is_abstract { private header "__type_traits/is_abstract.h" }
+ module is_aggregate { private header "__type_traits/is_aggregate.h" }
+ module is_arithmetic { private header "__type_traits/is_arithmetic.h" }
+ module is_array { private header "__type_traits/is_array.h" }
+ module is_assignable { private header "__type_traits/is_assignable.h" }
+ module is_base_of { private header "__type_traits/is_base_of.h" }
+ module is_bounded_array { private header "__type_traits/is_bounded_array.h" }
+ module is_callable { private header "__type_traits/is_callable.h" }
+ module is_class { private header "__type_traits/is_class.h" }
+ module is_compound { private header "__type_traits/is_compound.h" }
+ module is_const { private header "__type_traits/is_const.h" }
+ module is_constant_evaluated { private header "__type_traits/is_constant_evaluated.h" }
+ module is_constructible { private header "__type_traits/is_constructible.h" }
+ module is_convertible { private header "__type_traits/is_convertible.h" }
+ module is_copy_assignable { private header "__type_traits/is_copy_assignable.h" }
+ module is_copy_constructible { private header "__type_traits/is_copy_constructible.h" }
+ module is_core_convertible { private header "__type_traits/is_core_convertible.h" }
+ module is_default_constructible { private header "__type_traits/is_default_constructible.h" }
+ module is_destructible { private header "__type_traits/is_destructible.h" }
+ module is_empty { private header "__type_traits/is_empty.h" }
+ module is_enum { private header "__type_traits/is_enum.h" }
+ module is_final { private header "__type_traits/is_final.h" }
+ module is_floating_point { private header "__type_traits/is_floating_point.h" }
+ module is_function { private header "__type_traits/is_function.h" }
+ module is_fundamental { private header "__type_traits/is_fundamental.h" }
+ module is_integral { private header "__type_traits/is_integral.h" }
+ module is_literal_type { private header "__type_traits/is_literal_type.h" }
+ module is_member_function_pointer { private header "__type_traits/is_member_function_pointer.h" }
+ module is_member_object_pointer { private header "__type_traits/is_member_object_pointer.h" }
+ module is_member_pointer { private header "__type_traits/is_member_pointer.h" }
+ module is_move_assignable { private header "__type_traits/is_move_assignable.h" }
+ module is_move_constructible { private header "__type_traits/is_move_constructible.h" }
+ module is_nothrow_assignable { private header "__type_traits/is_nothrow_assignable.h" }
+ module is_nothrow_constructible { private header "__type_traits/is_nothrow_constructible.h" }
+ module is_nothrow_copy_assignable { private header "__type_traits/is_nothrow_copy_assignable.h" }
+ module is_nothrow_copy_constructible { private header "__type_traits/is_nothrow_copy_constructible.h" }
+ module is_nothrow_default_constructible { private header "__type_traits/is_nothrow_default_constructible.h" }
+ module is_nothrow_destructible { private header "__type_traits/is_nothrow_destructible.h" }
+ module is_nothrow_move_assignable { private header "__type_traits/is_nothrow_move_assignable.h" }
+ module is_nothrow_move_constructible { private header "__type_traits/is_nothrow_move_constructible.h" }
+ module is_null_pointer { private header "__type_traits/is_null_pointer.h" }
+ module is_object { private header "__type_traits/is_object.h" }
+ module is_pod { private header "__type_traits/is_pod.h" }
+ module is_pointer { private header "__type_traits/is_pointer.h" }
+ module is_polymorphic { private header "__type_traits/is_polymorphic.h" }
+ module is_reference { private header "__type_traits/is_reference.h" }
+ module is_reference_wrapper { private header "__type_traits/is_reference_wrapper.h" }
+ module is_referenceable { private header "__type_traits/is_referenceable.h" }
+ module is_same { private header "__type_traits/is_same.h" }
+ module is_scalar { private header "__type_traits/is_scalar.h" }
+ module is_scoped_enum { private header "__type_traits/is_scoped_enum.h" }
+ module is_signed { private header "__type_traits/is_signed.h" }
+ module is_standard_layout { private header "__type_traits/is_standard_layout.h" }
+ module is_trivial { private header "__type_traits/is_trivial.h" }
+ module is_trivially_assignable { private header "__type_traits/is_trivially_assignable.h" }
+ module is_trivially_constructible { private header "__type_traits/is_trivially_constructible.h" }
+ module is_trivially_copy_assignable { private header "__type_traits/is_trivially_copy_assignable.h" }
+ module is_trivially_copy_constructible { private header "__type_traits/is_trivially_copy_constructible.h" }
+ module is_trivially_copyable { private header "__type_traits/is_trivially_copyable.h" }
+ module is_trivially_default_constructible { private header "__type_traits/is_trivially_default_constructible.h" }
+ module is_trivially_destructible { private header "__type_traits/is_trivially_destructible.h" }
+ module is_trivially_move_assignable { private header "__type_traits/is_trivially_move_assignable.h" }
+ module is_trivially_move_constructible { private header "__type_traits/is_trivially_move_constructible.h" }
+ module is_unbounded_array { private header "__type_traits/is_unbounded_array.h" }
+ module is_union { private header "__type_traits/is_union.h" }
+ module is_unsigned { private header "__type_traits/is_unsigned.h" }
+ module is_void { private header "__type_traits/is_void.h" }
+ module is_volatile { private header "__type_traits/is_volatile.h" }
+ module negation { private header "__type_traits/negation.h" }
+ module rank { private header "__type_traits/rank.h" }
+ module remove_all_extents { private header "__type_traits/remove_all_extents.h" }
+ module remove_const { private header "__type_traits/remove_const.h" }
+ module remove_cv { private header "__type_traits/remove_cv.h" }
+ module remove_extent { private header "__type_traits/remove_extent.h" }
+ module remove_pointer { private header "__type_traits/remove_pointer.h" }
+ module remove_reference { private header "__type_traits/remove_reference.h" }
+ module remove_volatile { private header "__type_traits/remove_volatile.h" }
+ module type_identity { private header "__type_traits/type_identity.h" }
+ module underlying_type { private header "__type_traits/underlying_type.h" }
+ module void_t { private header "__type_traits/void_t.h" }
}
module typeindex {
header "typeindex"
@@ -947,6 +1177,7 @@ module std [system] {
module swap { private header "__utility/swap.h" }
module to_underlying { private header "__utility/to_underlying.h" }
module transaction { private header "__utility/transaction.h" }
+ module unreachable { private header "__utility/unreachable.h" }
}
}
module valarray {
@@ -972,22 +1203,26 @@ module std [system] {
export *
}
- // __config not modularised due to a bug in Clang
// FIXME: These should be private.
+ module __assert { header "__assert" export * }
module __availability { private header "__availability" export * }
module __bit_reference { private header "__bit_reference" export * }
module __bits { private header "__bits" export * }
module __debug { header "__debug" export * }
module __errc { private header "__errc" export * }
module __hash_table { header "__hash_table" export * }
- module __locale { private header "__locale" export * }
+ module __locale {
+ @requires_LIBCXX_ENABLE_LOCALIZATION@
+ private header "__locale" export *
+ }
module __mbstate_t { private header "__mbstate_t.h" export * }
module __mutex_base { private header "__mutex_base" export * }
module __node_handle { private header "__node_handle" export * }
- module __nullptr { header "__nullptr" export * }
module __split_buffer { private header "__split_buffer" export * }
- module __std_stream { private header "__std_stream" export * }
- module __string { private header "__string" export * }
+ module __std_stream {
+ @requires_LIBCXX_ENABLE_LOCALIZATION@
+ private header "__std_stream" export *
+ }
module __threading_support { header "__threading_support" export * }
module __tree { header "__tree" export * }
module __tuple { private header "__tuple" export * }
@@ -1000,7 +1235,7 @@ module std [system] {
header "experimental/algorithm"
export *
}
- module coroutine {
+ module coroutine {
requires coroutines
header "experimental/coroutine"
export *
@@ -1009,10 +1244,6 @@ module std [system] {
header "experimental/deque"
export *
}
- module filesystem {
- header "experimental/filesystem"
- export *
- }
module forward_list {
header "experimental/forward_list"
export *
@@ -1042,6 +1273,7 @@ module std [system] {
export *
}
module regex {
+ @requires_LIBCXX_ENABLE_LOCALIZATION@
header "experimental/regex"
export *
}
diff --git a/libcxx/include/mutex b/libcxx/include/mutex
index b2a4d7993e0d..5dfaad2b3510 100644
--- a/libcxx/include/mutex
+++ b/libcxx/include/mutex
@@ -186,20 +186,24 @@ template<class Callable, class ...Args>
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
#include <__mutex_base>
#include <__threading_support>
#include <__utility/forward.h>
#include <cstdint>
-#include <functional>
#include <memory>
#ifndef _LIBCPP_CXX03_LANG
# include <tuple>
#endif
#include <version>
+#ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES
+# include <functional>
+#endif
+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
diff --git a/libcxx/include/new b/libcxx/include/new
index be0d972f42da..ed95caed1c41 100644
--- a/libcxx/include/new
+++ b/libcxx/include/new
@@ -86,6 +86,7 @@ void operator delete[](void* ptr, void*) noexcept;
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__availability>
#include <__config>
#include <cstddef>
@@ -99,7 +100,7 @@ void operator delete[](void* ptr, void*) noexcept;
#endif
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
#if !defined(__cpp_sized_deallocation) || __cpp_sized_deallocation < 201309L
@@ -359,6 +360,17 @@ constexpr _Tp* launder(_Tp* __p) noexcept
}
#endif
+#if _LIBCPP_STD_VER > 14
+
+#if defined(__GCC_DESTRUCTIVE_SIZE) && defined(__GCC_CONSTRUCTIVE_SIZE)
+
+inline constexpr size_t hardware_destructive_interference_size = __GCC_DESTRUCTIVE_SIZE;
+inline constexpr size_t hardware_constructive_interference_size = __GCC_CONSTRUCTIVE_SIZE;
+
+#endif // defined(__GCC_DESTRUCTIVE_SIZE) && defined(__GCC_CONSTRUCTIVE_SIZE)
+
+#endif // _LIBCPP_STD_VER > 14
+
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_NEW
diff --git a/libcxx/include/numbers b/libcxx/include/numbers
index 2ac36695b888..3c8527dfc2de 100644
--- a/libcxx/include/numbers
+++ b/libcxx/include/numbers
@@ -58,15 +58,16 @@ namespace std::numbers {
}
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
#include <concepts>
#include <type_traits>
#include <version>
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -128,6 +129,6 @@ inline constexpr double phi = phi_v<double>;
_LIBCPP_END_NAMESPACE_STD
-#endif //_LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17
#endif // _LIBCPP_NUMBERS
diff --git a/libcxx/include/numeric b/libcxx/include/numeric
index 09d15a6024de..057faf508e6b 100644
--- a/libcxx/include/numeric
+++ b/libcxx/include/numeric
@@ -144,10 +144,9 @@ template<class T>
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
#include <cmath> // for isnormal
-#include <functional>
-#include <iterator>
#include <version>
#include <__numeric/accumulate.h>
@@ -164,8 +163,13 @@ template<class T>
#include <__numeric/transform_inclusive_scan.h>
#include <__numeric/transform_reduce.h>
+#ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES
+# include <functional>
+# include <iterator>
+#endif
+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
#if defined(_LIBCPP_HAS_PARALLEL_ALGORITHMS) && _LIBCPP_STD_VER >= 17
diff --git a/libcxx/include/optional b/libcxx/include/optional
index 917e9b5cdb57..349ceb5bc7f6 100644
--- a/libcxx/include/optional
+++ b/libcxx/include/optional
@@ -93,11 +93,11 @@ namespace std {
template <class U, class... Args>
constexpr explicit optional(in_place_t, initializer_list<U>, Args &&...);
template <class U = T>
- constexpr EXPLICIT optional(U &&);
+ constexpr explicit(see-below) optional(U &&);
template <class U>
- EXPLICIT optional(const optional<U> &); // constexpr in C++20
+ explicit(see-below) optional(const optional<U> &); // constexpr in C++20
template <class U>
- EXPLICIT optional(optional<U> &&); // constexpr in C++20
+ explicit(see-below) optional(optional<U> &&); // constexpr in C++20
// 23.6.3.2, destructor
~optional(); // constexpr in C++20
@@ -158,22 +158,45 @@ template<class T>
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__availability>
#include <__concepts/invocable.h>
#include <__config>
-#include <__debug>
-#include <__functional_base>
-#include <compare>
-#include <functional>
+#include <__functional/hash.h>
+#include <__functional/invoke.h>
+#include <__functional/unary_function.h>
+#include <__memory/construct_at.h>
+#include <__tuple>
+#include <__utility/forward.h>
+#include <__utility/in_place.h>
+#include <__utility/move.h>
+#include <__utility/swap.h>
#include <initializer_list>
#include <new>
#include <stdexcept>
#include <type_traits>
-#include <utility>
#include <version>
+#ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES
+# include <atomic>
+# include <chrono>
+# include <climits>
+# include <concepts>
+# include <ctime>
+# include <iterator>
+# include <memory>
+# include <ratio>
+# include <tuple>
+# include <typeinfo>
+# include <utility>
+# include <variant>
+#endif
+
+// standard-mandated includes
+#include <compare>
+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
namespace std // purposefully not using versioning namespace
@@ -382,9 +405,9 @@ struct __optional_storage_base : __optional_destruct_base<_Tp>
}
};
-// optional<T&> is currently required ill-formed, however it may to be in the
-// future. For this reason it has already been implemented to ensure we can
-// make the change in an ABI compatible manner.
+// 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>
{
@@ -1039,7 +1062,7 @@ public:
#if _LIBCPP_STD_VER > 20
template<class _Func>
- _LIBCPP_HIDE_FROM_ABI
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
constexpr auto and_then(_Func&& __f) & {
using _Up = invoke_result_t<_Func, value_type&>;
static_assert(__is_std_optional<remove_cvref_t<_Up>>::value,
@@ -1050,7 +1073,7 @@ public:
}
template<class _Func>
- _LIBCPP_HIDE_FROM_ABI
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
constexpr auto and_then(_Func&& __f) const& {
using _Up = invoke_result_t<_Func, const value_type&>;
static_assert(__is_std_optional<remove_cvref_t<_Up>>::value,
@@ -1061,7 +1084,7 @@ public:
}
template<class _Func>
- _LIBCPP_HIDE_FROM_ABI
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
constexpr auto and_then(_Func&& __f) && {
using _Up = invoke_result_t<_Func, value_type&&>;
static_assert(__is_std_optional<remove_cvref_t<_Up>>::value,
@@ -1083,7 +1106,7 @@ public:
}
template<class _Func>
- _LIBCPP_HIDE_FROM_ABI
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
constexpr auto transform(_Func&& __f) & {
using _Up = remove_cv_t<invoke_result_t<_Func, value_type&>>;
static_assert(!is_array_v<_Up>, "Result of f(value()) should not be an Array");
@@ -1098,7 +1121,7 @@ public:
}
template<class _Func>
- _LIBCPP_HIDE_FROM_ABI
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
constexpr auto transform(_Func&& __f) const& {
using _Up = remove_cv_t<invoke_result_t<_Func, const value_type&>>;
static_assert(!is_array_v<_Up>, "Result of f(value()) should not be an Array");
@@ -1113,7 +1136,7 @@ public:
}
template<class _Func>
- _LIBCPP_HIDE_FROM_ABI
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
constexpr auto transform(_Func&& __f) && {
using _Up = remove_cv_t<invoke_result_t<_Func, value_type&&>>;
static_assert(!is_array_v<_Up>, "Result of f(std::move(value())) should not be an Array");
@@ -1128,7 +1151,7 @@ public:
}
template<class _Func>
- _LIBCPP_HIDE_FROM_ABI
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
constexpr auto transform(_Func&& __f) const&& {
using _Up = remove_cvref_t<invoke_result_t<_Func, const value_type&&>>;
static_assert(!is_array_v<_Up>, "Result of f(std::move(value())) should not be an Array");
diff --git a/libcxx/include/ostream b/libcxx/include/ostream
index d948d591c8f0..283774585b92 100644
--- a/libcxx/include/ostream
+++ b/libcxx/include/ostream
@@ -134,16 +134,20 @@ template <class Stream, class T>
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
#include <bitset>
#include <ios>
-#include <iterator>
#include <locale>
#include <streambuf>
#include <version>
+#ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES
+# include <iterator>
+#endif
+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -1094,9 +1098,9 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, const bitset<_Size>& __x)
use_facet<ctype<_CharT> >(__os.getloc()).widen('1'));
}
-_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ostream<char>)
+extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ostream<char>;
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ostream<wchar_t>)
+extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ostream<wchar_t>;
#endif
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/queue b/libcxx/include/queue
index 9e1257b25e0e..9a5cfb39f24e 100644
--- a/libcxx/include/queue
+++ b/libcxx/include/queue
@@ -217,20 +217,30 @@ template <class T, class Container, class Compare>
*/
+#include <__algorithm/make_heap.h>
+#include <__algorithm/pop_heap.h>
+#include <__algorithm/push_heap.h>
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
+#include <__functional/operations.h>
#include <__iterator/iterator_traits.h>
#include <__memory/uses_allocator.h>
#include <__utility/forward.h>
-#include <algorithm>
-#include <compare>
#include <deque>
-#include <functional>
#include <type_traits>
#include <vector>
#include <version>
+#ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES
+# include <functional>
+#endif
+
+// standard-mandated includes
+#include <compare>
+#include <initializer_list>
+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/random b/libcxx/include/random
index 2e271cec46ad..41ee4d85fda3 100644
--- a/libcxx/include/random
+++ b/libcxx/include/random
@@ -1677,6 +1677,7 @@ class piecewise_linear_distribution
} // std
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
#include <__random/bernoulli_distribution.h>
#include <__random/binomial_distribution.h>
@@ -1694,6 +1695,7 @@ class piecewise_linear_distribution
#include <__random/geometric_distribution.h>
#include <__random/independent_bits_engine.h>
#include <__random/is_seed_sequence.h>
+#include <__random/is_valid.h>
#include <__random/knuth_b.h>
#include <__random/linear_congruential_engine.h>
#include <__random/log2.h>
@@ -1714,10 +1716,15 @@ class piecewise_linear_distribution
#include <__random/uniform_random_bit_generator.h>
#include <__random/uniform_real_distribution.h>
#include <__random/weibull_distribution.h>
-#include <initializer_list>
#include <version>
-#include <algorithm> // for backward compatibility; TODO remove it
+#ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES
+# include <algorithm>
+#endif
+
+// standard-mandated includes
+#include <initializer_list>
+
#include <cmath> // for backward compatibility; TODO remove it
#include <cstddef> // for backward compatibility; TODO remove it
#include <cstdint> // for backward compatibility; TODO remove it
@@ -1729,7 +1736,7 @@ class piecewise_linear_distribution
#include <vector> // for backward compatibility; TODO remove it
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
#endif // _LIBCPP_RANDOM
diff --git a/libcxx/include/ranges b/libcxx/include/ranges
index f7c543d7316c..82378a6b0daa 100644
--- a/libcxx/include/ranges
+++ b/libcxx/include/ranges
@@ -120,6 +120,14 @@ namespace std::ranges {
requires is_object_v<T>
class empty_view;
+ template<class T>
+ inline constexpr bool enable_borrowed_range<empty_view<T>> = true;
+
+ namespace views {
+ template<class T>
+ inline constexpr empty_view<T> empty{};
+ }
+
// [range.all], all view
namespace views {
inline constexpr unspecified all = unspecified;
@@ -142,6 +150,15 @@ namespace std::ranges {
template<class T>
inline constexpr bool enable_borrowed_range<owning_view<T>> = enable_borrowed_range<T>;
+ // [range.filter], filter view
+ template<input_range V, indirect_unary_predicate<iterator_t<V>> Pred>
+ requires view<V> && is_object_v<Pred>
+ class filter_view;
+
+ namespace views {
+ inline constexpr unspecified filter = unspecified;
+ }
+
// [range.drop], drop view
template<view V>
class drop_view;
@@ -196,15 +213,66 @@ namespace std::ranges {
template<input_range V>
requires view<V> && input_range<range_reference_t<V>>
class join_view;
+
+ // [range.lazy.split], lazy split view
+ template<class R>
+ concept tiny-range = see below; // exposition only
+
+ template<input_range V, forward_range Pattern>
+ requires view<V> && view<Pattern> &&
+ indirectly_comparable<iterator_t<V>, iterator_t<Pattern>, ranges::equal_to> &&
+ (forward_range<V> || tiny-range<Pattern>)
+ class lazy_split_view;
+
+ namespace views {
+ inline constexpr unspecified lazy_split = unspecified;
+ }
+
+ // [range.zip], zip view
+ template<input_range... Views>
+ requires (view<Views> && ...) && (sizeof...(Views) > 0)
+ class zip_view; // C++2b
+
+ template<class... Views>
+ inline constexpr bool enable_borrowed_range<zip_view<Views...>> = // C++2b
+ (enable_borrowed_range<Views> && ...);
+
+ namespace views { inline constexpr unspecified zip = unspecified; } // C++2b
}
-*/
+namespace std {
+ namespace views = ranges::views;
-// Make sure all feature-test macros are available.
-#include <version>
-// Enable the contents of the header only when libc++ was built with LIBCXX_ENABLE_INCOMPLETE_FEATURES.
-#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+ template<class T> struct tuple_size;
+ template<size_t I, class T> struct tuple_element;
+
+ template<class I, class S, ranges::subrange_kind K>
+ struct tuple_size<ranges::subrange<I, S, K>>
+ : integral_constant<size_t, 2> {};
+
+ template<class I, class S, ranges::subrange_kind K>
+ struct tuple_element<0, ranges::subrange<I, S, K>> {
+ using type = I;
+ };
+
+ template<class I, class S, ranges::subrange_kind K>
+ struct tuple_element<1, ranges::subrange<I, S, K>> {
+ using type = S;
+ };
+
+ template<class I, class S, ranges::subrange_kind K>
+ struct tuple_element<0, const ranges::subrange<I, S, K>> {
+ using type = I;
+ };
+
+ template<class I, class S, ranges::subrange_kind K>
+ struct tuple_element<1, const ranges::subrange<I, S, K>> {
+ using type = S;
+ };
+}
+*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
#include <__ranges/access.h>
#include <__ranges/all.h>
@@ -218,9 +286,13 @@ namespace std::ranges {
#include <__ranges/empty_view.h>
#include <__ranges/enable_borrowed_range.h>
#include <__ranges/enable_view.h>
+#include <__ranges/filter_view.h>
#include <__ranges/iota_view.h>
#include <__ranges/join_view.h>
+#include <__ranges/lazy_split_view.h>
+#include <__ranges/rbegin.h>
#include <__ranges/ref_view.h>
+#include <__ranges/rend.h>
#include <__ranges/reverse_view.h>
#include <__ranges/single_view.h>
#include <__ranges/size.h>
@@ -228,25 +300,17 @@ namespace std::ranges {
#include <__ranges/take_view.h>
#include <__ranges/transform_view.h>
#include <__ranges/view_interface.h>
+#include <__ranges/views.h>
+#include <__ranges/zip_view.h>
+#include <__tuple> // TODO: <ranges> has to export std::tuple_size. Replace this, once <tuple> is granularized.
#include <compare> // Required by the standard.
#include <initializer_list> // Required by the standard.
#include <iterator> // Required by the standard.
#include <type_traits>
+#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
-
-namespace views = ranges::views;
-
-#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
-
-_LIBCPP_END_NAMESPACE_STD
-
-#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
-
#endif // _LIBCPP_RANGES
diff --git a/libcxx/include/ratio b/libcxx/include/ratio
index 8859261208d0..5d7af88a2ac8 100644
--- a/libcxx/include/ratio
+++ b/libcxx/include/ratio
@@ -77,6 +77,7 @@ typedef ratio<1000000000000000000000000, 1> yotta; // not supported
}
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
#include <climits>
#include <cstdint>
@@ -84,7 +85,7 @@ typedef ratio<1000000000000000000000000, 1> yotta; // not supported
#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
@@ -416,11 +417,11 @@ struct _LIBCPP_TEMPLATE_VIS ratio_subtract
template <class _R1, class _R2>
struct _LIBCPP_TEMPLATE_VIS ratio_equal
- : public _LIBCPP_BOOL_CONSTANT((_R1::num == _R2::num && _R1::den == _R2::den)) {};
+ : _BoolConstant<(_R1::num == _R2::num && _R1::den == _R2::den)> {};
template <class _R1, class _R2>
struct _LIBCPP_TEMPLATE_VIS ratio_not_equal
- : public _LIBCPP_BOOL_CONSTANT((!ratio_equal<_R1, _R2>::value)) {};
+ : _BoolConstant<!ratio_equal<_R1, _R2>::value> {};
// ratio_less
@@ -479,19 +480,19 @@ struct __ratio_less<_R1, _R2, -1LL, -1LL>
template <class _R1, class _R2>
struct _LIBCPP_TEMPLATE_VIS ratio_less
- : public _LIBCPP_BOOL_CONSTANT((__ratio_less<_R1, _R2>::value)) {};
+ : _BoolConstant<__ratio_less<_R1, _R2>::value> {};
template <class _R1, class _R2>
struct _LIBCPP_TEMPLATE_VIS ratio_less_equal
- : public _LIBCPP_BOOL_CONSTANT((!ratio_less<_R2, _R1>::value)) {};
+ : _BoolConstant<!ratio_less<_R2, _R1>::value> {};
template <class _R1, class _R2>
struct _LIBCPP_TEMPLATE_VIS ratio_greater
- : public _LIBCPP_BOOL_CONSTANT((ratio_less<_R2, _R1>::value)) {};
+ : _BoolConstant<ratio_less<_R2, _R1>::value> {};
template <class _R1, class _R2>
struct _LIBCPP_TEMPLATE_VIS ratio_greater_equal
- : public _LIBCPP_BOOL_CONSTANT((!ratio_less<_R1, _R2>::value)) {};
+ : _BoolConstant<!ratio_less<_R1, _R2>::value> {};
template <class _R1, class _R2>
struct __ratio_gcd
diff --git a/libcxx/include/regex b/libcxx/include/regex
index 59b2c9a23399..a117c50f3984 100644
--- a/libcxx/include/regex
+++ b/libcxx/include/regex
@@ -762,23 +762,42 @@ typedef regex_token_iterator<wstring::const_iterator> wsregex_token_iterator;
} // std
*/
+#include <__algorithm/find.h>
+#include <__algorithm/search.h>
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
-#include <__debug>
+#include <__iterator/back_insert_iterator.h>
#include <__iterator/wrap_iter.h>
#include <__locale>
-#include <compare>
+#include <__utility/move.h>
+#include <__utility/swap.h>
#include <deque>
-#include <initializer_list>
-#include <iterator>
#include <memory>
#include <stdexcept>
#include <string>
-#include <utility>
#include <vector>
#include <version>
+#ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES
+# include <iterator>
+# include <utility>
+#endif
+
+// standard-mandated includes
+
+// [iterator.range]
+#include <__iterator/access.h>
+#include <__iterator/data.h>
+#include <__iterator/empty.h>
+#include <__iterator/reverse_access.h>
+#include <__iterator/size.h>
+
+// [re.syn]
+#include <compare>
+#include <initializer_list>
+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
@@ -2093,14 +2112,14 @@ class __r_anchor_multiline
{
typedef __owns_one_state<_CharT> base;
- bool __multiline;
+ bool __multiline_;
public:
typedef _VSTD::__state<_CharT> __state;
_LIBCPP_INLINE_VISIBILITY
__r_anchor_multiline(bool __multiline, __node<_CharT>* __s)
- : base(__s), __multiline(__multiline) {}
+ : base(__s), __multiline_(__multiline) {}
virtual void __exec(__state&) const;
};
@@ -2115,7 +2134,7 @@ __r_anchor_multiline<_CharT>::__exec(__state& __s) const
__s.__do_ = __state::__accept_but_not_consume;
__s.__node_ = this->first();
}
- else if (__multiline && __is_eol(*__s.__current_))
+ else if (__multiline_ && __is_eol(*__s.__current_))
{
__s.__do_ = __state::__accept_but_not_consume;
__s.__node_ = this->first();
diff --git a/libcxx/include/scoped_allocator b/libcxx/include/scoped_allocator
index 2b15655e2c0a..b505aad9dcf7 100644
--- a/libcxx/include/scoped_allocator
+++ b/libcxx/include/scoped_allocator
@@ -109,13 +109,14 @@ template <class OuterA1, class OuterA2, class... InnerAllocs>
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
#include <__utility/forward.h>
#include <memory>
#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/semaphore b/libcxx/include/semaphore
index 7dffc94b13ba..228cf773f0fd 100644
--- a/libcxx/include/semaphore
+++ b/libcxx/include/semaphore
@@ -45,19 +45,22 @@ using binary_semaphore = counting_semaphore<1>;
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__availability>
+#include <__chrono/time_point.h>
#include <__config>
#include <__thread/timed_backoff_policy.h>
#include <__threading_support>
#include <atomic>
+#include <limits>
#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
#ifdef _LIBCPP_HAS_NO_THREADS
-# error <semaphore> is not supported on this single threaded system
+# error "<semaphore> is not supported since libc++ has been configured without support for threads."
#endif
_LIBCPP_PUSH_MACROS
diff --git a/libcxx/include/set b/libcxx/include/set
index 803175296a34..da62f6f5ca5b 100644
--- a/libcxx/include/set
+++ b/libcxx/include/set
@@ -471,21 +471,40 @@ erase_if(multiset<Key, Compare, Allocator>& c, Predicate pred); // C++20
*/
+#include <__algorithm/equal.h>
+#include <__algorithm/lexicographical_compare.h>
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
-#include <__debug>
#include <__functional/is_transparent.h>
+#include <__functional/operations.h>
+#include <__iterator/erase_if_container.h>
#include <__iterator/iterator_traits.h>
+#include <__iterator/reverse_iterator.h>
#include <__node_handle>
#include <__tree>
#include <__utility/forward.h>
+#include <version>
+
+#ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES
+# include <functional>
+# include <iterator>
+#endif
+
+// standard-mandated includes
+
+// [iterator.range]
+#include <__iterator/access.h>
+#include <__iterator/data.h>
+#include <__iterator/empty.h>
+#include <__iterator/reverse_access.h>
+#include <__iterator/size.h>
+
+// [associative.set.syn]
#include <compare>
-#include <functional>
#include <initializer_list>
-#include <iterator> // __libcpp_erase_if_container
-#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -501,9 +520,9 @@ public:
// types:
typedef _Key key_type;
typedef key_type value_type;
- typedef __identity_t<_Compare> key_compare;
+ typedef __type_identity_t<_Compare> key_compare;
typedef key_compare value_compare;
- typedef __identity_t<_Allocator> allocator_type;
+ typedef __type_identity_t<_Allocator> allocator_type;
typedef value_type& reference;
typedef const value_type& const_reference;
@@ -1034,9 +1053,9 @@ public:
// types:
typedef _Key key_type;
typedef key_type value_type;
- typedef __identity_t<_Compare> key_compare;
+ typedef __type_identity_t<_Compare> key_compare;
typedef key_compare value_compare;
- typedef __identity_t<_Allocator> allocator_type;
+ typedef __type_identity_t<_Allocator> allocator_type;
typedef value_type& reference;
typedef const value_type& const_reference;
diff --git a/libcxx/include/setjmp.h b/libcxx/include/setjmp.h
index 3ecaeca720cd..de4f9edf4886 100644
--- a/libcxx/include/setjmp.h
+++ b/libcxx/include/setjmp.h
@@ -28,7 +28,7 @@ void longjmp(jmp_buf env, int val);
#include <__config>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
#include_next <setjmp.h>
diff --git a/libcxx/include/shared_mutex b/libcxx/include/shared_mutex
index f866443b8e25..a089aa9fa817 100644
--- a/libcxx/include/shared_mutex
+++ b/libcxx/include/shared_mutex
@@ -122,6 +122,7 @@ template <class Mutex>
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__availability>
#include <__config>
#include <version>
@@ -135,12 +136,12 @@ _LIBCPP_PUSH_MACROS
#include <__mutex_base>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
#ifdef _LIBCPP_HAS_NO_THREADS
-#error <shared_mutex> is not supported on this single threaded system
-#else // !_LIBCPP_HAS_NO_THREADS
+# error "<shared_mutex> is not supported since libc++ has been configured without support for threads."
+#endif
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -500,8 +501,6 @@ swap(shared_lock<_Mutex>& __x, shared_lock<_Mutex>& __y) _NOEXCEPT
_LIBCPP_END_NAMESPACE_STD
-#endif // !_LIBCPP_HAS_NO_THREADS
-
#endif // _LIBCPP_STD_VER > 11
_LIBCPP_POP_MACROS
diff --git a/libcxx/include/span b/libcxx/include/span
index bd11330e69d9..00793a210cbe 100644
--- a/libcxx/include/span
+++ b/libcxx/include/span
@@ -127,24 +127,43 @@ template<class R>
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
#include <__debug>
+#include <__fwd/span.h>
+#include <__iterator/bounded_iter.h>
#include <__iterator/concepts.h>
+#include <__iterator/iterator_traits.h>
#include <__iterator/wrap_iter.h>
+#include <__memory/pointer_traits.h>
#include <__ranges/concepts.h>
#include <__ranges/data.h>
#include <__ranges/enable_borrowed_range.h>
#include <__ranges/enable_view.h>
#include <__ranges/size.h>
+#include <__utility/forward.h>
#include <array> // for array
#include <cstddef> // for byte
-#include <iterator> // for iterators
#include <limits>
#include <type_traits> // for remove_cv, etc
#include <version>
+#ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES
+# include <functional>
+# include <iterator>
+#endif
+
+// standard-mandated includes
+
+// [iterator.range]
+#include <__iterator/access.h>
+#include <__iterator/data.h>
+#include <__iterator/empty.h>
+#include <__iterator/reverse_access.h>
+#include <__iterator/size.h>
+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
@@ -154,10 +173,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER > 17
-inline constexpr size_t dynamic_extent = numeric_limits<size_t>::max();
-template <typename _Tp, size_t _Extent = dynamic_extent> class span;
-
-
template <class _Tp>
struct __is_std_array : false_type {};
@@ -170,7 +185,23 @@ struct __is_std_span : false_type {};
template <class _Tp, size_t _Sz>
struct __is_std_span<span<_Tp, _Sz>> : true_type {};
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+// This is a temporary workaround until we ship <ranges> -- we've unfortunately been
+// shipping <span> before its API was finalized, and we used to provide a constructor
+// from container types that had the requirements below. To avoid breaking code that
+// has started relying on the range-based constructor until we ship all of <ranges>,
+// we emulate the constructor requirements like this.
+template <class _Range, class _ElementType>
+concept __span_compatible_range =
+ !__is_std_span<remove_cvref_t<_Range>>::value &&
+ !__is_std_array<remove_cvref_t<_Range>>::value &&
+ !is_array_v<remove_cvref_t<_Range>> &&
+ requires (_Range&& __r) {
+ data(std::forward<_Range>(__r));
+ size(std::forward<_Range>(__r));
+ } &&
+ is_convertible_v<remove_reference_t<ranges::range_reference_t<_Range>>(*)[], _ElementType(*)[]>;
+#else
template <class _Range, class _ElementType>
concept __span_compatible_range =
ranges::contiguous_range<_Range> &&
@@ -180,7 +211,16 @@ concept __span_compatible_range =
!__is_std_array<remove_cvref_t<_Range>>::value &&
!is_array_v<remove_cvref_t<_Range>> &&
is_convertible_v<remove_reference_t<ranges::range_reference_t<_Range>>(*)[], _ElementType(*)[]>;
-#endif
+#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+template <class _From, class _To>
+concept __span_array_convertible = is_convertible_v<_From(*)[], _To(*)[]>;
+
+template <class _It, class _Tp>
+concept __span_compatible_iterator = contiguous_iterator<_It> && __span_array_convertible<remove_reference_t<iter_reference_t<_It>>, _Tp>;
+
+template <class _Sentinel, class _It>
+concept __span_compatible_sentinel_for = sized_sentinel_for<_Sentinel, _It> && !is_convertible_v<_Sentinel, size_t>;
template <typename _Tp, size_t _Extent>
class _LIBCPP_TEMPLATE_VIS span {
@@ -194,8 +234,8 @@ public:
using const_pointer = const _Tp *;
using reference = _Tp &;
using const_reference = const _Tp &;
-#if (_LIBCPP_DEBUG_LEVEL == 2) || defined(_LIBCPP_ABI_SPAN_POINTER_ITERATORS)
- using iterator = pointer;
+#ifdef _LIBCPP_ENABLE_DEBUG_MODE
+ using iterator = __bounded_iter<pointer>;
#else
using iterator = __wrap_iter<pointer>;
#endif
@@ -204,17 +244,13 @@ public:
static constexpr size_type extent = _Extent;
// [span.cons], span constructors, copy, assignment, and destructor
- template <size_t _Sz = _Extent, enable_if_t<_Sz == 0, nullptr_t> = nullptr>
+ template <size_t _Sz = _Extent> requires(_Sz == 0)
_LIBCPP_INLINE_VISIBILITY constexpr span() noexcept : __data{nullptr} {}
constexpr span (const span&) noexcept = default;
constexpr span& operator=(const span&) noexcept = default;
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
- template <class _It,
- enable_if_t<contiguous_iterator<_It> &&
- is_convertible_v<remove_reference_t<iter_reference_t<_It>>(*)[], element_type (*)[]>,
- nullptr_t> = nullptr>
+ template <__span_compatible_iterator<element_type> _It>
_LIBCPP_INLINE_VISIBILITY
constexpr explicit span(_It __first, size_type __count)
: __data{_VSTD::to_address(__first)} {
@@ -222,11 +258,7 @@ public:
_LIBCPP_ASSERT(_Extent == __count, "size mismatch in span's constructor (iterator, len)");
}
- template <
- class _It, class _End,
- enable_if_t<is_convertible_v<remove_reference_t<iter_reference_t<_It> > (*)[], element_type (*)[]> &&
- contiguous_iterator<_It> && sized_sentinel_for<_End, _It> && !is_convertible_v<_End, size_t>,
- nullptr_t> = nullptr>
+ template <__span_compatible_iterator<element_type> _It, __span_compatible_sentinel_for<_It> _End>
_LIBCPP_INLINE_VISIBILITY
constexpr explicit span(_It __first, _End __last) : __data{_VSTD::to_address(__first)} {
(void)__last;
@@ -234,21 +266,32 @@ public:
_LIBCPP_ASSERT(__last - __first == _Extent,
"invalid range in span's constructor (iterator, sentinel): last - first != extent");
}
-#endif
_LIBCPP_INLINE_VISIBILITY constexpr span(type_identity_t<element_type> (&__arr)[_Extent]) noexcept : __data{__arr} {}
- template <class _OtherElementType,
- enable_if_t<is_convertible_v<_OtherElementType(*)[], element_type (*)[]>, nullptr_t> = nullptr>
+ template <__span_array_convertible<element_type> _OtherElementType>
_LIBCPP_INLINE_VISIBILITY
constexpr span(array<_OtherElementType, _Extent>& __arr) noexcept : __data{__arr.data()} {}
- template <class _OtherElementType,
- enable_if_t<is_convertible_v<const _OtherElementType(*)[], element_type (*)[]>, nullptr_t> = nullptr>
+ template <class _OtherElementType>
+ requires __span_array_convertible<const _OtherElementType, element_type>
_LIBCPP_INLINE_VISIBILITY
constexpr span(const array<_OtherElementType, _Extent>& __arr) noexcept : __data{__arr.data()} {}
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+ template <class _Container>
+ requires __span_compatible_range<_Container, element_type>
+ _LIBCPP_INLINE_VISIBILITY
+ constexpr explicit span(_Container& __c) : __data{std::data(__c)} {
+ _LIBCPP_ASSERT(std::size(__c) == _Extent, "size mismatch in span's constructor (range)");
+ }
+ template <class _Container>
+ requires __span_compatible_range<const _Container, element_type>
+ _LIBCPP_INLINE_VISIBILITY
+ constexpr explicit span(const _Container& __c) : __data{std::data(__c)} {
+ _LIBCPP_ASSERT(std::size(__c) == _Extent, "size mismatch in span's constructor (range)");
+ }
+#else
template <__span_compatible_range<element_type> _Range>
_LIBCPP_INLINE_VISIBILITY
constexpr explicit span(_Range&& __r) : __data{ranges::data(__r)} {
@@ -256,20 +299,14 @@ public:
}
#endif
- template <class _OtherElementType>
+ template <__span_array_convertible<element_type> _OtherElementType>
_LIBCPP_INLINE_VISIBILITY
- constexpr span(const span<_OtherElementType, _Extent>& __other,
- enable_if_t<
- is_convertible_v<_OtherElementType(*)[], element_type (*)[]>,
- nullptr_t> = nullptr)
+ constexpr span(const span<_OtherElementType, _Extent>& __other)
: __data{__other.data()} {}
- template <class _OtherElementType>
+ template <__span_array_convertible<element_type> _OtherElementType>
_LIBCPP_INLINE_VISIBILITY
- constexpr explicit span(const span<_OtherElementType, dynamic_extent>& __other,
- enable_if_t<
- is_convertible_v<_OtherElementType(*)[], element_type (*)[]>,
- nullptr_t> = nullptr) noexcept
+ constexpr explicit span(const span<_OtherElementType, dynamic_extent>& __other) noexcept
: __data{__other.data()} { _LIBCPP_ASSERT(_Extent == __other.size(), "size mismatch in span's constructor (other span)"); }
@@ -279,7 +316,7 @@ public:
_LIBCPP_INLINE_VISIBILITY
constexpr span<element_type, _Count> first() const noexcept
{
- static_assert(_Count <= _Extent, "Count out of range in span::first()");
+ static_assert(_Count <= _Extent, "span<T, N>::first<Count>(): Count out of range");
return span<element_type, _Count>{data(), _Count};
}
@@ -287,21 +324,21 @@ public:
_LIBCPP_INLINE_VISIBILITY
constexpr span<element_type, _Count> last() const noexcept
{
- static_assert(_Count <= _Extent, "Count out of range in span::last()");
+ static_assert(_Count <= _Extent, "span<T, N>::last<Count>(): Count out of range");
return span<element_type, _Count>{data() + size() - _Count, _Count};
}
_LIBCPP_INLINE_VISIBILITY
constexpr span<element_type, dynamic_extent> first(size_type __count) const noexcept
{
- _LIBCPP_ASSERT(__count <= size(), "Count out of range in span::first(count)");
+ _LIBCPP_ASSERT(__count <= size(), "span<T, N>::first(count): count out of range");
return {data(), __count};
}
_LIBCPP_INLINE_VISIBILITY
constexpr span<element_type, dynamic_extent> last(size_type __count) const noexcept
{
- _LIBCPP_ASSERT(__count <= size(), "Count out of range in span::last(count)");
+ _LIBCPP_ASSERT(__count <= size(), "span<T, N>::last(count): count out of range");
return {data() + size() - __count, __count};
}
@@ -310,8 +347,8 @@ public:
constexpr auto subspan() const noexcept
-> span<element_type, _Count != dynamic_extent ? _Count : _Extent - _Offset>
{
- static_assert(_Offset <= _Extent, "Offset out of range in span::subspan()");
- static_assert(_Count == dynamic_extent || _Count <= _Extent - _Offset, "Offset + count out of range in span::subspan()");
+ 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");
using _ReturnType = span<element_type, _Count != dynamic_extent ? _Count : _Extent - _Offset>;
return _ReturnType{data() + _Offset, _Count == dynamic_extent ? size() - _Offset : _Count};
@@ -322,11 +359,11 @@ public:
constexpr span<element_type, dynamic_extent>
subspan(size_type __offset, size_type __count = dynamic_extent) const noexcept
{
- _LIBCPP_ASSERT(__offset <= size(), "Offset out of range in span::subspan(offset, count)");
- _LIBCPP_ASSERT(__count <= size() || __count == dynamic_extent, "Count out of range in span::subspan(offset, count)");
+ _LIBCPP_ASSERT(__offset <= size(), "span<T, N>::subspan(offset, count): offset out of range");
+ _LIBCPP_ASSERT(__count <= size() || __count == dynamic_extent, "span<T, N>::subspan(offset, count): count out of range");
if (__count == dynamic_extent)
return {data() + __offset, size() - __offset};
- _LIBCPP_ASSERT(__count <= size() - __offset, "Offset + count out of range in span::subspan(offset, count)");
+ _LIBCPP_ASSERT(__count <= size() - __offset, "span<T, N>::subspan(offset, count): offset + count out of range");
return {data() + __offset, __count};
}
@@ -336,7 +373,7 @@ public:
_LIBCPP_INLINE_VISIBILITY constexpr reference operator[](size_type __idx) const noexcept
{
- _LIBCPP_ASSERT(__idx < size(), "span<T,N>[] index out of bounds");
+ _LIBCPP_ASSERT(__idx < size(), "span<T, N>::operator[](index): index out of range");
return __data[__idx];
}
@@ -355,8 +392,20 @@ public:
_LIBCPP_INLINE_VISIBILITY constexpr pointer data() const noexcept { return __data; }
// [span.iter], span iterator support
- _LIBCPP_INLINE_VISIBILITY constexpr iterator begin() const noexcept { return iterator(data()); }
- _LIBCPP_INLINE_VISIBILITY constexpr iterator end() const noexcept { return iterator(data() + size()); }
+ _LIBCPP_INLINE_VISIBILITY constexpr iterator begin() const noexcept {
+#ifdef _LIBCPP_ENABLE_DEBUG_MODE
+ return std::__make_bounded_iter(data(), data(), data() + size());
+#else
+ return iterator(this, data());
+#endif
+ }
+ _LIBCPP_INLINE_VISIBILITY constexpr iterator end() const noexcept {
+#ifdef _LIBCPP_ENABLE_DEBUG_MODE
+ return std::__make_bounded_iter(data() + size(), data(), data() + size());
+#else
+ return iterator(this, data() + size());
+#endif
+ }
_LIBCPP_INLINE_VISIBILITY constexpr reverse_iterator rbegin() const noexcept { return reverse_iterator(end()); }
_LIBCPP_INLINE_VISIBILITY constexpr reverse_iterator rend() const noexcept { return reverse_iterator(begin()); }
@@ -368,14 +417,11 @@ public:
private:
pointer __data;
-
};
template <typename _Tp>
class _LIBCPP_TEMPLATE_VIS span<_Tp, dynamic_extent> {
-private:
-
public:
// constants and types
using element_type = _Tp;
@@ -386,8 +432,8 @@ public:
using const_pointer = const _Tp *;
using reference = _Tp &;
using const_reference = const _Tp &;
-#if (_LIBCPP_DEBUG_LEVEL == 2) || defined(_LIBCPP_ABI_SPAN_POINTER_ITERATORS)
- using iterator = pointer;
+#ifdef _LIBCPP_ENABLE_DEBUG_MODE
+ using iterator = __bounded_iter<pointer>;
#else
using iterator = __wrap_iter<pointer>;
#endif
@@ -401,51 +447,47 @@ public:
constexpr span (const span&) noexcept = default;
constexpr span& operator=(const span&) noexcept = default;
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
- template <class _It,
- enable_if_t<contiguous_iterator<_It> &&
- is_convertible_v<remove_reference_t<iter_reference_t<_It> > (*)[], element_type (*)[]>,
- nullptr_t> = nullptr>
+ template <__span_compatible_iterator<element_type> _It>
_LIBCPP_INLINE_VISIBILITY
constexpr span(_It __first, size_type __count)
: __data{_VSTD::to_address(__first)}, __size{__count} {}
- template <
- class _It, class _End,
- enable_if_t<is_convertible_v<remove_reference_t<iter_reference_t<_It> > (*)[], element_type (*)[]> &&
- contiguous_iterator<_It> && sized_sentinel_for<_End, _It> && !is_convertible_v<_End, size_t>,
- nullptr_t> = nullptr>
+ template <__span_compatible_iterator<element_type> _It, __span_compatible_sentinel_for<_It> _End>
_LIBCPP_INLINE_VISIBILITY
constexpr span(_It __first, _End __last)
: __data(_VSTD::to_address(__first)), __size(__last - __first) {}
-#endif
template <size_t _Sz>
_LIBCPP_INLINE_VISIBILITY
constexpr span(type_identity_t<element_type> (&__arr)[_Sz]) noexcept : __data{__arr}, __size{_Sz} {}
- template <class _OtherElementType, size_t _Sz,
- enable_if_t<is_convertible_v<_OtherElementType(*)[], element_type (*)[]>, nullptr_t> = nullptr>
+ template <__span_array_convertible<element_type> _OtherElementType, size_t _Sz>
_LIBCPP_INLINE_VISIBILITY
constexpr span(array<_OtherElementType, _Sz>& __arr) noexcept : __data{__arr.data()}, __size{_Sz} {}
- template <class _OtherElementType, size_t _Sz,
- enable_if_t<is_convertible_v<const _OtherElementType(*)[], element_type (*)[]>, nullptr_t> = nullptr>
+ template <class _OtherElementType, size_t _Sz>
+ requires __span_array_convertible<const _OtherElementType, element_type>
_LIBCPP_INLINE_VISIBILITY
constexpr span(const array<_OtherElementType, _Sz>& __arr) noexcept : __data{__arr.data()}, __size{_Sz} {}
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+ template <class _Container>
+ requires __span_compatible_range<_Container, element_type>
+ _LIBCPP_INLINE_VISIBILITY
+ constexpr span(_Container& __c) : __data(std::data(__c)), __size{std::size(__c)} {}
+ template <class _Container>
+ requires __span_compatible_range<const _Container, element_type>
+ _LIBCPP_INLINE_VISIBILITY
+ constexpr span(const _Container& __c) : __data(std::data(__c)), __size{std::size(__c)} {}
+#else
template <__span_compatible_range<element_type> _Range>
_LIBCPP_INLINE_VISIBILITY
constexpr span(_Range&& __r) : __data(ranges::data(__r)), __size{ranges::size(__r)} {}
-# endif
+#endif
- template <class _OtherElementType, size_t _OtherExtent>
+ template <__span_array_convertible<element_type> _OtherElementType, size_t _OtherExtent>
_LIBCPP_INLINE_VISIBILITY
- constexpr span(const span<_OtherElementType, _OtherExtent>& __other,
- enable_if_t<
- is_convertible_v<_OtherElementType(*)[], element_type (*)[]>,
- nullptr_t> = nullptr) noexcept
+ constexpr span(const span<_OtherElementType, _OtherExtent>& __other) noexcept
: __data{__other.data()}, __size{__other.size()} {}
// ~span() noexcept = default;
@@ -454,7 +496,7 @@ public:
_LIBCPP_INLINE_VISIBILITY
constexpr span<element_type, _Count> first() const noexcept
{
- _LIBCPP_ASSERT(_Count <= size(), "Count out of range in span::first()");
+ _LIBCPP_ASSERT(_Count <= size(), "span<T>::first<Count>(): Count out of range");
return span<element_type, _Count>{data(), _Count};
}
@@ -462,21 +504,21 @@ public:
_LIBCPP_INLINE_VISIBILITY
constexpr span<element_type, _Count> last() const noexcept
{
- _LIBCPP_ASSERT(_Count <= size(), "Count out of range in span::last()");
+ _LIBCPP_ASSERT(_Count <= size(), "span<T>::last<Count>(): Count out of range");
return span<element_type, _Count>{data() + size() - _Count, _Count};
}
_LIBCPP_INLINE_VISIBILITY
constexpr span<element_type, dynamic_extent> first(size_type __count) const noexcept
{
- _LIBCPP_ASSERT(__count <= size(), "Count out of range in span::first(count)");
+ _LIBCPP_ASSERT(__count <= size(), "span<T>::first(count): count out of range");
return {data(), __count};
}
_LIBCPP_INLINE_VISIBILITY
constexpr span<element_type, dynamic_extent> last (size_type __count) const noexcept
{
- _LIBCPP_ASSERT(__count <= size(), "Count out of range in span::last(count)");
+ _LIBCPP_ASSERT(__count <= size(), "span<T>::last(count): count out of range");
return {data() + size() - __count, __count};
}
@@ -484,8 +526,8 @@ public:
_LIBCPP_INLINE_VISIBILITY
constexpr span<element_type, _Count> subspan() const noexcept
{
- _LIBCPP_ASSERT(_Offset <= size(), "Offset out of range in span::subspan()");
- _LIBCPP_ASSERT(_Count == dynamic_extent || _Count <= size() - _Offset, "Offset + count out of range in span::subspan()");
+ _LIBCPP_ASSERT(_Offset <= size(), "span<T>::subspan<Offset, Count>(): Offset out of range");
+ _LIBCPP_ASSERT(_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};
}
@@ -493,11 +535,11 @@ public:
_LIBCPP_INLINE_VISIBILITY
subspan(size_type __offset, size_type __count = dynamic_extent) const noexcept
{
- _LIBCPP_ASSERT(__offset <= size(), "Offset out of range in span::subspan(offset, count)");
- _LIBCPP_ASSERT(__count <= size() || __count == dynamic_extent, "count out of range in span::subspan(offset, count)");
+ _LIBCPP_ASSERT(__offset <= size(), "span<T>::subspan(offset, count): offset out of range");
+ _LIBCPP_ASSERT(__count <= size() || __count == dynamic_extent, "span<T>::subspan(offset, count): count out of range");
if (__count == dynamic_extent)
return {data() + __offset, size() - __offset};
- _LIBCPP_ASSERT(__count <= size() - __offset, "Offset + count out of range in span::subspan(offset, count)");
+ _LIBCPP_ASSERT(__count <= size() - __offset, "span<T>::subspan(offset, count): offset + count out of range");
return {data() + __offset, __count};
}
@@ -507,19 +549,19 @@ public:
_LIBCPP_INLINE_VISIBILITY constexpr reference operator[](size_type __idx) const noexcept
{
- _LIBCPP_ASSERT(__idx < size(), "span<T>[] index out of bounds");
+ _LIBCPP_ASSERT(__idx < size(), "span<T>::operator[](index): index out of range");
return __data[__idx];
}
_LIBCPP_INLINE_VISIBILITY constexpr reference front() const noexcept
{
- _LIBCPP_ASSERT(!empty(), "span<T>[].front() on empty span");
+ _LIBCPP_ASSERT(!empty(), "span<T>::front() on empty span");
return __data[0];
}
_LIBCPP_INLINE_VISIBILITY constexpr reference back() const noexcept
{
- _LIBCPP_ASSERT(!empty(), "span<T>[].back() on empty span");
+ _LIBCPP_ASSERT(!empty(), "span<T>::back() on empty span");
return __data[size()-1];
}
@@ -527,8 +569,20 @@ public:
_LIBCPP_INLINE_VISIBILITY constexpr pointer data() const noexcept { return __data; }
// [span.iter], span iterator support
- _LIBCPP_INLINE_VISIBILITY constexpr iterator begin() const noexcept { return iterator(data()); }
- _LIBCPP_INLINE_VISIBILITY constexpr iterator end() const noexcept { return iterator(data() + size()); }
+ _LIBCPP_INLINE_VISIBILITY constexpr iterator begin() const noexcept {
+#ifdef _LIBCPP_ENABLE_DEBUG_MODE
+ return std::__make_bounded_iter(data(), data(), data() + size());
+#else
+ return iterator(this, data());
+#endif
+ }
+ _LIBCPP_INLINE_VISIBILITY constexpr iterator end() const noexcept {
+#ifdef _LIBCPP_ENABLE_DEBUG_MODE
+ return std::__make_bounded_iter(data() + size(), data(), data() + size());
+#else
+ return iterator(this, data() + size());
+#endif
+ }
_LIBCPP_INLINE_VISIBILITY constexpr reverse_iterator rbegin() const noexcept { return reverse_iterator(end()); }
_LIBCPP_INLINE_VISIBILITY constexpr reverse_iterator rend() const noexcept { return reverse_iterator(begin()); }
@@ -543,32 +597,27 @@ private:
size_type __size;
};
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
template <class _Tp, size_t _Extent>
inline constexpr bool ranges::enable_borrowed_range<span<_Tp, _Extent> > = true;
template <class _ElementType, size_t _Extent>
inline constexpr bool ranges::enable_view<span<_ElementType, _Extent>> = true;
-#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
// as_bytes & as_writable_bytes
template <class _Tp, size_t _Extent>
_LIBCPP_INLINE_VISIBILITY
auto as_bytes(span<_Tp, _Extent> __s) noexcept
--> decltype(__s.__as_bytes())
-{ return __s.__as_bytes(); }
+{ return __s.__as_bytes(); }
-template <class _Tp, size_t _Extent>
+template <class _Tp, size_t _Extent> requires(!is_const_v<_Tp>)
_LIBCPP_INLINE_VISIBILITY
auto as_writable_bytes(span<_Tp, _Extent> __s) noexcept
--> enable_if_t<!is_const_v<_Tp>, decltype(__s.__as_writable_bytes())>
{ return __s.__as_writable_bytes(); }
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
-// Deduction guides
+#if _LIBCPP_STD_VER > 17
template<contiguous_iterator _It, class _EndOrSize>
span(_It, _EndOrSize) -> span<remove_reference_t<iter_reference_t<_It>>>;
-#endif
+#endif // _LIBCPP_STD_VER > 17
template<class _Tp, size_t _Sz>
span(_Tp (&)[_Sz]) -> span<_Tp, _Sz>;
@@ -579,7 +628,13 @@ template<class _Tp, size_t _Sz>
template<class _Tp, size_t _Sz>
span(const array<_Tp, _Sz>&) -> span<const _Tp, _Sz>;
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+template<class _Container>
+ span(_Container&) -> span<typename _Container::value_type>;
+
+template<class _Container>
+ span(const _Container&) -> span<const typename _Container::value_type>;
+#else
template<ranges::contiguous_range _Range>
span(_Range&&) -> span<remove_reference_t<ranges::range_reference_t<_Range>>>;
#endif
diff --git a/libcxx/include/sstream b/libcxx/include/sstream
index 6ad624a93a65..602a1b55b4a9 100644
--- a/libcxx/include/sstream
+++ b/libcxx/include/sstream
@@ -180,14 +180,16 @@ typedef basic_stringstream<wchar_t> wstringstream;
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
+#include <__utility/swap.h>
#include <istream>
#include <ostream>
#include <string>
#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
@@ -859,10 +861,10 @@ swap(basic_stringstream<_CharT, _Traits, _Allocator>& __x,
}
#if defined(_LIBCPP_ABI_ENABLE_ADDITIONAL_IOSTREAM_EXPLICIT_INSTANTIATIONS_1)
-_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_stringbuf<char>)
-_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_stringstream<char>)
-_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ostringstream<char>)
-_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_istringstream<char>)
+extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_stringbuf<char>;
+extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_stringstream<char>;
+extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ostringstream<char>;
+extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_istringstream<char>;
#endif
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/stack b/libcxx/include/stack
index ad65d7b29b4f..86435c4559de 100644
--- a/libcxx/include/stack
+++ b/libcxx/include/stack
@@ -98,6 +98,7 @@ template <class T, class Container>
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
#include <__iterator/iterator_traits.h>
#include <__memory/uses_allocator.h>
@@ -106,8 +107,16 @@ template <class T, class Container>
#include <type_traits>
#include <version>
+#ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES
+# include <functional>
+#endif
+
+// standard-mandated includes
+#include <compare>
+#include <initializer_list>
+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/stdatomic.h b/libcxx/include/stdatomic.h
new file mode 100644
index 000000000000..d9550c44061c
--- /dev/null
+++ b/libcxx/include/stdatomic.h
@@ -0,0 +1,235 @@
+// -*- 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_STDATOMIC_H
+#define _LIBCPP_STDATOMIC_H
+
+/*
+ stdatomic.h synopsis
+
+template<class T>
+ using std-atomic = std::atomic<T>; // exposition only
+
+#define _Atomic(T) std-atomic<T>
+
+#define ATOMIC_BOOL_LOCK_FREE see below
+#define ATOMIC_CHAR_LOCK_FREE see below
+#define ATOMIC_CHAR16_T_LOCK_FREE see below
+#define ATOMIC_CHAR32_T_LOCK_FREE see below
+#define ATOMIC_WCHAR_T_LOCK_FREE see below
+#define ATOMIC_SHORT_LOCK_FREE see below
+#define ATOMIC_INT_LOCK_FREE see below
+#define ATOMIC_LONG_LOCK_FREE see below
+#define ATOMIC_LLONG_LOCK_FREE see below
+#define ATOMIC_POINTER_LOCK_FREE see below
+
+using std::memory_order // see below
+using std::memory_order_relaxed // see below
+using std::memory_order_consume // see below
+using std::memory_order_acquire // see below
+using std::memory_order_release // see below
+using std::memory_order_acq_rel // see below
+using std::memory_order_seq_cst // see below
+
+using std::atomic_flag // see below
+
+using std::atomic_bool // see below
+using std::atomic_char // see below
+using std::atomic_schar // see below
+using std::atomic_uchar // see below
+using std::atomic_short // see below
+using std::atomic_ushort // see below
+using std::atomic_int // see below
+using std::atomic_uint // see below
+using std::atomic_long // see below
+using std::atomic_ulong // see below
+using std::atomic_llong // see below
+using std::atomic_ullong // see below
+using std::atomic_char8_t // see below
+using std::atomic_char16_t // see below
+using std::atomic_char32_t // see below
+using std::atomic_wchar_t // see below
+using std::atomic_int8_t // see below
+using std::atomic_uint8_t // see below
+using std::atomic_int16_t // see below
+using std::atomic_uint16_t // see below
+using std::atomic_int32_t // see below
+using std::atomic_uint32_t // see below
+using std::atomic_int64_t // see below
+using std::atomic_uint64_t // see below
+using std::atomic_int_least8_t // see below
+using std::atomic_uint_least8_t // see below
+using std::atomic_int_least16_t // see below
+using std::atomic_uint_least16_t // see below
+using std::atomic_int_least32_t // see below
+using std::atomic_uint_least32_t // see below
+using std::atomic_int_least64_t // see below
+using std::atomic_uint_least64_t // see below
+using std::atomic_int_fast8_t // see below
+using std::atomic_uint_fast8_t // see below
+using std::atomic_int_fast16_t // see below
+using std::atomic_uint_fast16_t // see below
+using std::atomic_int_fast32_t // see below
+using std::atomic_uint_fast32_t // see below
+using std::atomic_int_fast64_t // see below
+using std::atomic_uint_fast64_t // see below
+using std::atomic_intptr_t // see below
+using std::atomic_uintptr_t // see below
+using std::atomic_size_t // see below
+using std::atomic_ptrdiff_t // see below
+using std::atomic_intmax_t // see below
+using std::atomic_uintmax_t // see below
+
+using std::atomic_is_lock_free // see below
+using std::atomic_load // see below
+using std::atomic_load_explicit // see below
+using std::atomic_store // see below
+using std::atomic_store_explicit // see below
+using std::atomic_exchange // see below
+using std::atomic_exchange_explicit // see below
+using std::atomic_compare_exchange_strong // see below
+using std::atomic_compare_exchange_strong_explicit // see below
+using std::atomic_compare_exchange_weak // see below
+using std::atomic_compare_exchange_weak_explicit // see below
+using std::atomic_fetch_add // see below
+using std::atomic_fetch_add_explicit // see below
+using std::atomic_fetch_sub // see below
+using std::atomic_fetch_sub_explicit // see below
+using std::atomic_fetch_or // see below
+using std::atomic_fetch_or_explicit // see below
+using std::atomic_fetch_and // see below
+using std::atomic_fetch_and_explicit // see below
+using std::atomic_flag_test_and_set // see below
+using std::atomic_flag_test_and_set_explicit // see below
+using std::atomic_flag_clear // see below
+using std::atomic_flag_clear_explicit // see below
+
+using std::atomic_thread_fence // see below
+using std::atomic_signal_fence // see below
+
+*/
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 20
+
+#include <atomic>
+#include <version>
+
+#ifdef _Atomic
+# undef _Atomic
+#endif
+
+#define _Atomic(_Tp) ::std::atomic<_Tp>
+
+using std::memory_order _LIBCPP_USING_IF_EXISTS;
+using std::memory_order_relaxed _LIBCPP_USING_IF_EXISTS;
+using std::memory_order_consume _LIBCPP_USING_IF_EXISTS;
+using std::memory_order_acquire _LIBCPP_USING_IF_EXISTS;
+using std::memory_order_release _LIBCPP_USING_IF_EXISTS;
+using std::memory_order_acq_rel _LIBCPP_USING_IF_EXISTS;
+using std::memory_order_seq_cst _LIBCPP_USING_IF_EXISTS;
+
+using std::atomic_flag _LIBCPP_USING_IF_EXISTS;
+
+using std::atomic_bool _LIBCPP_USING_IF_EXISTS;
+using std::atomic_char _LIBCPP_USING_IF_EXISTS;
+using std::atomic_schar _LIBCPP_USING_IF_EXISTS;
+using std::atomic_uchar _LIBCPP_USING_IF_EXISTS;
+using std::atomic_short _LIBCPP_USING_IF_EXISTS;
+using std::atomic_ushort _LIBCPP_USING_IF_EXISTS;
+using std::atomic_int _LIBCPP_USING_IF_EXISTS;
+using std::atomic_uint _LIBCPP_USING_IF_EXISTS;
+using std::atomic_long _LIBCPP_USING_IF_EXISTS;
+using std::atomic_ulong _LIBCPP_USING_IF_EXISTS;
+using std::atomic_llong _LIBCPP_USING_IF_EXISTS;
+using std::atomic_ullong _LIBCPP_USING_IF_EXISTS;
+using std::atomic_char8_t _LIBCPP_USING_IF_EXISTS;
+using std::atomic_char16_t _LIBCPP_USING_IF_EXISTS;
+using std::atomic_char32_t _LIBCPP_USING_IF_EXISTS;
+using std::atomic_wchar_t _LIBCPP_USING_IF_EXISTS;
+
+using std::atomic_int8_t _LIBCPP_USING_IF_EXISTS;
+using std::atomic_uint8_t _LIBCPP_USING_IF_EXISTS;
+using std::atomic_int16_t _LIBCPP_USING_IF_EXISTS;
+using std::atomic_uint16_t _LIBCPP_USING_IF_EXISTS;
+using std::atomic_int32_t _LIBCPP_USING_IF_EXISTS;
+using std::atomic_uint32_t _LIBCPP_USING_IF_EXISTS;
+using std::atomic_int64_t _LIBCPP_USING_IF_EXISTS;
+using std::atomic_uint64_t _LIBCPP_USING_IF_EXISTS;
+
+using std::atomic_int_least8_t _LIBCPP_USING_IF_EXISTS;
+using std::atomic_uint_least8_t _LIBCPP_USING_IF_EXISTS;
+using std::atomic_int_least16_t _LIBCPP_USING_IF_EXISTS;
+using std::atomic_uint_least16_t _LIBCPP_USING_IF_EXISTS;
+using std::atomic_int_least32_t _LIBCPP_USING_IF_EXISTS;
+using std::atomic_uint_least32_t _LIBCPP_USING_IF_EXISTS;
+using std::atomic_int_least64_t _LIBCPP_USING_IF_EXISTS;
+using std::atomic_uint_least64_t _LIBCPP_USING_IF_EXISTS;
+
+using std::atomic_int_fast8_t _LIBCPP_USING_IF_EXISTS;
+using std::atomic_uint_fast8_t _LIBCPP_USING_IF_EXISTS;
+using std::atomic_int_fast16_t _LIBCPP_USING_IF_EXISTS;
+using std::atomic_uint_fast16_t _LIBCPP_USING_IF_EXISTS;
+using std::atomic_int_fast32_t _LIBCPP_USING_IF_EXISTS;
+using std::atomic_uint_fast32_t _LIBCPP_USING_IF_EXISTS;
+using std::atomic_int_fast64_t _LIBCPP_USING_IF_EXISTS;
+using std::atomic_uint_fast64_t _LIBCPP_USING_IF_EXISTS;
+
+using std::atomic_intptr_t _LIBCPP_USING_IF_EXISTS;
+using std::atomic_uintptr_t _LIBCPP_USING_IF_EXISTS;
+using std::atomic_size_t _LIBCPP_USING_IF_EXISTS;
+using std::atomic_ptrdiff_t _LIBCPP_USING_IF_EXISTS;
+using std::atomic_intmax_t _LIBCPP_USING_IF_EXISTS;
+using std::atomic_uintmax_t _LIBCPP_USING_IF_EXISTS;
+
+using std::atomic_compare_exchange_strong _LIBCPP_USING_IF_EXISTS;
+using std::atomic_compare_exchange_strong_explicit _LIBCPP_USING_IF_EXISTS;
+using std::atomic_compare_exchange_weak _LIBCPP_USING_IF_EXISTS;
+using std::atomic_compare_exchange_weak_explicit _LIBCPP_USING_IF_EXISTS;
+using std::atomic_exchange _LIBCPP_USING_IF_EXISTS;
+using std::atomic_exchange_explicit _LIBCPP_USING_IF_EXISTS;
+using std::atomic_fetch_add _LIBCPP_USING_IF_EXISTS;
+using std::atomic_fetch_add_explicit _LIBCPP_USING_IF_EXISTS;
+using std::atomic_fetch_and _LIBCPP_USING_IF_EXISTS;
+using std::atomic_fetch_and_explicit _LIBCPP_USING_IF_EXISTS;
+using std::atomic_fetch_or _LIBCPP_USING_IF_EXISTS;
+using std::atomic_fetch_or_explicit _LIBCPP_USING_IF_EXISTS;
+using std::atomic_fetch_sub _LIBCPP_USING_IF_EXISTS;
+using std::atomic_fetch_sub_explicit _LIBCPP_USING_IF_EXISTS;
+using std::atomic_flag_clear _LIBCPP_USING_IF_EXISTS;
+using std::atomic_flag_clear_explicit _LIBCPP_USING_IF_EXISTS;
+using std::atomic_flag_test_and_set _LIBCPP_USING_IF_EXISTS;
+using std::atomic_flag_test_and_set_explicit _LIBCPP_USING_IF_EXISTS;
+using std::atomic_is_lock_free _LIBCPP_USING_IF_EXISTS;
+using std::atomic_load _LIBCPP_USING_IF_EXISTS;
+using std::atomic_load_explicit _LIBCPP_USING_IF_EXISTS;
+using std::atomic_store _LIBCPP_USING_IF_EXISTS;
+using std::atomic_store_explicit _LIBCPP_USING_IF_EXISTS;
+
+using std::atomic_signal_fence _LIBCPP_USING_IF_EXISTS;
+using std::atomic_thread_fence _LIBCPP_USING_IF_EXISTS;
+
+#elif defined(_LIBCPP_COMPILER_CLANG_BASED)
+
+// Before C++23, we include the next <stdatomic.h> on the path to avoid hijacking
+// the header. We do this because Clang has historically shipped a <stdatomic.h>
+// header that would be available in all Standard modes, and we don't want to
+// break that use case.
+# if __has_include_next(<stdatomic.h>)
+# include_next <stdatomic.h>
+# endif
+
+#endif // _LIBCPP_STD_VER > 20
+
+#endif // _LIBCPP_STDATOMIC_H
diff --git a/libcxx/include/stdbool.h b/libcxx/include/stdbool.h
index 98d43214f08a..0bc1aa8304ad 100644
--- a/libcxx/include/stdbool.h
+++ b/libcxx/include/stdbool.h
@@ -9,7 +9,6 @@
#ifndef _LIBCPP_STDBOOL_H
#define _LIBCPP_STDBOOL_H
-
/*
stdbool.h synopsis
@@ -22,7 +21,7 @@ Macros:
#include <__config>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
#include_next <stdbool.h>
diff --git a/libcxx/include/stddef.h b/libcxx/include/stddef.h
index 13944ef8a851..19e344f2a000 100644
--- a/libcxx/include/stddef.h
+++ b/libcxx/include/stddef.h
@@ -11,7 +11,7 @@
defined(__need_wchar_t) || defined(__need_NULL) || defined(__need_wint_t)
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
#include_next <stddef.h>
@@ -39,18 +39,13 @@ Types:
#include <__config>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
#include_next <stddef.h>
#ifdef __cplusplus
-
-extern "C++" {
-#include <__nullptr>
-using std::nullptr_t;
-}
-
+ typedef decltype(nullptr) nullptr_t;
#endif
#endif // _LIBCPP_STDDEF_H
diff --git a/libcxx/include/stdexcept b/libcxx/include/stdexcept
index 5df2050ee4ec..ee5a296cd930 100644
--- a/libcxx/include/stdexcept
+++ b/libcxx/include/stdexcept
@@ -41,13 +41,14 @@ public:
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
#include <cstdlib>
#include <exception>
#include <iosfwd> // for string forward decl
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/libcxx/include/stdint.h b/libcxx/include/stdint.h
index 66676b6402d6..ee71f62ab095 100644
--- a/libcxx/include/stdint.h
+++ b/libcxx/include/stdint.h
@@ -106,7 +106,7 @@ Macros:
#include <__config>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
/* C99 stdlib (e.g. glibc < 2.18) does not provide macros needed
diff --git a/libcxx/include/stdio.h b/libcxx/include/stdio.h
index 24224d995964..ad1b4c05f1fa 100644
--- a/libcxx/include/stdio.h
+++ b/libcxx/include/stdio.h
@@ -10,7 +10,7 @@
#if defined(__need_FILE) || defined(__need___FILE)
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
#include_next <stdio.h>
@@ -101,7 +101,7 @@ void perror(const char* s);
#include <__config>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
#include_next <stdio.h>
diff --git a/libcxx/include/stdlib.h b/libcxx/include/stdlib.h
index 6ae6bb66b053..e4dce9c54546 100644
--- a/libcxx/include/stdlib.h
+++ b/libcxx/include/stdlib.h
@@ -10,7 +10,7 @@
#if defined(__need_malloc_and_calloc)
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
#include_next <stdlib.h>
@@ -87,7 +87,7 @@ void *aligned_alloc(size_t alignment, size_t size); // C11
#include <__config>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
#include_next <stdlib.h>
diff --git a/libcxx/include/streambuf b/libcxx/include/streambuf
index 9874ec2ce499..53a71720f11a 100644
--- a/libcxx/include/streambuf
+++ b/libcxx/include/streambuf
@@ -107,6 +107,7 @@ protected:
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
#include <cstdint>
#include <ios>
@@ -114,7 +115,7 @@ protected:
#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
@@ -487,11 +488,11 @@ basic_streambuf<_CharT, _Traits>::overflow(int_type)
return traits_type::eof();
}
-_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_streambuf<char>)
-_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_streambuf<wchar_t>)
+extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_streambuf<char>;
+extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_streambuf<wchar_t>;
-_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ios<char>)
-_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ios<wchar_t>)
+extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ios<char>;
+extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ios<wchar_t>;
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/string b/libcxx/include/string
index 3616de8a214d..bb169a82c9e7 100644
--- a/libcxx/include/string
+++ b/libcxx/include/string
@@ -95,248 +95,246 @@ public:
static const size_type npos = -1;
basic_string()
- noexcept(is_nothrow_default_constructible<allocator_type>::value);
- explicit basic_string(const allocator_type& a);
- basic_string(const basic_string& str);
+ noexcept(is_nothrow_default_constructible<allocator_type>::value); // constexpr since C++20
+ explicit basic_string(const allocator_type& a); // constexpr since C++20
+ basic_string(const basic_string& str); // constexpr since C++20
basic_string(basic_string&& str)
- noexcept(is_nothrow_move_constructible<allocator_type>::value);
+ noexcept(is_nothrow_move_constructible<allocator_type>::value); // constexpr since C++20
basic_string(const basic_string& str, size_type pos,
- const allocator_type& a = allocator_type());
+ const allocator_type& a = allocator_type()); // constexpr since C++20
basic_string(const basic_string& str, size_type pos, size_type n,
- const Allocator& a = Allocator());
+ const Allocator& a = Allocator()); // constexpr since C++20
template<class T>
- basic_string(const T& t, size_type pos, size_type n, const Allocator& a = Allocator()); // C++17
+ basic_string(const T& t, size_type pos, size_type n, const Allocator& a = Allocator()); // C++17, constexpr since C++20
template <class T>
- explicit basic_string(const T& t, const Allocator& a = Allocator()); // C++17
- basic_string(const value_type* s, const allocator_type& a = allocator_type());
- basic_string(const value_type* s, size_type n, const allocator_type& a = allocator_type());
+ explicit basic_string(const T& t, const Allocator& a = Allocator()); // C++17, constexpr since C++20
+ basic_string(const value_type* s, const allocator_type& a = allocator_type()); // constexpr since C++20
+ basic_string(const value_type* s, size_type n, const allocator_type& a = allocator_type()); // constexpr since C++20
basic_string(nullptr_t) = delete; // C++2b
- basic_string(size_type n, value_type c, const allocator_type& a = allocator_type());
+ basic_string(size_type n, value_type c, const allocator_type& a = allocator_type()); // constexpr since C++20
template<class InputIterator>
basic_string(InputIterator begin, InputIterator end,
- const allocator_type& a = allocator_type());
- basic_string(initializer_list<value_type>, const Allocator& = Allocator());
- basic_string(const basic_string&, const Allocator&);
- basic_string(basic_string&&, const Allocator&);
+ const allocator_type& a = allocator_type()); // constexpr since C++20
+ basic_string(initializer_list<value_type>, const Allocator& = Allocator()); // constexpr since C++20
+ basic_string(const basic_string&, const Allocator&); // constexpr since C++20
+ basic_string(basic_string&&, const Allocator&); // constexpr since C++20
- ~basic_string();
+ ~basic_string(); // constexpr since C++20
- operator basic_string_view<charT, traits>() const noexcept;
+ operator basic_string_view<charT, traits>() const noexcept; // constexpr since C++20
- basic_string& operator=(const basic_string& str);
+ basic_string& operator=(const basic_string& str); // constexpr since C++20
template <class T>
- basic_string& operator=(const T& t); // C++17
+ basic_string& operator=(const T& t); // C++17, constexpr since C++20
basic_string& operator=(basic_string&& str)
noexcept(
allocator_type::propagate_on_container_move_assignment::value ||
- allocator_type::is_always_equal::value ); // C++17
- basic_string& operator=(const value_type* s);
+ allocator_type::is_always_equal::value ); // C++17, constexpr since C++20
+ basic_string& operator=(const value_type* s); // constexpr since C++20
basic_string& operator=(nullptr_t) = delete; // C++2b
- basic_string& operator=(value_type c);
- basic_string& operator=(initializer_list<value_type>);
+ basic_string& operator=(value_type c); // constexpr since C++20
+ basic_string& operator=(initializer_list<value_type>); // constexpr since C++20
- iterator begin() noexcept;
- const_iterator begin() const noexcept;
- iterator end() noexcept;
- const_iterator end() const noexcept;
+ iterator begin() noexcept; // constexpr since C++20
+ const_iterator begin() const noexcept; // constexpr since C++20
+ iterator end() noexcept; // constexpr since C++20
+ const_iterator end() const noexcept; // constexpr since C++20
- reverse_iterator rbegin() noexcept;
- const_reverse_iterator rbegin() const noexcept;
- reverse_iterator rend() noexcept;
- const_reverse_iterator rend() const noexcept;
+ reverse_iterator rbegin() noexcept; // constexpr since C++20
+ const_reverse_iterator rbegin() const noexcept; // constexpr since C++20
+ reverse_iterator rend() noexcept; // constexpr since C++20
+ const_reverse_iterator rend() const noexcept; // constexpr since C++20
- const_iterator cbegin() const noexcept;
- const_iterator cend() const noexcept;
- const_reverse_iterator crbegin() const noexcept;
- const_reverse_iterator crend() const noexcept;
+ const_iterator cbegin() const noexcept; // constexpr since C++20
+ const_iterator cend() const noexcept; // constexpr since C++20
+ const_reverse_iterator crbegin() const noexcept; // constexpr since C++20
+ const_reverse_iterator crend() const noexcept; // constexpr since C++20
- size_type size() const noexcept;
- size_type length() const noexcept;
- size_type max_size() const noexcept;
- size_type capacity() const noexcept;
+ size_type size() const noexcept; // constexpr since C++20
+ size_type length() const noexcept; // constexpr since C++20
+ size_type max_size() const noexcept; // constexpr since C++20
+ size_type capacity() const noexcept; // constexpr since C++20
- void resize(size_type n, value_type c);
- void resize(size_type n);
+ void resize(size_type n, value_type c); // constexpr since C++20
+ void resize(size_type n); // constexpr since C++20
template<class Operation>
constexpr void resize_and_overwrite(size_type n, Operation op); // since C++23
- void reserve(size_type res_arg);
+ void reserve(size_type res_arg); // constexpr since C++20
void reserve(); // deprecated in C++20
- void shrink_to_fit();
- void clear() noexcept;
- bool empty() const noexcept;
+ void shrink_to_fit(); // constexpr since C++20
+ void clear() noexcept; // constexpr since C++20
+ bool empty() const noexcept; // constexpr since C++20
- const_reference operator[](size_type pos) const;
- reference operator[](size_type pos);
+ const_reference operator[](size_type pos) const; // constexpr since C++20
+ reference operator[](size_type pos); // constexpr since C++20
- const_reference at(size_type n) const;
- reference at(size_type n);
+ const_reference at(size_type n) const; // constexpr since C++20
+ reference at(size_type n); // constexpr since C++20
- basic_string& operator+=(const basic_string& str);
+ basic_string& operator+=(const basic_string& str); // constexpr since C++20
template <class T>
- basic_string& operator+=(const T& t); // C++17
- basic_string& operator+=(const value_type* s);
- basic_string& operator+=(value_type c);
- basic_string& operator+=(initializer_list<value_type>);
+ basic_string& operator+=(const T& t); // C++17, constexpr since C++20
+ basic_string& operator+=(const value_type* s); // constexpr since C++20
+ basic_string& operator+=(value_type c); // constexpr since C++20
+ basic_string& operator+=(initializer_list<value_type>); // constexpr since C++20
- basic_string& append(const basic_string& str);
+ basic_string& append(const basic_string& str); // constexpr since C++20
template <class T>
- basic_string& append(const T& t); // C++17
- basic_string& append(const basic_string& str, size_type pos, size_type n=npos); //C++14
+ basic_string& append(const T& t); // C++17, constexpr since C++20
+ basic_string& append(const basic_string& str, size_type pos, size_type n=npos); // C++14, constexpr since C++20
template <class T>
- basic_string& append(const T& t, size_type pos, size_type n=npos); // C++17
- basic_string& append(const value_type* s, size_type n);
- basic_string& append(const value_type* s);
- basic_string& append(size_type n, value_type c);
+ basic_string& append(const T& t, size_type pos, size_type n=npos); // C++17, constexpr since C++20
+ basic_string& append(const value_type* s, size_type n); // constexpr since C++20
+ basic_string& append(const value_type* s); // constexpr since C++20
+ basic_string& append(size_type n, value_type c); // constexpr since C++20
template<class InputIterator>
- basic_string& append(InputIterator first, InputIterator last);
- basic_string& append(initializer_list<value_type>);
+ basic_string& append(InputIterator first, InputIterator last); // constexpr since C++20
+ basic_string& append(initializer_list<value_type>); // constexpr since C++20
- void push_back(value_type c);
- void pop_back();
- reference front();
- const_reference front() const;
- reference back();
- const_reference back() const;
+ void push_back(value_type c); // constexpr since C++20
+ void pop_back(); // constexpr since C++20
+ reference front(); // constexpr since C++20
+ const_reference front() const; // constexpr since C++20
+ reference back(); // constexpr since C++20
+ const_reference back() const; // constexpr since C++20
- basic_string& assign(const basic_string& str);
+ basic_string& assign(const basic_string& str); // constexpr since C++20
template <class T>
- basic_string& assign(const T& t); // C++17
- basic_string& assign(basic_string&& str);
- basic_string& assign(const basic_string& str, size_type pos, size_type n=npos); // C++14
+ basic_string& assign(const T& t); // C++17, constexpr since C++20
+ basic_string& assign(basic_string&& str); // constexpr since C++20
+ basic_string& assign(const basic_string& str, size_type pos, size_type n=npos); // C++14, constexpr since C++20
template <class T>
- basic_string& assign(const T& t, size_type pos, size_type n=npos); // C++17
- basic_string& assign(const value_type* s, size_type n);
- basic_string& assign(const value_type* s);
- basic_string& assign(size_type n, value_type c);
+ basic_string& assign(const T& t, size_type pos, size_type n=npos); // C++17, constexpr since C++20
+ basic_string& assign(const value_type* s, size_type n); // constexpr since C++20
+ basic_string& assign(const value_type* s); // constexpr since C++20
+ basic_string& assign(size_type n, value_type c); // constexpr since C++20
template<class InputIterator>
- basic_string& assign(InputIterator first, InputIterator last);
- basic_string& assign(initializer_list<value_type>);
+ basic_string& assign(InputIterator first, InputIterator last); // constexpr since C++20
+ basic_string& assign(initializer_list<value_type>); // constexpr since C++20
- basic_string& insert(size_type pos1, const basic_string& str);
+ basic_string& insert(size_type pos1, const basic_string& str); // constexpr since C++20
template <class T>
- basic_string& insert(size_type pos1, const T& t);
+ basic_string& insert(size_type pos1, const T& t); // constexpr since C++20
basic_string& insert(size_type pos1, const basic_string& str,
- size_type pos2, size_type n);
+ size_type pos2, size_type n); // constexpr since C++20
template <class T>
- basic_string& insert(size_type pos1, const T& t, size_type pos2, size_type n); // C++17
- basic_string& insert(size_type pos, const value_type* s, size_type n=npos); //C++14
- basic_string& insert(size_type pos, const value_type* s);
- basic_string& insert(size_type pos, size_type n, value_type c);
- iterator insert(const_iterator p, value_type c);
- iterator insert(const_iterator p, size_type n, value_type c);
+ basic_string& insert(size_type pos1, const T& t, size_type pos2, size_type n); // C++17, constexpr since C++20
+ basic_string& insert(size_type pos, const value_type* s, size_type n=npos); // C++14, constexpr since C++20
+ basic_string& insert(size_type pos, const value_type* s); // constexpr since C++20
+ basic_string& insert(size_type pos, size_type n, value_type c); // constexpr since C++20
+ iterator insert(const_iterator p, value_type c); // constexpr since C++20
+ iterator insert(const_iterator p, size_type n, value_type c); // constexpr since C++20
template<class InputIterator>
- iterator insert(const_iterator p, InputIterator first, InputIterator last);
- iterator insert(const_iterator p, initializer_list<value_type>);
+ iterator insert(const_iterator p, InputIterator first, InputIterator last); // constexpr since C++20
+ iterator insert(const_iterator p, initializer_list<value_type>); // constexpr since C++20
- basic_string& erase(size_type pos = 0, size_type n = npos);
- iterator erase(const_iterator position);
- iterator erase(const_iterator first, const_iterator last);
+ basic_string& erase(size_type pos = 0, size_type n = npos); // constexpr since C++20
+ iterator erase(const_iterator position); // constexpr since C++20
+ iterator erase(const_iterator first, const_iterator last); // constexpr since C++20
- basic_string& replace(size_type pos1, size_type n1, const basic_string& str);
+ basic_string& replace(size_type pos1, size_type n1, const basic_string& str); // constexpr since C++20
template <class T>
- basic_string& replace(size_type pos1, size_type n1, const T& t); // C++17
+ basic_string& replace(size_type pos1, size_type n1, const T& t); // C++17, constexpr since C++20
basic_string& replace(size_type pos1, size_type n1, const basic_string& str,
- size_type pos2, size_type n2=npos); // C++14
+ size_type pos2, size_type n2=npos); // C++14, constexpr since C++20
template <class T>
basic_string& replace(size_type pos1, size_type n1, const T& t,
- size_type pos2, size_type n); // C++17
- basic_string& replace(size_type pos, size_type n1, const value_type* s, size_type n2);
- basic_string& replace(size_type pos, size_type n1, const value_type* s);
- basic_string& replace(size_type pos, size_type n1, size_type n2, value_type c);
- basic_string& replace(const_iterator i1, const_iterator i2, const basic_string& str);
+ size_type pos2, size_type n); // C++17, constexpr since C++20
+ basic_string& replace(size_type pos, size_type n1, const value_type* s, size_type n2); // constexpr since C++20
+ basic_string& replace(size_type pos, size_type n1, const value_type* s); // constexpr since C++20
+ basic_string& replace(size_type pos, size_type n1, size_type n2, value_type c); // constexpr since C++20
+ basic_string& replace(const_iterator i1, const_iterator i2, const basic_string& str); // constexpr since C++20
template <class T>
- basic_string& replace(const_iterator i1, const_iterator i2, const T& t); // C++17
- basic_string& replace(const_iterator i1, const_iterator i2, const value_type* s, size_type n);
- basic_string& replace(const_iterator i1, const_iterator i2, const value_type* s);
- basic_string& replace(const_iterator i1, const_iterator i2, size_type n, value_type c);
+ basic_string& replace(const_iterator i1, const_iterator i2, const T& t); // C++17, constexpr since C++20
+ basic_string& replace(const_iterator i1, const_iterator i2, const value_type* s, size_type n); // constexpr since C++20
+ basic_string& replace(const_iterator i1, const_iterator i2, const value_type* s); // constexpr since C++20
+ basic_string& replace(const_iterator i1, const_iterator i2, size_type n, value_type c); // constexpr since C++20
template<class InputIterator>
- basic_string& replace(const_iterator i1, const_iterator i2, InputIterator j1, InputIterator j2);
- basic_string& replace(const_iterator i1, const_iterator i2, initializer_list<value_type>);
+ basic_string& replace(const_iterator i1, const_iterator i2, InputIterator j1, InputIterator j2); // constexpr since C++20
+ basic_string& replace(const_iterator i1, const_iterator i2, initializer_list<value_type>); // constexpr since C++20
- size_type copy(value_type* s, size_type n, size_type pos = 0) const;
- basic_string substr(size_type pos = 0, size_type n = npos) const;
+ size_type copy(value_type* s, size_type n, size_type pos = 0) const; // constexpr since C++20
+ basic_string substr(size_type pos = 0, size_type n = npos) const; // constexpr since C++20
void swap(basic_string& str)
noexcept(allocator_traits<allocator_type>::propagate_on_container_swap::value ||
- allocator_traits<allocator_type>::is_always_equal::value); // C++17
+ allocator_traits<allocator_type>::is_always_equal::value); // C++17, constexpr since C++20
- const value_type* c_str() const noexcept;
- const value_type* data() const noexcept;
- value_type* data() noexcept; // C++17
+ const value_type* c_str() const noexcept; // constexpr since C++20
+ const value_type* data() const noexcept; // constexpr since C++20
+ value_type* data() noexcept; // C++17, constexpr since C++20
- allocator_type get_allocator() const noexcept;
+ allocator_type get_allocator() const noexcept; // constexpr since C++20
- size_type find(const basic_string& str, size_type pos = 0) const noexcept;
+ size_type find(const basic_string& str, size_type pos = 0) const noexcept; // constexpr since C++20
template <class T>
- size_type find(const T& t, size_type pos = 0) const noexcept; // C++17, noexcept as an extension
- size_type find(const value_type* s, size_type pos, size_type n) const noexcept;
- size_type find(const value_type* s, size_type pos = 0) const noexcept;
- size_type find(value_type c, size_type pos = 0) const noexcept;
+ size_type find(const T& t, size_type pos = 0) const noexcept; // C++17, noexcept as an extension, constexpr since C++20
+ size_type find(const value_type* s, size_type pos, size_type n) const noexcept; // constexpr since C++20
+ size_type find(const value_type* s, size_type pos = 0) const noexcept; // constexpr since C++20
+ size_type find(value_type c, size_type pos = 0) const noexcept; // constexpr since C++20
- size_type rfind(const basic_string& str, size_type pos = npos) const noexcept;
+ size_type rfind(const basic_string& str, size_type pos = npos) const noexcept; // constexpr since C++20
template <class T>
- size_type rfind(const T& t, size_type pos = npos) const noexcept; // C++17, noexcept as an extension
- size_type rfind(const value_type* s, size_type pos, size_type n) const noexcept;
- size_type rfind(const value_type* s, size_type pos = npos) const noexcept;
- size_type rfind(value_type c, size_type pos = npos) const noexcept;
+ size_type rfind(const T& t, size_type pos = npos) const noexcept; // C++17, noexcept as an extension, constexpr since C++20
+ size_type rfind(const value_type* s, size_type pos, size_type n) const noexcept; // constexpr since C++20
+ size_type rfind(const value_type* s, size_type pos = npos) const noexcept; // constexpr since C++20
+ size_type rfind(value_type c, size_type pos = npos) const noexcept; // constexpr since C++20
- size_type find_first_of(const basic_string& str, size_type pos = 0) const noexcept;
+ size_type find_first_of(const basic_string& str, size_type pos = 0) const noexcept; // constexpr since C++20
template <class T>
- size_type find_first_of(const T& t, size_type pos = 0) const noexcept; // C++17, noexcept as an extension
- size_type find_first_of(const value_type* s, size_type pos, size_type n) const noexcept;
- size_type find_first_of(const value_type* s, size_type pos = 0) const noexcept;
- size_type find_first_of(value_type c, size_type pos = 0) const noexcept;
+ size_type find_first_of(const T& t, size_type pos = 0) const noexcept; // C++17, noexcept as an extension, constexpr since C++20
+ size_type find_first_of(const value_type* s, size_type pos, size_type n) const noexcept; // constexpr since C++20
+ size_type find_first_of(const value_type* s, size_type pos = 0) const noexcept; // constexpr since C++20
+ size_type find_first_of(value_type c, size_type pos = 0) const noexcept; // constexpr since C++20
- size_type find_last_of(const basic_string& str, size_type pos = npos) const noexcept;
+ size_type find_last_of(const basic_string& str, size_type pos = npos) const noexcept; // constexpr since C++20
template <class T>
- size_type find_last_of(const T& t, size_type pos = npos) const noexcept noexcept; // C++17, noexcept as an extension
- size_type find_last_of(const value_type* s, size_type pos, size_type n) const noexcept;
- size_type find_last_of(const value_type* s, size_type pos = npos) const noexcept;
- size_type find_last_of(value_type c, size_type pos = npos) const noexcept;
+ size_type find_last_of(const T& t, size_type pos = npos) const noexcept noexcept; // C++17, noexcept as an extension, constexpr since C++20
+ size_type find_last_of(const value_type* s, size_type pos, size_type n) const noexcept; // constexpr since C++20
+ size_type find_last_of(const value_type* s, size_type pos = npos) const noexcept; // constexpr since C++20
+ size_type find_last_of(value_type c, size_type pos = npos) const noexcept; // constexpr since C++20
- size_type find_first_not_of(const basic_string& str, size_type pos = 0) const noexcept;
+ size_type find_first_not_of(const basic_string& str, size_type pos = 0) const noexcept; // constexpr since C++20
template <class T>
- size_type find_first_not_of(const T& t, size_type pos = 0) const noexcept; // C++17, noexcept as an extension
- size_type find_first_not_of(const value_type* s, size_type pos, size_type n) const noexcept;
- size_type find_first_not_of(const value_type* s, size_type pos = 0) const noexcept;
- size_type find_first_not_of(value_type c, size_type pos = 0) const noexcept;
+ size_type find_first_not_of(const T& t, size_type pos = 0) const noexcept; // C++17, noexcept as an extension, constexpr since C++20
+ size_type find_first_not_of(const value_type* s, size_type pos, size_type n) const noexcept; // constexpr since C++20
+ size_type find_first_not_of(const value_type* s, size_type pos = 0) const noexcept; // constexpr since C++20
+ size_type find_first_not_of(value_type c, size_type pos = 0) const noexcept; // constexpr since C++20
- size_type find_last_not_of(const basic_string& str, size_type pos = npos) const noexcept;
+ size_type find_last_not_of(const basic_string& str, size_type pos = npos) const noexcept; // constexpr since C++20
template <class T>
- size_type find_last_not_of(const T& t, size_type pos = npos) const noexcept; // C++17, noexcept as an extension
- size_type find_last_not_of(const value_type* s, size_type pos, size_type n) const noexcept;
- size_type find_last_not_of(const value_type* s, size_type pos = npos) const noexcept;
- size_type find_last_not_of(value_type c, size_type pos = npos) const noexcept;
+ size_type find_last_not_of(const T& t, size_type pos = npos) const noexcept; // C++17, noexcept as an extension, constexpr since C++20
+ size_type find_last_not_of(const value_type* s, size_type pos, size_type n) const noexcept; // constexpr since C++20
+ size_type find_last_not_of(const value_type* s, size_type pos = npos) const noexcept; // constexpr since C++20
+ size_type find_last_not_of(value_type c, size_type pos = npos) const noexcept; // constexpr since C++20
- int compare(const basic_string& str) const noexcept;
+ int compare(const basic_string& str) const noexcept; // constexpr since C++20
template <class T>
- int compare(const T& t) const noexcept; // C++17, noexcept as an extension
- int compare(size_type pos1, size_type n1, const basic_string& str) const;
+ int compare(const T& t) const noexcept; // C++17, noexcept as an extension, constexpr since C++20
+ int compare(size_type pos1, size_type n1, const basic_string& str) const; // constexpr since C++20
template <class T>
- int compare(size_type pos1, size_type n1, const T& t) const; // C++17
+ int compare(size_type pos1, size_type n1, const T& t) const; // C++17, constexpr since C++20
int compare(size_type pos1, size_type n1, const basic_string& str,
- size_type pos2, size_type n2=npos) const; // C++14
+ size_type pos2, size_type n2=npos) const; // C++14, constexpr since C++20
template <class T>
int compare(size_type pos1, size_type n1, const T& t,
- size_type pos2, size_type n2=npos) const; // C++17
- int compare(const value_type* s) const noexcept;
- int compare(size_type pos1, size_type n1, const value_type* s) const;
- int compare(size_type pos1, size_type n1, const value_type* s, size_type n2) const;
-
- bool starts_with(basic_string_view<charT, traits> sv) const noexcept; // C++20
- bool starts_with(charT c) const noexcept; // C++20
- bool starts_with(const charT* s) const; // C++20
- bool ends_with(basic_string_view<charT, traits> sv) const noexcept; // C++20
- bool ends_with(charT c) const noexcept; // C++20
- bool ends_with(const charT* s) const; // C++20
-
- constexpr bool contains(basic_string_view<charT, traits> sv) const noexcept; // C++2b
- constexpr bool contains(charT c) const noexcept; // C++2b
- constexpr bool contains(const charT* s) const; // C++2b
-
- bool __invariants() const;
+ size_type pos2, size_type n2=npos) const; // C++17, constexpr since C++20
+ int compare(const value_type* s) const noexcept; // constexpr since C++20
+ int compare(size_type pos1, size_type n1, const value_type* s) const; // constexpr since C++20
+ int compare(size_type pos1, size_type n1, const value_type* s, size_type n2) const; // constexpr since C++20
+
+ constexpr bool starts_with(basic_string_view<charT, traits> sv) const noexcept; // C++20
+ constexpr bool starts_with(charT c) const noexcept; // C++20
+ constexpr bool starts_with(const charT* s) const; // C++20
+ constexpr bool ends_with(basic_string_view<charT, traits> sv) const noexcept; // C++20
+ constexpr bool ends_with(charT c) const noexcept; // C++20
+ constexpr bool ends_with(const charT* s) const; // C++20
+
+ constexpr bool contains(basic_string_view<charT, traits> sv) const noexcept; // C++2b
+ constexpr bool contains(charT c) const noexcept; // C++2b
+ constexpr bool contains(const charT* s) const; // C++2b
};
template<class InputIterator,
@@ -349,88 +347,88 @@ basic_string(InputIterator, InputIterator, Allocator = Allocator())
template<class charT, class traits, class Allocator>
basic_string<charT, traits, Allocator>
operator+(const basic_string<charT, traits, Allocator>& lhs,
- const basic_string<charT, traits, Allocator>& rhs);
+ const basic_string<charT, traits, Allocator>& rhs); // constexpr since C++20
template<class charT, class traits, class Allocator>
basic_string<charT, traits, Allocator>
-operator+(const charT* lhs , const basic_string<charT,traits,Allocator>&rhs);
+operator+(const charT* lhs , const basic_string<charT,traits,Allocator>&rhs); // constexpr since C++20
template<class charT, class traits, class Allocator>
basic_string<charT, traits, Allocator>
-operator+(charT lhs, const basic_string<charT,traits,Allocator>& rhs);
+operator+(charT lhs, const basic_string<charT,traits,Allocator>& rhs); // constexpr since C++20
template<class charT, class traits, class Allocator>
basic_string<charT, traits, Allocator>
-operator+(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs);
+operator+(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs); // constexpr since C++20
template<class charT, class traits, class Allocator>
basic_string<charT, traits, Allocator>
-operator+(const basic_string<charT, traits, Allocator>& lhs, charT rhs);
+operator+(const basic_string<charT, traits, Allocator>& lhs, charT rhs); // constexpr since C++20
template<class charT, class traits, class Allocator>
bool operator==(const basic_string<charT, traits, Allocator>& lhs,
- const basic_string<charT, traits, Allocator>& rhs) noexcept;
+ const basic_string<charT, traits, Allocator>& rhs) noexcept; // constexpr since C++20
template<class charT, class traits, class Allocator>
-bool operator==(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept;
+bool operator==(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; // constexpr since C++20
template<class charT, class traits, class Allocator>
-bool operator==(const basic_string<charT,traits,Allocator>& lhs, const charT* rhs) noexcept;
+bool operator==(const basic_string<charT,traits,Allocator>& lhs, const charT* rhs) noexcept; // constexpr since C++20
template<class charT, class traits, class Allocator>
bool operator!=(const basic_string<charT,traits,Allocator>& lhs,
- const basic_string<charT, traits, Allocator>& rhs) noexcept;
+ const basic_string<charT, traits, Allocator>& rhs) noexcept; // constexpr since C++20
template<class charT, class traits, class Allocator>
-bool operator!=(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept;
+bool operator!=(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; // constexpr since C++20
template<class charT, class traits, class Allocator>
-bool operator!=(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept;
+bool operator!=(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept; // constexpr since C++20
template<class charT, class traits, class Allocator>
bool operator< (const basic_string<charT, traits, Allocator>& lhs,
- const basic_string<charT, traits, Allocator>& rhs) noexcept;
+ const basic_string<charT, traits, Allocator>& rhs) noexcept; // constexpr since C++20
template<class charT, class traits, class Allocator>
-bool operator< (const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept;
+bool operator< (const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept; // constexpr since C++20
template<class charT, class traits, class Allocator>
-bool operator< (const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept;
+bool operator< (const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; // constexpr since C++20
template<class charT, class traits, class Allocator>
bool operator> (const basic_string<charT, traits, Allocator>& lhs,
- const basic_string<charT, traits, Allocator>& rhs) noexcept;
+ const basic_string<charT, traits, Allocator>& rhs) noexcept; // constexpr since C++20
template<class charT, class traits, class Allocator>
-bool operator> (const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept;
+bool operator> (const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept; // constexpr since C++20
template<class charT, class traits, class Allocator>
-bool operator> (const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept;
+bool operator> (const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; // constexpr since C++20
template<class charT, class traits, class Allocator>
bool operator<=(const basic_string<charT, traits, Allocator>& lhs,
- const basic_string<charT, traits, Allocator>& rhs) noexcept;
+ const basic_string<charT, traits, Allocator>& rhs) noexcept; // constexpr since C++20
template<class charT, class traits, class Allocator>
-bool operator<=(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept;
+bool operator<=(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept; // constexpr since C++20
template<class charT, class traits, class Allocator>
-bool operator<=(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept;
+bool operator<=(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; // constexpr since C++20
template<class charT, class traits, class Allocator>
bool operator>=(const basic_string<charT, traits, Allocator>& lhs,
- const basic_string<charT, traits, Allocator>& rhs) noexcept;
+ const basic_string<charT, traits, Allocator>& rhs) noexcept; // constexpr since C++20
template<class charT, class traits, class Allocator>
-bool operator>=(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept;
+bool operator>=(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept; // constexpr since C++20
template<class charT, class traits, class Allocator>
-bool operator>=(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept;
+bool operator>=(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; // constexpr since C++20
template<class charT, class traits, class Allocator>
void swap(basic_string<charT, traits, Allocator>& lhs,
basic_string<charT, traits, Allocator>& rhs)
- noexcept(noexcept(lhs.swap(rhs)));
+ noexcept(noexcept(lhs.swap(rhs))); // constexpr since C++20
template<class charT, class traits, class Allocator>
basic_istream<charT, traits>&
@@ -508,45 +506,80 @@ template <> struct hash<u16string>;
template <> struct hash<u32string>;
template <> struct hash<wstring>;
-basic_string<char> operator "" s( const char *str, size_t len ); // C++14
-basic_string<wchar_t> operator "" s( const wchar_t *str, size_t len ); // C++14
-basic_string<char8_t> operator "" s( const char8_t *str, size_t len ); // C++20
-basic_string<char16_t> operator "" s( const char16_t *str, size_t len ); // C++14
-basic_string<char32_t> operator "" s( const char32_t *str, size_t len ); // C++14
+basic_string<char> operator "" s( const char *str, size_t len ); // C++14, constexpr since C++20
+basic_string<wchar_t> operator "" s( const wchar_t *str, size_t len ); // C++14, constexpr since C++20
+constexpr basic_string<char8_t> operator "" s( const char8_t *str, size_t len ); // C++20
+basic_string<char16_t> operator "" s( const char16_t *str, size_t len ); // C++14, constexpr since C++20
+basic_string<char32_t> operator "" s( const char32_t *str, size_t len ); // C++14, constexpr since C++20
} // std
*/
+#include <__algorithm/max.h>
+#include <__algorithm/min.h>
+#include <__algorithm/remove.h>
+#include <__algorithm/remove_if.h>
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
#include <__debug>
-#include <__functional_base>
+#include <__format/enable_insertable.h>
+#include <__functional/hash.h>
+#include <__functional/unary_function.h>
+#include <__ios/fpos.h>
+#include <__iterator/distance.h>
+#include <__iterator/iterator_traits.h>
+#include <__iterator/reverse_iterator.h>
#include <__iterator/wrap_iter.h>
-#include <algorithm>
-#include <compare>
+#include <__memory/allocate_at_least.h>
+#include <__string/char_traits.h>
+#include <__string/extern_template_lists.h>
+#include <__utility/auto_cast.h>
+#include <__utility/move.h>
+#include <__utility/swap.h>
+#include <__utility/unreachable.h>
+#include <climits>
+#include <cstdint>
#include <cstdio> // EOF
#include <cstdlib>
#include <cstring>
-#include <initializer_list>
#include <iosfwd>
-#include <iterator>
+#include <limits>
#include <memory>
#include <stdexcept>
#include <string_view>
#include <type_traits>
-#include <utility>
#include <version>
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-# include <cwchar>
+# include <cwchar>
#endif
-#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
-# include <cstdint>
+#ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES
+# include <algorithm>
+# include <functional>
+# include <iterator>
+# include <new>
+# include <typeinfo>
+# include <utility>
+# include <vector>
#endif
+// standard-mandated includes
+
+// [iterator.range]
+#include <__iterator/access.h>
+#include <__iterator/data.h>
+#include <__iterator/empty.h>
+#include <__iterator/reverse_access.h>
+#include <__iterator/size.h>
+
+// [string.syn]
+#include <compare>
+#include <initializer_list>
+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
@@ -555,80 +588,35 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD
-// fpos
-
-template <class _StateT>
-class _LIBCPP_TEMPLATE_VIS fpos
-{
-private:
- _StateT __st_;
- streamoff __off_;
-public:
- _LIBCPP_INLINE_VISIBILITY fpos(streamoff __off = streamoff()) : __st_(), __off_(__off) {}
-
- _LIBCPP_INLINE_VISIBILITY operator streamoff() const {return __off_;}
-
- _LIBCPP_INLINE_VISIBILITY _StateT state() const {return __st_;}
- _LIBCPP_INLINE_VISIBILITY void state(_StateT __st) {__st_ = __st;}
-
- _LIBCPP_INLINE_VISIBILITY fpos& operator+=(streamoff __off) {__off_ += __off; return *this;}
- _LIBCPP_INLINE_VISIBILITY fpos operator+ (streamoff __off) const {fpos __t(*this); __t += __off; return __t;}
- _LIBCPP_INLINE_VISIBILITY fpos& operator-=(streamoff __off) {__off_ -= __off; return *this;}
- _LIBCPP_INLINE_VISIBILITY fpos operator- (streamoff __off) const {fpos __t(*this); __t -= __off; return __t;}
-};
-
-template <class _StateT>
-inline _LIBCPP_INLINE_VISIBILITY
-streamoff operator-(const fpos<_StateT>& __x, const fpos<_StateT>& __y)
- {return streamoff(__x) - streamoff(__y);}
-
-template <class _StateT>
-inline _LIBCPP_INLINE_VISIBILITY
-bool operator==(const fpos<_StateT>& __x, const fpos<_StateT>& __y)
- {return streamoff(__x) == streamoff(__y);}
-
-template <class _StateT>
-inline _LIBCPP_INLINE_VISIBILITY
-bool operator!=(const fpos<_StateT>& __x, const fpos<_StateT>& __y)
- {return streamoff(__x) != streamoff(__y);}
-
// basic_string
template<class _CharT, class _Traits, class _Allocator>
basic_string<_CharT, _Traits, _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
operator+(const basic_string<_CharT, _Traits, _Allocator>& __x,
const basic_string<_CharT, _Traits, _Allocator>& __y);
template<class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<_CharT, _Traits, _Allocator>
operator+(const _CharT* __x, const basic_string<_CharT,_Traits,_Allocator>& __y);
template<class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<_CharT, _Traits, _Allocator>
operator+(_CharT __x, const basic_string<_CharT,_Traits,_Allocator>& __y);
template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<_CharT, _Traits, _Allocator>
operator+(const basic_string<_CharT, _Traits, _Allocator>& __x, const _CharT* __y);
template<class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<_CharT, _Traits, _Allocator>
operator+(const basic_string<_CharT, _Traits, _Allocator>& __x, _CharT __y);
-_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS string operator+<char, char_traits<char>, allocator<char> >(char const*, string const&))
-
-#ifndef _LIBCPP_ABI_NO_BASIC_STRING_BASE_CLASS
-template <bool>
-struct __basic_string_common;
-
-template <>
-struct __basic_string_common<true> {
- // Both are defined in string.cpp
- _LIBCPP_NORETURN _LIBCPP_EXPORTED_FROM_ABI void __throw_length_error() const;
- _LIBCPP_NORETURN _LIBCPP_EXPORTED_FROM_ABI void __throw_out_of_range() const;
-};
-#endif
+extern template _LIBCPP_FUNC_VIS string operator+<char, char_traits<char>, allocator<char> >(char const*, string const&);
template <class _Iter>
struct __string_is_trivial_iterator : public false_type {};
@@ -647,29 +635,13 @@ struct __can_be_converted_to_string_view : public _BoolConstant<
!is_convertible<const _Tp&, const _CharT*>::value
> {};
-#ifdef _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
-
-template <class _CharT, size_t = sizeof(_CharT)>
-struct __padding
-{
- unsigned char __xx[sizeof(_CharT)-1];
-};
-
-template <class _CharT>
-struct __padding<_CharT, 1>
-{
-};
-
-#endif // _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
-
#ifndef _LIBCPP_HAS_NO_CHAR8_T
typedef basic_string<char8_t> u8string;
#endif
-
-#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
typedef basic_string<char16_t> u16string;
typedef basic_string<char32_t> u32string;
-#endif
+
+struct __uninitialized_size_tag {};
template<class _CharT, class _Traits, class _Allocator>
class
@@ -677,14 +649,9 @@ class
#ifndef _LIBCPP_HAS_NO_CHAR8_T
_LIBCPP_PREFERRED_NAME(u8string)
#endif
-#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
_LIBCPP_PREFERRED_NAME(u16string)
_LIBCPP_PREFERRED_NAME(u32string)
-#endif
basic_string
-#ifndef _LIBCPP_ABI_NO_BASIC_STRING_BASE_CLASS
- : private __basic_string_common<true> // This base class is historical, but it needs to remain for ABI compatibility
-#endif
{
public:
typedef basic_string __self;
@@ -710,10 +677,11 @@ public:
typedef __wrap_iter<pointer> iterator;
typedef __wrap_iter<const_pointer> const_iterator;
- typedef _VSTD::reverse_iterator<iterator> reverse_iterator;
- typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator;
+ typedef std::reverse_iterator<iterator> reverse_iterator;
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
private:
+ static_assert(CHAR_BIT == 8, "This implementation assumes that one byte contains 8 bits");
#ifdef _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
@@ -721,62 +689,79 @@ private:
{
pointer __data_;
size_type __size_;
- size_type __cap_;
+ size_type __cap_ : sizeof(size_type) * CHAR_BIT - 1;
+ size_type __is_long_ : 1;
};
-#ifdef _LIBCPP_BIG_ENDIAN
- static const size_type __short_mask = 0x01;
- static const size_type __long_mask = 0x1ul;
-#else // _LIBCPP_BIG_ENDIAN
- static const size_type __short_mask = 0x80;
- static const size_type __long_mask = ~(size_type(~0) >> 1);
-#endif // _LIBCPP_BIG_ENDIAN
-
enum {__min_cap = (sizeof(__long) - 1)/sizeof(value_type) > 2 ?
(sizeof(__long) - 1)/sizeof(value_type) : 2};
struct __short
{
value_type __data_[__min_cap];
- struct
- : __padding<value_type>
- {
- unsigned char __size_;
- };
+ unsigned char __padding_[sizeof(value_type) - 1];
+ unsigned char __size_ : 7;
+ unsigned char __is_long_ : 1;
};
+// The __endian_factor is required because the field we use to store the size
+// has one fewer bit than it would if it were not a bitfield.
+//
+// If the LSB is used to store the short-flag in the short string representation,
+// we have to multiply the size by two when it is stored and divide it by two when
+// it is loaded to make sure that we always store an even number. In the long string
+// representation, we can ignore this because we can assume that we always allocate
+// an even amount of value_types.
+//
+// If the MSB is used for the short-flag, the max_size() is numeric_limits<size_type>::max() / 2.
+// This does not impact the short string representation, since we never need the MSB
+// for representing the size of a short string anyway.
+
+#ifdef _LIBCPP_BIG_ENDIAN
+ static const size_type __endian_factor = 2;
+#else
+ static const size_type __endian_factor = 1;
+#endif
+
+#else // _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
+
+#ifdef _LIBCPP_BIG_ENDIAN
+ static const size_type __endian_factor = 1;
#else
+ static const size_type __endian_factor = 2;
+#endif
+ // Attribute 'packed' is used to keep the layout compatible with the
+ // previous definition that did not use bit fields. This is because on
+ // some platforms bit fields have a default size rather than the actual
+ // size used, e.g., it is 4 bytes on AIX. See D128285 for details.
struct __long
{
- size_type __cap_;
+ struct _LIBCPP_PACKED {
+ size_type __is_long_ : 1;
+ size_type __cap_ : sizeof(size_type) * CHAR_BIT - 1;
+ };
size_type __size_;
pointer __data_;
};
-#ifdef _LIBCPP_BIG_ENDIAN
- static const size_type __short_mask = 0x80;
- static const size_type __long_mask = ~(size_type(~0) >> 1);
-#else // _LIBCPP_BIG_ENDIAN
- static const size_type __short_mask = 0x01;
- static const size_type __long_mask = 0x1ul;
-#endif // _LIBCPP_BIG_ENDIAN
-
enum {__min_cap = (sizeof(__long) - 1)/sizeof(value_type) > 2 ?
(sizeof(__long) - 1)/sizeof(value_type) : 2};
struct __short
{
- union
- {
- unsigned char __size_;
- value_type __lx;
+ struct _LIBCPP_PACKED {
+ unsigned char __is_long_ : 1;
+ unsigned char __size_ : 7;
};
+ char __padding_[sizeof(value_type) - 1];
value_type __data_[__min_cap];
};
#endif // _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
+ static_assert(sizeof(__short) == (sizeof(value_type) * (__min_cap + 1)), "__short has an unexpected size.");
+
union __ulx{__long __lx; __short __lxx;};
enum {__n_words = sizeof(__ulx) / sizeof(size_type)};
@@ -798,25 +783,47 @@ private:
__compressed_pair<__rep, allocator_type> __r_;
+ // Construct a string with the given allocator and enough storage to hold `__size` characters, but
+ // don't initialize the characters. The contents of the string, including the null terminator, must be
+ // initialized separately.
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
+ explicit basic_string(__uninitialized_size_tag, size_type __size, const allocator_type& __a)
+ : __r_(__default_init_tag(), __a) {
+ if (__size > max_size())
+ __throw_length_error();
+ if (__fits_in_sso(__size)) {
+ __zero();
+ __set_short_size(__size);
+ } else {
+ auto __capacity = __recommend(__size) + 1;
+ auto __allocation = __alloc_traits::allocate(__alloc(), __capacity);
+ __begin_lifetime(__allocation, __capacity);
+ __set_long_cap(__capacity);
+ __set_long_pointer(__allocation);
+ __set_long_size(__size);
+ }
+ std::__debug_db_insert_c(this);
+ }
+
public:
_LIBCPP_TEMPLATE_DATA_VIS
static const size_type npos = -1;
- _LIBCPP_INLINE_VISIBILITY basic_string()
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string()
_NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value);
- _LIBCPP_INLINE_VISIBILITY explicit basic_string(const allocator_type& __a)
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 explicit basic_string(const allocator_type& __a)
#if _LIBCPP_STD_VER <= 14
_NOEXCEPT_(is_nothrow_copy_constructible<allocator_type>::value);
#else
_NOEXCEPT;
#endif
- basic_string(const basic_string& __str);
- basic_string(const basic_string& __str, const allocator_type& __a);
+ _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string(const basic_string& __str);
+ _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string(const basic_string& __str, const allocator_type& __a);
#ifndef _LIBCPP_CXX03_LANG
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string(basic_string&& __str)
#if _LIBCPP_STD_VER <= 14
_NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value);
@@ -824,218 +831,221 @@ public:
_NOEXCEPT;
#endif
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string(basic_string&& __str, const allocator_type& __a);
#endif // _LIBCPP_CXX03_LANG
template <class = __enable_if_t<__is_allocator<_Allocator>::value, nullptr_t> >
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string(const _CharT* __s) : __r_(__default_init_tag(), __default_init_tag()) {
_LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*) detected nullptr");
__init(__s, traits_type::length(__s));
- _VSTD::__debug_db_insert_c(this);
+ std::__debug_db_insert_c(this);
}
template <class = __enable_if_t<__is_allocator<_Allocator>::value, nullptr_t> >
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string(const _CharT* __s, const _Allocator& __a);
#if _LIBCPP_STD_VER > 20
basic_string(nullptr_t) = delete;
#endif
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string(const _CharT* __s, size_type __n);
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string(const _CharT* __s, size_type __n, const _Allocator& __a);
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string(size_type __n, _CharT __c);
template <class = __enable_if_t<__is_allocator<_Allocator>::value, nullptr_t> >
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string(size_type __n, _CharT __c, const _Allocator& __a);
+ _LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string(const basic_string& __str, size_type __pos, size_type __n,
const _Allocator& __a = _Allocator());
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string(const basic_string& __str, size_type __pos,
const _Allocator& __a = _Allocator());
template<class _Tp, class = __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value> >
- _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+ _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string(const _Tp& __t, size_type __pos, size_type __n,
const allocator_type& __a = allocator_type());
template<class _Tp, class = __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
!__is_same_uncvref<_Tp, basic_string>::value> >
- _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+ _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
explicit basic_string(const _Tp& __t);
template<class _Tp, class = __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value> >
- _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+ _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
explicit basic_string(const _Tp& __t, const allocator_type& __a);
template<class _InputIterator, class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value> >
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string(_InputIterator __first, _InputIterator __last);
template<class _InputIterator, class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value> >
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string(_InputIterator __first, _InputIterator __last, const allocator_type& __a);
#ifndef _LIBCPP_CXX03_LANG
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string(initializer_list<_CharT> __il);
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string(initializer_list<_CharT> __il, const _Allocator& __a);
#endif // _LIBCPP_CXX03_LANG
- inline ~basic_string();
+ inline _LIBCPP_CONSTEXPR_AFTER_CXX17 ~basic_string();
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
operator __self_view() const _NOEXCEPT { return __self_view(data(), size()); }
- basic_string& operator=(const basic_string& __str);
+ _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& operator=(const basic_string& __str);
- template <class _Tp, class = __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value> >
- basic_string& operator=(const _Tp& __t)
- {__self_view __sv = __t; return assign(__sv);}
+ template <class _Tp, class = __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
+ !__is_same_uncvref<_Tp, basic_string>::value> >
+ _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& operator=(const _Tp& __t) {
+ __self_view __sv = __t;
+ return assign(__sv);
+ }
#ifndef _LIBCPP_CXX03_LANG
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string& operator=(basic_string&& __str)
_NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value));
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string& operator=(initializer_list<value_type> __il) {return assign(__il.begin(), __il.size());}
#endif
- _LIBCPP_INLINE_VISIBILITY basic_string& operator=(const value_type* __s) {return assign(__s);}
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
+ basic_string& operator=(const value_type* __s) {return assign(__s);}
#if _LIBCPP_STD_VER > 20
basic_string& operator=(nullptr_t) = delete;
#endif
- basic_string& operator=(value_type __c);
+ _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& operator=(value_type __c);
-#if _LIBCPP_DEBUG_LEVEL == 2
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
iterator begin() _NOEXCEPT
{return iterator(this, __get_pointer());}
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
const_iterator begin() const _NOEXCEPT
{return const_iterator(this, __get_pointer());}
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
iterator end() _NOEXCEPT
{return iterator(this, __get_pointer() + size());}
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
const_iterator end() const _NOEXCEPT
{return const_iterator(this, __get_pointer() + size());}
-#else
- _LIBCPP_INLINE_VISIBILITY
- iterator begin() _NOEXCEPT
- {return iterator(__get_pointer());}
- _LIBCPP_INLINE_VISIBILITY
- const_iterator begin() const _NOEXCEPT
- {return const_iterator(__get_pointer());}
- _LIBCPP_INLINE_VISIBILITY
- iterator end() _NOEXCEPT
- {return iterator(__get_pointer() + size());}
- _LIBCPP_INLINE_VISIBILITY
- const_iterator end() const _NOEXCEPT
- {return const_iterator(__get_pointer() + size());}
-#endif // _LIBCPP_DEBUG_LEVEL == 2
- _LIBCPP_INLINE_VISIBILITY
+
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
reverse_iterator rbegin() _NOEXCEPT
{return reverse_iterator(end());}
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
const_reverse_iterator rbegin() const _NOEXCEPT
{return const_reverse_iterator(end());}
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
reverse_iterator rend() _NOEXCEPT
{return reverse_iterator(begin());}
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
const_reverse_iterator rend() const _NOEXCEPT
{return const_reverse_iterator(begin());}
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
const_iterator cbegin() const _NOEXCEPT
{return begin();}
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
const_iterator cend() const _NOEXCEPT
{return end();}
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
const_reverse_iterator crbegin() const _NOEXCEPT
{return rbegin();}
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
const_reverse_iterator crend() const _NOEXCEPT
{return rend();}
- _LIBCPP_INLINE_VISIBILITY size_type size() const _NOEXCEPT
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type size() const _NOEXCEPT
{return __is_long() ? __get_long_size() : __get_short_size();}
- _LIBCPP_INLINE_VISIBILITY size_type length() const _NOEXCEPT {return size();}
- _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT;
- _LIBCPP_INLINE_VISIBILITY size_type capacity() const _NOEXCEPT
- {return (__is_long() ? __get_long_cap()
- : static_cast<size_type>(__min_cap)) - 1;}
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type length() const _NOEXCEPT {return size();}
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type max_size() const _NOEXCEPT;
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type capacity() const _NOEXCEPT {
+ return (__is_long() ? __get_long_cap() : static_cast<size_type>(__min_cap)) - 1;
+ }
- void resize(size_type __n, value_type __c);
- _LIBCPP_INLINE_VISIBILITY void resize(size_type __n) {resize(__n, value_type());}
+ _LIBCPP_CONSTEXPR_AFTER_CXX17 void resize(size_type __n, value_type __c);
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void resize(size_type __n) { resize(__n, value_type()); }
- void reserve(size_type __requested_capacity);
+ _LIBCPP_CONSTEXPR_AFTER_CXX17 void reserve(size_type __requested_capacity);
#if _LIBCPP_STD_VER > 20
template <class _Op>
_LIBCPP_HIDE_FROM_ABI constexpr
void resize_and_overwrite(size_type __n, _Op __op) {
__resize_default_init(__n);
- __erase_to_end(_VSTD::move(__op)(data(), _LIBCPP_AUTO_CAST(__n)));
+ __erase_to_end(std::move(__op)(data(), _LIBCPP_AUTO_CAST(__n)));
}
#endif
- _LIBCPP_INLINE_VISIBILITY void __resize_default_init(size_type __n);
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void __resize_default_init(size_type __n);
+
+ _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_HIDE_FROM_ABI void reserve() _NOEXCEPT { shrink_to_fit(); }
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void shrink_to_fit() _NOEXCEPT;
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void clear() _NOEXCEPT;
- _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_INLINE_VISIBILITY
- void reserve() _NOEXCEPT {shrink_to_fit();}
- _LIBCPP_INLINE_VISIBILITY
- void shrink_to_fit() _NOEXCEPT;
- _LIBCPP_INLINE_VISIBILITY
- void clear() _NOEXCEPT;
- _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
bool empty() const _NOEXCEPT {return size() == 0;}
- _LIBCPP_INLINE_VISIBILITY const_reference operator[](size_type __pos) const _NOEXCEPT;
- _LIBCPP_INLINE_VISIBILITY reference operator[](size_type __pos) _NOEXCEPT;
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
+ const_reference operator[](size_type __pos) const _NOEXCEPT;
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 reference operator[](size_type __pos) _NOEXCEPT;
- const_reference at(size_type __n) const;
- reference at(size_type __n);
+ _LIBCPP_CONSTEXPR_AFTER_CXX17 const_reference at(size_type __n) const;
+ _LIBCPP_CONSTEXPR_AFTER_CXX17 reference at(size_type __n);
- _LIBCPP_INLINE_VISIBILITY basic_string& operator+=(const basic_string& __str) {return append(__str);}
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& operator+=(const basic_string& __str) {
+ return append(__str);
+ }
template <class _Tp>
- _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+ _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
__enable_if_t
<
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value
&& !__is_same_uncvref<_Tp, basic_string >::value,
basic_string&
>
- operator+=(const _Tp& __t) {__self_view __sv = __t; return append(__sv);}
- _LIBCPP_INLINE_VISIBILITY basic_string& operator+=(const value_type* __s) {return append(__s);}
- _LIBCPP_INLINE_VISIBILITY basic_string& operator+=(value_type __c) {push_back(__c); return *this;}
+ operator+=(const _Tp& __t) {
+ __self_view __sv = __t; return append(__sv);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& operator+=(const value_type* __s) {
+ return append(__s);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& operator+=(value_type __c) {
+ push_back(__c);
+ return *this;
+ }
+
#ifndef _LIBCPP_CXX03_LANG
- _LIBCPP_INLINE_VISIBILITY basic_string& operator+=(initializer_list<value_type> __il) {return append(__il);}
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
+ basic_string& operator+=(initializer_list<value_type> __il) { return append(__il); }
#endif // _LIBCPP_CXX03_LANG
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string& append(const basic_string& __str);
template <class _Tp>
- _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+ _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
__enable_if_t<
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value
&& !__is_same_uncvref<_Tp, basic_string>::value,
basic_string&
>
append(const _Tp& __t) { __self_view __sv = __t; return append(__sv.data(), __sv.size()); }
- basic_string& append(const basic_string& __str, size_type __pos, size_type __n=npos);
+ _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& append(const basic_string& __str, size_type __pos, size_type __n=npos);
template <class _Tp>
- _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+ _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
__enable_if_t
<
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value
@@ -1043,11 +1053,11 @@ public:
basic_string&
>
append(const _Tp& __t, size_type __pos, size_type __n=npos);
- basic_string& append(const value_type* __s, size_type __n);
- basic_string& append(const value_type* __s);
- basic_string& append(size_type __n, value_type __c);
+ _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& append(const value_type* __s, size_type __n);
+ _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& append(const value_type* __s);
+ _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& append(size_type __n, value_type __c);
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
void __append_default_init(size_type __n);
template<class _InputIterator>
@@ -1057,7 +1067,7 @@ public:
__is_exactly_cpp17_input_iterator<_InputIterator>::value,
basic_string&
>
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
append(_InputIterator __first, _InputIterator __last) {
const basic_string __temp(__first, __last, __alloc());
append(__temp.data(), __temp.size());
@@ -1070,41 +1080,40 @@ public:
__is_cpp17_forward_iterator<_ForwardIterator>::value,
basic_string&
>
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
append(_ForwardIterator __first, _ForwardIterator __last);
#ifndef _LIBCPP_CXX03_LANG
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string& append(initializer_list<value_type> __il) {return append(__il.begin(), __il.size());}
#endif // _LIBCPP_CXX03_LANG
- void push_back(value_type __c);
- _LIBCPP_INLINE_VISIBILITY
- void pop_back();
- _LIBCPP_INLINE_VISIBILITY reference front() _NOEXCEPT;
- _LIBCPP_INLINE_VISIBILITY const_reference front() const _NOEXCEPT;
- _LIBCPP_INLINE_VISIBILITY reference back() _NOEXCEPT;
- _LIBCPP_INLINE_VISIBILITY const_reference back() const _NOEXCEPT;
+ _LIBCPP_CONSTEXPR_AFTER_CXX17 void push_back(value_type __c);
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void pop_back();
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 reference front() _NOEXCEPT;
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 const_reference front() const _NOEXCEPT;
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 reference back() _NOEXCEPT;
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 const_reference back() const _NOEXCEPT;
template <class _Tp>
- _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+ _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
__enable_if_t
<
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
basic_string&
>
assign(const _Tp & __t) { __self_view __sv = __t; return assign(__sv.data(), __sv.size()); }
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string& assign(const basic_string& __str) { return *this = __str; }
#ifndef _LIBCPP_CXX03_LANG
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string& assign(basic_string&& __str)
_NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value))
- {*this = _VSTD::move(__str); return *this;}
+ {*this = std::move(__str); return *this;}
#endif
- basic_string& assign(const basic_string& __str, size_type __pos, size_type __n=npos);
+ _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& assign(const basic_string& __str, size_type __pos, size_type __n=npos);
template <class _Tp>
- _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+ _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
__enable_if_t
<
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value
@@ -1112,11 +1121,11 @@ public:
basic_string&
>
assign(const _Tp & __t, size_type __pos, size_type __n=npos);
- basic_string& assign(const value_type* __s, size_type __n);
- basic_string& assign(const value_type* __s);
- basic_string& assign(size_type __n, value_type __c);
+ _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& assign(const value_type* __s, size_type __n);
+ _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& assign(const value_type* __s);
+ _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& assign(size_type __n, value_type __c);
template<class _InputIterator>
- _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+ _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
__enable_if_t
<
__is_exactly_cpp17_input_iterator<_InputIterator>::value,
@@ -1124,7 +1133,7 @@ public:
>
assign(_InputIterator __first, _InputIterator __last);
template<class _ForwardIterator>
- _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+ _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
__enable_if_t
<
__is_cpp17_forward_iterator<_ForwardIterator>::value,
@@ -1132,15 +1141,15 @@ public:
>
assign(_ForwardIterator __first, _ForwardIterator __last);
#ifndef _LIBCPP_CXX03_LANG
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string& assign(initializer_list<value_type> __il) {return assign(__il.begin(), __il.size());}
#endif // _LIBCPP_CXX03_LANG
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string& insert(size_type __pos1, const basic_string& __str);
template <class _Tp>
- _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+ _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
__enable_if_t
<
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
@@ -1150,22 +1159,23 @@ public:
{ __self_view __sv = __t; return insert(__pos1, __sv.data(), __sv.size()); }
template <class _Tp>
- _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+ _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
__enable_if_t
<
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value,
basic_string&
>
insert(size_type __pos1, const _Tp& __t, size_type __pos2, size_type __n=npos);
+ _LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string& insert(size_type __pos1, const basic_string& __str, size_type __pos2, size_type __n=npos);
- basic_string& insert(size_type __pos, const value_type* __s, size_type __n);
- basic_string& insert(size_type __pos, const value_type* __s);
- basic_string& insert(size_type __pos, size_type __n, value_type __c);
- iterator insert(const_iterator __pos, value_type __c);
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& insert(size_type __pos, const value_type* __s, size_type __n);
+ _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& insert(size_type __pos, const value_type* __s);
+ _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& insert(size_type __pos, size_type __n, value_type __c);
+ _LIBCPP_CONSTEXPR_AFTER_CXX17 iterator insert(const_iterator __pos, value_type __c);
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
iterator insert(const_iterator __pos, size_type __n, value_type __c);
template<class _InputIterator>
- _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+ _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
__enable_if_t
<
__is_exactly_cpp17_input_iterator<_InputIterator>::value,
@@ -1173,7 +1183,7 @@ public:
>
insert(const_iterator __pos, _InputIterator __first, _InputIterator __last);
template<class _ForwardIterator>
- _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+ _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
__enable_if_t
<
__is_cpp17_forward_iterator<_ForwardIterator>::value,
@@ -1181,45 +1191,47 @@ public:
>
insert(const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last);
#ifndef _LIBCPP_CXX03_LANG
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
iterator insert(const_iterator __pos, initializer_list<value_type> __il)
{return insert(__pos, __il.begin(), __il.end());}
#endif // _LIBCPP_CXX03_LANG
- basic_string& erase(size_type __pos = 0, size_type __n = npos);
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& erase(size_type __pos = 0, size_type __n = npos);
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
iterator erase(const_iterator __pos);
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
iterator erase(const_iterator __first, const_iterator __last);
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string& replace(size_type __pos1, size_type __n1, const basic_string& __str);
template <class _Tp>
- _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+ _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
__enable_if_t
<
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
basic_string&
>
replace(size_type __pos1, size_type __n1, const _Tp& __t) { __self_view __sv = __t; return replace(__pos1, __n1, __sv.data(), __sv.size()); }
+ _LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string& replace(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2=npos);
template <class _Tp>
- _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+ _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
__enable_if_t
<
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value,
basic_string&
>
replace(size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2=npos);
+ _LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string& replace(size_type __pos, size_type __n1, const value_type* __s, size_type __n2);
- basic_string& replace(size_type __pos, size_type __n1, const value_type* __s);
- basic_string& replace(size_type __pos, size_type __n1, size_type __n2, value_type __c);
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& replace(size_type __pos, size_type __n1, const value_type* __s);
+ _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& replace(size_type __pos, size_type __n1, size_type __n2, value_type __c);
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string& replace(const_iterator __i1, const_iterator __i2, const basic_string& __str);
template <class _Tp>
- _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+ _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
__enable_if_t
<
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
@@ -1227,14 +1239,14 @@ public:
>
replace(const_iterator __i1, const_iterator __i2, const _Tp& __t) { __self_view __sv = __t; return replace(__i1 - begin(), __i2 - __i1, __sv); }
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string& replace(const_iterator __i1, const_iterator __i2, const value_type* __s, size_type __n);
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string& replace(const_iterator __i1, const_iterator __i2, const value_type* __s);
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string& replace(const_iterator __i1, const_iterator __i2, size_type __n, value_type __c);
template<class _InputIterator>
- _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+ _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
__enable_if_t
<
__is_cpp17_input_iterator<_InputIterator>::value,
@@ -1242,16 +1254,16 @@ public:
>
replace(const_iterator __i1, const_iterator __i2, _InputIterator __j1, _InputIterator __j2);
#ifndef _LIBCPP_CXX03_LANG
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string& replace(const_iterator __i1, const_iterator __i2, initializer_list<value_type> __il)
{return replace(__i1, __i2, __il.begin(), __il.end());}
#endif // _LIBCPP_CXX03_LANG
- size_type copy(value_type* __s, size_type __n, size_type __pos = 0) const;
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type copy(value_type* __s, size_type __n, size_type __pos = 0) const;
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string substr(size_type __pos = 0, size_type __n = npos) const;
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
void swap(basic_string& __str)
#if _LIBCPP_STD_VER >= 14
_NOEXCEPT;
@@ -1260,123 +1272,129 @@ public:
__is_nothrow_swappable<allocator_type>::value);
#endif
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
const value_type* c_str() const _NOEXCEPT {return data();}
- _LIBCPP_INLINE_VISIBILITY
- const value_type* data() const _NOEXCEPT {return _VSTD::__to_address(__get_pointer());}
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
+ const value_type* data() const _NOEXCEPT {return std::__to_address(__get_pointer());}
#if _LIBCPP_STD_VER > 14 || defined(_LIBCPP_BUILDING_LIBRARY)
- _LIBCPP_INLINE_VISIBILITY
- value_type* data() _NOEXCEPT {return _VSTD::__to_address(__get_pointer());}
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
+ value_type* data() _NOEXCEPT {return std::__to_address(__get_pointer());}
#endif
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
allocator_type get_allocator() const _NOEXCEPT {return __alloc();}
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
size_type find(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT;
template <class _Tp>
- _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+ _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
__enable_if_t
<
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
size_type
>
find(const _Tp& __t, size_type __pos = 0) const _NOEXCEPT;
+ _LIBCPP_CONSTEXPR_AFTER_CXX17
size_type find(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
size_type find(const value_type* __s, size_type __pos = 0) const _NOEXCEPT;
- size_type find(value_type __c, size_type __pos = 0) const _NOEXCEPT;
+ _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type find(value_type __c, size_type __pos = 0) const _NOEXCEPT;
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
size_type rfind(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT;
template <class _Tp>
- _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+ _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
__enable_if_t
<
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
size_type
>
rfind(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT;
+ _LIBCPP_CONSTEXPR_AFTER_CXX17
size_type rfind(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
size_type rfind(const value_type* __s, size_type __pos = npos) const _NOEXCEPT;
- size_type rfind(value_type __c, size_type __pos = npos) const _NOEXCEPT;
+ _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type rfind(value_type __c, size_type __pos = npos) const _NOEXCEPT;
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
size_type find_first_of(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT;
template <class _Tp>
- _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+ _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
__enable_if_t
<
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
size_type
>
find_first_of(const _Tp& __t, size_type __pos = 0) const _NOEXCEPT;
+ _LIBCPP_CONSTEXPR_AFTER_CXX17
size_type find_first_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
size_type find_first_of(const value_type* __s, size_type __pos = 0) const _NOEXCEPT;
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
size_type find_first_of(value_type __c, size_type __pos = 0) const _NOEXCEPT;
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
size_type find_last_of(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT;
template <class _Tp>
- _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+ _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
__enable_if_t
<
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
size_type
>
find_last_of(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT;
+ _LIBCPP_CONSTEXPR_AFTER_CXX17
size_type find_last_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
size_type find_last_of(const value_type* __s, size_type __pos = npos) const _NOEXCEPT;
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
size_type find_last_of(value_type __c, size_type __pos = npos) const _NOEXCEPT;
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
size_type find_first_not_of(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT;
template <class _Tp>
- _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+ _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
__enable_if_t
<
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
size_type
>
find_first_not_of(const _Tp &__t, size_type __pos = 0) const _NOEXCEPT;
+ _LIBCPP_CONSTEXPR_AFTER_CXX17
size_type find_first_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
size_type find_first_not_of(const value_type* __s, size_type __pos = 0) const _NOEXCEPT;
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
size_type find_first_not_of(value_type __c, size_type __pos = 0) const _NOEXCEPT;
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
size_type find_last_not_of(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT;
template <class _Tp>
- _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+ _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
__enable_if_t
<
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
size_type
>
find_last_not_of(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT;
+ _LIBCPP_CONSTEXPR_AFTER_CXX17
size_type find_last_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
size_type find_last_not_of(const value_type* __s, size_type __pos = npos) const _NOEXCEPT;
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
size_type find_last_not_of(value_type __c, size_type __pos = npos) const _NOEXCEPT;
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
int compare(const basic_string& __str) const _NOEXCEPT;
template <class _Tp>
- _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+ _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
__enable_if_t
<
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
@@ -1385,7 +1403,7 @@ public:
compare(const _Tp &__t) const _NOEXCEPT;
template <class _Tp>
- _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+ _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
__enable_if_t
<
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
@@ -1393,199 +1411,243 @@ public:
>
compare(size_type __pos1, size_type __n1, const _Tp& __t) const;
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
int compare(size_type __pos1, size_type __n1, const basic_string& __str) const;
- int compare(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2=npos) const;
+ _LIBCPP_CONSTEXPR_AFTER_CXX17
+ int compare(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2,
+ size_type __n2 = npos) const;
template <class _Tp>
- inline _LIBCPP_INLINE_VISIBILITY
+ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
__enable_if_t
<
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value,
int
>
compare(size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2=npos) const;
- int compare(const value_type* __s) const _NOEXCEPT;
- int compare(size_type __pos1, size_type __n1, const value_type* __s) const;
+ _LIBCPP_CONSTEXPR_AFTER_CXX17 int compare(const value_type* __s) const _NOEXCEPT;
+ _LIBCPP_CONSTEXPR_AFTER_CXX17 int compare(size_type __pos1, size_type __n1, const value_type* __s) const;
+ _LIBCPP_CONSTEXPR_AFTER_CXX17
int compare(size_type __pos1, size_type __n1, const value_type* __s, size_type __n2) const;
#if _LIBCPP_STD_VER > 17
- constexpr _LIBCPP_INLINE_VISIBILITY
+ constexpr _LIBCPP_HIDE_FROM_ABI
bool starts_with(__self_view __sv) const noexcept
{ return __self_view(data(), size()).starts_with(__sv); }
- constexpr _LIBCPP_INLINE_VISIBILITY
+ constexpr _LIBCPP_HIDE_FROM_ABI
bool starts_with(value_type __c) const noexcept
{ return !empty() && _Traits::eq(front(), __c); }
- constexpr _LIBCPP_INLINE_VISIBILITY
+ constexpr _LIBCPP_HIDE_FROM_ABI
bool starts_with(const value_type* __s) const noexcept
{ return starts_with(__self_view(__s)); }
- constexpr _LIBCPP_INLINE_VISIBILITY
+ constexpr _LIBCPP_HIDE_FROM_ABI
bool ends_with(__self_view __sv) const noexcept
{ return __self_view(data(), size()).ends_with( __sv); }
- constexpr _LIBCPP_INLINE_VISIBILITY
+ constexpr _LIBCPP_HIDE_FROM_ABI
bool ends_with(value_type __c) const noexcept
{ return !empty() && _Traits::eq(back(), __c); }
- constexpr _LIBCPP_INLINE_VISIBILITY
+ constexpr _LIBCPP_HIDE_FROM_ABI
bool ends_with(const value_type* __s) const noexcept
{ return ends_with(__self_view(__s)); }
#endif
#if _LIBCPP_STD_VER > 20
- constexpr _LIBCPP_INLINE_VISIBILITY
+ constexpr _LIBCPP_HIDE_FROM_ABI
bool contains(__self_view __sv) const noexcept
{ return __self_view(data(), size()).contains(__sv); }
- constexpr _LIBCPP_INLINE_VISIBILITY
+ constexpr _LIBCPP_HIDE_FROM_ABI
bool contains(value_type __c) const noexcept
{ return __self_view(data(), size()).contains(__c); }
- constexpr _LIBCPP_INLINE_VISIBILITY
+ constexpr _LIBCPP_HIDE_FROM_ABI
bool contains(const value_type* __s) const
{ return __self_view(data(), size()).contains(__s); }
#endif
- _LIBCPP_INLINE_VISIBILITY bool __invariants() const;
-
- _LIBCPP_INLINE_VISIBILITY void __clear_and_shrink() _NOEXCEPT;
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 bool __invariants() const;
- _LIBCPP_INLINE_VISIBILITY void __shrink_or_extend(size_type __target_capacity);
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void __clear_and_shrink() _NOEXCEPT;
- _LIBCPP_INLINE_VISIBILITY
- bool __is_long() const _NOEXCEPT
- {return bool(__r_.first().__s.__size_ & __short_mask);}
-
-#if _LIBCPP_DEBUG_LEVEL == 2
+#ifdef _LIBCPP_ENABLE_DEBUG_MODE
bool __dereferenceable(const const_iterator* __i) const;
bool __decrementable(const const_iterator* __i) const;
bool __addable(const const_iterator* __i, ptrdiff_t __n) const;
bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const;
-#endif // _LIBCPP_DEBUG_LEVEL == 2
+#endif // _LIBCPP_ENABLE_DEBUG_MODE
private:
- _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI static bool __fits_in_sso(size_type __sz) {
- // SSO is disabled during constant evaluation because `__is_long` isn't constexpr friendly
- return !__libcpp_is_constant_evaluated() && (__sz < __min_cap);
+ template<class _Alloc>
+ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
+ bool friend operator==(const basic_string<char, char_traits<char>, _Alloc>& __lhs,
+ const basic_string<char, char_traits<char>, _Alloc>& __rhs) _NOEXCEPT;
+
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void __shrink_or_extend(size_type __target_capacity);
+
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
+ bool __is_long() const _NOEXCEPT {
+ if (__libcpp_is_constant_evaluated())
+ return true;
+ return __r_.first().__s.__is_long_;
}
- _LIBCPP_INLINE_VISIBILITY
- allocator_type& __alloc() _NOEXCEPT
- {return __r_.second();}
- _LIBCPP_INLINE_VISIBILITY
- const allocator_type& __alloc() const _NOEXCEPT
- {return __r_.second();}
+ static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void __begin_lifetime(pointer __begin, size_type __n) {
+#if _LIBCPP_STD_VER > 17
+ if (__libcpp_is_constant_evaluated()) {
+ for (size_type __i = 0; __i != __n; ++__i)
+ std::construct_at(std::addressof(__begin[__i]));
+ }
+#else
+ (void)__begin;
+ (void)__n;
+#endif // _LIBCPP_STD_VER > 17
+ }
-#ifdef _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void __default_init() {
+ __zero();
+ if (__libcpp_is_constant_evaluated()) {
+ size_type __sz = __recommend(0) + 1;
+ pointer __ptr = __alloc_traits::allocate(__alloc(), __sz);
+ __begin_lifetime(__ptr, __sz);
+ __set_long_pointer(__ptr);
+ __set_long_cap(__sz);
+ __set_long_size(0);
+ }
+ }
- _LIBCPP_INLINE_VISIBILITY
- void __set_short_size(size_type __s) _NOEXCEPT
-# ifdef _LIBCPP_BIG_ENDIAN
- {__r_.first().__s.__size_ = (unsigned char)(__s << 1);}
-# else
- {__r_.first().__s.__size_ = (unsigned char)(__s);}
-# endif
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void __deallocate_constexpr() {
+ if (__libcpp_is_constant_evaluated() && __get_pointer() != nullptr)
+ __alloc_traits::deallocate(__alloc(), __get_pointer(), __get_long_cap());
+ }
- _LIBCPP_INLINE_VISIBILITY
- size_type __get_short_size() const _NOEXCEPT
-# ifdef _LIBCPP_BIG_ENDIAN
- {return __r_.first().__s.__size_ >> 1;}
-# else
- {return __r_.first().__s.__size_;}
-# endif
+ _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI static bool __fits_in_sso(size_type __sz) {
+ // SSO is disabled during constant evaluation because `__is_long` isn't constexpr friendly
+ return !__libcpp_is_constant_evaluated() && (__sz < __min_cap);
+ }
-#else // _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
+ template <class _ForwardIterator>
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11
+ iterator __insert_from_safe_copy(size_type __n, size_type __ip, _ForwardIterator __first, _ForwardIterator __last) {
+ size_type __sz = size();
+ size_type __cap = capacity();
+ value_type* __p;
+ if (__cap - __sz >= __n)
+ {
+ __p = std::__to_address(__get_pointer());
+ size_type __n_move = __sz - __ip;
+ if (__n_move != 0)
+ traits_type::move(__p + __ip + __n, __p + __ip, __n_move);
+ }
+ else
+ {
+ __grow_by(__cap, __sz + __n - __cap, __sz, __ip, 0, __n);
+ __p = std::__to_address(__get_long_pointer());
+ }
+ __sz += __n;
+ __set_size(__sz);
+ traits_type::assign(__p[__sz], value_type());
+ for (__p += __ip; __first != __last; ++__p, ++__first)
+ traits_type::assign(*__p, *__first);
- _LIBCPP_INLINE_VISIBILITY
- void __set_short_size(size_type __s) _NOEXCEPT
-# ifdef _LIBCPP_BIG_ENDIAN
- {__r_.first().__s.__size_ = (unsigned char)(__s);}
-# else
- {__r_.first().__s.__size_ = (unsigned char)(__s << 1);}
-# endif
+ return begin() + __ip;
+ }
- _LIBCPP_INLINE_VISIBILITY
- size_type __get_short_size() const _NOEXCEPT
-# ifdef _LIBCPP_BIG_ENDIAN
- {return __r_.first().__s.__size_;}
-# else
- {return __r_.first().__s.__size_ >> 1;}
-# endif
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 allocator_type& __alloc() _NOEXCEPT { return __r_.second(); }
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR const allocator_type& __alloc() const _NOEXCEPT { return __r_.second(); }
-#endif // _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
+ void __set_short_size(size_type __s) _NOEXCEPT {
+ _LIBCPP_ASSERT(__s < __min_cap, "__s should never be greater than or equal to the short string capacity");
+ __r_.first().__s.__size_ = __s;
+ __r_.first().__s.__is_long_ = false;
+ }
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
+ size_type __get_short_size() const _NOEXCEPT {
+ _LIBCPP_ASSERT(!__r_.first().__s.__is_long_, "String has to be short when trying to get the short size");
+ return __r_.first().__s.__size_;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
void __set_long_size(size_type __s) _NOEXCEPT
{__r_.first().__l.__size_ = __s;}
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
size_type __get_long_size() const _NOEXCEPT
{return __r_.first().__l.__size_;}
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
void __set_size(size_type __s) _NOEXCEPT
{if (__is_long()) __set_long_size(__s); else __set_short_size(__s);}
- _LIBCPP_INLINE_VISIBILITY
- void __set_long_cap(size_type __s) _NOEXCEPT
- {__r_.first().__l.__cap_ = __long_mask | __s;}
- _LIBCPP_INLINE_VISIBILITY
- size_type __get_long_cap() const _NOEXCEPT
- {return __r_.first().__l.__cap_ & size_type(~__long_mask);}
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
+ void __set_long_cap(size_type __s) _NOEXCEPT {
+ __r_.first().__l.__cap_ = __s / __endian_factor;
+ __r_.first().__l.__is_long_ = true;
+ }
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
+ size_type __get_long_cap() const _NOEXCEPT {
+ return __r_.first().__l.__cap_ * __endian_factor;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
void __set_long_pointer(pointer __p) _NOEXCEPT
{__r_.first().__l.__data_ = __p;}
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
pointer __get_long_pointer() _NOEXCEPT
{return __r_.first().__l.__data_;}
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
const_pointer __get_long_pointer() const _NOEXCEPT
{return __r_.first().__l.__data_;}
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
pointer __get_short_pointer() _NOEXCEPT
{return pointer_traits<pointer>::pointer_to(__r_.first().__s.__data_[0]);}
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
const_pointer __get_short_pointer() const _NOEXCEPT
{return pointer_traits<const_pointer>::pointer_to(__r_.first().__s.__data_[0]);}
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
pointer __get_pointer() _NOEXCEPT
{return __is_long() ? __get_long_pointer() : __get_short_pointer();}
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
const_pointer __get_pointer() const _NOEXCEPT
{return __is_long() ? __get_long_pointer() : __get_short_pointer();}
- _LIBCPP_INLINE_VISIBILITY
- void __zero() _NOEXCEPT
- {
- size_type (&__a)[__n_words] = __r_.first().__r.__words;
- for (unsigned __i = 0; __i < __n_words; ++__i)
- __a[__i] = 0;
- }
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
+ void __zero() _NOEXCEPT {
+ __r_.first() = __rep();
+ }
template <size_type __a> static
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
size_type __align_it(size_type __s) _NOEXCEPT
{return (__s + (__a-1)) & ~(__a-1);}
enum {__alignment = 16};
- static _LIBCPP_INLINE_VISIBILITY
+ static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
size_type __recommend(size_type __s) _NOEXCEPT
- {
- if (__s < __min_cap) return static_cast<size_type>(__min_cap) - 1;
+ {
+ if (__s < __min_cap) {
+ if (__libcpp_is_constant_evaluated())
+ return static_cast<size_type>(__min_cap);
+ else
+ return static_cast<size_type>(__min_cap) - 1;
+ }
size_type __guess = __align_it<sizeof(value_type) < __alignment ?
__alignment/sizeof(value_type) : 1 > (__s+1) - 1;
if (__guess == __min_cap) ++__guess;
return __guess;
- }
+ }
- inline
+ inline _LIBCPP_CONSTEXPR_AFTER_CXX17
void __init(const value_type* __s, size_type __sz, size_type __reserve);
- inline
+ inline _LIBCPP_CONSTEXPR_AFTER_CXX17
void __init(const value_type* __s, size_type __sz);
- inline
+ inline _LIBCPP_CONSTEXPR_AFTER_CXX17
void __init(size_type __n, value_type __c);
// Slow path for the (inlined) copy constructor for 'long' strings.
@@ -1596,10 +1658,10 @@ private:
// to call the __init() functions as those are marked as inline which may
// result in over-aggressive inlining by the compiler, where our aim is
// to only inline the fast path code directly in the ctor.
- void __init_copy_ctor_external(const value_type* __s, size_type __sz);
+ _LIBCPP_CONSTEXPR_AFTER_CXX17 void __init_copy_ctor_external(const value_type* __s, size_type __sz);
template <class _InputIterator>
- inline
+ inline _LIBCPP_CONSTEXPR_AFTER_CXX17
__enable_if_t
<
__is_exactly_cpp17_input_iterator<_InputIterator>::value
@@ -1607,15 +1669,17 @@ private:
__init(_InputIterator __first, _InputIterator __last);
template <class _ForwardIterator>
- inline
+ inline _LIBCPP_CONSTEXPR_AFTER_CXX17
__enable_if_t
<
__is_cpp17_forward_iterator<_ForwardIterator>::value
>
__init(_ForwardIterator __first, _ForwardIterator __last);
+ _LIBCPP_CONSTEXPR_AFTER_CXX17
void __grow_by(size_type __old_cap, size_type __delta_cap, size_type __old_sz,
size_type __n_copy, size_type __n_del, size_type __n_add = 0);
+ _LIBCPP_CONSTEXPR_AFTER_CXX17
void __grow_by_and_replace(size_type __old_cap, size_type __delta_cap, size_type __old_sz,
size_type __n_copy, size_type __n_del,
size_type __n_add, const value_type* __p_new_stuff);
@@ -1624,21 +1688,21 @@ private:
// have proof that the input does not alias the current instance.
// For example, operator=(basic_string) performs a 'self' check.
template <bool __is_short>
- basic_string& __assign_no_alias(const value_type* __s, size_type __n);
+ _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& __assign_no_alias(const value_type* __s, size_type __n);
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
void __erase_to_end(size_type __pos);
// __erase_external_with_move is invoked for erase() invocations where
// `n ~= npos`, likely requiring memory moves on the string data.
- void __erase_external_with_move(size_type __pos, size_type __n);
+ _LIBCPP_CONSTEXPR_AFTER_CXX17 void __erase_external_with_move(size_type __pos, size_type __n);
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
void __copy_assign_alloc(const basic_string& __str)
{__copy_assign_alloc(__str, integral_constant<bool,
__alloc_traits::propagate_on_container_copy_assignment::value>());}
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
void __copy_assign_alloc(const basic_string& __str, true_type)
{
if (__alloc() == __str.__alloc())
@@ -1653,25 +1717,26 @@ private:
else
{
allocator_type __a = __str.__alloc();
- pointer __p = __alloc_traits::allocate(__a, __str.__get_long_cap());
+ auto __allocation = std::__allocate_at_least(__a, __str.__get_long_cap());
+ __begin_lifetime(__allocation.ptr, __allocation.count);
__clear_and_shrink();
- __alloc() = _VSTD::move(__a);
- __set_long_pointer(__p);
- __set_long_cap(__str.__get_long_cap());
+ __alloc() = std::move(__a);
+ __set_long_pointer(__allocation.ptr);
+ __set_long_cap(__allocation.count);
__set_long_size(__str.size());
}
}
}
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
void __copy_assign_alloc(const basic_string&, false_type) _NOEXCEPT
{}
#ifndef _LIBCPP_CXX03_LANG
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
void __move_assign(basic_string& __str, false_type)
_NOEXCEPT_(__alloc_traits::is_always_equal::value);
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
void __move_assign(basic_string& __str, true_type)
#if _LIBCPP_STD_VER > 14
_NOEXCEPT;
@@ -1680,7 +1745,7 @@ private:
#endif
#endif
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
void
__move_assign_alloc(basic_string& __str)
_NOEXCEPT_(
@@ -1689,78 +1754,83 @@ private:
{__move_assign_alloc(__str, integral_constant<bool,
__alloc_traits::propagate_on_container_move_assignment::value>());}
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
void __move_assign_alloc(basic_string& __c, true_type)
_NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
{
- __alloc() = _VSTD::move(__c.__alloc());
+ __alloc() = std::move(__c.__alloc());
}
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
void __move_assign_alloc(basic_string&, false_type)
_NOEXCEPT
{}
- basic_string& __assign_external(const value_type* __s);
- basic_string& __assign_external(const value_type* __s, size_type __n);
+ _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& __assign_external(const value_type* __s);
+ _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& __assign_external(const value_type* __s, size_type __n);
// Assigns the value in __s, guaranteed to be __n < __min_cap in length.
inline basic_string& __assign_short(const value_type* __s, size_type __n) {
pointer __p = __is_long()
? (__set_long_size(__n), __get_long_pointer())
: (__set_short_size(__n), __get_short_pointer());
- traits_type::move(_VSTD::__to_address(__p), __s, __n);
+ traits_type::move(std::__to_address(__p), __s, __n);
traits_type::assign(__p[__n], value_type());
return *this;
}
- _LIBCPP_HIDE_FROM_ABI basic_string& __null_terminate_at(value_type* __p, size_type __newsz) {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
+ basic_string& __null_terminate_at(value_type* __p, size_type __newsz) {
__set_size(__newsz);
__invalidate_iterators_past(__newsz);
traits_type::assign(__p[__newsz], value_type());
return *this;
}
- _LIBCPP_INLINE_VISIBILITY void __invalidate_all_iterators();
- _LIBCPP_INLINE_VISIBILITY void __invalidate_iterators_past(size_type);
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void __invalidate_iterators_past(size_type);
template<class _Tp>
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
bool __addr_in_range(_Tp&& __t) const {
- const volatile void *__p = _VSTD::addressof(__t);
+ // assume that the ranges overlap, because we can't check during constant evaluation
+ if (__libcpp_is_constant_evaluated())
+ return true;
+ const volatile void *__p = std::addressof(__t);
return data() <= __p && __p <= data() + size();
}
_LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI
void __throw_length_error() const {
- _VSTD::__throw_length_error("basic_string");
+ std::__throw_length_error("basic_string");
}
_LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI
void __throw_out_of_range() const {
- _VSTD::__throw_out_of_range("basic_string");
+ std::__throw_out_of_range("basic_string");
}
- friend basic_string operator+<>(const basic_string&, const basic_string&);
- friend basic_string operator+<>(const value_type*, const basic_string&);
- friend basic_string operator+<>(value_type, const basic_string&);
- friend basic_string operator+<>(const basic_string&, const value_type*);
- friend basic_string operator+<>(const basic_string&, value_type);
+ friend _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string operator+<>(const basic_string&, const basic_string&);
+ friend _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string operator+<>(const value_type*, const basic_string&);
+ friend _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string operator+<>(value_type, const basic_string&);
+ friend _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string operator+<>(const basic_string&, const value_type*);
+ friend _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string operator+<>(const basic_string&, value_type);
};
// These declarations must appear before any functions are implicitly used
// so that they have the correct visibility specifier.
+#define _LIBCPP_DECLARE(...) extern template __VA_ARGS__;
#ifdef _LIBCPP_ABI_STRING_OPTIMIZED_EXTERNAL_INSTANTIATION
- _LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE, char)
+ _LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_LIBCPP_DECLARE, char)
# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
- _LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE, wchar_t)
+ _LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_LIBCPP_DECLARE, wchar_t)
# endif
#else
- _LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE, char)
+ _LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_LIBCPP_DECLARE, char)
# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
- _LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE, wchar_t)
+ _LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_LIBCPP_DECLARE, wchar_t)
# endif
#endif
+#undef _LIBCPP_DECLARE
#if _LIBCPP_STD_VER >= 17
@@ -1792,22 +1862,11 @@ basic_string(basic_string_view<_CharT, _Traits>, _Sz, _Sz, const _Allocator& = _
#endif
template <class _CharT, class _Traits, class _Allocator>
-inline
-void
-basic_string<_CharT, _Traits, _Allocator>::__invalidate_all_iterators()
-{
-#if _LIBCPP_DEBUG_LEVEL == 2
- if (!__libcpp_is_constant_evaluated())
- __get_db()->__invalidate_all(this);
-#endif
-}
-
-template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
void
basic_string<_CharT, _Traits, _Allocator>::__invalidate_iterators_past(size_type __pos)
{
-#if _LIBCPP_DEBUG_LEVEL == 2
+#ifdef _LIBCPP_ENABLE_DEBUG_MODE
if (!__libcpp_is_constant_evaluated()) {
__c_node* __c = __get_db()->__find_c_and_lock(this);
if (__c)
@@ -1821,7 +1880,7 @@ basic_string<_CharT, _Traits, _Allocator>::__invalidate_iterators_past(size_type
{
(*__p)->__c_ = nullptr;
if (--__c->end_ != __p)
- _VSTD::memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*));
+ std::memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*));
}
}
__get_db()->unlock();
@@ -1829,21 +1888,21 @@ basic_string<_CharT, _Traits, _Allocator>::__invalidate_iterators_past(size_type
}
#else
(void)__pos;
-#endif // _LIBCPP_DEBUG_LEVEL == 2
+#endif // _LIBCPP_ENABLE_DEBUG_MODE
}
template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<_CharT, _Traits, _Allocator>::basic_string()
_NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
: __r_(__default_init_tag(), __default_init_tag())
{
- _VSTD::__debug_db_insert_c(this);
- __zero();
+ std::__debug_db_insert_c(this);
+ __default_init();
}
template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<_CharT, _Traits, _Allocator>::basic_string(const allocator_type& __a)
#if _LIBCPP_STD_VER <= 14
_NOEXCEPT_(is_nothrow_copy_constructible<allocator_type>::value)
@@ -1852,15 +1911,18 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const allocator_type& __
#endif
: __r_(__default_init_tag(), __a)
{
- _VSTD::__debug_db_insert_c(this);
- __zero();
+ std::__debug_db_insert_c(this);
+ __default_init();
}
template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
void basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s,
size_type __sz,
size_type __reserve)
{
+ if (__libcpp_is_constant_evaluated())
+ __zero();
if (__reserve > max_size())
__throw_length_error();
pointer __p;
@@ -1871,20 +1933,24 @@ void basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s,
}
else
{
- size_type __cap = __recommend(__reserve);
- __p = __alloc_traits::allocate(__alloc(), __cap+1);
+ auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__reserve) + 1);
+ __p = __allocation.ptr;
+ __begin_lifetime(__p, __allocation.count);
__set_long_pointer(__p);
- __set_long_cap(__cap+1);
+ __set_long_cap(__allocation.count);
__set_long_size(__sz);
}
- traits_type::copy(_VSTD::__to_address(__p), __s, __sz);
+ traits_type::copy(std::__to_address(__p), __s, __sz);
traits_type::assign(__p[__sz], value_type());
}
template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
void
basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_type __sz)
{
+ if (__libcpp_is_constant_evaluated())
+ __zero();
if (__sz > max_size())
__throw_length_error();
pointer __p;
@@ -1895,59 +1961,63 @@ basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_ty
}
else
{
- size_type __cap = __recommend(__sz);
- __p = __alloc_traits::allocate(__alloc(), __cap+1);
+ auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__sz) + 1);
+ __p = __allocation.ptr;
+ __begin_lifetime(__p, __allocation.count);
__set_long_pointer(__p);
- __set_long_cap(__cap+1);
+ __set_long_cap(__allocation.count);
__set_long_size(__sz);
}
- traits_type::copy(_VSTD::__to_address(__p), __s, __sz);
+ traits_type::copy(std::__to_address(__p), __s, __sz);
traits_type::assign(__p[__sz], value_type());
}
template <class _CharT, class _Traits, class _Allocator>
template <class>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, const _Allocator& __a)
: __r_(__default_init_tag(), __a)
{
_LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*, allocator) detected nullptr");
__init(__s, traits_type::length(__s));
- _VSTD::__debug_db_insert_c(this);
+ std::__debug_db_insert_c(this);
}
template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, size_type __n)
: __r_(__default_init_tag(), __default_init_tag())
{
_LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n) detected nullptr");
__init(__s, __n);
- _VSTD::__debug_db_insert_c(this);
+ std::__debug_db_insert_c(this);
}
template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, size_type __n, const _Allocator& __a)
: __r_(__default_init_tag(), __a)
{
_LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n, allocator) detected nullptr");
__init(__s, __n);
- _VSTD::__debug_db_insert_c(this);
+ std::__debug_db_insert_c(this);
}
template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str)
: __r_(__default_init_tag(), __alloc_traits::select_on_container_copy_construction(__str.__alloc()))
{
if (!__str.__is_long())
__r_.first().__r = __str.__r_.first().__r;
else
- __init_copy_ctor_external(_VSTD::__to_address(__str.__get_long_pointer()),
+ __init_copy_ctor_external(std::__to_address(__str.__get_long_pointer()),
__str.__get_long_size());
- _VSTD::__debug_db_insert_c(this);
+ std::__debug_db_insert_c(this);
}
template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<_CharT, _Traits, _Allocator>::basic_string(
const basic_string& __str, const allocator_type& __a)
: __r_(__default_init_tag(), __a)
@@ -1955,14 +2025,17 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(
if (!__str.__is_long())
__r_.first().__r = __str.__r_.first().__r;
else
- __init_copy_ctor_external(_VSTD::__to_address(__str.__get_long_pointer()),
+ __init_copy_ctor_external(std::__to_address(__str.__get_long_pointer()),
__str.__get_long_size());
- _VSTD::__debug_db_insert_c(this);
+ std::__debug_db_insert_c(this);
}
template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
void basic_string<_CharT, _Traits, _Allocator>::__init_copy_ctor_external(
const value_type* __s, size_type __sz) {
+ if (__libcpp_is_constant_evaluated())
+ __zero();
pointer __p;
if (__fits_in_sso(__sz)) {
__p = __get_short_pointer();
@@ -1970,60 +2043,65 @@ void basic_string<_CharT, _Traits, _Allocator>::__init_copy_ctor_external(
} else {
if (__sz > max_size())
__throw_length_error();
- size_t __cap = __recommend(__sz);
- __p = __alloc_traits::allocate(__alloc(), __cap + 1);
+ auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__sz) + 1);
+ __p = __allocation.ptr;
+ __begin_lifetime(__p, __allocation.count);
__set_long_pointer(__p);
- __set_long_cap(__cap + 1);
+ __set_long_cap(__allocation.count);
__set_long_size(__sz);
}
- traits_type::copy(_VSTD::__to_address(__p), __s, __sz + 1);
+ traits_type::copy(std::__to_address(__p), __s, __sz + 1);
}
#ifndef _LIBCPP_CXX03_LANG
template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<_CharT, _Traits, _Allocator>::basic_string(basic_string&& __str)
#if _LIBCPP_STD_VER <= 14
_NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
#else
_NOEXCEPT
#endif
- : __r_(_VSTD::move(__str.__r_))
+ : __r_(std::move(__str.__r_))
{
- __str.__zero();
- _VSTD::__debug_db_insert_c(this);
-#if _LIBCPP_DEBUG_LEVEL == 2
- if (!__libcpp_is_constant_evaluated() && __is_long())
- __get_db()->swap(this, &__str);
-#endif
+ __str.__default_init();
+ std::__debug_db_insert_c(this);
+ if (__is_long())
+ std::__debug_db_swap(this, &__str);
}
template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<_CharT, _Traits, _Allocator>::basic_string(basic_string&& __str, const allocator_type& __a)
: __r_(__default_init_tag(), __a)
{
if (__str.__is_long() && __a != __str.__alloc()) // copy, not move
- __init(_VSTD::__to_address(__str.__get_long_pointer()), __str.__get_long_size());
+ __init(std::__to_address(__str.__get_long_pointer()), __str.__get_long_size());
else
{
- __r_.first().__r = __str.__r_.first().__r;
- __str.__zero();
+ if (__libcpp_is_constant_evaluated()) {
+ __zero();
+ __r_.first().__l = __str.__r_.first().__l;
+ } else {
+ __r_.first().__r = __str.__r_.first().__r;
+ }
+ __str.__default_init();
}
- _VSTD::__debug_db_insert_c(this);
-#if _LIBCPP_DEBUG_LEVEL == 2
- if (!__libcpp_is_constant_evaluated() && __is_long())
- __get_db()->swap(this, &__str);
-#endif
+ std::__debug_db_insert_c(this);
+ if (__is_long())
+ std::__debug_db_swap(this, &__str);
}
#endif // _LIBCPP_CXX03_LANG
template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
void
basic_string<_CharT, _Traits, _Allocator>::__init(size_type __n, value_type __c)
{
+ if (__libcpp_is_constant_evaluated())
+ __zero();
if (__n > max_size())
__throw_length_error();
pointer __p;
@@ -2034,35 +2112,38 @@ basic_string<_CharT, _Traits, _Allocator>::__init(size_type __n, value_type __c)
}
else
{
- size_type __cap = __recommend(__n);
- __p = __alloc_traits::allocate(__alloc(), __cap+1);
+ auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__n) + 1);
+ __p = __allocation.ptr;
+ __begin_lifetime(__p, __allocation.count);
__set_long_pointer(__p);
- __set_long_cap(__cap+1);
+ __set_long_cap(__allocation.count);
__set_long_size(__n);
}
- traits_type::assign(_VSTD::__to_address(__p), __n, __c);
+ traits_type::assign(std::__to_address(__p), __n, __c);
traits_type::assign(__p[__n], value_type());
}
template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, _CharT __c)
: __r_(__default_init_tag(), __default_init_tag())
{
__init(__n, __c);
- _VSTD::__debug_db_insert_c(this);
+ std::__debug_db_insert_c(this);
}
template <class _CharT, class _Traits, class _Allocator>
template <class>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, _CharT __c, const _Allocator& __a)
: __r_(__default_init_tag(), __a)
{
__init(__n, __c);
- _VSTD::__debug_db_insert_c(this);
+ std::__debug_db_insert_c(this);
}
template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str,
size_type __pos, size_type __n,
const _Allocator& __a)
@@ -2071,12 +2152,12 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __st
size_type __str_sz = __str.size();
if (__pos > __str_sz)
__throw_out_of_range();
- __init(__str.data() + __pos, _VSTD::min(__n, __str_sz - __pos));
- _VSTD::__debug_db_insert_c(this);
+ __init(__str.data() + __pos, std::min(__n, __str_sz - __pos));
+ std::__debug_db_insert_c(this);
}
template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str, size_type __pos,
const _Allocator& __a)
: __r_(__default_init_tag(), __a)
@@ -2085,11 +2166,12 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __st
if (__pos > __str_sz)
__throw_out_of_range();
__init(__str.data() + __pos, __str_sz - __pos);
- _VSTD::__debug_db_insert_c(this);
+ std::__debug_db_insert_c(this);
}
template <class _CharT, class _Traits, class _Allocator>
template <class _Tp, class>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<_CharT, _Traits, _Allocator>::basic_string(
const _Tp& __t, size_type __pos, size_type __n, const allocator_type& __a)
: __r_(__default_init_tag(), __a)
@@ -2097,38 +2179,41 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(
__self_view __sv0 = __t;
__self_view __sv = __sv0.substr(__pos, __n);
__init(__sv.data(), __sv.size());
- _VSTD::__debug_db_insert_c(this);
+ std::__debug_db_insert_c(this);
}
template <class _CharT, class _Traits, class _Allocator>
template <class _Tp, class>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<_CharT, _Traits, _Allocator>::basic_string(const _Tp & __t)
: __r_(__default_init_tag(), __default_init_tag())
{
__self_view __sv = __t;
__init(__sv.data(), __sv.size());
- _VSTD::__debug_db_insert_c(this);
+ std::__debug_db_insert_c(this);
}
template <class _CharT, class _Traits, class _Allocator>
template <class _Tp, class>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<_CharT, _Traits, _Allocator>::basic_string(const _Tp & __t, const _Allocator& __a)
: __r_(__default_init_tag(), __a)
{
__self_view __sv = __t;
__init(__sv.data(), __sv.size());
- _VSTD::__debug_db_insert_c(this);
+ std::__debug_db_insert_c(this);
}
template <class _CharT, class _Traits, class _Allocator>
template <class _InputIterator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
__enable_if_t
<
__is_exactly_cpp17_input_iterator<_InputIterator>::value
>
basic_string<_CharT, _Traits, _Allocator>::__init(_InputIterator __first, _InputIterator __last)
{
- __zero();
+ __default_init();
#ifndef _LIBCPP_NO_EXCEPTIONS
try
{
@@ -2148,13 +2233,16 @@ basic_string<_CharT, _Traits, _Allocator>::__init(_InputIterator __first, _Input
template <class _CharT, class _Traits, class _Allocator>
template <class _ForwardIterator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
__enable_if_t
<
__is_cpp17_forward_iterator<_ForwardIterator>::value
>
basic_string<_CharT, _Traits, _Allocator>::__init(_ForwardIterator __first, _ForwardIterator __last)
{
- size_type __sz = static_cast<size_type>(_VSTD::distance(__first, __last));
+ if (__libcpp_is_constant_evaluated())
+ __zero();
+ size_type __sz = static_cast<size_type>(std::distance(__first, __last));
if (__sz > max_size())
__throw_length_error();
pointer __p;
@@ -2165,10 +2253,11 @@ basic_string<_CharT, _Traits, _Allocator>::__init(_ForwardIterator __first, _For
}
else
{
- size_type __cap = __recommend(__sz);
- __p = __alloc_traits::allocate(__alloc(), __cap+1);
+ auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__sz) + 1);
+ __p = __allocation.ptr;
+ __begin_lifetime(__p, __allocation.count);
__set_long_pointer(__p);
- __set_long_cap(__cap+1);
+ __set_long_cap(__allocation.count);
__set_long_size(__sz);
}
@@ -2192,62 +2281,60 @@ basic_string<_CharT, _Traits, _Allocator>::__init(_ForwardIterator __first, _For
template <class _CharT, class _Traits, class _Allocator>
template<class _InputIterator, class>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<_CharT, _Traits, _Allocator>::basic_string(_InputIterator __first, _InputIterator __last)
: __r_(__default_init_tag(), __default_init_tag())
{
__init(__first, __last);
- _VSTD::__debug_db_insert_c(this);
+ std::__debug_db_insert_c(this);
}
template <class _CharT, class _Traits, class _Allocator>
template<class _InputIterator, class>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<_CharT, _Traits, _Allocator>::basic_string(_InputIterator __first, _InputIterator __last,
const allocator_type& __a)
: __r_(__default_init_tag(), __a)
{
__init(__first, __last);
- _VSTD::__debug_db_insert_c(this);
+ std::__debug_db_insert_c(this);
}
#ifndef _LIBCPP_CXX03_LANG
template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<_CharT, _Traits, _Allocator>::basic_string(
initializer_list<_CharT> __il)
: __r_(__default_init_tag(), __default_init_tag())
{
__init(__il.begin(), __il.end());
- _VSTD::__debug_db_insert_c(this);
+ std::__debug_db_insert_c(this);
}
template <class _CharT, class _Traits, class _Allocator>
-inline
-
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<_CharT, _Traits, _Allocator>::basic_string(
initializer_list<_CharT> __il, const _Allocator& __a)
: __r_(__default_init_tag(), __a)
{
__init(__il.begin(), __il.end());
- _VSTD::__debug_db_insert_c(this);
+ std::__debug_db_insert_c(this);
}
#endif // _LIBCPP_CXX03_LANG
template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<_CharT, _Traits, _Allocator>::~basic_string()
{
-#if _LIBCPP_DEBUG_LEVEL == 2
- if (!__libcpp_is_constant_evaluated())
- __get_db()->__erase_c(this);
-#endif
+ std::__debug_db_erase_c(this);
if (__is_long())
__alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap());
}
template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
void
basic_string<_CharT, _Traits, _Allocator>::__grow_by_and_replace
(size_type __old_cap, size_type __delta_cap, size_type __old_sz,
@@ -2258,23 +2345,25 @@ basic_string<_CharT, _Traits, _Allocator>::__grow_by_and_replace
__throw_length_error();
pointer __old_p = __get_pointer();
size_type __cap = __old_cap < __ms / 2 - __alignment ?
- __recommend(_VSTD::max(__old_cap + __delta_cap, 2 * __old_cap)) :
+ __recommend(std::max(__old_cap + __delta_cap, 2 * __old_cap)) :
__ms - 1;
- pointer __p = __alloc_traits::allocate(__alloc(), __cap+1);
- __invalidate_all_iterators();
+ auto __allocation = std::__allocate_at_least(__alloc(), __cap + 1);
+ pointer __p = __allocation.ptr;
+ __begin_lifetime(__p, __allocation.count);
+ std::__debug_db_invalidate_all(this);
if (__n_copy != 0)
- traits_type::copy(_VSTD::__to_address(__p),
- _VSTD::__to_address(__old_p), __n_copy);
+ traits_type::copy(std::__to_address(__p),
+ std::__to_address(__old_p), __n_copy);
if (__n_add != 0)
- traits_type::copy(_VSTD::__to_address(__p) + __n_copy, __p_new_stuff, __n_add);
+ traits_type::copy(std::__to_address(__p) + __n_copy, __p_new_stuff, __n_add);
size_type __sec_cp_sz = __old_sz - __n_del - __n_copy;
if (__sec_cp_sz != 0)
- traits_type::copy(_VSTD::__to_address(__p) + __n_copy + __n_add,
- _VSTD::__to_address(__old_p) + __n_copy + __n_del, __sec_cp_sz);
- if (__old_cap+1 != __min_cap)
+ traits_type::copy(std::__to_address(__p) + __n_copy + __n_add,
+ std::__to_address(__old_p) + __n_copy + __n_del, __sec_cp_sz);
+ if (__old_cap+1 != __min_cap || __libcpp_is_constant_evaluated())
__alloc_traits::deallocate(__alloc(), __old_p, __old_cap+1);
__set_long_pointer(__p);
- __set_long_cap(__cap+1);
+ __set_long_cap(__allocation.count);
__old_sz = __n_copy + __n_add + __sec_cp_sz;
__set_long_size(__old_sz);
traits_type::assign(__p[__old_sz], value_type());
@@ -2282,6 +2371,7 @@ basic_string<_CharT, _Traits, _Allocator>::__grow_by_and_replace
template <class _CharT, class _Traits, class _Allocator>
void
+_LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<_CharT, _Traits, _Allocator>::__grow_by(size_type __old_cap, size_type __delta_cap, size_type __old_sz,
size_type __n_copy, size_type __n_del, size_type __n_add)
{
@@ -2290,36 +2380,39 @@ basic_string<_CharT, _Traits, _Allocator>::__grow_by(size_type __old_cap, size_t
__throw_length_error();
pointer __old_p = __get_pointer();
size_type __cap = __old_cap < __ms / 2 - __alignment ?
- __recommend(_VSTD::max(__old_cap + __delta_cap, 2 * __old_cap)) :
+ __recommend(std::max(__old_cap + __delta_cap, 2 * __old_cap)) :
__ms - 1;
- pointer __p = __alloc_traits::allocate(__alloc(), __cap+1);
- __invalidate_all_iterators();
+ auto __allocation = std::__allocate_at_least(__alloc(), __cap + 1);
+ pointer __p = __allocation.ptr;
+ __begin_lifetime(__p, __allocation.count);
+ std::__debug_db_invalidate_all(this);
if (__n_copy != 0)
- traits_type::copy(_VSTD::__to_address(__p),
- _VSTD::__to_address(__old_p), __n_copy);
+ traits_type::copy(std::__to_address(__p),
+ std::__to_address(__old_p), __n_copy);
size_type __sec_cp_sz = __old_sz - __n_del - __n_copy;
if (__sec_cp_sz != 0)
- traits_type::copy(_VSTD::__to_address(__p) + __n_copy + __n_add,
- _VSTD::__to_address(__old_p) + __n_copy + __n_del,
+ traits_type::copy(std::__to_address(__p) + __n_copy + __n_add,
+ std::__to_address(__old_p) + __n_copy + __n_del,
__sec_cp_sz);
- if (__old_cap+1 != __min_cap)
- __alloc_traits::deallocate(__alloc(), __old_p, __old_cap+1);
+ if (__libcpp_is_constant_evaluated() || __old_cap + 1 != __min_cap)
+ __alloc_traits::deallocate(__alloc(), __old_p, __old_cap + 1);
__set_long_pointer(__p);
- __set_long_cap(__cap+1);
+ __set_long_cap(__allocation.count);
}
// assign
template <class _CharT, class _Traits, class _Allocator>
template <bool __is_short>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<_CharT, _Traits, _Allocator>&
basic_string<_CharT, _Traits, _Allocator>::__assign_no_alias(
const value_type* __s, size_type __n) {
- size_type __cap = __is_short ? __min_cap : __get_long_cap();
+ size_type __cap = __is_short ? static_cast<size_type>(__min_cap) : __get_long_cap();
if (__n < __cap) {
pointer __p = __is_short ? __get_short_pointer() : __get_long_pointer();
__is_short ? __set_short_size(__n) : __set_long_size(__n);
- traits_type::copy(_VSTD::__to_address(__p), __s, __n);
+ traits_type::copy(std::__to_address(__p), __s, __n);
traits_type::assign(__p[__n], value_type());
__invalidate_iterators_past(__n);
} else {
@@ -2330,12 +2423,13 @@ basic_string<_CharT, _Traits, _Allocator>::__assign_no_alias(
}
template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<_CharT, _Traits, _Allocator>&
basic_string<_CharT, _Traits, _Allocator>::__assign_external(
const value_type* __s, size_type __n) {
size_type __cap = capacity();
if (__cap >= __n) {
- value_type* __p = _VSTD::__to_address(__get_pointer());
+ value_type* __p = std::__to_address(__get_pointer());
traits_type::move(__p, __s, __n);
return __null_terminate_at(__p, __n);
} else {
@@ -2346,6 +2440,7 @@ basic_string<_CharT, _Traits, _Allocator>::__assign_external(
}
template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<_CharT, _Traits, _Allocator>&
basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s, size_type __n)
{
@@ -2356,6 +2451,7 @@ basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s, size_ty
}
template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<_CharT, _Traits, _Allocator>&
basic_string<_CharT, _Traits, _Allocator>::assign(size_type __n, value_type __c)
{
@@ -2365,12 +2461,13 @@ basic_string<_CharT, _Traits, _Allocator>::assign(size_type __n, value_type __c)
size_type __sz = size();
__grow_by(__cap, __n - __cap, __sz, 0, __sz);
}
- value_type* __p = _VSTD::__to_address(__get_pointer());
+ value_type* __p = std::__to_address(__get_pointer());
traits_type::assign(__p, __n, __c);
return __null_terminate_at(__p, __n);
}
template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<_CharT, _Traits, _Allocator>&
basic_string<_CharT, _Traits, _Allocator>::operator=(value_type __c)
{
@@ -2392,6 +2489,7 @@ basic_string<_CharT, _Traits, _Allocator>::operator=(value_type __c)
}
template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<_CharT, _Traits, _Allocator>&
basic_string<_CharT, _Traits, _Allocator>::operator=(const basic_string& __str)
{
@@ -2413,7 +2511,7 @@ basic_string<_CharT, _Traits, _Allocator>::operator=(const basic_string& __str)
#ifndef _LIBCPP_CXX03_LANG
template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
void
basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, false_type)
_NOEXCEPT_(__alloc_traits::is_always_equal::value)
@@ -2425,7 +2523,7 @@ basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, fa
}
template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
void
basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, true_type)
#if _LIBCPP_STD_VER > 14
@@ -2446,12 +2544,16 @@ basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, tr
}
__move_assign_alloc(__str);
__r_.first() = __str.__r_.first();
- __str.__set_short_size(0);
- traits_type::assign(__str.__get_short_pointer()[0], value_type());
+ if (__libcpp_is_constant_evaluated()) {
+ __str.__default_init();
+ } else {
+ __str.__set_short_size(0);
+ traits_type::assign(__str.__get_short_pointer()[0], value_type());
+ }
}
template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<_CharT, _Traits, _Allocator>&
basic_string<_CharT, _Traits, _Allocator>::operator=(basic_string&& __str)
_NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value))
@@ -2465,6 +2567,7 @@ basic_string<_CharT, _Traits, _Allocator>::operator=(basic_string&& __str)
template <class _CharT, class _Traits, class _Allocator>
template<class _InputIterator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
__enable_if_t
<
__is_exactly_cpp17_input_iterator<_InputIterator>::value,
@@ -2479,6 +2582,7 @@ basic_string<_CharT, _Traits, _Allocator>::assign(_InputIterator __first, _Input
template <class _CharT, class _Traits, class _Allocator>
template<class _ForwardIterator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
__enable_if_t
<
__is_cpp17_forward_iterator<_ForwardIterator>::value,
@@ -2488,7 +2592,7 @@ basic_string<_CharT, _Traits, _Allocator>::assign(_ForwardIterator __first, _For
{
size_type __cap = capacity();
size_type __n = __string_is_trivial_iterator<_ForwardIterator>::value ?
- static_cast<size_type>(_VSTD::distance(__first, __last)) : 0;
+ static_cast<size_type>(std::distance(__first, __last)) : 0;
if (__string_is_trivial_iterator<_ForwardIterator>::value &&
(__cap >= __n || !__addr_in_range(*__first)))
@@ -2514,17 +2618,19 @@ basic_string<_CharT, _Traits, _Allocator>::assign(_ForwardIterator __first, _For
}
template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<_CharT, _Traits, _Allocator>&
basic_string<_CharT, _Traits, _Allocator>::assign(const basic_string& __str, size_type __pos, size_type __n)
{
size_type __sz = __str.size();
if (__pos > __sz)
__throw_out_of_range();
- return assign(__str.data() + __pos, _VSTD::min(__n, __sz - __pos));
+ return assign(__str.data() + __pos, std::min(__n, __sz - __pos));
}
template <class _CharT, class _Traits, class _Allocator>
template <class _Tp>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
__enable_if_t
<
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value
@@ -2537,17 +2643,19 @@ basic_string<_CharT, _Traits, _Allocator>::assign(const _Tp & __t, size_type __p
size_type __sz = __sv.size();
if (__pos > __sz)
__throw_out_of_range();
- return assign(__sv.data() + __pos, _VSTD::min(__n, __sz - __pos));
+ return assign(__sv.data() + __pos, std::min(__n, __sz - __pos));
}
template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<_CharT, _Traits, _Allocator>&
basic_string<_CharT, _Traits, _Allocator>::__assign_external(const value_type* __s) {
return __assign_external(__s, traits_type::length(__s));
}
template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<_CharT, _Traits, _Allocator>&
basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s)
{
@@ -2561,6 +2669,7 @@ basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s)
// append
template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<_CharT, _Traits, _Allocator>&
basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s, size_type __n)
{
@@ -2571,7 +2680,7 @@ basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s, size_ty
{
if (__n)
{
- value_type* __p = _VSTD::__to_address(__get_pointer());
+ value_type* __p = std::__to_address(__get_pointer());
traits_type::copy(__p + __sz, __s, __n);
__sz += __n;
__set_size(__sz);
@@ -2584,6 +2693,7 @@ basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s, size_ty
}
template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<_CharT, _Traits, _Allocator>&
basic_string<_CharT, _Traits, _Allocator>::append(size_type __n, value_type __c)
{
@@ -2594,7 +2704,7 @@ basic_string<_CharT, _Traits, _Allocator>::append(size_type __n, value_type __c)
if (__cap - __sz < __n)
__grow_by(__cap, __sz + __n - __cap, __sz, __sz, 0);
pointer __p = __get_pointer();
- traits_type::assign(_VSTD::__to_address(__p) + __sz, __n, __c);
+ traits_type::assign(std::__to_address(__p) + __sz, __n, __c);
__sz += __n;
__set_size(__sz);
traits_type::assign(__p[__sz], value_type());
@@ -2603,7 +2713,7 @@ basic_string<_CharT, _Traits, _Allocator>::append(size_type __n, value_type __c)
}
template <class _CharT, class _Traits, class _Allocator>
-inline void
+_LIBCPP_CONSTEXPR_AFTER_CXX17 inline void
basic_string<_CharT, _Traits, _Allocator>::__append_default_init(size_type __n)
{
if (__n)
@@ -2620,6 +2730,7 @@ basic_string<_CharT, _Traits, _Allocator>::__append_default_init(size_type __n)
}
template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
void
basic_string<_CharT, _Traits, _Allocator>::push_back(value_type __c)
{
@@ -2641,7 +2752,7 @@ basic_string<_CharT, _Traits, _Allocator>::push_back(value_type __c)
__grow_by(__cap, 1, __sz, __sz, 0);
__is_short = false; // the string is always long after __grow_by
}
- pointer __p;
+ pointer __p = __get_pointer();
if (__is_short)
{
__p = __get_short_pointer() + __sz;
@@ -2658,6 +2769,7 @@ basic_string<_CharT, _Traits, _Allocator>::push_back(value_type __c)
template <class _CharT, class _Traits, class _Allocator>
template<class _ForwardIterator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
__enable_if_t
<
__is_cpp17_forward_iterator<_ForwardIterator>::value,
@@ -2668,7 +2780,7 @@ basic_string<_CharT, _Traits, _Allocator>::append(
{
size_type __sz = size();
size_type __cap = capacity();
- size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last));
+ size_type __n = static_cast<size_type>(std::distance(__first, __last));
if (__n)
{
if (__string_is_trivial_iterator<_ForwardIterator>::value &&
@@ -2692,7 +2804,7 @@ basic_string<_CharT, _Traits, _Allocator>::append(
}
template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<_CharT, _Traits, _Allocator>&
basic_string<_CharT, _Traits, _Allocator>::append(const basic_string& __str)
{
@@ -2700,17 +2812,19 @@ basic_string<_CharT, _Traits, _Allocator>::append(const basic_string& __str)
}
template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<_CharT, _Traits, _Allocator>&
basic_string<_CharT, _Traits, _Allocator>::append(const basic_string& __str, size_type __pos, size_type __n)
{
size_type __sz = __str.size();
if (__pos > __sz)
__throw_out_of_range();
- return append(__str.data() + __pos, _VSTD::min(__n, __sz - __pos));
+ return append(__str.data() + __pos, std::min(__n, __sz - __pos));
}
template <class _CharT, class _Traits, class _Allocator>
template <class _Tp>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
__enable_if_t
<
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
@@ -2722,10 +2836,11 @@ basic_string<_CharT, _Traits, _Allocator>::append(const _Tp & __t, size_type __p
size_type __sz = __sv.size();
if (__pos > __sz)
__throw_out_of_range();
- return append(__sv.data() + __pos, _VSTD::min(__n, __sz - __pos));
+ return append(__sv.data() + __pos, std::min(__n, __sz - __pos));
}
template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<_CharT, _Traits, _Allocator>&
basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s)
{
@@ -2736,6 +2851,7 @@ basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s)
// insert
template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<_CharT, _Traits, _Allocator>&
basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_type* __s, size_type __n)
{
@@ -2744,11 +2860,18 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_t
if (__pos > __sz)
__throw_out_of_range();
size_type __cap = capacity();
+ if (__libcpp_is_constant_evaluated()) {
+ if (__cap - __sz >= __n)
+ __grow_by_and_replace(__cap, 0, __sz, __pos, 0, __n, __s);
+ else
+ __grow_by_and_replace(__cap, __sz + __n - __cap, __sz, __pos, 0, __n, __s);
+ return *this;
+ }
if (__cap - __sz >= __n)
{
if (__n)
{
- value_type* __p = _VSTD::__to_address(__get_pointer());
+ value_type* __p = std::__to_address(__get_pointer());
size_type __n_move = __sz - __pos;
if (__n_move != 0)
{
@@ -2768,6 +2891,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_t
}
template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<_CharT, _Traits, _Allocator>&
basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, size_type __n, value_type __c)
{
@@ -2780,7 +2904,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, size_type __n
value_type* __p;
if (__cap - __sz >= __n)
{
- __p = _VSTD::__to_address(__get_pointer());
+ __p = std::__to_address(__get_pointer());
size_type __n_move = __sz - __pos;
if (__n_move != 0)
traits_type::move(__p + __pos + __n, __p + __pos, __n_move);
@@ -2788,7 +2912,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, size_type __n
else
{
__grow_by(__cap, __sz + __n - __cap, __sz, __pos, 0, __n);
- __p = _VSTD::__to_address(__get_long_pointer());
+ __p = std::__to_address(__get_long_pointer());
}
traits_type::assign(__p + __pos, __n, __c);
__sz += __n;
@@ -2800,6 +2924,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, size_type __n
template <class _CharT, class _Traits, class _Allocator>
template<class _InputIterator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
__enable_if_t
<
__is_exactly_cpp17_input_iterator<_InputIterator>::value,
@@ -2816,6 +2941,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _InputIt
template <class _CharT, class _Traits, class _Allocator>
template<class _ForwardIterator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
__enable_if_t
<
__is_cpp17_forward_iterator<_ForwardIterator>::value,
@@ -2823,49 +2949,27 @@ __enable_if_t
>
basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last)
{
- _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this,
- "string::insert(iterator, range) called with an iterator not"
- " referring to this string");
+ _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this,
+ "string::insert(iterator, range) called with an iterator not referring to this string");
size_type __ip = static_cast<size_type>(__pos - begin());
- size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last));
- if (__n)
+ size_type __n = static_cast<size_type>(std::distance(__first, __last));
+ if (__n == 0)
+ return begin() + __ip;
+
+ if (__string_is_trivial_iterator<_ForwardIterator>::value && !__addr_in_range(*__first))
{
- if (__string_is_trivial_iterator<_ForwardIterator>::value &&
- !__addr_in_range(*__first))
- {
- size_type __sz = size();
- size_type __cap = capacity();
- value_type* __p;
- if (__cap - __sz >= __n)
- {
- __p = _VSTD::__to_address(__get_pointer());
- size_type __n_move = __sz - __ip;
- if (__n_move != 0)
- traits_type::move(__p + __ip + __n, __p + __ip, __n_move);
- }
- else
- {
- __grow_by(__cap, __sz + __n - __cap, __sz, __ip, 0, __n);
- __p = _VSTD::__to_address(__get_long_pointer());
- }
- __sz += __n;
- __set_size(__sz);
- traits_type::assign(__p[__sz], value_type());
- for (__p += __ip; __first != __last; ++__p, (void) ++__first)
- traits_type::assign(*__p, *__first);
- }
- else
- {
- const basic_string __temp(__first, __last, __alloc());
- return insert(__pos, __temp.data(), __temp.data() + __temp.size());
- }
+ return __insert_from_safe_copy(__n, __ip, __first, __last);
+ }
+ else
+ {
+ const basic_string __temp(__first, __last, __alloc());
+ return __insert_from_safe_copy(__n, __ip, __temp.begin(), __temp.end());
}
- return begin() + __ip;
}
template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<_CharT, _Traits, _Allocator>&
basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const basic_string& __str)
{
@@ -2873,6 +2977,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const basic_
}
template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<_CharT, _Traits, _Allocator>&
basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const basic_string& __str,
size_type __pos2, size_type __n)
@@ -2880,11 +2985,12 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const basic_
size_type __str_sz = __str.size();
if (__pos2 > __str_sz)
__throw_out_of_range();
- return insert(__pos1, __str.data() + __pos2, _VSTD::min(__n, __str_sz - __pos2));
+ return insert(__pos1, __str.data() + __pos2, std::min(__n, __str_sz - __pos2));
}
template <class _CharT, class _Traits, class _Allocator>
template <class _Tp>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
__enable_if_t
<
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
@@ -2897,10 +3003,11 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const _Tp& _
size_type __str_sz = __sv.size();
if (__pos2 > __str_sz)
__throw_out_of_range();
- return insert(__pos1, __sv.data() + __pos2, _VSTD::min(__n, __str_sz - __pos2));
+ return insert(__pos1, __sv.data() + __pos2, std::min(__n, __str_sz - __pos2));
}
template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<_CharT, _Traits, _Allocator>&
basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_type* __s)
{
@@ -2909,9 +3016,14 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_t
}
template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
typename basic_string<_CharT, _Traits, _Allocator>::iterator
basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, value_type __c)
{
+ _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this,
+ "string::insert(iterator, character) called with an iterator not"
+ " referring to this string");
+
size_type __ip = static_cast<size_type>(__pos - begin());
size_type __sz = size();
size_type __cap = capacity();
@@ -2919,11 +3031,11 @@ basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, value_ty
if (__cap == __sz)
{
__grow_by(__cap, 1, __sz, __ip, 0, 1);
- __p = _VSTD::__to_address(__get_long_pointer());
+ __p = std::__to_address(__get_long_pointer());
}
else
{
- __p = _VSTD::__to_address(__get_pointer());
+ __p = std::__to_address(__get_pointer());
size_type __n_move = __sz - __ip;
if (__n_move != 0)
traits_type::move(__p + __ip + 1, __p + __ip, __n_move);
@@ -2935,7 +3047,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, value_ty
}
template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
typename basic_string<_CharT, _Traits, _Allocator>::iterator
basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, size_type __n, value_type __c)
{
@@ -2950,6 +3062,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, size_typ
// replace
template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<_CharT, _Traits, _Allocator>&
basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, const value_type* __s, size_type __n2)
_LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
@@ -2958,11 +3071,15 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __
size_type __sz = size();
if (__pos > __sz)
__throw_out_of_range();
- __n1 = _VSTD::min(__n1, __sz - __pos);
+ __n1 = std::min(__n1, __sz - __pos);
size_type __cap = capacity();
if (__cap - __sz + __n1 >= __n2)
{
- value_type* __p = _VSTD::__to_address(__get_pointer());
+ if (__libcpp_is_constant_evaluated()) {
+ __grow_by_and_replace(__cap, 0, __sz, __pos, __n1, __n2, __s);
+ return *this;
+ }
+ value_type* __p = std::__to_address(__get_pointer());
if (__n1 != __n2)
{
size_type __n_move = __sz - __pos - __n1;
@@ -2999,18 +3116,19 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __
}
template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<_CharT, _Traits, _Allocator>&
basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, size_type __n2, value_type __c)
{
size_type __sz = size();
if (__pos > __sz)
__throw_out_of_range();
- __n1 = _VSTD::min(__n1, __sz - __pos);
+ __n1 = std::min(__n1, __sz - __pos);
size_type __cap = capacity();
value_type* __p;
if (__cap - __sz + __n1 >= __n2)
{
- __p = _VSTD::__to_address(__get_pointer());
+ __p = std::__to_address(__get_pointer());
if (__n1 != __n2)
{
size_type __n_move = __sz - __pos - __n1;
@@ -3021,7 +3139,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __
else
{
__grow_by(__cap, __sz - __n1 + __n2 - __cap, __sz, __pos, __n1, __n2);
- __p = _VSTD::__to_address(__get_long_pointer());
+ __p = std::__to_address(__get_long_pointer());
}
traits_type::assign(__p + __pos, __n2, __c);
return __null_terminate_at(__p, __sz - (__n1 - __n2));
@@ -3029,6 +3147,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __
template <class _CharT, class _Traits, class _Allocator>
template<class _InputIterator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
__enable_if_t
<
__is_cpp17_input_iterator<_InputIterator>::value,
@@ -3042,7 +3161,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_it
}
template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<_CharT, _Traits, _Allocator>&
basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type __n1, const basic_string& __str)
{
@@ -3050,6 +3169,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type _
}
template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<_CharT, _Traits, _Allocator>&
basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type __n1, const basic_string& __str,
size_type __pos2, size_type __n2)
@@ -3057,11 +3177,12 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type _
size_type __str_sz = __str.size();
if (__pos2 > __str_sz)
__throw_out_of_range();
- return replace(__pos1, __n1, __str.data() + __pos2, _VSTD::min(__n2, __str_sz - __pos2));
+ return replace(__pos1, __n1, __str.data() + __pos2, std::min(__n2, __str_sz - __pos2));
}
template <class _CharT, class _Traits, class _Allocator>
template <class _Tp>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
__enable_if_t
<
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
@@ -3074,10 +3195,11 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type _
size_type __str_sz = __sv.size();
if (__pos2 > __str_sz)
__throw_out_of_range();
- return replace(__pos1, __n1, __sv.data() + __pos2, _VSTD::min(__n2, __str_sz - __pos2));
+ return replace(__pos1, __n1, __sv.data() + __pos2, std::min(__n2, __str_sz - __pos2));
}
template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<_CharT, _Traits, _Allocator>&
basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, const value_type* __s)
{
@@ -3086,7 +3208,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __
}
template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<_CharT, _Traits, _Allocator>&
basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, const basic_string& __str)
{
@@ -3095,7 +3217,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_it
}
template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<_CharT, _Traits, _Allocator>&
basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, const value_type* __s, size_type __n)
{
@@ -3103,7 +3225,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_it
}
template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<_CharT, _Traits, _Allocator>&
basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, const value_type* __s)
{
@@ -3111,7 +3233,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_it
}
template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<_CharT, _Traits, _Allocator>&
basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, size_type __n, value_type __c)
{
@@ -3123,6 +3245,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_it
// 'externally instantiated' erase() implementation, called when __n != npos.
// Does not check __pos against size()
template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
void
basic_string<_CharT, _Traits, _Allocator>::__erase_external_with_move(
size_type __pos, size_type __n)
@@ -3130,8 +3253,8 @@ basic_string<_CharT, _Traits, _Allocator>::__erase_external_with_move(
if (__n)
{
size_type __sz = size();
- value_type* __p = _VSTD::__to_address(__get_pointer());
- __n = _VSTD::min(__n, __sz - __pos);
+ value_type* __p = std::__to_address(__get_pointer());
+ __n = std::min(__n, __sz - __pos);
size_type __n_move = __sz - __pos - __n;
if (__n_move != 0)
traits_type::move(__p + __pos, __p + __pos + __n, __n_move);
@@ -3140,6 +3263,7 @@ basic_string<_CharT, _Traits, _Allocator>::__erase_external_with_move(
}
template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<_CharT, _Traits, _Allocator>&
basic_string<_CharT, _Traits, _Allocator>::erase(size_type __pos,
size_type __n) {
@@ -3154,7 +3278,7 @@ basic_string<_CharT, _Traits, _Allocator>::erase(size_type __pos,
}
template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
typename basic_string<_CharT, _Traits, _Allocator>::iterator
basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __pos)
{
@@ -3170,7 +3294,7 @@ basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __pos)
}
template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
typename basic_string<_CharT, _Traits, _Allocator>::iterator
basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __first, const_iterator __last)
{
@@ -3186,7 +3310,7 @@ basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __first, const_i
}
template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
void
basic_string<_CharT, _Traits, _Allocator>::pop_back()
{
@@ -3195,11 +3319,11 @@ basic_string<_CharT, _Traits, _Allocator>::pop_back()
}
template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
void
basic_string<_CharT, _Traits, _Allocator>::clear() _NOEXCEPT
{
- __invalidate_all_iterators();
+ std::__debug_db_invalidate_all(this);
if (__is_long())
{
traits_type::assign(*__get_long_pointer(), value_type());
@@ -3213,14 +3337,15 @@ basic_string<_CharT, _Traits, _Allocator>::clear() _NOEXCEPT
}
template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
void
basic_string<_CharT, _Traits, _Allocator>::__erase_to_end(size_type __pos)
{
- __null_terminate_at(_VSTD::__to_address(__get_pointer()), __pos);
+ __null_terminate_at(std::__to_address(__get_pointer()), __pos);
}
template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
void
basic_string<_CharT, _Traits, _Allocator>::resize(size_type __n, value_type __c)
{
@@ -3232,7 +3357,7 @@ basic_string<_CharT, _Traits, _Allocator>::resize(size_type __n, value_type __c)
}
template <class _CharT, class _Traits, class _Allocator>
-inline void
+_LIBCPP_CONSTEXPR_AFTER_CXX17 inline void
basic_string<_CharT, _Traits, _Allocator>::__resize_default_init(size_type __n)
{
size_type __sz = size();
@@ -3243,19 +3368,21 @@ basic_string<_CharT, _Traits, _Allocator>::__resize_default_init(size_type __n)
}
template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
typename basic_string<_CharT, _Traits, _Allocator>::size_type
basic_string<_CharT, _Traits, _Allocator>::max_size() const _NOEXCEPT
{
size_type __m = __alloc_traits::max_size(__alloc());
-#ifdef _LIBCPP_BIG_ENDIAN
- return (__m <= ~__long_mask ? __m : __m/2) - __alignment;
-#else
- return __m - __alignment;
-#endif
+ if (__m <= std::numeric_limits<size_type>::max() / 2) {
+ return __m - __alignment;
+ } else {
+ bool __uses_lsb = __endian_factor == 2;
+ return __uses_lsb ? __m - __alignment : (__m / 2) - __alignment;
+ }
}
template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
void
basic_string<_CharT, _Traits, _Allocator>::reserve(size_type __requested_capacity)
{
@@ -3268,7 +3395,7 @@ basic_string<_CharT, _Traits, _Allocator>::reserve(size_type __requested_capacit
if (__requested_capacity <= capacity())
return;
- size_type __target_capacity = _VSTD::max(__requested_capacity, size());
+ size_type __target_capacity = std::max(__requested_capacity, size());
__target_capacity = __recommend(__target_capacity);
if (__target_capacity == capacity()) return;
@@ -3276,7 +3403,7 @@ basic_string<_CharT, _Traits, _Allocator>::reserve(size_type __requested_capacit
}
template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
void
basic_string<_CharT, _Traits, _Allocator>::shrink_to_fit() _NOEXCEPT
{
@@ -3287,7 +3414,7 @@ basic_string<_CharT, _Traits, _Allocator>::shrink_to_fit() _NOEXCEPT
}
template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
void
basic_string<_CharT, _Traits, _Allocator>::__shrink_or_extend(size_type __target_capacity)
{
@@ -3296,7 +3423,7 @@ basic_string<_CharT, _Traits, _Allocator>::__shrink_or_extend(size_type __target
pointer __new_data, __p;
bool __was_long, __now_long;
- if (__target_capacity == __min_cap - 1)
+ if (__fits_in_sso(__target_capacity))
{
__was_long = true;
__now_long = false;
@@ -3305,15 +3432,20 @@ basic_string<_CharT, _Traits, _Allocator>::__shrink_or_extend(size_type __target
}
else
{
- if (__target_capacity > __cap)
- __new_data = __alloc_traits::allocate(__alloc(), __target_capacity+1);
+ if (__target_capacity > __cap) {
+ auto __allocation = std::__allocate_at_least(__alloc(), __target_capacity + 1);
+ __new_data = __allocation.ptr;
+ __target_capacity = __allocation.count - 1;
+ }
else
{
#ifndef _LIBCPP_NO_EXCEPTIONS
try
{
#endif // _LIBCPP_NO_EXCEPTIONS
- __new_data = __alloc_traits::allocate(__alloc(), __target_capacity+1);
+ auto __allocation = std::__allocate_at_least(__alloc(), __target_capacity + 1);
+ __new_data = __allocation.ptr;
+ __target_capacity = __allocation.count - 1;
#ifndef _LIBCPP_NO_EXCEPTIONS
}
catch (...)
@@ -3325,12 +3457,13 @@ basic_string<_CharT, _Traits, _Allocator>::__shrink_or_extend(size_type __target
return;
#endif // _LIBCPP_NO_EXCEPTIONS
}
+ __begin_lifetime(__new_data, __target_capacity + 1);
__now_long = true;
__was_long = __is_long();
__p = __get_pointer();
}
- traits_type::copy(_VSTD::__to_address(__new_data),
- _VSTD::__to_address(__p), size()+1);
+ traits_type::copy(std::__to_address(__new_data),
+ std::__to_address(__p), size()+1);
if (__was_long)
__alloc_traits::deallocate(__alloc(), __p, __cap+1);
if (__now_long)
@@ -3341,11 +3474,11 @@ basic_string<_CharT, _Traits, _Allocator>::__shrink_or_extend(size_type __target
}
else
__set_short_size(__sz);
- __invalidate_all_iterators();
+ std::__debug_db_invalidate_all(this);
}
template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
typename basic_string<_CharT, _Traits, _Allocator>::const_reference
basic_string<_CharT, _Traits, _Allocator>::operator[](size_type __pos) const _NOEXCEPT
{
@@ -3354,7 +3487,7 @@ basic_string<_CharT, _Traits, _Allocator>::operator[](size_type __pos) const _NO
}
template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
typename basic_string<_CharT, _Traits, _Allocator>::reference
basic_string<_CharT, _Traits, _Allocator>::operator[](size_type __pos) _NOEXCEPT
{
@@ -3363,6 +3496,7 @@ basic_string<_CharT, _Traits, _Allocator>::operator[](size_type __pos) _NOEXCEPT
}
template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
typename basic_string<_CharT, _Traits, _Allocator>::const_reference
basic_string<_CharT, _Traits, _Allocator>::at(size_type __n) const
{
@@ -3372,6 +3506,7 @@ basic_string<_CharT, _Traits, _Allocator>::at(size_type __n) const
}
template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
typename basic_string<_CharT, _Traits, _Allocator>::reference
basic_string<_CharT, _Traits, _Allocator>::at(size_type __n)
{
@@ -3381,7 +3516,7 @@ basic_string<_CharT, _Traits, _Allocator>::at(size_type __n)
}
template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
typename basic_string<_CharT, _Traits, _Allocator>::reference
basic_string<_CharT, _Traits, _Allocator>::front() _NOEXCEPT
{
@@ -3390,7 +3525,7 @@ basic_string<_CharT, _Traits, _Allocator>::front() _NOEXCEPT
}
template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
typename basic_string<_CharT, _Traits, _Allocator>::const_reference
basic_string<_CharT, _Traits, _Allocator>::front() const _NOEXCEPT
{
@@ -3399,7 +3534,7 @@ basic_string<_CharT, _Traits, _Allocator>::front() const _NOEXCEPT
}
template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
typename basic_string<_CharT, _Traits, _Allocator>::reference
basic_string<_CharT, _Traits, _Allocator>::back() _NOEXCEPT
{
@@ -3408,7 +3543,7 @@ basic_string<_CharT, _Traits, _Allocator>::back() _NOEXCEPT
}
template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
typename basic_string<_CharT, _Traits, _Allocator>::const_reference
basic_string<_CharT, _Traits, _Allocator>::back() const _NOEXCEPT
{
@@ -3417,19 +3552,20 @@ basic_string<_CharT, _Traits, _Allocator>::back() const _NOEXCEPT
}
template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
typename basic_string<_CharT, _Traits, _Allocator>::size_type
basic_string<_CharT, _Traits, _Allocator>::copy(value_type* __s, size_type __n, size_type __pos) const
{
size_type __sz = size();
if (__pos > __sz)
__throw_out_of_range();
- size_type __rlen = _VSTD::min(__n, __sz - __pos);
+ size_type __rlen = std::min(__n, __sz - __pos);
traits_type::copy(__s, data() + __pos, __rlen);
return __rlen;
}
template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<_CharT, _Traits, _Allocator>
basic_string<_CharT, _Traits, _Allocator>::substr(size_type __pos, size_type __n) const
{
@@ -3437,7 +3573,7 @@ basic_string<_CharT, _Traits, _Allocator>::substr(size_type __pos, size_type __n
}
template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
void
basic_string<_CharT, _Traits, _Allocator>::swap(basic_string& __str)
#if _LIBCPP_STD_VER >= 14
@@ -3447,21 +3583,18 @@ basic_string<_CharT, _Traits, _Allocator>::swap(basic_string& __str)
__is_nothrow_swappable<allocator_type>::value)
#endif
{
-#if _LIBCPP_DEBUG_LEVEL == 2
- if (!__libcpp_is_constant_evaluated()) {
- if (!__is_long())
- __get_db()->__invalidate_all(this);
- if (!__str.__is_long())
- __get_db()->__invalidate_all(&__str);
- __get_db()->swap(this, &__str);
- }
-#endif
+ if (!__is_long())
+ std::__debug_db_invalidate_all(this);
+ if (!__str.__is_long())
+ std::__debug_db_invalidate_all(&__str);
+ std::__debug_db_swap(this, &__str);
+
_LIBCPP_ASSERT(
__alloc_traits::propagate_on_container_swap::value ||
__alloc_traits::is_always_equal::value ||
__alloc() == __str.__alloc(), "swapping non-equal allocators");
- _VSTD::swap(__r_.first(), __str.__r_.first());
- _VSTD::__swap_allocator(__alloc(), __str.__alloc());
+ std::swap(__r_.first(), __str.__r_.first());
+ std::__swap_allocator(__alloc(), __str.__alloc());
}
// find
@@ -3470,12 +3603,13 @@ template <class _Traits>
struct _LIBCPP_HIDDEN __traits_eq
{
typedef typename _Traits::char_type char_type;
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI
bool operator()(const char_type& __x, const char_type& __y) _NOEXCEPT
{return _Traits::eq(__x, __y);}
};
template<class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
typename basic_string<_CharT, _Traits, _Allocator>::size_type
basic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s,
size_type __pos,
@@ -3487,7 +3621,7 @@ basic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s,
}
template<class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
typename basic_string<_CharT, _Traits, _Allocator>::size_type
basic_string<_CharT, _Traits, _Allocator>::find(const basic_string& __str,
size_type __pos) const _NOEXCEPT
@@ -3498,6 +3632,7 @@ basic_string<_CharT, _Traits, _Allocator>::find(const basic_string& __str,
template<class _CharT, class _Traits, class _Allocator>
template <class _Tp>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
__enable_if_t
<
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
@@ -3512,7 +3647,7 @@ basic_string<_CharT, _Traits, _Allocator>::find(const _Tp &__t,
}
template<class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
typename basic_string<_CharT, _Traits, _Allocator>::size_type
basic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s,
size_type __pos) const _NOEXCEPT
@@ -3523,6 +3658,7 @@ basic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s,
}
template<class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
typename basic_string<_CharT, _Traits, _Allocator>::size_type
basic_string<_CharT, _Traits, _Allocator>::find(value_type __c,
size_type __pos) const _NOEXCEPT
@@ -3534,6 +3670,7 @@ basic_string<_CharT, _Traits, _Allocator>::find(value_type __c,
// rfind
template<class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
typename basic_string<_CharT, _Traits, _Allocator>::size_type
basic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s,
size_type __pos,
@@ -3545,7 +3682,7 @@ basic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s,
}
template<class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
typename basic_string<_CharT, _Traits, _Allocator>::size_type
basic_string<_CharT, _Traits, _Allocator>::rfind(const basic_string& __str,
size_type __pos) const _NOEXCEPT
@@ -3556,6 +3693,7 @@ basic_string<_CharT, _Traits, _Allocator>::rfind(const basic_string& __str,
template<class _CharT, class _Traits, class _Allocator>
template <class _Tp>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
__enable_if_t
<
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
@@ -3570,7 +3708,7 @@ basic_string<_CharT, _Traits, _Allocator>::rfind(const _Tp& __t,
}
template<class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
typename basic_string<_CharT, _Traits, _Allocator>::size_type
basic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s,
size_type __pos) const _NOEXCEPT
@@ -3581,6 +3719,7 @@ basic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s,
}
template<class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
typename basic_string<_CharT, _Traits, _Allocator>::size_type
basic_string<_CharT, _Traits, _Allocator>::rfind(value_type __c,
size_type __pos) const _NOEXCEPT
@@ -3592,6 +3731,7 @@ basic_string<_CharT, _Traits, _Allocator>::rfind(value_type __c,
// find_first_of
template<class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
typename basic_string<_CharT, _Traits, _Allocator>::size_type
basic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s,
size_type __pos,
@@ -3603,7 +3743,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s,
}
template<class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
typename basic_string<_CharT, _Traits, _Allocator>::size_type
basic_string<_CharT, _Traits, _Allocator>::find_first_of(const basic_string& __str,
size_type __pos) const _NOEXCEPT
@@ -3614,6 +3754,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_of(const basic_string& __s
template<class _CharT, class _Traits, class _Allocator>
template <class _Tp>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
__enable_if_t
<
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
@@ -3628,7 +3769,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_of(const _Tp& __t,
}
template<class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
typename basic_string<_CharT, _Traits, _Allocator>::size_type
basic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s,
size_type __pos) const _NOEXCEPT
@@ -3639,7 +3780,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s,
}
template<class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
typename basic_string<_CharT, _Traits, _Allocator>::size_type
basic_string<_CharT, _Traits, _Allocator>::find_first_of(value_type __c,
size_type __pos) const _NOEXCEPT
@@ -3650,6 +3791,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_of(value_type __c,
// find_last_of
template<class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
typename basic_string<_CharT, _Traits, _Allocator>::size_type
basic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s,
size_type __pos,
@@ -3661,7 +3803,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s,
}
template<class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
typename basic_string<_CharT, _Traits, _Allocator>::size_type
basic_string<_CharT, _Traits, _Allocator>::find_last_of(const basic_string& __str,
size_type __pos) const _NOEXCEPT
@@ -3672,6 +3814,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_of(const basic_string& __st
template<class _CharT, class _Traits, class _Allocator>
template <class _Tp>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
__enable_if_t
<
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
@@ -3686,7 +3829,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_of(const _Tp& __t,
}
template<class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
typename basic_string<_CharT, _Traits, _Allocator>::size_type
basic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s,
size_type __pos) const _NOEXCEPT
@@ -3697,7 +3840,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s,
}
template<class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
typename basic_string<_CharT, _Traits, _Allocator>::size_type
basic_string<_CharT, _Traits, _Allocator>::find_last_of(value_type __c,
size_type __pos) const _NOEXCEPT
@@ -3708,6 +3851,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_of(value_type __c,
// find_first_not_of
template<class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
typename basic_string<_CharT, _Traits, _Allocator>::size_type
basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* __s,
size_type __pos,
@@ -3719,7 +3863,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* _
}
template<class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
typename basic_string<_CharT, _Traits, _Allocator>::size_type
basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const basic_string& __str,
size_type __pos) const _NOEXCEPT
@@ -3730,6 +3874,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const basic_string&
template<class _CharT, class _Traits, class _Allocator>
template <class _Tp>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
__enable_if_t
<
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
@@ -3744,7 +3889,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const _Tp& __t,
}
template<class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
typename basic_string<_CharT, _Traits, _Allocator>::size_type
basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* __s,
size_type __pos) const _NOEXCEPT
@@ -3755,7 +3900,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* _
}
template<class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
typename basic_string<_CharT, _Traits, _Allocator>::size_type
basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(value_type __c,
size_type __pos) const _NOEXCEPT
@@ -3767,6 +3912,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(value_type __c,
// find_last_not_of
template<class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
typename basic_string<_CharT, _Traits, _Allocator>::size_type
basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __s,
size_type __pos,
@@ -3778,7 +3924,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __
}
template<class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
typename basic_string<_CharT, _Traits, _Allocator>::size_type
basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const basic_string& __str,
size_type __pos) const _NOEXCEPT
@@ -3789,6 +3935,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const basic_string&
template<class _CharT, class _Traits, class _Allocator>
template <class _Tp>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
__enable_if_t
<
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
@@ -3803,7 +3950,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const _Tp& __t,
}
template<class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
typename basic_string<_CharT, _Traits, _Allocator>::size_type
basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __s,
size_type __pos) const _NOEXCEPT
@@ -3814,7 +3961,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __
}
template<class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
typename basic_string<_CharT, _Traits, _Allocator>::size_type
basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(value_type __c,
size_type __pos) const _NOEXCEPT
@@ -3827,6 +3974,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(value_type __c,
template <class _CharT, class _Traits, class _Allocator>
template <class _Tp>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
__enable_if_t
<
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
@@ -3838,7 +3986,7 @@ basic_string<_CharT, _Traits, _Allocator>::compare(const _Tp& __t) const _NOEXCE
size_t __lhs_sz = size();
size_t __rhs_sz = __sv.size();
int __result = traits_type::compare(data(), __sv.data(),
- _VSTD::min(__lhs_sz, __rhs_sz));
+ std::min(__lhs_sz, __rhs_sz));
if (__result != 0)
return __result;
if (__lhs_sz < __rhs_sz)
@@ -3849,7 +3997,7 @@ basic_string<_CharT, _Traits, _Allocator>::compare(const _Tp& __t) const _NOEXCE
}
template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
int
basic_string<_CharT, _Traits, _Allocator>::compare(const basic_string& __str) const _NOEXCEPT
{
@@ -3857,6 +4005,7 @@ basic_string<_CharT, _Traits, _Allocator>::compare(const basic_string& __str) co
}
template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
int
basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
size_type __n1,
@@ -3867,8 +4016,8 @@ basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
size_type __sz = size();
if (__pos1 > __sz || __n2 == npos)
__throw_out_of_range();
- size_type __rlen = _VSTD::min(__n1, __sz - __pos1);
- int __r = traits_type::compare(data() + __pos1, __s, _VSTD::min(__rlen, __n2));
+ size_type __rlen = std::min(__n1, __sz - __pos1);
+ int __r = traits_type::compare(data() + __pos1, __s, std::min(__rlen, __n2));
if (__r == 0)
{
if (__rlen < __n2)
@@ -3881,6 +4030,7 @@ basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
template <class _CharT, class _Traits, class _Allocator>
template <class _Tp>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
__enable_if_t
<
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
@@ -3895,7 +4045,7 @@ basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
}
template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
int
basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
size_type __n1,
@@ -3906,6 +4056,7 @@ basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
template <class _CharT, class _Traits, class _Allocator>
template <class _Tp>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
__enable_if_t
<
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value
@@ -3923,6 +4074,7 @@ basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
}
template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
int
basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
size_type __n1,
@@ -3934,6 +4086,7 @@ basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
}
template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
int
basic_string<_CharT, _Traits, _Allocator>::compare(const value_type* __s) const _NOEXCEPT
{
@@ -3942,6 +4095,7 @@ basic_string<_CharT, _Traits, _Allocator>::compare(const value_type* __s) const
}
template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
int
basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
size_type __n1,
@@ -3954,7 +4108,7 @@ basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
// __invariants
template<class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
bool
basic_string<_CharT, _Traits, _Allocator>::__invariants() const
{
@@ -3972,7 +4126,7 @@ basic_string<_CharT, _Traits, _Allocator>::__invariants() const
// __clear_and_shrink
template<class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
void
basic_string<_CharT, _Traits, _Allocator>::__clear_and_shrink() _NOEXCEPT
{
@@ -3989,7 +4143,7 @@ basic_string<_CharT, _Traits, _Allocator>::__clear_and_shrink() _NOEXCEPT
// operator==
template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI
bool
operator==(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
@@ -4001,7 +4155,7 @@ operator==(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
}
template<class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI
bool
operator==(const basic_string<char, char_traits<char>, _Allocator>& __lhs,
const basic_string<char, char_traits<char>, _Allocator>& __rhs) _NOEXCEPT
@@ -4020,7 +4174,7 @@ operator==(const basic_string<char, char_traits<char>, _Allocator>& __lhs,
}
template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI
bool
operator==(const _CharT* __lhs,
const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
@@ -4033,7 +4187,7 @@ operator==(const _CharT* __lhs,
}
template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI
bool
operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
const _CharT* __rhs) _NOEXCEPT
@@ -4046,7 +4200,7 @@ operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
}
template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI
bool
operator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
@@ -4055,7 +4209,7 @@ operator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
}
template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI
bool
operator!=(const _CharT* __lhs,
const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
@@ -4064,7 +4218,7 @@ operator!=(const _CharT* __lhs,
}
template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI
bool
operator!=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
const _CharT* __rhs) _NOEXCEPT
@@ -4075,7 +4229,7 @@ operator!=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
// operator<
template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI
bool
operator< (const basic_string<_CharT, _Traits, _Allocator>& __lhs,
const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
@@ -4084,7 +4238,7 @@ operator< (const basic_string<_CharT, _Traits, _Allocator>& __lhs,
}
template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI
bool
operator< (const basic_string<_CharT, _Traits, _Allocator>& __lhs,
const _CharT* __rhs) _NOEXCEPT
@@ -4093,7 +4247,7 @@ operator< (const basic_string<_CharT, _Traits, _Allocator>& __lhs,
}
template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI
bool
operator< (const _CharT* __lhs,
const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
@@ -4104,7 +4258,7 @@ operator< (const _CharT* __lhs,
// operator>
template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI
bool
operator> (const basic_string<_CharT, _Traits, _Allocator>& __lhs,
const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
@@ -4113,7 +4267,7 @@ operator> (const basic_string<_CharT, _Traits, _Allocator>& __lhs,
}
template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI
bool
operator> (const basic_string<_CharT, _Traits, _Allocator>& __lhs,
const _CharT* __rhs) _NOEXCEPT
@@ -4122,7 +4276,7 @@ operator> (const basic_string<_CharT, _Traits, _Allocator>& __lhs,
}
template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI
bool
operator> (const _CharT* __lhs,
const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
@@ -4133,7 +4287,7 @@ operator> (const _CharT* __lhs,
// operator<=
template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI
bool
operator<=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
@@ -4142,7 +4296,7 @@ operator<=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
}
template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI
bool
operator<=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
const _CharT* __rhs) _NOEXCEPT
@@ -4151,7 +4305,7 @@ operator<=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
}
template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI
bool
operator<=(const _CharT* __lhs,
const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
@@ -4162,7 +4316,7 @@ operator<=(const _CharT* __lhs,
// operator>=
template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI
bool
operator>=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
@@ -4171,7 +4325,7 @@ operator>=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
}
template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI
bool
operator>=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
const _CharT* __rhs) _NOEXCEPT
@@ -4180,7 +4334,7 @@ operator>=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
}
template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI
bool
operator>=(const _CharT* __lhs,
const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
@@ -4191,123 +4345,152 @@ operator>=(const _CharT* __lhs,
// operator +
template<class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<_CharT, _Traits, _Allocator>
operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
const basic_string<_CharT, _Traits, _Allocator>& __rhs)
{
- basic_string<_CharT, _Traits, _Allocator> __r(__lhs.get_allocator());
- typename basic_string<_CharT, _Traits, _Allocator>::size_type __lhs_sz = __lhs.size();
- typename basic_string<_CharT, _Traits, _Allocator>::size_type __rhs_sz = __rhs.size();
- __r.__init(__lhs.data(), __lhs_sz, __lhs_sz + __rhs_sz);
- __r.append(__rhs.data(), __rhs_sz);
+ using _String = basic_string<_CharT, _Traits, _Allocator>;
+ auto __lhs_sz = __lhs.size();
+ auto __rhs_sz = __rhs.size();
+ _String __r(__uninitialized_size_tag(),
+ __lhs_sz + __rhs_sz,
+ _String::__alloc_traits::select_on_container_copy_construction(__lhs.get_allocator()));
+ auto __ptr = std::__to_address(__r.__get_pointer());
+ _Traits::copy(__ptr, __lhs.data(), __lhs_sz);
+ _Traits::copy(__ptr + __lhs_sz, __rhs.data(), __rhs_sz);
+ _Traits::assign(__ptr + __lhs_sz + __rhs_sz, 1, _CharT());
return __r;
}
template<class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<_CharT, _Traits, _Allocator>
operator+(const _CharT* __lhs , const basic_string<_CharT,_Traits,_Allocator>& __rhs)
{
- basic_string<_CharT, _Traits, _Allocator> __r(__rhs.get_allocator());
- typename basic_string<_CharT, _Traits, _Allocator>::size_type __lhs_sz = _Traits::length(__lhs);
- typename basic_string<_CharT, _Traits, _Allocator>::size_type __rhs_sz = __rhs.size();
- __r.__init(__lhs, __lhs_sz, __lhs_sz + __rhs_sz);
- __r.append(__rhs.data(), __rhs_sz);
+ using _String = basic_string<_CharT, _Traits, _Allocator>;
+ auto __lhs_sz = _Traits::length(__lhs);
+ auto __rhs_sz = __rhs.size();
+ _String __r(__uninitialized_size_tag(),
+ __lhs_sz + __rhs_sz,
+ _String::__alloc_traits::select_on_container_copy_construction(__rhs.get_allocator()));
+ auto __ptr = std::__to_address(__r.__get_pointer());
+ _Traits::copy(__ptr, __lhs, __lhs_sz);
+ _Traits::copy(__ptr + __lhs_sz, __rhs.data(), __rhs_sz);
+ _Traits::assign(__ptr + __lhs_sz + __rhs_sz, 1, _CharT());
return __r;
}
template<class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<_CharT, _Traits, _Allocator>
operator+(_CharT __lhs, const basic_string<_CharT,_Traits,_Allocator>& __rhs)
{
- basic_string<_CharT, _Traits, _Allocator> __r(__rhs.get_allocator());
- typename basic_string<_CharT, _Traits, _Allocator>::size_type __rhs_sz = __rhs.size();
- __r.__init(&__lhs, 1, 1 + __rhs_sz);
- __r.append(__rhs.data(), __rhs_sz);
+ using _String = basic_string<_CharT, _Traits, _Allocator>;
+ typename _String::size_type __rhs_sz = __rhs.size();
+ _String __r(__uninitialized_size_tag(),
+ __rhs_sz + 1,
+ _String::__alloc_traits::select_on_container_copy_construction(__rhs.get_allocator()));
+ auto __ptr = std::__to_address(__r.__get_pointer());
+ _Traits::assign(__ptr, 1, __lhs);
+ _Traits::copy(__ptr + 1, __rhs.data(), __rhs_sz);
+ _Traits::assign(__ptr + 1 + __rhs_sz, 1, _CharT());
return __r;
}
template<class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<_CharT, _Traits, _Allocator>
operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs)
{
- basic_string<_CharT, _Traits, _Allocator> __r(__lhs.get_allocator());
- typename basic_string<_CharT, _Traits, _Allocator>::size_type __lhs_sz = __lhs.size();
- typename basic_string<_CharT, _Traits, _Allocator>::size_type __rhs_sz = _Traits::length(__rhs);
- __r.__init(__lhs.data(), __lhs_sz, __lhs_sz + __rhs_sz);
- __r.append(__rhs, __rhs_sz);
+ using _String = basic_string<_CharT, _Traits, _Allocator>;
+ typename _String::size_type __lhs_sz = __lhs.size();
+ typename _String::size_type __rhs_sz = _Traits::length(__rhs);
+ _String __r(__uninitialized_size_tag(),
+ __lhs_sz + __rhs_sz,
+ _String::__alloc_traits::select_on_container_copy_construction(__lhs.get_allocator()));
+ auto __ptr = std::__to_address(__r.__get_pointer());
+ _Traits::copy(__ptr, __lhs.data(), __lhs_sz);
+ _Traits::copy(__ptr + __lhs_sz, __rhs, __rhs_sz);
+ _Traits::assign(__ptr + __lhs_sz + __rhs_sz, 1, _CharT());
return __r;
}
template<class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<_CharT, _Traits, _Allocator>
operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, _CharT __rhs)
{
- basic_string<_CharT, _Traits, _Allocator> __r(__lhs.get_allocator());
- typename basic_string<_CharT, _Traits, _Allocator>::size_type __lhs_sz = __lhs.size();
- __r.__init(__lhs.data(), __lhs_sz, __lhs_sz + 1);
- __r.push_back(__rhs);
+ using _String = basic_string<_CharT, _Traits, _Allocator>;
+ typename _String::size_type __lhs_sz = __lhs.size();
+ _String __r(__uninitialized_size_tag(),
+ __lhs_sz + 1,
+ _String::__alloc_traits::select_on_container_copy_construction(__lhs.get_allocator()));
+ auto __ptr = std::__to_address(__r.__get_pointer());
+ _Traits::copy(__ptr, __lhs.data(), __lhs_sz);
+ _Traits::assign(__ptr + __lhs_sz, 1, __rhs);
+ _Traits::assign(__ptr + 1 + __lhs_sz, 1, _CharT());
return __r;
}
#ifndef _LIBCPP_CXX03_LANG
template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<_CharT, _Traits, _Allocator>
operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs)
{
- return _VSTD::move(__lhs.append(__rhs));
+ return std::move(__lhs.append(__rhs));
}
template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<_CharT, _Traits, _Allocator>
operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, basic_string<_CharT, _Traits, _Allocator>&& __rhs)
{
- return _VSTD::move(__rhs.insert(0, __lhs));
+ return std::move(__rhs.insert(0, __lhs));
}
template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<_CharT, _Traits, _Allocator>
operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, basic_string<_CharT, _Traits, _Allocator>&& __rhs)
{
- return _VSTD::move(__lhs.append(__rhs));
+ return std::move(__lhs.append(__rhs));
}
template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<_CharT, _Traits, _Allocator>
operator+(const _CharT* __lhs , basic_string<_CharT,_Traits,_Allocator>&& __rhs)
{
- return _VSTD::move(__rhs.insert(0, __lhs));
+ return std::move(__rhs.insert(0, __lhs));
}
template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<_CharT, _Traits, _Allocator>
operator+(_CharT __lhs, basic_string<_CharT,_Traits,_Allocator>&& __rhs)
{
__rhs.insert(__rhs.begin(), __lhs);
- return _VSTD::move(__rhs);
+ return std::move(__rhs);
}
template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<_CharT, _Traits, _Allocator>
operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, const _CharT* __rhs)
{
- return _VSTD::move(__lhs.append(__rhs));
+ return std::move(__lhs.append(__rhs));
}
template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<_CharT, _Traits, _Allocator>
operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, _CharT __rhs)
{
__lhs.push_back(__rhs);
- return _VSTD::move(__lhs);
+ return std::move(__lhs);
}
#endif // _LIBCPP_CXX03_LANG
@@ -4315,7 +4498,7 @@ operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, _CharT __rhs)
// swap
template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
void
swap(basic_string<_CharT, _Traits, _Allocator>& __lhs,
basic_string<_CharT, _Traits, _Allocator>& __rhs)
@@ -4374,15 +4557,13 @@ const typename basic_string<_CharT, _Traits, _Allocator>::size_type
template <class _CharT, class _Allocator>
struct _LIBCPP_TEMPLATE_VIS
hash<basic_string<_CharT, char_traits<_CharT>, _Allocator> >
- : public unary_function<
- basic_string<_CharT, char_traits<_CharT>, _Allocator>, size_t>
+ : public __unary_function<basic_string<_CharT, char_traits<_CharT>, _Allocator>, size_t>
{
size_t
operator()(const basic_string<_CharT, char_traits<_CharT>, _Allocator>& __val) const _NOEXCEPT
{ return __do_string_hash(__val.data(), __val.data() + __val.size()); }
};
-
template<class _CharT, class _Traits, class _Allocator>
basic_ostream<_CharT, _Traits>&
operator<<(basic_ostream<_CharT, _Traits>& __os,
@@ -4399,68 +4580,68 @@ getline(basic_istream<_CharT, _Traits>& __is,
basic_string<_CharT, _Traits, _Allocator>& __str, _CharT __dlm);
template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_HIDE_FROM_ABI
basic_istream<_CharT, _Traits>&
getline(basic_istream<_CharT, _Traits>& __is,
basic_string<_CharT, _Traits, _Allocator>& __str);
template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_HIDE_FROM_ABI
basic_istream<_CharT, _Traits>&
getline(basic_istream<_CharT, _Traits>&& __is,
basic_string<_CharT, _Traits, _Allocator>& __str, _CharT __dlm);
template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_HIDE_FROM_ABI
basic_istream<_CharT, _Traits>&
getline(basic_istream<_CharT, _Traits>&& __is,
basic_string<_CharT, _Traits, _Allocator>& __str);
#if _LIBCPP_STD_VER > 17
template <class _CharT, class _Traits, class _Allocator, class _Up>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_HIDE_FROM_ABI
typename basic_string<_CharT, _Traits, _Allocator>::size_type
erase(basic_string<_CharT, _Traits, _Allocator>& __str, const _Up& __v) {
auto __old_size = __str.size();
- __str.erase(_VSTD::remove(__str.begin(), __str.end(), __v), __str.end());
+ __str.erase(std::remove(__str.begin(), __str.end(), __v), __str.end());
return __old_size - __str.size();
}
template <class _CharT, class _Traits, class _Allocator, class _Predicate>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_HIDE_FROM_ABI
typename basic_string<_CharT, _Traits, _Allocator>::size_type
erase_if(basic_string<_CharT, _Traits, _Allocator>& __str,
_Predicate __pred) {
auto __old_size = __str.size();
- __str.erase(_VSTD::remove_if(__str.begin(), __str.end(), __pred),
+ __str.erase(std::remove_if(__str.begin(), __str.end(), __pred),
__str.end());
return __old_size - __str.size();
}
#endif
-#if _LIBCPP_DEBUG_LEVEL == 2
+#ifdef _LIBCPP_ENABLE_DEBUG_MODE
template<class _CharT, class _Traits, class _Allocator>
bool
basic_string<_CharT, _Traits, _Allocator>::__dereferenceable(const const_iterator* __i) const
{
- return data() <= _VSTD::__to_address(__i->base()) &&
- _VSTD::__to_address(__i->base()) < data() + size();
+ return data() <= std::__to_address(__i->base()) &&
+ std::__to_address(__i->base()) < data() + size();
}
template<class _CharT, class _Traits, class _Allocator>
bool
basic_string<_CharT, _Traits, _Allocator>::__decrementable(const const_iterator* __i) const
{
- return data() < _VSTD::__to_address(__i->base()) &&
- _VSTD::__to_address(__i->base()) <= data() + size();
+ return data() < std::__to_address(__i->base()) &&
+ std::__to_address(__i->base()) <= data() + size();
}
template<class _CharT, class _Traits, class _Allocator>
bool
basic_string<_CharT, _Traits, _Allocator>::__addable(const const_iterator* __i, ptrdiff_t __n) const
{
- const value_type* __p = _VSTD::__to_address(__i->base()) + __n;
+ const value_type* __p = std::__to_address(__i->base()) + __n;
return data() <= __p && __p <= data() + size();
}
@@ -4468,11 +4649,11 @@ template<class _CharT, class _Traits, class _Allocator>
bool
basic_string<_CharT, _Traits, _Allocator>::__subscriptable(const const_iterator* __i, ptrdiff_t __n) const
{
- const value_type* __p = _VSTD::__to_address(__i->base()) + __n;
+ const value_type* __p = std::__to_address(__i->base()) + __n;
return data() <= __p && __p < data() + size();
}
-#endif // _LIBCPP_DEBUG_LEVEL == 2
+#endif // _LIBCPP_ENABLE_DEBUG_MODE
#if _LIBCPP_STD_VER > 11
// Literal suffixes for basic_string [basic.string.literals]
@@ -4480,14 +4661,14 @@ inline namespace literals
{
inline namespace string_literals
{
- inline _LIBCPP_INLINE_VISIBILITY
+ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<char> operator "" s( const char *__str, size_t __len )
{
return basic_string<char> (__str, __len);
}
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
- inline _LIBCPP_INLINE_VISIBILITY
+ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<wchar_t> operator "" s( const wchar_t *__str, size_t __len )
{
return basic_string<wchar_t> (__str, __len);
@@ -4495,26 +4676,36 @@ inline namespace literals
#endif
#ifndef _LIBCPP_HAS_NO_CHAR8_T
- inline _LIBCPP_INLINE_VISIBILITY
+ inline _LIBCPP_HIDE_FROM_ABI constexpr
basic_string<char8_t> operator "" s(const char8_t *__str, size_t __len) _NOEXCEPT
{
return basic_string<char8_t> (__str, __len);
}
#endif
- inline _LIBCPP_INLINE_VISIBILITY
+ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<char16_t> operator "" s( const char16_t *__str, size_t __len )
{
return basic_string<char16_t> (__str, __len);
}
- inline _LIBCPP_INLINE_VISIBILITY
+ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
basic_string<char32_t> operator "" s( const char32_t *__str, size_t __len )
{
return basic_string<char32_t> (__str, __len);
}
} // namespace string_literals
} // namespace literals
+
+#if _LIBCPP_STD_VER > 17
+template <>
+inline constexpr bool __format::__enable_insertable<std::basic_string<char>> = true;
+#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+template <>
+inline constexpr bool __format::__enable_insertable<std::basic_string<wchar_t>> = true;
+#endif
+#endif
+
#endif
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/string.h b/libcxx/include/string.h
index e5a8cfaf1928..082c632a29bc 100644
--- a/libcxx/include/string.h
+++ b/libcxx/include/string.h
@@ -54,7 +54,7 @@ size_t strlen(const char* s);
#include <__config>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
#include_next <string.h>
diff --git a/libcxx/include/string_view b/libcxx/include/string_view
index 992e88ea3c00..28013e7cb08e 100644
--- a/libcxx/include/string_view
+++ b/libcxx/include/string_view
@@ -11,7 +11,8 @@
#define _LIBCPP_STRING_VIEW
/*
-string_view synopsis
+
+ string_view synopsis
namespace std {
@@ -195,25 +196,48 @@ namespace std {
*/
+#include <__algorithm/min.h>
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
-#include <__debug>
+#include <__functional/hash.h>
+#include <__functional/unary_function.h>
+#include <__fwd/string_view.h>
+#include <__iterator/concepts.h>
+#include <__iterator/readable_traits.h>
+#include <__iterator/reverse_iterator.h>
+#include <__memory/pointer_traits.h>
#include <__ranges/concepts.h>
#include <__ranges/data.h>
#include <__ranges/enable_borrowed_range.h>
#include <__ranges/enable_view.h>
#include <__ranges/size.h>
-#include <__string>
-#include <algorithm>
-#include <compare>
+#include <__string/char_traits.h>
#include <iosfwd>
-#include <iterator>
#include <limits>
#include <stdexcept>
#include <type_traits>
#include <version>
+#ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES
+# include <algorithm>
+# include <functional>
+# include <iterator>
+#endif
+
+// standard-mandated includes
+
+// [iterator.range]
+#include <__iterator/access.h>
+#include <__iterator/data.h>
+#include <__iterator/empty.h>
+#include <__iterator/reverse_access.h>
+#include <__iterator/size.h>
+
+// [string.view.synop]
+#include <compare>
+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
@@ -222,18 +246,14 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD
-template<class _CharT, class _Traits = char_traits<_CharT> >
- class _LIBCPP_TEMPLATE_VIS basic_string_view;
-
-typedef basic_string_view<char> string_view;
-#ifndef _LIBCPP_HAS_NO_CHAR8_T
-typedef basic_string_view<char8_t> u8string_view;
-#endif
-typedef basic_string_view<char16_t> u16string_view;
-typedef basic_string_view<char32_t> u32string_view;
-#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-typedef basic_string_view<wchar_t> wstring_view;
-#endif
+// TODO: This is a workaround for some vendors to carry a downstream diff to accept `nullptr` in
+// string_view constructors. This can be refactored when this exact form isn't needed anymore.
+template <class _Traits>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
+inline size_t __char_traits_length_checked(const typename _Traits::char_type* __s) _NOEXCEPT {
+ // This needs to be a single statement for C++11 constexpr
+ return _LIBCPP_ASSERT(__s != nullptr, "null pointer passed to non-null argument of char_traits<...>::length"), _Traits::length(__s);
+}
template<class _CharT, class _Traits>
class
@@ -286,7 +306,7 @@ public:
#endif
}
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17
template <contiguous_iterator _It, sized_sentinel_for<_It> _End>
requires (is_same_v<iter_value_t<_It>, _CharT> && !is_convertible_v<_End, size_type>)
constexpr _LIBCPP_HIDE_FROM_ABI basic_string_view(_It __begin, _End __end)
@@ -294,9 +314,9 @@ public:
{
_LIBCPP_ASSERT((__end - __begin) >= 0, "std::string_view::string_view(iterator, sentinel) received invalid range");
}
-#endif
+#endif // _LIBCPP_STD_VER > 17
-#if _LIBCPP_STD_VER > 20 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 20 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
template <class _Range>
requires (
!is_same_v<remove_cvref_t<_Range>, basic_string_view> &&
@@ -313,7 +333,7 @@ public:
)
constexpr _LIBCPP_HIDE_FROM_ABI
basic_string_view(_Range&& __r) : __data(ranges::data(__r)), __size(ranges::size(__r)) {}
-#endif
+#endif // _LIBCPP_STD_VER > 20 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
_LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
basic_string_view(const _CharT* __s)
@@ -707,26 +727,26 @@ private:
size_type __size;
};
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17
template <class _CharT, class _Traits>
inline constexpr bool ranges::enable_view<basic_string_view<_CharT, _Traits>> = true;
template <class _CharT, class _Traits>
inline constexpr bool ranges::enable_borrowed_range<basic_string_view<_CharT, _Traits> > = true;
-#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17
// [string.view.deduct]
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17
template <contiguous_iterator _It, sized_sentinel_for<_It> _End>
basic_string_view(_It, _End) -> basic_string_view<iter_value_t<_It>>;
-#endif
+#endif // _LIBCPP_STD_VER > 17
-#if _LIBCPP_STD_VER > 20 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 20 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
template <ranges::contiguous_range _Range>
basic_string_view(_Range) -> basic_string_view<ranges::range_value_t<_Range>>;
-#endif
+#endif // _LIBCPP_STD_VER > 20 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
// [string.view.comparison]
// operator ==
@@ -900,7 +920,7 @@ operator<<(basic_ostream<_CharT, _Traits>& __os,
// [string.view.hash]
template<class _CharT>
struct _LIBCPP_TEMPLATE_VIS hash<basic_string_view<_CharT, char_traits<_CharT> > >
- : public unary_function<basic_string_view<_CharT, char_traits<_CharT> >, size_t>
+ : public __unary_function<basic_string_view<_CharT, char_traits<_CharT> >, size_t>
{
_LIBCPP_INLINE_VISIBILITY
size_t operator()(const basic_string_view<_CharT, char_traits<_CharT> > __val) const _NOEXCEPT {
@@ -908,7 +928,6 @@ struct _LIBCPP_TEMPLATE_VIS hash<basic_string_view<_CharT, char_traits<_CharT> >
}
};
-
#if _LIBCPP_STD_VER > 11
inline namespace literals
{
diff --git a/libcxx/include/strstream b/libcxx/include/strstream
index c34a5628b634..72386bb9567f 100644
--- a/libcxx/include/strstream
+++ b/libcxx/include/strstream
@@ -129,13 +129,14 @@ private:
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
#include <istream>
#include <ostream>
#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -265,8 +266,8 @@ public:
_LIBCPP_INLINE_VISIBILITY
istrstream& operator=(istrstream&& __rhs)
{
- istream::operator=(_VSTD::move(__rhs));
__sb_ = _VSTD::move(__rhs.__sb_);
+ istream::operator=(_VSTD::move(__rhs));
return *this;
}
#endif // _LIBCPP_CXX03_LANG
@@ -314,8 +315,8 @@ public:
_LIBCPP_INLINE_VISIBILITY
ostrstream& operator=(ostrstream&& __rhs)
{
- ostream::operator=(_VSTD::move(__rhs));
__sb_ = _VSTD::move(__rhs.__sb_);
+ ostream::operator=(_VSTD::move(__rhs));
return *this;
}
#endif // _LIBCPP_CXX03_LANG
@@ -374,8 +375,8 @@ public:
_LIBCPP_INLINE_VISIBILITY
strstream& operator=(strstream&& __rhs)
{
- iostream::operator=(_VSTD::move(__rhs));
__sb_ = _VSTD::move(__rhs.__sb_);
+ iostream::operator=(_VSTD::move(__rhs));
return *this;
}
#endif // _LIBCPP_CXX03_LANG
diff --git a/libcxx/include/system_error b/libcxx/include/system_error
index 6d3a6ca65038..2db901847d83 100644
--- a/libcxx/include/system_error
+++ b/libcxx/include/system_error
@@ -142,18 +142,21 @@ template <> struct hash<std::error_condition>;
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
#include <__errc>
+#include <__functional/hash.h>
#include <__functional/unary_function.h>
-#include <__functional_base>
-#include <compare>
#include <stdexcept>
#include <string>
#include <type_traits>
#include <version>
+// standard-mandated includes
+#include <compare>
+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -184,7 +187,7 @@ template <>
struct _LIBCPP_TEMPLATE_VIS is_error_condition_enum<errc>
: true_type { };
-#ifdef _LIBCPP_HAS_NO_STRONG_ENUMS
+#ifdef _LIBCPP_CXX03_LANG
template <>
struct _LIBCPP_TEMPLATE_VIS is_error_condition_enum<errc::__lx>
: true_type { };
@@ -202,9 +205,8 @@ class _LIBCPP_TYPE_VIS error_category
public:
virtual ~error_category() _NOEXCEPT;
-#if defined(_LIBCPP_BUILDING_LIBRARY) && \
- defined(_LIBCPP_DEPRECATED_ABI_LEGACY_LIBRARY_DEFINITIONS_FOR_INLINE_FUNCTIONS)
- error_category() _NOEXCEPT;
+#if defined(_LIBCPP_ERROR_CATEGORY_DEFINE_LEGACY_INLINE_FUNCTIONS)
+ error_category() noexcept;
#else
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_CONSTEXPR_AFTER_CXX11 error_category() _NOEXCEPT = default;
@@ -436,7 +438,7 @@ operator!=(const error_condition& __x, const error_condition& __y) _NOEXCEPT
template <>
struct _LIBCPP_TEMPLATE_VIS hash<error_code>
- : public unary_function<error_code, size_t>
+ : public __unary_function<error_code, size_t>
{
_LIBCPP_INLINE_VISIBILITY
size_t operator()(const error_code& __ec) const _NOEXCEPT
@@ -447,7 +449,7 @@ struct _LIBCPP_TEMPLATE_VIS hash<error_code>
template <>
struct _LIBCPP_TEMPLATE_VIS hash<error_condition>
- : public unary_function<error_condition, size_t>
+ : public __unary_function<error_condition, size_t>
{
_LIBCPP_INLINE_VISIBILITY
size_t operator()(const error_condition& __ec) const _NOEXCEPT
diff --git a/libcxx/include/tgmath.h b/libcxx/include/tgmath.h
index 412bde1d5eaf..c65091708a9a 100644
--- a/libcxx/include/tgmath.h
+++ b/libcxx/include/tgmath.h
@@ -20,7 +20,7 @@
#include <__config>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
#ifdef __cplusplus
diff --git a/libcxx/include/thread b/libcxx/include/thread
index 27756e42cdcb..1c8eb198986d 100644
--- a/libcxx/include/thread
+++ b/libcxx/include/thread
@@ -82,17 +82,15 @@ void sleep_for(const chrono::duration<Rep, Period>& rel_time);
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
-#include <__debug>
-#include <__functional_base>
+#include <__functional/hash.h>
#include <__mutex_base>
#include <__thread/poll_with_backoff.h>
#include <__thread/timed_backoff_policy.h>
#include <__threading_support>
#include <__utility/forward.h>
-#include <chrono>
#include <cstddef>
-#include <functional>
#include <iosfwd>
#include <memory>
#include <system_error>
@@ -100,16 +98,24 @@ void sleep_for(const chrono::duration<Rep, Period>& rel_time);
#include <type_traits>
#include <version>
+#ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES
+# include <chrono>
+# include <functional>
+#endif
+
+// standard-mandated includes
+#include <compare>
+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
#include <__undef_macros>
#ifdef _LIBCPP_HAS_NO_THREADS
-#error <thread> is not supported on this single threaded system
-#else // !_LIBCPP_HAS_NO_THREADS
+# error "<thread> is not supported since libc++ has been configured without support for threads."
+#endif
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -200,7 +206,7 @@ __thread_specific_ptr<_Tp>::set_pointer(pointer __p)
template<>
struct _LIBCPP_TEMPLATE_VIS hash<__thread_id>
- : public unary_function<__thread_id, size_t>
+ : public __unary_function<__thread_id, size_t>
{
_LIBCPP_INLINE_VISIBILITY
size_t operator()(__thread_id __v) const _NOEXCEPT
@@ -229,11 +235,7 @@ public:
thread() _NOEXCEPT : __t_(_LIBCPP_NULL_THREAD) {}
#ifndef _LIBCPP_CXX03_LANG
template <class _Fp, class ..._Args,
- class = typename enable_if
- <
- !is_same<typename __uncvref<_Fp>::type, thread>::value
- >::type
- >
+ class = __enable_if_t<!is_same<__uncvref_t<_Fp>, thread>::value> >
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
explicit thread(_Fp&& __f, _Args&&... __args);
#else // _LIBCPP_CXX03_LANG
@@ -408,8 +410,6 @@ void yield() _NOEXCEPT {__libcpp_thread_yield();}
_LIBCPP_END_NAMESPACE_STD
-#endif // !_LIBCPP_HAS_NO_THREADS
-
_LIBCPP_POP_MACROS
#endif // _LIBCPP_THREAD
diff --git a/libcxx/include/tuple b/libcxx/include/tuple
index 5cf120fec359..221eb23dd3f8 100644
--- a/libcxx/include/tuple
+++ b/libcxx/include/tuple
@@ -25,14 +25,24 @@ public:
explicit(see-below) tuple(U&&...); // constexpr in C++14
tuple(const tuple&) = default;
tuple(tuple&&) = default;
+
+ template<class... UTypes>
+ constexpr explicit(see-below) tuple(tuple<UTypes...>&); // C++23
template <class... U>
explicit(see-below) tuple(const tuple<U...>&); // constexpr in C++14
template <class... U>
explicit(see-below) tuple(tuple<U...>&&); // constexpr in C++14
+ template<class... UTypes>
+ constexpr explicit(see-below) tuple(const tuple<UTypes...>&&); // C++23
+
+ template<class U1, class U2>
+ constexpr explicit(see-below) tuple(pair<U1, U2>&); // iff sizeof...(Types) == 2 // C++23
template <class U1, class U2>
explicit(see-below) tuple(const pair<U1, U2>&); // iff sizeof...(T) == 2 // constexpr in C++14
template <class U1, class U2>
explicit(see-below) tuple(pair<U1, U2>&&); // iff sizeof...(T) == 2 // constexpr in C++14
+ template<class U1, class U2>
+ constexpr explicit(see-below) tuple(const pair<U1, U2>&&); // iff sizeof...(Types) == 2 // C++23
// allocator-extended constructors
template <class Alloc>
@@ -45,25 +55,47 @@ public:
tuple(allocator_arg_t, const Alloc& a, const tuple&); // constexpr in C++20
template <class Alloc>
tuple(allocator_arg_t, const Alloc& a, tuple&&); // constexpr in C++20
+ template<class Alloc, class... UTypes>
+ constexpr explicit(see-below)
+ tuple(allocator_arg_t, const Alloc& a, tuple<UTypes...>&); // C++23
template <class Alloc, class... U>
explicit(see-below) tuple(allocator_arg_t, const Alloc& a, const tuple<U...>&); // constexpr in C++20
template <class Alloc, class... U>
explicit(see-below) tuple(allocator_arg_t, const Alloc& a, tuple<U...>&&); // constexpr in C++20
+ template<class Alloc, class... UTypes>
+ constexpr explicit(see-below)
+ tuple(allocator_arg_t, const Alloc& a, const tuple<UTypes...>&&); // C++23
+ template<class Alloc, class U1, class U2>
+ constexpr explicit(see-below)
+ tuple(allocator_arg_t, const Alloc& a, pair<U1, U2>&); // C++23
template <class Alloc, class U1, class U2>
explicit(see-below) tuple(allocator_arg_t, const Alloc& a, const pair<U1, U2>&); // constexpr in C++20
template <class Alloc, class U1, class U2>
explicit(see-below) tuple(allocator_arg_t, const Alloc& a, pair<U1, U2>&&); // constexpr in C++20
+ template<class Alloc, class U1, class U2>
+ constexpr explicit(see-below)
+ tuple(allocator_arg_t, const Alloc& a, const pair<U1, U2>&&); // C++23
tuple& operator=(const tuple&); // constexpr in C++20
+ constexpr const tuple& operator=(const tuple&) const; // C++23
tuple& operator=(tuple&&) noexcept(is_nothrow_move_assignable_v<T> && ...); // constexpr in C++20
+ constexpr const tuple& operator=(tuple&&) const; // C++23
template <class... U>
tuple& operator=(const tuple<U...>&); // constexpr in C++20
+ template<class... UTypes>
+ constexpr const tuple& operator=(const tuple<UTypes...>&) const; // C++23
template <class... U>
tuple& operator=(tuple<U...>&&); // constexpr in C++20
+ template<class... UTypes>
+ constexpr const tuple& operator=(tuple<UTypes...>&&) const; // C++23
template <class U1, class U2>
tuple& operator=(const pair<U1, U2>&); // iff sizeof...(T) == 2 // constexpr in C++20
+ template<class U1, class U2>
+ constexpr const tuple& operator=(const pair<U1, U2>&) const; // iff sizeof...(Types) == 2 // C++23
template <class U1, class U2>
tuple& operator=(pair<U1, U2>&&); // iff sizeof...(T) == 2 // constexpr in C++20
+ template<class U1, class U2>
+ constexpr const tuple& operator=(pair<U1, U2>&&) const; // iff sizeof...(Types) == 2 // C++23
template<class U, size_t N>
tuple& operator=(array<U, N> const&) // iff sizeof...(T) == N, EXTENSION
@@ -71,6 +103,7 @@ public:
tuple& operator=(array<U, N>&&) // iff sizeof...(T) == N, EXTENSION
void swap(tuple&) noexcept(AND(swap(declval<T&>(), declval<T&>())...)); // constexpr in C++20
+ constexpr void swap(const tuple&) const noexcept(see-below); // C++23
};
@@ -161,29 +194,44 @@ template <class... Types>
void
swap(tuple<Types...>& x, tuple<Types...>& y) noexcept(noexcept(x.swap(y)));
+template <class... Types>
+ constexpr void swap(const tuple<Types...>& x, const tuple<Types...>& y) noexcept(see-below); // C++23
+
} // std
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__compare/common_comparison_category.h>
#include <__compare/synth_three_way.h>
#include <__config>
#include <__functional/unwrap_ref.h>
-#include <__functional_base>
#include <__memory/allocator_arg_t.h>
#include <__memory/uses_allocator.h>
#include <__tuple>
#include <__utility/forward.h>
#include <__utility/integer_sequence.h>
#include <__utility/move.h>
-#include <compare>
+#include <__utility/pair.h>
+#include <__utility/piecewise_construct.h>
+#include <__utility/swap.h>
#include <cstddef>
#include <type_traits>
-#include <utility>
#include <version>
+#ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES
+# include <exception>
+# include <iosfwd>
+# include <new>
+# include <typeinfo>
+# include <utility>
+#endif
+
+// standard-mandated includes
+#include <compare>
+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -206,6 +254,13 @@ void swap(__tuple_leaf<_Ip, _Hp, _Ep>& __x, __tuple_leaf<_Ip, _Hp, _Ep>& __y)
swap(__x.get(), __y.get());
}
+template <size_t _Ip, class _Hp, bool _Ep>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11
+void swap(const __tuple_leaf<_Ip, _Hp, _Ep>& __x, const __tuple_leaf<_Ip, _Hp, _Ep>& __y)
+ _NOEXCEPT_(__is_nothrow_swappable<const _Hp>::value) {
+ swap(__x.get(), __y.get());
+}
+
template <size_t _Ip, class _Hp, bool>
class __tuple_leaf
{
@@ -294,6 +349,12 @@ public:
return 0;
}
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+ int swap(const __tuple_leaf& __t) const _NOEXCEPT_(__is_nothrow_swappable<const __tuple_leaf>::value) {
+ _VSTD::swap(*this, __t);
+ return 0;
+ }
+
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 _Hp& get() _NOEXCEPT {return __value_;}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const _Hp& get() const _NOEXCEPT {return __value_;}
};
@@ -360,6 +421,12 @@ public:
return 0;
}
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+ int swap(const __tuple_leaf& __rhs) const _NOEXCEPT_(__is_nothrow_swappable<const __tuple_leaf>::value) {
+ _VSTD::swap(*this, __rhs);
+ return 0;
+ }
+
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 _Hp& get() _NOEXCEPT {return static_cast<_Hp&>(*this);}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const _Hp& get() const _NOEXCEPT {return static_cast<const _Hp&>(*this);}
};
@@ -450,6 +517,13 @@ struct _LIBCPP_DECLSPEC_EMPTY_BASES __tuple_impl<__tuple_indices<_Indx...>, _Tp.
{
_VSTD::__swallow(__tuple_leaf<_Indx, _Tp>::swap(static_cast<__tuple_leaf<_Indx, _Tp>&>(__t))...);
}
+
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+ void swap(const __tuple_impl& __t) const
+ _NOEXCEPT_(__all<__is_nothrow_swappable<const _Tp>::value...>::value)
+ {
+ _VSTD::__swallow(__tuple_leaf<_Indx, _Tp>::swap(static_cast<const __tuple_leaf<_Indx, _Tp>&>(__t))...);
+ }
};
template<class _Dest, class _Source, size_t ..._Np>
@@ -685,6 +759,7 @@ public:
template <class _Alloc, template<class...> class _And = _And, __enable_if_t<
_And<is_copy_constructible<_Tp>...>::value
, int> = 0>
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
tuple(allocator_arg_t, const _Alloc& __alloc, const tuple& __t)
: __base_(allocator_arg_t(), __alloc, __t)
{ }
@@ -692,30 +767,39 @@ public:
template <class _Alloc, template<class...> class _And = _And, __enable_if_t<
_And<is_move_constructible<_Tp>...>::value
, int> = 0>
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
tuple(allocator_arg_t, const _Alloc& __alloc, tuple&& __t)
: __base_(allocator_arg_t(), __alloc, _VSTD::move(__t))
{ }
// tuple(const tuple<U...>&) constructors (including allocator_arg_t variants)
- template <class ..._Up>
- struct _EnableCopyFromOtherTuple : _And<
- _Not<is_same<tuple<_Tp...>, tuple<_Up...> > >,
- _Lazy<_Or,
- _BoolConstant<sizeof...(_Tp) != 1>,
+
+ template <class _OtherTuple, class _DecayedOtherTuple = __uncvref_t<_OtherTuple>, class = void>
+ struct _EnableCtorFromUTypesTuple : false_type {};
+
+ template <class _OtherTuple, class... _Up>
+ struct _EnableCtorFromUTypesTuple<_OtherTuple, tuple<_Up...>,
+ // the length of the packs needs to checked first otherwise the 2 packs cannot be expanded simultaneously below
+ __enable_if_t<sizeof...(_Up) == sizeof...(_Tp)>> : _And<
+ // the two conditions below are not in spec. The purpose is to disable the UTypes Ctor when copy/move Ctor can work.
+ // Otherwise, is_constructible can trigger hard error in those cases https://godbolt.org/z/M94cGdKcE
+ _Not<is_same<_OtherTuple, const tuple&> >,
+ _Not<is_same<_OtherTuple, tuple&&> >,
+ is_constructible<_Tp, __copy_cvref_t<_OtherTuple, _Up> >...,
+ _Lazy<_Or, _BoolConstant<sizeof...(_Tp) != 1>,
// _Tp and _Up are 1-element packs - the pack expansions look
// weird to avoid tripping up the type traits in degenerate cases
_Lazy<_And,
- _Not<is_convertible<const tuple<_Up>&, _Tp> >...,
- _Not<is_constructible<_Tp, const tuple<_Up>&> >...
+ _Not<is_same<_Tp, _Up> >...,
+ _Not<is_convertible<_OtherTuple, _Tp> >...,
+ _Not<is_constructible<_Tp, _OtherTuple> >...
>
- >,
- is_constructible<_Tp, const _Up&>...
- > { };
+ >
+ > {};
template <class ..._Up, __enable_if_t<
_And<
- _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
- _EnableCopyFromOtherTuple<_Up...>,
+ _EnableCtorFromUTypesTuple<const tuple<_Up...>&>,
is_convertible<const _Up&, _Tp>... // explicit check
>::value
, int> = 0>
@@ -727,8 +811,7 @@ public:
template <class ..._Up, __enable_if_t<
_And<
- _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
- _EnableCopyFromOtherTuple<_Up...>,
+ _EnableCtorFromUTypesTuple<const tuple<_Up...>&>,
_Not<_Lazy<_And, is_convertible<const _Up&, _Tp>...> > // explicit check
>::value
, int> = 0>
@@ -740,8 +823,7 @@ public:
template <class ..._Up, class _Alloc, __enable_if_t<
_And<
- _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
- _EnableCopyFromOtherTuple<_Up...>,
+ _EnableCtorFromUTypesTuple<const tuple<_Up...>&>,
is_convertible<const _Up&, _Tp>... // explicit check
>::value
, int> = 0>
@@ -752,8 +834,7 @@ public:
template <class ..._Up, class _Alloc, __enable_if_t<
_And<
- _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
- _EnableCopyFromOtherTuple<_Up...>,
+ _EnableCtorFromUTypesTuple<const tuple<_Up...>&>,
_Not<_Lazy<_And, is_convertible<const _Up&, _Tp>...> > // explicit check
>::value
, int> = 0>
@@ -762,26 +843,27 @@ public:
: __base_(allocator_arg_t(), __a, __t)
{ }
+#if _LIBCPP_STD_VER > 20
+ // tuple(tuple<U...>&) constructors (including allocator_arg_t variants)
+
+ template <class... _Up, enable_if_t<
+ _EnableCtorFromUTypesTuple<tuple<_Up...>&>::value>* = nullptr>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ explicit(!(is_convertible_v<_Up&, _Tp> && ...))
+ tuple(tuple<_Up...>& __t) : __base_(__t) {}
+
+ template <class _Alloc, class... _Up, enable_if_t<
+ _EnableCtorFromUTypesTuple<tuple<_Up...>&>::value>* = nullptr>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ explicit(!(is_convertible_v<_Up&, _Tp> && ...))
+ tuple(allocator_arg_t, const _Alloc& __alloc, tuple<_Up...>& __t) : __base_(allocator_arg_t(), __alloc, __t) {}
+#endif // _LIBCPP_STD_VER > 20
+
// tuple(tuple<U...>&&) constructors (including allocator_arg_t variants)
- template <class ..._Up>
- struct _EnableMoveFromOtherTuple : _And<
- _Not<is_same<tuple<_Tp...>, tuple<_Up...> > >,
- _Lazy<_Or,
- _BoolConstant<sizeof...(_Tp) != 1>,
- // _Tp and _Up are 1-element packs - the pack expansions look
- // weird to avoid tripping up the type traits in degenerate cases
- _Lazy<_And,
- _Not<is_convertible<tuple<_Up>, _Tp> >...,
- _Not<is_constructible<_Tp, tuple<_Up> > >...
- >
- >,
- is_constructible<_Tp, _Up>...
- > { };
template <class ..._Up, __enable_if_t<
_And<
- _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
- _EnableMoveFromOtherTuple<_Up...>,
+ _EnableCtorFromUTypesTuple<tuple<_Up...>&&>,
is_convertible<_Up, _Tp>... // explicit check
>::value
, int> = 0>
@@ -793,8 +875,7 @@ public:
template <class ..._Up, __enable_if_t<
_And<
- _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
- _EnableMoveFromOtherTuple<_Up...>,
+ _EnableCtorFromUTypesTuple<tuple<_Up...>&&>,
_Not<_Lazy<_And, is_convertible<_Up, _Tp>...> > // explicit check
>::value
, int> = 0>
@@ -806,8 +887,7 @@ public:
template <class _Alloc, class ..._Up, __enable_if_t<
_And<
- _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
- _EnableMoveFromOtherTuple<_Up...>,
+ _EnableCtorFromUTypesTuple<tuple<_Up...>&&>,
is_convertible<_Up, _Tp>... // explicit check
>::value
, int> = 0>
@@ -818,8 +898,7 @@ public:
template <class _Alloc, class ..._Up, __enable_if_t<
_And<
- _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
- _EnableMoveFromOtherTuple<_Up...>,
+ _EnableCtorFromUTypesTuple<tuple<_Up...>&&>,
_Not<_Lazy<_And, is_convertible<_Up, _Tp>...> > // explicit check
>::value
, int> = 0>
@@ -828,57 +907,77 @@ public:
: __base_(allocator_arg_t(), __a, _VSTD::move(__t))
{ }
+#if _LIBCPP_STD_VER > 20
+ // tuple(const tuple<U...>&&) constructors (including allocator_arg_t variants)
+
+ template <class... _Up, enable_if_t<
+ _EnableCtorFromUTypesTuple<const tuple<_Up...>&&>::value>* = nullptr>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ explicit(!(is_convertible_v<const _Up&&, _Tp> && ...))
+ tuple(const tuple<_Up...>&& __t) : __base_(std::move(__t)) {}
+
+ template <class _Alloc, class... _Up, enable_if_t<
+ _EnableCtorFromUTypesTuple<const tuple<_Up...>&&>::value>* = nullptr>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ explicit(!(is_convertible_v<const _Up&&, _Tp> && ...))
+ tuple(allocator_arg_t, const _Alloc& __alloc, const tuple<_Up...>&& __t)
+ : __base_(allocator_arg_t(), __alloc, std::move(__t)) {}
+#endif // _LIBCPP_STD_VER > 20
+
// tuple(const pair<U1, U2>&) constructors (including allocator_arg_t variants)
- template <class _Up1, class _Up2, class ..._DependentTp>
- struct _EnableImplicitCopyFromPair : _And<
- is_constructible<_FirstType<_DependentTp...>, const _Up1&>,
- is_constructible<_SecondType<_DependentTp...>, const _Up2&>,
- is_convertible<const _Up1&, _FirstType<_DependentTp...> >, // explicit check
- is_convertible<const _Up2&, _SecondType<_DependentTp...> >
- > { };
- template <class _Up1, class _Up2, class ..._DependentTp>
- struct _EnableExplicitCopyFromPair : _And<
- is_constructible<_FirstType<_DependentTp...>, const _Up1&>,
- is_constructible<_SecondType<_DependentTp...>, const _Up2&>,
- _Not<is_convertible<const _Up1&, _FirstType<_DependentTp...> > >, // explicit check
- _Not<is_convertible<const _Up2&, _SecondType<_DependentTp...> > >
- > { };
+ template <template <class...> class Pred, class _Pair, class _DecayedPair = __uncvref_t<_Pair>, class _Tuple = tuple>
+ struct _CtorPredicateFromPair : false_type{};
+
+ template <template <class...> class Pred, class _Pair, class _Up1, class _Up2, class _Tp1, class _Tp2>
+ struct _CtorPredicateFromPair<Pred, _Pair, pair<_Up1, _Up2>, tuple<_Tp1, _Tp2> > : _And<
+ Pred<_Tp1, __copy_cvref_t<_Pair, _Up1> >,
+ Pred<_Tp2, __copy_cvref_t<_Pair, _Up2> >
+ > {};
+
+ template <class _Pair>
+ struct _EnableCtorFromPair : _CtorPredicateFromPair<is_constructible, _Pair>{};
+
+ template <class _Pair>
+ struct _NothrowConstructibleFromPair : _CtorPredicateFromPair<is_nothrow_constructible, _Pair>{};
+
+ template <class _Pair, class _DecayedPair = __uncvref_t<_Pair>, class _Tuple = tuple>
+ struct _BothImplicitlyConvertible : false_type{};
+
+ template <class _Pair, class _Up1, class _Up2, class _Tp1, class _Tp2>
+ struct _BothImplicitlyConvertible<_Pair, pair<_Up1, _Up2>, tuple<_Tp1, _Tp2> > : _And<
+ is_convertible<__copy_cvref_t<_Pair, _Up1>, _Tp1>,
+ is_convertible<__copy_cvref_t<_Pair, _Up2>, _Tp2>
+ > {};
template <class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t<
_And<
- _BoolConstant<sizeof...(_Tp) == 2>,
- _EnableImplicitCopyFromPair<_Up1, _Up2, _Tp...>
+ _EnableCtorFromPair<const pair<_Up1, _Up2>&>,
+ _BothImplicitlyConvertible<const pair<_Up1, _Up2>&> // explicit check
>::value
, int> = 0>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
tuple(const pair<_Up1, _Up2>& __p)
- _NOEXCEPT_((_And<
- is_nothrow_constructible<_FirstType<_Tp...>, const _Up1&>,
- is_nothrow_constructible<_SecondType<_Tp...>, const _Up2&>
- >::value))
+ _NOEXCEPT_((_NothrowConstructibleFromPair<const pair<_Up1, _Up2>&>::value))
: __base_(__p)
{ }
template <class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t<
_And<
- _BoolConstant<sizeof...(_Tp) == 2>,
- _EnableExplicitCopyFromPair<_Up1, _Up2, _Tp...>
+ _EnableCtorFromPair<const pair<_Up1, _Up2>&>,
+ _Not<_BothImplicitlyConvertible<const pair<_Up1, _Up2>&> > // explicit check
>::value
, int> = 0>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
explicit tuple(const pair<_Up1, _Up2>& __p)
- _NOEXCEPT_((_And<
- is_nothrow_constructible<_FirstType<_Tp...>, const _Up1&>,
- is_nothrow_constructible<_SecondType<_Tp...>, const _Up2&>
- >::value))
+ _NOEXCEPT_((_NothrowConstructibleFromPair<const pair<_Up1, _Up2>&>::value))
: __base_(__p)
{ }
template <class _Alloc, class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t<
_And<
- _BoolConstant<sizeof...(_Tp) == 2>,
- _EnableImplicitCopyFromPair<_Up1, _Up2, _Tp...>
+ _EnableCtorFromPair<const pair<_Up1, _Up2>&>,
+ _BothImplicitlyConvertible<const pair<_Up1, _Up2>&> // explicit check
>::value
, int> = 0>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
@@ -888,8 +987,8 @@ public:
template <class _Alloc, class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t<
_And<
- _BoolConstant<sizeof...(_Tp) == 2>,
- _EnableExplicitCopyFromPair<_Up1, _Up2, _Tp...>
+ _EnableCtorFromPair<const pair<_Up1, _Up2>&>,
+ _Not<_BothImplicitlyConvertible<const pair<_Up1, _Up2>&> > // explicit check
>::value
, int> = 0>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
@@ -897,57 +996,52 @@ public:
: __base_(allocator_arg_t(), __a, __p)
{ }
- // tuple(pair<U1, U2>&&) constructors (including allocator_arg_t variants)
- template <class _Up1, class _Up2, class ..._DependentTp>
- struct _EnableImplicitMoveFromPair : _And<
- is_constructible<_FirstType<_DependentTp...>, _Up1>,
- is_constructible<_SecondType<_DependentTp...>, _Up2>,
- is_convertible<_Up1, _FirstType<_DependentTp...> >, // explicit check
- is_convertible<_Up2, _SecondType<_DependentTp...> >
- > { };
+#if _LIBCPP_STD_VER > 20
+ // tuple(pair<U1, U2>&) constructors (including allocator_arg_t variants)
+
+ template <class _U1, class _U2, enable_if_t<
+ _EnableCtorFromPair<pair<_U1, _U2>&>::value>* = nullptr>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ explicit(!_BothImplicitlyConvertible<pair<_U1, _U2>&>::value)
+ tuple(pair<_U1, _U2>& __p) : __base_(__p) {}
+
+ template <class _Alloc, class _U1, class _U2, enable_if_t<
+ _EnableCtorFromPair<std::pair<_U1, _U2>&>::value>* = nullptr>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ explicit(!_BothImplicitlyConvertible<pair<_U1, _U2>&>::value)
+ tuple(allocator_arg_t, const _Alloc& __alloc, pair<_U1, _U2>& __p) : __base_(allocator_arg_t(), __alloc, __p) {}
+#endif
- template <class _Up1, class _Up2, class ..._DependentTp>
- struct _EnableExplicitMoveFromPair : _And<
- is_constructible<_FirstType<_DependentTp...>, _Up1>,
- is_constructible<_SecondType<_DependentTp...>, _Up2>,
- _Not<is_convertible<_Up1, _FirstType<_DependentTp...> > >, // explicit check
- _Not<is_convertible<_Up2, _SecondType<_DependentTp...> > >
- > { };
+ // tuple(pair<U1, U2>&&) constructors (including allocator_arg_t variants)
template <class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t<
_And<
- _BoolConstant<sizeof...(_Tp) == 2>,
- _EnableImplicitMoveFromPair<_Up1, _Up2, _Tp...>
+ _EnableCtorFromPair<pair<_Up1, _Up2>&&>,
+ _BothImplicitlyConvertible<pair<_Up1, _Up2>&&> // explicit check
>::value
, int> = 0>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
tuple(pair<_Up1, _Up2>&& __p)
- _NOEXCEPT_((_And<
- is_nothrow_constructible<_FirstType<_Tp...>, _Up1>,
- is_nothrow_constructible<_SecondType<_Tp...>, _Up2>
- >::value))
+ _NOEXCEPT_((_NothrowConstructibleFromPair<pair<_Up1, _Up2>&&>::value))
: __base_(_VSTD::move(__p))
{ }
template <class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t<
_And<
- _BoolConstant<sizeof...(_Tp) == 2>,
- _EnableExplicitMoveFromPair<_Up1, _Up2, _Tp...>
+ _EnableCtorFromPair<pair<_Up1, _Up2>&&>,
+ _Not<_BothImplicitlyConvertible<pair<_Up1, _Up2>&&> > // explicit check
>::value
, int> = 0>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
explicit tuple(pair<_Up1, _Up2>&& __p)
- _NOEXCEPT_((_And<
- is_nothrow_constructible<_FirstType<_Tp...>, _Up1>,
- is_nothrow_constructible<_SecondType<_Tp...>, _Up2>
- >::value))
+ _NOEXCEPT_((_NothrowConstructibleFromPair<pair<_Up1, _Up2>&&>::value))
: __base_(_VSTD::move(__p))
{ }
template <class _Alloc, class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t<
_And<
- _BoolConstant<sizeof...(_Tp) == 2>,
- _EnableImplicitMoveFromPair<_Up1, _Up2, _Tp...>
+ _EnableCtorFromPair<pair<_Up1, _Up2>&&>,
+ _BothImplicitlyConvertible<pair<_Up1, _Up2>&&> // explicit check
>::value
, int> = 0>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
@@ -957,8 +1051,8 @@ public:
template <class _Alloc, class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t<
_And<
- _BoolConstant<sizeof...(_Tp) == 2>,
- _EnableExplicitMoveFromPair<_Up1, _Up2, _Tp...>
+ _EnableCtorFromPair<pair<_Up1, _Up2>&&>,
+ _Not<_BothImplicitlyConvertible<pair<_Up1, _Up2>&&> > // explicit check
>::value
, int> = 0>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
@@ -966,6 +1060,23 @@ public:
: __base_(allocator_arg_t(), __a, _VSTD::move(__p))
{ }
+#if _LIBCPP_STD_VER > 20
+ // tuple(const pair<U1, U2>&&) constructors (including allocator_arg_t variants)
+
+ template <class _U1, class _U2, enable_if_t<
+ _EnableCtorFromPair<const pair<_U1, _U2>&&>::value>* = nullptr>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ explicit(!_BothImplicitlyConvertible<const pair<_U1, _U2>&&>::value)
+ tuple(const pair<_U1, _U2>&& __p) : __base_(std::move(__p)) {}
+
+ template <class _Alloc, class _U1, class _U2, enable_if_t<
+ _EnableCtorFromPair<const pair<_U1, _U2>&&>::value>* = nullptr>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ explicit(!_BothImplicitlyConvertible<const pair<_U1, _U2>&&>::value)
+ tuple(allocator_arg_t, const _Alloc& __alloc, const pair<_U1, _U2>&& __p)
+ : __base_(allocator_arg_t(), __alloc, std::move(__p)) {}
+#endif // _LIBCPP_STD_VER > 20
+
// [tuple.assign]
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
tuple& operator=(_If<_And<is_copy_assignable<_Tp>...>::value, tuple, __nat> const& __tuple)
@@ -976,6 +1087,25 @@ public:
return *this;
}
+#if _LIBCPP_STD_VER > 20
+ _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, typename __make_tuple_indices<sizeof...(_Tp)>::type());
+ 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),
+ __tuple_types<_Tp...>(),
+ typename __make_tuple_indices<sizeof...(_Tp)>::type());
+ return *this;
+ }
+#endif // _LIBCPP_STD_VER > 20
+
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
tuple& operator=(_If<_And<is_move_assignable<_Tp>...>::value, tuple, __nat>&& __tuple)
_NOEXCEPT_((_And<is_nothrow_move_assignable<_Tp>...>::value))
@@ -1017,38 +1147,89 @@ public:
return *this;
}
- template<class _Up1, class _Up2, class _Dep = true_type, __enable_if_t<
- _And<_Dep,
- _BoolConstant<sizeof...(_Tp) == 2>,
- is_assignable<_FirstType<_Tp..., _Dep>&, _Up1 const&>,
- is_assignable<_SecondType<_Tp..., _Dep>&, _Up2 const&>
- >::value
+
+#if _LIBCPP_STD_VER > 20
+ template <class... _UTypes, 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,
+ typename __make_tuple_indices<sizeof...(_Tp)>::type());
+ return *this;
+ }
+
+ template <class... _UTypes, 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,
+ __tuple_types<_UTypes...>(),
+ typename __make_tuple_indices<sizeof...(_Tp)>::type());
+ return *this;
+ }
+#endif // _LIBCPP_STD_VER > 20
+
+ template <template<class...> class Pred, bool _Const,
+ class _Pair, class _DecayedPair = __uncvref_t<_Pair>, class _Tuple = tuple>
+ struct _AssignPredicateFromPair : false_type {};
+
+ template <template<class...> class Pred, bool _Const,
+ class _Pair, class _Up1, class _Up2, class _Tp1, class _Tp2>
+ struct _AssignPredicateFromPair<Pred, _Const, _Pair, pair<_Up1, _Up2>, tuple<_Tp1, _Tp2> > :
+ _And<Pred<__maybe_const<_Const, _Tp1>&, __copy_cvref_t<_Pair, _Up1> >,
+ Pred<__maybe_const<_Const, _Tp2>&, __copy_cvref_t<_Pair, _Up2> >
+ > {};
+
+ template <bool _Const, class _Pair>
+ struct _EnableAssignFromPair : _AssignPredicateFromPair<is_assignable, _Const, _Pair> {};
+
+ template <bool _Const, class _Pair>
+ struct _NothrowAssignFromPair : _AssignPredicateFromPair<is_nothrow_assignable, _Const, _Pair> {};
+
+#if _LIBCPP_STD_VER > 20
+ template <class _U1, class _U2, enable_if_t<
+ _EnableAssignFromPair<true, const pair<_U1, _U2>&>::value>* = nullptr>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ const tuple& operator=(const pair<_U1, _U2>& __pair) const
+ noexcept(_NothrowAssignFromPair<true, const pair<_U1, _U2>&>::value) {
+ std::get<0>(*this) = __pair.first;
+ std::get<1>(*this) = __pair.second;
+ return *this;
+ }
+
+ template <class _U1, class _U2, enable_if_t<
+ _EnableAssignFromPair<true, pair<_U1, _U2>&&>::value>* = nullptr>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ const tuple& operator=(pair<_U1, _U2>&& __pair) const
+ noexcept(_NothrowAssignFromPair<true, pair<_U1, _U2>&&>::value) {
+ std::get<0>(*this) = std::move(__pair.first);
+ std::get<1>(*this) = std::move(__pair.second);
+ return *this;
+ }
+#endif // _LIBCPP_STD_VER > 20
+
+ template<class _Up1, class _Up2, __enable_if_t<
+ _EnableAssignFromPair<false, pair<_Up1, _Up2> const&>::value
,int> = 0>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
tuple& operator=(pair<_Up1, _Up2> const& __pair)
- _NOEXCEPT_((_And<
- is_nothrow_assignable<_FirstType<_Tp...>&, _Up1 const&>,
- is_nothrow_assignable<_SecondType<_Tp...>&, _Up2 const&>
- >::value))
+ _NOEXCEPT_((_NothrowAssignFromPair<false, pair<_Up1, _Up2> const&>::value))
{
_VSTD::get<0>(*this) = __pair.first;
_VSTD::get<1>(*this) = __pair.second;
return *this;
}
- template<class _Up1, class _Up2, class _Dep = true_type, __enable_if_t<
- _And<_Dep,
- _BoolConstant<sizeof...(_Tp) == 2>,
- is_assignable<_FirstType<_Tp..., _Dep>&, _Up1>,
- is_assignable<_SecondType<_Tp..., _Dep>&, _Up2>
- >::value
+ template<class _Up1, class _Up2, __enable_if_t<
+ _EnableAssignFromPair<false, pair<_Up1, _Up2>&&>::value
,int> = 0>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
tuple& operator=(pair<_Up1, _Up2>&& __pair)
- _NOEXCEPT_((_And<
- is_nothrow_assignable<_FirstType<_Tp...>&, _Up1>,
- is_nothrow_assignable<_SecondType<_Tp...>&, _Up2>
- >::value))
+ _NOEXCEPT_((_NothrowAssignFromPair<false, pair<_Up1, _Up2>&&>::value))
{
_VSTD::get<0>(*this) = _VSTD::forward<_Up1>(__pair.first);
_VSTD::get<1>(*this) = _VSTD::forward<_Up2>(__pair.second);
@@ -1092,6 +1273,13 @@ public:
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
void swap(tuple& __t) _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
{__base_.swap(__t.__base_);}
+
+#if _LIBCPP_STD_VER > 20
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ void swap(const tuple& __t) const noexcept(__all<is_nothrow_swappable_v<const _Tp&>...>::value) {
+ __base_.swap(__t.__base_);
+ }
+#endif // _LIBCPP_STD_VER > 20
};
template <>
@@ -1114,6 +1302,9 @@ public:
tuple(allocator_arg_t, const _Alloc&, array<_Up, 0>) _NOEXCEPT {}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
void swap(tuple&) _NOEXCEPT {}
+#if _LIBCPP_STD_VER > 20
+ _LIBCPP_HIDE_FROM_ABI constexpr void swap(const tuple&) const noexcept {}
+#endif
};
#if _LIBCPP_STD_VER > 20
@@ -1128,7 +1319,7 @@ template <class... _TTypes, class... _UTypes>
struct common_type<tuple<_TTypes...>, tuple<_UTypes...>> {
using type = tuple<common_type_t<_TTypes, _UTypes>...>;
};
-#endif
+#endif // _LIBCPP_STD_VER > 20
#if _LIBCPP_STD_VER > 14
template <class ..._Tp>
@@ -1154,6 +1345,16 @@ swap(tuple<_Tp...>& __t, tuple<_Tp...>& __u)
_NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
{__t.swap(__u);}
+#if _LIBCPP_STD_VER > 20
+template <class... _Tp>
+_LIBCPP_HIDE_FROM_ABI constexpr
+enable_if_t<__all<is_swappable_v<const _Tp>...>::value, void>
+swap(const tuple<_Tp...>& __lhs, const tuple<_Tp...>& __rhs)
+ noexcept(__all<is_nothrow_swappable_v<const _Tp>...>::value) {
+ __lhs.swap(__rhs);
+}
+#endif
+
// get
template <size_t _Ip, class ..._Tp>
@@ -1333,7 +1534,7 @@ operator==(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
return __tuple_equal<sizeof...(_Tp)>()(__x, __y);
}
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17
// operator<=>
@@ -1355,7 +1556,7 @@ operator<=>(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
return _VSTD::__tuple_compare_three_way(__x, __y, index_sequence_for<_Tp...>{});
}
-#else // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#else // _LIBCPP_STD_VER > 17
template <class ..._Tp, class ..._Up>
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
@@ -1425,7 +1626,7 @@ operator<=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
return !(__y < __x);
}
-#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17
// tuple_cat
@@ -1445,9 +1646,10 @@ struct __tuple_cat_return_1
template <class ..._Types, class _Tuple0>
struct __tuple_cat_return_1<tuple<_Types...>, true, _Tuple0>
{
- typedef _LIBCPP_NODEBUG typename __tuple_cat_type<tuple<_Types...>,
- typename __make_tuple_types<typename __uncvref<_Tuple0>::type>::type>::type
- type;
+ using type _LIBCPP_NODEBUG = typename __tuple_cat_type<
+ tuple<_Types...>,
+ typename __make_tuple_types<__uncvref_t<_Tuple0> >::type
+ >::type;
};
template <class ..._Types, class _Tuple0, class _Tuple1, class ..._Tuples>
@@ -1455,7 +1657,7 @@ struct __tuple_cat_return_1<tuple<_Types...>, true, _Tuple0, _Tuple1, _Tuples...
: public __tuple_cat_return_1<
typename __tuple_cat_type<
tuple<_Types...>,
- typename __make_tuple_types<typename __uncvref<_Tuple0>::type>::type
+ typename __make_tuple_types<__uncvref_t<_Tuple0> >::type
>::type,
__tuple_like<typename remove_reference<_Tuple1>::type>::value,
_Tuple1, _Tuples...>
@@ -1529,6 +1731,7 @@ struct __tuple_cat<tuple<_Types...>, __tuple_indices<_I0...>, __tuple_indices<_J
typename __tuple_cat_return_ref<tuple<_Types...>&&, _Tuple0&&>::type
operator()(tuple<_Types...> __t, _Tuple0&& __t0)
{
+ (void)__t; // avoid unused parameter warning on GCC when _I0 is empty
return _VSTD::forward_as_tuple(
_VSTD::forward<_Types>(_VSTD::get<_I0>(__t))...,
_VSTD::get<_J0>(_VSTD::forward<_Tuple0>(__t0))...);
@@ -1539,6 +1742,7 @@ struct __tuple_cat<tuple<_Types...>, __tuple_indices<_I0...>, __tuple_indices<_J
typename __tuple_cat_return_ref<tuple<_Types...>&&, _Tuple0&&, _Tuple1&&, _Tuples&&...>::type
operator()(tuple<_Types...> __t, _Tuple0&& __t0, _Tuple1&& __t1, _Tuples&& ...__tpls)
{
+ (void)__t; // avoid unused parameter warning on GCC when _I0 is empty
typedef _LIBCPP_NODEBUG typename remove_reference<_Tuple0>::type _T0;
typedef _LIBCPP_NODEBUG typename remove_reference<_Tuple1>::type _T1;
return __tuple_cat<
@@ -1593,7 +1797,7 @@ inline _LIBCPP_INLINE_VISIBILITY
constexpr decltype(auto) __apply_tuple_impl(_Fn && __f, _Tuple && __t,
__tuple_indices<_Id...>)
_LIBCPP_NOEXCEPT_RETURN(
- _VSTD::__invoke_constexpr(
+ _VSTD::__invoke(
_VSTD::forward<_Fn>(__f),
_VSTD::get<_Id>(_VSTD::forward<_Tuple>(__t))...)
)
diff --git a/libcxx/include/type_traits b/libcxx/include/type_traits
index b4010851f133..f7d81e65dd8e 100644
--- a/libcxx/include/type_traits
+++ b/libcxx/include/type_traits
@@ -416,103 +416,119 @@ namespace std
}
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
+#include <__functional/invoke.h>
+#include <__type_traits/add_const.h>
+#include <__type_traits/add_cv.h>
+#include <__type_traits/add_lvalue_reference.h>
+#include <__type_traits/add_pointer.h>
+#include <__type_traits/add_rvalue_reference.h>
+#include <__type_traits/add_volatile.h>
+#include <__type_traits/alignment_of.h>
+#include <__type_traits/apply_cv.h>
+#include <__type_traits/conditional.h>
+#include <__type_traits/conjunction.h>
+#include <__type_traits/decay.h>
+#include <__type_traits/disjunction.h>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/extent.h>
+#include <__type_traits/has_unique_object_representation.h>
+#include <__type_traits/has_virtual_destructor.h>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/is_abstract.h>
+#include <__type_traits/is_aggregate.h>
+#include <__type_traits/is_arithmetic.h>
+#include <__type_traits/is_array.h>
+#include <__type_traits/is_assignable.h>
+#include <__type_traits/is_base_of.h>
+#include <__type_traits/is_bounded_array.h>
+#include <__type_traits/is_callable.h>
+#include <__type_traits/is_class.h>
+#include <__type_traits/is_compound.h>
+#include <__type_traits/is_const.h>
+#include <__type_traits/is_constant_evaluated.h>
+#include <__type_traits/is_constructible.h>
+#include <__type_traits/is_convertible.h>
+#include <__type_traits/is_copy_assignable.h>
+#include <__type_traits/is_copy_constructible.h>
+#include <__type_traits/is_default_constructible.h>
+#include <__type_traits/is_destructible.h>
+#include <__type_traits/is_empty.h>
+#include <__type_traits/is_enum.h>
+#include <__type_traits/is_final.h>
+#include <__type_traits/is_floating_point.h>
+#include <__type_traits/is_function.h>
+#include <__type_traits/is_fundamental.h>
+#include <__type_traits/is_integral.h>
+#include <__type_traits/is_literal_type.h>
+#include <__type_traits/is_member_function_pointer.h>
+#include <__type_traits/is_member_object_pointer.h>
+#include <__type_traits/is_member_pointer.h>
+#include <__type_traits/is_move_assignable.h>
+#include <__type_traits/is_move_constructible.h>
+#include <__type_traits/is_nothrow_assignable.h>
+#include <__type_traits/is_nothrow_constructible.h>
+#include <__type_traits/is_nothrow_copy_assignable.h>
+#include <__type_traits/is_nothrow_copy_constructible.h>
+#include <__type_traits/is_nothrow_default_constructible.h>
+#include <__type_traits/is_nothrow_destructible.h>
+#include <__type_traits/is_nothrow_move_assignable.h>
+#include <__type_traits/is_nothrow_move_constructible.h>
+#include <__type_traits/is_null_pointer.h>
+#include <__type_traits/is_object.h>
+#include <__type_traits/is_pod.h>
+#include <__type_traits/is_pointer.h>
+#include <__type_traits/is_polymorphic.h>
+#include <__type_traits/is_reference.h>
+#include <__type_traits/is_reference_wrapper.h>
+#include <__type_traits/is_referenceable.h>
+#include <__type_traits/is_same.h>
+#include <__type_traits/is_scalar.h>
+#include <__type_traits/is_scoped_enum.h>
+#include <__type_traits/is_signed.h>
+#include <__type_traits/is_standard_layout.h>
+#include <__type_traits/is_trivial.h>
+#include <__type_traits/is_trivially_assignable.h>
+#include <__type_traits/is_trivially_constructible.h>
+#include <__type_traits/is_trivially_copy_assignable.h>
+#include <__type_traits/is_trivially_copy_constructible.h>
+#include <__type_traits/is_trivially_copyable.h>
+#include <__type_traits/is_trivially_default_constructible.h>
+#include <__type_traits/is_trivially_destructible.h>
+#include <__type_traits/is_trivially_move_assignable.h>
+#include <__type_traits/is_trivially_move_constructible.h>
+#include <__type_traits/is_unbounded_array.h>
+#include <__type_traits/is_union.h>
+#include <__type_traits/is_unsigned.h>
+#include <__type_traits/is_void.h>
+#include <__type_traits/is_volatile.h>
+#include <__type_traits/negation.h>
+#include <__type_traits/rank.h>
+#include <__type_traits/remove_all_extents.h>
+#include <__type_traits/remove_const.h>
+#include <__type_traits/remove_cv.h>
+#include <__type_traits/remove_extent.h>
+#include <__type_traits/remove_pointer.h>
+#include <__type_traits/remove_reference.h>
+#include <__type_traits/remove_volatile.h>
+#include <__type_traits/type_identity.h>
+#include <__type_traits/underlying_type.h>
+#include <__type_traits/void_t.h>
+#include <__utility/declval.h>
#include <cstddef>
+#include <cstdint>
#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _T1, class _T2> struct _LIBCPP_TEMPLATE_VIS pair;
-template <class _Tp> class _LIBCPP_TEMPLATE_VIS reference_wrapper;
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS hash;
-template <class _Tp, _Tp __v>
-struct _LIBCPP_TEMPLATE_VIS integral_constant
-{
- static _LIBCPP_CONSTEXPR const _Tp value = __v;
- typedef _Tp value_type;
- typedef integral_constant type;
- _LIBCPP_INLINE_VISIBILITY
- _LIBCPP_CONSTEXPR operator value_type() const _NOEXCEPT {return value;}
-#if _LIBCPP_STD_VER > 11
- _LIBCPP_INLINE_VISIBILITY
- constexpr value_type operator ()() const _NOEXCEPT {return value;}
-#endif
-};
-
-template <class _Tp, _Tp __v>
-_LIBCPP_CONSTEXPR const _Tp integral_constant<_Tp, __v>::value;
-
-#if _LIBCPP_STD_VER > 14
-template <bool __b>
-using bool_constant = integral_constant<bool, __b>;
-#define _LIBCPP_BOOL_CONSTANT(__b) bool_constant<(__b)>
-#else
-#define _LIBCPP_BOOL_CONSTANT(__b) integral_constant<bool,(__b)>
-#endif
-
-template <bool, class _Tp = void> struct _LIBCPP_TEMPLATE_VIS enable_if {};
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS enable_if<true, _Tp> {typedef _Tp type;};
-
-template <bool _Bp, class _Tp = void> using __enable_if_t _LIBCPP_NODEBUG = typename enable_if<_Bp, _Tp>::type;
-
-#if _LIBCPP_STD_VER > 11
-template <bool _Bp, class _Tp = void> using enable_if_t = typename enable_if<_Bp, _Tp>::type;
-#endif
-
-typedef _LIBCPP_BOOL_CONSTANT(true) true_type;
-typedef _LIBCPP_BOOL_CONSTANT(false) false_type;
-
-template <bool _Val>
-using _BoolConstant _LIBCPP_NODEBUG = integral_constant<bool, _Val>;
-
-template <bool> struct _MetaBase;
-template <>
-struct _MetaBase<true> {
- template <class _Tp, class _Up>
- using _SelectImpl _LIBCPP_NODEBUG = _Tp;
- template <template <class...> class _FirstFn, template <class...> class, class ..._Args>
- using _SelectApplyImpl _LIBCPP_NODEBUG = _FirstFn<_Args...>;
- template <class _First, class...>
- using _FirstImpl _LIBCPP_NODEBUG = _First;
- template <class, class _Second, class...>
- using _SecondImpl _LIBCPP_NODEBUG = _Second;
- template <class _Result, class _First, class ..._Rest>
- using _OrImpl _LIBCPP_NODEBUG = typename _MetaBase<_First::value != true && sizeof...(_Rest) != 0>::template _OrImpl<_First, _Rest...>;
-};
-
-template <>
-struct _MetaBase<false> {
- template <class _Tp, class _Up>
- using _SelectImpl _LIBCPP_NODEBUG = _Up;
- template <template <class...> class, template <class...> class _SecondFn, class ..._Args>
- using _SelectApplyImpl _LIBCPP_NODEBUG = _SecondFn<_Args...>;
- template <class _Result, class ...>
- using _OrImpl _LIBCPP_NODEBUG = _Result;
-};
-template <bool _Cond, class _IfRes, class _ElseRes>
-using _If _LIBCPP_NODEBUG = typename _MetaBase<_Cond>::template _SelectImpl<_IfRes, _ElseRes>;
-template <class ..._Rest>
-using _Or _LIBCPP_NODEBUG = typename _MetaBase< sizeof...(_Rest) != 0 >::template _OrImpl<false_type, _Rest...>;
-template <class _Pred>
-struct _Not : _BoolConstant<!_Pred::value> {};
-template <class ..._Args>
-using _FirstType _LIBCPP_NODEBUG = typename _MetaBase<(sizeof...(_Args) >= 1)>::template _FirstImpl<_Args...>;
-template <class ..._Args>
-using _SecondType _LIBCPP_NODEBUG = typename _MetaBase<(sizeof...(_Args) >= 2)>::template _SecondImpl<_Args...>;
-
-template <class ...> using __expand_to_true = true_type;
-template <class ..._Pred>
-__expand_to_true<__enable_if_t<_Pred::value>...> __and_helper(int);
-template <class ...>
-false_type __and_helper(...);
-template <class ..._Pred>
-using _And _LIBCPP_NODEBUG = decltype(__and_helper<_Pred...>(0));
-
template <template <class...> class _Func, class ..._Args>
struct _Lazy : _Func<_Args...> {};
@@ -526,51 +542,11 @@ false_type __sfinae_test_impl(...);
template <template <class ...> class _Templ, class ..._Args>
using _IsValidExpansion _LIBCPP_NODEBUG = decltype(__sfinae_test_impl<_Templ, _Args...>(0));
-template <class>
-struct __void_t { typedef void type; };
-
-template <class _Tp>
-struct __identity { typedef _Tp type; };
-
-template <class _Tp>
-using __identity_t _LIBCPP_NODEBUG = typename __identity<_Tp>::type;
-
template <class _Tp, bool>
struct _LIBCPP_TEMPLATE_VIS __dependent_type : public _Tp {};
-
-template <bool _Bp, class _If, class _Then>
- struct _LIBCPP_TEMPLATE_VIS conditional {typedef _If type;};
-template <class _If, class _Then>
- struct _LIBCPP_TEMPLATE_VIS conditional<false, _If, _Then> {typedef _Then type;};
-
-#if _LIBCPP_STD_VER > 11
-template <bool _Bp, class _If, class _Then> using conditional_t = typename conditional<_Bp, _If, _Then>::type;
-#endif
-
// is_same
-template <class _Tp, class _Up>
-struct _LIBCPP_TEMPLATE_VIS is_same : _BoolConstant<__is_same(_Tp, _Up)> { };
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp, class _Up>
-inline constexpr bool is_same_v = __is_same(_Tp, _Up);
-#endif
-
-// _IsSame<T,U> has the same effect as is_same<T,U> but instantiates fewer types:
-// is_same<A,B> and is_same<C,D> are guaranteed to be different types, but
-// _IsSame<A,B> and _IsSame<C,D> are the same type (namely, false_type).
-// Neither GCC nor Clang can mangle the __is_same builtin, so _IsSame
-// mustn't be directly used anywhere that contributes to name-mangling
-// (such as in a dependent return type).
-
-template <class _Tp, class _Up>
-using _IsSame = _BoolConstant<__is_same(_Tp, _Up)>;
-
-template <class _Tp, class _Up>
-using _IsNotSame = _BoolConstant<!__is_same(_Tp, _Up)>;
-
template <class _Tp>
using __test_for_primary_template = __enable_if_t<
_IsSame<_Tp, typename _Tp::__primary_template>::value
@@ -580,187 +556,8 @@ using __is_primary_template = _IsValidExpansion<
__test_for_primary_template, _Tp
>;
-// helper class
-
-struct __two {char __lx[2];};
-
-// is_const
-
-#if __has_keyword(__is_const)
-
-template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_const : _BoolConstant<__is_const(_Tp)> { };
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool is_const_v = __is_const(_Tp);
-#endif
-
-#else
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_const : public false_type {};
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_const<_Tp const> : public true_type {};
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool is_const_v = is_const<_Tp>::value;
-#endif
-
-#endif // __has_keyword(__is_const)
-
-// is_volatile
-
-#if __has_keyword(__is_volatile)
-
-template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_volatile : _BoolConstant<__is_volatile(_Tp)> { };
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool is_volatile_v = __is_volatile(_Tp);
-#endif
-
-#else
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_volatile : public false_type {};
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_volatile<_Tp volatile> : public true_type {};
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool is_volatile_v = is_volatile<_Tp>::value;
-#endif
-
-#endif // __has_keyword(__is_volatile)
-
-// remove_const
-
-#if __has_keyword(__remove_const)
-
-template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS remove_const {typedef __remove_const(_Tp) type;};
-
-#if _LIBCPP_STD_VER > 11
-template <class _Tp> using remove_const_t = __remove_const(_Tp);
-#endif
-
-#else
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_const {typedef _Tp type;};
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_const<const _Tp> {typedef _Tp type;};
-#if _LIBCPP_STD_VER > 11
-template <class _Tp> using remove_const_t = typename remove_const<_Tp>::type;
-#endif
-
-#endif // __has_keyword(__remove_const)
-
-// remove_volatile
-
-#if __has_keyword(__remove_volatile)
-
-template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS remove_volatile {typedef __remove_volatile(_Tp) type;};
-
-#if _LIBCPP_STD_VER > 11
-template <class _Tp> using remove_volatile_t = __remove_volatile(_Tp);
-#endif
-
-#else
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_volatile {typedef _Tp type;};
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_volatile<volatile _Tp> {typedef _Tp type;};
-#if _LIBCPP_STD_VER > 11
-template <class _Tp> using remove_volatile_t = typename remove_volatile<_Tp>::type;
-#endif
-
-#endif // __has_keyword(__remove_volatile)
-
-// remove_cv
-
-#if __has_keyword(__remove_cv)
-
-template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS remove_cv {typedef __remove_cv(_Tp) type;};
-
-#if _LIBCPP_STD_VER > 11
-template <class _Tp> using remove_cv_t = __remove_cv(_Tp);
-#endif
-
-#else
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_cv
-{typedef typename remove_volatile<typename remove_const<_Tp>::type>::type type;};
-#if _LIBCPP_STD_VER > 11
-template <class _Tp> using remove_cv_t = typename remove_cv<_Tp>::type;
-#endif
-
-#endif // __has_keyword(__remove_cv)
-
-// is_void
-
-#if __has_keyword(__is_void)
-
-template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_void : _BoolConstant<__is_void(_Tp)> { };
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool is_void_v = __is_void(_Tp);
-#endif
-
-#else
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_void
- : public is_same<typename remove_cv<_Tp>::type, void> {};
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool is_void_v = is_void<_Tp>::value;
-#endif
-
-#endif // __has_keyword(__is_void)
-
-// __is_nullptr_t
-
-template <class _Tp> struct __is_nullptr_t_impl : public false_type {};
-template <> struct __is_nullptr_t_impl<nullptr_t> : public true_type {};
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS __is_nullptr_t
- : public __is_nullptr_t_impl<typename remove_cv<_Tp>::type> {};
-
-#if _LIBCPP_STD_VER > 11
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_null_pointer
- : public __is_nullptr_t_impl<typename remove_cv<_Tp>::type> {};
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool is_null_pointer_v = is_null_pointer<_Tp>::value;
-#endif
-#endif // _LIBCPP_STD_VER > 11
-
// is_integral
-#if __has_keyword(__is_integral)
-
-template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_integral : _BoolConstant<__is_integral(_Tp)> { };
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool is_integral_v = __is_integral(_Tp);
-#endif
-
-#else
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_integral
- : public _BoolConstant<__libcpp_is_integral<typename remove_cv<_Tp>::type>::value> {};
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool is_integral_v = is_integral<_Tp>::value;
-#endif
-
-#endif // __has_keyword(__is_integral)
-
// [basic.fundamental] defines five standard signed integer types;
// __int128_t is an extended signed integer type.
// The signed and unsigned integer types, plus bool and the
@@ -786,956 +583,27 @@ template <> struct __libcpp_is_unsigned_integer<unsigned long long> : public tru
template <> struct __libcpp_is_unsigned_integer<__uint128_t> : public true_type {};
#endif
-// is_floating_point
-// <concepts> implements __libcpp_floating_point
-
-template <class _Tp> struct __libcpp_is_floating_point : public false_type {};
-template <> struct __libcpp_is_floating_point<float> : public true_type {};
-template <> struct __libcpp_is_floating_point<double> : public true_type {};
-template <> struct __libcpp_is_floating_point<long double> : public true_type {};
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_floating_point
- : public __libcpp_is_floating_point<typename remove_cv<_Tp>::type> {};
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool is_floating_point_v = is_floating_point<_Tp>::value;
-#endif
-
-// is_array
-
-#if __has_keyword(__is_array)
-
-template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_array : _BoolConstant<__is_array(_Tp)> { };
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool is_array_v = __is_array(_Tp);
-#endif
-
-#else
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_array
- : public false_type {};
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_array<_Tp[]>
- : public true_type {};
-template <class _Tp, size_t _Np> struct _LIBCPP_TEMPLATE_VIS is_array<_Tp[_Np]>
- : public true_type {};
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool is_array_v = is_array<_Tp>::value;
-#endif
-
-#endif // __has_keyword(__is_array)
-
-// is_pointer
-
-// Before AppleClang 12.0.5, __is_pointer didn't work for Objective-C types.
-#if __has_keyword(__is_pointer) && \
- !(defined(_LIBCPP_APPLE_CLANG_VER) && _LIBCPP_APPLE_CLANG_VER < 1205)
-
-template<class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_pointer : _BoolConstant<__is_pointer(_Tp)> { };
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool is_pointer_v = __is_pointer(_Tp);
-#endif
-
-#else // __has_keyword(__is_pointer)
-
-template <class _Tp> struct __libcpp_is_pointer : public false_type {};
-template <class _Tp> struct __libcpp_is_pointer<_Tp*> : public true_type {};
-
-template <class _Tp> struct __libcpp_remove_objc_qualifiers { typedef _Tp type; };
-#if defined(_LIBCPP_HAS_OBJC_ARC)
-template <class _Tp> struct __libcpp_remove_objc_qualifiers<_Tp __strong> { typedef _Tp type; };
-template <class _Tp> struct __libcpp_remove_objc_qualifiers<_Tp __weak> { typedef _Tp type; };
-template <class _Tp> struct __libcpp_remove_objc_qualifiers<_Tp __autoreleasing> { typedef _Tp type; };
-template <class _Tp> struct __libcpp_remove_objc_qualifiers<_Tp __unsafe_unretained> { typedef _Tp type; };
-#endif
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_pointer
- : public __libcpp_is_pointer<typename __libcpp_remove_objc_qualifiers<typename remove_cv<_Tp>::type>::type> {};
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool is_pointer_v = is_pointer<_Tp>::value;
-#endif
-
-#endif // __has_keyword(__is_pointer)
-
-// is_reference
-
-#if __has_keyword(__is_lvalue_reference) && \
- __has_keyword(__is_rvalue_reference) && \
- __has_keyword(__is_reference)
-
-template<class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_lvalue_reference : _BoolConstant<__is_lvalue_reference(_Tp)> { };
-
-template<class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_rvalue_reference : _BoolConstant<__is_rvalue_reference(_Tp)> { };
-
-template<class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_reference : _BoolConstant<__is_reference(_Tp)> { };
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool is_reference_v = __is_reference(_Tp);
-template <class _Tp>
-inline constexpr bool is_lvalue_reference_v = __is_lvalue_reference(_Tp);
-template <class _Tp>
-inline constexpr bool is_rvalue_reference_v = __is_rvalue_reference(_Tp);
-#endif
-
-#else // __has_keyword(__is_lvalue_reference) && etc...
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_lvalue_reference : public false_type {};
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_lvalue_reference<_Tp&> : public true_type {};
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_rvalue_reference : public false_type {};
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_rvalue_reference<_Tp&&> : public true_type {};
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_reference : public false_type {};
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_reference<_Tp&> : public true_type {};
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_reference<_Tp&&> : public true_type {};
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool is_reference_v = is_reference<_Tp>::value;
-
-template <class _Tp>
-inline constexpr bool is_lvalue_reference_v = is_lvalue_reference<_Tp>::value;
-
-template <class _Tp>
-inline constexpr bool is_rvalue_reference_v = is_rvalue_reference<_Tp>::value;
-#endif
-
-#endif // __has_keyword(__is_lvalue_reference) && etc...
-
-// is_union
-
-#if __has_feature(is_union) || defined(_LIBCPP_COMPILER_GCC)
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_union
- : public integral_constant<bool, __is_union(_Tp)> {};
-
-#else
-
-template <class _Tp> struct __libcpp_union : public false_type {};
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_union
- : public __libcpp_union<typename remove_cv<_Tp>::type> {};
-
-#endif
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool is_union_v = is_union<_Tp>::value;
-#endif
-
-// is_class
-
-#if __has_feature(is_class) || defined(_LIBCPP_COMPILER_GCC)
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_class
- : public integral_constant<bool, __is_class(_Tp)> {};
-
-#else
-
-namespace __is_class_imp
-{
-template <class _Tp> char __test(int _Tp::*);
-template <class _Tp> __two __test(...);
-}
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_class
- : public integral_constant<bool, sizeof(__is_class_imp::__test<_Tp>(0)) == 1 && !is_union<_Tp>::value> {};
-
-#endif
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool is_class_v = is_class<_Tp>::value;
-#endif
-
-// is_function
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_function
- : public _BoolConstant<
-#ifdef __clang__
- __is_function(_Tp)
-#else
- !(is_reference<_Tp>::value || is_const<const _Tp>::value)
-#endif
- > {};
-
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool is_function_v = is_function<_Tp>::value;
-#endif
-
-template <class _Tp> struct __libcpp_is_member_pointer {
- enum {
- __is_member = false,
- __is_func = false,
- __is_obj = false
- };
-};
-template <class _Tp, class _Up> struct __libcpp_is_member_pointer<_Tp _Up::*> {
- enum {
- __is_member = true,
- __is_func = is_function<_Tp>::value,
- __is_obj = !__is_func,
- };
-};
-
-#if __has_keyword(__is_member_function_pointer)
-
-template<class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_member_function_pointer
- : _BoolConstant<__is_member_function_pointer(_Tp)> { };
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool is_member_function_pointer_v = __is_member_function_pointer(_Tp);
-#endif
-
-#else // __has_keyword(__is_member_function_pointer)
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_member_function_pointer
- : public _BoolConstant< __libcpp_is_member_pointer<typename remove_cv<_Tp>::type>::__is_func > {};
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool is_member_function_pointer_v = is_member_function_pointer<_Tp>::value;
-#endif
-
-#endif // __has_keyword(__is_member_function_pointer)
-
-// is_member_pointer
-
-#if __has_keyword(__is_member_pointer)
-
-template<class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_member_pointer : _BoolConstant<__is_member_pointer(_Tp)> { };
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool is_member_pointer_v = __is_member_pointer(_Tp);
-#endif
-
-#else // __has_keyword(__is_member_pointer)
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_member_pointer
- : public _BoolConstant< __libcpp_is_member_pointer<typename remove_cv<_Tp>::type>::__is_member > {};
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool is_member_pointer_v = is_member_pointer<_Tp>::value;
-#endif
-
-#endif // __has_keyword(__is_member_pointer)
-
-// is_member_object_pointer
-
-#if __has_keyword(__is_member_object_pointer)
-
-template<class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_member_object_pointer
- : _BoolConstant<__is_member_object_pointer(_Tp)> { };
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool is_member_object_pointer_v = __is_member_object_pointer(_Tp);
-#endif
-
-#else // __has_keyword(__is_member_object_pointer)
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_member_object_pointer
- : public _BoolConstant< __libcpp_is_member_pointer<typename remove_cv<_Tp>::type>::__is_obj > {};
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool is_member_object_pointer_v = is_member_object_pointer<_Tp>::value;
-#endif
-
-#endif // __has_keyword(__is_member_object_pointer)
-
-// is_enum
-
-#if __has_feature(is_enum) || defined(_LIBCPP_COMPILER_GCC)
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_enum
- : public integral_constant<bool, __is_enum(_Tp)> {};
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool is_enum_v = __is_enum(_Tp);
-#endif
-
-#else
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_enum
- : public integral_constant<bool, !is_void<_Tp>::value &&
- !is_integral<_Tp>::value &&
- !is_floating_point<_Tp>::value &&
- !is_array<_Tp>::value &&
- !is_pointer<_Tp>::value &&
- !is_reference<_Tp>::value &&
- !is_member_pointer<_Tp>::value &&
- !is_union<_Tp>::value &&
- !is_class<_Tp>::value &&
- !is_function<_Tp>::value > {};
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool is_enum_v = is_enum<_Tp>::value;
-#endif
-
-#endif // __has_feature(is_enum) || defined(_LIBCPP_COMPILER_GCC)
-
-// is_arithmetic
-
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_arithmetic
- : public integral_constant<bool, is_integral<_Tp>::value ||
- is_floating_point<_Tp>::value> {};
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool is_arithmetic_v = is_arithmetic<_Tp>::value;
-#endif
-
-// is_fundamental
-
-// Before Clang 10, __is_fundamental didn't work for nullptr_t.
-// In C++03 nullptr_t is library-provided but must still count as "fundamental."
-#if __has_keyword(__is_fundamental) && \
- !(defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER < 1000) && \
- !defined(_LIBCPP_CXX03_LANG)
-
-template<class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_fundamental : _BoolConstant<__is_fundamental(_Tp)> { };
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool is_fundamental_v = __is_fundamental(_Tp);
-#endif
-
-#else // __has_keyword(__is_fundamental)
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_fundamental
- : public integral_constant<bool, is_void<_Tp>::value ||
- __is_nullptr_t<_Tp>::value ||
- is_arithmetic<_Tp>::value> {};
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool is_fundamental_v = is_fundamental<_Tp>::value;
-#endif
-
-#endif // __has_keyword(__is_fundamental)
-
-// is_scalar
-
-// In C++03 nullptr_t is library-provided but must still count as "scalar."
-#if __has_keyword(__is_scalar) && !defined(_LIBCPP_CXX03_LANG)
-
-template<class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_scalar : _BoolConstant<__is_scalar(_Tp)> { };
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool is_scalar_v = __is_scalar(_Tp);
-#endif
-
-#else // __has_keyword(__is_scalar)
-
-template <class _Tp> struct __is_block : false_type {};
-#if defined(_LIBCPP_HAS_EXTENSION_BLOCKS)
-template <class _Rp, class ..._Args> struct __is_block<_Rp (^)(_Args...)> : true_type {};
-#endif
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_scalar
- : public integral_constant<bool, is_arithmetic<_Tp>::value ||
- is_member_pointer<_Tp>::value ||
- is_pointer<_Tp>::value ||
- __is_nullptr_t<_Tp>::value ||
- __is_block<_Tp>::value ||
- is_enum<_Tp>::value > {};
-
-template <> struct _LIBCPP_TEMPLATE_VIS is_scalar<nullptr_t> : public true_type {};
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool is_scalar_v = is_scalar<_Tp>::value;
-#endif
-
-#endif // __has_keyword(__is_scalar)
-
-// is_object
-
-#if __has_keyword(__is_object)
-
-template<class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_object : _BoolConstant<__is_object(_Tp)> { };
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool is_object_v = __is_object(_Tp);
-#endif
-
-#else // __has_keyword(__is_object)
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_object
- : public integral_constant<bool, is_scalar<_Tp>::value ||
- is_array<_Tp>::value ||
- is_union<_Tp>::value ||
- is_class<_Tp>::value > {};
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool is_object_v = is_object<_Tp>::value;
-#endif
-
-#endif // __has_keyword(__is_object)
-
-// is_compound
-
-// >= 11 because in C++03 nullptr isn't actually nullptr
-#if __has_keyword(__is_compound) && !defined(_LIBCPP_CXX03_LANG)
-
-template<class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_compound : _BoolConstant<__is_compound(_Tp)> { };
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool is_compound_v = __is_compound(_Tp);
-#endif
-
-#else // __has_keyword(__is_compound)
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_compound
- : public integral_constant<bool, !is_fundamental<_Tp>::value> {};
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool is_compound_v = is_compound<_Tp>::value;
-#endif
-
-#endif // __has_keyword(__is_compound)
-
-// __is_referenceable [defns.referenceable]
-
-struct __is_referenceable_impl {
- template <class _Tp> static _Tp& __test(int);
- template <class _Tp> static __two __test(...);
-};
-
-template <class _Tp>
-struct __is_referenceable : integral_constant<bool,
- _IsNotSame<decltype(__is_referenceable_impl::__test<_Tp>(0)), __two>::value> {};
-
-
-// add_const
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS add_const {
- typedef _LIBCPP_NODEBUG const _Tp type;
-};
-
-#if _LIBCPP_STD_VER > 11
-template <class _Tp> using add_const_t = typename add_const<_Tp>::type;
-#endif
-
-// add_volatile
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS add_volatile {
- typedef _LIBCPP_NODEBUG volatile _Tp type;
-};
-
-#if _LIBCPP_STD_VER > 11
-template <class _Tp> using add_volatile_t = typename add_volatile<_Tp>::type;
-#endif
-
-// add_cv
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS add_cv {
- typedef _LIBCPP_NODEBUG const volatile _Tp type;
-};
-
-#if _LIBCPP_STD_VER > 11
-template <class _Tp> using add_cv_t = typename add_cv<_Tp>::type;
-#endif
-
-// remove_reference
-
-#if __has_keyword(__remove_reference)
-
-template<class _Tp>
-struct _LIBCPP_TEMPLATE_VIS remove_reference { typedef __remove_reference(_Tp) type; };
-
-#else // __has_keyword(__remove_reference)
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_reference {typedef _LIBCPP_NODEBUG _Tp type;};
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_reference<_Tp&> {typedef _LIBCPP_NODEBUG _Tp type;};
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_reference<_Tp&&> {typedef _LIBCPP_NODEBUG _Tp type;};
-
-#if _LIBCPP_STD_VER > 11
-template <class _Tp> using remove_reference_t = typename remove_reference<_Tp>::type;
-#endif
-
-#endif // __has_keyword(__remove_reference)
-
-// add_lvalue_reference
-
-template <class _Tp, bool = __is_referenceable<_Tp>::value> struct __add_lvalue_reference_impl { typedef _LIBCPP_NODEBUG _Tp type; };
-template <class _Tp > struct __add_lvalue_reference_impl<_Tp, true> { typedef _LIBCPP_NODEBUG _Tp& type; };
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS add_lvalue_reference
-{typedef _LIBCPP_NODEBUG typename __add_lvalue_reference_impl<_Tp>::type type;};
-
-#if _LIBCPP_STD_VER > 11
-template <class _Tp> using add_lvalue_reference_t = typename add_lvalue_reference<_Tp>::type;
-#endif
-
-template <class _Tp, bool = __is_referenceable<_Tp>::value> struct __add_rvalue_reference_impl { typedef _LIBCPP_NODEBUG _Tp type; };
-template <class _Tp > struct __add_rvalue_reference_impl<_Tp, true> { typedef _LIBCPP_NODEBUG _Tp&& type; };
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS add_rvalue_reference
-{typedef _LIBCPP_NODEBUG typename __add_rvalue_reference_impl<_Tp>::type type;};
-
-#if _LIBCPP_STD_VER > 11
-template <class _Tp> using add_rvalue_reference_t = typename add_rvalue_reference<_Tp>::type;
-#endif
-
-// Suppress deprecation notice for volatile-qualified return type resulting
-// from volatile-qualified types _Tp.
-_LIBCPP_SUPPRESS_DEPRECATED_PUSH
-template <class _Tp> _Tp&& __declval(int);
-template <class _Tp> _Tp __declval(long);
-_LIBCPP_SUPPRESS_DEPRECATED_POP
-
-template <class _Tp>
-decltype(__declval<_Tp>(0))
-declval() _NOEXCEPT;
-
-// __uncvref
-
-template <class _Tp>
-struct __uncvref {
- typedef _LIBCPP_NODEBUG typename remove_cv<typename remove_reference<_Tp>::type>::type type;
-};
-
template <class _Tp>
struct __unconstref {
typedef _LIBCPP_NODEBUG typename remove_const<typename remove_reference<_Tp>::type>::type type;
};
-#ifndef _LIBCPP_CXX03_LANG
template <class _Tp>
-using __uncvref_t _LIBCPP_NODEBUG = typename __uncvref<_Tp>::type;
-#endif
+using __uncvref_t _LIBCPP_NODEBUG = typename remove_cv<typename remove_reference<_Tp>::type>::type;
// __is_same_uncvref
template <class _Tp, class _Up>
-struct __is_same_uncvref : _IsSame<typename __uncvref<_Tp>::type,
- typename __uncvref<_Up>::type> {};
+struct __is_same_uncvref : _IsSame<__uncvref_t<_Tp>, __uncvref_t<_Up> > {};
#if _LIBCPP_STD_VER > 17
// remove_cvref - same as __uncvref
template <class _Tp>
-struct remove_cvref : public __uncvref<_Tp> {};
-
-template <class _Tp> using remove_cvref_t = typename remove_cvref<_Tp>::type;
-#endif
-
-
-struct __any
-{
- __any(...);
+struct remove_cvref {
+ using type _LIBCPP_NODEBUG = __uncvref_t<_Tp>;
};
-// remove_pointer
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_pointer {typedef _LIBCPP_NODEBUG _Tp type;};
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_pointer<_Tp*> {typedef _LIBCPP_NODEBUG _Tp type;};
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_pointer<_Tp* const> {typedef _LIBCPP_NODEBUG _Tp type;};
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_pointer<_Tp* volatile> {typedef _LIBCPP_NODEBUG _Tp type;};
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_pointer<_Tp* const volatile> {typedef _LIBCPP_NODEBUG _Tp type;};
-
-#if _LIBCPP_STD_VER > 11
-template <class _Tp> using remove_pointer_t = typename remove_pointer<_Tp>::type;
-#endif
-
-// add_pointer
-
-template <class _Tp,
- bool = __is_referenceable<_Tp>::value ||
- _IsSame<typename remove_cv<_Tp>::type, void>::value>
-struct __add_pointer_impl
- {typedef _LIBCPP_NODEBUG typename remove_reference<_Tp>::type* type;};
-template <class _Tp> struct __add_pointer_impl<_Tp, false>
- {typedef _LIBCPP_NODEBUG _Tp type;};
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS add_pointer
- {typedef _LIBCPP_NODEBUG typename __add_pointer_impl<_Tp>::type type;};
-
-#if _LIBCPP_STD_VER > 11
-template <class _Tp> using add_pointer_t = typename add_pointer<_Tp>::type;
-#endif
-
-// type_identity
-#if _LIBCPP_STD_VER > 17
-template<class _Tp> struct type_identity { typedef _Tp type; };
-template<class _Tp> using type_identity_t = typename type_identity<_Tp>::type;
-#endif
-
-// is_signed
-
-#if __has_keyword(__is_signed)
-
-template<class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_signed : _BoolConstant<__is_signed(_Tp)> { };
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool is_signed_v = __is_signed(_Tp);
-#endif
-
-#else // __has_keyword(__is_signed)
-
-template <class _Tp, bool = is_integral<_Tp>::value>
-struct __libcpp_is_signed_impl : public _LIBCPP_BOOL_CONSTANT(_Tp(-1) < _Tp(0)) {};
-
-template <class _Tp>
-struct __libcpp_is_signed_impl<_Tp, false> : public true_type {}; // floating point
-
-template <class _Tp, bool = is_arithmetic<_Tp>::value>
-struct __libcpp_is_signed : public __libcpp_is_signed_impl<_Tp> {};
-
-template <class _Tp> struct __libcpp_is_signed<_Tp, false> : public false_type {};
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_signed : public __libcpp_is_signed<_Tp> {};
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool is_signed_v = is_signed<_Tp>::value;
-#endif
-
-#endif // __has_keyword(__is_signed)
-
-// is_unsigned
-
-// Before Clang 13, __is_unsigned returned true for enums with signed underlying type.
-// No currently-released version of AppleClang contains the fixed intrinsic.
-#if __has_keyword(__is_unsigned) && \
- !(defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER < 1300) && \
- !defined(_LIBCPP_APPLE_CLANG_VER)
-
-template<class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_unsigned : _BoolConstant<__is_unsigned(_Tp)> { };
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool is_unsigned_v = __is_unsigned(_Tp);
-#endif
-
-#else // __has_keyword(__is_unsigned)
-
-template <class _Tp, bool = is_integral<_Tp>::value>
-struct __libcpp_is_unsigned_impl : public _LIBCPP_BOOL_CONSTANT(_Tp(0) < _Tp(-1)) {};
-
-template <class _Tp>
-struct __libcpp_is_unsigned_impl<_Tp, false> : public false_type {}; // floating point
-
-template <class _Tp, bool = is_arithmetic<_Tp>::value>
-struct __libcpp_is_unsigned : public __libcpp_is_unsigned_impl<_Tp> {};
-
-template <class _Tp> struct __libcpp_is_unsigned<_Tp, false> : public false_type {};
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_unsigned : public __libcpp_is_unsigned<_Tp> {};
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool is_unsigned_v = is_unsigned<_Tp>::value;
-#endif
-
-#endif // __has_keyword(__is_unsigned)
-
-// rank
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS rank
- : public integral_constant<size_t, 0> {};
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS rank<_Tp[]>
- : public integral_constant<size_t, rank<_Tp>::value + 1> {};
-template <class _Tp, size_t _Np> struct _LIBCPP_TEMPLATE_VIS rank<_Tp[_Np]>
- : public integral_constant<size_t, rank<_Tp>::value + 1> {};
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr size_t rank_v = rank<_Tp>::value;
-#endif
-
-// extent
-
-#if __has_keyword(__array_extent)
-
-template<class _Tp, size_t _Dim = 0>
-struct _LIBCPP_TEMPLATE_VIS extent
- : integral_constant<size_t, __array_extent(_Tp, _Dim)> { };
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp, unsigned _Ip = 0>
-inline constexpr size_t extent_v = __array_extent(_Tp, _Ip);
-#endif
-
-#else // __has_keyword(__array_extent)
-
-template <class _Tp, unsigned _Ip = 0> struct _LIBCPP_TEMPLATE_VIS extent
- : public integral_constant<size_t, 0> {};
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS extent<_Tp[], 0>
- : public integral_constant<size_t, 0> {};
-template <class _Tp, unsigned _Ip> struct _LIBCPP_TEMPLATE_VIS extent<_Tp[], _Ip>
- : public integral_constant<size_t, extent<_Tp, _Ip-1>::value> {};
-template <class _Tp, size_t _Np> struct _LIBCPP_TEMPLATE_VIS extent<_Tp[_Np], 0>
- : public integral_constant<size_t, _Np> {};
-template <class _Tp, size_t _Np, unsigned _Ip> struct _LIBCPP_TEMPLATE_VIS extent<_Tp[_Np], _Ip>
- : public integral_constant<size_t, extent<_Tp, _Ip-1>::value> {};
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp, unsigned _Ip = 0>
-inline constexpr size_t extent_v = extent<_Tp, _Ip>::value;
-#endif
-
-#endif // __has_keyword(__array_extent)
-
-// remove_extent
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_extent
- {typedef _Tp type;};
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_extent<_Tp[]>
- {typedef _Tp type;};
-template <class _Tp, size_t _Np> struct _LIBCPP_TEMPLATE_VIS remove_extent<_Tp[_Np]>
- {typedef _Tp type;};
-
-#if _LIBCPP_STD_VER > 11
-template <class _Tp> using remove_extent_t = typename remove_extent<_Tp>::type;
-#endif
-
-// remove_all_extents
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_all_extents
- {typedef _Tp type;};
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_all_extents<_Tp[]>
- {typedef typename remove_all_extents<_Tp>::type type;};
-template <class _Tp, size_t _Np> struct _LIBCPP_TEMPLATE_VIS remove_all_extents<_Tp[_Np]>
- {typedef typename remove_all_extents<_Tp>::type type;};
-
-#if _LIBCPP_STD_VER > 11
-template <class _Tp> using remove_all_extents_t = typename remove_all_extents<_Tp>::type;
-#endif
-
-#if _LIBCPP_STD_VER > 17
-// is_bounded_array
-
-template <class> struct _LIBCPP_TEMPLATE_VIS is_bounded_array : false_type {};
-template <class _Tp, size_t _Np> struct _LIBCPP_TEMPLATE_VIS is_bounded_array<_Tp[_Np]> : true_type {};
-
-template <class _Tp>
-inline constexpr
-bool is_bounded_array_v = is_bounded_array<_Tp>::value;
-
-// is_unbounded_array
-
-template <class> struct _LIBCPP_TEMPLATE_VIS is_unbounded_array : false_type {};
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_unbounded_array<_Tp[]> : true_type {};
-
-template <class _Tp>
-inline constexpr
-bool is_unbounded_array_v = is_unbounded_array<_Tp>::value;
-#endif
-
-// decay
-
-template <class _Up, bool>
-struct __decay {
- typedef _LIBCPP_NODEBUG typename remove_cv<_Up>::type type;
-};
-
-template <class _Up>
-struct __decay<_Up, true> {
-public:
- typedef _LIBCPP_NODEBUG typename conditional
- <
- is_array<_Up>::value,
- typename remove_extent<_Up>::type*,
- typename conditional
- <
- is_function<_Up>::value,
- typename add_pointer<_Up>::type,
- typename remove_cv<_Up>::type
- >::type
- >::type type;
-};
-
-template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS decay
-{
-private:
- typedef _LIBCPP_NODEBUG typename remove_reference<_Tp>::type _Up;
-public:
- typedef _LIBCPP_NODEBUG typename __decay<_Up, __is_referenceable<_Up>::value>::type type;
-};
-
-#if _LIBCPP_STD_VER > 11
-template <class _Tp> using decay_t = typename decay<_Tp>::type;
-#endif
-
-// is_abstract
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_abstract
- : public integral_constant<bool, __is_abstract(_Tp)> {};
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool is_abstract_v = is_abstract<_Tp>::value;
-#endif
-
-// is_final
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS
-__libcpp_is_final : public integral_constant<bool, __is_final(_Tp)> {};
-
-#if _LIBCPP_STD_VER > 11
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS
-is_final : public integral_constant<bool, __is_final(_Tp)> {};
-#endif
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool is_final_v = is_final<_Tp>::value;
-#endif
-
-// is_aggregate
-#if _LIBCPP_STD_VER > 14
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS
-is_aggregate : public integral_constant<bool, __is_aggregate(_Tp)> {};
-
-template <class _Tp>
-inline constexpr bool is_aggregate_v = is_aggregate<_Tp>::value;
-
-#endif // _LIBCPP_STD_VER > 14
-
-// is_base_of
-
-template <class _Bp, class _Dp>
-struct _LIBCPP_TEMPLATE_VIS is_base_of
- : public integral_constant<bool, __is_base_of(_Bp, _Dp)> {};
-
-#if _LIBCPP_STD_VER > 14
-template <class _Bp, class _Dp>
-inline constexpr bool is_base_of_v = is_base_of<_Bp, _Dp>::value;
-#endif
-
-// __is_core_convertible
-
-// [conv.general]/3 says "E is convertible to T" whenever "T t=E;" is well-formed.
-// We can't test for that, but we can test implicit convertibility by passing it
-// to a function. Notice that __is_core_convertible<void,void> is false,
-// and __is_core_convertible<immovable-type,immovable-type> is true in C++17 and later.
-
-template <class _Tp, class _Up, class = void>
-struct __is_core_convertible : public false_type {};
-
-template <class _Tp, class _Up>
-struct __is_core_convertible<_Tp, _Up, decltype(
- static_cast<void(*)(_Up)>(0) ( static_cast<_Tp(*)()>(0)() )
-)> : public true_type {};
-
-// is_convertible
-
-#if __has_feature(is_convertible_to) && !defined(_LIBCPP_USE_IS_CONVERTIBLE_FALLBACK)
-
-template <class _T1, class _T2> struct _LIBCPP_TEMPLATE_VIS is_convertible
- : public integral_constant<bool, __is_convertible_to(_T1, _T2)> {};
-
-#else // __has_feature(is_convertible_to)
-
-namespace __is_convertible_imp
-{
-template <class _Tp> void __test_convert(_Tp);
-
-template <class _From, class _To, class = void>
-struct __is_convertible_test : public false_type {};
-
-template <class _From, class _To>
-struct __is_convertible_test<_From, _To,
- decltype(__is_convertible_imp::__test_convert<_To>(declval<_From>()))> : public true_type
-{};
-
-template <class _Tp, bool _IsArray = is_array<_Tp>::value,
- bool _IsFunction = is_function<_Tp>::value,
- bool _IsVoid = is_void<_Tp>::value>
- struct __is_array_function_or_void {enum {value = 0};};
-template <class _Tp> struct __is_array_function_or_void<_Tp, true, false, false> {enum {value = 1};};
-template <class _Tp> struct __is_array_function_or_void<_Tp, false, true, false> {enum {value = 2};};
-template <class _Tp> struct __is_array_function_or_void<_Tp, false, false, true> {enum {value = 3};};
-}
-
-template <class _Tp,
- unsigned = __is_convertible_imp::__is_array_function_or_void<typename remove_reference<_Tp>::type>::value>
-struct __is_convertible_check
-{
- static const size_t __v = 0;
-};
-
-template <class _Tp>
-struct __is_convertible_check<_Tp, 0>
-{
- static const size_t __v = sizeof(_Tp);
-};
-
-template <class _T1, class _T2,
- unsigned _T1_is_array_function_or_void = __is_convertible_imp::__is_array_function_or_void<_T1>::value,
- unsigned _T2_is_array_function_or_void = __is_convertible_imp::__is_array_function_or_void<_T2>::value>
-struct __is_convertible
- : public integral_constant<bool,
- __is_convertible_imp::__is_convertible_test<_T1, _T2>::value
- >
-{};
-
-template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 0, 1> : public false_type {};
-template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 1, 1> : public false_type {};
-template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 2, 1> : public false_type {};
-template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 3, 1> : public false_type {};
-
-template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 0, 2> : public false_type {};
-template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 1, 2> : public false_type {};
-template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 2, 2> : public false_type {};
-template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 3, 2> : public false_type {};
-
-template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 0, 3> : public false_type {};
-template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 1, 3> : public false_type {};
-template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 2, 3> : public false_type {};
-template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 3, 3> : public true_type {};
-
-template <class _T1, class _T2> struct _LIBCPP_TEMPLATE_VIS is_convertible
- : public __is_convertible<_T1, _T2>
-{
- static const size_t __complete_check1 = __is_convertible_check<_T1>::__v;
- static const size_t __complete_check2 = __is_convertible_check<_T2>::__v;
-};
-
-#endif // __has_feature(is_convertible_to)
-
-#if _LIBCPP_STD_VER > 14
-template <class _From, class _To>
-inline constexpr bool is_convertible_v = is_convertible<_From, _To>::value;
+template <class _Tp> using remove_cvref_t = typename remove_cvref<_Tp>::type;
#endif
// is_nothrow_convertible
@@ -1764,109 +632,6 @@ inline constexpr bool is_nothrow_convertible_v = is_nothrow_convertible<_Fm, _To
#endif // _LIBCPP_STD_VER > 17
-// is_empty
-
-#if __has_feature(is_empty) || defined(_LIBCPP_COMPILER_GCC)
-
-template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_empty
- : public integral_constant<bool, __is_empty(_Tp)> {};
-
-#else // __has_feature(is_empty)
-
-template <class _Tp>
-struct __is_empty1
- : public _Tp
-{
- double __lx;
-};
-
-struct __is_empty2
-{
- double __lx;
-};
-
-template <class _Tp, bool = is_class<_Tp>::value>
-struct __libcpp_empty : public integral_constant<bool, sizeof(__is_empty1<_Tp>) == sizeof(__is_empty2)> {};
-
-template <class _Tp> struct __libcpp_empty<_Tp, false> : public false_type {};
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_empty : public __libcpp_empty<_Tp> {};
-
-#endif // __has_feature(is_empty)
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool is_empty_v = is_empty<_Tp>::value;
-#endif
-
-// is_polymorphic
-
-#if __has_feature(is_polymorphic) || defined(_LIBCPP_COMPILER_MSVC)
-
-template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_polymorphic
- : public integral_constant<bool, __is_polymorphic(_Tp)> {};
-
-#else
-
-template<typename _Tp> char &__is_polymorphic_impl(
- typename enable_if<sizeof((_Tp*)dynamic_cast<const volatile void*>(declval<_Tp*>())) != 0,
- int>::type);
-template<typename _Tp> __two &__is_polymorphic_impl(...);
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_polymorphic
- : public integral_constant<bool, sizeof(__is_polymorphic_impl<_Tp>(0)) == 1> {};
-
-#endif // __has_feature(is_polymorphic)
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool is_polymorphic_v = is_polymorphic<_Tp>::value;
-#endif
-
-// has_virtual_destructor
-
-#if __has_feature(has_virtual_destructor) || defined(_LIBCPP_COMPILER_GCC)
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS has_virtual_destructor
- : public integral_constant<bool, __has_virtual_destructor(_Tp)> {};
-
-#else
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS has_virtual_destructor
- : public false_type {};
-
-#endif
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool has_virtual_destructor_v = has_virtual_destructor<_Tp>::value;
-#endif
-
-// has_unique_object_representations
-
-#if _LIBCPP_STD_VER > 14
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS has_unique_object_representations
- : public integral_constant<bool,
- __has_unique_object_representations(remove_cv_t<remove_all_extents_t<_Tp>>)> {};
-
-template <class _Tp>
-inline constexpr bool has_unique_object_representations_v = has_unique_object_representations<_Tp>::value;
-
-#endif
-
-// alignment_of
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS alignment_of
- : public integral_constant<size_t, _LIBCPP_ALIGNOF(_Tp)> {};
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr size_t alignment_of_v = alignment_of<_Tp>::value;
-#endif
-
// aligned_storage
template <class _Hp, class _Tp>
@@ -1876,16 +641,6 @@ struct __type_list
typedef _Tp _Tail;
};
-struct __nat
-{
-#ifndef _LIBCPP_CXX03_LANG
- __nat() = delete;
- __nat(const __nat&) = delete;
- __nat& operator=(const __nat&) = delete;
- ~__nat() = delete;
-#endif
-};
-
template <class _Tp>
struct __align_type
{
@@ -2151,55 +906,6 @@ struct __find_first<__type_list<_Hp, _Tp>, _Size, false>
typedef _LIBCPP_NODEBUG typename __find_first<_Tp, _Size>::type type;
};
-template <class _Tp, class _Up, bool = is_const<typename remove_reference<_Tp>::type>::value,
- bool = is_volatile<typename remove_reference<_Tp>::type>::value>
-struct __apply_cv
-{
- typedef _LIBCPP_NODEBUG _Up type;
-};
-
-template <class _Tp, class _Up>
-struct __apply_cv<_Tp, _Up, true, false>
-{
- typedef _LIBCPP_NODEBUG const _Up type;
-};
-
-template <class _Tp, class _Up>
-struct __apply_cv<_Tp, _Up, false, true>
-{
- typedef volatile _Up type;
-};
-
-template <class _Tp, class _Up>
-struct __apply_cv<_Tp, _Up, true, true>
-{
- typedef const volatile _Up type;
-};
-
-template <class _Tp, class _Up>
-struct __apply_cv<_Tp&, _Up, false, false>
-{
- typedef _Up& type;
-};
-
-template <class _Tp, class _Up>
-struct __apply_cv<_Tp&, _Up, true, false>
-{
- typedef const _Up& type;
-};
-
-template <class _Tp, class _Up>
-struct __apply_cv<_Tp&, _Up, false, true>
-{
- typedef volatile _Up& type;
-};
-
-template <class _Tp, class _Up>
-struct __apply_cv<_Tp&, _Up, true, true>
-{
- typedef const volatile _Up& type;
-};
-
template <class _Tp, bool = is_integral<_Tp>::value || is_enum<_Tp>::value>
struct __make_signed {};
@@ -2274,9 +980,28 @@ typename make_unsigned<_Tp>::type __to_unsigned_like(_Tp __x) noexcept {
}
#endif
-#if _LIBCPP_STD_VER > 14
-template <class...> using void_t = void;
+template <class _Tp, class _Up>
+using __copy_unsigned_t = __conditional_t<is_unsigned<_Tp>::value, typename make_unsigned<_Up>::type, _Up>;
+
+/// Helper to promote an integral to smallest 32, 64, or 128 bit representation.
+///
+/// The restriction is the same as the integral version of to_char.
+template <class _Tp>
+#if _LIBCPP_STD_VER > 17
+ requires (is_signed_v<_Tp> || is_unsigned_v<_Tp> || is_same_v<_Tp, char>)
+#endif
+using __make_32_64_or_128_bit_t =
+ __copy_unsigned_t<_Tp,
+ __conditional_t<sizeof(_Tp) <= sizeof(int32_t), int32_t,
+ __conditional_t<sizeof(_Tp) <= sizeof(int64_t), int64_t,
+#ifndef _LIBCPP_HAS_NO_INT128
+ __conditional_t<sizeof(_Tp) <= sizeof(__int128_t), __int128_t,
+ /* else */ void>
+#else
+ /* else */ void
#endif
+ > >
+ >;
#if _LIBCPP_STD_VER > 17
// Let COND_RES(X, Y) be:
@@ -2388,7 +1113,6 @@ struct _LIBCPP_TEMPLATE_VIS
template <class ..._Tp> using common_type_t = typename common_type<_Tp...>::type;
#endif
-#if _LIBCPP_STD_VER > 11
// Let COPYCV(FROM, TO) be an alias for type TO with the addition of FROM's
// top-level cv-qualifiers.
template <class _From, class _To>
@@ -2400,19 +1124,19 @@ struct __copy_cv
template <class _From, class _To>
struct __copy_cv<const _From, _To>
{
- using type = add_const_t<_To>;
+ using type = typename add_const<_To>::type;
};
template <class _From, class _To>
struct __copy_cv<volatile _From, _To>
{
- using type = add_volatile_t<_To>;
+ using type = typename add_volatile<_To>::type;
};
template <class _From, class _To>
struct __copy_cv<const volatile _From, _To>
{
- using type = add_cv_t<_To>;
+ using type = typename add_cv<_To>::type;
};
template <class _From, class _To>
@@ -2427,22 +1151,21 @@ struct __copy_cvref
template <class _From, class _To>
struct __copy_cvref<_From&, _To>
{
- using type = add_lvalue_reference_t<__copy_cv_t<_From, _To>>;
+ using type = typename add_lvalue_reference<__copy_cv_t<_From, _To> >::type;
};
template <class _From, class _To>
struct __copy_cvref<_From&&, _To>
{
- using type = add_rvalue_reference_t<__copy_cv_t<_From, _To>>;
+ using type = typename add_rvalue_reference<__copy_cv_t<_From, _To> >::type;
};
template <class _From, class _To>
using __copy_cvref_t = typename __copy_cvref<_From, _To>::type;
-#endif // _LIBCPP_STD_VER > 11
// common_reference
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17
// Let COND_RES(X, Y) be:
template <class _Xp, class _Yp>
using __cond_res =
@@ -2596,404 +1319,7 @@ struct common_reference<_Tp, _Up, _Vp, _Rest...>
// bullet 5 - Otherwise, there shall be no member `type`.
template <class...> struct common_reference {};
-#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
-
-// is_assignable
-
-template<typename, typename _Tp> struct __select_2nd { typedef _LIBCPP_NODEBUG _Tp type; };
-
-#if __has_keyword(__is_assignable)
-
-template<class _Tp, class _Up>
-struct _LIBCPP_TEMPLATE_VIS is_assignable : _BoolConstant<__is_assignable(_Tp, _Up)> { };
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp, class _Arg>
-inline constexpr bool is_assignable_v = __is_assignable(_Tp, _Arg);
-#endif
-
-#else // __has_keyword(__is_assignable)
-
-template <class _Tp, class _Arg>
-typename __select_2nd<decltype((declval<_Tp>() = declval<_Arg>())), true_type>::type
-__is_assignable_test(int);
-
-template <class, class>
-false_type __is_assignable_test(...);
-
-
-template <class _Tp, class _Arg, bool = is_void<_Tp>::value || is_void<_Arg>::value>
-struct __is_assignable_imp
- : public decltype((_VSTD::__is_assignable_test<_Tp, _Arg>(0))) {};
-
-template <class _Tp, class _Arg>
-struct __is_assignable_imp<_Tp, _Arg, true>
- : public false_type
-{
-};
-
-template <class _Tp, class _Arg>
-struct is_assignable
- : public __is_assignable_imp<_Tp, _Arg> {};
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp, class _Arg>
-inline constexpr bool is_assignable_v = is_assignable<_Tp, _Arg>::value;
-#endif
-
-#endif // __has_keyword(__is_assignable)
-
-// is_copy_assignable
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_copy_assignable
- : public is_assignable<typename add_lvalue_reference<_Tp>::type,
- typename add_lvalue_reference<typename add_const<_Tp>::type>::type> {};
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool is_copy_assignable_v = is_copy_assignable<_Tp>::value;
-#endif
-
-// is_move_assignable
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_move_assignable
- : public is_assignable<typename add_lvalue_reference<_Tp>::type,
- typename add_rvalue_reference<_Tp>::type> {};
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool is_move_assignable_v = is_move_assignable<_Tp>::value;
-#endif
-
-// is_destructible
-
-#if __has_keyword(__is_destructible)
-
-template<class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_destructible : _BoolConstant<__is_destructible(_Tp)> { };
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool is_destructible_v = __is_destructible(_Tp);
-#endif
-
-#else // __has_keyword(__is_destructible)
-
-// if it's a reference, return true
-// if it's a function, return false
-// if it's void, return false
-// if it's an array of unknown bound, return false
-// Otherwise, return "declval<_Up&>().~_Up()" is well-formed
-// where _Up is remove_all_extents<_Tp>::type
-
-template <class>
-struct __is_destructible_apply { typedef int type; };
-
-template <typename _Tp>
-struct __is_destructor_wellformed {
- template <typename _Tp1>
- static char __test (
- typename __is_destructible_apply<decltype(declval<_Tp1&>().~_Tp1())>::type
- );
-
- template <typename _Tp1>
- static __two __test (...);
-
- static const bool value = sizeof(__test<_Tp>(12)) == sizeof(char);
-};
-
-template <class _Tp, bool>
-struct __destructible_imp;
-
-template <class _Tp>
-struct __destructible_imp<_Tp, false>
- : public integral_constant<bool,
- __is_destructor_wellformed<typename remove_all_extents<_Tp>::type>::value> {};
-
-template <class _Tp>
-struct __destructible_imp<_Tp, true>
- : public true_type {};
-
-template <class _Tp, bool>
-struct __destructible_false;
-
-template <class _Tp>
-struct __destructible_false<_Tp, false> : public __destructible_imp<_Tp, is_reference<_Tp>::value> {};
-
-template <class _Tp>
-struct __destructible_false<_Tp, true> : public false_type {};
-
-template <class _Tp>
-struct is_destructible
- : public __destructible_false<_Tp, is_function<_Tp>::value> {};
-
-template <class _Tp>
-struct is_destructible<_Tp[]>
- : public false_type {};
-
-template <>
-struct is_destructible<void>
- : public false_type {};
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool is_destructible_v = is_destructible<_Tp>::value;
-#endif
-
-#endif // __has_keyword(__is_destructible)
-
-template <class _MP, bool _IsMemberFunctionPtr, bool _IsMemberObjectPtr>
-struct __member_pointer_traits_imp
-{
-};
-
-template <class _Rp, class _Class, class ..._Param>
-struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...), true, false>
-{
- typedef _Class _ClassType;
- typedef _Rp _ReturnType;
- typedef _Rp (_FnType) (_Param...);
-};
-
-template <class _Rp, class _Class, class ..._Param>
-struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...), true, false>
-{
- typedef _Class _ClassType;
- typedef _Rp _ReturnType;
- typedef _Rp (_FnType) (_Param..., ...);
-};
-
-template <class _Rp, class _Class, class ..._Param>
-struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const, true, false>
-{
- typedef _Class const _ClassType;
- typedef _Rp _ReturnType;
- typedef _Rp (_FnType) (_Param...);
-};
-
-template <class _Rp, class _Class, class ..._Param>
-struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const, true, false>
-{
- typedef _Class const _ClassType;
- typedef _Rp _ReturnType;
- typedef _Rp (_FnType) (_Param..., ...);
-};
-
-template <class _Rp, class _Class, class ..._Param>
-struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) volatile, true, false>
-{
- typedef _Class volatile _ClassType;
- typedef _Rp _ReturnType;
- typedef _Rp (_FnType) (_Param...);
-};
-
-template <class _Rp, class _Class, class ..._Param>
-struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) volatile, true, false>
-{
- typedef _Class volatile _ClassType;
- typedef _Rp _ReturnType;
- typedef _Rp (_FnType) (_Param..., ...);
-};
-
-template <class _Rp, class _Class, class ..._Param>
-struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const volatile, true, false>
-{
- typedef _Class const volatile _ClassType;
- typedef _Rp _ReturnType;
- typedef _Rp (_FnType) (_Param...);
-};
-
-template <class _Rp, class _Class, class ..._Param>
-struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const volatile, true, false>
-{
- typedef _Class const volatile _ClassType;
- typedef _Rp _ReturnType;
- typedef _Rp (_FnType) (_Param..., ...);
-};
-
-#if __has_feature(cxx_reference_qualified_functions) || defined(_LIBCPP_COMPILER_GCC)
-
-template <class _Rp, class _Class, class ..._Param>
-struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) &, true, false>
-{
- typedef _Class& _ClassType;
- typedef _Rp _ReturnType;
- typedef _Rp (_FnType) (_Param...);
-};
-
-template <class _Rp, class _Class, class ..._Param>
-struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) &, true, false>
-{
- typedef _Class& _ClassType;
- typedef _Rp _ReturnType;
- typedef _Rp (_FnType) (_Param..., ...);
-};
-
-template <class _Rp, class _Class, class ..._Param>
-struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const&, true, false>
-{
- typedef _Class const& _ClassType;
- typedef _Rp _ReturnType;
- typedef _Rp (_FnType) (_Param...);
-};
-
-template <class _Rp, class _Class, class ..._Param>
-struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const&, true, false>
-{
- typedef _Class const& _ClassType;
- typedef _Rp _ReturnType;
- typedef _Rp (_FnType) (_Param..., ...);
-};
-
-template <class _Rp, class _Class, class ..._Param>
-struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) volatile&, true, false>
-{
- typedef _Class volatile& _ClassType;
- typedef _Rp _ReturnType;
- typedef _Rp (_FnType) (_Param...);
-};
-
-template <class _Rp, class _Class, class ..._Param>
-struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) volatile&, true, false>
-{
- typedef _Class volatile& _ClassType;
- typedef _Rp _ReturnType;
- typedef _Rp (_FnType) (_Param..., ...);
-};
-
-template <class _Rp, class _Class, class ..._Param>
-struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const volatile&, true, false>
-{
- typedef _Class const volatile& _ClassType;
- typedef _Rp _ReturnType;
- typedef _Rp (_FnType) (_Param...);
-};
-
-template <class _Rp, class _Class, class ..._Param>
-struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const volatile&, true, false>
-{
- typedef _Class const volatile& _ClassType;
- typedef _Rp _ReturnType;
- typedef _Rp (_FnType) (_Param..., ...);
-};
-
-template <class _Rp, class _Class, class ..._Param>
-struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) &&, true, false>
-{
- typedef _Class&& _ClassType;
- typedef _Rp _ReturnType;
- typedef _Rp (_FnType) (_Param...);
-};
-
-template <class _Rp, class _Class, class ..._Param>
-struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) &&, true, false>
-{
- typedef _Class&& _ClassType;
- typedef _Rp _ReturnType;
- typedef _Rp (_FnType) (_Param..., ...);
-};
-
-template <class _Rp, class _Class, class ..._Param>
-struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const&&, true, false>
-{
- typedef _Class const&& _ClassType;
- typedef _Rp _ReturnType;
- typedef _Rp (_FnType) (_Param...);
-};
-
-template <class _Rp, class _Class, class ..._Param>
-struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const&&, true, false>
-{
- typedef _Class const&& _ClassType;
- typedef _Rp _ReturnType;
- typedef _Rp (_FnType) (_Param..., ...);
-};
-
-template <class _Rp, class _Class, class ..._Param>
-struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) volatile&&, true, false>
-{
- typedef _Class volatile&& _ClassType;
- typedef _Rp _ReturnType;
- typedef _Rp (_FnType) (_Param...);
-};
-
-template <class _Rp, class _Class, class ..._Param>
-struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) volatile&&, true, false>
-{
- typedef _Class volatile&& _ClassType;
- typedef _Rp _ReturnType;
- typedef _Rp (_FnType) (_Param..., ...);
-};
-
-template <class _Rp, class _Class, class ..._Param>
-struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const volatile&&, true, false>
-{
- typedef _Class const volatile&& _ClassType;
- typedef _Rp _ReturnType;
- typedef _Rp (_FnType) (_Param...);
-};
-
-template <class _Rp, class _Class, class ..._Param>
-struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const volatile&&, true, false>
-{
- typedef _Class const volatile&& _ClassType;
- typedef _Rp _ReturnType;
- typedef _Rp (_FnType) (_Param..., ...);
-};
-
-#endif // __has_feature(cxx_reference_qualified_functions) || defined(_LIBCPP_COMPILER_GCC)
-
-
-template <class _Rp, class _Class>
-struct __member_pointer_traits_imp<_Rp _Class::*, false, true>
-{
- typedef _Class _ClassType;
- typedef _Rp _ReturnType;
-};
-
-template <class _MP>
-struct __member_pointer_traits
- : public __member_pointer_traits_imp<typename remove_cv<_MP>::type,
- is_member_function_pointer<_MP>::value,
- is_member_object_pointer<_MP>::value>
-{
-// typedef ... _ClassType;
-// typedef ... _ReturnType;
-// typedef ... _FnType;
-};
-
-
-template <class _DecayedFp>
-struct __member_pointer_class_type {};
-
-template <class _Ret, class _ClassType>
-struct __member_pointer_class_type<_Ret _ClassType::*> {
- typedef _ClassType type;
-};
-
-// template <class T, class... Args> struct is_constructible;
-
-template <class _Tp, class ..._Args>
-struct _LIBCPP_TEMPLATE_VIS is_constructible
- : public integral_constant<bool, __is_constructible(_Tp, _Args...)>
-{ };
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp, class ..._Args>
-inline constexpr bool is_constructible_v = is_constructible<_Tp, _Args...>::value;
-#endif
-
-// is_default_constructible
-
-template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_default_constructible
- : public is_constructible<_Tp>
- {};
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool is_default_constructible_v = is_default_constructible<_Tp>::value;
-#endif
+#endif // _LIBCPP_STD_VER > 17
#ifndef _LIBCPP_CXX03_LANG
// First of all, we can't implement this check in C++03 mode because the {}
@@ -3019,854 +1345,22 @@ struct __is_implicitly_default_constructible<_Tp, decltype(__test_implicit_defau
{ };
#endif // !C++03
-// is_copy_constructible
-
-template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_copy_constructible
- : public is_constructible<_Tp,
- typename add_lvalue_reference<typename add_const<_Tp>::type>::type> {};
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool is_copy_constructible_v = is_copy_constructible<_Tp>::value;
-#endif
-
-// is_move_constructible
-
-template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_move_constructible
- : public is_constructible<_Tp, typename add_rvalue_reference<_Tp>::type>
- {};
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool is_move_constructible_v = is_move_constructible<_Tp>::value;
-#endif
-
-// is_trivially_constructible
-
-template <class _Tp, class... _Args>
-struct _LIBCPP_TEMPLATE_VIS is_trivially_constructible
- : integral_constant<bool, __is_trivially_constructible(_Tp, _Args...)>
-{
-};
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp, class... _Args>
-inline constexpr bool is_trivially_constructible_v = is_trivially_constructible<_Tp, _Args...>::value;
-#endif
-
-// is_trivially_default_constructible
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_trivially_default_constructible
- : public is_trivially_constructible<_Tp>
- {};
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool is_trivially_default_constructible_v = is_trivially_default_constructible<_Tp>::value;
-#endif
-
-// is_trivially_copy_constructible
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_trivially_copy_constructible
- : public is_trivially_constructible<_Tp, typename add_lvalue_reference<const _Tp>::type>
- {};
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool is_trivially_copy_constructible_v = is_trivially_copy_constructible<_Tp>::value;
-#endif
-
-// is_trivially_move_constructible
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_trivially_move_constructible
- : public is_trivially_constructible<_Tp, typename add_rvalue_reference<_Tp>::type>
- {};
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool is_trivially_move_constructible_v = is_trivially_move_constructible<_Tp>::value;
-#endif
-
-// is_trivially_assignable
-
-template <class _Tp, class _Arg>
-struct is_trivially_assignable
- : integral_constant<bool, __is_trivially_assignable(_Tp, _Arg)>
-{ };
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp, class _Arg>
-inline constexpr bool is_trivially_assignable_v = is_trivially_assignable<_Tp, _Arg>::value;
-#endif
-
-// is_trivially_copy_assignable
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_trivially_copy_assignable
- : public is_trivially_assignable<typename add_lvalue_reference<_Tp>::type,
- typename add_lvalue_reference<typename add_const<_Tp>::type>::type> {};
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool is_trivially_copy_assignable_v = is_trivially_copy_assignable<_Tp>::value;
-#endif
-
-// is_trivially_move_assignable
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_trivially_move_assignable
- : public is_trivially_assignable<typename add_lvalue_reference<_Tp>::type,
- typename add_rvalue_reference<_Tp>::type>
- {};
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool is_trivially_move_assignable_v = is_trivially_move_assignable<_Tp>::value;
-#endif
-
-// is_trivially_destructible
-
-#if __has_keyword(__is_trivially_destructible)
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_trivially_destructible
- : public integral_constant<bool, __is_trivially_destructible(_Tp)> {};
-
-#elif __has_feature(has_trivial_destructor) || defined(_LIBCPP_COMPILER_GCC)
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_trivially_destructible
- : public integral_constant<bool, is_destructible<_Tp>::value && __has_trivial_destructor(_Tp)> {};
-
-#else
-
-template <class _Tp> struct __libcpp_trivial_destructor
- : public integral_constant<bool, is_scalar<_Tp>::value ||
- is_reference<_Tp>::value> {};
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_trivially_destructible
- : public __libcpp_trivial_destructor<typename remove_all_extents<_Tp>::type> {};
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_trivially_destructible<_Tp[]>
- : public false_type {};
-
-#endif
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool is_trivially_destructible_v = is_trivially_destructible<_Tp>::value;
-#endif
-
-// is_nothrow_constructible
-
-#if __has_keyword(__is_nothrow_constructible)
-
-template <class _Tp, class... _Args>
-struct _LIBCPP_TEMPLATE_VIS is_nothrow_constructible
- : public integral_constant<bool, __is_nothrow_constructible(_Tp, _Args...)> {};
-
-#else
-
-template <bool, bool, class _Tp, class... _Args> struct __libcpp_is_nothrow_constructible;
-
-template <class _Tp, class... _Args>
-struct __libcpp_is_nothrow_constructible</*is constructible*/true, /*is reference*/false, _Tp, _Args...>
- : public integral_constant<bool, noexcept(_Tp(declval<_Args>()...))>
-{
-};
-
-template <class _Tp>
-void __implicit_conversion_to(_Tp) noexcept { }
-
-template <class _Tp, class _Arg>
-struct __libcpp_is_nothrow_constructible</*is constructible*/true, /*is reference*/true, _Tp, _Arg>
- : public integral_constant<bool, noexcept(_VSTD::__implicit_conversion_to<_Tp>(declval<_Arg>()))>
-{
-};
-
-template <class _Tp, bool _IsReference, class... _Args>
-struct __libcpp_is_nothrow_constructible</*is constructible*/false, _IsReference, _Tp, _Args...>
- : public false_type
-{
-};
-
-template <class _Tp, class... _Args>
-struct _LIBCPP_TEMPLATE_VIS is_nothrow_constructible
- : __libcpp_is_nothrow_constructible<is_constructible<_Tp, _Args...>::value, is_reference<_Tp>::value, _Tp, _Args...>
-{
-};
-
-template <class _Tp, size_t _Ns>
-struct _LIBCPP_TEMPLATE_VIS is_nothrow_constructible<_Tp[_Ns]>
- : __libcpp_is_nothrow_constructible<is_constructible<_Tp>::value, is_reference<_Tp>::value, _Tp>
-{
-};
-
-#endif // _LIBCPP_HAS_NO_NOEXCEPT
-
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp, class ..._Args>
-inline constexpr bool is_nothrow_constructible_v = is_nothrow_constructible<_Tp, _Args...>::value;
-#endif
-
-// is_nothrow_default_constructible
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_nothrow_default_constructible
- : public is_nothrow_constructible<_Tp>
- {};
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool is_nothrow_default_constructible_v = is_nothrow_default_constructible<_Tp>::value;
-#endif
-
-// is_nothrow_copy_constructible
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_nothrow_copy_constructible
- : public is_nothrow_constructible<_Tp,
- typename add_lvalue_reference<typename add_const<_Tp>::type>::type> {};
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool is_nothrow_copy_constructible_v = is_nothrow_copy_constructible<_Tp>::value;
-#endif
-
-// is_nothrow_move_constructible
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_nothrow_move_constructible
- : public is_nothrow_constructible<_Tp, typename add_rvalue_reference<_Tp>::type>
- {};
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool is_nothrow_move_constructible_v = is_nothrow_move_constructible<_Tp>::value;
-#endif
-
-// is_nothrow_assignable
-
-#if __has_keyword(__is_nothrow_assignable)
-
-template <class _Tp, class _Arg>
-struct _LIBCPP_TEMPLATE_VIS is_nothrow_assignable
- : public integral_constant<bool, __is_nothrow_assignable(_Tp, _Arg)> {};
-
-#else
-
-template <bool, class _Tp, class _Arg> struct __libcpp_is_nothrow_assignable;
-
-template <class _Tp, class _Arg>
-struct __libcpp_is_nothrow_assignable<false, _Tp, _Arg>
- : public false_type
-{
-};
-
-template <class _Tp, class _Arg>
-struct __libcpp_is_nothrow_assignable<true, _Tp, _Arg>
- : public integral_constant<bool, noexcept(declval<_Tp>() = declval<_Arg>()) >
-{
-};
-
-template <class _Tp, class _Arg>
-struct _LIBCPP_TEMPLATE_VIS is_nothrow_assignable
- : public __libcpp_is_nothrow_assignable<is_assignable<_Tp, _Arg>::value, _Tp, _Arg>
-{
-};
-
-#endif // _LIBCPP_HAS_NO_NOEXCEPT
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp, class _Arg>
-inline constexpr bool is_nothrow_assignable_v = is_nothrow_assignable<_Tp, _Arg>::value;
-#endif
-
-// is_nothrow_copy_assignable
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_nothrow_copy_assignable
- : public is_nothrow_assignable<typename add_lvalue_reference<_Tp>::type,
- typename add_lvalue_reference<typename add_const<_Tp>::type>::type> {};
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool is_nothrow_copy_assignable_v = is_nothrow_copy_assignable<_Tp>::value;
-#endif
-
-// is_nothrow_move_assignable
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_nothrow_move_assignable
- : public is_nothrow_assignable<typename add_lvalue_reference<_Tp>::type,
- typename add_rvalue_reference<_Tp>::type>
- {};
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool is_nothrow_move_assignable_v = is_nothrow_move_assignable<_Tp>::value;
-#endif
-
-// is_nothrow_destructible
-
-#if !defined(_LIBCPP_CXX03_LANG)
-
-template <bool, class _Tp> struct __libcpp_is_nothrow_destructible;
-
-template <class _Tp>
-struct __libcpp_is_nothrow_destructible<false, _Tp>
- : public false_type
-{
-};
-
-template <class _Tp>
-struct __libcpp_is_nothrow_destructible<true, _Tp>
- : public integral_constant<bool, noexcept(declval<_Tp>().~_Tp()) >
-{
-};
-
-template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_nothrow_destructible
- : public __libcpp_is_nothrow_destructible<is_destructible<_Tp>::value, _Tp>
-{
-};
-
-template <class _Tp, size_t _Ns>
-struct _LIBCPP_TEMPLATE_VIS is_nothrow_destructible<_Tp[_Ns]>
- : public is_nothrow_destructible<_Tp>
-{
-};
-
-template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_nothrow_destructible<_Tp&>
- : public true_type
-{
-};
-
-template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_nothrow_destructible<_Tp&&>
- : public true_type
-{
-};
-
-#else
-
-template <class _Tp> struct __libcpp_nothrow_destructor
- : public integral_constant<bool, is_scalar<_Tp>::value ||
- is_reference<_Tp>::value> {};
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_nothrow_destructible
- : public __libcpp_nothrow_destructor<typename remove_all_extents<_Tp>::type> {};
-
-template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_nothrow_destructible<_Tp[]>
- : public false_type {};
-
-#endif
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool is_nothrow_destructible_v = is_nothrow_destructible<_Tp>::value;
-#endif
-
-// is_pod
-
-#if __has_feature(is_pod) || defined(_LIBCPP_COMPILER_GCC)
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_pod
- : public integral_constant<bool, __is_pod(_Tp)> {};
-
-#else
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_pod
- : public integral_constant<bool, is_trivially_default_constructible<_Tp>::value &&
- is_trivially_copy_constructible<_Tp>::value &&
- is_trivially_copy_assignable<_Tp>::value &&
- is_trivially_destructible<_Tp>::value> {};
-
-#endif
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool is_pod_v = is_pod<_Tp>::value;
-#endif
-
-// is_literal_type;
-
-#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS)
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 is_literal_type
- : public integral_constant<bool, __is_literal_type(_Tp)>
- {};
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-_LIBCPP_DEPRECATED_IN_CXX17 inline constexpr bool is_literal_type_v = is_literal_type<_Tp>::value;
-#endif // _LIBCPP_STD_VER > 14
-#endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS)
-
-// is_standard_layout;
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_standard_layout
-#if __has_feature(is_standard_layout) || defined(_LIBCPP_COMPILER_GCC)
- : public integral_constant<bool, __is_standard_layout(_Tp)>
-#else
- : integral_constant<bool, is_scalar<typename remove_all_extents<_Tp>::type>::value>
-#endif
- {};
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool is_standard_layout_v = is_standard_layout<_Tp>::value;
-#endif
-
-// is_trivially_copyable;
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_trivially_copyable
- : public integral_constant<bool, __is_trivially_copyable(_Tp)>
- {};
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool is_trivially_copyable_v = is_trivially_copyable<_Tp>::value;
-#endif
-
-// is_trivial;
-
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_trivial
-#if __has_feature(is_trivial) || defined(_LIBCPP_COMPILER_GCC)
- : public integral_constant<bool, __is_trivial(_Tp)>
-#else
- : integral_constant<bool, is_trivially_copyable<_Tp>::value &&
- is_trivially_default_constructible<_Tp>::value>
-#endif
- {};
-
-#if _LIBCPP_STD_VER > 14
-template <class _Tp>
-inline constexpr bool is_trivial_v = is_trivial<_Tp>::value;
-#endif
-
-template <class _Tp> struct __is_reference_wrapper_impl : public false_type {};
-template <class _Tp> struct __is_reference_wrapper_impl<reference_wrapper<_Tp> > : public true_type {};
-template <class _Tp> struct __is_reference_wrapper
- : public __is_reference_wrapper_impl<typename remove_cv<_Tp>::type> {};
-
-#ifndef _LIBCPP_CXX03_LANG
-
-template <class _Fp, class _A0,
- class _DecayFp = typename decay<_Fp>::type,
- class _DecayA0 = typename decay<_A0>::type,
- class _ClassT = typename __member_pointer_class_type<_DecayFp>::type>
-using __enable_if_bullet1 = typename enable_if
- <
- is_member_function_pointer<_DecayFp>::value
- && is_base_of<_ClassT, _DecayA0>::value
- >::type;
-
-template <class _Fp, class _A0,
- class _DecayFp = typename decay<_Fp>::type,
- class _DecayA0 = typename decay<_A0>::type>
-using __enable_if_bullet2 = typename enable_if
- <
- is_member_function_pointer<_DecayFp>::value
- && __is_reference_wrapper<_DecayA0>::value
- >::type;
-
-template <class _Fp, class _A0,
- class _DecayFp = typename decay<_Fp>::type,
- class _DecayA0 = typename decay<_A0>::type,
- class _ClassT = typename __member_pointer_class_type<_DecayFp>::type>
-using __enable_if_bullet3 = typename enable_if
- <
- is_member_function_pointer<_DecayFp>::value
- && !is_base_of<_ClassT, _DecayA0>::value
- && !__is_reference_wrapper<_DecayA0>::value
- >::type;
-
-template <class _Fp, class _A0,
- class _DecayFp = typename decay<_Fp>::type,
- class _DecayA0 = typename decay<_A0>::type,
- class _ClassT = typename __member_pointer_class_type<_DecayFp>::type>
-using __enable_if_bullet4 = typename enable_if
- <
- is_member_object_pointer<_DecayFp>::value
- && is_base_of<_ClassT, _DecayA0>::value
- >::type;
-
-template <class _Fp, class _A0,
- class _DecayFp = typename decay<_Fp>::type,
- class _DecayA0 = typename decay<_A0>::type>
-using __enable_if_bullet5 = typename enable_if
- <
- is_member_object_pointer<_DecayFp>::value
- && __is_reference_wrapper<_DecayA0>::value
- >::type;
-
-template <class _Fp, class _A0,
- class _DecayFp = typename decay<_Fp>::type,
- class _DecayA0 = typename decay<_A0>::type,
- class _ClassT = typename __member_pointer_class_type<_DecayFp>::type>
-using __enable_if_bullet6 = typename enable_if
- <
- is_member_object_pointer<_DecayFp>::value
- && !is_base_of<_ClassT, _DecayA0>::value
- && !__is_reference_wrapper<_DecayA0>::value
- >::type;
-
-// __invoke forward declarations
-
-// fall back - none of the bullets
-
-template <class ..._Args>
-auto __invoke(__any, _Args&& ...__args) -> __nat;
-
-template <class ..._Args>
-auto __invoke_constexpr(__any, _Args&& ...__args) -> __nat;
-
-// bullets 1, 2 and 3
-
-template <class _Fp, class _A0, class ..._Args,
- class = __enable_if_bullet1<_Fp, _A0>>
-inline _LIBCPP_INLINE_VISIBILITY
-_LIBCPP_CONSTEXPR_AFTER_CXX17 auto
-__invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args)
- noexcept(noexcept((static_cast<_A0&&>(__a0).*__f)(static_cast<_Args&&>(__args)...)))
- -> decltype( (static_cast<_A0&&>(__a0).*__f)(static_cast<_Args&&>(__args)...))
- { return (static_cast<_A0&&>(__a0).*__f)(static_cast<_Args&&>(__args)...); }
-
-template <class _Fp, class _A0, class ..._Args,
- class = __enable_if_bullet1<_Fp, _A0>>
-inline _LIBCPP_INLINE_VISIBILITY
-_LIBCPP_CONSTEXPR auto
-__invoke_constexpr(_Fp&& __f, _A0&& __a0, _Args&& ...__args)
- noexcept(noexcept((static_cast<_A0&&>(__a0).*__f)(static_cast<_Args&&>(__args)...)))
- -> decltype( (static_cast<_A0&&>(__a0).*__f)(static_cast<_Args&&>(__args)...))
- { return (static_cast<_A0&&>(__a0).*__f)(static_cast<_Args&&>(__args)...); }
-
-template <class _Fp, class _A0, class ..._Args,
- class = __enable_if_bullet2<_Fp, _A0>>
-inline _LIBCPP_INLINE_VISIBILITY
-_LIBCPP_CONSTEXPR_AFTER_CXX17 auto
-__invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args)
- noexcept(noexcept((__a0.get().*__f)(static_cast<_Args&&>(__args)...)))
- -> decltype( (__a0.get().*__f)(static_cast<_Args&&>(__args)...))
- { return (__a0.get().*__f)(static_cast<_Args&&>(__args)...); }
-
-template <class _Fp, class _A0, class ..._Args,
- class = __enable_if_bullet2<_Fp, _A0>>
-inline _LIBCPP_INLINE_VISIBILITY
-_LIBCPP_CONSTEXPR auto
-__invoke_constexpr(_Fp&& __f, _A0&& __a0, _Args&& ...__args)
- noexcept(noexcept((__a0.get().*__f)(static_cast<_Args&&>(__args)...)))
- -> decltype( (__a0.get().*__f)(static_cast<_Args&&>(__args)...))
- { return (__a0.get().*__f)(static_cast<_Args&&>(__args)...); }
-
-template <class _Fp, class _A0, class ..._Args,
- class = __enable_if_bullet3<_Fp, _A0>>
-inline _LIBCPP_INLINE_VISIBILITY
-_LIBCPP_CONSTEXPR_AFTER_CXX17 auto
-__invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args)
- noexcept(noexcept(((*static_cast<_A0&&>(__a0)).*__f)(static_cast<_Args&&>(__args)...)))
- -> decltype( ((*static_cast<_A0&&>(__a0)).*__f)(static_cast<_Args&&>(__args)...))
- { return ((*static_cast<_A0&&>(__a0)).*__f)(static_cast<_Args&&>(__args)...); }
-
-template <class _Fp, class _A0, class ..._Args,
- class = __enable_if_bullet3<_Fp, _A0>>
-inline _LIBCPP_INLINE_VISIBILITY
-_LIBCPP_CONSTEXPR auto
-__invoke_constexpr(_Fp&& __f, _A0&& __a0, _Args&& ...__args)
- noexcept(noexcept(((*static_cast<_A0&&>(__a0)).*__f)(static_cast<_Args&&>(__args)...)))
- -> decltype( ((*static_cast<_A0&&>(__a0)).*__f)(static_cast<_Args&&>(__args)...))
- { return ((*static_cast<_A0&&>(__a0)).*__f)(static_cast<_Args&&>(__args)...); }
-
-// bullets 4, 5 and 6
-
-template <class _Fp, class _A0,
- class = __enable_if_bullet4<_Fp, _A0>>
-inline _LIBCPP_INLINE_VISIBILITY
-_LIBCPP_CONSTEXPR_AFTER_CXX17 auto
-__invoke(_Fp&& __f, _A0&& __a0)
- noexcept(noexcept(static_cast<_A0&&>(__a0).*__f))
- -> decltype( static_cast<_A0&&>(__a0).*__f)
- { return static_cast<_A0&&>(__a0).*__f; }
-
-template <class _Fp, class _A0,
- class = __enable_if_bullet4<_Fp, _A0>>
-inline _LIBCPP_INLINE_VISIBILITY
-_LIBCPP_CONSTEXPR auto
-__invoke_constexpr(_Fp&& __f, _A0&& __a0)
- noexcept(noexcept(static_cast<_A0&&>(__a0).*__f))
- -> decltype( static_cast<_A0&&>(__a0).*__f)
- { return static_cast<_A0&&>(__a0).*__f; }
-
-template <class _Fp, class _A0,
- class = __enable_if_bullet5<_Fp, _A0>>
-inline _LIBCPP_INLINE_VISIBILITY
-_LIBCPP_CONSTEXPR_AFTER_CXX17 auto
-__invoke(_Fp&& __f, _A0&& __a0)
- noexcept(noexcept(__a0.get().*__f))
- -> decltype( __a0.get().*__f)
- { return __a0.get().*__f; }
-
-template <class _Fp, class _A0,
- class = __enable_if_bullet5<_Fp, _A0>>
-inline _LIBCPP_INLINE_VISIBILITY
-_LIBCPP_CONSTEXPR auto
-__invoke_constexpr(_Fp&& __f, _A0&& __a0)
- noexcept(noexcept(__a0.get().*__f))
- -> decltype( __a0.get().*__f)
- { return __a0.get().*__f; }
-
-template <class _Fp, class _A0,
- class = __enable_if_bullet6<_Fp, _A0>>
-inline _LIBCPP_INLINE_VISIBILITY
-_LIBCPP_CONSTEXPR_AFTER_CXX17 auto
-__invoke(_Fp&& __f, _A0&& __a0)
- noexcept(noexcept((*static_cast<_A0&&>(__a0)).*__f))
- -> decltype( (*static_cast<_A0&&>(__a0)).*__f)
- { return (*static_cast<_A0&&>(__a0)).*__f; }
-
-template <class _Fp, class _A0,
- class = __enable_if_bullet6<_Fp, _A0>>
-inline _LIBCPP_INLINE_VISIBILITY
-_LIBCPP_CONSTEXPR auto
-__invoke_constexpr(_Fp&& __f, _A0&& __a0)
- noexcept(noexcept((*static_cast<_A0&&>(__a0)).*__f))
- -> decltype( (*static_cast<_A0&&>(__a0)).*__f)
- { return (*static_cast<_A0&&>(__a0)).*__f; }
-
-// bullet 7
-
-template <class _Fp, class ..._Args>
-inline _LIBCPP_INLINE_VISIBILITY
-_LIBCPP_CONSTEXPR_AFTER_CXX17 auto
-__invoke(_Fp&& __f, _Args&& ...__args)
- noexcept(noexcept(static_cast<_Fp&&>(__f)(static_cast<_Args&&>(__args)...)))
- -> decltype( static_cast<_Fp&&>(__f)(static_cast<_Args&&>(__args)...))
- { return static_cast<_Fp&&>(__f)(static_cast<_Args&&>(__args)...); }
-
-template <class _Fp, class ..._Args>
-inline _LIBCPP_INLINE_VISIBILITY
-_LIBCPP_CONSTEXPR auto
-__invoke_constexpr(_Fp&& __f, _Args&& ...__args)
- noexcept(noexcept(static_cast<_Fp&&>(__f)(static_cast<_Args&&>(__args)...)))
- -> decltype( static_cast<_Fp&&>(__f)(static_cast<_Args&&>(__args)...))
- { return static_cast<_Fp&&>(__f)(static_cast<_Args&&>(__args)...); }
-
-// __invokable
-template <class _Ret, class _Fp, class ..._Args>
-struct __invokable_r
-{
- template <class _XFp, class ..._XArgs>
- static auto __try_call(int) -> decltype(
- _VSTD::__invoke(declval<_XFp>(), declval<_XArgs>()...));
- template <class _XFp, class ..._XArgs>
- static __nat __try_call(...);
-
- // FIXME: Check that _Ret, _Fp, and _Args... are all complete types, cv void,
- // or incomplete array types as required by the standard.
- using _Result = decltype(__try_call<_Fp, _Args...>(0));
-
- using type =
- typename conditional<
- _IsNotSame<_Result, __nat>::value,
- typename conditional<
- is_void<_Ret>::value,
- true_type,
- is_convertible<_Result, _Ret>
- >::type,
- false_type
- >::type;
- static const bool value = type::value;
-};
-template <class _Fp, class ..._Args>
-using __invokable = __invokable_r<void, _Fp, _Args...>;
-
-template <bool _IsInvokable, bool _IsCVVoid, class _Ret, class _Fp, class ..._Args>
-struct __nothrow_invokable_r_imp {
- static const bool value = false;
-};
-
-template <class _Ret, class _Fp, class ..._Args>
-struct __nothrow_invokable_r_imp<true, false, _Ret, _Fp, _Args...>
-{
- typedef __nothrow_invokable_r_imp _ThisT;
-
- template <class _Tp>
- static void __test_noexcept(_Tp) noexcept;
-
- static const bool value = noexcept(_ThisT::__test_noexcept<_Ret>(
- _VSTD::__invoke(declval<_Fp>(), declval<_Args>()...)));
-};
-
-template <class _Ret, class _Fp, class ..._Args>
-struct __nothrow_invokable_r_imp<true, true, _Ret, _Fp, _Args...>
-{
- static const bool value = noexcept(
- _VSTD::__invoke(declval<_Fp>(), declval<_Args>()...));
-};
-
-template <class _Ret, class _Fp, class ..._Args>
-using __nothrow_invokable_r =
- __nothrow_invokable_r_imp<
- __invokable_r<_Ret, _Fp, _Args...>::value,
- is_void<_Ret>::value,
- _Ret, _Fp, _Args...
- >;
-
-template <class _Fp, class ..._Args>
-using __nothrow_invokable =
- __nothrow_invokable_r_imp<
- __invokable<_Fp, _Args...>::value,
- true, void, _Fp, _Args...
- >;
-
-template <class _Fp, class ..._Args>
-struct __invoke_of
- : public enable_if<
- __invokable<_Fp, _Args...>::value,
- typename __invokable_r<void, _Fp, _Args...>::_Result>
-{
-};
-
-#endif // _LIBCPP_CXX03_LANG
-
// result_of
#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS)
template <class _Callable> class _LIBCPP_DEPRECATED_IN_CXX17 result_of;
-#ifndef _LIBCPP_CXX03_LANG
-
template <class _Fp, class ..._Args>
class _LIBCPP_TEMPLATE_VIS result_of<_Fp(_Args...)>
: public __invoke_of<_Fp, _Args...>
{
};
-#else // C++03
-
-template <class _Fn, bool, bool>
-class __result_of
-{
-};
-
-template <class _Fn, class ..._Args>
-class __result_of<_Fn(_Args...), true, false>
-{
-public:
- typedef decltype(declval<_Fn>()(declval<_Args>()...)) type;
-};
-
-template <class _MP, class _Tp, bool _IsMemberFunctionPtr>
-struct __result_of_mp;
-
-// member function pointer
-
-template <class _MP, class _Tp>
-struct __result_of_mp<_MP, _Tp, true>
-{
- using type = typename __member_pointer_traits<_MP>::_ReturnType;
-};
-
-// member data pointer
-
-template <class _MP, class _Tp, bool>
-struct __result_of_mdp;
-
-template <class _Rp, class _Class, class _Tp>
-struct __result_of_mdp<_Rp _Class::*, _Tp, false>
-{
- using type = typename __apply_cv<decltype(*declval<_Tp>()), _Rp>::type&;
-};
-
-template <class _Rp, class _Class, class _Tp>
-struct __result_of_mdp<_Rp _Class::*, _Tp, true>
-{
- using type = typename __apply_cv<_Tp, _Rp>::type&;
-};
-
-template <class _Rp, class _Class, class _Tp>
-struct __result_of_mp<_Rp _Class::*, _Tp, false>
- : public __result_of_mdp<_Rp _Class::*, _Tp,
- is_base_of<_Class, typename remove_reference<_Tp>::type>::value>
-{
-};
-
-template <class _Fn, class _Tp>
-class __result_of<_Fn(_Tp), false, true> // _Fn must be member pointer
- : public __result_of_mp<typename remove_reference<_Fn>::type,
- _Tp,
- is_member_function_pointer<typename remove_reference<_Fn>::type>::value>
-{
-};
-
-template <class _Fn, class _Tp, class ..._Args>
-class __result_of<_Fn(_Tp, _Args...), false, true> // _Fn must be member pointer
- : public __result_of_mp<typename remove_reference<_Fn>::type,
- _Tp,
- is_member_function_pointer<typename remove_reference<_Fn>::type>::value>
-{
-};
-
-template <class _Fn, class ..._Args>
-class _LIBCPP_TEMPLATE_VIS result_of<_Fn(_Args...)>
- : public __result_of<_Fn(_Args...),
- is_class<typename remove_reference<_Fn>::type>::value ||
- is_function<typename remove_pointer<typename remove_reference<_Fn>::type>::type>::value,
- is_member_pointer<typename remove_reference<_Fn>::type>::value
- >
-{
-};
-
-#endif // C++03
-
#if _LIBCPP_STD_VER > 11
template <class _Tp> using result_of_t _LIBCPP_DEPRECATED_IN_CXX17 = typename result_of<_Tp>::type;
#endif // _LIBCPP_STD_VER > 11
#endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS)
-#if _LIBCPP_STD_VER > 14
-
-// invoke_result
-
-template <class _Fn, class... _Args>
-struct _LIBCPP_TEMPLATE_VIS invoke_result
- : __invoke_of<_Fn, _Args...>
-{
-};
-
-template <class _Fn, class... _Args>
-using invoke_result_t = typename invoke_result<_Fn, _Args...>::type;
-
-// is_invocable
-
-template <class _Fn, class ..._Args>
-struct _LIBCPP_TEMPLATE_VIS is_invocable
- : integral_constant<bool, __invokable<_Fn, _Args...>::value> {};
-
-template <class _Ret, class _Fn, class ..._Args>
-struct _LIBCPP_TEMPLATE_VIS is_invocable_r
- : integral_constant<bool, __invokable_r<_Ret, _Fn, _Args...>::value> {};
-
-template <class _Fn, class ..._Args>
-inline constexpr bool is_invocable_v = is_invocable<_Fn, _Args...>::value;
-
-template <class _Ret, class _Fn, class ..._Args>
-inline constexpr bool is_invocable_r_v = is_invocable_r<_Ret, _Fn, _Args...>::value;
-
-// is_nothrow_invocable
-
-template <class _Fn, class ..._Args>
-struct _LIBCPP_TEMPLATE_VIS is_nothrow_invocable
- : integral_constant<bool, __nothrow_invokable<_Fn, _Args...>::value> {};
-
-template <class _Ret, class _Fn, class ..._Args>
-struct _LIBCPP_TEMPLATE_VIS is_nothrow_invocable_r
- : integral_constant<bool, __nothrow_invokable_r<_Ret, _Fn, _Args...>::value> {};
-
-template <class _Fn, class ..._Args>
-inline constexpr bool is_nothrow_invocable_v = is_nothrow_invocable<_Fn, _Args...>::value;
-
-template <class _Ret, class _Fn, class ..._Args>
-inline constexpr bool is_nothrow_invocable_r_v = is_nothrow_invocable_r<_Ret, _Fn, _Args...>::value;
-
-#endif // _LIBCPP_STD_VER > 14
-
// __swappable
template <class _Tp> struct __is_swappable;
@@ -3999,24 +1493,6 @@ inline constexpr bool is_nothrow_swappable_v = is_nothrow_swappable<_Tp>::value;
#endif // _LIBCPP_STD_VER > 14
-template <class _Tp, bool = is_enum<_Tp>::value> struct __underlying_type_impl;
-
-template <class _Tp>
-struct __underlying_type_impl<_Tp, false> {};
-
-template <class _Tp>
-struct __underlying_type_impl<_Tp, true>
-{
- typedef __underlying_type(_Tp) type;
-};
-
-template <class _Tp>
-struct underlying_type : __underlying_type_impl<_Tp, is_enum<_Tp>::value> {};
-
-#if _LIBCPP_STD_VER > 11
-template <class _Tp> using underlying_type_t = typename underlying_type<_Tp>::type;
-#endif
-
template <class _Tp, bool = is_enum<_Tp>::value>
struct __sfinae_underlying_type
{
@@ -4063,42 +1539,6 @@ inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
typename __sfinae_underlying_type<_Tp>::__promoted_type
__convert_to_integral(_Tp __val) { return __val; }
-// is_scoped_enum [meta.unary.prop]
-
-#if _LIBCPP_STD_VER > 20
-template <class _Tp, bool = is_enum_v<_Tp> >
-struct __is_scoped_enum_helper : false_type {};
-
-template <class _Tp>
-struct __is_scoped_enum_helper<_Tp, true>
- : public bool_constant<!is_convertible_v<_Tp, underlying_type_t<_Tp> > > {};
-
-template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_scoped_enum
- : public __is_scoped_enum_helper<_Tp> {};
-
-template <class _Tp>
-inline constexpr bool is_scoped_enum_v = is_scoped_enum<_Tp>::value;
-#endif
-
-#if _LIBCPP_STD_VER > 14
-
-template <class... _Args>
-struct conjunction : _And<_Args...> {};
-template<class... _Args>
-inline constexpr bool conjunction_v = conjunction<_Args...>::value;
-
-template <class... _Args>
-struct disjunction : _Or<_Args...> {};
-template<class... _Args>
-inline constexpr bool disjunction_v = disjunction<_Args...>::value;
-
-template <class _Tp>
-struct negation : _Not<_Tp> {};
-template<class _Tp>
-inline constexpr bool negation_v = negation<_Tp>::value;
-#endif // _LIBCPP_STD_VER > 14
-
// These traits are used in __tree and __hash_table
struct __extract_key_fail_tag {};
struct __extract_key_self_tag {};
@@ -4129,26 +1569,14 @@ template <class _ValTy, class _Key, class _RawValTy>
struct __can_extract_map_key<_ValTy, _Key, _Key, _RawValTy>
: false_type {};
-#if _LIBCPP_STD_VER > 17
-_LIBCPP_INLINE_VISIBILITY
-inline constexpr bool is_constant_evaluated() noexcept {
- return __builtin_is_constant_evaluated();
-}
-#endif
-
-inline _LIBCPP_CONSTEXPR
-bool __libcpp_is_constant_evaluated() _NOEXCEPT { return __builtin_is_constant_evaluated(); }
-
template <class _CharT>
using _IsCharLikeType = _And<is_standard_layout<_CharT>, is_trivial<_CharT> >;
template<class _Tp>
using __make_const_lvalue_ref = const typename remove_reference<_Tp>::type&;
-#if _LIBCPP_STD_VER > 17
template<bool _Const, class _Tp>
-using __maybe_const = conditional_t<_Const, const _Tp, _Tp>;
-#endif // _LIBCPP_STD_VER > 17
+using __maybe_const = typename conditional<_Const, const _Tp, _Tp>::type;
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/typeindex b/libcxx/include/typeindex
index ede0c7fb25c2..5fb7b30ecfee 100644
--- a/libcxx/include/typeindex
+++ b/libcxx/include/typeindex
@@ -44,15 +44,23 @@ struct hash<type_index>
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
#include <__functional/unary_function.h>
-#include <__functional_base>
-#include <compare>
#include <typeinfo>
#include <version>
+#ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES
+# include <iosfwd>
+# include <new>
+# include <utility>
+#endif
+
+// standard-mandated includes
+#include <compare>
+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -93,7 +101,7 @@ template <class _Tp> struct _LIBCPP_TEMPLATE_VIS hash;
template <>
struct _LIBCPP_TEMPLATE_VIS hash<type_index>
- : public unary_function<type_index, size_t>
+ : public __unary_function<type_index, size_t>
{
_LIBCPP_INLINE_VISIBILITY
size_t operator()(type_index __index) const _NOEXCEPT
diff --git a/libcxx/include/typeinfo b/libcxx/include/typeinfo
index af8217548770..a0ac527db782 100644
--- a/libcxx/include/typeinfo
+++ b/libcxx/include/typeinfo
@@ -56,6 +56,7 @@ public:
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__availability>
#include <__config>
#include <cstddef>
@@ -68,7 +69,7 @@ public:
#endif
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
#if defined(_LIBCPP_ABI_VCRUNTIME)
diff --git a/libcxx/include/uchar.h b/libcxx/include/uchar.h
new file mode 100644
index 000000000000..bb152c72cb3c
--- /dev/null
+++ b/libcxx/include/uchar.h
@@ -0,0 +1,52 @@
+// -*- 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_UCHAR_H
+#define _LIBCPP_UCHAR_H
+
+/*
+ uchar.h synopsis // since C++11
+
+Macros:
+
+ __STDC_UTF_16__
+ __STDC_UTF_32__
+
+Types:
+
+ mbstate_t
+ size_t
+
+size_t mbrtoc16(char16_t* pc16, const char* s, size_t n, mbstate_t* ps);
+size_t c16rtomb(char* s, char16_t c16, mbstate_t* ps);
+size_t mbrtoc32(char32_t* pc32, const char* s, size_t n, mbstate_t* ps);
+size_t c32rtomb(char* s, char32_t c32, mbstate_t* ps);
+
+*/
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if !defined(_LIBCPP_CXX03_LANG)
+
+// Some platforms don't implement <uchar.h> and we don't want to give a hard
+// error on those platforms. When the platform doesn't provide <uchar.h>, at
+// least include <stddef.h> so we get the declaration for size_t.
+#if __has_include_next(<uchar.h>)
+# include_next <uchar.h>
+#else
+# include <stddef.h>
+#endif
+
+#endif // _LIBCPP_CXX03_LANG
+
+#endif // _LIBCPP_UCHAR_H
diff --git a/libcxx/include/unordered_map b/libcxx/include/unordered_map
index 361db707d246..72749e11e843 100644
--- a/libcxx/include/unordered_map
+++ b/libcxx/include/unordered_map
@@ -514,23 +514,44 @@ template <class Key, class T, class Hash, class Pred, class Alloc>
*/
+#include <__algorithm/is_permutation.h>
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
#include <__debug>
#include <__functional/is_transparent.h>
+#include <__functional/operations.h>
#include <__hash_table>
+#include <__iterator/distance.h>
+#include <__iterator/erase_if_container.h>
#include <__iterator/iterator_traits.h>
#include <__memory/addressof.h>
#include <__node_handle>
#include <__utility/forward.h>
-#include <compare>
-#include <functional>
-#include <iterator> // __libcpp_erase_if_container
#include <stdexcept>
#include <tuple>
#include <version>
+#ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES
+# include <algorithm>
+# include <bit>
+# include <iterator>
+#endif
+
+// standard-mandated includes
+
+// [iterator.range]
+#include <__iterator/access.h>
+#include <__iterator/data.h>
+#include <__iterator/empty.h>
+#include <__iterator/reverse_access.h>
+#include <__iterator/size.h>
+
+// [unord.map.syn]
+#include <compare>
+#include <initializer_list>
+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -1012,9 +1033,9 @@ public:
// types
typedef _Key key_type;
typedef _Tp mapped_type;
- typedef __identity_t<_Hash> hasher;
- typedef __identity_t<_Pred> key_equal;
- typedef __identity_t<_Alloc> allocator_type;
+ typedef __type_identity_t<_Hash> hasher;
+ typedef __type_identity_t<_Pred> key_equal;
+ typedef __type_identity_t<_Alloc> allocator_type;
typedef pair<const key_type, mapped_type> value_type;
typedef value_type& reference;
typedef const value_type& const_reference;
@@ -1510,7 +1531,7 @@ public:
_LIBCPP_INLINE_VISIBILITY
void reserve(size_type __n) {__table_.reserve(__n);}
-#if _LIBCPP_DEBUG_LEVEL == 2
+#ifdef _LIBCPP_ENABLE_DEBUG_MODE
bool __dereferenceable(const const_iterator* __i) const
{return __table_.__dereferenceable(_VSTD::addressof(__i->__i_));}
@@ -1521,7 +1542,7 @@ public:
bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const
{return __table_.__addable(_VSTD::addressof(__i->__i_), __n);}
-#endif // _LIBCPP_DEBUG_LEVEL == 2
+#endif // _LIBCPP_ENABLE_DEBUG_MODE
private:
@@ -1692,9 +1713,7 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
: __table_(_VSTD::move(__u.__table_))
{
_VSTD::__debug_db_insert_c(this);
-#if _LIBCPP_DEBUG_LEVEL == 2
- __get_db()->swap(this, _VSTD::addressof(__u));
-#endif
+ std::__debug_db_swap(this, std::addressof(__u));
}
template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
@@ -1711,10 +1730,8 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
__u.__table_.remove((__i++).__i_)->__value_.__move());
}
}
-#if _LIBCPP_DEBUG_LEVEL == 2
else
- __get_db()->swap(this, _VSTD::addressof(__u));
-#endif
+ std::__debug_db_swap(this, std::addressof(__u));
}
template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
@@ -1906,9 +1923,9 @@ public:
// types
typedef _Key key_type;
typedef _Tp mapped_type;
- typedef __identity_t<_Hash> hasher;
- typedef __identity_t<_Pred> key_equal;
- typedef __identity_t<_Alloc> allocator_type;
+ typedef __type_identity_t<_Hash> hasher;
+ typedef __type_identity_t<_Pred> key_equal;
+ typedef __type_identity_t<_Alloc> allocator_type;
typedef pair<const key_type, mapped_type> value_type;
typedef value_type& reference;
typedef const value_type& const_reference;
@@ -2290,7 +2307,7 @@ public:
_LIBCPP_INLINE_VISIBILITY
void reserve(size_type __n) {__table_.reserve(__n);}
-#if _LIBCPP_DEBUG_LEVEL == 2
+#ifdef _LIBCPP_ENABLE_DEBUG_MODE
bool __dereferenceable(const const_iterator* __i) const
{return __table_.__dereferenceable(_VSTD::addressof(__i->__i_));}
@@ -2301,7 +2318,7 @@ public:
bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const
{return __table_.__addable(_VSTD::addressof(__i->__i_), __n);}
-#endif // _LIBCPP_DEBUG_LEVEL == 2
+#endif // _LIBCPP_ENABLE_DEBUG_MODE
};
@@ -2468,9 +2485,7 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
: __table_(_VSTD::move(__u.__table_))
{
_VSTD::__debug_db_insert_c(this);
-#if _LIBCPP_DEBUG_LEVEL == 2
- __get_db()->swap(this, _VSTD::addressof(__u));
-#endif
+ std::__debug_db_swap(this, std::addressof(__u));
}
template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
@@ -2488,10 +2503,8 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
__u.__table_.remove((__i++).__i_)->__value_.__move());
}
}
-#if _LIBCPP_DEBUG_LEVEL == 2
else
- __get_db()->swap(this, _VSTD::addressof(__u));
-#endif
+ std::__debug_db_swap(this, std::addressof(__u));
}
template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
diff --git a/libcxx/include/unordered_set b/libcxx/include/unordered_set
index 29a19f2f0cb5..97aa935f187c 100644
--- a/libcxx/include/unordered_set
+++ b/libcxx/include/unordered_set
@@ -459,20 +459,41 @@ template <class Value, class Hash, class Pred, class Alloc>
*/
+#include <__algorithm/is_permutation.h>
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
#include <__debug>
#include <__functional/is_transparent.h>
+#include <__functional/operations.h>
#include <__hash_table>
+#include <__iterator/distance.h>
+#include <__iterator/erase_if_container.h>
+#include <__iterator/iterator_traits.h>
#include <__memory/addressof.h>
#include <__node_handle>
#include <__utility/forward.h>
-#include <compare>
-#include <functional>
-#include <iterator> // __libcpp_erase_if_container
#include <version>
+#ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES
+# include <functional>
+# include <iterator>
+#endif
+
+// standard-mandated includes
+
+// [iterator.range]
+#include <__iterator/access.h>
+#include <__iterator/data.h>
+#include <__iterator/empty.h>
+#include <__iterator/reverse_access.h>
+#include <__iterator/size.h>
+
+// [unord.set.syn]
+#include <compare>
+#include <initializer_list>
+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -488,9 +509,9 @@ public:
// types
typedef _Value key_type;
typedef key_type value_type;
- typedef __identity_t<_Hash> hasher;
- typedef __identity_t<_Pred> key_equal;
- typedef __identity_t<_Alloc> allocator_type;
+ typedef __type_identity_t<_Hash> hasher;
+ typedef __type_identity_t<_Pred> key_equal;
+ typedef __type_identity_t<_Alloc> allocator_type;
typedef value_type& reference;
typedef const value_type& const_reference;
static_assert((is_same<value_type, typename allocator_type::value_type>::value),
@@ -637,36 +658,27 @@ public:
pair<iterator, bool> emplace(_Args&&... __args)
{return __table_.__emplace_unique(_VSTD::forward<_Args>(__args)...);}
template <class... _Args>
- _LIBCPP_INLINE_VISIBILITY
-#if _LIBCPP_DEBUG_LEVEL == 2
- iterator emplace_hint(const_iterator __p, _Args&&... __args)
- {
- _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this,
- "unordered_set::emplace_hint(const_iterator, args...) called with an iterator not"
- " referring to this unordered_set");
- return __table_.__emplace_unique(_VSTD::forward<_Args>(__args)...).first;
- }
-#else
- iterator emplace_hint(const_iterator, _Args&&... __args)
- {return __table_.__emplace_unique(_VSTD::forward<_Args>(__args)...).first;}
-#endif
+ _LIBCPP_INLINE_VISIBILITY
+ iterator emplace_hint(const_iterator __p, _Args&&... __args) {
+ _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(std::addressof(__p)) == this,
+ "unordered_set::emplace_hint(const_iterator, args...) called with an iterator not"
+ " referring to this unordered_set");
+ (void)__p;
+ return __table_.__emplace_unique(std::forward<_Args>(__args)...).first;
+ }
_LIBCPP_INLINE_VISIBILITY
pair<iterator, bool> insert(value_type&& __x)
{return __table_.__insert_unique(_VSTD::move(__x));}
_LIBCPP_INLINE_VISIBILITY
-#if _LIBCPP_DEBUG_LEVEL == 2
- iterator insert(const_iterator __p, value_type&& __x)
- {
- _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this,
- "unordered_set::insert(const_iterator, value_type&&) called with an iterator not"
- " referring to this unordered_set");
- return insert(_VSTD::move(__x)).first;
- }
-#else
- iterator insert(const_iterator, value_type&& __x)
- {return insert(_VSTD::move(__x)).first;}
-#endif
+ iterator insert(const_iterator __p, value_type&& __x) {
+ _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(std::addressof(__p)) == this,
+ "unordered_set::insert(const_iterator, value_type&&) called with an iterator not"
+ " referring to this unordered_set");
+ (void)__p;
+ return insert(std::move(__x)).first;
+ }
+
_LIBCPP_INLINE_VISIBILITY
void insert(initializer_list<value_type> __il)
{insert(__il.begin(), __il.end());}
@@ -676,18 +688,13 @@ public:
{return __table_.__insert_unique(__x);}
_LIBCPP_INLINE_VISIBILITY
-#if _LIBCPP_DEBUG_LEVEL == 2
- iterator insert(const_iterator __p, const value_type& __x)
- {
- _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this,
- "unordered_set::insert(const_iterator, const value_type&) called with an iterator not"
- " referring to this unordered_set");
- return insert(__x).first;
- }
-#else
- iterator insert(const_iterator, const value_type& __x)
- {return insert(__x).first;}
-#endif
+ iterator insert(const_iterator __p, const value_type& __x) {
+ _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(std::addressof(__p)) == this,
+ "unordered_set::insert(const_iterator, const value_type&) called with an iterator not"
+ " referring to this unordered_set");
+ (void)__p;
+ return insert(__x).first;
+ }
template <class _InputIterator>
_LIBCPP_INLINE_VISIBILITY
void insert(_InputIterator __first, _InputIterator __last);
@@ -855,7 +862,7 @@ public:
_LIBCPP_INLINE_VISIBILITY
void reserve(size_type __n) {__table_.reserve(__n);}
-#if _LIBCPP_DEBUG_LEVEL == 2
+#ifdef _LIBCPP_ENABLE_DEBUG_MODE
bool __dereferenceable(const const_iterator* __i) const
{return __table_.__dereferenceable(__i);}
@@ -866,7 +873,7 @@ public:
bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const
{return __table_.__addable(__i, __n);}
-#endif // _LIBCPP_DEBUG_LEVEL == 2
+#endif // _LIBCPP_ENABLE_DEBUG_MODE
};
@@ -1019,9 +1026,7 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
: __table_(_VSTD::move(__u.__table_))
{
_VSTD::__debug_db_insert_c(this);
-#if _LIBCPP_DEBUG_LEVEL == 2
- __get_db()->swap(this, _VSTD::addressof(__u));
-#endif
+ std::__debug_db_swap(this, std::addressof(__u));
}
template <class _Value, class _Hash, class _Pred, class _Alloc>
@@ -1036,10 +1041,8 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
while (__u.size() != 0)
__table_.__insert_unique(_VSTD::move(__u.__table_.remove(__i++)->__value_));
}
-#if _LIBCPP_DEBUG_LEVEL == 2
else
- __get_db()->swap(this, _VSTD::addressof(__u));
-#endif
+ std::__debug_db_swap(this, std::addressof(__u));
}
template <class _Value, class _Hash, class _Pred, class _Alloc>
@@ -1162,9 +1165,9 @@ public:
// types
typedef _Value key_type;
typedef key_type value_type;
- typedef __identity_t<_Hash> hasher;
- typedef __identity_t<_Pred> key_equal;
- typedef __identity_t<_Alloc> allocator_type;
+ typedef __type_identity_t<_Hash> hasher;
+ typedef __type_identity_t<_Pred> key_equal;
+ typedef __type_identity_t<_Alloc> allocator_type;
typedef value_type& reference;
typedef const value_type& const_reference;
static_assert((is_same<value_type, typename allocator_type::value_type>::value),
@@ -1497,7 +1500,7 @@ public:
_LIBCPP_INLINE_VISIBILITY
void reserve(size_type __n) {__table_.reserve(__n);}
-#if _LIBCPP_DEBUG_LEVEL == 2
+#ifdef _LIBCPP_ENABLE_DEBUG_MODE
bool __dereferenceable(const const_iterator* __i) const
{return __table_.__dereferenceable(__i);}
@@ -1508,7 +1511,7 @@ public:
bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const
{return __table_.__addable(__i, __n);}
-#endif // _LIBCPP_DEBUG_LEVEL == 2
+#endif // _LIBCPP_ENABLE_DEBUG_MODE
};
@@ -1660,9 +1663,7 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
: __table_(_VSTD::move(__u.__table_))
{
_VSTD::__debug_db_insert_c(this);
-#if _LIBCPP_DEBUG_LEVEL == 2
- __get_db()->swap(this, _VSTD::addressof(__u));
-#endif
+ std::__debug_db_swap(this, std::addressof(__u));
}
template <class _Value, class _Hash, class _Pred, class _Alloc>
@@ -1677,10 +1678,8 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
while (__u.size() != 0)
__table_.__insert_multi(_VSTD::move(__u.__table_.remove(__i++)->__value_));
}
-#if _LIBCPP_DEBUG_LEVEL == 2
else
- __get_db()->swap(this, _VSTD::addressof(__u));
-#endif
+ std::__debug_db_swap(this, std::addressof(__u));
}
template <class _Value, class _Hash, class _Pred, class _Alloc>
diff --git a/libcxx/include/utility b/libcxx/include/utility
index 9dd7905516a8..7a1a45e334a3 100644
--- a/libcxx/include/utility
+++ b/libcxx/include/utility
@@ -95,6 +95,12 @@ struct pair
is_nothrow_swappable_v<T2>); // constexpr in C++20
};
+template<class T1, class T2, class U1, class U2, template<class> class TQual, template<class> class UQual>
+struct basic_common_reference<pair<T1, T2>, pair<U1, U2>, TQual, UQual>; // since C++23
+
+template<class T1, class T2, class U1, class U2>
+struct common_type<pair<T1, T2>, pair<U1, U2>>; // since C++23
+
template<class T1, class T2> pair(T1, T2) -> pair<T1, T2>;
template <class T1, class T2> bool operator==(const pair<T1,T2>&, const pair<T1,T2>&); // constexpr in C++14
@@ -214,8 +220,8 @@ template <class T>
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
-#include <__debug>
#include <__tuple>
#include <__utility/as_const.h>
#include <__utility/auto_cast.h>
@@ -233,12 +239,20 @@ template <class T>
#include <__utility/swap.h>
#include <__utility/to_underlying.h>
#include <__utility/transaction.h>
+#include <__utility/unreachable.h>
+#include <type_traits>
+#include <version>
+
+#ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES
+# include <iosfwd>
+#endif
+
+// standard-mandated includes
#include <compare>
#include <initializer_list>
-#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
#endif // _LIBCPP_UTILITY
diff --git a/libcxx/include/valarray b/libcxx/include/valarray
index a55d921872ba..6f8a3b84197b 100644
--- a/libcxx/include/valarray
+++ b/libcxx/include/valarray
@@ -341,17 +341,35 @@ template <class T> unspecified2 end(const valarray<T>& v);
*/
+#include <__algorithm/copy.h>
+#include <__algorithm/count.h>
+#include <__algorithm/fill.h>
+#include <__algorithm/max_element.h>
+#include <__algorithm/min.h>
+#include <__algorithm/min_element.h>
+#include <__algorithm/unwrap_iter.h>
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
-#include <algorithm>
+#include <__functional/operations.h>
+#include <__memory/allocator.h>
+#include <__memory/uninitialized_algorithms.h>
+#include <__utility/move.h>
+#include <__utility/swap.h>
#include <cmath>
#include <cstddef>
-#include <functional>
-#include <initializer_list>
#include <new>
#include <version>
+#ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES
+# include <algorithm>
+# include <functional>
+#endif
+
+// standard-mandated includes
+#include <initializer_list>
+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
@@ -912,10 +930,14 @@ public:
#endif // _LIBCPP_CXX03_LANG
// unary operators:
- valarray operator+() const;
- valarray operator-() const;
- valarray operator~() const;
- valarray<bool> operator!() const;
+ _LIBCPP_INLINE_VISIBILITY
+ __val_expr<_UnaryOp<__unary_plus<_Tp>, const valarray&> > operator+() const;
+ _LIBCPP_INLINE_VISIBILITY
+ __val_expr<_UnaryOp<negate<_Tp>, const valarray&> > operator-() const;
+ _LIBCPP_INLINE_VISIBILITY
+ __val_expr<_UnaryOp<__bit_not<_Tp>, const valarray&> > operator~() const;
+ _LIBCPP_INLINE_VISIBILITY
+ __val_expr<_UnaryOp<logical_not<_Tp>, const valarray&> > operator!() const;
// computed assignment:
_LIBCPP_INLINE_VISIBILITY
@@ -1089,7 +1111,7 @@ template<class _Tp, size_t _Size>
valarray(const _Tp(&)[_Size], size_t) -> valarray<_Tp>;
#endif
-_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void valarray<size_t>::resize(size_t, size_t))
+extern template _LIBCPP_FUNC_VIS void valarray<size_t>::resize(size_t, size_t);
template <class _Op, class _Tp>
struct _UnaryOp<_Op, valarray<_Tp> >
@@ -1530,21 +1552,21 @@ public:
gslice(size_t __start, const valarray<size_t>& __size,
valarray<size_t>&& __stride)
: __size_(__size),
- __stride_(move(__stride))
+ __stride_(std::move(__stride))
{__init(__start);}
_LIBCPP_INLINE_VISIBILITY
gslice(size_t __start, valarray<size_t>&& __size,
const valarray<size_t>& __stride)
- : __size_(move(__size)),
+ : __size_(std::move(__size)),
__stride_(__stride)
{__init(__start);}
_LIBCPP_INLINE_VISIBILITY
gslice(size_t __start, valarray<size_t>&& __size,
valarray<size_t>&& __stride)
- : __size_(move(__size)),
- __stride_(move(__stride))
+ : __size_(std::move(__size)),
+ __stride_(std::move(__stride))
{__init(__start);}
#endif // _LIBCPP_CXX03_LANG
@@ -1695,7 +1717,7 @@ private:
#ifndef _LIBCPP_CXX03_LANG
gslice_array(gslice&& __gs, const valarray<value_type>& __v)
: __vp_(const_cast<value_type*>(__v.__begin_)),
- __1d_(move(__gs.__1d_))
+ __1d_(std::move(__gs.__1d_))
{}
#endif // _LIBCPP_CXX03_LANG
@@ -2389,7 +2411,7 @@ private:
_LIBCPP_INLINE_VISIBILITY
indirect_array(valarray<size_t>&& __ia, const valarray<value_type>& __v)
: __vp_(const_cast<value_type*>(__v.__begin_)),
- __1d_(move(__ia))
+ __1d_(std::move(__ia))
{}
#endif // _LIBCPP_CXX03_LANG
@@ -2608,7 +2630,7 @@ private:
_LIBCPP_INLINE_VISIBILITY
__indirect_expr(valarray<size_t>&& __ia, const _RmExpr& __e)
: __expr_(__e),
- __1d_(move(__ia))
+ __1d_(std::move(__ia))
{}
#endif // _LIBCPP_CXX03_LANG
@@ -3203,7 +3225,7 @@ inline
__val_expr<__indirect_expr<const valarray<_Tp>&> >
valarray<_Tp>::operator[](gslice&& __gs) const
{
- return __val_expr<__indirect_expr<const valarray&> >(__indirect_expr<const valarray&>(move(__gs.__1d_), *this));
+ return __val_expr<__indirect_expr<const valarray&> >(__indirect_expr<const valarray&>(std::move(__gs.__1d_), *this));
}
template <class _Tp>
@@ -3211,7 +3233,7 @@ inline
gslice_array<_Tp>
valarray<_Tp>::operator[](gslice&& __gs)
{
- return gslice_array<value_type>(move(__gs), *this);
+ return gslice_array<value_type>(std::move(__gs), *this);
}
#endif // _LIBCPP_CXX03_LANG
@@ -3239,7 +3261,7 @@ inline
__val_expr<__mask_expr<const valarray<_Tp>&> >
valarray<_Tp>::operator[](valarray<bool>&& __vb) const
{
- return __val_expr<__mask_expr<const valarray&> >(__mask_expr<const valarray&>(move(__vb), *this));
+ return __val_expr<__mask_expr<const valarray&> >(__mask_expr<const valarray&>(std::move(__vb), *this));
}
template <class _Tp>
@@ -3247,7 +3269,7 @@ inline
mask_array<_Tp>
valarray<_Tp>::operator[](valarray<bool>&& __vb)
{
- return mask_array<value_type>(move(__vb), *this);
+ return mask_array<value_type>(std::move(__vb), *this);
}
#endif // _LIBCPP_CXX03_LANG
@@ -3275,7 +3297,7 @@ inline
__val_expr<__indirect_expr<const valarray<_Tp>&> >
valarray<_Tp>::operator[](valarray<size_t>&& __vs) const
{
- return __val_expr<__indirect_expr<const valarray&> >(__indirect_expr<const valarray&>(move(__vs), *this));
+ return __val_expr<__indirect_expr<const valarray&> >(__indirect_expr<const valarray&>(std::move(__vs), *this));
}
template <class _Tp>
@@ -3283,69 +3305,45 @@ inline
indirect_array<_Tp>
valarray<_Tp>::operator[](valarray<size_t>&& __vs)
{
- return indirect_array<value_type>(move(__vs), *this);
+ return indirect_array<value_type>(std::move(__vs), *this);
}
#endif // _LIBCPP_CXX03_LANG
template <class _Tp>
-valarray<_Tp>
+inline
+__val_expr<_UnaryOp<__unary_plus<_Tp>, const valarray<_Tp>&> >
valarray<_Tp>::operator+() const
{
- valarray<value_type> __r;
- size_t __n = size();
- if (__n)
- {
- __r.__begin_ = __r.__end_ = allocator<value_type>().allocate(__n);
- for (const value_type* __p = __begin_; __n; ++__r.__end_, ++__p, --__n)
- ::new ((void*)__r.__end_) value_type(+*__p);
- }
- return __r;
+ using _Op = _UnaryOp<__unary_plus<_Tp>, const valarray<_Tp>&>;
+ return __val_expr<_Op>(_Op(__unary_plus<_Tp>(), *this));
}
template <class _Tp>
-valarray<_Tp>
+inline
+__val_expr<_UnaryOp<negate<_Tp>, const valarray<_Tp>&> >
valarray<_Tp>::operator-() const
{
- valarray<value_type> __r;
- size_t __n = size();
- if (__n)
- {
- __r.__begin_ = __r.__end_ = allocator<value_type>().allocate(__n);
- for (const value_type* __p = __begin_; __n; ++__r.__end_, ++__p, --__n)
- ::new ((void*)__r.__end_) value_type(-*__p);
- }
- return __r;
+ using _Op = _UnaryOp<negate<_Tp>, const valarray<_Tp>&>;
+ return __val_expr<_Op>(_Op(negate<_Tp>(), *this));
}
template <class _Tp>
-valarray<_Tp>
+inline
+__val_expr<_UnaryOp<__bit_not<_Tp>, const valarray<_Tp>&> >
valarray<_Tp>::operator~() const
{
- valarray<value_type> __r;
- size_t __n = size();
- if (__n)
- {
- __r.__begin_ = __r.__end_ = allocator<value_type>().allocate(__n);
- for (const value_type* __p = __begin_; __n; ++__r.__end_, ++__p, --__n)
- ::new ((void*)__r.__end_) value_type(~*__p);
- }
- return __r;
+ using _Op = _UnaryOp<__bit_not<_Tp>, const valarray<_Tp>&>;
+ return __val_expr<_Op>(_Op(__bit_not<_Tp>(), *this));
}
template <class _Tp>
-valarray<bool>
+inline
+__val_expr<_UnaryOp<logical_not<_Tp>, const valarray<_Tp>&> >
valarray<_Tp>::operator!() const
{
- valarray<bool> __r;
- size_t __n = size();
- if (__n)
- {
- __r.__begin_ = __r.__end_ = allocator<bool>().allocate(__n);
- for (const value_type* __p = __begin_; __n; ++__r.__end_, ++__p, --__n)
- ::new ((void*)__r.__end_) bool(!*__p);
- }
- return __r;
+ using _Op = _UnaryOp<logical_not<_Tp>, const valarray<_Tp>&>;
+ return __val_expr<_Op>(_Op(logical_not<_Tp>(), *this));
}
template <class _Tp>
diff --git a/libcxx/include/variant b/libcxx/include/variant
index 21fd53729d55..65dec64dbbbd 100644
--- a/libcxx/include/variant
+++ b/libcxx/include/variant
@@ -199,24 +199,36 @@ namespace std {
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__availability>
#include <__config>
#include <__functional/hash.h>
+#include <__functional/operations.h>
+#include <__functional/unary_function.h>
#include <__tuple>
#include <__utility/forward.h>
+#include <__utility/in_place.h>
+#include <__utility/move.h>
+#include <__utility/swap.h>
#include <__variant/monostate.h>
-#include <compare>
#include <exception>
#include <initializer_list>
#include <limits>
#include <new>
#include <tuple>
#include <type_traits>
-#include <utility>
#include <version>
+#ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES
+# include <typeinfo>
+# include <utility>
+#endif
+
+// standard-mandated includes
+#include <compare>
+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
@@ -533,7 +545,7 @@ private:
template <class _Fp, class... _Vs>
inline _LIBCPP_INLINE_VISIBILITY
static constexpr decltype(auto) __dispatch(_Fp __f, _Vs... __vs) {
- return _VSTD::__invoke_constexpr(
+ return _VSTD::__invoke(
static_cast<_Fp>(__f),
__access::__base::__get_alt<_Is>(static_cast<_Vs>(__vs))...);
}
@@ -549,7 +561,7 @@ private:
inline _LIBCPP_INLINE_VISIBILITY
static constexpr auto __make_fdiagonal_impl() {
return __make_dispatch<_Fp, _Vs...>(
- index_sequence<((void)__identity<_Vs>{}, _Ip)...>{});
+ index_sequence<((void)__type_identity<_Vs>{}, _Ip)...>{});
}
template <class _Fp, class... _Vs, size_t... _Is>
@@ -653,8 +665,8 @@ private:
__std_visit_exhaustive_visitor_check<
_Visitor,
decltype((_VSTD::forward<_Alts>(__alts).__value))...>();
- return _VSTD::__invoke_constexpr(_VSTD::forward<_Visitor>(__visitor),
- _VSTD::forward<_Alts>(__alts).__value...);
+ return _VSTD::__invoke(_VSTD::forward<_Visitor>(__visitor),
+ _VSTD::forward<_Alts>(__alts).__value...);
}
_Visitor&& __visitor;
};
@@ -669,12 +681,12 @@ private:
_Visitor,
decltype((_VSTD::forward<_Alts>(__alts).__value))...>();
if constexpr (is_void_v<_Rp>) {
- _VSTD::__invoke_constexpr(_VSTD::forward<_Visitor>(__visitor),
- _VSTD::forward<_Alts>(__alts).__value...);
+ _VSTD::__invoke(_VSTD::forward<_Visitor>(__visitor),
+ _VSTD::forward<_Alts>(__alts).__value...);
}
else {
- return _VSTD::__invoke_constexpr(_VSTD::forward<_Visitor>(__visitor),
- _VSTD::forward<_Alts>(__alts).__value...);
+ return _VSTD::__invoke(_VSTD::forward<_Visitor>(__visitor),
+ _VSTD::forward<_Alts>(__alts).__value...);
}
}
@@ -1121,8 +1133,11 @@ class _LIBCPP_TEMPLATE_VIS __impl
using __base_type = __copy_assignment<__traits<_Types...>>;
public:
- using __base_type::__base_type;
- using __base_type::operator=;
+ using __base_type::__base_type; // get in_place_index_t constructor & friends
+ __impl(__impl const&) = default;
+ __impl(__impl&&) = default;
+ __impl& operator=(__impl const&) = default;
+ __impl& operator=(__impl&&) = default;
template <size_t _Ip, class _Arg>
inline _LIBCPP_INLINE_VISIBILITY
@@ -1186,12 +1201,12 @@ private:
struct __no_narrowing_check {
template <class _Dest, class _Source>
- using _Apply = __identity<_Dest>;
+ using _Apply = __type_identity<_Dest>;
};
struct __narrowing_check {
template <class _Dest>
- static auto __test_impl(_Dest (&&)[1]) -> __identity<_Dest>;
+ static auto __test_impl(_Dest (&&)[1]) -> __type_identity<_Dest>;
template <class _Dest, class _Source>
using _Apply _LIBCPP_NODEBUG = decltype(__test_impl<_Dest>({declval<_Source>()}));
};
@@ -1217,7 +1232,7 @@ template <class _Tp, size_t>
struct __overload_bool {
template <class _Up, class _Ap = __uncvref_t<_Up>>
auto operator()(bool, _Up&&) const
- -> enable_if_t<is_same_v<_Ap, bool>, __identity<_Tp>>;
+ -> enable_if_t<is_same_v<_Ap, bool>, __type_identity<_Tp>>;
};
template <size_t _Idx>
diff --git a/libcxx/include/vector b/libcxx/include/vector
index fd0fb0db2756..f5c09011948d 100644
--- a/libcxx/include/vector
+++ b/libcxx/include/vector
@@ -271,20 +271,33 @@ erase_if(vector<T, Allocator>& c, Predicate pred); // C++20
*/
+#include <__algorithm/copy.h>
+#include <__algorithm/equal.h>
+#include <__algorithm/fill_n.h>
+#include <__algorithm/lexicographical_compare.h>
+#include <__algorithm/remove.h>
+#include <__algorithm/remove_if.h>
+#include <__algorithm/rotate.h>
+#include <__algorithm/unwrap_iter.h>
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__bit_reference>
#include <__config>
#include <__debug>
-#include <__functional_base>
+#include <__format/enable_insertable.h>
+#include <__functional/hash.h>
+#include <__functional/unary_function.h>
+#include <__iterator/advance.h>
#include <__iterator/iterator_traits.h>
+#include <__iterator/reverse_iterator.h>
#include <__iterator/wrap_iter.h>
+#include <__memory/allocate_at_least.h>
#include <__split_buffer>
#include <__utility/forward.h>
-#include <algorithm>
+#include <__utility/move.h>
+#include <__utility/swap.h>
#include <climits>
-#include <compare>
#include <cstdlib>
#include <cstring>
-#include <initializer_list>
#include <iosfwd> // for forward declaration of vector
#include <limits>
#include <memory>
@@ -292,65 +305,39 @@ erase_if(vector<T, Allocator>& c, Predicate pred); // C++20
#include <type_traits>
#include <version>
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+#ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES
+# include <algorithm>
+# include <typeinfo>
+# include <utility>
#endif
-_LIBCPP_PUSH_MACROS
-#include <__undef_macros>
-
+// standard-mandated includes
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-template <bool>
-struct __vector_base_common;
-
-template <>
-struct __vector_base_common<true> {
- // Both are defined in vector.cpp
- _LIBCPP_NORETURN _LIBCPP_EXPORTED_FROM_ABI void __throw_length_error() const;
- _LIBCPP_NORETURN _LIBCPP_EXPORTED_FROM_ABI void __throw_out_of_range() const;
-};
+// [iterator.range]
+#include <__iterator/access.h>
+#include <__iterator/data.h>
+#include <__iterator/empty.h>
+#include <__iterator/reverse_access.h>
+#include <__iterator/size.h>
-template <class _Tp, class _Allocator>
-class __vector_base
- : protected __vector_base_common<true> // This base class is historical, but it needs to remain for ABI compatibility
-{
- typedef _Allocator allocator_type;
- typedef typename allocator_traits<allocator_type>::pointer pointer;
+// [vector.syn]
+#include <compare>
+#include <initializer_list>
-protected:
- pointer __begin_;
- pointer __end_;
- __compressed_pair<pointer, allocator_type> __end_cap_;
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
- _LIBCPP_INLINE_VISIBILITY
- __vector_base()
- _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
- : __begin_(nullptr),
- __end_(nullptr),
- __end_cap_(nullptr, __default_init_tag()) {}
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
- _LIBCPP_INLINE_VISIBILITY __vector_base(const allocator_type& __a)
- : __begin_(nullptr),
- __end_(nullptr),
- __end_cap_(nullptr, __a) {}
-#ifndef _LIBCPP_CXX03_LANG
- _LIBCPP_INLINE_VISIBILITY __vector_base(allocator_type&& __a) _NOEXCEPT
- : __begin_(nullptr),
- __end_(nullptr),
- __end_cap_(nullptr, _VSTD::move(__a)) {}
-#endif
-};
+_LIBCPP_BEGIN_NAMESPACE_STD
template <class _Tp, class _Allocator /* = allocator<_Tp> */>
class _LIBCPP_TEMPLATE_VIS vector
- // This base class is historical, but it needs to remain for ABI compatibility.
- : private __vector_base<_Tp, _Allocator>
{
private:
- typedef __vector_base<_Tp, _Allocator> __base;
typedef allocator<_Tp> __default_allocator_type;
public:
typedef vector __self;
@@ -382,7 +369,7 @@ public:
#else
_NOEXCEPT
#endif
- : __base(__a)
+ : __end_cap_(nullptr, __a)
{
_VSTD::__debug_db_insert_c(this);
}
@@ -394,7 +381,7 @@ public:
template <class = __enable_if_t<__is_allocator<_Allocator>::value> >
vector(size_type __n, const value_type& __x, const allocator_type& __a)
- : __base(__a)
+ : __end_cap_(nullptr, __a)
{
_VSTD::__debug_db_insert_c(this);
if (__n > 0)
@@ -437,9 +424,7 @@ public:
~vector()
{
__annotate_delete();
-#if _LIBCPP_DEBUG_LEVEL == 2
- __get_db()->__erase_c(this);
-#endif
+ std::__debug_db_erase_c(this);
if (this->__begin_ != nullptr)
{
@@ -449,7 +434,7 @@ public:
}
vector(const vector& __x);
- vector(const vector& __x, const __identity_t<allocator_type>& __a);
+ vector(const vector& __x, const __type_identity_t<allocator_type>& __a);
_LIBCPP_INLINE_VISIBILITY
vector& operator=(const vector& __x);
@@ -461,25 +446,24 @@ public:
vector(initializer_list<value_type> __il, const allocator_type& __a);
_LIBCPP_INLINE_VISIBILITY
+ vector& operator=(initializer_list<value_type> __il)
+ {assign(__il.begin(), __il.end()); return *this;}
+#endif // !_LIBCPP_CXX03_LANG
+
+ _LIBCPP_INLINE_VISIBILITY
vector(vector&& __x)
#if _LIBCPP_STD_VER > 14
- _NOEXCEPT;
+ noexcept;
#else
_NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value);
#endif
_LIBCPP_INLINE_VISIBILITY
- vector(vector&& __x, const __identity_t<allocator_type>& __a);
+ vector(vector&& __x, const __type_identity_t<allocator_type>& __a);
_LIBCPP_INLINE_VISIBILITY
vector& operator=(vector&& __x)
_NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value));
- _LIBCPP_INLINE_VISIBILITY
- vector& operator=(initializer_list<value_type> __il)
- {assign(__il.begin(), __il.end()); return *this;}
-
-#endif // !_LIBCPP_CXX03_LANG
-
template <class _InputIterator>
typename enable_if
<
@@ -591,41 +575,26 @@ public:
const value_type* data() const _NOEXCEPT
{return _VSTD::__to_address(this->__begin_);}
-#ifdef _LIBCPP_CXX03_LANG
- _LIBCPP_INLINE_VISIBILITY
- void __emplace_back(const value_type& __x) { push_back(__x); }
-#else
- template <class _Arg>
- _LIBCPP_INLINE_VISIBILITY
- void __emplace_back(_Arg&& __arg) {
- emplace_back(_VSTD::forward<_Arg>(__arg));
- }
-#endif
-
_LIBCPP_INLINE_VISIBILITY void push_back(const_reference __x);
-#ifndef _LIBCPP_CXX03_LANG
_LIBCPP_INLINE_VISIBILITY void push_back(value_type&& __x);
template <class... _Args>
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_INLINE_VISIBILITY
#if _LIBCPP_STD_VER > 14
reference emplace_back(_Args&&... __args);
#else
void emplace_back(_Args&&... __args);
#endif
-#endif // !_LIBCPP_CXX03_LANG
_LIBCPP_INLINE_VISIBILITY
void pop_back();
iterator insert(const_iterator __position, const_reference __x);
-#ifndef _LIBCPP_CXX03_LANG
iterator insert(const_iterator __position, value_type&& __x);
template <class... _Args>
- iterator emplace(const_iterator __position, _Args&&... __args);
-#endif // !_LIBCPP_CXX03_LANG
+ iterator emplace(const_iterator __position, _Args&&... __args);
iterator insert(const_iterator __position, size_type __n, const_reference __x);
template <class _InputIterator>
@@ -665,7 +634,7 @@ public:
size_type __old_size = size();
__clear();
__annotate_shrink(__old_size);
- __invalidate_all_iterators();
+ std::__debug_db_invalidate_all(this);
}
void resize(size_type __sz);
@@ -681,19 +650,41 @@ public:
bool __invariants() const;
-#if _LIBCPP_DEBUG_LEVEL == 2
+#ifdef _LIBCPP_ENABLE_DEBUG_MODE
bool __dereferenceable(const const_iterator* __i) const;
bool __decrementable(const const_iterator* __i) const;
bool __addable(const const_iterator* __i, ptrdiff_t __n) const;
bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const;
-#endif // _LIBCPP_DEBUG_LEVEL == 2
+#endif // _LIBCPP_ENABLE_DEBUG_MODE
private:
- _LIBCPP_INLINE_VISIBILITY void __invalidate_all_iterators();
+ pointer __begin_ = nullptr;
+ pointer __end_ = nullptr;
+ __compressed_pair<pointer, allocator_type> __end_cap_ =
+ __compressed_pair<pointer, allocator_type>(nullptr, __default_init_tag());
+
_LIBCPP_INLINE_VISIBILITY void __invalidate_iterators_past(pointer __new_last);
- void __vallocate(size_type __n);
+
+
+ // Allocate space for __n objects
+ // throws length_error if __n > max_size()
+ // throws (probably bad_alloc) if memory run out
+ // Precondition: __begin_ == __end_ == __end_cap() == 0
+ // Precondition: __n > 0
+ // Postcondition: capacity() >= __n
+ // Postcondition: size() == 0
+ _LIBCPP_HIDE_FROM_ABI void __vallocate(size_type __n) {
+ if (__n > max_size())
+ __throw_length_error();
+ auto __allocation = std::__allocate_at_least(__alloc(), __n);
+ __begin_ = __allocation.ptr;
+ __end_ = __allocation.ptr;
+ __end_cap() = __begin_ + __allocation.count;
+ __annotate_new(0);
+ }
+
void __vdeallocate() _NOEXCEPT;
_LIBCPP_INLINE_VISIBILITY size_type __recommend(size_type __new_size) const;
void __construct_at_end(size_type __n);
@@ -728,7 +719,6 @@ private:
__annotate_shrink(__old_size);
}
-#ifndef _LIBCPP_CXX03_LANG
template <class _Up>
_LIBCPP_INLINE_VISIBILITY
inline void __push_back_slow_path(_Up&& __x);
@@ -736,11 +726,6 @@ private:
template <class... _Args>
_LIBCPP_INLINE_VISIBILITY
inline void __emplace_back_slow_path(_Args&&... __args);
-#else
- template <class _Up>
- _LIBCPP_INLINE_VISIBILITY
- inline void __push_back_slow_path(_Up& __x);
-#endif
// The following functions are no-ops outside of AddressSanitizer mode.
// We call annotatations only for the default Allocator because other allocators
@@ -859,20 +844,12 @@ private:
_LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI
void __throw_length_error() const {
-#ifndef _LIBCPP_NO_EXCEPTIONS
- __vector_base_common<true>::__throw_length_error();
-#else
- _VSTD::abort();
-#endif
+ _VSTD::__throw_length_error("vector");
}
_LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI
void __throw_out_of_range() const {
-#ifndef _LIBCPP_NO_EXCEPTIONS
- __vector_base_common<true>::__throw_out_of_range();
-#else
- _VSTD::abort();
-#endif
+ _VSTD::__throw_out_of_range("vector");
}
_LIBCPP_INLINE_VISIBILITY
@@ -934,7 +911,7 @@ vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer<value_type, a
_VSTD::swap(this->__end_cap(), __v.__end_cap());
__v.__first_ = __v.__begin_;
__annotate_new(size());
- __invalidate_all_iterators();
+ std::__debug_db_invalidate_all(this);
}
template <class _Tp, class _Allocator>
@@ -950,28 +927,10 @@ vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer<value_type, a
_VSTD::swap(this->__end_cap(), __v.__end_cap());
__v.__first_ = __v.__begin_;
__annotate_new(size());
- __invalidate_all_iterators();
+ std::__debug_db_invalidate_all(this);
return __r;
}
-// Allocate space for __n objects
-// throws length_error if __n > max_size()
-// throws (probably bad_alloc) if memory run out
-// Precondition: __begin_ == __end_ == __end_cap() == 0
-// Precondition: __n > 0
-// Postcondition: capacity() == __n
-// Postcondition: size() == 0
-template <class _Tp, class _Allocator>
-void
-vector<_Tp, _Allocator>::__vallocate(size_type __n)
-{
- if (__n > max_size())
- this->__throw_length_error();
- this->__begin_ = this->__end_ = __alloc_traits::allocate(this->__alloc(), __n);
- this->__end_cap() = this->__begin_ + __n;
- __annotate_new(0);
-}
-
template <class _Tp, class _Allocator>
void
vector<_Tp, _Allocator>::__vdeallocate() _NOEXCEPT
@@ -1106,7 +1065,7 @@ vector<_Tp, _Allocator>::vector(size_type __n)
#if _LIBCPP_STD_VER > 11
template <class _Tp, class _Allocator>
vector<_Tp, _Allocator>::vector(size_type __n, const allocator_type& __a)
- : __base(__a)
+ : __end_cap_(nullptr, __a)
{
_VSTD::__debug_db_insert_c(this);
if (__n > 0)
@@ -1140,7 +1099,7 @@ vector<_Tp, _Allocator>::vector(_InputIterator __first,
{
_VSTD::__debug_db_insert_c(this);
for (; __first != __last; ++__first)
- __emplace_back(*__first);
+ emplace_back(*__first);
}
template <class _Tp, class _Allocator>
@@ -1151,11 +1110,11 @@ vector<_Tp, _Allocator>::vector(_InputIterator __first, _InputIterator __last, c
is_constructible<
value_type,
typename iterator_traits<_InputIterator>::reference>::value>::type*)
- : __base(__a)
+ : __end_cap_(nullptr, __a)
{
_VSTD::__debug_db_insert_c(this);
for (; __first != __last; ++__first)
- __emplace_back(*__first);
+ emplace_back(*__first);
}
template <class _Tp, class _Allocator>
@@ -1183,7 +1142,7 @@ vector<_Tp, _Allocator>::vector(_ForwardIterator __first, _ForwardIterator __las
is_constructible<
value_type,
typename iterator_traits<_ForwardIterator>::reference>::value>::type*)
- : __base(__a)
+ : __end_cap_(nullptr, __a)
{
_VSTD::__debug_db_insert_c(this);
size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last));
@@ -1196,7 +1155,7 @@ vector<_Tp, _Allocator>::vector(_ForwardIterator __first, _ForwardIterator __las
template <class _Tp, class _Allocator>
vector<_Tp, _Allocator>::vector(const vector& __x)
- : __base(__alloc_traits::select_on_container_copy_construction(__x.__alloc()))
+ : __end_cap_(nullptr, __alloc_traits::select_on_container_copy_construction(__x.__alloc()))
{
_VSTD::__debug_db_insert_c(this);
size_type __n = __x.size();
@@ -1208,8 +1167,8 @@ vector<_Tp, _Allocator>::vector(const vector& __x)
}
template <class _Tp, class _Allocator>
-vector<_Tp, _Allocator>::vector(const vector& __x, const __identity_t<allocator_type>& __a)
- : __base(__a)
+vector<_Tp, _Allocator>::vector(const vector& __x, const __type_identity_t<allocator_type>& __a)
+ : __end_cap_(nullptr, __a)
{
_VSTD::__debug_db_insert_c(this);
size_type __n = __x.size();
@@ -1220,22 +1179,18 @@ vector<_Tp, _Allocator>::vector(const vector& __x, const __identity_t<allocator_
}
}
-#ifndef _LIBCPP_CXX03_LANG
-
template <class _Tp, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
vector<_Tp, _Allocator>::vector(vector&& __x)
#if _LIBCPP_STD_VER > 14
- _NOEXCEPT
+ noexcept
#else
_NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
#endif
- : __base(_VSTD::move(__x.__alloc()))
+ : __end_cap_(nullptr, _VSTD::move(__x.__alloc()))
{
_VSTD::__debug_db_insert_c(this);
-#if _LIBCPP_DEBUG_LEVEL == 2
- __get_db()->swap(this, _VSTD::addressof(__x));
-#endif
+ std::__debug_db_swap(this, std::addressof(__x));
this->__begin_ = __x.__begin_;
this->__end_ = __x.__end_;
this->__end_cap() = __x.__end_cap();
@@ -1244,8 +1199,8 @@ vector<_Tp, _Allocator>::vector(vector&& __x)
template <class _Tp, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
-vector<_Tp, _Allocator>::vector(vector&& __x, const __identity_t<allocator_type>& __a)
- : __base(__a)
+vector<_Tp, _Allocator>::vector(vector&& __x, const __type_identity_t<allocator_type>& __a)
+ : __end_cap_(nullptr, __a)
{
_VSTD::__debug_db_insert_c(this);
if (__a == __x.__alloc())
@@ -1254,9 +1209,7 @@ vector<_Tp, _Allocator>::vector(vector&& __x, const __identity_t<allocator_type>
this->__end_ = __x.__end_;
this->__end_cap() = __x.__end_cap();
__x.__begin_ = __x.__end_ = __x.__end_cap() = nullptr;
-#if _LIBCPP_DEBUG_LEVEL == 2
- __get_db()->swap(this, _VSTD::addressof(__x));
-#endif
+ std::__debug_db_swap(this, std::addressof(__x));
}
else
{
@@ -1265,6 +1218,8 @@ vector<_Tp, _Allocator>::vector(vector&& __x, const __identity_t<allocator_type>
}
}
+#ifndef _LIBCPP_CXX03_LANG
+
template <class _Tp, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
vector<_Tp, _Allocator>::vector(initializer_list<value_type> __il)
@@ -1280,7 +1235,7 @@ vector<_Tp, _Allocator>::vector(initializer_list<value_type> __il)
template <class _Tp, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
vector<_Tp, _Allocator>::vector(initializer_list<value_type> __il, const allocator_type& __a)
- : __base(__a)
+ : __end_cap_(nullptr, __a)
{
_VSTD::__debug_db_insert_c(this);
if (__il.size() > 0)
@@ -1290,6 +1245,8 @@ vector<_Tp, _Allocator>::vector(initializer_list<value_type> __il, const allocat
}
}
+#endif // _LIBCPP_CXX03_LANG
+
template <class _Tp, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
vector<_Tp, _Allocator>&
@@ -1326,13 +1283,9 @@ vector<_Tp, _Allocator>::__move_assign(vector& __c, true_type)
this->__end_ = __c.__end_;
this->__end_cap() = __c.__end_cap();
__c.__begin_ = __c.__end_ = __c.__end_cap() = nullptr;
-#if _LIBCPP_DEBUG_LEVEL == 2
- __get_db()->swap(this, _VSTD::addressof(__c));
-#endif
+ std::__debug_db_swap(this, std::addressof(__c));
}
-#endif // !_LIBCPP_CXX03_LANG
-
template <class _Tp, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
vector<_Tp, _Allocator>&
@@ -1361,7 +1314,7 @@ vector<_Tp, _Allocator>::assign(_InputIterator __first, _InputIterator __last)
{
clear();
for (; __first != __last; ++__first)
- __emplace_back(*__first);
+ emplace_back(*__first);
}
template <class _Tp, class _Allocator>
@@ -1399,7 +1352,7 @@ vector<_Tp, _Allocator>::assign(_ForwardIterator __first, _ForwardIterator __las
__vallocate(__recommend(__new_size));
__construct_at_end(__first, __last, __new_size);
}
- __invalidate_all_iterators();
+ std::__debug_db_invalidate_all(this);
}
template <class _Tp, class _Allocator>
@@ -1421,31 +1374,7 @@ vector<_Tp, _Allocator>::assign(size_type __n, const_reference __u)
__vallocate(__recommend(static_cast<size_type>(__n)));
__construct_at_end(__n, __u);
}
- __invalidate_all_iterators();
-}
-
-template <class _Tp, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
-typename vector<_Tp, _Allocator>::iterator
-vector<_Tp, _Allocator>::__make_iter(pointer __p) _NOEXCEPT
-{
-#if _LIBCPP_DEBUG_LEVEL == 2
- return iterator(this, __p);
-#else
- return iterator(__p);
-#endif
-}
-
-template <class _Tp, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
-typename vector<_Tp, _Allocator>::const_iterator
-vector<_Tp, _Allocator>::__make_iter(const_pointer __p) const _NOEXCEPT
-{
-#if _LIBCPP_DEBUG_LEVEL == 2
- return const_iterator(this, __p);
-#else
- return const_iterator(__p);
-#endif
+ std::__debug_db_invalidate_all(this);
}
template <class _Tp, class _Allocator>
@@ -1453,7 +1382,7 @@ inline _LIBCPP_INLINE_VISIBILITY
typename vector<_Tp, _Allocator>::iterator
vector<_Tp, _Allocator>::begin() _NOEXCEPT
{
- return __make_iter(this->__begin_);
+ return iterator(this, this->__begin_);
}
template <class _Tp, class _Allocator>
@@ -1461,7 +1390,7 @@ inline _LIBCPP_INLINE_VISIBILITY
typename vector<_Tp, _Allocator>::const_iterator
vector<_Tp, _Allocator>::begin() const _NOEXCEPT
{
- return __make_iter(this->__begin_);
+ return const_iterator(this, this->__begin_);
}
template <class _Tp, class _Allocator>
@@ -1469,7 +1398,7 @@ inline _LIBCPP_INLINE_VISIBILITY
typename vector<_Tp, _Allocator>::iterator
vector<_Tp, _Allocator>::end() _NOEXCEPT
{
- return __make_iter(this->__end_);
+ return iterator(this, this->__end_);
}
template <class _Tp, class _Allocator>
@@ -1477,7 +1406,7 @@ inline _LIBCPP_INLINE_VISIBILITY
typename vector<_Tp, _Allocator>::const_iterator
vector<_Tp, _Allocator>::end() const _NOEXCEPT
{
- return __make_iter(this->__end_);
+ return const_iterator(this, this->__end_);
}
template <class _Tp, class _Allocator>
@@ -1555,11 +1484,7 @@ vector<_Tp, _Allocator>::shrink_to_fit() _NOEXCEPT
template <class _Tp, class _Allocator>
template <class _Up>
void
-#ifndef _LIBCPP_CXX03_LANG
vector<_Tp, _Allocator>::__push_back_slow_path(_Up&& __x)
-#else
-vector<_Tp, _Allocator>::__push_back_slow_path(_Up& __x)
-#endif
{
allocator_type& __a = this->__alloc();
__split_buffer<value_type, allocator_type&> __v(__recommend(size() + 1), size(), __a);
@@ -1582,8 +1507,6 @@ vector<_Tp, _Allocator>::push_back(const_reference __x)
__push_back_slow_path(__x);
}
-#ifndef _LIBCPP_CXX03_LANG
-
template <class _Tp, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
void
@@ -1631,8 +1554,6 @@ vector<_Tp, _Allocator>::emplace_back(_Args&&... __args)
#endif
}
-#endif // !_LIBCPP_CXX03_LANG
-
template <class _Tp, class _Allocator>
inline
void
@@ -1655,7 +1576,7 @@ vector<_Tp, _Allocator>::erase(const_iterator __position)
pointer __p = this->__begin_ + __ps;
this->__destruct_at_end(_VSTD::move(__p + 1, this->__end_, __p));
this->__invalidate_iterators_past(__p-1);
- iterator __r = __make_iter(__p);
+ iterator __r = iterator(this, __p);
return __r;
}
@@ -1674,7 +1595,7 @@ vector<_Tp, _Allocator>::erase(const_iterator __first, const_iterator __last)
this->__destruct_at_end(_VSTD::move(__p + (__last - __first), this->__end_, __p));
this->__invalidate_iterators_past(__p - 1);
}
- iterator __r = __make_iter(__p);
+ iterator __r = iterator(this, __p);
return __r;
}
@@ -1726,11 +1647,9 @@ vector<_Tp, _Allocator>::insert(const_iterator __position, const_reference __x)
__v.push_back(__x);
__p = __swap_out_circular_buffer(__v, __p);
}
- return __make_iter(__p);
+ return iterator(this, __p);
}
-#ifndef _LIBCPP_CXX03_LANG
-
template <class _Tp, class _Allocator>
typename vector<_Tp, _Allocator>::iterator
vector<_Tp, _Allocator>::insert(const_iterator __position, value_type&& __x)
@@ -1757,7 +1676,7 @@ vector<_Tp, _Allocator>::insert(const_iterator __position, value_type&& __x)
__v.push_back(_VSTD::move(__x));
__p = __swap_out_circular_buffer(__v, __p);
}
- return __make_iter(__p);
+ return iterator(this, __p);
}
template <class _Tp, class _Allocator>
@@ -1788,11 +1707,9 @@ vector<_Tp, _Allocator>::emplace(const_iterator __position, _Args&&... __args)
__v.emplace_back(_VSTD::forward<_Args>(__args)...);
__p = __swap_out_circular_buffer(__v, __p);
}
- return __make_iter(__p);
+ return iterator(this, __p);
}
-#endif // !_LIBCPP_CXX03_LANG
-
template <class _Tp, class _Allocator>
typename vector<_Tp, _Allocator>::iterator
vector<_Tp, _Allocator>::insert(const_iterator __position, size_type __n, const_reference __x)
@@ -1829,7 +1746,7 @@ vector<_Tp, _Allocator>::insert(const_iterator __position, size_type __n, const_
__p = __swap_out_circular_buffer(__v, __p);
}
}
- return __make_iter(__p);
+ return iterator(this, __p);
}
template <class _Tp, class _Allocator>
@@ -1872,14 +1789,14 @@ vector<_Tp, _Allocator>::insert(const_iterator __position, _InputIterator __firs
}
catch (...)
{
- erase(__make_iter(__old_last), end());
+ erase(iterator(this, __old_last), end());
throw;
}
#endif // _LIBCPP_NO_EXCEPTIONS
}
__p = _VSTD::rotate(__p, __old_last, this->__end_);
- insert(__make_iter(__p), _VSTD::make_move_iterator(__v.begin()),
- _VSTD::make_move_iterator(__v.end()));
+ insert(iterator(this, __p), _VSTD::make_move_iterator(__v.begin()),
+ _VSTD::make_move_iterator(__v.end()));
return begin() + __off;
}
@@ -1929,7 +1846,7 @@ vector<_Tp, _Allocator>::insert(const_iterator __position, _ForwardIterator __fi
__p = __swap_out_circular_buffer(__v, __p);
}
}
- return __make_iter(__p);
+ return iterator(this, __p);
}
template <class _Tp, class _Allocator>
@@ -1973,9 +1890,7 @@ vector<_Tp, _Allocator>::swap(vector& __x)
_VSTD::swap(this->__end_cap(), __x.__end_cap());
_VSTD::__swap_allocator(this->__alloc(), __x.__alloc(),
integral_constant<bool,__alloc_traits::propagate_on_container_swap::value>());
-#if _LIBCPP_DEBUG_LEVEL == 2
- __get_db()->swap(this, _VSTD::addressof(__x));
-#endif
+ std::__debug_db_swap(this, std::addressof(__x));
}
template <class _Tp, class _Allocator>
@@ -1999,7 +1914,7 @@ vector<_Tp, _Allocator>::__invariants() const
return true;
}
-#if _LIBCPP_DEBUG_LEVEL == 2
+#ifdef _LIBCPP_ENABLE_DEBUG_MODE
template <class _Tp, class _Allocator>
bool
@@ -2031,24 +1946,13 @@ vector<_Tp, _Allocator>::__subscriptable(const const_iterator* __i, ptrdiff_t __
return this->__begin_ <= __p && __p < this->__end_;
}
-#endif // _LIBCPP_DEBUG_LEVEL == 2
-
-template <class _Tp, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
-void
-vector<_Tp, _Allocator>::__invalidate_all_iterators()
-{
-#if _LIBCPP_DEBUG_LEVEL == 2
- __get_db()->__invalidate_all(this);
-#endif
-}
-
+#endif // _LIBCPP_ENABLE_DEBUG_MODE
template <class _Tp, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
void
vector<_Tp, _Allocator>::__invalidate_iterators_past(pointer __new_last) {
-#if _LIBCPP_DEBUG_LEVEL == 2
+#ifdef _LIBCPP_ENABLE_DEBUG_MODE
__c_node* __c = __get_db()->__find_c_and_lock(this);
for (__i_node** __p = __c->end_; __p != __c->beg_; ) {
--__p;
@@ -2079,7 +1983,6 @@ struct __has_storage_type<vector<bool, _Allocator> >
template <class _Allocator>
class _LIBCPP_TEMPLATE_VIS vector<bool, _Allocator>
- : private __vector_base_common<true>
{
public:
typedef vector __self;
@@ -2107,7 +2010,11 @@ private:
__compressed_pair<size_type, __storage_allocator> __cap_alloc_;
public:
typedef __bit_reference<vector> reference;
+#ifdef _LIBCPP_ABI_BITSET_VECTOR_BOOL_CONST_SUBSCRIPT_RETURN_BOOL
+ using const_reference = bool;
+#else
typedef __bit_const_reference<vector> const_reference;
+#endif
private:
_LIBCPP_INLINE_VISIBILITY
size_type& __cap() _NOEXCEPT
@@ -2172,23 +2079,23 @@ public:
vector(initializer_list<value_type> __il, const allocator_type& __a);
_LIBCPP_INLINE_VISIBILITY
+ vector& operator=(initializer_list<value_type> __il)
+ {assign(__il.begin(), __il.end()); return *this;}
+
+#endif // !_LIBCPP_CXX03_LANG
+
+ _LIBCPP_INLINE_VISIBILITY
vector(vector&& __v)
#if _LIBCPP_STD_VER > 14
- _NOEXCEPT;
+ noexcept;
#else
_NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value);
#endif
- vector(vector&& __v, const __identity_t<allocator_type>& __a);
+ vector(vector&& __v, const __type_identity_t<allocator_type>& __a);
_LIBCPP_INLINE_VISIBILITY
vector& operator=(vector&& __v)
_NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value));
- _LIBCPP_INLINE_VISIBILITY
- vector& operator=(initializer_list<value_type> __il)
- {assign(__il.begin(), __il.end()); return *this;}
-
-#endif // !_LIBCPP_CXX03_LANG
-
template <class _InputIterator>
typename enable_if
<
@@ -2304,7 +2211,6 @@ public:
iterator insert(const_iterator __position, const value_type& __x);
iterator insert(const_iterator __position, size_type __n, const value_type& __x);
- iterator insert(const_iterator __position, size_type __n, const_reference __x);
template <class _InputIterator>
typename enable_if
<
@@ -2348,12 +2254,36 @@ public:
bool __invariants() const;
private:
- _LIBCPP_INLINE_VISIBILITY void __invalidate_all_iterators();
- void __vallocate(size_type __n);
+ _LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI
+ void __throw_length_error() const {
+ _VSTD::__throw_length_error("vector");
+ }
+
+ _LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI
+ void __throw_out_of_range() const {
+ _VSTD::__throw_out_of_range("vector");
+ }
+
+ // Allocate space for __n objects
+ // throws length_error if __n > max_size()
+ // throws (probably bad_alloc) if memory run out
+ // Precondition: __begin_ == __end_ == __cap() == 0
+ // Precondition: __n > 0
+ // Postcondition: capacity() >= __n
+ // Postcondition: size() == 0
+ _LIBCPP_HIDE_FROM_ABI void __vallocate(size_type __n) {
+ if (__n > max_size())
+ __throw_length_error();
+ auto __allocation = std::__allocate_at_least(__alloc(), __external_cap_to_internal(__n));
+ __begin_ = __allocation.ptr;
+ __size_ = 0;
+ __cap() = __allocation.count;
+ }
+
void __vdeallocate() _NOEXCEPT;
_LIBCPP_INLINE_VISIBILITY
static size_type __align_it(size_type __new_size) _NOEXCEPT
- {return __new_size + (__bits_per_word-1) & ~((size_type)__bits_per_word-1);}
+ {return (__new_size + (__bits_per_word-1)) & ~((size_type)__bits_per_word-1);}
_LIBCPP_INLINE_VISIBILITY size_type __recommend(size_type __new_size) const;
_LIBCPP_INLINE_VISIBILITY void __construct_at_end(size_type __n, bool __x);
template <class _ForwardIterator>
@@ -2368,8 +2298,10 @@ private:
reference __make_ref(size_type __pos) _NOEXCEPT
{return reference(__begin_ + __pos / __bits_per_word, __storage_type(1) << __pos % __bits_per_word);}
_LIBCPP_INLINE_VISIBILITY
- const_reference __make_ref(size_type __pos) const _NOEXCEPT
- {return const_reference(__begin_ + __pos / __bits_per_word, __storage_type(1) << __pos % __bits_per_word);}
+ const_reference __make_ref(size_type __pos) const _NOEXCEPT {
+ return __bit_const_reference<vector>(__begin_ + __pos / __bits_per_word,
+ __storage_type(1) << __pos % __bits_per_word);
+ }
_LIBCPP_INLINE_VISIBILITY
iterator __make_iter(size_type __pos) _NOEXCEPT
{return iterator(__begin_ + __pos / __bits_per_word, static_cast<unsigned>(__pos % __bits_per_word));}
@@ -2429,39 +2361,13 @@ private:
};
template <class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
-void
-vector<bool, _Allocator>::__invalidate_all_iterators()
-{
-}
-
-// Allocate space for __n objects
-// throws length_error if __n > max_size()
-// throws (probably bad_alloc) if memory run out
-// Precondition: __begin_ == __end_ == __cap() == 0
-// Precondition: __n > 0
-// Postcondition: capacity() == __n
-// Postcondition: size() == 0
-template <class _Allocator>
-void
-vector<bool, _Allocator>::__vallocate(size_type __n)
-{
- if (__n > max_size())
- this->__throw_length_error();
- __n = __external_cap_to_internal(__n);
- this->__begin_ = __storage_traits::allocate(this->__alloc(), __n);
- this->__size_ = 0;
- this->__cap() = __n;
-}
-
-template <class _Allocator>
void
vector<bool, _Allocator>::__vdeallocate() _NOEXCEPT
{
if (this->__begin_ != nullptr)
{
__storage_traits::deallocate(this->__alloc(), this->__begin_, __cap());
- __invalidate_all_iterators();
+ std::__debug_db_invalidate_all(this);
this->__begin_ = nullptr;
this->__size_ = this->__cap() = 0;
}
@@ -2634,7 +2540,7 @@ vector<bool, _Allocator>::vector(_InputIterator __first, _InputIterator __last,
{
if (__begin_ != nullptr)
__storage_traits::deallocate(__alloc(), __begin_, __cap());
- __invalidate_all_iterators();
+ std::__debug_db_invalidate_all(this);
throw;
}
#endif // _LIBCPP_NO_EXCEPTIONS
@@ -2661,7 +2567,7 @@ vector<bool, _Allocator>::vector(_InputIterator __first, _InputIterator __last,
{
if (__begin_ != nullptr)
__storage_traits::deallocate(__alloc(), __begin_, __cap());
- __invalidate_all_iterators();
+ std::__debug_db_invalidate_all(this);
throw;
}
#endif // _LIBCPP_NO_EXCEPTIONS
@@ -2736,7 +2642,7 @@ vector<bool, _Allocator>::~vector()
{
if (__begin_ != nullptr)
__storage_traits::deallocate(__alloc(), __begin_, __cap());
- __invalidate_all_iterators();
+ std::__debug_db_invalidate_all(this);
}
template <class _Allocator>
@@ -2786,8 +2692,6 @@ vector<bool, _Allocator>::operator=(const vector& __v)
return *this;
}
-#ifndef _LIBCPP_CXX03_LANG
-
template <class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY vector<bool, _Allocator>::vector(vector&& __v)
#if _LIBCPP_STD_VER > 14
@@ -2804,7 +2708,7 @@ inline _LIBCPP_INLINE_VISIBILITY vector<bool, _Allocator>::vector(vector&& __v)
}
template <class _Allocator>
-vector<bool, _Allocator>::vector(vector&& __v, const __identity_t<allocator_type>& __a)
+vector<bool, _Allocator>::vector(vector&& __v, const __type_identity_t<allocator_type>& __a)
: __begin_(nullptr),
__size_(0),
__cap_alloc_(0, __a)
@@ -2859,8 +2763,6 @@ vector<bool, _Allocator>::__move_assign(vector& __c, true_type)
__c.__cap() = __c.__size_ = 0;
}
-#endif // !_LIBCPP_CXX03_LANG
-
template <class _Allocator>
void
vector<bool, _Allocator>::assign(size_type __n, const value_type& __x)
@@ -2880,7 +2782,7 @@ vector<bool, _Allocator>::assign(size_type __n, const value_type& __x)
}
_VSTD::fill_n(begin(), __n, __x);
}
- __invalidate_all_iterators();
+ std::__debug_db_invalidate_all(this);
}
template <class _Allocator>
@@ -2934,7 +2836,7 @@ vector<bool, _Allocator>::reserve(size_type __n)
__v.__vallocate(__n);
__v.__construct_at_end(this->begin(), this->end());
swap(__v);
- __invalidate_all_iterators();
+ std::__debug_db_invalidate_all(this);
}
}
@@ -3243,7 +3145,7 @@ vector<bool, _Allocator>::__hash_code() const _NOEXCEPT
template <class _Allocator>
struct _LIBCPP_TEMPLATE_VIS hash<vector<bool, _Allocator> >
- : public unary_function<vector<bool, _Allocator>, size_t>
+ : public __unary_function<vector<bool, _Allocator>, size_t>
{
_LIBCPP_INLINE_VISIBILITY
size_t operator()(const vector<bool, _Allocator>& __vec) const _NOEXCEPT
@@ -3324,8 +3226,16 @@ erase_if(vector<_Tp, _Allocator>& __c, _Predicate __pred) {
__c.erase(_VSTD::remove_if(__c.begin(), __c.end(), __pred), __c.end());
return __old_size - __c.size();
}
+
+template <>
+inline constexpr bool __format::__enable_insertable<std::vector<char>> = true;
+#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+template <>
+inline constexpr bool __format::__enable_insertable<std::vector<wchar_t>> = true;
#endif
+#endif // _LIBCPP_STD_VER > 17
+
_LIBCPP_END_NAMESPACE_STD
_LIBCPP_POP_MACROS
diff --git a/libcxx/include/version b/libcxx/include/version
index 0c2365612853..2034e4b1f3d9 100644
--- a/libcxx/include/version
+++ b/libcxx/include/version
@@ -38,6 +38,7 @@ __cpp_lib_atomic_shared_ptr 201711L <atomic>
__cpp_lib_atomic_value_initialization 201911L <atomic> <memory>
__cpp_lib_atomic_wait 201907L <atomic>
__cpp_lib_barrier 201907L <barrier>
+__cpp_lib_bind_back 202202L <functional>
__cpp_lib_bind_front 201907L <functional>
__cpp_lib_bit_cast 201806L <bit>
__cpp_lib_bitops 201907L <bit>
@@ -55,13 +56,14 @@ __cpp_lib_clamp 201603L <algorithm>
__cpp_lib_complex_udls 201309L <complex>
__cpp_lib_concepts 202002L <concepts>
__cpp_lib_constexpr_algorithms 201806L <algorithm>
+__cpp_lib_constexpr_cmath 202202L <cmath> <cstdlib>
__cpp_lib_constexpr_complex 201711L <complex>
__cpp_lib_constexpr_dynamic_alloc 201907L <memory>
__cpp_lib_constexpr_functional 201907L <functional>
__cpp_lib_constexpr_iterator 201811L <iterator>
__cpp_lib_constexpr_memory 201811L <memory>
__cpp_lib_constexpr_numeric 201911L <numeric>
-__cpp_lib_constexpr_string 201811L <string>
+__cpp_lib_constexpr_string 201907L <string>
__cpp_lib_constexpr_string_view 201811L <string_view>
__cpp_lib_constexpr_tuple 201811L <tuple>
__cpp_lib_constexpr_typeinfo 202106L <typeinfo>
@@ -115,7 +117,6 @@ __cpp_lib_map_try_emplace 201411L <map>
__cpp_lib_math_constants 201907L <numbers>
__cpp_lib_math_special_functions 201603L <cmath>
__cpp_lib_memory_resource 201603L <memory_resource>
-__cpp_lib_monadic_optional 202110L <optional>
__cpp_lib_move_only_function 202110L <functional>
__cpp_lib_node_extract 201606L <map> <set> <unordered_map>
<unordered_set>
@@ -125,16 +126,27 @@ __cpp_lib_nonmember_container_access 201411L <array> <deque>
<unordered_map> <unordered_set> <vector>
__cpp_lib_not_fn 201603L <functional>
__cpp_lib_null_iterators 201304L <iterator>
-__cpp_lib_optional 201606L <optional>
+__cpp_lib_optional 202110L <optional>
+ 201606L // C++17
__cpp_lib_out_ptr 202106L <memory>
__cpp_lib_parallel_algorithm 201603L <algorithm> <numeric>
__cpp_lib_polymorphic_allocator 201902L <memory_resource>
__cpp_lib_quoted_string_io 201304L <iomanip>
__cpp_lib_ranges 201811L <algorithm> <functional> <iterator>
<memory> <ranges>
+__cpp_lib_ranges_chunk 202202L <ranges>
+__cpp_lib_ranges_chunk_by 202202L <ranges>
+__cpp_lib_ranges_iota 202202L <numeric>
+__cpp_lib_ranges_join_with 202202L <ranges>
+__cpp_lib_ranges_slide 202202L <ranges>
__cpp_lib_ranges_starts_ends_with 202106L <algorithm>
+__cpp_lib_ranges_to_container 202202L <deque> <forward_list> <list>
+ <map> <priority_queue> <queue>
+ <set> <stack> <string>
+ <unordered_map> <unordered_set> <vector>
__cpp_lib_ranges_zip 202110L <ranges> <tuple> <utility>
__cpp_lib_raw_memory_algorithms 201606L <memory>
+__cpp_lib_reference_from_temporary 202202L <type_traits>
__cpp_lib_remove_cvref 201711L <type_traits>
__cpp_lib_result_of_sfinae 201210L <functional> <type_traits>
__cpp_lib_robust_nonmodifying_seq_ops 201304L <algorithm>
@@ -142,7 +154,8 @@ __cpp_lib_sample 201603L <algorithm>
__cpp_lib_scoped_lock 201703L <mutex>
__cpp_lib_semaphore 201907L <semaphore>
__cpp_lib_shared_mutex 201505L <shared_mutex>
-__cpp_lib_shared_ptr_arrays 201611L <memory>
+__cpp_lib_shared_ptr_arrays 201707L <memory>
+ 201611L // C++17
__cpp_lib_shared_ptr_weak_type 201606L <memory>
__cpp_lib_shared_timed_mutex 201402L <shared_mutex>
__cpp_lib_shift 201806L <algorithm>
@@ -174,16 +187,18 @@ __cpp_lib_type_identity 201806L <type_traits>
__cpp_lib_type_trait_variable_templates 201510L <type_traits>
__cpp_lib_uncaught_exceptions 201411L <exception>
__cpp_lib_unordered_map_try_emplace 201411L <unordered_map>
+__cpp_lib_unreachable 202202L <utility>
__cpp_lib_unwrap_ref 201811L <functional>
__cpp_lib_variant 202102L <variant>
__cpp_lib_void_t 201411L <type_traits>
*/
+#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
// clang-format off
@@ -222,7 +237,7 @@ __cpp_lib_void_t 201411L <type_traits>
# define __cpp_lib_as_const 201510L
# define __cpp_lib_atomic_is_always_lock_free 201603L
# define __cpp_lib_bool_constant 201505L
-// # define __cpp_lib_boyer_moore_searcher 201603L
+# define __cpp_lib_boyer_moore_searcher 201603L
# define __cpp_lib_byte 201603L
# define __cpp_lib_chrono 201611L
# define __cpp_lib_clamp 201603L
@@ -232,7 +247,9 @@ __cpp_lib_void_t 201411L <type_traits>
# define __cpp_lib_filesystem 201703L
# endif
# define __cpp_lib_gcd_lcm 201606L
-// # define __cpp_lib_hardware_interference_size 201703L
+# if defined(__GCC_DESTRUCTIVE_SIZE) && defined(__GCC_CONSTRUCTIVE_SIZE)
+# define __cpp_lib_hardware_interference_size 201703L
+# endif
# define __cpp_lib_has_unique_object_representations 201606L
# define __cpp_lib_hypot 201603L
# define __cpp_lib_incomplete_container_elements 201505L
@@ -273,7 +290,7 @@ __cpp_lib_void_t 201411L <type_traits>
#if _LIBCPP_STD_VER > 17
# undef __cpp_lib_array_constexpr
# define __cpp_lib_array_constexpr 201811L
-// # define __cpp_lib_assume_aligned 201811L
+# define __cpp_lib_assume_aligned 201811L
# define __cpp_lib_atomic_flag_test 201907L
// # define __cpp_lib_atomic_float 201711L
# define __cpp_lib_atomic_lock_free_type_aliases 201907L
@@ -301,7 +318,7 @@ __cpp_lib_void_t 201411L <type_traits>
# define __cpp_lib_constexpr_iterator 201811L
# define __cpp_lib_constexpr_memory 201811L
# define __cpp_lib_constexpr_numeric 201911L
-# define __cpp_lib_constexpr_string 201811L
+# define __cpp_lib_constexpr_string 201907L
# define __cpp_lib_constexpr_string_view 201811L
# define __cpp_lib_constexpr_tuple 201811L
# define __cpp_lib_constexpr_utility 201811L
@@ -319,9 +336,7 @@ __cpp_lib_void_t 201411L <type_traits>
# endif
# define __cpp_lib_generic_unordered_lookup 201811L
# define __cpp_lib_int_pow2 202002L
-# if !defined(_LIBCPP_HAS_NO_CONCEPTS)
-# define __cpp_lib_integer_comparison_functions 202002L
-# endif
+# define __cpp_lib_integer_comparison_functions 202002L
# define __cpp_lib_interpolate 201902L
# define __cpp_lib_is_constant_evaluated 201811L
// # define __cpp_lib_is_layout_compatible 201907L
@@ -334,15 +349,15 @@ __cpp_lib_void_t 201411L <type_traits>
# define __cpp_lib_latch 201907L
# endif
# define __cpp_lib_list_remove_return_type 201806L
-# if !defined(_LIBCPP_HAS_NO_CONCEPTS)
-# define __cpp_lib_math_constants 201907L
-# endif
+# define __cpp_lib_math_constants 201907L
// # define __cpp_lib_polymorphic_allocator 201902L
// # define __cpp_lib_ranges 201811L
# define __cpp_lib_remove_cvref 201711L
# if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_semaphore)
# define __cpp_lib_semaphore 201907L
# endif
+# undef __cpp_lib_shared_ptr_arrays
+# define __cpp_lib_shared_ptr_arrays 201707L
# define __cpp_lib_shift 201806L
// # define __cpp_lib_smart_ptr_for_overwrite 202002L
// # define __cpp_lib_source_location 201907L
@@ -361,23 +376,34 @@ __cpp_lib_void_t 201411L <type_traits>
#if _LIBCPP_STD_VER > 20
# define __cpp_lib_adaptor_iterator_pair_constructor 202106L
-// # define __cpp_lib_allocate_at_least 202106L
+# define __cpp_lib_allocate_at_least 202106L
// # define __cpp_lib_associative_heterogeneous_erasure 202110L
+// # define __cpp_lib_bind_back 202202L
# define __cpp_lib_byteswap 202110L
+// # define __cpp_lib_constexpr_cmath 202202L
// # define __cpp_lib_constexpr_typeinfo 202106L
// # define __cpp_lib_invoke_r 202106L
# define __cpp_lib_is_scoped_enum 202011L
-# define __cpp_lib_monadic_optional 202110L
// # define __cpp_lib_move_only_function 202110L
+# undef __cpp_lib_optional
+# define __cpp_lib_optional 202110L
// # define __cpp_lib_out_ptr 202106L
+// # define __cpp_lib_ranges_chunk 202202L
+// # define __cpp_lib_ranges_chunk_by 202202L
+// # define __cpp_lib_ranges_iota 202202L
+// # define __cpp_lib_ranges_join_with 202202L
+// # define __cpp_lib_ranges_slide 202202L
// # define __cpp_lib_ranges_starts_ends_with 202106L
+// # define __cpp_lib_ranges_to_container 202202L
// # define __cpp_lib_ranges_zip 202110L
+// # define __cpp_lib_reference_from_temporary 202202L
// # define __cpp_lib_spanstream 202106L
// # define __cpp_lib_stacktrace 202011L
-// # define __cpp_lib_stdatomic_h 202011L
+# define __cpp_lib_stdatomic_h 202011L
# define __cpp_lib_string_contains 202011L
# define __cpp_lib_string_resize_and_overwrite 202110L
# define __cpp_lib_to_underlying 202102L
+# define __cpp_lib_unreachable 202202L
#endif
// clang-format on
diff --git a/libcxx/include/wchar.h b/libcxx/include/wchar.h
index 4d2f62e45cae..ce63cf247618 100644
--- a/libcxx/include/wchar.h
+++ b/libcxx/include/wchar.h
@@ -10,7 +10,7 @@
#if defined(__need_wint_t) || defined(__need_mbstate_t)
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
#include_next <wchar.h>
@@ -113,7 +113,7 @@ size_t wcsrtombs(char* restrict dst, const wchar_t** restrict src, size_t len,
#endif
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
#ifdef __cplusplus
diff --git a/libcxx/include/wctype.h b/libcxx/include/wctype.h
index 08bef7caab90..e4dc61ad5cf4 100644
--- a/libcxx/include/wctype.h
+++ b/libcxx/include/wctype.h
@@ -51,7 +51,7 @@ wctrans_t wctrans(const char* property);
#endif
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
// TODO: